aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/infrastructure/rhino1_7R1/src
diff options
context:
space:
mode:
authoralexanders@b2ef00c0-3703-41da-baef-cfe82387ac0c <none@none>2010-02-03 00:50:41 +0000
committeralexanders@b2ef00c0-3703-41da-baef-cfe82387ac0c <none@none>2010-02-03 00:50:41 +0000
commit89bda83e0570ab87c6e449f5955613d5385e90b3 (patch)
treebeae82eff98e4b6e18e1521c49d48d087a8cef55 /trunk/infrastructure/rhino1_7R1/src
parentd912ef9675f2e516df4eba081107729afbffe10c (diff)
downloadetherpad-89bda83e0570ab87c6e449f5955613d5385e90b3.tar.gz
etherpad-89bda83e0570ab87c6e449f5955613d5385e90b3.tar.xz
etherpad-89bda83e0570ab87c6e449f5955613d5385e90b3.zip
removed obsolete svn folder from hg tree
--HG-- extra : convert_revision : svn%3Ab2ef00c0-3703-41da-baef-cfe82387ac0c/trunk%408
Diffstat (limited to 'trunk/infrastructure/rhino1_7R1/src')
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/build.xml98
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/manifest3
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ByteCode.java274
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ClassFileWriter.java3038
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java311
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/BaseFunction.java553
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Callable.java59
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassCache.java220
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassShutter.java89
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/CompilerEnvirons.java233
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ConstProperties.java109
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java2526
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextAction.java59
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextFactory.java594
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextListener.java60
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DToA.java1271
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Decompiler.java918
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefaultErrorReporter.java113
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefiningClassLoader.java88
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Delegator.java266
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EcmaError.java160
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ErrorReporter.java106
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Evaluator.java118
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EvaluatorException.java123
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Function.java84
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionNode.java117
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionObject.java569
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/GeneratedClassLoader.java66
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IRFactory.java1607
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionCall.java55
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionObject.java189
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdScriptableObject.java734
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ImporterTopLevel.java318
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InformativeParser.java225
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterfaceAdapter.java156
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpretedFunction.java221
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Interpreter.java4643
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpreterData.java192
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaAdapter.java1129
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaMembers.java935
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaScriptException.java117
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Kit.java486
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/LazilyLoadedCtor.java136
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/MemberBox.java362
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeArray.java1727
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeBoolean.java170
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeCall.java154
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeDate.java1604
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeError.java227
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeFunction.java169
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGenerator.java281
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGlobal.java790
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeIterator.java260
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaArray.java168
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaClass.java320
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaConstructor.java85
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaMethod.java576
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java1002
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaPackage.java199
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaTopPackage.java187
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeMath.java399
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeNumber.java244
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeObject.java316
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeScript.java221
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeString.java983
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeWith.java207
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Node.java1394
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NodeTransformer.java565
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjArray.java388
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjToIntMap.java697
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Parser.java2554
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/PolicySecurityController.java223
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Ref.java64
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RefCallable.java59
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RegExpProxy.java71
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RhinoException.java306
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Script.java73
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptOrFnNode.java241
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptRuntime.java3830
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Scriptable.java342
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptableObject.java2428
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecureCaller.java198
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityController.java211
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityUtilities.java80
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SpecialRef.java151
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Synchronizer.java81
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Token.java436
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/TokenStream.java1500
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UintMap.java659
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Undefined.java60
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UniqueTag.java120
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/VMBridge.java183
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrapFactory.java183
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrappedException.java93
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Wrapper.java58
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/continuations/Continuation.java136
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebugFrame.java91
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableObject.java61
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableScript.java119
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/Debugger.java69
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk11/VMBridge_jdk11.java84
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk13/VMBridge_jdk13.java157
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk15/VMBridge_jdk15.java87
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Block.java615
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/ClassCompiler.java214
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Codegen.java5031
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/DataFlowBitSet.java134
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptFunctionNode.java149
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptRuntime.java311
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptTransformer.java133
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Optimizer.java510
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExp.java2782
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExpCtor.java289
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/RegExpImpl.java541
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/SubString.java75
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages.properties778
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages_fr.properties329
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableInputStream.java112
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableOutputStream.java207
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLLib.java132
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLObject.java128
121 files changed, 0 insertions, 64541 deletions
diff --git a/trunk/infrastructure/rhino1_7R1/src/build.xml b/trunk/infrastructure/rhino1_7R1/src/build.xml
deleted file mode 100644
index a0a1e13..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/build.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- ***** 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):
- -
- - 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 ***** -->
-
-
-<!--
-Build file for Rhino using Ant (see http://jakarta.apache.org/ant/index.html)
-Requires Ant version 1.2
--->
-<project name="src" default="compile" basedir="..">
-
- <property file="build.properties"/>
-
- <available property="jdk15"
- classname="java.lang.reflect.ParameterizedType" />
-
- <target name="compile" depends="compile-most,compile-jdk15">
- </target>
-
- <target name="compile-most">
- <javac srcdir="src"
- destdir="${classes}"
- includes="org/**/*.java"
- excludes="org/**/jdk15/*.java"
- deprecation="on"
- debug="${debug}"
- target="${target-jvm}"
- source="${source-level}"
- >
- </javac>
- <copy todir="${classes}">
- <fileset dir="src" includes="org/**/*.properties" />
- <filterset>
- <filter token="IMPLEMENTATION.VERSION"
- value="${implementation.version}"/>
- </filterset>
- </copy>
- </target>
-
- <target name="compile-jdk15" if="jdk15">
- <javac srcdir="src"
- destdir="${classes}"
- includes="org/**/jdk15/*.java"
- deprecation="on"
- debug="${debug}"
- target="${target-jvm}"
- source="${source-level}"
- >
- </javac>
- </target>
-
- <target name="copy-source">
- <mkdir dir="${dist.dir}/src"/>
- <copy todir="${dist.dir}/src">
- <fileset dir="src"
- includes="**/*.java,**/*.properties,**/*.xml,manifest"/>
- </copy>
- </target>
-
- <target name="clean">
- <delete includeEmptyDirs="true">
- <fileset dir="${classes}"
- excludes="org/mozilla/javascript/tools/**"/>
- </delete>
- </target>
-
-</project>
diff --git a/trunk/infrastructure/rhino1_7R1/src/manifest b/trunk/infrastructure/rhino1_7R1/src/manifest
deleted file mode 100644
index b7d0c06..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/manifest
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: org.mozilla.javascript.tools.shell.Main
-Class-Path: xbean.jar
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ByteCode.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ByteCode.java
deleted file mode 100644
index fa4713e..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ByteCode.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/* -*- 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):
- * Roger Lawrence
- *
- * 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.classfile;
-
-/**
- * This class provides opcode values expected by the JVM in Java class files.
- *
- * It also provides tables for internal use by the ClassFileWriter.
- *
- * @author Roger Lawrence
- */
-public class ByteCode {
-
- /**
- * The byte opcodes defined by the Java Virtual Machine.
- */
- public static final int
- NOP = 0x00,
- ACONST_NULL = 0x01,
- ICONST_M1 = 0x02,
- ICONST_0 = 0x03,
- ICONST_1 = 0x04,
- ICONST_2 = 0x05,
- ICONST_3 = 0x06,
- ICONST_4 = 0x07,
- ICONST_5 = 0x08,
- LCONST_0 = 0x09,
- LCONST_1 = 0x0A,
- FCONST_0 = 0x0B,
- FCONST_1 = 0x0C,
- FCONST_2 = 0x0D,
- DCONST_0 = 0x0E,
- DCONST_1 = 0x0F,
- BIPUSH = 0x10,
- SIPUSH = 0x11,
- LDC = 0x12,
- LDC_W = 0x13,
- LDC2_W = 0x14,
- ILOAD = 0x15,
- LLOAD = 0x16,
- FLOAD = 0x17,
- DLOAD = 0x18,
- ALOAD = 0x19,
- ILOAD_0 = 0x1A,
- ILOAD_1 = 0x1B,
- ILOAD_2 = 0x1C,
- ILOAD_3 = 0x1D,
- LLOAD_0 = 0x1E,
- LLOAD_1 = 0x1F,
- LLOAD_2 = 0x20,
- LLOAD_3 = 0x21,
- FLOAD_0 = 0x22,
- FLOAD_1 = 0x23,
- FLOAD_2 = 0x24,
- FLOAD_3 = 0x25,
- DLOAD_0 = 0x26,
- DLOAD_1 = 0x27,
- DLOAD_2 = 0x28,
- DLOAD_3 = 0x29,
- ALOAD_0 = 0x2A,
- ALOAD_1 = 0x2B,
- ALOAD_2 = 0x2C,
- ALOAD_3 = 0x2D,
- IALOAD = 0x2E,
- LALOAD = 0x2F,
- FALOAD = 0x30,
- DALOAD = 0x31,
- AALOAD = 0x32,
- BALOAD = 0x33,
- CALOAD = 0x34,
- SALOAD = 0x35,
- ISTORE = 0x36,
- LSTORE = 0x37,
- FSTORE = 0x38,
- DSTORE = 0x39,
- ASTORE = 0x3A,
- ISTORE_0 = 0x3B,
- ISTORE_1 = 0x3C,
- ISTORE_2 = 0x3D,
- ISTORE_3 = 0x3E,
- LSTORE_0 = 0x3F,
- LSTORE_1 = 0x40,
- LSTORE_2 = 0x41,
- LSTORE_3 = 0x42,
- FSTORE_0 = 0x43,
- FSTORE_1 = 0x44,
- FSTORE_2 = 0x45,
- FSTORE_3 = 0x46,
- DSTORE_0 = 0x47,
- DSTORE_1 = 0x48,
- DSTORE_2 = 0x49,
- DSTORE_3 = 0x4A,
- ASTORE_0 = 0x4B,
- ASTORE_1 = 0x4C,
- ASTORE_2 = 0x4D,
- ASTORE_3 = 0x4E,
- IASTORE = 0x4F,
- LASTORE = 0x50,
- FASTORE = 0x51,
- DASTORE = 0x52,
- AASTORE = 0x53,
- BASTORE = 0x54,
- CASTORE = 0x55,
- SASTORE = 0x56,
- POP = 0x57,
- POP2 = 0x58,
- DUP = 0x59,
- DUP_X1 = 0x5A,
- DUP_X2 = 0x5B,
- DUP2 = 0x5C,
- DUP2_X1 = 0x5D,
- DUP2_X2 = 0x5E,
- SWAP = 0x5F,
- IADD = 0x60,
- LADD = 0x61,
- FADD = 0x62,
- DADD = 0x63,
- ISUB = 0x64,
- LSUB = 0x65,
- FSUB = 0x66,
- DSUB = 0x67,
- IMUL = 0x68,
- LMUL = 0x69,
- FMUL = 0x6A,
- DMUL = 0x6B,
- IDIV = 0x6C,
- LDIV = 0x6D,
- FDIV = 0x6E,
- DDIV = 0x6F,
- IREM = 0x70,
- LREM = 0x71,
- FREM = 0x72,
- DREM = 0x73,
- INEG = 0x74,
- LNEG = 0x75,
- FNEG = 0x76,
- DNEG = 0x77,
- ISHL = 0x78,
- LSHL = 0x79,
- ISHR = 0x7A,
- LSHR = 0x7B,
- IUSHR = 0x7C,
- LUSHR = 0x7D,
- IAND = 0x7E,
- LAND = 0x7F,
- IOR = 0x80,
- LOR = 0x81,
- IXOR = 0x82,
- LXOR = 0x83,
- IINC = 0x84,
- I2L = 0x85,
- I2F = 0x86,
- I2D = 0x87,
- L2I = 0x88,
- L2F = 0x89,
- L2D = 0x8A,
- F2I = 0x8B,
- F2L = 0x8C,
- F2D = 0x8D,
- D2I = 0x8E,
- D2L = 0x8F,
- D2F = 0x90,
- I2B = 0x91,
- I2C = 0x92,
- I2S = 0x93,
- LCMP = 0x94,
- FCMPL = 0x95,
- FCMPG = 0x96,
- DCMPL = 0x97,
- DCMPG = 0x98,
- IFEQ = 0x99,
- IFNE = 0x9A,
- IFLT = 0x9B,
- IFGE = 0x9C,
- IFGT = 0x9D,
- IFLE = 0x9E,
- IF_ICMPEQ = 0x9F,
- IF_ICMPNE = 0xA0,
- IF_ICMPLT = 0xA1,
- IF_ICMPGE = 0xA2,
- IF_ICMPGT = 0xA3,
- IF_ICMPLE = 0xA4,
- IF_ACMPEQ = 0xA5,
- IF_ACMPNE = 0xA6,
- GOTO = 0xA7,
- JSR = 0xA8,
- RET = 0xA9,
- TABLESWITCH = 0xAA,
- LOOKUPSWITCH = 0xAB,
- IRETURN = 0xAC,
- LRETURN = 0xAD,
- FRETURN = 0xAE,
- DRETURN = 0xAF,
- ARETURN = 0xB0,
- RETURN = 0xB1,
- GETSTATIC = 0xB2,
- PUTSTATIC = 0xB3,
- GETFIELD = 0xB4,
- PUTFIELD = 0xB5,
- INVOKEVIRTUAL = 0xB6,
- INVOKESPECIAL = 0xB7,
- INVOKESTATIC = 0xB8,
- INVOKEINTERFACE = 0xB9,
- NEW = 0xBB,
- NEWARRAY = 0xBC,
- ANEWARRAY = 0xBD,
- ARRAYLENGTH = 0xBE,
- ATHROW = 0xBF,
- CHECKCAST = 0xC0,
- INSTANCEOF = 0xC1,
- MONITORENTER = 0xC2,
- MONITOREXIT = 0xC3,
- WIDE = 0xC4,
- MULTIANEWARRAY = 0xC5,
- IFNULL = 0xC6,
- IFNONNULL = 0xC7,
- GOTO_W = 0xC8,
- JSR_W = 0xC9,
- BREAKPOINT = 0xCA,
-
- IMPDEP1 = 0xFE,
- IMPDEP2 = 0xFF;
-
- /**
- * Types for the NEWARRAY opcode.
- */
- public static final byte
- T_BOOLEAN = 4,
- T_CHAR = 5,
- T_FLOAT = 6,
- T_DOUBLE = 7,
- T_BYTE = 8,
- T_SHORT = 9,
- T_INT = 10,
- T_LONG = 11;
-
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ClassFileWriter.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ClassFileWriter.java
deleted file mode 100644
index b9c6c96..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ClassFileWriter.java
+++ /dev/null
@@ -1,3038 +0,0 @@
-/* -*- 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):
- * Roger Lawrence
- *
- * 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.classfile;
-
-import org.mozilla.javascript.ObjToIntMap;
-import org.mozilla.javascript.ObjArray;
-import org.mozilla.javascript.UintMap;
-
-import java.io.*;
-
-/**
- * ClassFileWriter
- *
- * A ClassFileWriter is used to write a Java class file. Methods are
- * provided to create fields and methods, and within methods to write
- * Java bytecodes.
- *
- * @author Roger Lawrence
- */
-public class ClassFileWriter {
-
- /**
- * Thrown for cases where the error in generating the class file is
- * due to a program size constraints rather than a likely bug in the
- * compiler.
- */
- public static class ClassFileFormatException extends RuntimeException {
- ClassFileFormatException(String message) {
- super(message);
- }
- }
-
- /**
- * Construct a ClassFileWriter for a class.
- *
- * @param className the name of the class to write, including
- * full package qualification.
- * @param superClassName the name of the superclass of the class
- * to write, including full package qualification.
- * @param sourceFileName the name of the source file to use for
- * producing debug information, or null if debug information
- * is not desired
- */
- public ClassFileWriter(String className, String superClassName,
- String sourceFileName)
- {
- generatedClassName = className;
- itsConstantPool = new ConstantPool(this);
- itsThisClassIndex = itsConstantPool.addClass(className);
- itsSuperClassIndex = itsConstantPool.addClass(superClassName);
- if (sourceFileName != null)
- itsSourceFileNameIndex = itsConstantPool.addUtf8(sourceFileName);
- itsFlags = ACC_PUBLIC;
- }
-
- public final String getClassName()
- {
- return generatedClassName;
- }
-
- /**
- * Add an interface implemented by this class.
- *
- * This method may be called multiple times for classes that
- * implement multiple interfaces.
- *
- * @param interfaceName a name of an interface implemented
- * by the class being written, including full package
- * qualification.
- */
- public void addInterface(String interfaceName) {
- short interfaceIndex = itsConstantPool.addClass(interfaceName);
- itsInterfaces.add(new Short(interfaceIndex));
- }
-
- public static final short
- ACC_PUBLIC = 0x0001,
- ACC_PRIVATE = 0x0002,
- ACC_PROTECTED = 0x0004,
- ACC_STATIC = 0x0008,
- ACC_FINAL = 0x0010,
- ACC_SYNCHRONIZED = 0x0020,
- ACC_VOLATILE = 0x0040,
- ACC_TRANSIENT = 0x0080,
- ACC_NATIVE = 0x0100,
- ACC_ABSTRACT = 0x0400;
-
- /**
- * Set the class's flags.
- *
- * Flags must be a set of the following flags, bitwise or'd
- * together:
- * ACC_PUBLIC
- * ACC_PRIVATE
- * ACC_PROTECTED
- * ACC_FINAL
- * ACC_ABSTRACT
- * TODO: check that this is the appropriate set
- * @param flags the set of class flags to set
- */
- public void setFlags(short flags) {
- itsFlags = flags;
- }
-
- static String getSlashedForm(String name)
- {
- return name.replace('.', '/');
- }
-
- /**
- * Convert Java class name in dot notation into
- * "Lname-with-dots-replaced-by-slashes;" form suitable for use as
- * JVM type signatures.
- */
- public static String classNameToSignature(String name)
- {
- int nameLength = name.length();
- int colonPos = 1 + nameLength;
- char[] buf = new char[colonPos + 1];
- buf[0] = 'L';
- buf[colonPos] = ';';
- name.getChars(0, nameLength, buf, 1);
- for (int i = 1; i != colonPos; ++i) {
- if (buf[i] == '.') {
- buf[i] = '/';
- }
- }
- return new String(buf, 0, colonPos + 1);
- }
-
- /**
- * Add a field to the class.
- *
- * @param fieldName the name of the field
- * @param type the type of the field using ...
- * @param flags the attributes of the field, such as ACC_PUBLIC, etc.
- * bitwise or'd together
- */
- public void addField(String fieldName, String type, short flags) {
- short fieldNameIndex = itsConstantPool.addUtf8(fieldName);
- short typeIndex = itsConstantPool.addUtf8(type);
- itsFields.add(new ClassFileField(fieldNameIndex, typeIndex, flags));
- }
-
- /**
- * Add a field to the class.
- *
- * @param fieldName the name of the field
- * @param type the type of the field using ...
- * @param flags the attributes of the field, such as ACC_PUBLIC, etc.
- * bitwise or'd together
- * @param value an initial integral value
- */
- public void addField(String fieldName, String type, short flags,
- int value)
- {
- short fieldNameIndex = itsConstantPool.addUtf8(fieldName);
- short typeIndex = itsConstantPool.addUtf8(type);
- ClassFileField field = new ClassFileField(fieldNameIndex, typeIndex,
- flags);
- field.setAttributes(itsConstantPool.addUtf8("ConstantValue"),
- (short)0,
- (short)0,
- itsConstantPool.addConstant(value));
- itsFields.add(field);
- }
-
- /**
- * Add a field to the class.
- *
- * @param fieldName the name of the field
- * @param type the type of the field using ...
- * @param flags the attributes of the field, such as ACC_PUBLIC, etc.
- * bitwise or'd together
- * @param value an initial long value
- */
- public void addField(String fieldName, String type, short flags,
- long value)
- {
- short fieldNameIndex = itsConstantPool.addUtf8(fieldName);
- short typeIndex = itsConstantPool.addUtf8(type);
- ClassFileField field = new ClassFileField(fieldNameIndex, typeIndex,
- flags);
- field.setAttributes(itsConstantPool.addUtf8("ConstantValue"),
- (short)0,
- (short)2,
- itsConstantPool.addConstant(value));
- itsFields.add(field);
- }
-
- /**
- * Add a field to the class.
- *
- * @param fieldName the name of the field
- * @param type the type of the field using ...
- * @param flags the attributes of the field, such as ACC_PUBLIC, etc.
- * bitwise or'd together
- * @param value an initial double value
- */
- public void addField(String fieldName, String type, short flags,
- double value)
- {
- short fieldNameIndex = itsConstantPool.addUtf8(fieldName);
- short typeIndex = itsConstantPool.addUtf8(type);
- ClassFileField field = new ClassFileField(fieldNameIndex, typeIndex,
- flags);
- field.setAttributes(itsConstantPool.addUtf8("ConstantValue"),
- (short)0,
- (short)2,
- itsConstantPool.addConstant(value));
- itsFields.add(field);
- }
-
- /**
- * Add Information about java variable to use when generating the local
- * variable table.
- *
- * @param name variable name.
- * @param type variable type as bytecode descriptor string.
- * @param startPC the starting bytecode PC where this variable is live,
- * or -1 if it does not have a Java register.
- * @param register the Java register number of variable
- * or -1 if it does not have a Java register.
- */
- public void addVariableDescriptor(String name, String type, int startPC, int register)
- {
- int nameIndex = itsConstantPool.addUtf8(name);
- int descriptorIndex = itsConstantPool.addUtf8(type);
- int [] chunk = { nameIndex, descriptorIndex, startPC, register };
- if (itsVarDescriptors == null) {
- itsVarDescriptors = new ObjArray();
- }
- itsVarDescriptors.add(chunk);
- }
-
- /**
- * Add a method and begin adding code.
- *
- * This method must be called before other methods for adding code,
- * exception tables, etc. can be invoked.
- *
- * @param methodName the name of the method
- * @param type a string representing the type
- * @param flags the attributes of the field, such as ACC_PUBLIC, etc.
- * bitwise or'd together
- */
- public void startMethod(String methodName, String type, short flags) {
- short methodNameIndex = itsConstantPool.addUtf8(methodName);
- short typeIndex = itsConstantPool.addUtf8(type);
- itsCurrentMethod = new ClassFileMethod(methodNameIndex, typeIndex,
- flags);
- itsMethods.add(itsCurrentMethod);
- }
-
- /**
- * Complete generation of the method.
- *
- * After this method is called, no more code can be added to the
- * method begun with <code>startMethod</code>.
- *
- * @param maxLocals the maximum number of local variable slots
- * (a.k.a. Java registers) used by the method
- */
- public void stopMethod(short maxLocals) {
- if (itsCurrentMethod == null)
- throw new IllegalStateException("No method to stop");
-
- fixLabelGotos();
-
- itsMaxLocals = maxLocals;
-
- int lineNumberTableLength = 0;
- if (itsLineNumberTable != null) {
- // 6 bytes for the attribute header
- // 2 bytes for the line number count
- // 4 bytes for each entry
- lineNumberTableLength = 6 + 2 + (itsLineNumberTableTop * 4);
- }
-
- int variableTableLength = 0;
- if (itsVarDescriptors != null) {
- // 6 bytes for the attribute header
- // 2 bytes for the variable count
- // 10 bytes for each entry
- variableTableLength = 6 + 2 + (itsVarDescriptors.size() * 10);
- }
-
- int attrLength = 2 + // attribute_name_index
- 4 + // attribute_length
- 2 + // max_stack
- 2 + // max_locals
- 4 + // code_length
- itsCodeBufferTop +
- 2 + // exception_table_length
- (itsExceptionTableTop * 8) +
- 2 + // attributes_count
- lineNumberTableLength +
- variableTableLength;
-
- if (attrLength > 65536) {
- // See http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html,
- // section 4.10, "The amount of code per non-native, non-abstract
- // method is limited to 65536 bytes...
- throw new ClassFileFormatException(
- "generated bytecode for method exceeds 64K limit.");
- }
- byte[] codeAttribute = new byte[attrLength];
- int index = 0;
- int codeAttrIndex = itsConstantPool.addUtf8("Code");
- index = putInt16(codeAttrIndex, codeAttribute, index);
- attrLength -= 6; // discount the attribute header
- index = putInt32(attrLength, codeAttribute, index);
- index = putInt16(itsMaxStack, codeAttribute, index);
- index = putInt16(itsMaxLocals, codeAttribute, index);
- index = putInt32(itsCodeBufferTop, codeAttribute, index);
- System.arraycopy(itsCodeBuffer, 0, codeAttribute, index,
- itsCodeBufferTop);
- index += itsCodeBufferTop;
-
- if (itsExceptionTableTop > 0) {
- index = putInt16(itsExceptionTableTop, codeAttribute, index);
- for (int i = 0; i < itsExceptionTableTop; i++) {
- ExceptionTableEntry ete = itsExceptionTable[i];
- short startPC = (short)getLabelPC(ete.itsStartLabel);
- short endPC = (short)getLabelPC(ete.itsEndLabel);
- short handlerPC = (short)getLabelPC(ete.itsHandlerLabel);
- short catchType = ete.itsCatchType;
- if (startPC == -1)
- throw new IllegalStateException("start label not defined");
- if (endPC == -1)
- throw new IllegalStateException("end label not defined");
- if (handlerPC == -1)
- throw new IllegalStateException(
- "handler label not defined");
-
- index = putInt16(startPC, codeAttribute, index);
- index = putInt16(endPC, codeAttribute, index);
- index = putInt16(handlerPC, codeAttribute, index);
- index = putInt16(catchType, codeAttribute, index);
- }
- }
- else {
- // write 0 as exception table length
- index = putInt16(0, codeAttribute, index);
- }
-
- int attributeCount = 0;
- if (itsLineNumberTable != null)
- attributeCount++;
- if (itsVarDescriptors != null)
- attributeCount++;
- index = putInt16(attributeCount, codeAttribute, index);
-
- if (itsLineNumberTable != null) {
- int lineNumberTableAttrIndex
- = itsConstantPool.addUtf8("LineNumberTable");
- index = putInt16(lineNumberTableAttrIndex, codeAttribute, index);
- int tableAttrLength = 2 + (itsLineNumberTableTop * 4);
- index = putInt32(tableAttrLength, codeAttribute, index);
- index = putInt16(itsLineNumberTableTop, codeAttribute, index);
- for (int i = 0; i < itsLineNumberTableTop; i++) {
- index = putInt32(itsLineNumberTable[i], codeAttribute, index);
- }
- }
-
- if (itsVarDescriptors != null) {
- int variableTableAttrIndex
- = itsConstantPool.addUtf8("LocalVariableTable");
- index = putInt16(variableTableAttrIndex, codeAttribute, index);
- int varCount = itsVarDescriptors.size();
- int tableAttrLength = 2 + (varCount * 10);
- index = putInt32(tableAttrLength, codeAttribute, index);
- index = putInt16(varCount, codeAttribute, index);
- for (int i = 0; i < varCount; i++) {
- int[] chunk = (int[])itsVarDescriptors.get(i);
- int nameIndex = chunk[0];
- int descriptorIndex = chunk[1];
- int startPC = chunk[2];
- int register = chunk[3];
- int length = itsCodeBufferTop - startPC;
-
- index = putInt16(startPC, codeAttribute, index);
- index = putInt16(length, codeAttribute, index);
- index = putInt16(nameIndex, codeAttribute, index);
- index = putInt16(descriptorIndex, codeAttribute, index);
- index = putInt16(register, codeAttribute, index);
- }
- }
-
- itsCurrentMethod.setCodeAttribute(codeAttribute);
-
- itsExceptionTable = null;
- itsExceptionTableTop = 0;
- itsLineNumberTableTop = 0;
- itsCodeBufferTop = 0;
- itsCurrentMethod = null;
- itsMaxStack = 0;
- itsStackTop = 0;
- itsLabelTableTop = 0;
- itsFixupTableTop = 0;
- itsVarDescriptors = null;
- }
-
- /**
- * Add the single-byte opcode to the current method.
- *
- * @param theOpCode the opcode of the bytecode
- */
- public void add(int theOpCode) {
- if (opcodeCount(theOpCode) != 0)
- throw new IllegalArgumentException("Unexpected operands");
- int newStack = itsStackTop + stackChange(theOpCode);
- if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
- if (DEBUGCODE)
- System.out.println("Add " + bytecodeStr(theOpCode));
- addToCodeBuffer(theOpCode);
- itsStackTop = (short)newStack;
- if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
- if (DEBUGSTACK) {
- System.out.println("After "+bytecodeStr(theOpCode)
- +" stack = "+itsStackTop);
- }
- }
-
- /**
- * Add a single-operand opcode to the current method.
- *
- * @param theOpCode the opcode of the bytecode
- * @param theOperand the operand of the bytecode
- */
- public void add(int theOpCode, int theOperand) {
- if (DEBUGCODE) {
- System.out.println("Add "+bytecodeStr(theOpCode)
- +", "+Integer.toHexString(theOperand));
- }
- int newStack = itsStackTop + stackChange(theOpCode);
- if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
-
- switch (theOpCode) {
- case ByteCode.GOTO :
- // fallthru...
- case ByteCode.IFEQ :
- case ByteCode.IFNE :
- case ByteCode.IFLT :
- case ByteCode.IFGE :
- case ByteCode.IFGT :
- case ByteCode.IFLE :
- case ByteCode.IF_ICMPEQ :
- case ByteCode.IF_ICMPNE :
- case ByteCode.IF_ICMPLT :
- case ByteCode.IF_ICMPGE :
- case ByteCode.IF_ICMPGT :
- case ByteCode.IF_ICMPLE :
- case ByteCode.IF_ACMPEQ :
- case ByteCode.IF_ACMPNE :
- case ByteCode.JSR :
- case ByteCode.IFNULL :
- case ByteCode.IFNONNULL : {
- if ((theOperand & 0x80000000) != 0x80000000) {
- if ((theOperand < 0) || (theOperand > 65535))
- throw new IllegalArgumentException(
- "Bad label for branch");
- }
- int branchPC = itsCodeBufferTop;
- addToCodeBuffer(theOpCode);
- if ((theOperand & 0x80000000) != 0x80000000) {
- // hard displacement
- addToCodeInt16(theOperand);
- }
- else { // a label
- int targetPC = getLabelPC(theOperand);
- if (DEBUGLABELS) {
- int theLabel = theOperand & 0x7FFFFFFF;
- System.out.println("Fixing branch to " +
- theLabel + " at " + targetPC +
- " from " + branchPC);
- }
- if (targetPC != -1) {
- int offset = targetPC - branchPC;
- addToCodeInt16(offset);
- }
- else {
- addLabelFixup(theOperand, branchPC + 1);
- addToCodeInt16(0);
- }
- }
- }
- break;
-
- case ByteCode.BIPUSH :
- if ((byte)theOperand != theOperand)
- throw new IllegalArgumentException("out of range byte");
- addToCodeBuffer(theOpCode);
- addToCodeBuffer((byte)theOperand);
- break;
-
- case ByteCode.SIPUSH :
- if ((short)theOperand != theOperand)
- throw new IllegalArgumentException("out of range short");
- addToCodeBuffer(theOpCode);
- addToCodeInt16(theOperand);
- break;
-
- case ByteCode.NEWARRAY :
- if (!(0 <= theOperand && theOperand < 256))
- throw new IllegalArgumentException("out of range index");
- addToCodeBuffer(theOpCode);
- addToCodeBuffer(theOperand);
- break;
-
- case ByteCode.GETFIELD :
- case ByteCode.PUTFIELD :
- if (!(0 <= theOperand && theOperand < 65536))
- throw new IllegalArgumentException("out of range field");
- addToCodeBuffer(theOpCode);
- addToCodeInt16(theOperand);
- break;
-
- case ByteCode.LDC :
- case ByteCode.LDC_W :
- case ByteCode.LDC2_W :
- if (!(0 <= theOperand && theOperand < 65536))
- throw new IllegalArgumentException("out of range index");
- if (theOperand >= 256
- || theOpCode == ByteCode.LDC_W
- || theOpCode == ByteCode.LDC2_W)
- {
- if (theOpCode == ByteCode.LDC) {
- addToCodeBuffer(ByteCode.LDC_W);
- } else {
- addToCodeBuffer(theOpCode);
- }
- addToCodeInt16(theOperand);
- } else {
- addToCodeBuffer(theOpCode);
- addToCodeBuffer(theOperand);
- }
- break;
-
- case ByteCode.RET :
- case ByteCode.ILOAD :
- case ByteCode.LLOAD :
- case ByteCode.FLOAD :
- case ByteCode.DLOAD :
- case ByteCode.ALOAD :
- case ByteCode.ISTORE :
- case ByteCode.LSTORE :
- case ByteCode.FSTORE :
- case ByteCode.DSTORE :
- case ByteCode.ASTORE :
- if (!(0 <= theOperand && theOperand < 65536))
- throw new ClassFileFormatException("out of range variable");
- if (theOperand >= 256) {
- addToCodeBuffer(ByteCode.WIDE);
- addToCodeBuffer(theOpCode);
- addToCodeInt16(theOperand);
- }
- else {
- addToCodeBuffer(theOpCode);
- addToCodeBuffer(theOperand);
- }
- break;
-
- default :
- throw new IllegalArgumentException(
- "Unexpected opcode for 1 operand");
- }
-
- itsStackTop = (short)newStack;
- if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
- if (DEBUGSTACK) {
- System.out.println("After "+bytecodeStr(theOpCode)
- +" stack = "+itsStackTop);
- }
- }
-
- /**
- * Generate the load constant bytecode for the given integer.
- *
- * @param k the constant
- */
- public void addLoadConstant(int k) {
- switch (k) {
- case 0: add(ByteCode.ICONST_0); break;
- case 1: add(ByteCode.ICONST_1); break;
- case 2: add(ByteCode.ICONST_2); break;
- case 3: add(ByteCode.ICONST_3); break;
- case 4: add(ByteCode.ICONST_4); break;
- case 5: add(ByteCode.ICONST_5); break;
- default:
- add(ByteCode.LDC, itsConstantPool.addConstant(k));
- break;
- }
- }
-
- /**
- * Generate the load constant bytecode for the given long.
- *
- * @param k the constant
- */
- public void addLoadConstant(long k) {
- add(ByteCode.LDC2_W, itsConstantPool.addConstant(k));
- }
-
- /**
- * Generate the load constant bytecode for the given float.
- *
- * @param k the constant
- */
- public void addLoadConstant(float k) {
- add(ByteCode.LDC, itsConstantPool.addConstant(k));
- }
-
- /**
- * Generate the load constant bytecode for the given double.
- *
- * @param k the constant
- */
- public void addLoadConstant(double k) {
- add(ByteCode.LDC2_W, itsConstantPool.addConstant(k));
- }
-
- /**
- * Generate the load constant bytecode for the given string.
- *
- * @param k the constant
- */
- public void addLoadConstant(String k) {
- add(ByteCode.LDC, itsConstantPool.addConstant(k));
- }
-
- /**
- * Add the given two-operand bytecode to the current method.
- *
- * @param theOpCode the opcode of the bytecode
- * @param theOperand1 the first operand of the bytecode
- * @param theOperand2 the second operand of the bytecode
- */
- public void add(int theOpCode, int theOperand1, int theOperand2) {
- if (DEBUGCODE) {
- System.out.println("Add "+bytecodeStr(theOpCode)
- +", "+Integer.toHexString(theOperand1)
- +", "+Integer.toHexString(theOperand2));
- }
- int newStack = itsStackTop + stackChange(theOpCode);
- if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
-
- if (theOpCode == ByteCode.IINC) {
- if (!(0 <= theOperand1 && theOperand1 < 65536))
- throw new ClassFileFormatException("out of range variable");
- if (!(0 <= theOperand2 && theOperand2 < 65536))
- throw new ClassFileFormatException("out of range increment");
-
- if (theOperand1 > 255 || theOperand2 < -128 || theOperand2 > 127) {
- addToCodeBuffer(ByteCode.WIDE);
- addToCodeBuffer(ByteCode.IINC);
- addToCodeInt16(theOperand1);
- addToCodeInt16(theOperand2);
- }
- else {
- addToCodeBuffer(ByteCode.WIDE);
- addToCodeBuffer(ByteCode.IINC);
- addToCodeBuffer(theOperand1);
- addToCodeBuffer(theOperand2);
- }
- }
- else if (theOpCode == ByteCode.MULTIANEWARRAY) {
- if (!(0 <= theOperand1 && theOperand1 < 65536))
- throw new IllegalArgumentException("out of range index");
- if (!(0 <= theOperand2 && theOperand2 < 256))
- throw new IllegalArgumentException("out of range dimensions");
-
- addToCodeBuffer(ByteCode.MULTIANEWARRAY);
- addToCodeInt16(theOperand1);
- addToCodeBuffer(theOperand2);
- }
- else {
- throw new IllegalArgumentException(
- "Unexpected opcode for 2 operands");
- }
- itsStackTop = (short)newStack;
- if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
- if (DEBUGSTACK) {
- System.out.println("After "+bytecodeStr(theOpCode)
- +" stack = "+itsStackTop);
- }
-
- }
-
- public void add(int theOpCode, String className) {
- if (DEBUGCODE) {
- System.out.println("Add "+bytecodeStr(theOpCode)
- +", "+className);
- }
- int newStack = itsStackTop + stackChange(theOpCode);
- if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
- switch (theOpCode) {
- case ByteCode.NEW :
- case ByteCode.ANEWARRAY :
- case ByteCode.CHECKCAST :
- case ByteCode.INSTANCEOF : {
- short classIndex = itsConstantPool.addClass(className);
- addToCodeBuffer(theOpCode);
- addToCodeInt16(classIndex);
- }
- break;
-
- default :
- throw new IllegalArgumentException(
- "bad opcode for class reference");
- }
- itsStackTop = (short)newStack;
- if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
- if (DEBUGSTACK) {
- System.out.println("After "+bytecodeStr(theOpCode)
- +" stack = "+itsStackTop);
- }
- }
-
-
- public void add(int theOpCode, String className, String fieldName,
- String fieldType)
- {
- if (DEBUGCODE) {
- System.out.println("Add "+bytecodeStr(theOpCode)
- +", "+className+", "+fieldName+", "+fieldType);
- }
- int newStack = itsStackTop + stackChange(theOpCode);
- char fieldTypeChar = fieldType.charAt(0);
- int fieldSize = (fieldTypeChar == 'J' || fieldTypeChar == 'D')
- ? 2 : 1;
- switch (theOpCode) {
- case ByteCode.GETFIELD :
- case ByteCode.GETSTATIC :
- newStack += fieldSize;
- break;
- case ByteCode.PUTSTATIC :
- case ByteCode.PUTFIELD :
- newStack -= fieldSize;
- break;
- default :
- throw new IllegalArgumentException(
- "bad opcode for field reference");
- }
- if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
- short fieldRefIndex = itsConstantPool.addFieldRef(className,
- fieldName, fieldType);
- addToCodeBuffer(theOpCode);
- addToCodeInt16(fieldRefIndex);
-
- itsStackTop = (short)newStack;
- if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
- if (DEBUGSTACK) {
- System.out.println("After "+bytecodeStr(theOpCode)
- +" stack = "+itsStackTop);
- }
- }
-
- public void addInvoke(int theOpCode, String className, String methodName,
- String methodType)
- {
- if (DEBUGCODE) {
- System.out.println("Add "+bytecodeStr(theOpCode)
- +", "+className+", "+methodName+", "
- +methodType);
- }
- int parameterInfo = sizeOfParameters(methodType);
- int parameterCount = parameterInfo >>> 16;
- int stackDiff = (short)parameterInfo;
-
- int newStack = itsStackTop + stackDiff;
- newStack += stackChange(theOpCode); // adjusts for 'this'
- if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
-
- switch (theOpCode) {
- case ByteCode.INVOKEVIRTUAL :
- case ByteCode.INVOKESPECIAL :
- case ByteCode.INVOKESTATIC :
- case ByteCode.INVOKEINTERFACE : {
- addToCodeBuffer(theOpCode);
- if (theOpCode == ByteCode.INVOKEINTERFACE) {
- short ifMethodRefIndex
- = itsConstantPool.addInterfaceMethodRef(
- className, methodName,
- methodType);
- addToCodeInt16(ifMethodRefIndex);
- addToCodeBuffer(parameterCount + 1);
- addToCodeBuffer(0);
- }
- else {
- short methodRefIndex = itsConstantPool.addMethodRef(
- className, methodName,
- methodType);
- addToCodeInt16(methodRefIndex);
- }
- }
- break;
-
- default :
- throw new IllegalArgumentException(
- "bad opcode for method reference");
- }
- itsStackTop = (short)newStack;
- if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
- if (DEBUGSTACK) {
- System.out.println("After "+bytecodeStr(theOpCode)
- +" stack = "+itsStackTop);
- }
- }
-
- /**
- * Generate code to load the given integer on stack.
- *
- * @param k the constant
- */
- public void addPush(int k)
- {
- if ((byte)k == k) {
- if (k == -1) {
- add(ByteCode.ICONST_M1);
- } else if (0 <= k && k <= 5) {
- add((byte)(ByteCode.ICONST_0 + k));
- } else {
- add(ByteCode.BIPUSH, (byte)k);
- }
- } else if ((short)k == k) {
- add(ByteCode.SIPUSH, (short)k);
- } else {
- addLoadConstant(k);
- }
- }
-
- public void addPush(boolean k)
- {
- add(k ? ByteCode.ICONST_1 : ByteCode.ICONST_0);
- }
-
- /**
- * Generate code to load the given long on stack.
- *
- * @param k the constant
- */
- public void addPush(long k)
- {
- int ik = (int)k;
- if (ik == k) {
- addPush(ik);
- add(ByteCode.I2L);
- } else {
- addLoadConstant(k);
- }
- }
-
- /**
- * Generate code to load the given double on stack.
- *
- * @param k the constant
- */
- public void addPush(double k)
- {
- if (k == 0.0) {
- // zero
- add(ByteCode.DCONST_0);
- if (1.0 / k < 0) {
- // Negative zero
- add(ByteCode.DNEG);
- }
- } else if (k == 1.0 || k == -1.0) {
- add(ByteCode.DCONST_1);
- if (k < 0) {
- add(ByteCode.DNEG);
- }
- } else {
- addLoadConstant(k);
- }
- }
-
- /**
- * Generate the code to leave on stack the given string even if the
- * string encoding exeeds the class file limit for single string constant
- *
- * @param k the constant
- */
- public void addPush(String k) {
- int length = k.length();
- int limit = itsConstantPool.getUtfEncodingLimit(k, 0, length);
- if (limit == length) {
- addLoadConstant(k);
- return;
- }
- // Split string into picies fitting the UTF limit and generate code for
- // StringBuffer sb = new StringBuffer(length);
- // sb.append(loadConstant(piece_1));
- // ...
- // sb.append(loadConstant(piece_N));
- // sb.toString();
- final String SB = "java/lang/StringBuffer";
- add(ByteCode.NEW, SB);
- add(ByteCode.DUP);
- addPush(length);
- addInvoke(ByteCode.INVOKESPECIAL, SB, "<init>", "(I)V");
- int cursor = 0;
- for (;;) {
- add(ByteCode.DUP);
- String s = k.substring(cursor, limit);
- addLoadConstant(s);
- addInvoke(ByteCode.INVOKEVIRTUAL, SB, "append",
- "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
- add(ByteCode.POP);
- if (limit == length) {
- break;
- }
- cursor = limit;
- limit = itsConstantPool.getUtfEncodingLimit(k, limit, length);
- }
- addInvoke(ByteCode.INVOKEVIRTUAL, SB, "toString",
- "()Ljava/lang/String;");
- }
-
- /**
- * Check if k fits limit on string constant size imposed by class file
- * format.
- *
- * @param k the string constant
- */
- public boolean isUnderStringSizeLimit(String k)
- {
- return itsConstantPool.isUnderUtfEncodingLimit(k);
- }
-
- /**
- * Store integer from stack top into the given local.
- *
- * @param local number of local register
- */
- public void addIStore(int local)
- {
- xop(ByteCode.ISTORE_0, ByteCode.ISTORE, local);
- }
-
- /**
- * Store long from stack top into the given local.
- *
- * @param local number of local register
- */
- public void addLStore(int local)
- {
- xop(ByteCode.LSTORE_0, ByteCode.LSTORE, local);
- }
-
- /**
- * Store float from stack top into the given local.
- *
- * @param local number of local register
- */
- public void addFStore(int local)
- {
- xop(ByteCode.FSTORE_0, ByteCode.FSTORE, local);
- }
-
- /**
- * Store double from stack top into the given local.
- *
- * @param local number of local register
- */
- public void addDStore(int local)
- {
- xop(ByteCode.DSTORE_0, ByteCode.DSTORE, local);
- }
-
- /**
- * Store object from stack top into the given local.
- *
- * @param local number of local register
- */
- public void addAStore(int local)
- {
- xop(ByteCode.ASTORE_0, ByteCode.ASTORE, local);
- }
-
- /**
- * Load integer from the given local into stack.
- *
- * @param local number of local register
- */
- public void addILoad(int local)
- {
- xop(ByteCode.ILOAD_0, ByteCode.ILOAD, local);
- }
-
- /**
- * Load long from the given local into stack.
- *
- * @param local number of local register
- */
- public void addLLoad(int local)
- {
- xop(ByteCode.LLOAD_0, ByteCode.LLOAD, local);
- }
-
- /**
- * Load float from the given local into stack.
- *
- * @param local number of local register
- */
- public void addFLoad(int local)
- {
- xop(ByteCode.FLOAD_0, ByteCode.FLOAD, local);
- }
-
- /**
- * Load double from the given local into stack.
- *
- * @param local number of local register
- */
- public void addDLoad(int local)
- {
- xop(ByteCode.DLOAD_0, ByteCode.DLOAD, local);
- }
-
- /**
- * Load object from the given local into stack.
- *
- * @param local number of local register
- */
- public void addALoad(int local)
- {
- xop(ByteCode.ALOAD_0, ByteCode.ALOAD, local);
- }
-
- /**
- * Load "this" into stack.
- */
- public void addLoadThis()
- {
- add(ByteCode.ALOAD_0);
- }
-
- private void xop(int shortOp, int op, int local)
- {
- switch (local) {
- case 0:
- add(shortOp);
- break;
- case 1:
- add(shortOp + 1);
- break;
- case 2:
- add(shortOp + 2);
- break;
- case 3:
- add(shortOp + 3);
- break;
- default:
- add(op, local);
- }
- }
-
- public int addTableSwitch(int low, int high)
- {
- if (DEBUGCODE) {
- System.out.println("Add "+bytecodeStr(ByteCode.TABLESWITCH)
- +" "+low+" "+high);
- }
- if (low > high)
- throw new ClassFileFormatException("Bad bounds: "+low+' '+ high);
-
- int newStack = itsStackTop + stackChange(ByteCode.TABLESWITCH);
- if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
-
- int entryCount = high - low + 1;
- int padSize = 3 & ~itsCodeBufferTop; // == 3 - itsCodeBufferTop % 4
-
- int N = addReservedCodeSpace(1 + padSize + 4 * (1 + 2 + entryCount));
- int switchStart = N;
- itsCodeBuffer[N++] = (byte)ByteCode.TABLESWITCH;
- while (padSize != 0) {
- itsCodeBuffer[N++] = 0;
- --padSize;
- }
- N += 4; // skip default offset
- N = putInt32(low, itsCodeBuffer, N);
- putInt32(high, itsCodeBuffer, N);
-
- itsStackTop = (short)newStack;
- if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
- if (DEBUGSTACK) {
- System.out.println("After "+bytecodeStr(ByteCode.TABLESWITCH)
- +" stack = "+itsStackTop);
- }
-
- return switchStart;
- }
-
- public final void markTableSwitchDefault(int switchStart)
- {
- setTableSwitchJump(switchStart, -1, itsCodeBufferTop);
- }
-
- public final void markTableSwitchCase(int switchStart, int caseIndex)
- {
- setTableSwitchJump(switchStart, caseIndex, itsCodeBufferTop);
- }
-
- public final void markTableSwitchCase(int switchStart, int caseIndex,
- int stackTop)
- {
- if (!(0 <= stackTop && stackTop <= itsMaxStack))
- throw new IllegalArgumentException("Bad stack index: "+stackTop);
- itsStackTop = (short)stackTop;
- setTableSwitchJump(switchStart, caseIndex, itsCodeBufferTop);
- }
-
- public void setTableSwitchJump(int switchStart, int caseIndex,
- int jumpTarget)
- {
- if (!(0 <= jumpTarget && jumpTarget <= itsCodeBufferTop))
- throw new IllegalArgumentException("Bad jump target: "+jumpTarget);
- if (!(caseIndex >= -1))
- throw new IllegalArgumentException("Bad case index: "+caseIndex);
-
- int padSize = 3 & ~switchStart; // == 3 - switchStart % 4
- int caseOffset;
- if (caseIndex < 0) {
- // default label
- caseOffset = switchStart + 1 + padSize;
- } else {
- caseOffset = switchStart + 1 + padSize + 4 * (3 + caseIndex);
- }
- if (!(0 <= switchStart
- && switchStart <= itsCodeBufferTop - 4 * 4 - padSize - 1))
- {
- throw new IllegalArgumentException(
- switchStart+" is outside a possible range of tableswitch"
- +" in already generated code");
- }
- if ((0xFF & itsCodeBuffer[switchStart]) != ByteCode.TABLESWITCH) {
- throw new IllegalArgumentException(
- switchStart+" is not offset of tableswitch statement");
- }
- if (!(0 <= caseOffset && caseOffset + 4 <= itsCodeBufferTop)) {
- // caseIndex >= -1 does not guarantee that caseOffset >= 0 due
- // to a possible overflow.
- throw new ClassFileFormatException(
- "Too big case index: "+caseIndex);
- }
- // ALERT: perhaps check against case bounds?
- putInt32(jumpTarget - switchStart, itsCodeBuffer, caseOffset);
- }
-
- public int acquireLabel()
- {
- int top = itsLabelTableTop;
- if (itsLabelTable == null || top == itsLabelTable.length) {
- if (itsLabelTable == null) {
- itsLabelTable = new int[MIN_LABEL_TABLE_SIZE];
- }else {
- int[] tmp = new int[itsLabelTable.length * 2];
- System.arraycopy(itsLabelTable, 0, tmp, 0, top);
- itsLabelTable = tmp;
- }
- }
- itsLabelTableTop = top + 1;
- itsLabelTable[top] = -1;
- return top | 0x80000000;
- }
-
- public void markLabel(int label)
- {
- if (!(label < 0))
- throw new IllegalArgumentException("Bad label, no biscuit");
-
- label &= 0x7FFFFFFF;
- if (label > itsLabelTableTop)
- throw new IllegalArgumentException("Bad label");
-
- if (itsLabelTable[label] != -1) {
- throw new IllegalStateException("Can only mark label once");
- }
-
- itsLabelTable[label] = itsCodeBufferTop;
- }
-
- public void markLabel(int label, short stackTop)
- {
- markLabel(label);
- itsStackTop = stackTop;
- }
-
- public void markHandler(int theLabel) {
- itsStackTop = 1;
- markLabel(theLabel);
- }
-
- private int getLabelPC(int label)
- {
- if (!(label < 0))
- throw new IllegalArgumentException("Bad label, no biscuit");
- label &= 0x7FFFFFFF;
- if (!(label < itsLabelTableTop))
- throw new IllegalArgumentException("Bad label");
- return itsLabelTable[label];
- }
-
- private void addLabelFixup(int label, int fixupSite)
- {
- if (!(label < 0))
- throw new IllegalArgumentException("Bad label, no biscuit");
- label &= 0x7FFFFFFF;
- if (!(label < itsLabelTableTop))
- throw new IllegalArgumentException("Bad label");
- int top = itsFixupTableTop;
- if (itsFixupTable == null || top == itsFixupTable.length) {
- if (itsFixupTable == null) {
- itsFixupTable = new long[MIN_FIXUP_TABLE_SIZE];
- }else {
- long[] tmp = new long[itsFixupTable.length * 2];
- System.arraycopy(itsFixupTable, 0, tmp, 0, top);
- itsFixupTable = tmp;
- }
- }
- itsFixupTableTop = top + 1;
- itsFixupTable[top] = ((long)label << 32) | fixupSite;
- }
-
- private void fixLabelGotos()
- {
- byte[] codeBuffer = itsCodeBuffer;
- for (int i = 0; i < itsFixupTableTop; i++) {
- long fixup = itsFixupTable[i];
- int label = (int)(fixup >> 32);
- int fixupSite = (int)fixup;
- int pc = itsLabelTable[label];
- if (pc == -1) {
- // Unlocated label
- throw new RuntimeException();
- }
- // -1 to get delta from instruction start
- int offset = pc - (fixupSite - 1);
- if ((short)offset != offset) {
- throw new ClassFileFormatException
- ("Program too complex: too big jump offset");
- }
- codeBuffer[fixupSite] = (byte)(offset >> 8);
- codeBuffer[fixupSite + 1] = (byte)offset;
- }
- itsFixupTableTop = 0;
- }
-
- /**
- * Get the current offset into the code of the current method.
- *
- * @return an integer representing the offset
- */
- public int getCurrentCodeOffset() {
- return itsCodeBufferTop;
- }
-
- public short getStackTop() {
- return itsStackTop;
- }
-
- public void setStackTop(short n) {
- itsStackTop = n;
- }
-
- public void adjustStackTop(int delta) {
- int newStack = itsStackTop + delta;
- if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
- itsStackTop = (short)newStack;
- if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
- if (DEBUGSTACK) {
- System.out.println("After "+"adjustStackTop("+delta+")"
- +" stack = "+itsStackTop);
- }
- }
-
- private void addToCodeBuffer(int b)
- {
- int N = addReservedCodeSpace(1);
- itsCodeBuffer[N] = (byte)b;
- }
-
- private void addToCodeInt16(int value)
- {
- int N = addReservedCodeSpace(2);
- putInt16(value, itsCodeBuffer, N);
- }
-
- private int addReservedCodeSpace(int size)
- {
- if (itsCurrentMethod == null)
- throw new IllegalArgumentException("No method to add to");
- int oldTop = itsCodeBufferTop;
- int newTop = oldTop + size;
- if (newTop > itsCodeBuffer.length) {
- int newSize = itsCodeBuffer.length * 2;
- if (newTop > newSize) { newSize = newTop; }
- byte[] tmp = new byte[newSize];
- System.arraycopy(itsCodeBuffer, 0, tmp, 0, oldTop);
- itsCodeBuffer = tmp;
- }
- itsCodeBufferTop = newTop;
- return oldTop;
- }
-
- public void addExceptionHandler(int startLabel, int endLabel,
- int handlerLabel, String catchClassName)
- {
- if ((startLabel & 0x80000000) != 0x80000000)
- throw new IllegalArgumentException("Bad startLabel");
- if ((endLabel & 0x80000000) != 0x80000000)
- throw new IllegalArgumentException("Bad endLabel");
- if ((handlerLabel & 0x80000000) != 0x80000000)
- throw new IllegalArgumentException("Bad handlerLabel");
-
- /*
- * If catchClassName is null, use 0 for the catch_type_index; which
- * means catch everything. (Even when the verifier has let you throw
- * something other than a Throwable.)
- */
- short catch_type_index = (catchClassName == null)
- ? 0
- : itsConstantPool.addClass(catchClassName);
- ExceptionTableEntry newEntry = new ExceptionTableEntry(
- startLabel,
- endLabel,
- handlerLabel,
- catch_type_index);
- int N = itsExceptionTableTop;
- if (N == 0) {
- itsExceptionTable = new ExceptionTableEntry[ExceptionTableSize];
- } else if (N == itsExceptionTable.length) {
- ExceptionTableEntry[] tmp = new ExceptionTableEntry[N * 2];
- System.arraycopy(itsExceptionTable, 0, tmp, 0, N);
- itsExceptionTable = tmp;
- }
- itsExceptionTable[N] = newEntry;
- itsExceptionTableTop = N + 1;
-
- }
-
- public void addLineNumberEntry(short lineNumber) {
- if (itsCurrentMethod == null)
- throw new IllegalArgumentException("No method to stop");
- int N = itsLineNumberTableTop;
- if (N == 0) {
- itsLineNumberTable = new int[LineNumberTableSize];
- } else if (N == itsLineNumberTable.length) {
- int[] tmp = new int[N * 2];
- System.arraycopy(itsLineNumberTable, 0, tmp, 0, N);
- itsLineNumberTable = tmp;
- }
- itsLineNumberTable[N] = (itsCodeBufferTop << 16) + lineNumber;
- itsLineNumberTableTop = N + 1;
- }
-
- /**
- * Write the class file to the OutputStream.
- *
- * @param oStream the stream to write to
- * @throws IOException if writing to the stream produces an exception
- */
- public void write(OutputStream oStream)
- throws IOException
- {
- byte[] array = toByteArray();
- oStream.write(array);
- }
-
- private int getWriteSize()
- {
- int size = 0;
-
- if (itsSourceFileNameIndex != 0) {
- itsConstantPool.addUtf8("SourceFile");
- }
-
- size += 8; //writeLong(FileHeaderConstant);
- size += itsConstantPool.getWriteSize();
- size += 2; //writeShort(itsFlags);
- size += 2; //writeShort(itsThisClassIndex);
- size += 2; //writeShort(itsSuperClassIndex);
- size += 2; //writeShort(itsInterfaces.size());
- size += 2 * itsInterfaces.size();
-
- size += 2; //writeShort(itsFields.size());
- for (int i = 0; i < itsFields.size(); i++) {
- size += ((ClassFileField)(itsFields.get(i))).getWriteSize();
- }
-
- size += 2; //writeShort(itsMethods.size());
- for (int i = 0; i < itsMethods.size(); i++) {
- size += ((ClassFileMethod)(itsMethods.get(i))).getWriteSize();
- }
-
- if (itsSourceFileNameIndex != 0) {
- size += 2; //writeShort(1); attributes count
- size += 2; //writeShort(sourceFileAttributeNameIndex);
- size += 4; //writeInt(2);
- size += 2; //writeShort(itsSourceFileNameIndex);
- }else {
- size += 2; //out.writeShort(0); no attributes
- }
-
- return size;
- }
-
- /**
- * Get the class file as array of bytesto the OutputStream.
- */
- public byte[] toByteArray()
- {
- int dataSize = getWriteSize();
- byte[] data = new byte[dataSize];
- int offset = 0;
-
- short sourceFileAttributeNameIndex = 0;
- if (itsSourceFileNameIndex != 0) {
- sourceFileAttributeNameIndex = itsConstantPool.addUtf8(
- "SourceFile");
- }
-
- offset = putInt64(FileHeaderConstant, data, offset);
- offset = itsConstantPool.write(data, offset);
- offset = putInt16(itsFlags, data, offset);
- offset = putInt16(itsThisClassIndex, data, offset);
- offset = putInt16(itsSuperClassIndex, data, offset);
- offset = putInt16(itsInterfaces.size(), data, offset);
- for (int i = 0; i < itsInterfaces.size(); i++) {
- int interfaceIndex = ((Short)(itsInterfaces.get(i))).shortValue();
- offset = putInt16(interfaceIndex, data, offset);
- }
- offset = putInt16(itsFields.size(), data, offset);
- for (int i = 0; i < itsFields.size(); i++) {
- ClassFileField field = (ClassFileField)itsFields.get(i);
- offset = field.write(data, offset);
- }
- offset = putInt16(itsMethods.size(), data, offset);
- for (int i = 0; i < itsMethods.size(); i++) {
- ClassFileMethod method = (ClassFileMethod)itsMethods.get(i);
- offset = method.write(data, offset);
- }
- if (itsSourceFileNameIndex != 0) {
- offset = putInt16(1, data, offset); // attributes count
- offset = putInt16(sourceFileAttributeNameIndex, data, offset);
- offset = putInt32(2, data, offset);
- offset = putInt16(itsSourceFileNameIndex, data, offset);
- } else {
- offset = putInt16(0, data, offset); // no attributes
- }
-
- if (offset != dataSize) {
- // Check getWriteSize is consistent with write!
- throw new RuntimeException();
- }
-
- return data;
- }
-
- static int putInt64(long value, byte[] array, int offset)
- {
- offset = putInt32((int)(value >>> 32), array, offset);
- return putInt32((int)value, array, offset);
- }
-
- private static void badStack(int value)
- {
- String s;
- if (value < 0) { s = "Stack underflow: "+value; }
- else { s = "Too big stack: "+value; }
- throw new IllegalStateException(s);
- }
-
- /*
- Really weird. Returns an int with # parameters in hi 16 bits, and
- stack difference removal of parameters from stack and pushing the
- result (it does not take into account removal of this in case of
- non-static methods).
- If Java really supported references we wouldn't have to be this
- perverted.
- */
- private static int sizeOfParameters(String pString)
- {
- int length = pString.length();
- int rightParenthesis = pString.lastIndexOf(')');
- if (3 <= length /* minimal signature takes at least 3 chars: ()V */
- && pString.charAt(0) == '('
- && 1 <= rightParenthesis && rightParenthesis + 1 < length)
- {
- boolean ok = true;
- int index = 1;
- int stackDiff = 0;
- int count = 0;
- stringLoop:
- while (index != rightParenthesis) {
- switch (pString.charAt(index)) {
- default:
- ok = false;
- break stringLoop;
- case 'J' :
- case 'D' :
- --stackDiff;
- // fall thru
- case 'B' :
- case 'S' :
- case 'C' :
- case 'I' :
- case 'Z' :
- case 'F' :
- --stackDiff;
- ++count;
- ++index;
- continue;
- case '[' :
- ++index;
- int c = pString.charAt(index);
- while (c == '[') {
- ++index;
- c = pString.charAt(index);
- }
- switch (c) {
- default:
- ok = false;
- break stringLoop;
- case 'J' :
- case 'D' :
- case 'B' :
- case 'S' :
- case 'C' :
- case 'I' :
- case 'Z' :
- case 'F' :
- --stackDiff;
- ++count;
- ++index;
- continue;
- case 'L':
- // fall thru
- }
- // fall thru
- case 'L' : {
- --stackDiff;
- ++count;
- ++index;
- int semicolon = pString.indexOf(';', index);
- if (!(index + 1 <= semicolon
- && semicolon < rightParenthesis))
- {
- ok = false;
- break stringLoop;
- }
- index = semicolon + 1;
- continue;
- }
- }
- }
- if (ok) {
- switch (pString.charAt(rightParenthesis + 1)) {
- default:
- ok = false;
- break;
- case 'J' :
- case 'D' :
- ++stackDiff;
- // fall thru
- case 'B' :
- case 'S' :
- case 'C' :
- case 'I' :
- case 'Z' :
- case 'F' :
- case 'L' :
- case '[' :
- ++stackDiff;
- // fall thru
- case 'V' :
- break;
- }
- if (ok) {
- return ((count << 16) | (0xFFFF & stackDiff));
- }
- }
- }
- throw new IllegalArgumentException(
- "Bad parameter signature: "+pString);
- }
-
- static int putInt16(int value, byte[] array, int offset)
- {
- array[offset + 0] = (byte)(value >>> 8);
- array[offset + 1] = (byte)value;
- return offset + 2;
- }
-
- static int putInt32(int value, byte[] array, int offset)
- {
- array[offset + 0] = (byte)(value >>> 24);
- array[offset + 1] = (byte)(value >>> 16);
- array[offset + 2] = (byte)(value >>> 8);
- array[offset + 3] = (byte)value;
- return offset + 4;
- }
-
- /**
- * Number of operands accompanying the opcode.
- */
- static int opcodeCount(int opcode)
- {
- switch (opcode) {
- case ByteCode.AALOAD:
- case ByteCode.AASTORE:
- case ByteCode.ACONST_NULL:
- case ByteCode.ALOAD_0:
- case ByteCode.ALOAD_1:
- case ByteCode.ALOAD_2:
- case ByteCode.ALOAD_3:
- case ByteCode.ARETURN:
- case ByteCode.ARRAYLENGTH:
- case ByteCode.ASTORE_0:
- case ByteCode.ASTORE_1:
- case ByteCode.ASTORE_2:
- case ByteCode.ASTORE_3:
- case ByteCode.ATHROW:
- case ByteCode.BALOAD:
- case ByteCode.BASTORE:
- case ByteCode.BREAKPOINT:
- case ByteCode.CALOAD:
- case ByteCode.CASTORE:
- case ByteCode.D2F:
- case ByteCode.D2I:
- case ByteCode.D2L:
- case ByteCode.DADD:
- case ByteCode.DALOAD:
- case ByteCode.DASTORE:
- case ByteCode.DCMPG:
- case ByteCode.DCMPL:
- case ByteCode.DCONST_0:
- case ByteCode.DCONST_1:
- case ByteCode.DDIV:
- case ByteCode.DLOAD_0:
- case ByteCode.DLOAD_1:
- case ByteCode.DLOAD_2:
- case ByteCode.DLOAD_3:
- case ByteCode.DMUL:
- case ByteCode.DNEG:
- case ByteCode.DREM:
- case ByteCode.DRETURN:
- case ByteCode.DSTORE_0:
- case ByteCode.DSTORE_1:
- case ByteCode.DSTORE_2:
- case ByteCode.DSTORE_3:
- case ByteCode.DSUB:
- case ByteCode.DUP:
- case ByteCode.DUP2:
- case ByteCode.DUP2_X1:
- case ByteCode.DUP2_X2:
- case ByteCode.DUP_X1:
- case ByteCode.DUP_X2:
- case ByteCode.F2D:
- case ByteCode.F2I:
- case ByteCode.F2L:
- case ByteCode.FADD:
- case ByteCode.FALOAD:
- case ByteCode.FASTORE:
- case ByteCode.FCMPG:
- case ByteCode.FCMPL:
- case ByteCode.FCONST_0:
- case ByteCode.FCONST_1:
- case ByteCode.FCONST_2:
- case ByteCode.FDIV:
- case ByteCode.FLOAD_0:
- case ByteCode.FLOAD_1:
- case ByteCode.FLOAD_2:
- case ByteCode.FLOAD_3:
- case ByteCode.FMUL:
- case ByteCode.FNEG:
- case ByteCode.FREM:
- case ByteCode.FRETURN:
- case ByteCode.FSTORE_0:
- case ByteCode.FSTORE_1:
- case ByteCode.FSTORE_2:
- case ByteCode.FSTORE_3:
- case ByteCode.FSUB:
- case ByteCode.I2B:
- case ByteCode.I2C:
- case ByteCode.I2D:
- case ByteCode.I2F:
- case ByteCode.I2L:
- case ByteCode.I2S:
- case ByteCode.IADD:
- case ByteCode.IALOAD:
- case ByteCode.IAND:
- case ByteCode.IASTORE:
- case ByteCode.ICONST_0:
- case ByteCode.ICONST_1:
- case ByteCode.ICONST_2:
- case ByteCode.ICONST_3:
- case ByteCode.ICONST_4:
- case ByteCode.ICONST_5:
- case ByteCode.ICONST_M1:
- case ByteCode.IDIV:
- case ByteCode.ILOAD_0:
- case ByteCode.ILOAD_1:
- case ByteCode.ILOAD_2:
- case ByteCode.ILOAD_3:
- case ByteCode.IMPDEP1:
- case ByteCode.IMPDEP2:
- case ByteCode.IMUL:
- case ByteCode.INEG:
- case ByteCode.IOR:
- case ByteCode.IREM:
- case ByteCode.IRETURN:
- case ByteCode.ISHL:
- case ByteCode.ISHR:
- case ByteCode.ISTORE_0:
- case ByteCode.ISTORE_1:
- case ByteCode.ISTORE_2:
- case ByteCode.ISTORE_3:
- case ByteCode.ISUB:
- case ByteCode.IUSHR:
- case ByteCode.IXOR:
- case ByteCode.L2D:
- case ByteCode.L2F:
- case ByteCode.L2I:
- case ByteCode.LADD:
- case ByteCode.LALOAD:
- case ByteCode.LAND:
- case ByteCode.LASTORE:
- case ByteCode.LCMP:
- case ByteCode.LCONST_0:
- case ByteCode.LCONST_1:
- case ByteCode.LDIV:
- case ByteCode.LLOAD_0:
- case ByteCode.LLOAD_1:
- case ByteCode.LLOAD_2:
- case ByteCode.LLOAD_3:
- case ByteCode.LMUL:
- case ByteCode.LNEG:
- case ByteCode.LOR:
- case ByteCode.LREM:
- case ByteCode.LRETURN:
- case ByteCode.LSHL:
- case ByteCode.LSHR:
- case ByteCode.LSTORE_0:
- case ByteCode.LSTORE_1:
- case ByteCode.LSTORE_2:
- case ByteCode.LSTORE_3:
- case ByteCode.LSUB:
- case ByteCode.LUSHR:
- case ByteCode.LXOR:
- case ByteCode.MONITORENTER:
- case ByteCode.MONITOREXIT:
- case ByteCode.NOP:
- case ByteCode.POP:
- case ByteCode.POP2:
- case ByteCode.RETURN:
- case ByteCode.SALOAD:
- case ByteCode.SASTORE:
- case ByteCode.SWAP:
- case ByteCode.WIDE:
- return 0;
- case ByteCode.ALOAD:
- case ByteCode.ANEWARRAY:
- case ByteCode.ASTORE:
- case ByteCode.BIPUSH:
- case ByteCode.CHECKCAST:
- case ByteCode.DLOAD:
- case ByteCode.DSTORE:
- case ByteCode.FLOAD:
- case ByteCode.FSTORE:
- case ByteCode.GETFIELD:
- case ByteCode.GETSTATIC:
- case ByteCode.GOTO:
- case ByteCode.GOTO_W:
- case ByteCode.IFEQ:
- case ByteCode.IFGE:
- case ByteCode.IFGT:
- case ByteCode.IFLE:
- case ByteCode.IFLT:
- case ByteCode.IFNE:
- case ByteCode.IFNONNULL:
- case ByteCode.IFNULL:
- case ByteCode.IF_ACMPEQ:
- case ByteCode.IF_ACMPNE:
- case ByteCode.IF_ICMPEQ:
- case ByteCode.IF_ICMPGE:
- case ByteCode.IF_ICMPGT:
- case ByteCode.IF_ICMPLE:
- case ByteCode.IF_ICMPLT:
- case ByteCode.IF_ICMPNE:
- case ByteCode.ILOAD:
- case ByteCode.INSTANCEOF:
- case ByteCode.INVOKEINTERFACE:
- case ByteCode.INVOKESPECIAL:
- case ByteCode.INVOKESTATIC:
- case ByteCode.INVOKEVIRTUAL:
- case ByteCode.ISTORE:
- case ByteCode.JSR:
- case ByteCode.JSR_W:
- case ByteCode.LDC:
- case ByteCode.LDC2_W:
- case ByteCode.LDC_W:
- case ByteCode.LLOAD:
- case ByteCode.LSTORE:
- case ByteCode.NEW:
- case ByteCode.NEWARRAY:
- case ByteCode.PUTFIELD:
- case ByteCode.PUTSTATIC:
- case ByteCode.RET:
- case ByteCode.SIPUSH:
- return 1;
-
- case ByteCode.IINC:
- case ByteCode.MULTIANEWARRAY:
- return 2;
-
- case ByteCode.LOOKUPSWITCH:
- case ByteCode.TABLESWITCH:
- return -1;
- }
- throw new IllegalArgumentException("Bad opcode: "+opcode);
- }
-
- /**
- * The effect on the operand stack of a given opcode.
- */
- static int stackChange(int opcode)
- {
- // For INVOKE... accounts only for popping this (unless static),
- // ignoring parameters and return type
- switch (opcode) {
- case ByteCode.DASTORE:
- case ByteCode.LASTORE:
- return -4;
-
- case ByteCode.AASTORE:
- case ByteCode.BASTORE:
- case ByteCode.CASTORE:
- case ByteCode.DCMPG:
- case ByteCode.DCMPL:
- case ByteCode.FASTORE:
- case ByteCode.IASTORE:
- case ByteCode.LCMP:
- case ByteCode.SASTORE:
- return -3;
-
- case ByteCode.DADD:
- case ByteCode.DDIV:
- case ByteCode.DMUL:
- case ByteCode.DREM:
- case ByteCode.DRETURN:
- case ByteCode.DSTORE:
- case ByteCode.DSTORE_0:
- case ByteCode.DSTORE_1:
- case ByteCode.DSTORE_2:
- case ByteCode.DSTORE_3:
- case ByteCode.DSUB:
- case ByteCode.IF_ACMPEQ:
- case ByteCode.IF_ACMPNE:
- case ByteCode.IF_ICMPEQ:
- case ByteCode.IF_ICMPGE:
- case ByteCode.IF_ICMPGT:
- case ByteCode.IF_ICMPLE:
- case ByteCode.IF_ICMPLT:
- case ByteCode.IF_ICMPNE:
- case ByteCode.LADD:
- case ByteCode.LAND:
- case ByteCode.LDIV:
- case ByteCode.LMUL:
- case ByteCode.LOR:
- case ByteCode.LREM:
- case ByteCode.LRETURN:
- case ByteCode.LSTORE:
- case ByteCode.LSTORE_0:
- case ByteCode.LSTORE_1:
- case ByteCode.LSTORE_2:
- case ByteCode.LSTORE_3:
- case ByteCode.LSUB:
- case ByteCode.LXOR:
- case ByteCode.POP2:
- return -2;
-
- case ByteCode.AALOAD:
- case ByteCode.ARETURN:
- case ByteCode.ASTORE:
- case ByteCode.ASTORE_0:
- case ByteCode.ASTORE_1:
- case ByteCode.ASTORE_2:
- case ByteCode.ASTORE_3:
- case ByteCode.ATHROW:
- case ByteCode.BALOAD:
- case ByteCode.CALOAD:
- case ByteCode.D2F:
- case ByteCode.D2I:
- case ByteCode.FADD:
- case ByteCode.FALOAD:
- case ByteCode.FCMPG:
- case ByteCode.FCMPL:
- case ByteCode.FDIV:
- case ByteCode.FMUL:
- case ByteCode.FREM:
- case ByteCode.FRETURN:
- case ByteCode.FSTORE:
- case ByteCode.FSTORE_0:
- case ByteCode.FSTORE_1:
- case ByteCode.FSTORE_2:
- case ByteCode.FSTORE_3:
- case ByteCode.FSUB:
- case ByteCode.GETFIELD:
- case ByteCode.IADD:
- case ByteCode.IALOAD:
- case ByteCode.IAND:
- case ByteCode.IDIV:
- case ByteCode.IFEQ:
- case ByteCode.IFGE:
- case ByteCode.IFGT:
- case ByteCode.IFLE:
- case ByteCode.IFLT:
- case ByteCode.IFNE:
- case ByteCode.IFNONNULL:
- case ByteCode.IFNULL:
- case ByteCode.IMUL:
- case ByteCode.INVOKEINTERFACE: //
- case ByteCode.INVOKESPECIAL: // but needs to account for
- case ByteCode.INVOKEVIRTUAL: // pops 'this' (unless static)
- case ByteCode.IOR:
- case ByteCode.IREM:
- case ByteCode.IRETURN:
- case ByteCode.ISHL:
- case ByteCode.ISHR:
- case ByteCode.ISTORE:
- case ByteCode.ISTORE_0:
- case ByteCode.ISTORE_1:
- case ByteCode.ISTORE_2:
- case ByteCode.ISTORE_3:
- case ByteCode.ISUB:
- case ByteCode.IUSHR:
- case ByteCode.IXOR:
- case ByteCode.L2F:
- case ByteCode.L2I:
- case ByteCode.LOOKUPSWITCH:
- case ByteCode.LSHL:
- case ByteCode.LSHR:
- case ByteCode.LUSHR:
- case ByteCode.MONITORENTER:
- case ByteCode.MONITOREXIT:
- case ByteCode.POP:
- case ByteCode.PUTFIELD:
- case ByteCode.SALOAD:
- case ByteCode.TABLESWITCH:
- return -1;
-
- case ByteCode.ANEWARRAY:
- case ByteCode.ARRAYLENGTH:
- case ByteCode.BREAKPOINT:
- case ByteCode.CHECKCAST:
- case ByteCode.D2L:
- case ByteCode.DALOAD:
- case ByteCode.DNEG:
- case ByteCode.F2I:
- case ByteCode.FNEG:
- case ByteCode.GETSTATIC:
- case ByteCode.GOTO:
- case ByteCode.GOTO_W:
- case ByteCode.I2B:
- case ByteCode.I2C:
- case ByteCode.I2F:
- case ByteCode.I2S:
- case ByteCode.IINC:
- case ByteCode.IMPDEP1:
- case ByteCode.IMPDEP2:
- case ByteCode.INEG:
- case ByteCode.INSTANCEOF:
- case ByteCode.INVOKESTATIC:
- case ByteCode.L2D:
- case ByteCode.LALOAD:
- case ByteCode.LNEG:
- case ByteCode.NEWARRAY:
- case ByteCode.NOP:
- case ByteCode.PUTSTATIC:
- case ByteCode.RET:
- case ByteCode.RETURN:
- case ByteCode.SWAP:
- case ByteCode.WIDE:
- return 0;
-
- case ByteCode.ACONST_NULL:
- case ByteCode.ALOAD:
- case ByteCode.ALOAD_0:
- case ByteCode.ALOAD_1:
- case ByteCode.ALOAD_2:
- case ByteCode.ALOAD_3:
- case ByteCode.BIPUSH:
- case ByteCode.DUP:
- case ByteCode.DUP_X1:
- case ByteCode.DUP_X2:
- case ByteCode.F2D:
- case ByteCode.F2L:
- case ByteCode.FCONST_0:
- case ByteCode.FCONST_1:
- case ByteCode.FCONST_2:
- case ByteCode.FLOAD:
- case ByteCode.FLOAD_0:
- case ByteCode.FLOAD_1:
- case ByteCode.FLOAD_2:
- case ByteCode.FLOAD_3:
- case ByteCode.I2D:
- case ByteCode.I2L:
- case ByteCode.ICONST_0:
- case ByteCode.ICONST_1:
- case ByteCode.ICONST_2:
- case ByteCode.ICONST_3:
- case ByteCode.ICONST_4:
- case ByteCode.ICONST_5:
- case ByteCode.ICONST_M1:
- case ByteCode.ILOAD:
- case ByteCode.ILOAD_0:
- case ByteCode.ILOAD_1:
- case ByteCode.ILOAD_2:
- case ByteCode.ILOAD_3:
- case ByteCode.JSR:
- case ByteCode.JSR_W:
- case ByteCode.LDC:
- case ByteCode.LDC_W:
- case ByteCode.MULTIANEWARRAY:
- case ByteCode.NEW:
- case ByteCode.SIPUSH:
- return 1;
-
- case ByteCode.DCONST_0:
- case ByteCode.DCONST_1:
- case ByteCode.DLOAD:
- case ByteCode.DLOAD_0:
- case ByteCode.DLOAD_1:
- case ByteCode.DLOAD_2:
- case ByteCode.DLOAD_3:
- case ByteCode.DUP2:
- case ByteCode.DUP2_X1:
- case ByteCode.DUP2_X2:
- case ByteCode.LCONST_0:
- case ByteCode.LCONST_1:
- case ByteCode.LDC2_W:
- case ByteCode.LLOAD:
- case ByteCode.LLOAD_0:
- case ByteCode.LLOAD_1:
- case ByteCode.LLOAD_2:
- case ByteCode.LLOAD_3:
- return 2;
- }
- throw new IllegalArgumentException("Bad opcode: "+opcode);
- }
-
- /*
- * Number of bytes of operands generated after the opcode.
- * Not in use currently.
- */
-/*
- int extra(int opcode)
- {
- switch (opcode) {
- case ByteCode.AALOAD:
- case ByteCode.AASTORE:
- case ByteCode.ACONST_NULL:
- case ByteCode.ALOAD_0:
- case ByteCode.ALOAD_1:
- case ByteCode.ALOAD_2:
- case ByteCode.ALOAD_3:
- case ByteCode.ARETURN:
- case ByteCode.ARRAYLENGTH:
- case ByteCode.ASTORE_0:
- case ByteCode.ASTORE_1:
- case ByteCode.ASTORE_2:
- case ByteCode.ASTORE_3:
- case ByteCode.ATHROW:
- case ByteCode.BALOAD:
- case ByteCode.BASTORE:
- case ByteCode.BREAKPOINT:
- case ByteCode.CALOAD:
- case ByteCode.CASTORE:
- case ByteCode.D2F:
- case ByteCode.D2I:
- case ByteCode.D2L:
- case ByteCode.DADD:
- case ByteCode.DALOAD:
- case ByteCode.DASTORE:
- case ByteCode.DCMPG:
- case ByteCode.DCMPL:
- case ByteCode.DCONST_0:
- case ByteCode.DCONST_1:
- case ByteCode.DDIV:
- case ByteCode.DLOAD_0:
- case ByteCode.DLOAD_1:
- case ByteCode.DLOAD_2:
- case ByteCode.DLOAD_3:
- case ByteCode.DMUL:
- case ByteCode.DNEG:
- case ByteCode.DREM:
- case ByteCode.DRETURN:
- case ByteCode.DSTORE_0:
- case ByteCode.DSTORE_1:
- case ByteCode.DSTORE_2:
- case ByteCode.DSTORE_3:
- case ByteCode.DSUB:
- case ByteCode.DUP2:
- case ByteCode.DUP2_X1:
- case ByteCode.DUP2_X2:
- case ByteCode.DUP:
- case ByteCode.DUP_X1:
- case ByteCode.DUP_X2:
- case ByteCode.F2D:
- case ByteCode.F2I:
- case ByteCode.F2L:
- case ByteCode.FADD:
- case ByteCode.FALOAD:
- case ByteCode.FASTORE:
- case ByteCode.FCMPG:
- case ByteCode.FCMPL:
- case ByteCode.FCONST_0:
- case ByteCode.FCONST_1:
- case ByteCode.FCONST_2:
- case ByteCode.FDIV:
- case ByteCode.FLOAD_0:
- case ByteCode.FLOAD_1:
- case ByteCode.FLOAD_2:
- case ByteCode.FLOAD_3:
- case ByteCode.FMUL:
- case ByteCode.FNEG:
- case ByteCode.FREM:
- case ByteCode.FRETURN:
- case ByteCode.FSTORE_0:
- case ByteCode.FSTORE_1:
- case ByteCode.FSTORE_2:
- case ByteCode.FSTORE_3:
- case ByteCode.FSUB:
- case ByteCode.I2B:
- case ByteCode.I2C:
- case ByteCode.I2D:
- case ByteCode.I2F:
- case ByteCode.I2L:
- case ByteCode.I2S:
- case ByteCode.IADD:
- case ByteCode.IALOAD:
- case ByteCode.IAND:
- case ByteCode.IASTORE:
- case ByteCode.ICONST_0:
- case ByteCode.ICONST_1:
- case ByteCode.ICONST_2:
- case ByteCode.ICONST_3:
- case ByteCode.ICONST_4:
- case ByteCode.ICONST_5:
- case ByteCode.ICONST_M1:
- case ByteCode.IDIV:
- case ByteCode.ILOAD_0:
- case ByteCode.ILOAD_1:
- case ByteCode.ILOAD_2:
- case ByteCode.ILOAD_3:
- case ByteCode.IMPDEP1:
- case ByteCode.IMPDEP2:
- case ByteCode.IMUL:
- case ByteCode.INEG:
- case ByteCode.IOR:
- case ByteCode.IREM:
- case ByteCode.IRETURN:
- case ByteCode.ISHL:
- case ByteCode.ISHR:
- case ByteCode.ISTORE_0:
- case ByteCode.ISTORE_1:
- case ByteCode.ISTORE_2:
- case ByteCode.ISTORE_3:
- case ByteCode.ISUB:
- case ByteCode.IUSHR:
- case ByteCode.IXOR:
- case ByteCode.L2D:
- case ByteCode.L2F:
- case ByteCode.L2I:
- case ByteCode.LADD:
- case ByteCode.LALOAD:
- case ByteCode.LAND:
- case ByteCode.LASTORE:
- case ByteCode.LCMP:
- case ByteCode.LCONST_0:
- case ByteCode.LCONST_1:
- case ByteCode.LDIV:
- case ByteCode.LLOAD_0:
- case ByteCode.LLOAD_1:
- case ByteCode.LLOAD_2:
- case ByteCode.LLOAD_3:
- case ByteCode.LMUL:
- case ByteCode.LNEG:
- case ByteCode.LOR:
- case ByteCode.LREM:
- case ByteCode.LRETURN:
- case ByteCode.LSHL:
- case ByteCode.LSHR:
- case ByteCode.LSTORE_0:
- case ByteCode.LSTORE_1:
- case ByteCode.LSTORE_2:
- case ByteCode.LSTORE_3:
- case ByteCode.LSUB:
- case ByteCode.LUSHR:
- case ByteCode.LXOR:
- case ByteCode.MONITORENTER:
- case ByteCode.MONITOREXIT:
- case ByteCode.NOP:
- case ByteCode.POP2:
- case ByteCode.POP:
- case ByteCode.RETURN:
- case ByteCode.SALOAD:
- case ByteCode.SASTORE:
- case ByteCode.SWAP:
- case ByteCode.WIDE:
- return 0;
-
- case ByteCode.ALOAD:
- case ByteCode.ASTORE:
- case ByteCode.BIPUSH:
- case ByteCode.DLOAD:
- case ByteCode.DSTORE:
- case ByteCode.FLOAD:
- case ByteCode.FSTORE:
- case ByteCode.ILOAD:
- case ByteCode.ISTORE:
- case ByteCode.LDC:
- case ByteCode.LLOAD:
- case ByteCode.LSTORE:
- case ByteCode.NEWARRAY:
- case ByteCode.RET:
- return 1;
-
- case ByteCode.ANEWARRAY:
- case ByteCode.CHECKCAST:
- case ByteCode.GETFIELD:
- case ByteCode.GETSTATIC:
- case ByteCode.GOTO:
- case ByteCode.IFEQ:
- case ByteCode.IFGE:
- case ByteCode.IFGT:
- case ByteCode.IFLE:
- case ByteCode.IFLT:
- case ByteCode.IFNE:
- case ByteCode.IFNONNULL:
- case ByteCode.IFNULL:
- case ByteCode.IF_ACMPEQ:
- case ByteCode.IF_ACMPNE:
- case ByteCode.IF_ICMPEQ:
- case ByteCode.IF_ICMPGE:
- case ByteCode.IF_ICMPGT:
- case ByteCode.IF_ICMPLE:
- case ByteCode.IF_ICMPLT:
- case ByteCode.IF_ICMPNE:
- case ByteCode.IINC:
- case ByteCode.INSTANCEOF:
- case ByteCode.INVOKEINTERFACE:
- case ByteCode.INVOKESPECIAL:
- case ByteCode.INVOKESTATIC:
- case ByteCode.INVOKEVIRTUAL:
- case ByteCode.JSR:
- case ByteCode.LDC2_W:
- case ByteCode.LDC_W:
- case ByteCode.NEW:
- case ByteCode.PUTFIELD:
- case ByteCode.PUTSTATIC:
- case ByteCode.SIPUSH:
- return 2;
-
- case ByteCode.MULTIANEWARRAY:
- return 3;
-
- case ByteCode.GOTO_W:
- case ByteCode.JSR_W:
- return 4;
-
- case ByteCode.LOOKUPSWITCH: // depends on alignment
- case ByteCode.TABLESWITCH: // depends on alignment
- return -1;
- }
- throw new IllegalArgumentException("Bad opcode: "+opcode);
- }
-*/
- private static String bytecodeStr(int code)
- {
- if (DEBUGSTACK || DEBUGCODE) {
- switch (code) {
- case ByteCode.NOP: return "nop";
- case ByteCode.ACONST_NULL: return "aconst_null";
- case ByteCode.ICONST_M1: return "iconst_m1";
- case ByteCode.ICONST_0: return "iconst_0";
- case ByteCode.ICONST_1: return "iconst_1";
- case ByteCode.ICONST_2: return "iconst_2";
- case ByteCode.ICONST_3: return "iconst_3";
- case ByteCode.ICONST_4: return "iconst_4";
- case ByteCode.ICONST_5: return "iconst_5";
- case ByteCode.LCONST_0: return "lconst_0";
- case ByteCode.LCONST_1: return "lconst_1";
- case ByteCode.FCONST_0: return "fconst_0";
- case ByteCode.FCONST_1: return "fconst_1";
- case ByteCode.FCONST_2: return "fconst_2";
- case ByteCode.DCONST_0: return "dconst_0";
- case ByteCode.DCONST_1: return "dconst_1";
- case ByteCode.BIPUSH: return "bipush";
- case ByteCode.SIPUSH: return "sipush";
- case ByteCode.LDC: return "ldc";
- case ByteCode.LDC_W: return "ldc_w";
- case ByteCode.LDC2_W: return "ldc2_w";
- case ByteCode.ILOAD: return "iload";
- case ByteCode.LLOAD: return "lload";
- case ByteCode.FLOAD: return "fload";
- case ByteCode.DLOAD: return "dload";
- case ByteCode.ALOAD: return "aload";
- case ByteCode.ILOAD_0: return "iload_0";
- case ByteCode.ILOAD_1: return "iload_1";
- case ByteCode.ILOAD_2: return "iload_2";
- case ByteCode.ILOAD_3: return "iload_3";
- case ByteCode.LLOAD_0: return "lload_0";
- case ByteCode.LLOAD_1: return "lload_1";
- case ByteCode.LLOAD_2: return "lload_2";
- case ByteCode.LLOAD_3: return "lload_3";
- case ByteCode.FLOAD_0: return "fload_0";
- case ByteCode.FLOAD_1: return "fload_1";
- case ByteCode.FLOAD_2: return "fload_2";
- case ByteCode.FLOAD_3: return "fload_3";
- case ByteCode.DLOAD_0: return "dload_0";
- case ByteCode.DLOAD_1: return "dload_1";
- case ByteCode.DLOAD_2: return "dload_2";
- case ByteCode.DLOAD_3: return "dload_3";
- case ByteCode.ALOAD_0: return "aload_0";
- case ByteCode.ALOAD_1: return "aload_1";
- case ByteCode.ALOAD_2: return "aload_2";
- case ByteCode.ALOAD_3: return "aload_3";
- case ByteCode.IALOAD: return "iaload";
- case ByteCode.LALOAD: return "laload";
- case ByteCode.FALOAD: return "faload";
- case ByteCode.DALOAD: return "daload";
- case ByteCode.AALOAD: return "aaload";
- case ByteCode.BALOAD: return "baload";
- case ByteCode.CALOAD: return "caload";
- case ByteCode.SALOAD: return "saload";
- case ByteCode.ISTORE: return "istore";
- case ByteCode.LSTORE: return "lstore";
- case ByteCode.FSTORE: return "fstore";
- case ByteCode.DSTORE: return "dstore";
- case ByteCode.ASTORE: return "astore";
- case ByteCode.ISTORE_0: return "istore_0";
- case ByteCode.ISTORE_1: return "istore_1";
- case ByteCode.ISTORE_2: return "istore_2";
- case ByteCode.ISTORE_3: return "istore_3";
- case ByteCode.LSTORE_0: return "lstore_0";
- case ByteCode.LSTORE_1: return "lstore_1";
- case ByteCode.LSTORE_2: return "lstore_2";
- case ByteCode.LSTORE_3: return "lstore_3";
- case ByteCode.FSTORE_0: return "fstore_0";
- case ByteCode.FSTORE_1: return "fstore_1";
- case ByteCode.FSTORE_2: return "fstore_2";
- case ByteCode.FSTORE_3: return "fstore_3";
- case ByteCode.DSTORE_0: return "dstore_0";
- case ByteCode.DSTORE_1: return "dstore_1";
- case ByteCode.DSTORE_2: return "dstore_2";
- case ByteCode.DSTORE_3: return "dstore_3";
- case ByteCode.ASTORE_0: return "astore_0";
- case ByteCode.ASTORE_1: return "astore_1";
- case ByteCode.ASTORE_2: return "astore_2";
- case ByteCode.ASTORE_3: return "astore_3";
- case ByteCode.IASTORE: return "iastore";
- case ByteCode.LASTORE: return "lastore";
- case ByteCode.FASTORE: return "fastore";
- case ByteCode.DASTORE: return "dastore";
- case ByteCode.AASTORE: return "aastore";
- case ByteCode.BASTORE: return "bastore";
- case ByteCode.CASTORE: return "castore";
- case ByteCode.SASTORE: return "sastore";
- case ByteCode.POP: return "pop";
- case ByteCode.POP2: return "pop2";
- case ByteCode.DUP: return "dup";
- case ByteCode.DUP_X1: return "dup_x1";
- case ByteCode.DUP_X2: return "dup_x2";
- case ByteCode.DUP2: return "dup2";
- case ByteCode.DUP2_X1: return "dup2_x1";
- case ByteCode.DUP2_X2: return "dup2_x2";
- case ByteCode.SWAP: return "swap";
- case ByteCode.IADD: return "iadd";
- case ByteCode.LADD: return "ladd";
- case ByteCode.FADD: return "fadd";
- case ByteCode.DADD: return "dadd";
- case ByteCode.ISUB: return "isub";
- case ByteCode.LSUB: return "lsub";
- case ByteCode.FSUB: return "fsub";
- case ByteCode.DSUB: return "dsub";
- case ByteCode.IMUL: return "imul";
- case ByteCode.LMUL: return "lmul";
- case ByteCode.FMUL: return "fmul";
- case ByteCode.DMUL: return "dmul";
- case ByteCode.IDIV: return "idiv";
- case ByteCode.LDIV: return "ldiv";
- case ByteCode.FDIV: return "fdiv";
- case ByteCode.DDIV: return "ddiv";
- case ByteCode.IREM: return "irem";
- case ByteCode.LREM: return "lrem";
- case ByteCode.FREM: return "frem";
- case ByteCode.DREM: return "drem";
- case ByteCode.INEG: return "ineg";
- case ByteCode.LNEG: return "lneg";
- case ByteCode.FNEG: return "fneg";
- case ByteCode.DNEG: return "dneg";
- case ByteCode.ISHL: return "ishl";
- case ByteCode.LSHL: return "lshl";
- case ByteCode.ISHR: return "ishr";
- case ByteCode.LSHR: return "lshr";
- case ByteCode.IUSHR: return "iushr";
- case ByteCode.LUSHR: return "lushr";
- case ByteCode.IAND: return "iand";
- case ByteCode.LAND: return "land";
- case ByteCode.IOR: return "ior";
- case ByteCode.LOR: return "lor";
- case ByteCode.IXOR: return "ixor";
- case ByteCode.LXOR: return "lxor";
- case ByteCode.IINC: return "iinc";
- case ByteCode.I2L: return "i2l";
- case ByteCode.I2F: return "i2f";
- case ByteCode.I2D: return "i2d";
- case ByteCode.L2I: return "l2i";
- case ByteCode.L2F: return "l2f";
- case ByteCode.L2D: return "l2d";
- case ByteCode.F2I: return "f2i";
- case ByteCode.F2L: return "f2l";
- case ByteCode.F2D: return "f2d";
- case ByteCode.D2I: return "d2i";
- case ByteCode.D2L: return "d2l";
- case ByteCode.D2F: return "d2f";
- case ByteCode.I2B: return "i2b";
- case ByteCode.I2C: return "i2c";
- case ByteCode.I2S: return "i2s";
- case ByteCode.LCMP: return "lcmp";
- case ByteCode.FCMPL: return "fcmpl";
- case ByteCode.FCMPG: return "fcmpg";
- case ByteCode.DCMPL: return "dcmpl";
- case ByteCode.DCMPG: return "dcmpg";
- case ByteCode.IFEQ: return "ifeq";
- case ByteCode.IFNE: return "ifne";
- case ByteCode.IFLT: return "iflt";
- case ByteCode.IFGE: return "ifge";
- case ByteCode.IFGT: return "ifgt";
- case ByteCode.IFLE: return "ifle";
- case ByteCode.IF_ICMPEQ: return "if_icmpeq";
- case ByteCode.IF_ICMPNE: return "if_icmpne";
- case ByteCode.IF_ICMPLT: return "if_icmplt";
- case ByteCode.IF_ICMPGE: return "if_icmpge";
- case ByteCode.IF_ICMPGT: return "if_icmpgt";
- case ByteCode.IF_ICMPLE: return "if_icmple";
- case ByteCode.IF_ACMPEQ: return "if_acmpeq";
- case ByteCode.IF_ACMPNE: return "if_acmpne";
- case ByteCode.GOTO: return "goto";
- case ByteCode.JSR: return "jsr";
- case ByteCode.RET: return "ret";
- case ByteCode.TABLESWITCH: return "tableswitch";
- case ByteCode.LOOKUPSWITCH: return "lookupswitch";
- case ByteCode.IRETURN: return "ireturn";
- case ByteCode.LRETURN: return "lreturn";
- case ByteCode.FRETURN: return "freturn";
- case ByteCode.DRETURN: return "dreturn";
- case ByteCode.ARETURN: return "areturn";
- case ByteCode.RETURN: return "return";
- case ByteCode.GETSTATIC: return "getstatic";
- case ByteCode.PUTSTATIC: return "putstatic";
- case ByteCode.GETFIELD: return "getfield";
- case ByteCode.PUTFIELD: return "putfield";
- case ByteCode.INVOKEVIRTUAL: return "invokevirtual";
- case ByteCode.INVOKESPECIAL: return "invokespecial";
- case ByteCode.INVOKESTATIC: return "invokestatic";
- case ByteCode.INVOKEINTERFACE: return "invokeinterface";
- case ByteCode.NEW: return "new";
- case ByteCode.NEWARRAY: return "newarray";
- case ByteCode.ANEWARRAY: return "anewarray";
- case ByteCode.ARRAYLENGTH: return "arraylength";
- case ByteCode.ATHROW: return "athrow";
- case ByteCode.CHECKCAST: return "checkcast";
- case ByteCode.INSTANCEOF: return "instanceof";
- case ByteCode.MONITORENTER: return "monitorenter";
- case ByteCode.MONITOREXIT: return "monitorexit";
- case ByteCode.WIDE: return "wide";
- case ByteCode.MULTIANEWARRAY: return "multianewarray";
- case ByteCode.IFNULL: return "ifnull";
- case ByteCode.IFNONNULL: return "ifnonnull";
- case ByteCode.GOTO_W: return "goto_w";
- case ByteCode.JSR_W: return "jsr_w";
- case ByteCode.BREAKPOINT: return "breakpoint";
-
- case ByteCode.IMPDEP1: return "impdep1";
- case ByteCode.IMPDEP2: return "impdep2";
- }
- }
- return "";
- }
-
- final char[] getCharBuffer(int minimalSize)
- {
- if (minimalSize > tmpCharBuffer.length) {
- int newSize = tmpCharBuffer.length * 2;
- if (minimalSize > newSize) { newSize = minimalSize; }
- tmpCharBuffer = new char[newSize];
- }
- return tmpCharBuffer;
- }
-
- private static final int LineNumberTableSize = 16;
- private static final int ExceptionTableSize = 4;
-
- private final static long FileHeaderConstant = 0xCAFEBABE0003002DL;
- // Set DEBUG flags to true to get better checking and progress info.
- private static final boolean DEBUGSTACK = false;
- private static final boolean DEBUGLABELS = false;
- private static final boolean DEBUGCODE = false;
-
- private String generatedClassName;
-
- private ExceptionTableEntry itsExceptionTable[];
- private int itsExceptionTableTop;
-
- private int itsLineNumberTable[]; // pack start_pc & line_number together
- private int itsLineNumberTableTop;
-
- private byte[] itsCodeBuffer = new byte[256];
- private int itsCodeBufferTop;
-
- private ConstantPool itsConstantPool;
-
- private ClassFileMethod itsCurrentMethod;
- private short itsStackTop;
-
- private short itsMaxStack;
- private short itsMaxLocals;
-
- private ObjArray itsMethods = new ObjArray();
- private ObjArray itsFields = new ObjArray();
- private ObjArray itsInterfaces = new ObjArray();
-
- private short itsFlags;
- private short itsThisClassIndex;
- private short itsSuperClassIndex;
- private short itsSourceFileNameIndex;
-
- private static final int MIN_LABEL_TABLE_SIZE = 32;
- private int[] itsLabelTable;
- private int itsLabelTableTop;
-
-// itsFixupTable[i] = (label_index << 32) | fixup_site
- private static final int MIN_FIXUP_TABLE_SIZE = 40;
- private long[] itsFixupTable;
- private int itsFixupTableTop;
- private ObjArray itsVarDescriptors;
-
- private char[] tmpCharBuffer = new char[64];
-}
-
-final class ExceptionTableEntry
-{
-
- ExceptionTableEntry(int startLabel, int endLabel,
- int handlerLabel, short catchType)
- {
- itsStartLabel = startLabel;
- itsEndLabel = endLabel;
- itsHandlerLabel = handlerLabel;
- itsCatchType = catchType;
- }
-
- int itsStartLabel;
- int itsEndLabel;
- int itsHandlerLabel;
- short itsCatchType;
-}
-
-final class ClassFileField
-{
-
- ClassFileField(short nameIndex, short typeIndex, short flags)
- {
- itsNameIndex = nameIndex;
- itsTypeIndex = typeIndex;
- itsFlags = flags;
- itsHasAttributes = false;
- }
-
- void setAttributes(short attr1, short attr2, short attr3, int index)
- {
- itsHasAttributes = true;
- itsAttr1 = attr1;
- itsAttr2 = attr2;
- itsAttr3 = attr3;
- itsIndex = index;
- }
-
- int write(byte[] data, int offset)
- {
- offset = ClassFileWriter.putInt16(itsFlags, data, offset);
- offset = ClassFileWriter.putInt16(itsNameIndex, data, offset);
- offset = ClassFileWriter.putInt16(itsTypeIndex, data, offset);
- if (!itsHasAttributes) {
- // write 0 attributes
- offset = ClassFileWriter.putInt16(0, data, offset);
- } else {
- offset = ClassFileWriter.putInt16(1, data, offset);
- offset = ClassFileWriter.putInt16(itsAttr1, data, offset);
- offset = ClassFileWriter.putInt16(itsAttr2, data, offset);
- offset = ClassFileWriter.putInt16(itsAttr3, data, offset);
- offset = ClassFileWriter.putInt16(itsIndex, data, offset);
- }
- return offset;
- }
-
- int getWriteSize()
- {
- int size = 2 * 3;
- if (!itsHasAttributes) {
- size += 2;
- } else {
- size += 2 + 2 * 4;
- }
- return size;
- }
-
- private short itsNameIndex;
- private short itsTypeIndex;
- private short itsFlags;
- private boolean itsHasAttributes;
- private short itsAttr1, itsAttr2, itsAttr3;
- private int itsIndex;
-}
-
-final class ClassFileMethod
-{
-
- ClassFileMethod(short nameIndex, short typeIndex, short flags)
- {
- itsNameIndex = nameIndex;
- itsTypeIndex = typeIndex;
- itsFlags = flags;
- }
-
- void setCodeAttribute(byte codeAttribute[])
- {
- itsCodeAttribute = codeAttribute;
- }
-
- int write(byte[] data, int offset)
- {
- offset = ClassFileWriter.putInt16(itsFlags, data, offset);
- offset = ClassFileWriter.putInt16(itsNameIndex, data, offset);
- offset = ClassFileWriter.putInt16(itsTypeIndex, data, offset);
- // Code attribute only
- offset = ClassFileWriter.putInt16(1, data, offset);
- System.arraycopy(itsCodeAttribute, 0, data, offset,
- itsCodeAttribute.length);
- offset += itsCodeAttribute.length;
- return offset;
- }
-
- int getWriteSize()
- {
- return 2 * 4 + itsCodeAttribute.length;
- }
-
- private short itsNameIndex;
- private short itsTypeIndex;
- private short itsFlags;
- private byte[] itsCodeAttribute;
-
-}
-
-final class ConstantPool
-{
-
- ConstantPool(ClassFileWriter cfw)
- {
- this.cfw = cfw;
- itsTopIndex = 1; // the zero'th entry is reserved
- itsPool = new byte[ConstantPoolSize];
- itsTop = 0;
- }
-
- private static final int ConstantPoolSize = 256;
- private static final byte
- CONSTANT_Class = 7,
- CONSTANT_Fieldref = 9,
- CONSTANT_Methodref = 10,
- CONSTANT_InterfaceMethodref = 11,
- CONSTANT_String = 8,
- CONSTANT_Integer = 3,
- CONSTANT_Float = 4,
- CONSTANT_Long = 5,
- CONSTANT_Double = 6,
- CONSTANT_NameAndType = 12,
- CONSTANT_Utf8 = 1;
-
- int write(byte[] data, int offset)
- {
- offset = ClassFileWriter.putInt16((short)itsTopIndex, data, offset);
- System.arraycopy(itsPool, 0, data, offset, itsTop);
- offset += itsTop;
- return offset;
- }
-
- int getWriteSize()
- {
- return 2 + itsTop;
- }
-
- int addConstant(int k)
- {
- ensure(5);
- itsPool[itsTop++] = CONSTANT_Integer;
- itsTop = ClassFileWriter.putInt32(k, itsPool, itsTop);
- return (short)(itsTopIndex++);
- }
-
- int addConstant(long k)
- {
- ensure(9);
- itsPool[itsTop++] = CONSTANT_Long;
- itsTop = ClassFileWriter.putInt64(k, itsPool, itsTop);
- int index = itsTopIndex;
- itsTopIndex += 2;
- return index;
- }
-
- int addConstant(float k)
- {
- ensure(5);
- itsPool[itsTop++] = CONSTANT_Float;
- int bits = Float.floatToIntBits(k);
- itsTop = ClassFileWriter.putInt32(bits, itsPool, itsTop);
- return itsTopIndex++;
- }
-
- int addConstant(double k)
- {
- ensure(9);
- itsPool[itsTop++] = CONSTANT_Double;
- long bits = Double.doubleToLongBits(k);
- itsTop = ClassFileWriter.putInt64(bits, itsPool, itsTop);
- int index = itsTopIndex;
- itsTopIndex += 2;
- return index;
- }
-
- int addConstant(String k)
- {
- int utf8Index = 0xFFFF & addUtf8(k);
- int theIndex = itsStringConstHash.getInt(utf8Index, -1);
- if (theIndex == -1) {
- theIndex = itsTopIndex++;
- ensure(3);
- itsPool[itsTop++] = CONSTANT_String;
- itsTop = ClassFileWriter.putInt16(utf8Index, itsPool, itsTop);
- itsStringConstHash.put(utf8Index, theIndex);
- }
- return theIndex;
- }
-
- boolean isUnderUtfEncodingLimit(String s)
- {
- int strLen = s.length();
- if (strLen * 3 <= MAX_UTF_ENCODING_SIZE) {
- return true;
- } else if (strLen > MAX_UTF_ENCODING_SIZE) {
- return false;
- }
- return strLen == getUtfEncodingLimit(s, 0, strLen);
- }
-
- /**
- * Get maximum i such that <tt>start <= i <= end</tt> and
- * <tt>s.substring(start, i)</tt> fits JVM UTF string encoding limit.
- */
- int getUtfEncodingLimit(String s, int start, int end)
- {
- if ((end - start) * 3 <= MAX_UTF_ENCODING_SIZE) {
- return end;
- }
- int limit = MAX_UTF_ENCODING_SIZE;
- for (int i = start; i != end; i++) {
- int c = s.charAt(i);
- if (0 != c && c <= 0x7F) {
- --limit;
- } else if (c < 0x7FF) {
- limit -= 2;
- } else {
- limit -= 3;
- }
- if (limit < 0) {
- return i;
- }
- }
- return end;
- }
-
- short addUtf8(String k)
- {
- int theIndex = itsUtf8Hash.get(k, -1);
- if (theIndex == -1) {
- int strLen = k.length();
- boolean tooBigString;
- if (strLen > MAX_UTF_ENCODING_SIZE) {
- tooBigString = true;
- } else {
- tooBigString = false;
- // Ask for worst case scenario buffer when each char takes 3
- // bytes
- ensure(1 + 2 + strLen * 3);
- int top = itsTop;
-
- itsPool[top++] = CONSTANT_Utf8;
- top += 2; // skip length
-
- char[] chars = cfw.getCharBuffer(strLen);
- k.getChars(0, strLen, chars, 0);
-
- for (int i = 0; i != strLen; i++) {
- int c = chars[i];
- if (c != 0 && c <= 0x7F) {
- itsPool[top++] = (byte)c;
- } else if (c > 0x7FF) {
- itsPool[top++] = (byte)(0xE0 | (c >> 12));
- itsPool[top++] = (byte)(0x80 | ((c >> 6) & 0x3F));
- itsPool[top++] = (byte)(0x80 | (c & 0x3F));
- } else {
- itsPool[top++] = (byte)(0xC0 | (c >> 6));
- itsPool[top++] = (byte)(0x80 | (c & 0x3F));
- }
- }
-
- int utfLen = top - (itsTop + 1 + 2);
- if (utfLen > MAX_UTF_ENCODING_SIZE) {
- tooBigString = true;
- } else {
- // Write back length
- itsPool[itsTop + 1] = (byte)(utfLen >>> 8);
- itsPool[itsTop + 2] = (byte)utfLen;
-
- itsTop = top;
- theIndex = itsTopIndex++;
- itsUtf8Hash.put(k, theIndex);
- }
- }
- if (tooBigString) {
- throw new IllegalArgumentException("Too big string");
- }
- }
- return (short)theIndex;
- }
-
- private short addNameAndType(String name, String type)
- {
- short nameIndex = addUtf8(name);
- short typeIndex = addUtf8(type);
- ensure(5);
- itsPool[itsTop++] = CONSTANT_NameAndType;
- itsTop = ClassFileWriter.putInt16(nameIndex, itsPool, itsTop);
- itsTop = ClassFileWriter.putInt16(typeIndex, itsPool, itsTop);
- return (short)(itsTopIndex++);
- }
-
- short addClass(String className)
- {
- int theIndex = itsClassHash.get(className, -1);
- if (theIndex == -1) {
- String slashed = className;
- if (className.indexOf('.') > 0) {
- slashed = ClassFileWriter.getSlashedForm(className);
- theIndex = itsClassHash.get(slashed, -1);
- if (theIndex != -1) {
- itsClassHash.put(className, theIndex);
- }
- }
- if (theIndex == -1) {
- int utf8Index = addUtf8(slashed);
- ensure(3);
- itsPool[itsTop++] = CONSTANT_Class;
- itsTop = ClassFileWriter.putInt16(utf8Index, itsPool, itsTop);
- theIndex = itsTopIndex++;
- itsClassHash.put(slashed, theIndex);
- if (className != slashed) {
- itsClassHash.put(className, theIndex);
- }
- }
- }
- return (short)theIndex;
- }
-
- short addFieldRef(String className, String fieldName, String fieldType)
- {
- FieldOrMethodRef ref = new FieldOrMethodRef(className, fieldName,
- fieldType);
-
- int theIndex = itsFieldRefHash.get(ref, -1);
- if (theIndex == -1) {
- short ntIndex = addNameAndType(fieldName, fieldType);
- short classIndex = addClass(className);
- ensure(5);
- itsPool[itsTop++] = CONSTANT_Fieldref;
- itsTop = ClassFileWriter.putInt16(classIndex, itsPool, itsTop);
- itsTop = ClassFileWriter.putInt16(ntIndex, itsPool, itsTop);
- theIndex = itsTopIndex++;
- itsFieldRefHash.put(ref, theIndex);
- }
- return (short)theIndex;
- }
-
- short addMethodRef(String className, String methodName,
- String methodType)
- {
- FieldOrMethodRef ref = new FieldOrMethodRef(className, methodName,
- methodType);
-
- int theIndex = itsMethodRefHash.get(ref, -1);
- if (theIndex == -1) {
- short ntIndex = addNameAndType(methodName, methodType);
- short classIndex = addClass(className);
- ensure(5);
- itsPool[itsTop++] = CONSTANT_Methodref;
- itsTop = ClassFileWriter.putInt16(classIndex, itsPool, itsTop);
- itsTop = ClassFileWriter.putInt16(ntIndex, itsPool, itsTop);
- theIndex = itsTopIndex++;
- itsMethodRefHash.put(ref, theIndex);
- }
- return (short)theIndex;
- }
-
- short addInterfaceMethodRef(String className,
- String methodName, String methodType)
- {
- short ntIndex = addNameAndType(methodName, methodType);
- short classIndex = addClass(className);
- ensure(5);
- itsPool[itsTop++] = CONSTANT_InterfaceMethodref;
- itsTop = ClassFileWriter.putInt16(classIndex, itsPool, itsTop);
- itsTop = ClassFileWriter.putInt16(ntIndex, itsPool, itsTop);
- return (short)(itsTopIndex++);
- }
-
- void ensure(int howMuch)
- {
- if (itsTop + howMuch > itsPool.length) {
- int newCapacity = itsPool.length * 2;
- if (itsTop + howMuch > newCapacity) {
- newCapacity = itsTop + howMuch;
- }
- byte[] tmp = new byte[newCapacity];
- System.arraycopy(itsPool, 0, tmp, 0, itsTop);
- itsPool = tmp;
- }
- }
-
- private ClassFileWriter cfw;
-
- private static final int MAX_UTF_ENCODING_SIZE = 65535;
-
- private UintMap itsStringConstHash = new UintMap();
- private ObjToIntMap itsUtf8Hash = new ObjToIntMap();
- private ObjToIntMap itsFieldRefHash = new ObjToIntMap();
- private ObjToIntMap itsMethodRefHash = new ObjToIntMap();
- private ObjToIntMap itsClassHash = new ObjToIntMap();
-
- private int itsTop;
- private int itsTopIndex;
- private byte itsPool[];
-}
-
-final class FieldOrMethodRef
-{
- FieldOrMethodRef(String className, String name, String type)
- {
- this.className = className;
- this.name = name;
- this.type = type;
- }
-
- public boolean equals(Object obj)
- {
- if (!(obj instanceof FieldOrMethodRef)) { return false; }
- FieldOrMethodRef x = (FieldOrMethodRef)obj;
- return className.equals(x.className)
- && name.equals(x.name)
- && type.equals(x.type);
- }
-
- public int hashCode()
- {
- if (hashCode == -1) {
- int h1 = className.hashCode();
- int h2 = name.hashCode();
- int h3 = type.hashCode();
- hashCode = h1 ^ h2 ^ h3;
- }
- return hashCode;
- }
-
- private String className;
- private String name;
- private String type;
- private int hashCode = -1;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java
deleted file mode 100644
index 954b078..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/* -*- 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;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/BaseFunction.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/BaseFunction.java
deleted file mode 100644
index d7d8992..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/BaseFunction.java
+++ /dev/null
@@ -1,553 +0,0 @@
-/* -*- 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
- * Roger Lawrence
- * Mike McCabe
- *
- * 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;
-
-/**
- * The base class for Function objects
- * See ECMA 15.3.
- * @author Norris Boyd
- */
-public class BaseFunction extends IdScriptableObject implements Function
-{
-
- static final long serialVersionUID = 5311394446546053859L;
-
- private static final Object FUNCTION_TAG = new Object();
-
- static void init(Scriptable scope, boolean sealed)
- {
- BaseFunction obj = new BaseFunction();
- // Function.prototype attributes: see ECMA 15.3.3.1
- obj.prototypePropertyAttributes = DONTENUM | READONLY | PERMANENT;
- obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
- }
-
- public BaseFunction()
- {
- }
-
- public BaseFunction(Scriptable scope, Scriptable prototype)
- {
- super(scope, prototype);
- }
-
- public String getClassName() {
- return "Function";
- }
-
- /**
- * Implements the instanceof operator for JavaScript Function objects.
- * <p>
- * <code>
- * foo = new Foo();<br>
- * foo instanceof Foo; // true<br>
- * </code>
- *
- * @param instance The value that appeared on the LHS of the instanceof
- * operator
- * @return true if the "prototype" property of "this" appears in
- * value's prototype chain
- *
- */
- public boolean hasInstance(Scriptable instance)
- {
- Object protoProp = ScriptableObject.getProperty(this, "prototype");
- if (protoProp instanceof Scriptable) {
- return ScriptRuntime.jsDelegatesTo(instance, (Scriptable)protoProp);
- }
- throw ScriptRuntime.typeError1("msg.instanceof.bad.prototype",
- getFunctionName());
- }
-
-// #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;
-
- protected int getMaxInstanceId()
- {
- return MAX_INSTANCE_ID;
- }
-
- protected int findInstanceIdInfo(String s)
- {
- int id;
-// #generated# Last update: 2007-05-09 08:15:15 EDT
- 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;
- break L0;
- }
-// #/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 = prototypePropertyAttributes;
- break;
- case Id_arguments:
- attr = DONTENUM | PERMANENT;
- break;
- default: throw new IllegalStateException();
- }
- return instanceIdInfo(attr, id);
- }
-
- protected String getInstanceIdName(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";
- }
- return super.getInstanceIdName(id);
- }
-
- protected Object getInstanceIdValue(int id)
- {
- switch (id) {
- case Id_length: return ScriptRuntime.wrapInt(getLength());
- case Id_arity: return ScriptRuntime.wrapInt(getArity());
- case Id_name: return getFunctionName();
- case Id_prototype: return getPrototypeProperty();
- case Id_arguments: return getArguments();
- }
- return super.getInstanceIdValue(id);
- }
-
- protected void setInstanceIdValue(int id, Object value)
- {
- if (id == Id_prototype) {
- if ((prototypePropertyAttributes & READONLY) == 0) {
- prototypeProperty = (value != null)
- ? value : UniqueTag.NULL_VALUE;
- }
- return;
- } else if (id == Id_arguments) {
- if (value == NOT_FOUND) {
- // This should not be called since "arguments" is PERMANENT
- Kit.codeBug();
- }
- defaultPut("arguments", value);
- }
- super.setInstanceIdValue(id, value);
- }
-
- protected void fillConstructorProperties(IdFunctionObject ctor)
- {
- // Fix up bootstrapping problem: getPrototype of the IdFunctionObject
- // 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));
- }
- initPrototypeMethod(FUNCTION_TAG, id, s, arity);
- }
-
- static boolean isApply(IdFunctionObject f) {
- return f.hasTag(FUNCTION_TAG) && f.methodId() == Id_apply;
- }
-
- static boolean isApplyOrCall(IdFunctionObject f) {
- if(f.hasTag(FUNCTION_TAG)) {
- switch(f.methodId()) {
- case Id_apply:
- case Id_call:
- return true;
- }
- }
- return false;
- }
-
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(FUNCTION_TAG)) {
- return super.execIdCall(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 ScriptRuntime.applyOrCall(id == Id_apply,
- cx, scope, thisObj, args);
- }
- throw new IllegalArgumentException(String.valueOf(id));
- }
-
- private BaseFunction realFunction(Scriptable thisObj, IdFunctionObject f)
- {
- Object x = thisObj.getDefaultValue(ScriptRuntime.FunctionClass);
- if (x instanceof BaseFunction) {
- return (BaseFunction)x;
- }
- throw ScriptRuntime.typeError1("msg.incompat.call",
- f.getFunctionName());
- }
-
- /**
- * Make value as DontEnum, DontDelete, ReadOnly
- * prototype property of this Function object
- */
- public void setImmunePrototypeProperty(Object value)
- {
- if ((prototypePropertyAttributes & READONLY) != 0) {
- throw new IllegalStateException();
- }
- prototypeProperty = (value != null) ? value : UniqueTag.NULL_VALUE;
- prototypePropertyAttributes = DONTENUM | PERMANENT | READONLY;
- }
-
- protected Scriptable getClassPrototype()
- {
- Object protoVal = getPrototypeProperty();
- if (protoVal instanceof Scriptable) {
- return (Scriptable) protoVal;
- }
- return getClassPrototype(this, "Object");
- }
-
- /**
- * Should be overridden.
- */
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- return Undefined.instance;
- }
-
- public Scriptable construct(Context cx, Scriptable scope, Object[] args)
- {
- Scriptable result = createObject(cx, scope);
- if (result != null) {
- Object val = call(cx, scope, result, args);
- if (val instanceof Scriptable) {
- result = (Scriptable)val;
- }
- } else {
- Object val = call(cx, scope, null, args);
- if (!(val instanceof Scriptable)) {
- // It is program error not to return Scriptable from
- // the call method if createObject returns null.
- throw new IllegalStateException(
- "Bad implementaion of call as constructor, name="
- +getFunctionName()+" in "+getClass().getName());
- }
- result = (Scriptable)val;
- if (result.getPrototype() == null) {
- result.setPrototype(getClassPrototype());
- }
- if (result.getParentScope() == null) {
- Scriptable parent = getParentScope();
- if (result != parent) {
- result.setParentScope(parent);
- }
- }
- }
- return result;
- }
-
- /**
- * Creates new script object.
- * The default implementation of {@link #construct} uses the method to
- * to get the value for <tt>thisObj</tt> argument when invoking
- * {@link #call}.
- * The methos is allowed to return <tt>null</tt> to indicate that
- * {@link #call} will create a new object itself. In this case
- * {@link #construct} will set scope and prototype on the result
- * {@link #call} unless they are already set.
- */
- public Scriptable createObject(Context cx, Scriptable scope)
- {
- Scriptable newInstance = new NativeObject();
- newInstance.setPrototype(getClassPrototype());
- newInstance.setParentScope(getParentScope());
- return newInstance;
- }
-
- /**
- * Decompile the source information associated with this js
- * function/script back into a string.
- *
- * @param indent How much to indent the decompiled result.
- *
- * @param flags Flags specifying format of decompilation output.
- */
- 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("() {\n\t");
- }
- sb.append("[native code, arity=");
- sb.append(getArity());
- sb.append("]\n");
- if (!justbody) {
- sb.append("}\n");
- }
- return sb.toString();
- }
-
- public int getArity() { return 0; }
-
- public int getLength() { return 0; }
-
- public String getFunctionName()
- {
- return "";
- }
-
- final Object getPrototypeProperty() {
- Object result = prototypeProperty;
- if (result == null) {
- synchronized (this) {
- result = prototypeProperty;
- if (result == null) {
- setupDefaultPrototype();
- result = prototypeProperty;
- }
- }
- }
- else if (result == UniqueTag.NULL_VALUE) { result = null; }
- return result;
- }
-
- private void setupDefaultPrototype()
- {
- NativeObject obj = new NativeObject();
- final int attr = ScriptableObject.DONTENUM;
- obj.defineProperty("constructor", this, attr);
- // put the prototype property into the object now, then in the
- // wacky case of a user defining a function Object(), we don't
- // get an infinite loop trying to find the prototype.
- prototypeProperty = obj;
- Scriptable proto = getObjectPrototype(this);
- if (proto != obj) {
- // not the one we just made, it must remain grounded
- obj.setPrototype(proto);
- }
- }
-
- 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
- Object value = defaultGet("arguments");
- if (value != NOT_FOUND) {
- // Should after changing <Function name>.arguments its
- // activation still be available during Function call?
- // This code assumes it should not:
- // defaultGet("arguments") != NOT_FOUND
- // means assigned arguments
- return value;
- }
- Context cx = Context.getContext();
- NativeCall activation = ScriptRuntime.findFunctionActivation(cx, this);
- return (activation == null)
- ? null
- : activation.get("arguments", activation);
- }
-
- private static Object jsConstructor(Context cx, Scriptable scope,
- Object[] args)
- {
- int arglen = args.length;
- StringBuffer sourceBuf = new StringBuffer();
-
- sourceBuf.append("function ");
- /* version != 1.2 Function constructor behavior -
- * print 'anonymous' as the function name if the
- * version (under which the function was compiled) is
- * less than 1.2... or if it's greater than 1.2, because
- * we need to be closer to ECMA.
- */
- if (cx.getLanguageVersion() != Context.VERSION_1_2) {
- sourceBuf.append("anonymous");
- }
- sourceBuf.append('(');
-
- // Append arguments as coma separated strings
- for (int i = 0; i < arglen - 1; i++) {
- if (i > 0) {
- sourceBuf.append(',');
- }
- sourceBuf.append(ScriptRuntime.toString(args[i]));
- }
- sourceBuf.append(") {");
- if (arglen != 0) {
- // append function body
- String funBody = ScriptRuntime.toString(args[arglen - 1]);
- sourceBuf.append(funBody);
- }
- sourceBuf.append('}');
- String source = sourceBuf.toString();
-
- int[] linep = new int[1];
- String filename = Context.getSourcePositionFromStack(linep);
- if (filename == null) {
- filename = "<eval'ed string>";
- linep[0] = 1;
- }
-
- String sourceURI = ScriptRuntime.
- makeUrlForGeneratedScript(false, filename, linep[0]);
-
- Scriptable global = ScriptableObject.getTopLevelScope(scope);
-
- ErrorReporter reporter;
- reporter = DefaultErrorReporter.forEval(cx.getErrorReporter());
-
- Evaluator evaluator = Context.createInterpreter();
- if (evaluator == null) {
- throw new JavaScriptException("Interpreter not present",
- filename, linep[0]);
- }
-
- // Compile with explicit interpreter instance to force interpreter
- // mode.
- return cx.compileFunction(global, source, evaluator, reporter,
- sourceURI, 1, null);
- }
-
- protected int findPrototypeId(String s)
- {
- int id;
-// #string_id_map#
-// #generated# Last update: 2007-05-09 08:15:15 EDT
- L0: { id = 0; String X = null; int c;
- L: switch (s.length()) {
- case 4: X="call";id=Id_call; break L;
- case 5: X="apply";id=Id_apply; break L;
- case 8: c=s.charAt(3);
- if (c=='o') { X="toSource";id=Id_toSource; }
- else if (c=='t') { X="toString";id=Id_toString; }
- break L;
- case 11: X="constructor";id=Id_constructor; break L;
- }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- Id_constructor = 1,
- Id_toString = 2,
- Id_toSource = 3,
- Id_apply = 4,
- Id_call = 5,
-
- MAX_PROTOTYPE_ID = 5;
-
-// #/string_id_map#
-
- private Object prototypeProperty;
- // For function object instances, attribute is PERMANENT; see ECMA 15.3.5.2
- private int prototypePropertyAttributes = PERMANENT;
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Callable.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Callable.java
deleted file mode 100644
index 03e0fce..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Callable.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- 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):
- * Igor Bukanov, igor@fastmail.fm
- *
- * 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;
-
-/**
- * Generic notion of callable object that can execute some script-related code
- * upon request with specified values for script scope and this objects.
- */
-public interface Callable
-{
- /**
- * Perform the call.
- *
- * @param cx the current Context for this thread
- * @param scope the scope to use to resolve properties.
- * @param thisObj the JavaScript <code>this</code> object
- * @param args the array of arguments
- * @return the result of the call
- */
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args);
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassCache.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassCache.java
deleted file mode 100644
index 9047278..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassCache.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/* -*- 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):
- * Igor Bukanov, igor@fastmail.fm
- * Norris Boyd
- *
- * 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;
-
-import java.util.Map;
-import java.util.HashMap;
-
-/**
- * Cache of generated classes and data structures to access Java runtime
- * from JavaScript.
- *
- * @author Igor Bukanov
- *
- * @since Rhino 1.5 Release 5
- */
-public class ClassCache
-{
- private static final Object AKEY = new Object();
- private volatile boolean cachingIsEnabled = true;
- private HashMap<Class<?>,JavaMembers> classTable
- = new HashMap<Class<?>,JavaMembers>();
- private HashMap<Class<?>,JavaMembers> javaAdapterGeneratedClasses
- = new HashMap<Class<?>,JavaMembers>();
- private HashMap<JavaAdapter.JavaAdapterSignature,Class<?>> classAdapterCache
- = new HashMap<JavaAdapter.JavaAdapterSignature,Class<?>>();
- private HashMap<Class<?>,Object> interfaceAdapterCache;
- private int generatedClassSerial;
-
- /**
- * Search for ClassCache object in the given scope.
- * The method first calls
- * {@link ScriptableObject#getTopLevelScope(Scriptable scope)}
- * to get the top most scope and then tries to locate associated
- * ClassCache object in the prototype chain of the top scope.
- *
- * @param scope scope to search for ClassCache object.
- * @return previously associated ClassCache object or a new instance of
- * ClassCache if no ClassCache object was found.
- *
- * @see #associate(ScriptableObject topScope)
- */
- public static ClassCache get(Scriptable scope)
- {
- ClassCache cache = (ClassCache)
- ScriptableObject.getTopScopeValue(scope, AKEY);
- if (cache == null) {
- throw new RuntimeException("Can't find top level scope for " +
- "ClassCache.get");
- }
- return cache;
- }
-
- /**
- * Associate ClassCache object with the given top-level scope.
- * The ClassCache object can only be associated with the given scope once.
- *
- * @param topScope scope to associate this ClassCache object with.
- * @return true if no previous ClassCache objects were embedded into
- * the scope and this ClassCache were successfully associated
- * or false otherwise.
- *
- * @see #get(Scriptable scope)
- */
- public boolean associate(ScriptableObject topScope)
- {
- if (topScope.getParentScope() != null) {
- // Can only associate cache with top level scope
- throw new IllegalArgumentException();
- }
- if (this == topScope.associateValue(AKEY, this)) {
- return true;
- }
- return false;
- }
-
- /**
- * Empty caches of generated Java classes and Java reflection information.
- */
- public synchronized void clearCaches()
- {
- classTable.clear();
- javaAdapterGeneratedClasses.clear();
- classAdapterCache.clear();
- interfaceAdapterCache = null;
- }
-
- /**
- * Check if generated Java classes and Java reflection information
- * is cached.
- */
- public final boolean isCachingEnabled()
- {
- return cachingIsEnabled;
- }
-
- /**
- * Set whether to cache some values.
- * <p>
- * By default, the engine will cache the results of
- * <tt>Class.getMethods()</tt> and similar calls.
- * This can speed execution dramatically, but increases the memory
- * footprint. Also, with caching enabled, references may be held to
- * objects past the lifetime of any real usage.
- * <p>
- * If caching is enabled and this method is called with a
- * <code>false</code> argument, the caches will be emptied.
- * <p>
- * Caching is enabled by default.
- *
- * @param enabled if true, caching is enabled
- *
- * @see #clearCaches()
- */
- public synchronized void setCachingEnabled(boolean enabled)
- {
- if (enabled == cachingIsEnabled)
- return;
- if (!enabled)
- clearCaches();
- cachingIsEnabled = enabled;
- }
-
- /**
- * @return a map from classes to associated JavaMembers objects
- */
- Map<Class<?>,JavaMembers> getClassCacheMap() {
- return classTable;
- }
-
- Map<JavaAdapter.JavaAdapterSignature,Class<?>> getInterfaceAdapterCacheMap()
- {
- return classAdapterCache;
- }
-
- /**
- * @deprecated
- * The method always returns false.
- * @see #setInvokerOptimizationEnabled(boolean enabled)
- */
- public boolean isInvokerOptimizationEnabled()
- {
- return false;
- }
-
- /**
- * @deprecated
- * The method does nothing.
- * Invoker optimization is no longer used by Rhino.
- * On modern JDK like 1.4 or 1.5 the disadvantages of the optimization
- * like increased memory usage or longer initialization time overweight
- * small speed increase that can be gained using generated proxy class
- * to replace reflection.
- */
- public synchronized void setInvokerOptimizationEnabled(boolean enabled)
- {
- }
-
- /**
- * Internal engine method to return serial number for generated classes
- * to ensure name uniqueness.
- */
- public final synchronized int newClassSerialNumber()
- {
- return ++generatedClassSerial;
- }
-
- Object getInterfaceAdapter(Class<?> cl)
- {
- return interfaceAdapterCache == null
- ? null
- : interfaceAdapterCache.get(cl);
- }
-
- synchronized void cacheInterfaceAdapter(Class<?> cl, Object iadapter)
- {
- if (cachingIsEnabled) {
- if (interfaceAdapterCache == null) {
- interfaceAdapterCache = new HashMap<Class<?>,Object>();
- }
- interfaceAdapterCache.put(cl, iadapter);
- }
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassShutter.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassShutter.java
deleted file mode 100644
index d5f4cd6..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassShutter.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
-Embeddings that wish to filter Java classes that are visible to scripts
-through the LiveConnect, should implement this interface.
-
-@see Context#setClassShutter(ClassShutter)
-@since 1.5 Release 4
-@author Norris Boyd
-*/
-
- public interface ClassShutter {
-
- /**
- * Return true iff the Java class with the given name should be exposed
- * to scripts.
- * <p>
- * An embedding may filter which Java classes are exposed through
- * LiveConnect to JavaScript scripts.
- * <p>
- * Due to the fact that there is no package reflection in Java,
- * this method will also be called with package names. There
- * is no way for Rhino to tell if "Packages.a.b" is a package name
- * or a class that doesn't exist. What Rhino does is attempt
- * to load each segment of "Packages.a.b.c": It first attempts to
- * load class "a", then attempts to load class "a.b", then
- * finally attempts to load class "a.b.c". On a Rhino installation
- * without any ClassShutter set, and without any of the
- * above classes, the expression "Packages.a.b.c" will result in
- * a [JavaPackage a.b.c] and not an error.
- * <p>
- * With ClassShutter supplied, Rhino will first call
- * visibleToScripts before attempting to look up the class name. If
- * visibleToScripts returns false, the class name lookup is not
- * performed and subsequent Rhino execution assumes the class is
- * not present. So for "java.lang.System.out.println" the lookup
- * of "java.lang.System" is skipped and thus Rhino assumes that
- * "java.lang.System" doesn't exist. So then for "java.lang.System.out",
- * Rhino attempts to load the class "java.lang.System.out" because
- * it assumes that "java.lang.System" is a package name.
- * <p>
- * @param fullClassName the full name of the class (including the package
- * name, with '.' as a delimiter). For example the
- * standard string class is "java.lang.String"
- * @return whether or not to reveal this class to scripts
- */
- public boolean visibleToScripts(String fullClassName);
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/CompilerEnvirons.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/CompilerEnvirons.java
deleted file mode 100644
index 645d098..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/CompilerEnvirons.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/* -*- 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):
- * Igor Bukanov, igor@fastmail.fm
- * Bob Jervis
- *
- * 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;
-
-import java.util.Hashtable;
-
-public class CompilerEnvirons
-{
- public CompilerEnvirons()
- {
- errorReporter = DefaultErrorReporter.instance;
- languageVersion = Context.VERSION_DEFAULT;
- generateDebugInfo = true;
- useDynamicScope = false;
- reservedKeywordAsIdentifier = false;
- allowMemberExprAsFunctionName = false;
- xmlAvailable = true;
- optimizationLevel = 0;
- generatingSource = true;
- strictMode = false;
- warningAsError = false;
- generateObserverCount = false;
- }
-
- public void initFromContext(Context cx)
- {
- setErrorReporter(cx.getErrorReporter());
- this.languageVersion = cx.getLanguageVersion();
- useDynamicScope = cx.compileFunctionsWithDynamicScopeFlag;
- generateDebugInfo = (!cx.isGeneratingDebugChanged()
- || cx.isGeneratingDebug());
- reservedKeywordAsIdentifier
- = cx.hasFeature(Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER);
- allowMemberExprAsFunctionName
- = cx.hasFeature(Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME);
- strictMode
- = cx.hasFeature(Context.FEATURE_STRICT_MODE);
- warningAsError = cx.hasFeature(Context.FEATURE_WARNING_AS_ERROR);
- xmlAvailable
- = cx.hasFeature(Context.FEATURE_E4X);
-
- optimizationLevel = cx.getOptimizationLevel();
-
- generatingSource = cx.isGeneratingSource();
- activationNames = cx.activationNames;
-
- // Observer code generation in compiled code :
- generateObserverCount = cx.generateObserverCount;
- }
-
- public final ErrorReporter getErrorReporter()
- {
- return errorReporter;
- }
-
- public void setErrorReporter(ErrorReporter errorReporter)
- {
- if (errorReporter == null) throw new IllegalArgumentException();
- this.errorReporter = errorReporter;
- }
-
- public final int getLanguageVersion()
- {
- return languageVersion;
- }
-
- public void setLanguageVersion(int languageVersion)
- {
- Context.checkLanguageVersion(languageVersion);
- this.languageVersion = languageVersion;
- }
-
- public final boolean isGenerateDebugInfo()
- {
- return generateDebugInfo;
- }
-
- public void setGenerateDebugInfo(boolean flag)
- {
- this.generateDebugInfo = flag;
- }
-
- public final boolean isUseDynamicScope()
- {
- return useDynamicScope;
- }
-
- public final boolean isReservedKeywordAsIdentifier()
- {
- return reservedKeywordAsIdentifier;
- }
-
- public void setReservedKeywordAsIdentifier(boolean flag)
- {
- reservedKeywordAsIdentifier = flag;
- }
-
- public final boolean isAllowMemberExprAsFunctionName()
- {
- return allowMemberExprAsFunctionName;
- }
-
- public void setAllowMemberExprAsFunctionName(boolean flag)
- {
- allowMemberExprAsFunctionName = flag;
- }
-
- public final boolean isXmlAvailable()
- {
- return xmlAvailable;
- }
-
- public void setXmlAvailable(boolean flag)
- {
- xmlAvailable = flag;
- }
-
- public final int getOptimizationLevel()
- {
- return optimizationLevel;
- }
-
- public void setOptimizationLevel(int level)
- {
- Context.checkOptimizationLevel(level);
- this.optimizationLevel = level;
- }
-
- public final boolean isGeneratingSource()
- {
- return generatingSource;
- }
-
- public final boolean isStrictMode()
- {
- return strictMode;
- }
-
- public final boolean reportWarningAsError()
- {
- return warningAsError;
- }
-
- /**
- * Specify whether or not source information should be generated.
- * <p>
- * Without source information, evaluating the "toString" method
- * on JavaScript functions produces only "[native code]" for
- * the body of the function.
- * Note that code generated without source is not fully ECMA
- * conformant.
- */
- public void setGeneratingSource(boolean generatingSource)
- {
- this.generatingSource = generatingSource;
- }
-
- /**
- * @return true iff code will be generated with callbacks to enable
- * instruction thresholds
- */
- public boolean isGenerateObserverCount() {
- return generateObserverCount;
- }
-
- /**
- * Turn on or off generation of code with callbacks to
- * track the count of executed instructions.
- * Currently only affects JVM byte code generation: this slows down the
- * generated code, but code generated without the callbacks will not
- * be counted toward instruction thresholds. Rhino's interpretive
- * mode does instruction counting without inserting callbacks, so
- * there is no requirement to compile code differently.
- * @param generateObserverCount if true, generated code will contain
- * calls to accumulate an estimate of the instructions executed.
- */
- public void setGenerateObserverCount(boolean generateObserverCount) {
- this.generateObserverCount = generateObserverCount;
- }
-
- private ErrorReporter errorReporter;
-
- private int languageVersion;
- private boolean generateDebugInfo;
- private boolean useDynamicScope;
- private boolean reservedKeywordAsIdentifier;
- private boolean allowMemberExprAsFunctionName;
- private boolean xmlAvailable;
- private int optimizationLevel;
- private boolean generatingSource;
- private boolean strictMode;
- private boolean warningAsError;
- private boolean generateObserverCount;
- Hashtable activationNames;
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ConstProperties.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ConstProperties.java
deleted file mode 100644
index 860db79..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ConstProperties.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/* -*- 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):
- * Bob Jervis
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-public interface ConstProperties {
- /**
- * Sets a named const property in this object.
- * <p>
- * The property is specified by a string name
- * as defined for <code>Scriptable.get</code>.
- * <p>
- * The possible values that may be passed in are as defined for
- * <code>Scriptable.get</code>. A class that implements this method may choose
- * to ignore calls to set certain properties, in which case those
- * properties are effectively read-only.<p>
- * For properties defined in a prototype chain,
- * use <code>putProperty</code> in ScriptableObject. <p>
- * Note that if a property <i>a</i> is defined in the prototype <i>p</i>
- * of an object <i>o</i>, then evaluating <code>o.a = 23</code> will cause
- * <code>set</code> to be called on the prototype <i>p</i> with
- * <i>o</i> as the <i>start</i> parameter.
- * To preserve JavaScript semantics, it is the Scriptable
- * object's responsibility to modify <i>o</i>. <p>
- * This design allows properties to be defined in prototypes and implemented
- * in terms of getters and setters of Java values without consuming slots
- * in each instance.<p>
- * <p>
- * The values that may be set are limited to the following:
- * <UL>
- * <LI>java.lang.Boolean objects</LI>
- * <LI>java.lang.String objects</LI>
- * <LI>java.lang.Number objects</LI>
- * <LI>org.mozilla.javascript.Scriptable objects</LI>
- * <LI>null</LI>
- * <LI>The value returned by Context.getUndefinedValue()</LI>
- * </UL><p>
- * Arbitrary Java objects may be wrapped in a Scriptable by first calling
- * <code>Context.toObject</code>. This allows the property of a JavaScript
- * object to contain an arbitrary Java object as a value.<p>
- * Note that <code>has</code> will be called by the runtime first before
- * <code>set</code> is called to determine in which object the
- * property is defined.
- * Note that this method is not expected to traverse the prototype chain,
- * which is different from the ECMA [[Put]] operation.
- * @param name the name of the property
- * @param start the object whose property is being set
- * @param value value to set the property to
- * @see org.mozilla.javascript.Scriptable#has(String, Scriptable)
- * @see org.mozilla.javascript.Scriptable#get(String, Scriptable)
- * @see org.mozilla.javascript.ScriptableObject#putProperty(Scriptable, String, Object)
- * @see org.mozilla.javascript.Context#toObject(Object, Scriptable)
- */
- public void putConst(String name, Scriptable start, Object value);
-
- /**
- * Reserves a definition spot for a const. This will set up a definition
- * of the const property, but set its value to undefined. The semantics of
- * the start parameter is the same as for putConst.
- * @param name The name of the property.
- * @param start The object whose property is being reserved.
- */
- public void defineConst(String name, Scriptable start);
-
- /**
- * Returns true if the named property is defined as a const on this object.
- * @param name
- * @return true if the named property is defined as a const, false
- * otherwise.
- */
- public boolean isConst(String name);
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java
deleted file mode 100644
index 0833883..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java
+++ /dev/null
@@ -1,2526 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Bob Jervis
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.io.CharArrayWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Hashtable;
-import java.util.Locale;
-
-import org.mozilla.javascript.debug.DebuggableScript;
-import org.mozilla.javascript.debug.Debugger;
-import org.mozilla.javascript.xml.XMLLib;
-
-/**
- * This class represents the runtime context of an executing script.
- *
- * Before executing a script, an instance of Context must be created
- * and associated with the thread that will be executing the script.
- * The Context will be used to store information about the executing
- * of the script such as the call stack. Contexts are associated with
- * the current thread using the {@link #call(ContextAction)}
- * or {@link #enter()} methods.<p>
- *
- * Different forms of script execution are supported. Scripts may be
- * evaluated from the source directly, or first compiled and then later
- * executed. Interactive execution is also supported.<p>
- *
- * Some aspects of script execution, such as type conversions and
- * object creation, may be accessed directly through methods of
- * Context.
- *
- * @see Scriptable
- * @author Norris Boyd
- * @author Brendan Eich
- */
-
-public class Context
-{
- /**
- * Language versions.
- *
- * All integral values are reserved for future version numbers.
- */
-
- /**
- * The unknown version.
- */
- public static final int VERSION_UNKNOWN = -1;
-
- /**
- * The default version.
- */
- public static final int VERSION_DEFAULT = 0;
-
- /**
- * JavaScript 1.0
- */
- public static final int VERSION_1_0 = 100;
-
- /**
- * JavaScript 1.1
- */
- public static final int VERSION_1_1 = 110;
-
- /**
- * JavaScript 1.2
- */
- public static final int VERSION_1_2 = 120;
-
- /**
- * JavaScript 1.3
- */
- public static final int VERSION_1_3 = 130;
-
- /**
- * JavaScript 1.4
- */
- public static final int VERSION_1_4 = 140;
-
- /**
- * JavaScript 1.5
- */
- public static final int VERSION_1_5 = 150;
-
- /**
- * JavaScript 1.6
- */
- public static final int VERSION_1_6 = 160;
-
- /**
- * JavaScript 1.7
- */
- public static final int VERSION_1_7 = 170;
-
- /**
- * Controls behaviour of <tt>Date.prototype.getYear()</tt>.
- * If <tt>hasFeature(FEATURE_NON_ECMA_GET_YEAR)</tt> returns true,
- * Date.prototype.getYear subtructs 1900 only if 1900 <= date < 2000.
- * The default behavior of {@link #hasFeature(int)} is always to subtruct
- * 1900 as rquired by ECMAScript B.2.4.
- */
- public static final int FEATURE_NON_ECMA_GET_YEAR = 1;
-
- /**
- * Control if member expression as function name extension is available.
- * If <tt>hasFeature(FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME)</tt> returns
- * true, allow <tt>function memberExpression(args) { body }</tt> to be
- * syntax sugar for <tt>memberExpression = function(args) { body }</tt>,
- * when memberExpression is not a simple identifier.
- * See ECMAScript-262, section 11.2 for definition of memberExpression.
- * By default {@link #hasFeature(int)} returns false.
- */
- public static final int FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME = 2;
-
- /**
- * Control if reserved keywords are treated as identifiers.
- * If <tt>hasFeature(RESERVED_KEYWORD_AS_IDENTIFIER)</tt> returns true,
- * treat future reserved keyword (see Ecma-262, section 7.5.3) as ordinary
- * identifiers but warn about this usage.
- *
- * By default {@link #hasFeature(int)} returns false.
- */
- public static final int FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER = 3;
-
- /**
- * Control if <tt>toString()</tt> should returns the same result
- * as <tt>toSource()</tt> when applied to objects and arrays.
- * If <tt>hasFeature(FEATURE_TO_STRING_AS_SOURCE)</tt> returns true,
- * calling <tt>toString()</tt> on JS objects gives the same result as
- * calling <tt>toSource()</tt>. That is it returns JS source with code
- * to create an object with all enumeratable fields of the original object
- * instead of printing <tt>[object <i>result of
- * {@link Scriptable#getClassName()}</i>]</tt>.
- * <p>
- * By default {@link #hasFeature(int)} returns true only if
- * the current JS version is set to {@link #VERSION_1_2}.
- */
- public static final int FEATURE_TO_STRING_AS_SOURCE = 4;
-
- /**
- * Control if properties <tt>__proto__</tt> and <tt>__parent__</tt>
- * are treated specially.
- * If <tt>hasFeature(FEATURE_PARENT_PROTO_PROPERTIES)</tt> returns true,
- * treat <tt>__parent__</tt> and <tt>__proto__</tt> as special properties.
- * <p>
- * The properties allow to query and set scope and prototype chains for the
- * objects. The special meaning of the properties is available
- * only when they are used as the right hand side of the dot operator.
- * For example, while <tt>x.__proto__ = y</tt> changes the prototype
- * chain of the object <tt>x</tt> to point to <tt>y</tt>,
- * <tt>x["__proto__"] = y</tt> simply assigns a new value to the property
- * <tt>__proto__</tt> in <tt>x</tt> even when the feature is on.
- *
- * By default {@link #hasFeature(int)} returns true.
- */
- public static final int FEATURE_PARENT_PROTO_PROPERTIES = 5;
-
- /**
- * @deprecated In previous releases, this name was given to
- * FEATURE_PARENT_PROTO_PROPERTIES.
- */
- public static final int FEATURE_PARENT_PROTO_PROPRTIES = 5;
-
- /**
- * Control if support for E4X(ECMAScript for XML) extension is available.
- * If hasFeature(FEATURE_E4X) returns true, the XML syntax is available.
- * <p>
- * By default {@link #hasFeature(int)} returns true if
- * the current JS version is set to {@link #VERSION_DEFAULT}
- * or is at least {@link #VERSION_1_6}.
- * @since 1.6 Release 1
- */
- public static final int FEATURE_E4X = 6;
-
- /**
- * Control if dynamic scope should be used for name access.
- * If hasFeature(FEATURE_DYNAMIC_SCOPE) returns true, then the name lookup
- * during name resolution will use the top scope of the script or function
- * which is at the top of JS execution stack instead of the top scope of the
- * script or function from the current stack frame if the top scope of
- * the top stack frame contains the top scope of the current stack frame
- * on its prototype chain.
- * <p>
- * This is useful to define shared scope containing functions that can
- * be called from scripts and functions using private scopes.
- * <p>
- * By default {@link #hasFeature(int)} returns false.
- * @since 1.6 Release 1
- */
- public static final int FEATURE_DYNAMIC_SCOPE = 7;
-
- /**
- * Control if strict variable mode is enabled.
- * When the feature is on Rhino reports runtime errors if assignment
- * to a global variable that does not exist is executed. When the feature
- * is off such assignments creates new variable in the global scope as
- * required by ECMA 262.
- * <p>
- * By default {@link #hasFeature(int)} returns false.
- * @since 1.6 Release 1
- */
- public static final int FEATURE_STRICT_VARS = 8;
-
- /**
- * Control if strict eval mode is enabled.
- * When the feature is on Rhino reports runtime errors if non-string
- * argument is passed to the eval function. When the feature is off
- * eval simply return non-string argument as is without performing any
- * evaluation as required by ECMA 262.
- * <p>
- * By default {@link #hasFeature(int)} returns false.
- * @since 1.6 Release 1
- */
- public static final int FEATURE_STRICT_EVAL = 9;
-
- /**
- * When the feature is on Rhino will add a "fileName" and "lineNumber"
- * properties to Error objects automatically. When the feature is off, you
- * have to explicitly pass them as the second and third argument to the
- * Error constructor. Note that neither behaviour is fully ECMA 262
- * compliant (as 262 doesn't specify a three-arg constructor), but keeping
- * the feature off results in Error objects that don't have
- * additional non-ECMA properties when constructed using the ECMA-defined
- * single-arg constructor and is thus desirable if a stricter ECMA
- * compliance is desired, specifically adherence to the point 15.11.5. of
- * the standard.
- * <p>
- * By default {@link #hasFeature(int)} returns false.
- * @since 1.6 Release 6
- */
- public static final int FEATURE_LOCATION_INFORMATION_IN_ERROR = 10;
-
- /**
- * Controls whether JS 1.5 'strict mode' is enabled.
- * When the feature is on, Rhino reports more than a dozen different
- * warnings. When the feature is off, these warnings are not generated.
- * FEATURE_STRICT_MODE implies FEATURE_STRICT_VARS and FEATURE_STRICT_EVAL.
- * <p>
- * By default {@link #hasFeature(int)} returns false.
- * @since 1.6 Release 6
- */
- public static final int FEATURE_STRICT_MODE = 11;
-
- /**
- * Controls whether a warning should be treated as an error.
- * @since 1.6 Release 6
- */
- public static final int FEATURE_WARNING_AS_ERROR = 12;
-
- /**
- * Enables enhanced access to Java.
- * Specifically, controls whether private and protected members can be
- * accessed, and whether scripts can catch all Java exceptions.
- * <p>
- * Note that this feature should only be enabled for trusted scripts.
- * <p>
- * By default {@link #hasFeature(int)} returns false.
- * @since 1.7 Release 1
- */
- public static final int FEATURE_ENHANCED_JAVA_ACCESS = 13;
-
-
- public static final String languageVersionProperty = "language version";
- public static final String errorReporterProperty = "error reporter";
-
- /**
- * Convenient value to use as zero-length array of objects.
- */
- public static final Object[] emptyArgs = ScriptRuntime.emptyArgs;
-
- /**
- * Create a new Context.
- *
- * Note that the Context must be associated with a thread before
- * it can be used to execute a script.
- * @deprecated use {@link ContextFactory#enter()} or
- * {@link ContextFactory#call(ContextAction)} instead.
- */
- public Context()
- {
- this(ContextFactory.getGlobal());
- }
-
- Context(ContextFactory factory)
- {
- assert factory != null;
- this.factory = factory;
- setLanguageVersion(VERSION_DEFAULT);
- optimizationLevel = codegenClass != null ? 0 : -1;
- maximumInterpreterStackDepth = Integer.MAX_VALUE;
- }
-
- /**
- * Get the current Context.
- *
- * The current Context is per-thread; this method looks up
- * the Context associated with the current thread. <p>
- *
- * @return the Context associated with the current thread, or
- * null if no context is associated with the current
- * thread.
- * @see ContextFactory#enterContext()
- * @see ContextFactory#call(ContextAction)
- */
- public static Context getCurrentContext()
- {
- Object helper = VMBridge.instance.getThreadContextHelper();
- return VMBridge.instance.getContext(helper);
- }
-
- /**
- * Same as calling {@link ContextFactory#enterContext()} on the global
- * ContextFactory instance.
- * @deprecated use {@link ContextFactory#enter()} or
- * {@link ContextFactory#call(ContextAction)} instead as this method relies
- * on usage of a static singleton "global" ContextFactory.
- * @return a Context associated with the current thread
- * @see #getCurrentContext()
- * @see #exit()
- * @see #call(ContextAction)
- */
- public static Context enter()
- {
- return enter(null);
- }
-
- /**
- * Get a Context associated with the current thread, using
- * the given Context if need be.
- * <p>
- * The same as <code>enter()</code> except that <code>cx</code>
- * is associated with the current thread and returned if
- * the current thread has no associated context and <code>cx</code>
- * is not associated with any other thread.
- * @param cx a Context to associate with the thread if possible
- * @return a Context associated with the current thread
- * @deprecated use {@link ContextFactory#enterContext(Context)} instead as
- * this method relies on usage of a static singleton "global" ContextFactory.
- * @see ContextFactory#enterContext(Context)
- * @see ContextFactory#call(ContextAction)
- */
- public static Context enter(Context cx)
- {
- return enter(cx, ContextFactory.getGlobal());
- }
-
- static final Context enter(Context cx, ContextFactory factory)
- {
- Object helper = VMBridge.instance.getThreadContextHelper();
- Context old = VMBridge.instance.getContext(helper);
- if (old != null) {
- cx = old;
- } else {
- if (cx == null) {
- cx = factory.makeContext();
- if (cx.enterCount != 0) {
- throw new IllegalStateException("factory.makeContext() returned Context instance already associated with some thread");
- }
- factory.onContextCreated(cx);
- if (factory.isSealed() && !cx.isSealed()) {
- cx.seal(null);
- }
- } else {
- if (cx.enterCount != 0) {
- throw new IllegalStateException("can not use Context instance already associated with some thread");
- }
- }
- VMBridge.instance.setContext(helper, cx);
- }
- ++cx.enterCount;
- return cx;
- }
-
- /**
- * Exit a block of code requiring a Context.
- *
- * Calling <code>exit()</code> will remove the association between
- * the current thread and a Context if the prior call to
- * {@link ContextFactory#enterContext()} on this thread newly associated a
- * Context with this thread. Once the current thread no longer has an
- * associated Context, it cannot be used to execute JavaScript until it is
- * again associated with a Context.
- * @see ContextFactory#enterContext()
- */
- public static void exit()
- {
- Object helper = VMBridge.instance.getThreadContextHelper();
- Context cx = VMBridge.instance.getContext(helper);
- if (cx == null) {
- throw new IllegalStateException(
- "Calling Context.exit without previous Context.enter");
- }
- if (cx.enterCount < 1) Kit.codeBug();
- if (--cx.enterCount == 0) {
- VMBridge.instance.setContext(helper, null);
- cx.factory.onContextReleased(cx);
- }
- }
-
- /**
- * Call {@link ContextAction#run(Context cx)}
- * using the Context instance associated with the current thread.
- * If no Context is associated with the thread, then
- * <tt>ContextFactory.getGlobal().makeContext()</tt> will be called to
- * construct new Context instance. The instance will be temporary
- * associated with the thread during call to
- * {@link ContextAction#run(Context)}.
- * @deprecated use {@link ContextFactory#call(ContextAction)} instead as
- * this method relies on usage of a static singleton "global"
- * ContextFactory.
- * @return The result of {@link ContextAction#run(Context)}.
- */
- public static Object call(ContextAction action)
- {
- return call(ContextFactory.getGlobal(), action);
- }
-
- /**
- * Call {@link
- * Callable#call(Context cx, Scriptable scope, Scriptable thisObj,
- * Object[] args)}
- * using the Context instance associated with the current thread.
- * If no Context is associated with the thread, then
- * {@link ContextFactory#makeContext()} will be called to construct
- * new Context instance. The instance will be temporary associated
- * with the thread during call to {@link ContextAction#run(Context)}.
- * <p>
- * It is allowed but not advisable to use null for <tt>factory</tt>
- * argument in which case the global static singleton ContextFactory
- * instance will be used to create new context instances.
- * @see ContextFactory#call(ContextAction)
- */
- public static Object call(ContextFactory factory, final Callable callable,
- final Scriptable scope, final Scriptable thisObj,
- final Object[] args)
- {
- if(factory == null) {
- factory = ContextFactory.getGlobal();
- }
- return call(factory, new ContextAction() {
- public Object run(Context cx) {
- return callable.call(cx, scope, thisObj, args);
- }
- });
- }
-
- /**
- * The method implements {@links ContextFactory#call(ContextAction)} logic.
- */
- static Object call(ContextFactory factory, ContextAction action) {
- Context cx = enter(null, factory);
- try {
- return action.run(cx);
- }
- finally {
- exit();
- }
- }
-
- /**
- * @deprecated
- * @see ContextFactory#addListener(ContextFactory.Listener)
- * @see ContextFactory#getGlobal()
- */
- public static void addContextListener(ContextListener listener)
- {
- // Special workaround for the debugger
- String DBG = "org.mozilla.javascript.tools.debugger.Main";
- if (DBG.equals(listener.getClass().getName())) {
- Class cl = listener.getClass();
- Class factoryClass = Kit.classOrNull(
- "org.mozilla.javascript.ContextFactory");
- Class[] sig = { factoryClass };
- Object[] args = { ContextFactory.getGlobal() };
- try {
- Method m = cl.getMethod("attachTo", sig);
- m.invoke(listener, args);
- } catch (Exception ex) {
- RuntimeException rex = new RuntimeException();
- Kit.initCause(rex, ex);
- throw rex;
- }
- return;
- }
-
- ContextFactory.getGlobal().addListener(listener);
- }
-
- /**
- * @deprecated
- * @see ContextFactory#removeListener(ContextFactory.Listener)
- * @see ContextFactory#getGlobal()
- */
- public static void removeContextListener(ContextListener listener)
- {
- ContextFactory.getGlobal().addListener(listener);
- }
-
- /**
- * Return {@link ContextFactory} instance used to create this Context.
- */
- public final ContextFactory getFactory()
- {
- return factory;
- }
-
- /**
- * Checks if this is a sealed Context. A sealed Context instance does not
- * allow to modify any of its properties and will throw an exception
- * on any such attempt.
- * @see #seal(Object sealKey)
- */
- public final boolean isSealed()
- {
- return sealed;
- }
-
- /**
- * Seal this Context object so any attempt to modify any of its properties
- * including calling {@link #enter()} and {@link #exit()} methods will
- * throw an exception.
- * <p>
- * If <tt>sealKey</tt> is not null, calling
- * {@link #unseal(Object sealKey)} with the same key unseals
- * the object. If <tt>sealKey</tt> is null, unsealing is no longer possible.
- *
- * @see #isSealed()
- * @see #unseal(Object)
- */
- public final void seal(Object sealKey)
- {
- if (sealed) onSealedMutation();
- sealed = true;
- this.sealKey = sealKey;
- }
-
- /**
- * Unseal previously sealed Context object.
- * The <tt>sealKey</tt> argument should not be null and should match
- * <tt>sealKey</tt> suplied with the last call to
- * {@link #seal(Object)} or an exception will be thrown.
- *
- * @see #isSealed()
- * @see #seal(Object sealKey)
- */
- public final void unseal(Object sealKey)
- {
- if (sealKey == null) throw new IllegalArgumentException();
- if (this.sealKey != sealKey) throw new IllegalArgumentException();
- if (!sealed) throw new IllegalStateException();
- sealed = false;
- this.sealKey = null;
- }
-
- static void onSealedMutation()
- {
- throw new IllegalStateException();
- }
-
- /**
- * Get the current language version.
- * <p>
- * The language version number affects JavaScript semantics as detailed
- * in the overview documentation.
- *
- * @return an integer that is one of VERSION_1_0, VERSION_1_1, etc.
- */
- public final int getLanguageVersion()
- {
- return version;
- }
-
- /**
- * Set the language version.
- *
- * <p>
- * Setting the language version will affect functions and scripts compiled
- * subsequently. See the overview documentation for version-specific
- * behavior.
- *
- * @param version the version as specified by VERSION_1_0, VERSION_1_1, etc.
- */
- public void setLanguageVersion(int version)
- {
- if (sealed) onSealedMutation();
- checkLanguageVersion(version);
- Object listeners = propertyListeners;
- if (listeners != null && version != this.version) {
- firePropertyChangeImpl(listeners, languageVersionProperty,
- new Integer(this.version),
- new Integer(version));
- }
- this.version = version;
- }
-
- public static boolean isValidLanguageVersion(int version)
- {
- switch (version) {
- case VERSION_DEFAULT:
- case VERSION_1_0:
- case VERSION_1_1:
- case VERSION_1_2:
- case VERSION_1_3:
- case VERSION_1_4:
- case VERSION_1_5:
- case VERSION_1_6:
- case VERSION_1_7:
- return true;
- }
- return false;
- }
-
- public static void checkLanguageVersion(int version)
- {
- if (isValidLanguageVersion(version)) {
- return;
- }
- throw new IllegalArgumentException("Bad language version: "+version);
- }
-
- /**
- * Get the implementation version.
- *
- * <p>
- * The implementation version is of the form
- * <pre>
- * "<i>name langVer</i> <code>release</code> <i>relNum date</i>"
- * </pre>
- * where <i>name</i> is the name of the product, <i>langVer</i> is
- * the language version, <i>relNum</i> is the release number, and
- * <i>date</i> is the release date for that specific
- * release in the form "yyyy mm dd".
- *
- * @return a string that encodes the product, language version, release
- * number, and date.
- */
- public final String getImplementationVersion()
- {
- // XXX Probably it would be better to embed this directly into source
- // with special build preprocessing but that would require some ant
- // tweaking and then replacing token in resource files was simpler
- if (implementationVersion == null) {
- implementationVersion
- = ScriptRuntime.getMessage0("implementation.version");
- }
- return implementationVersion;
- }
-
- /**
- * Get the current error reporter.
- *
- * @see org.mozilla.javascript.ErrorReporter
- */
- public final ErrorReporter getErrorReporter()
- {
- if (errorReporter == null) {
- return DefaultErrorReporter.instance;
- }
- return errorReporter;
- }
-
- /**
- * Change the current error reporter.
- *
- * @return the previous error reporter
- * @see org.mozilla.javascript.ErrorReporter
- */
- public final ErrorReporter setErrorReporter(ErrorReporter reporter)
- {
- if (sealed) onSealedMutation();
- if (reporter == null) throw new IllegalArgumentException();
- ErrorReporter old = getErrorReporter();
- if (reporter == old) {
- return old;
- }
- Object listeners = propertyListeners;
- if (listeners != null) {
- firePropertyChangeImpl(listeners, errorReporterProperty,
- old, reporter);
- }
- this.errorReporter = reporter;
- return old;
- }
-
- /**
- * Get the current locale. Returns the default locale if none has
- * been set.
- *
- * @see java.util.Locale
- */
-
- public final Locale getLocale()
- {
- if (locale == null)
- locale = Locale.getDefault();
- return locale;
- }
-
- /**
- * Set the current locale.
- *
- * @see java.util.Locale
- */
- public final Locale setLocale(Locale loc)
- {
- if (sealed) onSealedMutation();
- Locale result = locale;
- locale = loc;
- return result;
- }
-
- /**
- * Register an object to receive notifications when a bound property
- * has changed
- * @see java.beans.PropertyChangeEvent
- * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
- * @param l the listener
- */
- public final void addPropertyChangeListener(PropertyChangeListener l)
- {
- if (sealed) onSealedMutation();
- propertyListeners = Kit.addListener(propertyListeners, l);
- }
-
- /**
- * Remove an object from the list of objects registered to receive
- * notification of changes to a bounded property
- * @see java.beans.PropertyChangeEvent
- * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
- * @param l the listener
- */
- public final void removePropertyChangeListener(PropertyChangeListener l)
- {
- if (sealed) onSealedMutation();
- propertyListeners = Kit.removeListener(propertyListeners, l);
- }
-
- /**
- * Notify any registered listeners that a bounded property has changed
- * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
- * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
- * @see java.beans.PropertyChangeListener
- * @see java.beans.PropertyChangeEvent
- * @param property the bound property
- * @param oldValue the old value
- * @param newValue the new value
- */
- final void firePropertyChange(String property, Object oldValue,
- Object newValue)
- {
- Object listeners = propertyListeners;
- if (listeners != null) {
- firePropertyChangeImpl(listeners, property, oldValue, newValue);
- }
- }
-
- private void firePropertyChangeImpl(Object listeners, String property,
- Object oldValue, Object newValue)
- {
- for (int i = 0; ; ++i) {
- Object l = Kit.getListener(listeners, i);
- if (l == null)
- break;
- if (l instanceof PropertyChangeListener) {
- PropertyChangeListener pcl = (PropertyChangeListener)l;
- pcl.propertyChange(new PropertyChangeEvent(
- this, property, oldValue, newValue));
- }
- }
- }
-
- /**
- * Report a warning using the error reporter for the current thread.
- *
- * @param message the warning message to report
- * @param sourceName a string describing the source, such as a filename
- * @param lineno the starting line number
- * @param lineSource the text of the line (may be null)
- * @param lineOffset the offset into lineSource where problem was detected
- * @see org.mozilla.javascript.ErrorReporter
- */
- public static void reportWarning(String message, String sourceName,
- int lineno, String lineSource,
- int lineOffset)
- {
- Context cx = Context.getContext();
- if (cx.hasFeature(FEATURE_WARNING_AS_ERROR))
- reportError(message, sourceName, lineno, lineSource, lineOffset);
- else
- cx.getErrorReporter().warning(message, sourceName, lineno,
- lineSource, lineOffset);
- }
-
- /**
- * Report a warning using the error reporter for the current thread.
- *
- * @param message the warning message to report
- * @see org.mozilla.javascript.ErrorReporter
- */
- public static void reportWarning(String message)
- {
- int[] linep = { 0 };
- String filename = getSourcePositionFromStack(linep);
- Context.reportWarning(message, filename, linep[0], null, 0);
- }
-
- public static void reportWarning(String message, Throwable t)
- {
- int[] linep = { 0 };
- String filename = getSourcePositionFromStack(linep);
- Writer sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- pw.println(message);
- t.printStackTrace(pw);
- pw.flush();
- Context.reportWarning(sw.toString(), filename, linep[0], null, 0);
- }
-
- /**
- * Report an error using the error reporter for the current thread.
- *
- * @param message the error message to report
- * @param sourceName a string describing the source, such as a filename
- * @param lineno the starting line number
- * @param lineSource the text of the line (may be null)
- * @param lineOffset the offset into lineSource where problem was detected
- * @see org.mozilla.javascript.ErrorReporter
- */
- public static void reportError(String message, String sourceName,
- int lineno, String lineSource,
- int lineOffset)
- {
- Context cx = getCurrentContext();
- if (cx != null) {
- cx.getErrorReporter().error(message, sourceName, lineno,
- lineSource, lineOffset);
- } else {
- throw new EvaluatorException(message, sourceName, lineno,
- lineSource, lineOffset);
- }
- }
-
- /**
- * Report an error using the error reporter for the current thread.
- *
- * @param message the error message to report
- * @see org.mozilla.javascript.ErrorReporter
- */
- public static void reportError(String message)
- {
- int[] linep = { 0 };
- String filename = getSourcePositionFromStack(linep);
- Context.reportError(message, filename, linep[0], null, 0);
- }
-
- /**
- * Report a runtime error using the error reporter for the current thread.
- *
- * @param message the error message to report
- * @param sourceName a string describing the source, such as a filename
- * @param lineno the starting line number
- * @param lineSource the text of the line (may be null)
- * @param lineOffset the offset into lineSource where problem was detected
- * @return a runtime exception that will be thrown to terminate the
- * execution of the script
- * @see org.mozilla.javascript.ErrorReporter
- */
- public static EvaluatorException reportRuntimeError(String message,
- String sourceName,
- int lineno,
- String lineSource,
- int lineOffset)
- {
- Context cx = getCurrentContext();
- if (cx != null) {
- return cx.getErrorReporter().
- runtimeError(message, sourceName, lineno,
- lineSource, lineOffset);
- } else {
- throw new EvaluatorException(message, sourceName, lineno,
- lineSource, lineOffset);
- }
- }
-
- static EvaluatorException reportRuntimeError0(String messageId)
- {
- String msg = ScriptRuntime.getMessage0(messageId);
- return reportRuntimeError(msg);
- }
-
- static EvaluatorException reportRuntimeError1(String messageId,
- Object arg1)
- {
- String msg = ScriptRuntime.getMessage1(messageId, arg1);
- return reportRuntimeError(msg);
- }
-
- static EvaluatorException reportRuntimeError2(String messageId,
- Object arg1, Object arg2)
- {
- String msg = ScriptRuntime.getMessage2(messageId, arg1, arg2);
- return reportRuntimeError(msg);
- }
-
- static EvaluatorException reportRuntimeError3(String messageId,
- Object arg1, Object arg2,
- Object arg3)
- {
- String msg = ScriptRuntime.getMessage3(messageId, arg1, arg2, arg3);
- return reportRuntimeError(msg);
- }
-
- static EvaluatorException reportRuntimeError4(String messageId,
- Object arg1, Object arg2,
- Object arg3, Object arg4)
- {
- String msg
- = ScriptRuntime.getMessage4(messageId, arg1, arg2, arg3, arg4);
- return reportRuntimeError(msg);
- }
-
- /**
- * Report a runtime error using the error reporter for the current thread.
- *
- * @param message the error message to report
- * @see org.mozilla.javascript.ErrorReporter
- */
- public static EvaluatorException reportRuntimeError(String message)
- {
- int[] linep = { 0 };
- String filename = getSourcePositionFromStack(linep);
- return Context.reportRuntimeError(message, filename, linep[0], null, 0);
- }
-
- /**
- * Initialize the standard objects.
- *
- * Creates instances of the standard objects and their constructors
- * (Object, String, Number, Date, etc.), setting up 'scope' to act
- * as a global object as in ECMA 15.1.<p>
- *
- * This method must be called to initialize a scope before scripts
- * can be evaluated in that scope.<p>
- *
- * This method does not affect the Context it is called upon.
- *
- * @return the initialized scope
- */
- public final ScriptableObject initStandardObjects()
- {
- return initStandardObjects(null, false);
- }
-
- /**
- * Initialize the standard objects.
- *
- * Creates instances of the standard objects and their constructors
- * (Object, String, Number, Date, etc.), setting up 'scope' to act
- * as a global object as in ECMA 15.1.<p>
- *
- * This method must be called to initialize a scope before scripts
- * can be evaluated in that scope.<p>
- *
- * This method does not affect the Context it is called upon.
- *
- * @param scope the scope to initialize, or null, in which case a new
- * object will be created to serve as the scope
- * @return the initialized scope. The method returns the value of the scope
- * argument if it is not null or newly allocated scope object which
- * is an instance {@link ScriptableObject}.
- */
- public final Scriptable initStandardObjects(ScriptableObject scope)
- {
- return initStandardObjects(scope, false);
- }
-
- /**
- * Initialize the standard objects.
- *
- * Creates instances of the standard objects and their constructors
- * (Object, String, Number, Date, etc.), setting up 'scope' to act
- * as a global object as in ECMA 15.1.<p>
- *
- * This method must be called to initialize a scope before scripts
- * can be evaluated in that scope.<p>
- *
- * This method does not affect the Context it is called upon.<p>
- *
- * This form of the method also allows for creating "sealed" standard
- * objects. An object that is sealed cannot have properties added, changed,
- * or removed. This is useful to create a "superglobal" that can be shared
- * among several top-level objects. Note that sealing is not allowed in
- * the current ECMA/ISO language specification, but is likely for
- * the next version.
- *
- * @param scope the scope to initialize, or null, in which case a new
- * object will be created to serve as the scope
- * @param sealed whether or not to create sealed standard objects that
- * cannot be modified.
- * @return the initialized scope. The method returns the value of the scope
- * argument if it is not null or newly allocated scope object.
- * @since 1.4R3
- */
- public ScriptableObject initStandardObjects(ScriptableObject scope,
- boolean sealed)
- {
- return ScriptRuntime.initStandardObjects(this, scope, sealed);
- }
-
- /**
- * Get the singleton object that represents the JavaScript Undefined value.
- */
- public static Object getUndefinedValue()
- {
- return Undefined.instance;
- }
-
- /**
- * Evaluate a JavaScript source string.
- *
- * The provided source name and line number are used for error messages
- * and for producing debug information.
- *
- * @param scope the scope to execute in
- * @param source the JavaScript source
- * @param sourceName a string describing the source, such as a filename
- * @param lineno the starting line number
- * @param securityDomain an arbitrary object that specifies security
- * information about the origin or owner of the script. For
- * implementations that don't care about security, this value
- * may be null.
- * @return the result of evaluating the string
- * @see org.mozilla.javascript.SecurityController
- */
- public final Object evaluateString(Scriptable scope, String source,
- String sourceName, int lineno,
- Object securityDomain)
- {
- Script script = compileString(source, sourceName, lineno,
- securityDomain);
- if (script != null) {
- return script.exec(this, scope);
- } else {
- return null;
- }
- }
-
- /**
- * Evaluate a reader as JavaScript source.
- *
- * All characters of the reader are consumed.
- *
- * @param scope the scope to execute in
- * @param in the Reader to get JavaScript source from
- * @param sourceName a string describing the source, such as a filename
- * @param lineno the starting line number
- * @param securityDomain an arbitrary object that specifies security
- * information about the origin or owner of the script. For
- * implementations that don't care about security, this value
- * may be null.
- * @return the result of evaluating the source
- *
- * @exception IOException if an IOException was generated by the Reader
- */
- public final Object evaluateReader(Scriptable scope, Reader in,
- String sourceName, int lineno,
- Object securityDomain)
- throws IOException
- {
- Script script = compileReader(scope, in, sourceName, lineno,
- securityDomain);
- if (script != null) {
- return script.exec(this, scope);
- } else {
- return null;
- }
- }
-
- /**
- * Check whether a string is ready to be compiled.
- * <p>
- * stringIsCompilableUnit is intended to support interactive compilation of
- * javascript. If compiling the string would result in an error
- * that might be fixed by appending more source, this method
- * returns false. In every other case, it returns true.
- * <p>
- * Interactive shells may accumulate source lines, using this
- * method after each new line is appended to check whether the
- * statement being entered is complete.
- *
- * @param source the source buffer to check
- * @return whether the source is ready for compilation
- * @since 1.4 Release 2
- */
- public final boolean stringIsCompilableUnit(String source)
- {
- boolean errorseen = false;
- CompilerEnvirons compilerEnv = new CompilerEnvirons();
- compilerEnv.initFromContext(this);
- // no source name or source text manager, because we're just
- // going to throw away the result.
- compilerEnv.setGeneratingSource(false);
- /*APPJET*/
- Parser p = InformativeParser.makeParser(compilerEnv,
- DefaultErrorReporter.instance);
- try {
- p.parse(source, null, 1);
- } catch (EvaluatorException ee) {
- errorseen = true;
- }
- // Return false only if an error occurred as a result of reading past
- // the end of the file, i.e. if the source could be fixed by
- // appending more source.
- if (errorseen && p.eof())
- return false;
- else
- return true;
- }
-
- /**
- * @deprecated
- * @see #compileReader(Reader in, String sourceName, int lineno,
- * Object securityDomain)
- */
- public final Script compileReader(Scriptable scope, Reader in,
- String sourceName, int lineno,
- Object securityDomain)
- throws IOException
- {
- return compileReader(in, sourceName, lineno, securityDomain);
- }
-
- /**
- * Compiles the source in the given reader.
- * <p>
- * Returns a script that may later be executed.
- * Will consume all the source in the reader.
- *
- * @param in the input reader
- * @param sourceName a string describing the source, such as a filename
- * @param lineno the starting line number for reporting errors
- * @param securityDomain an arbitrary object that specifies security
- * information about the origin or owner of the script. For
- * implementations that don't care about security, this value
- * may be null.
- * @return a script that may later be executed
- * @exception IOException if an IOException was generated by the Reader
- * @see org.mozilla.javascript.Script
- */
- public final Script compileReader(Reader in, String sourceName,
- int lineno, Object securityDomain)
- throws IOException
- {
- if (lineno < 0) {
- // For compatibility IllegalArgumentException can not be thrown here
- lineno = 0;
- }
- return (Script) compileImpl(null, in, null, sourceName, lineno,
- securityDomain, false, null, null);
- }
-
- /**
- * Compiles the source in the given string.
- * <p>
- * Returns a script that may later be executed.
- *
- * @param source the source string
- * @param sourceName a string describing the source, such as a filename
- * @param lineno the starting line number for reporting errors
- * @param securityDomain an arbitrary object that specifies security
- * information about the origin or owner of the script. For
- * implementations that don't care about security, this value
- * may be null.
- * @return a script that may later be executed
- * @see org.mozilla.javascript.Script
- */
- public final Script compileString(String source,
- String sourceName, int lineno,
- Object securityDomain)
- {
- if (lineno < 0) {
- // For compatibility IllegalArgumentException can not be thrown here
- lineno = 0;
- }
- return compileString(source, null, null, sourceName, lineno,
- securityDomain);
- }
-
- final Script compileString(String source,
- Evaluator compiler,
- ErrorReporter compilationErrorReporter,
- String sourceName, int lineno,
- Object securityDomain)
- {
- try {
- return (Script) compileImpl(null, null, source, sourceName, lineno,
- securityDomain, false,
- compiler, compilationErrorReporter);
- } catch (IOException ex) {
- // Should not happen when dealing with source as string
- throw new RuntimeException();
- }
- }
-
- /**
- * Compile a JavaScript function.
- * <p>
- * The function source must be a function definition as defined by
- * ECMA (e.g., "function f(a) { return a; }").
- *
- * @param scope the scope to compile relative to
- * @param source the function definition source
- * @param sourceName a string describing the source, such as a filename
- * @param lineno the starting line number
- * @param securityDomain an arbitrary object that specifies security
- * information about the origin or owner of the script. For
- * implementations that don't care about security, this value
- * may be null.
- * @return a Function that may later be called
- * @see org.mozilla.javascript.Function
- */
- public final Function compileFunction(Scriptable scope, String source,
- String sourceName, int lineno,
- Object securityDomain)
- {
- return compileFunction(scope, source, null, null, sourceName, lineno,
- securityDomain);
- }
-
- final Function compileFunction(Scriptable scope, String source,
- Evaluator compiler,
- ErrorReporter compilationErrorReporter,
- String sourceName, int lineno,
- Object securityDomain)
- {
- try {
- return (Function) compileImpl(scope, null, source, sourceName,
- lineno, securityDomain, true,
- compiler, compilationErrorReporter);
- }
- catch (IOException ioe) {
- // Should never happen because we just made the reader
- // from a String
- throw new RuntimeException();
- }
- }
-
- /**
- * Decompile the script.
- * <p>
- * The canonical source of the script is returned.
- *
- * @param script the script to decompile
- * @param indent the number of spaces to indent the result
- * @return a string representing the script source
- */
- public final String decompileScript(Script script, int indent)
- {
- NativeFunction scriptImpl = (NativeFunction) script;
- return scriptImpl.decompile(indent, 0);
- }
-
- /**
- * Decompile a JavaScript Function.
- * <p>
- * Decompiles a previously compiled JavaScript function object to
- * canonical source.
- * <p>
- * Returns function body of '[native code]' if no decompilation
- * information is available.
- *
- * @param fun the JavaScript function to decompile
- * @param indent the number of spaces to indent the result
- * @return a string representing the function source
- */
- public final String decompileFunction(Function fun, int indent)
- {
- if (fun instanceof BaseFunction)
- return ((BaseFunction)fun).decompile(indent, 0);
- else
- return "function " + fun.getClassName() +
- "() {\n\t[native code]\n}\n";
- }
-
- /**
- * Decompile the body of a JavaScript Function.
- * <p>
- * Decompiles the body a previously compiled JavaScript Function
- * object to canonical source, omitting the function header and
- * trailing brace.
- *
- * Returns '[native code]' if no decompilation information is available.
- *
- * @param fun the JavaScript function to decompile
- * @param indent the number of spaces to indent the result
- * @return a string representing the function body source.
- */
- public final String decompileFunctionBody(Function fun, int indent)
- {
- if (fun instanceof BaseFunction) {
- BaseFunction bf = (BaseFunction)fun;
- return bf.decompile(indent, Decompiler.ONLY_BODY_FLAG);
- }
- // ALERT: not sure what the right response here is.
- return "[native code]\n";
- }
-
- /**
- * Create a new JavaScript object.
- *
- * Equivalent to evaluating "new Object()".
- * @param scope the scope to search for the constructor and to evaluate
- * against
- * @return the new object
- */
- public final Scriptable newObject(Scriptable scope)
- {
- return newObject(scope, "Object", ScriptRuntime.emptyArgs);
- }
-
- /**
- * Create a new JavaScript object by executing the named constructor.
- *
- * The call <code>newObject(scope, "Foo")</code> is equivalent to
- * evaluating "new Foo()".
- *
- * @param scope the scope to search for the constructor and to evaluate against
- * @param constructorName the name of the constructor to call
- * @return the new object
- */
- public final Scriptable newObject(Scriptable scope, String constructorName)
- {
- return newObject(scope, constructorName, ScriptRuntime.emptyArgs);
- }
-
- /**
- * Creates a new JavaScript object by executing the named constructor.
- *
- * Searches <code>scope</code> for the named constructor, calls it with
- * the given arguments, and returns the result.<p>
- *
- * The code
- * <pre>
- * Object[] args = { "a", "b" };
- * newObject(scope, "Foo", args)</pre>
- * is equivalent to evaluating "new Foo('a', 'b')", assuming that the Foo
- * constructor has been defined in <code>scope</code>.
- *
- * @param scope The scope to search for the constructor and to evaluate
- * against
- * @param constructorName the name of the constructor to call
- * @param args the array of arguments for the constructor
- * @return the new object
- */
- public final Scriptable newObject(Scriptable scope, String constructorName,
- Object[] args)
- {
- scope = ScriptableObject.getTopLevelScope(scope);
- Function ctor = ScriptRuntime.getExistingCtor(this, scope,
- constructorName);
- if (args == null) { args = ScriptRuntime.emptyArgs; }
- return ctor.construct(this, scope, args);
- }
-
- /**
- * Create an array with a specified initial length.
- * <p>
- * @param scope the scope to create the object in
- * @param length the initial length (JavaScript arrays may have
- * additional properties added dynamically).
- * @return the new array object
- */
- public final Scriptable newArray(Scriptable scope, int length)
- {
- NativeArray result = new NativeArray(length);
- ScriptRuntime.setObjectProtoAndParent(result, scope);
- return result;
- }
-
- /**
- * Create an array with a set of initial elements.
- *
- * @param scope the scope to create the object in.
- * @param elements the initial elements. Each object in this array
- * must be an acceptable JavaScript type and type
- * of array should be exactly Object[], not
- * SomeObjectSubclass[].
- * @return the new array object.
- */
- public final Scriptable newArray(Scriptable scope, Object[] elements)
- {
- if (elements.getClass().getComponentType() != ScriptRuntime.ObjectClass)
- throw new IllegalArgumentException();
- NativeArray result = new NativeArray(elements);
- ScriptRuntime.setObjectProtoAndParent(result, scope);
- return result;
- }
-
- /**
- * Get the elements of a JavaScript array.
- * <p>
- * If the object defines a length property convertible to double number,
- * then the number is converted Uint32 value as defined in Ecma 9.6
- * and Java array of that size is allocated.
- * The array is initialized with the values obtained by
- * calling get() on object for each value of i in [0,length-1]. If
- * there is not a defined value for a property the Undefined value
- * is used to initialize the corresponding element in the array. The
- * Java array is then returned.
- * If the object doesn't define a length property or it is not a number,
- * empty array is returned.
- * @param object the JavaScript array or array-like object
- * @return a Java array of objects
- * @since 1.4 release 2
- */
- public final Object[] getElements(Scriptable object)
- {
- return ScriptRuntime.getArrayElements(object);
- }
-
- /**
- * Convert the value to a JavaScript boolean value.
- * <p>
- * See ECMA 9.2.
- *
- * @param value a JavaScript value
- * @return the corresponding boolean value converted using
- * the ECMA rules
- */
- public static boolean toBoolean(Object value)
- {
- return ScriptRuntime.toBoolean(value);
- }
-
- /**
- * Convert the value to a JavaScript Number value.
- * <p>
- * Returns a Java double for the JavaScript Number.
- * <p>
- * See ECMA 9.3.
- *
- * @param value a JavaScript value
- * @return the corresponding double value converted using
- * the ECMA rules
- */
- public static double toNumber(Object value)
- {
- return ScriptRuntime.toNumber(value);
- }
-
- /**
- * Convert the value to a JavaScript String value.
- * <p>
- * See ECMA 9.8.
- * <p>
- * @param value a JavaScript value
- * @return the corresponding String value converted using
- * the ECMA rules
- */
- public static String toString(Object value)
- {
- return ScriptRuntime.toString(value);
- }
-
- /**
- * Convert the value to an JavaScript object value.
- * <p>
- * Note that a scope must be provided to look up the constructors
- * for Number, Boolean, and String.
- * <p>
- * See ECMA 9.9.
- * <p>
- * Additionally, arbitrary Java objects and classes will be
- * wrapped in a Scriptable object with its Java fields and methods
- * reflected as JavaScript properties of the object.
- *
- * @param value any Java object
- * @param scope global scope containing constructors for Number,
- * Boolean, and String
- * @return new JavaScript object
- */
- public static Scriptable toObject(Object value, Scriptable scope)
- {
- return ScriptRuntime.toObject(scope, value);
- }
-
- /**
- * @deprecated
- * @see #toObject(Object, Scriptable)
- */
- public static Scriptable toObject(Object value, Scriptable scope,
- Class staticType)
- {
- return ScriptRuntime.toObject(scope, value);
- }
-
- /**
- * Convenient method to convert java value to its closest representation
- * in JavaScript.
- * <p>
- * If value is an instance of String, Number, Boolean, Function or
- * Scriptable, it is returned as it and will be treated as the corresponding
- * JavaScript type of string, number, boolean, function and object.
- * <p>
- * Note that for Number instances during any arithmetic operation in
- * JavaScript the engine will always use the result of
- * <tt>Number.doubleValue()</tt> resulting in a precision loss if
- * the number can not fit into double.
- * <p>
- * If value is an instance of Character, it will be converted to string of
- * length 1 and its JavaScript type will be string.
- * <p>
- * The rest of values will be wrapped as LiveConnect objects
- * by calling {@link WrapFactory#wrap(Context cx, Scriptable scope,
- * Object obj, Class staticType)} as in:
- * <pre>
- * Context cx = Context.getCurrentContext();
- * return cx.getWrapFactory().wrap(cx, scope, value, null);
- * </pre>
- *
- * @param value any Java object
- * @param scope top scope object
- * @return value suitable to pass to any API that takes JavaScript values.
- */
- public static Object javaToJS(Object value, Scriptable scope)
- {
- if (value instanceof String || value instanceof Number
- || value instanceof Boolean || value instanceof Scriptable)
- {
- return value;
- } else if (value instanceof Character) {
- return String.valueOf(((Character)value).charValue());
- } else {
- Context cx = Context.getContext();
- return cx.getWrapFactory().wrap(cx, scope, value, null);
- }
- }
-
- /**
- * Convert a JavaScript value into the desired type.
- * Uses the semantics defined with LiveConnect3 and throws an
- * Illegal argument exception if the conversion cannot be performed.
- * @param value the JavaScript value to convert
- * @param desiredType the Java type to convert to. Primitive Java
- * types are represented using the TYPE fields in the corresponding
- * wrapper class in java.lang.
- * @return the converted value
- * @throws EvaluatorException if the conversion cannot be performed
- */
- public static Object jsToJava(Object value, Class desiredType)
- throws EvaluatorException
- {
- return NativeJavaObject.coerceTypeImpl(desiredType, value);
- }
-
- /**
- * @deprecated
- * @see #jsToJava(Object, Class)
- * @throws IllegalArgumentException if the conversion cannot be performed.
- * Note that {@link #jsToJava(Object, Class)} throws
- * {@link EvaluatorException} instead.
- */
- public static Object toType(Object value, Class desiredType)
- throws IllegalArgumentException
- {
- try {
- return jsToJava(value, desiredType);
- } catch (EvaluatorException ex) {
- IllegalArgumentException
- ex2 = new IllegalArgumentException(ex.getMessage());
- Kit.initCause(ex2, ex);
- throw ex2;
- }
- }
-
- /**
- * Rethrow the exception wrapping it as the script runtime exception.
- * Unless the exception is instance of {@link EcmaError} or
- * {@link EvaluatorException} it will be wrapped as
- * {@link WrappedException}, a subclass of {@link EvaluatorException}.
- * The resulting exception object always contains
- * source name and line number of script that triggered exception.
- * <p>
- * This method always throws an exception, its return value is provided
- * only for convenience to allow a usage like:
- * <pre>
- * throw Context.throwAsScriptRuntimeEx(ex);
- * </pre>
- * to indicate that code after the method is unreachable.
- * @throws EvaluatorException
- * @throws EcmaError
- */
- public static RuntimeException throwAsScriptRuntimeEx(Throwable e)
- {
- while ((e instanceof InvocationTargetException)) {
- e = ((InvocationTargetException) e).getTargetException();
- }
- // special handling of Error so scripts would not catch them
- if (e instanceof Error) {
- Context cx = getContext();
- if (cx == null ||
- !cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS))
- {
- throw (Error)e;
- }
- }
- if (e instanceof RhinoException) {
- throw (RhinoException)e;
- }
- throw new WrappedException(e);
- }
-
- /**
- * Tell whether debug information is being generated.
- * @since 1.3
- */
- public final boolean isGeneratingDebug()
- {
- return generatingDebug;
- }
-
- /**
- * Specify whether or not debug information should be generated.
- * <p>
- * Setting the generation of debug information on will set the
- * optimization level to zero.
- * @since 1.3
- */
- public final void setGeneratingDebug(boolean generatingDebug)
- {
- if (sealed) onSealedMutation();
- generatingDebugChanged = true;
- if (generatingDebug && getOptimizationLevel() > 0)
- setOptimizationLevel(0);
- this.generatingDebug = generatingDebug;
- }
-
- /**
- * Tell whether source information is being generated.
- * @since 1.3
- */
- public final boolean isGeneratingSource()
- {
- return generatingSource;
- }
-
- /**
- * Specify whether or not source information should be generated.
- * <p>
- * Without source information, evaluating the "toString" method
- * on JavaScript functions produces only "[native code]" for
- * the body of the function.
- * Note that code generated without source is not fully ECMA
- * conformant.
- * @since 1.3
- */
- public final void setGeneratingSource(boolean generatingSource)
- {
- if (sealed) onSealedMutation();
- this.generatingSource = generatingSource;
- }
-
- /**
- * Get the current optimization level.
- * <p>
- * The optimization level is expressed as an integer between -1 and
- * 9.
- * @since 1.3
- *
- */
- public final int getOptimizationLevel()
- {
- return optimizationLevel;
- }
-
- /**
- * Set the current optimization level.
- * <p>
- * The optimization level is expected to be an integer between -1 and
- * 9. Any negative values will be interpreted as -1, and any values
- * greater than 9 will be interpreted as 9.
- * An optimization level of -1 indicates that interpretive mode will
- * always be used. Levels 0 through 9 indicate that class files may
- * be generated. Higher optimization levels trade off compile time
- * performance for runtime performance.
- * The optimizer level can't be set greater than -1 if the optimizer
- * package doesn't exist at run time.
- * @param optimizationLevel an integer indicating the level of
- * optimization to perform
- * @since 1.3
- *
- */
- public final void setOptimizationLevel(int optimizationLevel)
- {
- if (sealed) onSealedMutation();
- if (optimizationLevel == -2) {
- // To be compatible with Cocoon fork
- optimizationLevel = -1;
- }
- checkOptimizationLevel(optimizationLevel);
- if (codegenClass == null)
- optimizationLevel = -1;
- this.optimizationLevel = optimizationLevel;
- }
-
- public static boolean isValidOptimizationLevel(int optimizationLevel)
- {
- return -1 <= optimizationLevel && optimizationLevel <= 9;
- }
-
- public static void checkOptimizationLevel(int optimizationLevel)
- {
- if (isValidOptimizationLevel(optimizationLevel)) {
- return;
- }
- throw new IllegalArgumentException(
- "Optimization level outside [-1..9]: "+optimizationLevel);
- }
-
- /**
- * Returns the maximum stack depth (in terms of number of call frames)
- * allowed in a single invocation of interpreter. If the set depth would be
- * exceeded, the interpreter will throw an EvaluatorException in the script.
- * Defaults to Integer.MAX_VALUE. The setting only has effect for
- * interpreted functions (those compiled with optimization level set to -1).
- * As the interpreter doesn't use the Java stack but rather manages its own
- * stack in the heap memory, a runaway recursion in interpreted code would
- * eventually consume all available memory and cause OutOfMemoryError
- * instead of a StackOverflowError limited to only a single thread. This
- * setting helps prevent such situations.
- *
- * @return The current maximum interpreter stack depth.
- */
- public final int getMaximumInterpreterStackDepth()
- {
- return maximumInterpreterStackDepth;
- }
-
- /**
- * Sets the maximum stack depth (in terms of number of call frames)
- * allowed in a single invocation of interpreter. If the set depth would be
- * exceeded, the interpreter will throw an EvaluatorException in the script.
- * Defaults to Integer.MAX_VALUE. The setting only has effect for
- * interpreted functions (those compiled with optimization level set to -1).
- * As the interpreter doesn't use the Java stack but rather manages its own
- * stack in the heap memory, a runaway recursion in interpreted code would
- * eventually consume all available memory and cause OutOfMemoryError
- * instead of a StackOverflowError limited to only a single thread. This
- * setting helps prevent such situations.
- *
- * @param max the new maximum interpreter stack depth
- * @throws IllegalStateException if this context's optimization level is not
- * -1
- * @throws IllegalArgumentException if the new depth is not at least 1
- */
- public final void setMaximumInterpreterStackDepth(int max)
- {
- if(sealed) onSealedMutation();
- if(optimizationLevel != -1) {
- throw new IllegalStateException("Cannot set maximumInterpreterStackDepth when optimizationLevel != -1");
- }
- if(max < 1) {
- throw new IllegalArgumentException("Cannot set maximumInterpreterStackDepth to less than 1");
- }
- maximumInterpreterStackDepth = max;
- }
-
- /**
- * Set the security controller for this context.
- * <p> SecurityController may only be set if it is currently null
- * and {@link SecurityController#hasGlobal()} is <tt>false</tt>.
- * Otherwise a SecurityException is thrown.
- * @param controller a SecurityController object
- * @throws SecurityException if there is already a SecurityController
- * object for this Context or globally installed.
- * @see SecurityController#initGlobal(SecurityController controller)
- * @see SecurityController#hasGlobal()
- */
- public final void setSecurityController(SecurityController controller)
- {
- if (sealed) onSealedMutation();
- if (controller == null) throw new IllegalArgumentException();
- if (securityController != null) {
- throw new SecurityException("Can not overwrite existing SecurityController object");
- }
- if (SecurityController.hasGlobal()) {
- throw new SecurityException("Can not overwrite existing global SecurityController object");
- }
- securityController = controller;
- }
-
- /**
- * Set the LiveConnect access filter for this context.
- * <p> {@link ClassShutter} may only be set if it is currently null.
- * Otherwise a SecurityException is thrown.
- * @param shutter a ClassShutter object
- * @throws SecurityException if there is already a ClassShutter
- * object for this Context
- */
- public final void setClassShutter(ClassShutter shutter)
- {
- if (sealed) onSealedMutation();
- if (shutter == null) throw new IllegalArgumentException();
- if (classShutter != null) {
- throw new SecurityException("Cannot overwrite existing " +
- "ClassShutter object");
- }
- classShutter = shutter;
- }
-
- final ClassShutter getClassShutter()
- {
- return classShutter;
- }
-
- /**
- * Get a value corresponding to a key.
- * <p>
- * Since the Context is associated with a thread it can be
- * used to maintain values that can be later retrieved using
- * the current thread.
- * <p>
- * Note that the values are maintained with the Context, so
- * if the Context is disassociated from the thread the values
- * cannot be retrieved. Also, if private data is to be maintained
- * in this manner the key should be a java.lang.Object
- * whose reference is not divulged to untrusted code.
- * @param key the key used to lookup the value
- * @return a value previously stored using putThreadLocal.
- */
- public final Object getThreadLocal(Object key)
- {
- if (hashtable == null)
- return null;
- return hashtable.get(key);
- }
-
- /**
- * Put a value that can later be retrieved using a given key.
- * <p>
- * @param key the key used to index the value
- * @param value the value to save
- */
- public final void putThreadLocal(Object key, Object value)
- {
- if (sealed) onSealedMutation();
- if (hashtable == null)
- hashtable = new Hashtable();
- hashtable.put(key, value);
- }
-
- /**
- * Remove values from thread-local storage.
- * @param key the key for the entry to remove.
- * @since 1.5 release 2
- */
- public final void removeThreadLocal(Object key)
- {
- if (sealed) onSealedMutation();
- if (hashtable == null)
- return;
- hashtable.remove(key);
- }
-
- /**
- * @deprecated
- * @see #FEATURE_DYNAMIC_SCOPE
- * @see #hasFeature(int)
- */
- public final boolean hasCompileFunctionsWithDynamicScope()
- {
- return compileFunctionsWithDynamicScopeFlag;
- }
-
- /**
- * @deprecated
- * @see #FEATURE_DYNAMIC_SCOPE
- * @see #hasFeature(int)
- */
- public final void setCompileFunctionsWithDynamicScope(boolean flag)
- {
- if (sealed) onSealedMutation();
- compileFunctionsWithDynamicScopeFlag = flag;
- }
-
- /**
- * @deprecated
- * @see ClassCache#get(Scriptable)
- * @see ClassCache#setCachingEnabled(boolean)
- */
- public static void setCachingEnabled(boolean cachingEnabled)
- {
- }
-
- /**
- * Set a WrapFactory for this Context.
- * <p>
- * The WrapFactory allows custom object wrapping behavior for
- * Java object manipulated with JavaScript.
- * @see WrapFactory
- * @since 1.5 Release 4
- */
- public final void setWrapFactory(WrapFactory wrapFactory)
- {
- if (sealed) onSealedMutation();
- if (wrapFactory == null) throw new IllegalArgumentException();
- this.wrapFactory = wrapFactory;
- }
-
- /**
- * Return the current WrapFactory, or null if none is defined.
- * @see WrapFactory
- * @since 1.5 Release 4
- */
- public final WrapFactory getWrapFactory()
- {
- if (wrapFactory == null) {
- wrapFactory = new WrapFactory();
- }
- return wrapFactory;
- }
-
- /**
- * Return the current debugger.
- * @return the debugger, or null if none is attached.
- */
- public final Debugger getDebugger()
- {
- return debugger;
- }
-
- /**
- * Return the debugger context data associated with current context.
- * @return the debugger data, or null if debugger is not attached
- */
- public final Object getDebuggerContextData()
- {
- return debuggerData;
- }
-
- /**
- * Set the associated debugger.
- * @param debugger the debugger to be used on callbacks from
- * the engine.
- * @param contextData arbitrary object that debugger can use to store
- * per Context data.
- */
- public final void setDebugger(Debugger debugger, Object contextData)
- {
- if (sealed) onSealedMutation();
- this.debugger = debugger;
- debuggerData = contextData;
- }
-
- /**
- * Return DebuggableScript instance if any associated with the script.
- * If callable supports DebuggableScript implementation, the method
- * returns it. Otherwise null is returned.
- */
- public static DebuggableScript getDebuggableView(Script script)
- {
- if (script instanceof NativeFunction) {
- return ((NativeFunction)script).getDebuggableView();
- }
- return null;
- }
-
- /**
- * Controls certain aspects of script semantics.
- * Should be overwritten to alter default behavior.
- * <p>
- * The default implementation calls
- * {@link ContextFactory#hasFeature(Context cx, int featureIndex)}
- * that allows to customize Context behavior without introducing
- * Context subclasses. {@link ContextFactory} documentation gives
- * an example of hasFeature implementation.
- *
- * @param featureIndex feature index to check
- * @return true if the <code>featureIndex</code> feature is turned on
- * @see #FEATURE_NON_ECMA_GET_YEAR
- * @see #FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME
- * @see #FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER
- * @see #FEATURE_TO_STRING_AS_SOURCE
- * @see #FEATURE_PARENT_PROTO_PROPRTIES
- * @see #FEATURE_E4X
- * @see #FEATURE_DYNAMIC_SCOPE
- * @see #FEATURE_STRICT_VARS
- * @see #FEATURE_STRICT_EVAL
- * @see #FEATURE_LOCATION_INFORMATION_IN_ERROR
- * @see #FEATURE_STRICT_MODE
- * @see #FEATURE_WARNING_AS_ERROR
- * @see #FEATURE_ENHANCED_JAVA_ACCESS
- */
- public boolean hasFeature(int featureIndex)
- {
- ContextFactory f = getFactory();
- return f.hasFeature(this, featureIndex);
- }
-
- /**
- Returns an object which specifies an E4X implementation to use within
- this <code>Context</code>. Note
- that the XMLLib.Factory interface should be considered experimental.
-
- The default implementation uses the implementation provided by this
- <code>Context</code>'s {@link ContextFactory}.
-
- @return An XMLLib.Factory. Should not return <code>null</code> if
- {@link #FEATURE_E4X} is enabled. See {@link #hasFeature}.
- */
- public XMLLib.Factory getE4xImplementationFactory() {
- return getFactory().getE4xImplementationFactory();
- }
-
- /**
- * Get threshold of executed instructions counter that triggers call to
- * <code>observeInstructionCount()</code>.
- * When the threshold is zero, instruction counting is disabled,
- * otherwise each time the run-time executes at least the threshold value
- * of script instructions, <code>observeInstructionCount()</code> will
- * be called.
- */
- public final int getInstructionObserverThreshold()
- {
- return instructionThreshold;
- }
-
- /**
- * Set threshold of executed instructions counter that triggers call to
- * <code>observeInstructionCount()</code>.
- * When the threshold is zero, instruction counting is disabled,
- * otherwise each time the run-time executes at least the threshold value
- * of script instructions, <code>observeInstructionCount()</code> will
- * be called.<p/>
- * Note that the meaning of "instruction" is not guaranteed to be
- * consistent between compiled and interpretive modes: executing a given
- * script or function in the different modes will result in different
- * instruction counts against the threshold.
- * {@link #setGenerateObserverCount} is called with true if
- * <code>threshold</code> is greater than zero, false otherwise.
- * @param threshold The instruction threshold
- */
- public final void setInstructionObserverThreshold(int threshold)
- {
- if (sealed) onSealedMutation();
- if (threshold < 0) throw new IllegalArgumentException();
- instructionThreshold = threshold;
- setGenerateObserverCount(threshold > 0);
- }
-
- /**
- * Turn on or off generation of code with callbacks to
- * track the count of executed instructions.
- * Currently only affects JVM byte code generation: this slows down the
- * generated code, but code generated without the callbacks will not
- * be counted toward instruction thresholds. Rhino's interpretive
- * mode does instruction counting without inserting callbacks, so
- * there is no requirement to compile code differently.
- * @param generateObserverCount if true, generated code will contain
- * calls to accumulate an estimate of the instructions executed.
- */
- public void setGenerateObserverCount(boolean generateObserverCount) {
- this.generateObserverCount = generateObserverCount;
- }
-
- /**
- * Allow application to monitor counter of executed script instructions
- * in Context subclasses.
- * Run-time calls this when instruction counting is enabled and the counter
- * reaches limit set by <code>setInstructionObserverThreshold()</code>.
- * The method is useful to observe long running scripts and if necessary
- * to terminate them.
- * <p>
- * The instruction counting support is available only for interpreted
- * scripts generated when the optimization level is set to -1.
- * <p>
- * The default implementation calls
- * {@link ContextFactory#observeInstructionCount(Context cx,
- * int instructionCount)}
- * that allows to customize Context behavior without introducing
- * Context subclasses.
- *
- * @param instructionCount amount of script instruction executed since
- * last call to <code>observeInstructionCount</code>
- * @throws Error to terminate the script
- * @see #setOptimizationLevel(int)
- */
- protected void observeInstructionCount(int instructionCount)
- {
- ContextFactory f = getFactory();
- f.observeInstructionCount(this, instructionCount);
- }
-
- /**
- * Create class loader for generated classes.
- * The method calls {@link ContextFactory#createClassLoader(ClassLoader)}
- * using the result of {@link #getFactory()}.
- */
- public GeneratedClassLoader createClassLoader(ClassLoader parent)
- {
- ContextFactory f = getFactory();
- return f.createClassLoader(parent);
- }
-
- public final ClassLoader getApplicationClassLoader()
- {
- if (applicationClassLoader == null) {
- ContextFactory f = getFactory();
- ClassLoader loader = f.getApplicationClassLoader();
- if (loader == null) {
- ClassLoader threadLoader
- = VMBridge.instance.getCurrentThreadClassLoader();
- if (threadLoader != null
- && Kit.testIfCanLoadRhinoClasses(threadLoader))
- {
- // Thread.getContextClassLoader is not cached since
- // its caching prevents it from GC which may lead to
- // a memory leak and hides updates to
- // Thread.getContextClassLoader
- return threadLoader;
- }
- // Thread.getContextClassLoader can not load Rhino classes,
- // try to use the loader of ContextFactory or Context
- // subclasses.
- Class fClass = f.getClass();
- if (fClass != ScriptRuntime.ContextFactoryClass) {
- loader = fClass.getClassLoader();
- } else {
- loader = getClass().getClassLoader();
- }
- }
- applicationClassLoader = loader;
- }
- return applicationClassLoader;
- }
-
- public final void setApplicationClassLoader(ClassLoader loader)
- {
- if (sealed) onSealedMutation();
- if (loader == null) {
- // restore default behaviour
- applicationClassLoader = null;
- return;
- }
- if (!Kit.testIfCanLoadRhinoClasses(loader)) {
- throw new IllegalArgumentException(
- "Loader can not resolve Rhino classes");
- }
- applicationClassLoader = loader;
- }
-
- /********** end of API **********/
-
- /**
- * Internal method that reports an error for missing calls to
- * enter().
- */
- static Context getContext()
- {
- Context cx = getCurrentContext();
- if (cx == null) {
- throw new RuntimeException(
- "No Context associated with current Thread");
- }
- return cx;
- }
-
- private Object compileImpl(Scriptable scope,
- Reader sourceReader, String sourceString,
- String sourceName, int lineno,
- Object securityDomain, boolean returnFunction,
- Evaluator compiler,
- ErrorReporter compilationErrorReporter)
- throws IOException
- {
- if(sourceName == null) {
- sourceName = "unnamed script";
- }
- if (securityDomain != null && getSecurityController() == null) {
- throw new IllegalArgumentException(
- "securityDomain should be null if setSecurityController() was never called");
- }
-
- // One of sourceReader or sourceString has to be null
- if (!(sourceReader == null ^ sourceString == null)) Kit.codeBug();
- // scope should be given if and only if compiling function
- if (!(scope == null ^ returnFunction)) Kit.codeBug();
-
- CompilerEnvirons compilerEnv = new CompilerEnvirons();
- compilerEnv.initFromContext(this);
- if (compilationErrorReporter == null) {
- compilationErrorReporter = compilerEnv.getErrorReporter();
- }
-
- if (debugger != null) {
- if (sourceReader != null) {
- sourceString = Kit.readReader(sourceReader);
- sourceReader = null;
- }
- }
-
- /*APPJET*/
- Parser p = InformativeParser.makeParser(compilerEnv,
- compilationErrorReporter);
- if (returnFunction) {
- p.calledByCompileFunction = true;
- }
- ScriptOrFnNode tree;
- if (sourceString != null) {
- tree = p.parse(sourceString, sourceName, lineno);
- } else {
- tree = p.parse(sourceReader, sourceName, lineno);
- }
- if (returnFunction) {
- if (!(tree.getFunctionCount() == 1
- && tree.getFirstChild() != null
- && tree.getFirstChild().getType() == Token.FUNCTION))
- {
- // XXX: the check just look for the first child
- // and allows for more nodes after it for compatibility
- // with sources like function() {};;;
- throw new IllegalArgumentException(
- "compileFunction only accepts source with single JS function: "+sourceString);
- }
- }
-
- if (compiler == null) {
- compiler = createCompiler();
- }
-
- String encodedSource = p.getEncodedSource();
-
- Object bytecode = compiler.compile(compilerEnv,
- tree, encodedSource,
- returnFunction);
-
- if (debugger != null) {
- if (sourceString == null) Kit.codeBug();
- if (bytecode instanceof DebuggableScript) {
- DebuggableScript dscript = (DebuggableScript)bytecode;
- notifyDebugger_r(this, dscript, sourceString);
- } else {
- throw new RuntimeException("NOT SUPPORTED");
- }
- }
-
- Object result;
- if (returnFunction) {
- result = compiler.createFunctionObject(this, scope, bytecode, securityDomain);
- } else {
- result = compiler.createScriptObject(bytecode, securityDomain);
- }
-
- return result;
- }
-
- private static void notifyDebugger_r(Context cx, DebuggableScript dscript,
- String debugSource)
- {
- cx.debugger.handleCompilationDone(cx, dscript, debugSource);
- for (int i = 0; i != dscript.getFunctionCount(); ++i) {
- notifyDebugger_r(cx, dscript.getFunction(i), debugSource);
- }
- }
-
- private static Class codegenClass = Kit.classOrNull(
- "org.mozilla.javascript.optimizer.Codegen");
- private static Class interpreterClass = Kit.classOrNull(
- "org.mozilla.javascript.Interpreter");
-
- private Evaluator createCompiler()
- {
- Evaluator result = null;
- if (optimizationLevel >= 0 && codegenClass != null) {
- result = (Evaluator)Kit.newInstanceOrNull(codegenClass);
- }
- if (result == null) {
- result = createInterpreter();
- }
- return result;
- }
-
- static Evaluator createInterpreter()
- {
- return (Evaluator)Kit.newInstanceOrNull(interpreterClass);
- }
-
- static String getSourcePositionFromStack(int[] linep)
- {
- Context cx = getCurrentContext();
- if (cx == null)
- return null;
- if (cx.lastInterpreterFrame != null) {
- Evaluator evaluator = createInterpreter();
- if (evaluator != null)
- return evaluator.getSourcePositionFromStack(cx, linep);
- }
- /**
- * A bit of a hack, but the only way to get filename and line
- * number from an enclosing frame.
- */
- CharArrayWriter writer = new CharArrayWriter();
- RuntimeException re = new RuntimeException();
- re.printStackTrace(new PrintWriter(writer));
- String s = writer.toString();
- int open = -1;
- int close = -1;
- int colon = -1;
- for (int i=0; i < s.length(); i++) {
- char c = s.charAt(i);
- if (c == ':')
- colon = i;
- else if (c == '(')
- open = i;
- else if (c == ')')
- close = i;
- else if (c == '\n' && open != -1 && close != -1 && colon != -1 &&
- open < colon && colon < close)
- {
- String fileStr = s.substring(open + 1, colon);
- if (!fileStr.endsWith(".java")) {
- String lineStr = s.substring(colon + 1, close);
- try {
- linep[0] = Integer.parseInt(lineStr);
- if (linep[0] < 0) {
- linep[0] = 0;
- }
- return fileStr;
- }
- catch (NumberFormatException e) {
- // fall through
- }
- }
- open = close = colon = -1;
- }
- }
-
- return null;
- }
-
- RegExpProxy getRegExpProxy()
- {
- if (regExpProxy == null) {
- Class cl = Kit.classOrNull(
- "org.mozilla.javascript.regexp.RegExpImpl");
- if (cl != null) {
- regExpProxy = (RegExpProxy)Kit.newInstanceOrNull(cl);
- }
- }
- return regExpProxy;
- }
-
- final boolean isVersionECMA1()
- {
- return version == VERSION_DEFAULT || version >= VERSION_1_3;
- }
-
-// The method must NOT be public or protected
- SecurityController getSecurityController()
- {
- SecurityController global = SecurityController.global();
- if (global != null) {
- return global;
- }
- return securityController;
- }
-
- public final boolean isGeneratingDebugChanged()
- {
- return generatingDebugChanged;
- }
-
- /**
- * Add a name to the list of names forcing the creation of real
- * activation objects for functions.
- *
- * @param name the name of the object to add to the list
- */
- public void addActivationName(String name)
- {
- if (sealed) onSealedMutation();
- if (activationNames == null)
- activationNames = new Hashtable(5);
- activationNames.put(name, name);
- }
-
- /**
- * Check whether the name is in the list of names of objects
- * forcing the creation of activation objects.
- *
- * @param name the name of the object to test
- *
- * @return true if an function activation object is needed.
- */
- public final boolean isActivationNeeded(String name)
- {
- return activationNames != null && activationNames.containsKey(name);
- }
-
- /**
- * Remove a name from the list of names forcing the creation of real
- * activation objects for functions.
- *
- * @param name the name of the object to remove from the list
- */
- public void removeActivationName(String name)
- {
- if (sealed) onSealedMutation();
- if (activationNames != null)
- activationNames.remove(name);
- }
-
- private static String implementationVersion;
-
- private final ContextFactory factory;
- private boolean sealed;
- private Object sealKey;
-
- Scriptable topCallScope;
- NativeCall currentActivationCall;
- XMLLib cachedXMLLib;
-
- // for Objects, Arrays to tag themselves as being printed out,
- // so they don't print themselves out recursively.
- // Use ObjToIntMap instead of java.util.HashSet for JDK 1.1 compatibility
- ObjToIntMap iterating;
-
- Object interpreterSecurityDomain;
-
- int version;
-
- private SecurityController securityController;
- private ClassShutter classShutter;
- private ErrorReporter errorReporter;
- RegExpProxy regExpProxy;
- private Locale locale;
- private boolean generatingDebug;
- private boolean generatingDebugChanged;
- private boolean generatingSource=true;
- boolean compileFunctionsWithDynamicScopeFlag;
- boolean useDynamicScope;
- private int optimizationLevel;
- private int maximumInterpreterStackDepth;
- private WrapFactory wrapFactory;
- Debugger debugger;
- private Object debuggerData;
- private int enterCount;
- private Object propertyListeners;
- private Hashtable hashtable;
- private ClassLoader applicationClassLoader;
-
- /**
- * This is the list of names of objects forcing the creation of
- * function activation records.
- */
- Hashtable activationNames;
-
- // For the interpreter to store the last frame for error reports etc.
- Object lastInterpreterFrame;
-
- // For the interpreter to store information about previous invocations
- // interpreter invocations
- ObjArray previousInterpreterInvocations;
-
- // For instruction counting (interpreter only)
- int instructionCount;
- int instructionThreshold;
-
- // It can be used to return the second index-like result from function
- int scratchIndex;
-
- // It can be used to return the second uint32 result from function
- long scratchUint32;
-
- // It can be used to return the second Scriptable result from function
- Scriptable scratchScriptable;
-
- // Generate an observer count on compiled code
- public boolean generateObserverCount = false;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextAction.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextAction.java
deleted file mode 100644
index 1c584a9..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextAction.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- 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):
- * Igor Bukanov, igor@fastmail.fm
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * Interface to represent arbitrary action that requires to have Context
- * object associated with the current thread for its execution.
- */
-public interface ContextAction
-{
- /**
- * Execute action using the supplied Context instance.
- * When Rhino runtime calls the method, <tt>cx</tt> will be associated
- * with the current thread as active context.
- *
- * @see Context#call(ContextAction)
- * @see ContextFactory#call(ContextAction)
- */
- public Object run(Context cx);
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextFactory.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextFactory.java
deleted file mode 100644
index 4f9fde2..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextFactory.java
+++ /dev/null
@@ -1,594 +0,0 @@
-/* -*- 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):
- * Igor Bukanov, igor@fastmail.fm
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * Factory class that Rhino runtime uses to create new {@link Context}
- * instances. A <code>ContextFactory</code> can also notify listeners
- * about context creation and release.
- * <p>
- * When the Rhino runtime needs to create new {@link Context} instance during
- * execution of {@link Context#enter()} or {@link Context}, it will call
- * {@link #makeContext()} of the current global ContextFactory.
- * See {@link #getGlobal()} and {@link #initGlobal(ContextFactory)}.
- * <p>
- * It is also possible to use explicit ContextFactory instances for Context
- * creation. This is useful to have a set of independent Rhino runtime
- * instances under single JVM. See {@link #call(ContextAction)}.
- * <p>
- * The following example demonstrates Context customization to terminate
- * scripts running more then 10 seconds and to provide better compatibility
- * with JavaScript code using MSIE-specific features.
- * <pre>
- * import org.mozilla.javascript.*;
- *
- * class MyFactory extends ContextFactory
- * {
- *
- * // Custom {@link Context} to store execution time.
- * private static class MyContext extends Context
- * {
- * long startTime;
- * }
- *
- * static {
- * // Initialize GlobalFactory with custom factory
- * ContextFactory.initGlobal(new MyFactory());
- * }
- *
- * // Override {@link #makeContext()}
- * protected Context makeContext()
- * {
- * MyContext cx = new MyContext();
- * // Use pure interpreter mode to allow for
- * // {@link #observeInstructionCount(Context, int)} to work
- * cx.setOptimizationLevel(-1);
- * // Make Rhino runtime to call observeInstructionCount
- * // each 10000 bytecode instructions
- * cx.setInstructionObserverThreshold(10000);
- * return cx;
- * }
- *
- * // Override {@link #hasFeature(Context, int)}
- * public boolean hasFeature(Context cx, int featureIndex)
- * {
- * // Turn on maximum compatibility with MSIE scripts
- * switch (featureIndex) {
- * case {@link Context#FEATURE_NON_ECMA_GET_YEAR}:
- * return true;
- *
- * case {@link Context#FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME}:
- * return true;
- *
- * case {@link Context#FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER}:
- * return true;
- *
- * case {@link Context#FEATURE_PARENT_PROTO_PROPERTIES}:
- * return false;
- * }
- * return super.hasFeature(cx, featureIndex);
- * }
- *
- * // Override {@link #observeInstructionCount(Context, int)}
- * protected void observeInstructionCount(Context cx, int instructionCount)
- * {
- * MyContext mcx = (MyContext)cx;
- * long currentTime = System.currentTimeMillis();
- * if (currentTime - mcx.startTime > 10*1000) {
- * // More then 10 seconds from Context creation time:
- * // it is time to stop the script.
- * // Throw Error instance to ensure that script will never
- * // get control back through catch or finally.
- * throw new Error();
- * }
- * }
- *
- * // Override {@link #doTopCall(Callable,
- Context, Scriptable,
- Scriptable, Object[])}
- * protected Object doTopCall(Callable callable,
- * Context cx, Scriptable scope,
- * Scriptable thisObj, Object[] args)
- * {
- * MyContext mcx = (MyContext)cx;
- * mcx.startTime = System.currentTimeMillis();
- *
- * return super.doTopCall(callable, cx, scope, thisObj, args);
- * }
- *
- * }
- *
- * </pre>
- */
-
-public class ContextFactory
-{
- private static volatile boolean hasCustomGlobal;
- private static ContextFactory global = new ContextFactory();
-
- private volatile boolean sealed;
-
- private final Object listenersLock = new Object();
- private volatile Object listeners;
- private boolean disabledListening;
- private ClassLoader applicationClassLoader;
-
- /**
- * Listener of {@link Context} creation and release events.
- */
- public interface Listener
- {
- /**
- * Notify about newly created {@link Context} object.
- */
- public void contextCreated(Context cx);
-
- /**
- * Notify that the specified {@link Context} instance is no longer
- * associated with the current thread.
- */
- public void contextReleased(Context cx);
- }
-
- /**
- * Get global ContextFactory.
- *
- * @see #hasExplicitGlobal()
- * @see #initGlobal(ContextFactory)
- */
- public static ContextFactory getGlobal()
- {
- return global;
- }
-
- /**
- * Check if global factory was set.
- * Return true to indicate that {@link #initGlobal(ContextFactory)} was
- * already called and false to indicate that the global factory was not
- * explicitly set.
- *
- * @see #getGlobal()
- * @see #initGlobal(ContextFactory)
- */
- public static boolean hasExplicitGlobal()
- {
- return hasCustomGlobal;
- }
-
- /**
- * Set global ContextFactory.
- * The method can only be called once.
- *
- * @see #getGlobal()
- * @see #hasExplicitGlobal()
- */
- public synchronized static void initGlobal(ContextFactory factory)
- {
- if (factory == null) {
- throw new IllegalArgumentException();
- }
- if (hasCustomGlobal) {
- throw new IllegalStateException();
- }
- hasCustomGlobal = true;
- global = factory;
- }
-
- /**
- * Create new {@link Context} instance to be associated with the current
- * thread.
- * This is a callback method used by Rhino to create {@link Context}
- * instance when it is necessary to associate one with the current
- * execution thread. <tt>makeContext()</tt> is allowed to call
- * {@link Context#seal(Object)} on the result to prevent
- * {@link Context} changes by hostile scripts or applets.
- */
- protected Context makeContext()
- {
- return new Context(this);
- }
-
- /**
- * Implementation of {@link Context#hasFeature(int featureIndex)}.
- * This can be used to customize {@link Context} without introducing
- * additional subclasses.
- */
- protected boolean hasFeature(Context cx, int featureIndex)
- {
- int version;
- switch (featureIndex) {
- case Context.FEATURE_NON_ECMA_GET_YEAR:
- /*
- * During the great date rewrite of 1.3, we tried to track the
- * evolving ECMA standard, which then had a definition of
- * getYear which always subtracted 1900. Which we
- * implemented, not realizing that it was incompatible with
- * the old behavior... now, rather than thrash the behavior
- * yet again, we've decided to leave it with the - 1900
- * behavior and point people to the getFullYear method. But
- * we try to protect existing scripts that have specified a
- * version...
- */
- version = cx.getLanguageVersion();
- return (version == Context.VERSION_1_0
- || version == Context.VERSION_1_1
- || version == Context.VERSION_1_2);
-
- case Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME:
- return false;
-
- case Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER:
- return false;
-
- case Context.FEATURE_TO_STRING_AS_SOURCE:
- version = cx.getLanguageVersion();
- return version == Context.VERSION_1_2;
-
- case Context.FEATURE_PARENT_PROTO_PROPERTIES:
- return true;
-
- case Context.FEATURE_E4X:
- version = cx.getLanguageVersion();
- return (version == Context.VERSION_DEFAULT
- || version >= Context.VERSION_1_6);
-
- case Context.FEATURE_DYNAMIC_SCOPE:
- return false;
-
- case Context.FEATURE_STRICT_VARS:
- return false;
-
- case Context.FEATURE_STRICT_EVAL:
- return false;
-
- case Context.FEATURE_LOCATION_INFORMATION_IN_ERROR:
- return false;
-
- case Context.FEATURE_STRICT_MODE:
- return false;
-
- case Context.FEATURE_WARNING_AS_ERROR:
- return false;
-
- case Context.FEATURE_ENHANCED_JAVA_ACCESS:
- return false;
- }
- // It is a bug to call the method with unknown featureIndex
- throw new IllegalArgumentException(String.valueOf(featureIndex));
- }
-
- private boolean isDom3Present() {
- Class nodeClass = Kit.classOrNull("org.w3c.dom.Node");
- if (nodeClass == null) return false;
- // Check to see whether DOM3 is present; use a new method defined in
- // DOM3 that is vital to our implementation
- try {
- nodeClass.getMethod("getUserData", new Class[] { String.class });
- return true;
- } catch (NoSuchMethodException e) {
- return false;
- }
- }
-
- /**
- * Provides a default
- * {@link org.mozilla.javascript.xml.XMLLib.Factory XMLLib.Factory}
- * to be used by the <code>Context</code> instances produced by this
- * factory. See {@link Context#getE4xImplementationFactory} for details.
- *
- * May return null, in which case E4X functionality is not supported in
- * Rhino.
- *
- * The default implementation now prefers the DOM3 E4X implementation.
- */
- protected org.mozilla.javascript.xml.XMLLib.Factory
- getE4xImplementationFactory()
- {
- // Must provide default implementation, rather than abstract method,
- // so that past implementors of ContextFactory do not fail at runtime
- // upon invocation of this method.
- // Note that the default implementation returns null if we
- // neither have XMLBeans nor a DOM3 implementation present.
-
- if (isDom3Present()) {
- return org.mozilla.javascript.xml.XMLLib.Factory.create(
- "org.mozilla.javascript.xmlimpl.XMLLibImpl"
- );
- } else if (Kit.classOrNull("org.apache.xmlbeans.XmlCursor") != null) {
- return org.mozilla.javascript.xml.XMLLib.Factory.create(
- "org.mozilla.javascript.xml.impl.xmlbeans.XMLLibImpl"
- );
- } else {
- return null;
- }
- }
-
-
- /**
- * Create class loader for generated classes.
- * This method creates an instance of the default implementation
- * of {@link GeneratedClassLoader}. Rhino uses this interface to load
- * generated JVM classes when no {@link SecurityController}
- * is installed.
- * Application can override the method to provide custom class loading.
- */
- protected GeneratedClassLoader createClassLoader(ClassLoader parent)
- {
- return new DefiningClassLoader(parent);
- }
-
- /**
- * Get ClassLoader to use when searching for Java classes.
- * Unless it was explicitly initialized with
- * {@link #initApplicationClassLoader(ClassLoader)} the method returns
- * null to indicate that Thread.getContextClassLoader() should be used.
- */
- public final ClassLoader getApplicationClassLoader()
- {
- return applicationClassLoader;
- }
-
- /**
- * Set explicit class loader to use when searching for Java classes.
- *
- * @see #getApplicationClassLoader()
- */
- public final void initApplicationClassLoader(ClassLoader loader)
- {
- if (loader == null)
- throw new IllegalArgumentException("loader is null");
- if (!Kit.testIfCanLoadRhinoClasses(loader))
- throw new IllegalArgumentException(
- "Loader can not resolve Rhino classes");
-
- if (this.applicationClassLoader != null)
- throw new IllegalStateException(
- "applicationClassLoader can only be set once");
- checkNotSealed();
-
- this.applicationClassLoader = loader;
- }
-
- /**
- * Execute top call to script or function.
- * When the runtime is about to execute a script or function that will
- * create the first stack frame with scriptable code, it calls this method
- * to perform the real call. In this way execution of any script
- * happens inside this function.
- */
- protected Object doTopCall(Callable callable,
- Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- return callable.call(cx, scope, thisObj, args);
- }
-
- /**
- * Implementation of
- * {@link Context#observeInstructionCount(int instructionCount)}.
- * This can be used to customize {@link Context} without introducing
- * additional subclasses.
- */
- protected void observeInstructionCount(Context cx, int instructionCount)
- {
- }
-
- protected void onContextCreated(Context cx)
- {
- Object listeners = this.listeners;
- for (int i = 0; ; ++i) {
- Listener l = (Listener)Kit.getListener(listeners, i);
- if (l == null)
- break;
- l.contextCreated(cx);
- }
- }
-
- protected void onContextReleased(Context cx)
- {
- Object listeners = this.listeners;
- for (int i = 0; ; ++i) {
- Listener l = (Listener)Kit.getListener(listeners, i);
- if (l == null)
- break;
- l.contextReleased(cx);
- }
- }
-
- public final void addListener(Listener listener)
- {
- checkNotSealed();
- synchronized (listenersLock) {
- if (disabledListening) {
- throw new IllegalStateException();
- }
- listeners = Kit.addListener(listeners, listener);
- }
- }
-
- public final void removeListener(Listener listener)
- {
- checkNotSealed();
- synchronized (listenersLock) {
- if (disabledListening) {
- throw new IllegalStateException();
- }
- listeners = Kit.removeListener(listeners, listener);
- }
- }
-
- /**
- * The method is used only to implement
- * Context.disableStaticContextListening()
- */
- final void disableContextListening()
- {
- checkNotSealed();
- synchronized (listenersLock) {
- disabledListening = true;
- listeners = null;
- }
- }
-
- /**
- * Checks if this is a sealed ContextFactory.
- * @see #seal()
- */
- public final boolean isSealed()
- {
- return sealed;
- }
-
- /**
- * Seal this ContextFactory so any attempt to modify it like to add or
- * remove its listeners will throw an exception.
- * @see #isSealed()
- */
- public final void seal()
- {
- checkNotSealed();
- sealed = true;
- }
-
- protected final void checkNotSealed()
- {
- if (sealed) throw new IllegalStateException();
- }
-
- /**
- * Call {@link ContextAction#run(Context cx)}
- * using the {@link Context} instance associated with the current thread.
- * If no Context is associated with the thread, then
- * {@link #makeContext()} will be called to construct
- * new Context instance. The instance will be temporary associated
- * with the thread during call to {@link ContextAction#run(Context)}.
- *
- * @see ContextFactory#call(ContextAction)
- * @see Context#call(ContextFactory factory, Callable callable,
- * Scriptable scope, Scriptable thisObj,
- * Object[] args)
- */
- public final Object call(ContextAction action)
- {
- return Context.call(this, action);
- }
-
- /**
- * Get a context associated with the current thread, creating one if need
- * be. The Context stores the execution state of the JavaScript engine, so
- * it is required that the context be entered before execution may begin.
- * Once a thread has entered a Context, then getCurrentContext() may be
- * called to find the context that is associated with the current thread.
- * <p>
- * Calling <code>enterContext()</code> will return either the Context
- * currently associated with the thread, or will create a new context and
- * associate it with the current thread. Each call to
- * <code>enterContext()</code> must have a matching call to
- * {@link Context#exit()}.
- * <pre>
- * Context cx = contextFactory.enterContext();
- * try {
- * ...
- * cx.evaluateString(...);
- * } finally {
- * Context.exit();
- * }
- * </pre>
- * Instead of using <tt>enterContext()</tt>, <tt>exit()</tt> pair consider
- * using {@link #call(ContextAction)} which guarantees proper association
- * of Context instances with the current thread.
- * With this method the above example becomes:
- * <pre>
- * ContextFactory.call(new ContextAction() {
- * public Object run(Context cx) {
- * ...
- * cx.evaluateString(...);
- * return null;
- * }
- * });
- * </pre>
- * @return a Context associated with the current thread
- * @see Context#getCurrentContext()
- * @see Context#exit()
- * @see #call(ContextAction)
- */
- public Context enterContext()
- {
- return enterContext(null);
- }
-
- /**
- * @deprecated use {@link #enterContext()} instead
- * @return a Context associated with the current thread
- */
- public final Context enter()
- {
- return enterContext(null);
- }
-
- /**
- * @deprecated Use {@link Context#exit()} instead.
- */
- public final void exit()
- {
- Context.exit();
- }
-
- /**
- * Get a Context associated with the current thread, using the given
- * Context if need be.
- * <p>
- * The same as <code>enterContext()</code> except that <code>cx</code>
- * is associated with the current thread and returned if the current thread
- * has no associated context and <code>cx</code> is not associated with any
- * other thread.
- * @param cx a Context to associate with the thread if possible
- * @return a Context associated with the current thread
- * @see #enterContext()
- * @see #call(ContextAction)
- * @throws IllegalStateException if <code>cx</code> is already associated
- * with a different thread
- */
- public final Context enterContext(Context cx)
- {
- return Context.enter(cx, this);
- }
-} \ No newline at end of file
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextListener.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextListener.java
deleted file mode 100644
index 5e17145..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextListener.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * @deprecated Embeddings that wish to customize newly created
- * {@link Context} instances should implement
- * {@link ContextFactory.Listener}.
- */
-public interface ContextListener extends ContextFactory.Listener
-{
-
- /**
- * @deprecated Rhino runtime never calls the method.
- */
- public void contextEntered(Context cx);
-
- /**
- * @deprecated Rhino runtime never calls the method.
- */
- public void contextExited(Context cx);
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DToA.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DToA.java
deleted file mode 100644
index ad2a68a..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DToA.java
+++ /dev/null
@@ -1,1271 +0,0 @@
-/* -*- 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):
- * Waldemar Horwat
- * Roger Lawrence
- * Attila Szegedi
- *
- * 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 ***** */
-
-/****************************************************************
- *
- * The author of this software is David M. Gay.
- *
- * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose without fee is hereby granted, provided that this entire notice
- * is included in all copies of any software which is or includes a copy
- * or modification of this software and in all copies of the supporting
- * documentation for such software.
- *
- * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
- * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
- * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
- *
- ***************************************************************/
-
-package org.mozilla.javascript;
-
-import java.math.BigInteger;
-
-class DToA {
-
-
-/* "-0.0000...(1073 zeros after decimal point)...0001\0" is the longest string that we could produce,
- * which occurs when printing -5e-324 in binary. We could compute a better estimate of the size of
- * the output string and malloc fewer bytes depending on d and base, but why bother? */
-
- private static final int DTOBASESTR_BUFFER_SIZE = 1078;
-
- private static char BASEDIGIT(int digit) {
- return (char)((digit >= 10) ? 'a' - 10 + digit : '0' + digit);
- }
-
- static final int
- DTOSTR_STANDARD = 0, /* Either fixed or exponential format; round-trip */
- DTOSTR_STANDARD_EXPONENTIAL = 1, /* Always exponential format; round-trip */
- DTOSTR_FIXED = 2, /* Round to <precision> digits after the decimal point; exponential if number is large */
- DTOSTR_EXPONENTIAL = 3, /* Always exponential format; <precision> significant digits */
- DTOSTR_PRECISION = 4; /* Either fixed or exponential format; <precision> significant digits */
-
-
- private static final int Frac_mask = 0xfffff;
- private static final int Exp_shift = 20;
- private static final int Exp_msk1 = 0x100000;
-
- private static final long Frac_maskL = 0xfffffffffffffL;
- private static final int Exp_shiftL = 52;
- private static final long Exp_msk1L = 0x10000000000000L;
-
- private static final int Bias = 1023;
- private static final int P = 53;
-
- private static final int Exp_shift1 = 20;
- private static final int Exp_mask = 0x7ff00000;
- private static final int Exp_mask_shifted = 0x7ff;
- private static final int Bndry_mask = 0xfffff;
- private static final int Log2P = 1;
-
- private static final int Sign_bit = 0x80000000;
- private static final int Exp_11 = 0x3ff00000;
- private static final int Ten_pmax = 22;
- private static final int Quick_max = 14;
- private static final int Bletch = 0x10;
- private static final int Frac_mask1 = 0xfffff;
- private static final int Int_max = 14;
- private static final int n_bigtens = 5;
-
-
- private static final double tens[] = {
- 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
- 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
- 1e20, 1e21, 1e22
- };
-
- private static final double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
-
- private static int lo0bits(int y)
- {
- int k;
- int x = y;
-
- if ((x & 7) != 0) {
- if ((x & 1) != 0)
- return 0;
- if ((x & 2) != 0) {
- return 1;
- }
- return 2;
- }
- k = 0;
- if ((x & 0xffff) == 0) {
- k = 16;
- x >>>= 16;
- }
- if ((x & 0xff) == 0) {
- k += 8;
- x >>>= 8;
- }
- if ((x & 0xf) == 0) {
- k += 4;
- x >>>= 4;
- }
- if ((x & 0x3) == 0) {
- k += 2;
- x >>>= 2;
- }
- if ((x & 1) == 0) {
- k++;
- x >>>= 1;
- if ((x & 1) == 0)
- return 32;
- }
- return k;
- }
-
- /* Return the number (0 through 32) of most significant zero bits in x. */
- private static int hi0bits(int x)
- {
- int k = 0;
-
- if ((x & 0xffff0000) == 0) {
- k = 16;
- x <<= 16;
- }
- if ((x & 0xff000000) == 0) {
- k += 8;
- x <<= 8;
- }
- if ((x & 0xf0000000) == 0) {
- k += 4;
- x <<= 4;
- }
- if ((x & 0xc0000000) == 0) {
- k += 2;
- x <<= 2;
- }
- if ((x & 0x80000000) == 0) {
- k++;
- if ((x & 0x40000000) == 0)
- return 32;
- }
- return k;
- }
-
- private static void stuffBits(byte bits[], int offset, int val)
- {
- bits[offset] = (byte)(val >> 24);
- bits[offset + 1] = (byte)(val >> 16);
- bits[offset + 2] = (byte)(val >> 8);
- bits[offset + 3] = (byte)(val);
- }
-
- /* Convert d into the form b*2^e, where b is an odd integer. b is the returned
- * Bigint and e is the returned binary exponent. Return the number of significant
- * bits in b in bits. d must be finite and nonzero. */
- private static BigInteger d2b(double d, int[] e, int[] bits)
- {
- byte dbl_bits[];
- int i, k, y, z, de;
- long dBits = Double.doubleToLongBits(d);
- int d0 = (int)(dBits >>> 32);
- int d1 = (int)(dBits);
-
- z = d0 & Frac_mask;
- d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
-
- if ((de = (d0 >>> Exp_shift)) != 0)
- z |= Exp_msk1;
-
- if ((y = d1) != 0) {
- dbl_bits = new byte[8];
- k = lo0bits(y);
- y >>>= k;
- if (k != 0) {
- stuffBits(dbl_bits, 4, y | z << (32 - k));
- z >>= k;
- }
- else
- stuffBits(dbl_bits, 4, y);
- stuffBits(dbl_bits, 0, z);
- i = (z != 0) ? 2 : 1;
- }
- else {
- // JS_ASSERT(z);
- dbl_bits = new byte[4];
- k = lo0bits(z);
- z >>>= k;
- stuffBits(dbl_bits, 0, z);
- k += 32;
- i = 1;
- }
- if (de != 0) {
- e[0] = de - Bias - (P-1) + k;
- bits[0] = P - k;
- }
- else {
- e[0] = de - Bias - (P-1) + 1 + k;
- bits[0] = 32*i - hi0bits(z);
- }
- return new BigInteger(dbl_bits);
- }
-
- static String JS_dtobasestr(int base, double d)
- {
- if (!(2 <= base && base <= 36))
- throw new IllegalArgumentException("Bad base: "+base);
-
- /* Check for Infinity and NaN */
- if (Double.isNaN(d)) {
- return "NaN";
- } else if (Double.isInfinite(d)) {
- return (d > 0.0) ? "Infinity" : "-Infinity";
- } else if (d == 0) {
- // ALERT: should it distinguish -0.0 from +0.0 ?
- return "0";
- }
-
- boolean negative;
- if (d >= 0.0) {
- negative = false;
- } else {
- negative = true;
- d = -d;
- }
-
- /* Get the integer part of d including '-' sign. */
- String intDigits;
-
- double dfloor = Math.floor(d);
- long lfloor = (long)dfloor;
- if (lfloor == dfloor) {
- // int part fits long
- intDigits = Long.toString((negative) ? -lfloor : lfloor, base);
- } else {
- // BigInteger should be used
- long floorBits = Double.doubleToLongBits(dfloor);
- int exp = (int)(floorBits >> Exp_shiftL) & Exp_mask_shifted;
- long mantissa;
- if (exp == 0) {
- mantissa = (floorBits & Frac_maskL) << 1;
- } else {
- mantissa = (floorBits & Frac_maskL) | Exp_msk1L;
- }
- if (negative) {
- mantissa = -mantissa;
- }
- exp -= 1075;
- BigInteger x = BigInteger.valueOf(mantissa);
- if (exp > 0) {
- x = x.shiftLeft(exp);
- } else if (exp < 0) {
- x = x.shiftRight(-exp);
- }
- intDigits = x.toString(base);
- }
-
- if (d == dfloor) {
- // No fraction part
- return intDigits;
- } else {
- /* We have a fraction. */
-
- char[] buffer; /* The output string */
- int p; /* index to current position in the buffer */
- int digit;
- double df; /* The fractional part of d */
- BigInteger b;
-
- buffer = new char[DTOBASESTR_BUFFER_SIZE];
- p = 0;
- df = d - dfloor;
-
- long dBits = Double.doubleToLongBits(d);
- int word0 = (int)(dBits >> 32);
- int word1 = (int)(dBits);
-
- int[] e = new int[1];
- int[] bbits = new int[1];
-
- b = d2b(df, e, bbits);
-// JS_ASSERT(e < 0);
- /* At this point df = b * 2^e. e must be less than zero because 0 < df < 1. */
-
- int s2 = -(word0 >>> Exp_shift1 & Exp_mask >> Exp_shift1);
- if (s2 == 0)
- s2 = -1;
- s2 += Bias + P;
- /* 1/2^s2 = (nextDouble(d) - d)/2 */
-// JS_ASSERT(-s2 < e);
- BigInteger mlo = BigInteger.valueOf(1);
- BigInteger mhi = mlo;
- if ((word1 == 0) && ((word0 & Bndry_mask) == 0)
- && ((word0 & (Exp_mask & Exp_mask << 1)) != 0)) {
- /* The special case. Here we want to be within a quarter of the last input
- significant digit instead of one half of it when the output string's value is less than d. */
- s2 += Log2P;
- mhi = BigInteger.valueOf(1<<Log2P);
- }
-
- b = b.shiftLeft(e[0] + s2);
- BigInteger s = BigInteger.valueOf(1);
- s = s.shiftLeft(s2);
- /* At this point we have the following:
- * s = 2^s2;
- * 1 > df = b/2^s2 > 0;
- * (d - prevDouble(d))/2 = mlo/2^s2;
- * (nextDouble(d) - d)/2 = mhi/2^s2. */
- BigInteger bigBase = BigInteger.valueOf(base);
-
- boolean done = false;
- do {
- b = b.multiply(bigBase);
- BigInteger[] divResult = b.divideAndRemainder(s);
- b = divResult[1];
- digit = (char)(divResult[0].intValue());
- if (mlo == mhi)
- mlo = mhi = mlo.multiply(bigBase);
- else {
- mlo = mlo.multiply(bigBase);
- mhi = mhi.multiply(bigBase);
- }
-
- /* Do we yet have the shortest string that will round to d? */
- int j = b.compareTo(mlo);
- /* j is b/2^s2 compared with mlo/2^s2. */
- BigInteger delta = s.subtract(mhi);
- int j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta);
- /* j1 is b/2^s2 compared with 1 - mhi/2^s2. */
- if (j1 == 0 && ((word1 & 1) == 0)) {
- if (j > 0)
- digit++;
- done = true;
- } else
- if (j < 0 || (j == 0 && ((word1 & 1) == 0))) {
- if (j1 > 0) {
- /* Either dig or dig+1 would work here as the least significant digit.
- Use whichever would produce an output value closer to d. */
- b = b.shiftLeft(1);
- j1 = b.compareTo(s);
- if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output
- * such as 3.5 in base 3. */
- digit++;
- }
- done = true;
- } else if (j1 > 0) {
- digit++;
- done = true;
- }
-// JS_ASSERT(digit < (uint32)base);
- buffer[p++] = BASEDIGIT(digit);
- } while (!done);
-
- StringBuffer sb = new StringBuffer(intDigits.length() + 1 + p);
- sb.append(intDigits);
- sb.append('.');
- sb.append(buffer, 0, p);
- return sb.toString();
- }
-
- }
-
- /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
- *
- * Inspired by "How to Print Floating-Point Numbers Accurately" by
- * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
- *
- * Modifications:
- * 1. Rather than iterating, we use a simple numeric overestimate
- * to determine k = floor(log10(d)). We scale relevant
- * quantities using O(log2(k)) rather than O(k) multiplications.
- * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
- * try to generate digits strictly left to right. Instead, we
- * compute with fewer bits and propagate the carry if necessary
- * when rounding the final digit up. This is often faster.
- * 3. Under the assumption that input will be rounded nearest,
- * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
- * That is, we allow equality in stopping tests when the
- * round-nearest rule will give the same floating-point value
- * as would satisfaction of the stopping test with strict
- * inequality.
- * 4. We remove common factors of powers of 2 from relevant
- * quantities.
- * 5. When converting floating-point integers less than 1e16,
- * we use floating-point arithmetic rather than resorting
- * to multiple-precision integers.
- * 6. When asked to produce fewer than 15 digits, we first try
- * to get by with floating-point arithmetic; we resort to
- * multiple-precision integer arithmetic only if we cannot
- * guarantee that the floating-point calculation has given
- * the correctly rounded result. For k requested digits and
- * "uniformly" distributed input, the probability is
- * something like 10^(k-15) that we must resort to the Long
- * calculation.
- */
-
- static int word0(double d)
- {
- long dBits = Double.doubleToLongBits(d);
- return (int)(dBits >> 32);
- }
-
- static double setWord0(double d, int i)
- {
- long dBits = Double.doubleToLongBits(d);
- dBits = ((long)i << 32) | (dBits & 0x0FFFFFFFFL);
- return Double.longBitsToDouble(dBits);
- }
-
- static int word1(double d)
- {
- long dBits = Double.doubleToLongBits(d);
- return (int)(dBits);
- }
-
- /* Return b * 5^k. k must be nonnegative. */
- // XXXX the C version built a cache of these
- static BigInteger pow5mult(BigInteger b, int k)
- {
- return b.multiply(BigInteger.valueOf(5).pow(k));
- }
-
- static boolean roundOff(StringBuffer buf)
- {
- int i = buf.length();
- while (i != 0) {
- --i;
- char c = buf.charAt(i);
- if (c != '9') {
- buf.setCharAt(i, (char)(c + 1));
- buf.setLength(i + 1);
- return false;
- }
- }
- buf.setLength(0);
- return true;
- }
-
- /* Always emits at least one digit. */
- /* If biasUp is set, then rounding in modes 2 and 3 will round away from zero
- * when the number is exactly halfway between two representable values. For example,
- * rounding 2.5 to zero digits after the decimal point will return 3 and not 2.
- * 2.49 will still round to 2, and 2.51 will still round to 3. */
- /* bufsize should be at least 20 for modes 0 and 1. For the other modes,
- * bufsize should be two greater than the maximum number of output characters expected. */
- static int
- JS_dtoa(double d, int mode, boolean biasUp, int ndigits,
- boolean[] sign, StringBuffer buf)
- {
- /* Arguments ndigits, decpt, sign are similar to those
- of ecvt and fcvt; trailing zeros are suppressed from
- the returned string. If not null, *rve is set to point
- to the end of the return value. If d is +-Infinity or NaN,
- then *decpt is set to 9999.
-
- mode:
- 0 ==> shortest string that yields d when read in
- and rounded to nearest.
- 1 ==> like 0, but with Steele & White stopping rule;
- e.g. with IEEE P754 arithmetic , mode 0 gives
- 1e23 whereas mode 1 gives 9.999999999999999e22.
- 2 ==> max(1,ndigits) significant digits. This gives a
- return value similar to that of ecvt, except
- that trailing zeros are suppressed.
- 3 ==> through ndigits past the decimal point. This
- gives a return value similar to that from fcvt,
- except that trailing zeros are suppressed, and
- ndigits can be negative.
- 4-9 should give the same return values as 2-3, i.e.,
- 4 <= mode <= 9 ==> same return as mode
- 2 + (mode & 1). These modes are mainly for
- debugging; often they run slower but sometimes
- faster than modes 2-3.
- 4,5,8,9 ==> left-to-right digit generation.
- 6-9 ==> don't try fast floating-point estimate
- (if applicable).
-
- Values of mode other than 0-9 are treated as mode 0.
-
- Sufficient space is allocated to the return value
- to hold the suppressed trailing zeros.
- */
-
- int b2, b5, i, ieps, ilim, ilim0, ilim1,
- j, j1, k, k0, m2, m5, s2, s5;
- char dig;
- long L;
- long x;
- BigInteger b, b1, delta, mlo, mhi, S;
- int[] be = new int[1];
- int[] bbits = new int[1];
- double d2, ds, eps;
- boolean spec_case, denorm, k_check, try_quick, leftright;
-
- if ((word0(d) & Sign_bit) != 0) {
- /* set sign for everything, including 0's and NaNs */
- sign[0] = true;
- // word0(d) &= ~Sign_bit; /* clear sign bit */
- d = setWord0(d, word0(d) & ~Sign_bit);
- }
- else
- sign[0] = false;
-
- if ((word0(d) & Exp_mask) == Exp_mask) {
- /* Infinity or NaN */
- buf.append(((word1(d) == 0) && ((word0(d) & Frac_mask) == 0)) ? "Infinity" : "NaN");
- return 9999;
- }
- if (d == 0) {
-// no_digits:
- buf.setLength(0);
- buf.append('0'); /* copy "0" to buffer */
- return 1;
- }
-
- b = d2b(d, be, bbits);
- if ((i = (word0(d) >>> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
- d2 = setWord0(d, (word0(d) & Frac_mask1) | Exp_11);
- /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
- * log10(x) = log(x) / log(10)
- * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
- * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
- *
- * This suggests computing an approximation k to log10(d) by
- *
- * k = (i - Bias)*0.301029995663981
- * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
- *
- * We want k to be too large rather than too small.
- * The error in the first-order Taylor series approximation
- * is in our favor, so we just round up the constant enough
- * to compensate for any error in the multiplication of
- * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
- * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
- * adding 1e-13 to the constant term more than suffices.
- * Hence we adjust the constant term to 0.1760912590558.
- * (We could get a more accurate k by invoking log10,
- * but this is probably not worthwhile.)
- */
- i -= Bias;
- denorm = false;
- }
- else {
- /* d is denormalized */
- i = bbits[0] + be[0] + (Bias + (P-1) - 1);
- x = (i > 32) ? word0(d) << (64 - i) | word1(d) >>> (i - 32) : word1(d) << (32 - i);
-// d2 = x;
-// word0(d2) -= 31*Exp_msk1; /* adjust exponent */
- d2 = setWord0(x, word0(x) - 31*Exp_msk1);
- i -= (Bias + (P-1) - 1) + 1;
- denorm = true;
- }
- /* At this point d = f*2^i, where 1 <= f < 2. d2 is an approximation of f. */
- ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
- k = (int)ds;
- if (ds < 0.0 && ds != k)
- k--; /* want k = floor(ds) */
- k_check = true;
- if (k >= 0 && k <= Ten_pmax) {
- if (d < tens[k])
- k--;
- k_check = false;
- }
- /* At this point floor(log10(d)) <= k <= floor(log10(d))+1.
- If k_check is zero, we're guaranteed that k = floor(log10(d)). */
- j = bbits[0] - i - 1;
- /* At this point d = b/2^j, where b is an odd integer. */
- if (j >= 0) {
- b2 = 0;
- s2 = j;
- }
- else {
- b2 = -j;
- s2 = 0;
- }
- if (k >= 0) {
- b5 = 0;
- s5 = k;
- s2 += k;
- }
- else {
- b2 -= k;
- b5 = -k;
- s5 = 0;
- }
- /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer,
- b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */
- if (mode < 0 || mode > 9)
- mode = 0;
- try_quick = true;
- if (mode > 5) {
- mode -= 4;
- try_quick = false;
- }
- leftright = true;
- ilim = ilim1 = 0;
- switch(mode) {
- case 0:
- case 1:
- ilim = ilim1 = -1;
- i = 18;
- ndigits = 0;
- break;
- case 2:
- leftright = false;
- /* no break */
- case 4:
- if (ndigits <= 0)
- ndigits = 1;
- ilim = ilim1 = i = ndigits;
- break;
- case 3:
- leftright = false;
- /* no break */
- case 5:
- i = ndigits + k + 1;
- ilim = i;
- ilim1 = i - 1;
- if (i <= 0)
- i = 1;
- }
- /* ilim is the maximum number of significant digits we want, based on k and ndigits. */
- /* ilim1 is the maximum number of significant digits we want, based on k and ndigits,
- when it turns out that k was computed too high by one. */
-
- boolean fast_failed = false;
- if (ilim >= 0 && ilim <= Quick_max && try_quick) {
-
- /* Try to get by with floating-point arithmetic. */
-
- i = 0;
- d2 = d;
- k0 = k;
- ilim0 = ilim;
- ieps = 2; /* conservative */
- /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */
- if (k > 0) {
- ds = tens[k&0xf];
- j = k >> 4;
- if ((j & Bletch) != 0) {
- /* prevent overflows */
- j &= Bletch - 1;
- d /= bigtens[n_bigtens-1];
- ieps++;
- }
- for(; (j != 0); j >>= 1, i++)
- if ((j & 1) != 0) {
- ieps++;
- ds *= bigtens[i];
- }
- d /= ds;
- }
- else if ((j1 = -k) != 0) {
- d *= tens[j1 & 0xf];
- for(j = j1 >> 4; (j != 0); j >>= 1, i++)
- if ((j & 1) != 0) {
- ieps++;
- d *= bigtens[i];
- }
- }
- /* Check that k was computed correctly. */
- if (k_check && d < 1.0 && ilim > 0) {
- if (ilim1 <= 0)
- fast_failed = true;
- else {
- ilim = ilim1;
- k--;
- d *= 10.;
- ieps++;
- }
- }
- /* eps bounds the cumulative error. */
-// eps = ieps*d + 7.0;
-// word0(eps) -= (P-1)*Exp_msk1;
- eps = ieps*d + 7.0;
- eps = setWord0(eps, word0(eps) - (P-1)*Exp_msk1);
- if (ilim == 0) {
- S = mhi = null;
- d -= 5.0;
- if (d > eps) {
- buf.append('1');
- k++;
- return k + 1;
- }
- if (d < -eps) {
- buf.setLength(0);
- buf.append('0'); /* copy "0" to buffer */
- return 1;
- }
- fast_failed = true;
- }
- if (!fast_failed) {
- fast_failed = true;
- if (leftright) {
- /* Use Steele & White method of only
- * generating digits needed.
- */
- eps = 0.5/tens[ilim-1] - eps;
- for(i = 0;;) {
- L = (long)d;
- d -= L;
- buf.append((char)('0' + L));
- if (d < eps) {
- return k + 1;
- }
- if (1.0 - d < eps) {
-// goto bump_up;
- char lastCh;
- while (true) {
- lastCh = buf.charAt(buf.length() - 1);
- buf.setLength(buf.length() - 1);
- if (lastCh != '9') break;
- if (buf.length() == 0) {
- k++;
- lastCh = '0';
- break;
- }
- }
- buf.append((char)(lastCh + 1));
- return k + 1;
- }
- if (++i >= ilim)
- break;
- eps *= 10.0;
- d *= 10.0;
- }
- }
- else {
- /* Generate ilim digits, then fix them up. */
- eps *= tens[ilim-1];
- for(i = 1;; i++, d *= 10.0) {
- L = (long)d;
- d -= L;
- buf.append((char)('0' + L));
- if (i == ilim) {
- if (d > 0.5 + eps) {
-// goto bump_up;
- char lastCh;
- while (true) {
- lastCh = buf.charAt(buf.length() - 1);
- buf.setLength(buf.length() - 1);
- if (lastCh != '9') break;
- if (buf.length() == 0) {
- k++;
- lastCh = '0';
- break;
- }
- }
- buf.append((char)(lastCh + 1));
- return k + 1;
- }
- else
- if (d < 0.5 - eps) {
- stripTrailingZeroes(buf);
-// while(*--s == '0') ;
-// s++;
- return k + 1;
- }
- break;
- }
- }
- }
- }
- if (fast_failed) {
- buf.setLength(0);
- d = d2;
- k = k0;
- ilim = ilim0;
- }
- }
-
- /* Do we have a "small" integer? */
-
- if (be[0] >= 0 && k <= Int_max) {
- /* Yes. */
- ds = tens[k];
- if (ndigits < 0 && ilim <= 0) {
- S = mhi = null;
- if (ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds)) {
- buf.setLength(0);
- buf.append('0'); /* copy "0" to buffer */
- return 1;
- }
- buf.append('1');
- k++;
- return k + 1;
- }
- for(i = 1;; i++) {
- L = (long) (d / ds);
- d -= L*ds;
- buf.append((char)('0' + L));
- if (i == ilim) {
- d += d;
- if ((d > ds) || (d == ds && (((L & 1) != 0) || biasUp))) {
-// bump_up:
-// while(*--s == '9')
-// if (s == buf) {
-// k++;
-// *s = '0';
-// break;
-// }
-// ++*s++;
- char lastCh;
- while (true) {
- lastCh = buf.charAt(buf.length() - 1);
- buf.setLength(buf.length() - 1);
- if (lastCh != '9') break;
- if (buf.length() == 0) {
- k++;
- lastCh = '0';
- break;
- }
- }
- buf.append((char)(lastCh + 1));
- }
- break;
- }
- d *= 10.0;
- if (d == 0)
- break;
- }
- return k + 1;
- }
-
- m2 = b2;
- m5 = b5;
- mhi = mlo = null;
- if (leftright) {
- if (mode < 2) {
- i = (denorm) ? be[0] + (Bias + (P-1) - 1 + 1) : 1 + P - bbits[0];
- /* i is 1 plus the number of trailing zero bits in d's significand. Thus,
- (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */
- }
- else {
- j = ilim - 1;
- if (m5 >= j)
- m5 -= j;
- else {
- s5 += j -= m5;
- b5 += j;
- m5 = 0;
- }
- if ((i = ilim) < 0) {
- m2 -= i;
- i = 0;
- }
- /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */
- }
- b2 += i;
- s2 += i;
- mhi = BigInteger.valueOf(1);
- /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or
- input (when mode < 2) significant digit, divided by 10^k. */
- }
- /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5). Reduce common factors in
- b2, m2, and s2 without changing the equalities. */
- if (m2 > 0 && s2 > 0) {
- i = (m2 < s2) ? m2 : s2;
- b2 -= i;
- m2 -= i;
- s2 -= i;
- }
-
- /* Fold b5 into b and m5 into mhi. */
- if (b5 > 0) {
- if (leftright) {
- if (m5 > 0) {
- mhi = pow5mult(mhi, m5);
- b1 = mhi.multiply(b);
- b = b1;
- }
- if ((j = b5 - m5) != 0)
- b = pow5mult(b, j);
- }
- else
- b = pow5mult(b, b5);
- }
- /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and
- (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */
-
- S = BigInteger.valueOf(1);
- if (s5 > 0)
- S = pow5mult(S, s5);
- /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and
- (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */
-
- /* Check for special case that d is a normalized power of 2. */
- spec_case = false;
- if (mode < 2) {
- if ( (word1(d) == 0) && ((word0(d) & Bndry_mask) == 0)
- && ((word0(d) & (Exp_mask & Exp_mask << 1)) != 0)
- ) {
- /* The special case. Here we want to be within a quarter of the last input
- significant digit instead of one half of it when the decimal output string's value is less than d. */
- b2 += Log2P;
- s2 += Log2P;
- spec_case = true;
- }
- }
-
- /* Arrange for convenient computation of quotients:
- * shift left if necessary so divisor has 4 leading 0 bits.
- *
- * Perhaps we should just compute leading 28 bits of S once
- * and for all and pass them and a shift to quorem, so it
- * can do shifts and ors to compute the numerator for q.
- */
- byte [] S_bytes = S.toByteArray();
- int S_hiWord = 0;
- for (int idx = 0; idx < 4; idx++) {
- S_hiWord = (S_hiWord << 8);
- if (idx < S_bytes.length)
- S_hiWord |= (S_bytes[idx] & 0xFF);
- }
- if ((i = (((s5 != 0) ? 32 - hi0bits(S_hiWord) : 1) + s2) & 0x1f) != 0)
- i = 32 - i;
- /* i is the number of leading zero bits in the most significant word of S*2^s2. */
- if (i > 4) {
- i -= 4;
- b2 += i;
- m2 += i;
- s2 += i;
- }
- else if (i < 4) {
- i += 28;
- b2 += i;
- m2 += i;
- s2 += i;
- }
- /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */
- if (b2 > 0)
- b = b.shiftLeft(b2);
- if (s2 > 0)
- S = S.shiftLeft(s2);
- /* Now we have d/10^k = b/S and
- (mhi * 2^m2) / S = maximum acceptable error, divided by 10^k. */
- if (k_check) {
- if (b.compareTo(S) < 0) {
- k--;
- b = b.multiply(BigInteger.valueOf(10)); /* we botched the k estimate */
- if (leftright)
- mhi = mhi.multiply(BigInteger.valueOf(10));
- ilim = ilim1;
- }
- }
- /* At this point 1 <= d/10^k = b/S < 10. */
-
- if (ilim <= 0 && mode > 2) {
- /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode.
- Output either zero or the minimum nonzero output depending on which is closer to d. */
- if ((ilim < 0 )
- || ((i = b.compareTo(S = S.multiply(BigInteger.valueOf(5)))) < 0)
- || ((i == 0 && !biasUp))) {
- /* Always emit at least one digit. If the number appears to be zero
- using the current mode, then emit one '0' digit and set decpt to 1. */
- /*no_digits:
- k = -1 - ndigits;
- goto ret; */
- buf.setLength(0);
- buf.append('0'); /* copy "0" to buffer */
- return 1;
-// goto no_digits;
- }
-// one_digit:
- buf.append('1');
- k++;
- return k + 1;
- }
- if (leftright) {
- if (m2 > 0)
- mhi = mhi.shiftLeft(m2);
-
- /* Compute mlo -- check for special case
- * that d is a normalized power of 2.
- */
-
- mlo = mhi;
- if (spec_case) {
- mhi = mlo;
- mhi = mhi.shiftLeft(Log2P);
- }
- /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */
- /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */
-
- for(i = 1;;i++) {
- BigInteger[] divResult = b.divideAndRemainder(S);
- b = divResult[1];
- dig = (char)(divResult[0].intValue() + '0');
- /* Do we yet have the shortest decimal string
- * that will round to d?
- */
- j = b.compareTo(mlo);
- /* j is b/S compared with mlo/S. */
- delta = S.subtract(mhi);
- j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta);
- /* j1 is b/S compared with 1 - mhi/S. */
- if ((j1 == 0) && (mode == 0) && ((word1(d) & 1) == 0)) {
- if (dig == '9') {
- buf.append('9');
- if (roundOff(buf)) {
- k++;
- buf.append('1');
- }
- return k + 1;
-// goto round_9_up;
- }
- if (j > 0)
- dig++;
- buf.append(dig);
- return k + 1;
- }
- if ((j < 0)
- || ((j == 0)
- && (mode == 0)
- && ((word1(d) & 1) == 0)
- )) {
- if (j1 > 0) {
- /* Either dig or dig+1 would work here as the least significant decimal digit.
- Use whichever would produce a decimal value closer to d. */
- b = b.shiftLeft(1);
- j1 = b.compareTo(S);
- if (((j1 > 0) || (j1 == 0 && (((dig & 1) == 1) || biasUp)))
- && (dig++ == '9')) {
- buf.append('9');
- if (roundOff(buf)) {
- k++;
- buf.append('1');
- }
- return k + 1;
-// goto round_9_up;
- }
- }
- buf.append(dig);
- return k + 1;
- }
- if (j1 > 0) {
- if (dig == '9') { /* possible if i == 1 */
-// round_9_up:
-// *s++ = '9';
-// goto roundoff;
- buf.append('9');
- if (roundOff(buf)) {
- k++;
- buf.append('1');
- }
- return k + 1;
- }
- buf.append((char)(dig + 1));
- return k + 1;
- }
- buf.append(dig);
- if (i == ilim)
- break;
- b = b.multiply(BigInteger.valueOf(10));
- if (mlo == mhi)
- mlo = mhi = mhi.multiply(BigInteger.valueOf(10));
- else {
- mlo = mlo.multiply(BigInteger.valueOf(10));
- mhi = mhi.multiply(BigInteger.valueOf(10));
- }
- }
- }
- else
- for(i = 1;; i++) {
-// (char)(dig = quorem(b,S) + '0');
- BigInteger[] divResult = b.divideAndRemainder(S);
- b = divResult[1];
- dig = (char)(divResult[0].intValue() + '0');
- buf.append(dig);
- if (i >= ilim)
- break;
- b = b.multiply(BigInteger.valueOf(10));
- }
-
- /* Round off last digit */
-
- b = b.shiftLeft(1);
- j = b.compareTo(S);
- if ((j > 0) || (j == 0 && (((dig & 1) == 1) || biasUp))) {
-// roundoff:
-// while(*--s == '9')
-// if (s == buf) {
-// k++;
-// *s++ = '1';
-// goto ret;
-// }
-// ++*s++;
- if (roundOff(buf)) {
- k++;
- buf.append('1');
- return k + 1;
- }
- }
- else {
- stripTrailingZeroes(buf);
-// while(*--s == '0') ;
-// s++;
- }
-// ret:
-// Bfree(S);
-// if (mhi) {
-// if (mlo && mlo != mhi)
-// Bfree(mlo);
-// Bfree(mhi);
-// }
-// ret1:
-// Bfree(b);
-// JS_ASSERT(s < buf + bufsize);
- return k + 1;
- }
-
- private static void
- stripTrailingZeroes(StringBuffer buf)
- {
-// while(*--s == '0') ;
-// s++;
- int bl = buf.length();
- while(bl-->0 && buf.charAt(bl) == '0') {
- // empty
- }
- buf.setLength(bl + 1);
- }
-
- /* Mapping of JSDToStrMode -> JS_dtoa mode */
- private static final int dtoaModes[] = {
- 0, /* DTOSTR_STANDARD */
- 0, /* DTOSTR_STANDARD_EXPONENTIAL, */
- 3, /* DTOSTR_FIXED, */
- 2, /* DTOSTR_EXPONENTIAL, */
- 2}; /* DTOSTR_PRECISION */
-
- static void
- JS_dtostr(StringBuffer buffer, int mode, int precision, double d)
- {
- int decPt; /* Position of decimal point relative to first digit returned by JS_dtoa */
- boolean[] sign = new boolean[1]; /* true if the sign bit was set in d */
- int nDigits; /* Number of significand digits returned by JS_dtoa */
-
-// JS_ASSERT(bufferSize >= (size_t)(mode <= DTOSTR_STANDARD_EXPONENTIAL ? DTOSTR_STANDARD_BUFFER_SIZE :
-// DTOSTR_VARIABLE_BUFFER_SIZE(precision)));
-
- if (mode == DTOSTR_FIXED && (d >= 1e21 || d <= -1e21))
- mode = DTOSTR_STANDARD; /* Change mode here rather than below because the buffer may not be large enough to hold a large integer. */
-
- decPt = JS_dtoa(d, dtoaModes[mode], mode >= DTOSTR_FIXED, precision, sign, buffer);
- nDigits = buffer.length();
-
- /* If Infinity, -Infinity, or NaN, return the string regardless of the mode. */
- if (decPt != 9999) {
- boolean exponentialNotation = false;
- int minNDigits = 0; /* Minimum number of significand digits required by mode and precision */
- int p;
-
- switch (mode) {
- case DTOSTR_STANDARD:
- if (decPt < -5 || decPt > 21)
- exponentialNotation = true;
- else
- minNDigits = decPt;
- break;
-
- case DTOSTR_FIXED:
- if (precision >= 0)
- minNDigits = decPt + precision;
- else
- minNDigits = decPt;
- break;
-
- case DTOSTR_EXPONENTIAL:
-// JS_ASSERT(precision > 0);
- minNDigits = precision;
- /* Fall through */
- case DTOSTR_STANDARD_EXPONENTIAL:
- exponentialNotation = true;
- break;
-
- case DTOSTR_PRECISION:
-// JS_ASSERT(precision > 0);
- minNDigits = precision;
- if (decPt < -5 || decPt > precision)
- exponentialNotation = true;
- break;
- }
-
- /* If the number has fewer than minNDigits, pad it with zeros at the end */
- if (nDigits < minNDigits) {
- p = minNDigits;
- nDigits = minNDigits;
- do {
- buffer.append('0');
- } while (buffer.length() != p);
- }
-
- if (exponentialNotation) {
- /* Insert a decimal point if more than one significand digit */
- if (nDigits != 1) {
- buffer.insert(1, '.');
- }
- buffer.append('e');
- if ((decPt - 1) >= 0)
- buffer.append('+');
- buffer.append(decPt - 1);
-// JS_snprintf(numEnd, bufferSize - (numEnd - buffer), "e%+d", decPt-1);
- } else if (decPt != nDigits) {
- /* Some kind of a fraction in fixed notation */
-// JS_ASSERT(decPt <= nDigits);
- if (decPt > 0) {
- /* dd...dd . dd...dd */
- buffer.insert(decPt, '.');
- } else {
- /* 0 . 00...00dd...dd */
- for (int i = 0; i < 1 - decPt; i++)
- buffer.insert(0, '0');
- buffer.insert(1, '.');
- }
- }
- }
-
- /* If negative and neither -0.0 nor NaN, output a leading '-'. */
- if (sign[0] &&
- !(word0(d) == Sign_bit && word1(d) == 0) &&
- !((word0(d) & Exp_mask) == Exp_mask &&
- ((word1(d) != 0) || ((word0(d) & Frac_mask) != 0)))) {
- buffer.insert(0, '-');
- }
- }
-
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Decompiler.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Decompiler.java
deleted file mode 100644
index 8547d37..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Decompiler.java
+++ /dev/null
@@ -1,918 +0,0 @@
-/* -*- 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):
- * Mike Ang
- * Igor Bukanov
- * Bob Jervis
- * Mike McCabe
- *
- * 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;
-
-/**
- * The following class save decompilation information about the source.
- * Source information is returned from the parser as a String
- * associated with function nodes and with the toplevel script. When
- * saved in the constant pool of a class, this string will be UTF-8
- * encoded, and token values will occupy a single byte.
-
- * Source is saved (mostly) as token numbers. The tokens saved pretty
- * much correspond to the token stream of a 'canonical' representation
- * of the input program, as directed by the parser. (There were a few
- * cases where tokens could have been left out where decompiler could
- * easily reconstruct them, but I left them in for clarity). (I also
- * looked adding source collection to TokenStream instead, where I
- * could have limited the changes to a few lines in getToken... but
- * this wouldn't have saved any space in the resulting source
- * representation, and would have meant that I'd have to duplicate
- * parser logic in the decompiler to disambiguate situations where
- * newlines are important.) The function decompile expands the
- * tokens back into their string representations, using simple
- * lookahead to correct spacing and indentation.
- *
- * Assignments are saved as two-token pairs (Token.ASSIGN, op). Number tokens
- * are stored inline, as a NUMBER token, a character representing the type, and
- * either 1 or 4 characters representing the bit-encoding of the number. String
- * types NAME, STRING and OBJECT are currently stored as a token type,
- * followed by a character giving the length of the string (assumed to
- * be less than 2^16), followed by the characters of the string
- * inlined into the source string. Changing this to some reference to
- * to the string in the compiled class' constant pool would probably
- * save a lot of space... but would require some method of deriving
- * the final constant pool entry from information available at parse
- * time.
- */
-public class Decompiler
-{
- /**
- * Flag to indicate that the decompilation should omit the
- * function header and trailing brace.
- */
- public static final int ONLY_BODY_FLAG = 1 << 0;
-
- /**
- * Flag to indicate that the decompilation generates toSource result.
- */
- public static final int TO_SOURCE_FLAG = 1 << 1;
-
- /**
- * Decompilation property to specify initial ident value.
- */
- public static final int INITIAL_INDENT_PROP = 1;
-
- /**
- * Decompilation property to specify default identation offset.
- */
- public static final int INDENT_GAP_PROP = 2;
-
- /**
- * Decompilation property to specify identation offset for case labels.
- */
- public static final int CASE_GAP_PROP = 3;
-
- // Marker to denote the last RC of function so it can be distinguished from
- // the last RC of object literals in case of function expressions
- private static final int FUNCTION_END = Token.LAST_TOKEN + 1;
-
- String getEncodedSource()
- {
- return sourceToString(0);
- }
-
- int getCurrentOffset()
- {
- return sourceTop;
- }
-
- int markFunctionStart(int functionType)
- {
- int savedOffset = getCurrentOffset();
- addToken(Token.FUNCTION);
- append((char)functionType);
- return savedOffset;
- }
-
- int markFunctionEnd(int functionStart)
- {
- int offset = getCurrentOffset();
- append((char)FUNCTION_END);
- return offset;
- }
-
- void addToken(int token)
- {
- if (!(0 <= token && token <= Token.LAST_TOKEN))
- throw new IllegalArgumentException();
-
- append((char)token);
- }
-
- void addEOL(int token)
- {
- if (!(0 <= token && token <= Token.LAST_TOKEN))
- throw new IllegalArgumentException();
-
- append((char)token);
- append((char)Token.EOL);
- }
-
- void addName(String str)
- {
- addToken(Token.NAME);
- appendString(str);
- }
-
- void addString(String str)
- {
- addToken(Token.STRING);
- appendString(str);
- }
-
- void addRegexp(String regexp, String flags)
- {
- addToken(Token.REGEXP);
- appendString('/' + regexp + '/' + flags);
- }
-
- void addNumber(double n)
- {
- addToken(Token.NUMBER);
-
- /* encode the number in the source stream.
- * Save as NUMBER type (char | char char char char)
- * where type is
- * 'D' - double, 'S' - short, 'J' - long.
-
- * We need to retain float vs. integer type info to keep the
- * behavior of liveconnect type-guessing the same after
- * decompilation. (Liveconnect tries to present 1.0 to Java
- * as a float/double)
- * OPT: This is no longer true. We could compress the format.
-
- * This may not be the most space-efficient encoding;
- * the chars created below may take up to 3 bytes in
- * constant pool UTF-8 encoding, so a Double could take
- * up to 12 bytes.
- */
-
- long lbits = (long)n;
- if (lbits != n) {
- // if it's floating point, save as a Double bit pattern.
- // (12/15/97 our scanner only returns Double for f.p.)
- lbits = Double.doubleToLongBits(n);
- append('D');
- append((char)(lbits >> 48));
- append((char)(lbits >> 32));
- append((char)(lbits >> 16));
- append((char)lbits);
- }
- else {
- // we can ignore negative values, bc they're already prefixed
- // by NEG
- if (lbits < 0) Kit.codeBug();
-
- // will it fit in a char?
- // this gives a short encoding for integer values up to 2^16.
- if (lbits <= Character.MAX_VALUE) {
- append('S');
- append((char)lbits);
- }
- else { // Integral, but won't fit in a char. Store as a long.
- append('J');
- append((char)(lbits >> 48));
- append((char)(lbits >> 32));
- append((char)(lbits >> 16));
- append((char)lbits);
- }
- }
- }
-
- private void appendString(String str)
- {
- int L = str.length();
- int lengthEncodingSize = 1;
- if (L >= 0x8000) {
- lengthEncodingSize = 2;
- }
- int nextTop = sourceTop + lengthEncodingSize + L;
- if (nextTop > sourceBuffer.length) {
- increaseSourceCapacity(nextTop);
- }
- if (L >= 0x8000) {
- // Use 2 chars to encode strings exceeding 32K, were the highest
- // bit in the first char indicates presence of the next byte
- sourceBuffer[sourceTop] = (char)(0x8000 | (L >>> 16));
- ++sourceTop;
- }
- sourceBuffer[sourceTop] = (char)L;
- ++sourceTop;
- str.getChars(0, L, sourceBuffer, sourceTop);
- sourceTop = nextTop;
- }
-
- private void append(char c)
- {
- if (sourceTop == sourceBuffer.length) {
- increaseSourceCapacity(sourceTop + 1);
- }
- sourceBuffer[sourceTop] = c;
- ++sourceTop;
- }
-
- private void increaseSourceCapacity(int minimalCapacity)
- {
- // Call this only when capacity increase is must
- if (minimalCapacity <= sourceBuffer.length) Kit.codeBug();
- int newCapacity = sourceBuffer.length * 2;
- if (newCapacity < minimalCapacity) {
- newCapacity = minimalCapacity;
- }
- char[] tmp = new char[newCapacity];
- System.arraycopy(sourceBuffer, 0, tmp, 0, sourceTop);
- sourceBuffer = tmp;
- }
-
- private String sourceToString(int offset)
- {
- if (offset < 0 || sourceTop < offset) Kit.codeBug();
- return new String(sourceBuffer, offset, sourceTop - offset);
- }
-
- /**
- * Decompile the source information associated with this js
- * function/script back into a string. For the most part, this
- * just means translating tokens back to their string
- * representations; there's a little bit of lookahead logic to
- * decide the proper spacing/indentation. Most of the work in
- * mapping the original source to the prettyprinted decompiled
- * version is done by the parser.
- *
- * @param source encoded source tree presentation
- *
- * @param flags flags to select output format
- *
- * @param properties indentation properties
- *
- */
- public static String decompile(String source, int flags,
- UintMap properties)
- {
- int length = source.length();
- if (length == 0) { return ""; }
-
- int indent = properties.getInt(INITIAL_INDENT_PROP, 0);
- if (indent < 0) throw new IllegalArgumentException();
- int indentGap = properties.getInt(INDENT_GAP_PROP, 4);
- if (indentGap < 0) throw new IllegalArgumentException();
- int caseGap = properties.getInt(CASE_GAP_PROP, 2);
- if (caseGap < 0) throw new IllegalArgumentException();
-
- StringBuffer result = new StringBuffer();
- boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
- boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG));
-
- // Spew tokens in source, for debugging.
- // as TYPE number char
- if (printSource) {
- System.err.println("length:" + length);
- for (int i = 0; i < length; ++i) {
- // Note that tokenToName will fail unless Context.printTrees
- // is true.
- String tokenname = null;
- if (Token.printNames) {
- tokenname = Token.name(source.charAt(i));
- }
- if (tokenname == null) {
- tokenname = "---";
- }
- String pad = tokenname.length() > 7
- ? "\t"
- : "\t\t";
- System.err.println
- (tokenname
- + pad + (int)source.charAt(i)
- + "\t'" + ScriptRuntime.escapeString
- (source.substring(i, i+1))
- + "'");
- }
- System.err.println();
- }
-
- int braceNesting = 0;
- boolean afterFirstEOL = false;
- int i = 0;
- int topFunctionType;
- if (source.charAt(i) == Token.SCRIPT) {
- ++i;
- topFunctionType = -1;
- } else {
- topFunctionType = source.charAt(i + 1);
- }
-
- if (!toSource) {
- // add an initial newline to exactly match js.
- result.append('\n');
- for (int j = 0; j < indent; j++)
- result.append(' ');
- } else {
- if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
- result.append('(');
- }
- }
-
- while (i < length) {
- switch(source.charAt(i)) {
- case Token.GET:
- case Token.SET:
- result.append(source.charAt(i) == Token.GET ? "get " : "set ");
- ++i;
- i = printSourceString(source, i + 1, false, result);
- // Now increment one more to get past the FUNCTION token
- ++i;
- break;
-
- case Token.NAME:
- case Token.REGEXP: // re-wrapped in '/'s in parser...
- i = printSourceString(source, i + 1, false, result);
- continue;
-
- case Token.STRING:
- i = printSourceString(source, i + 1, true, result);
- continue;
-
- case Token.NUMBER:
- i = printSourceNumber(source, i + 1, result);
- continue;
-
- case Token.TRUE:
- result.append("true");
- break;
-
- case Token.FALSE:
- result.append("false");
- break;
-
- case Token.NULL:
- result.append("null");
- break;
-
- case Token.THIS:
- result.append("this");
- break;
-
- case Token.FUNCTION:
- ++i; // skip function type
- result.append("function ");
- break;
-
- case FUNCTION_END:
- // Do nothing
- break;
-
- case Token.COMMA:
- result.append(", ");
- break;
-
- case Token.LC:
- ++braceNesting;
- if (Token.EOL == getNext(source, length, i))
- indent += indentGap;
- result.append('{');
- break;
-
- case Token.RC: {
- --braceNesting;
- /* don't print the closing RC if it closes the
- * toplevel function and we're called from
- * decompileFunctionBody.
- */
- if (justFunctionBody && braceNesting == 0)
- break;
-
- result.append('}');
- switch (getNext(source, length, i)) {
- case Token.EOL:
- case FUNCTION_END:
- indent -= indentGap;
- break;
- case Token.WHILE:
- case Token.ELSE:
- indent -= indentGap;
- result.append(' ');
- break;
- }
- break;
- }
- case Token.LP:
- result.append('(');
- break;
-
- case Token.RP:
- result.append(')');
- if (Token.LC == getNext(source, length, i))
- result.append(' ');
- break;
-
- case Token.LB:
- result.append('[');
- break;
-
- case Token.RB:
- result.append(']');
- break;
-
- case Token.EOL: {
- if (toSource) break;
- boolean newLine = true;
- if (!afterFirstEOL) {
- afterFirstEOL = true;
- if (justFunctionBody) {
- /* throw away just added 'function name(...) {'
- * and restore the original indent
- */
- result.setLength(0);
- indent -= indentGap;
- newLine = false;
- }
- }
- if (newLine) {
- result.append('\n');
- }
-
- /* add indent if any tokens remain,
- * less setback if next token is
- * a label, case or default.
- */
- if (i + 1 < length) {
- int less = 0;
- int nextToken = source.charAt(i + 1);
- if (nextToken == Token.CASE
- || nextToken == Token.DEFAULT)
- {
- less = indentGap - caseGap;
- } else if (nextToken == Token.RC) {
- less = indentGap;
- }
-
- /* elaborate check against label... skip past a
- * following inlined NAME and look for a COLON.
- */
- else if (nextToken == Token.NAME) {
- int afterName = getSourceStringEnd(source, i + 2);
- if (source.charAt(afterName) == Token.COLON)
- less = indentGap;
- }
-
- for (; less < indent; less++)
- result.append(' ');
- }
- break;
- }
- case Token.DOT:
- result.append('.');
- break;
-
- case Token.NEW:
- result.append("new ");
- break;
-
- case Token.DELPROP:
- result.append("delete ");
- break;
-
- case Token.IF:
- result.append("if ");
- break;
-
- case Token.ELSE:
- result.append("else ");
- break;
-
- case Token.FOR:
- result.append("for ");
- break;
-
- case Token.IN:
- result.append(" in ");
- break;
-
- case Token.WITH:
- result.append("with ");
- break;
-
- case Token.WHILE:
- result.append("while ");
- break;
-
- case Token.DO:
- result.append("do ");
- break;
-
- case Token.TRY:
- result.append("try ");
- break;
-
- case Token.CATCH:
- result.append("catch ");
- break;
-
- case Token.FINALLY:
- result.append("finally ");
- break;
-
- case Token.THROW:
- result.append("throw ");
- break;
-
- case Token.SWITCH:
- result.append("switch ");
- break;
-
- case Token.BREAK:
- result.append("break");
- if (Token.NAME == getNext(source, length, i))
- result.append(' ');
- break;
-
- case Token.CONTINUE:
- result.append("continue");
- if (Token.NAME == getNext(source, length, i))
- result.append(' ');
- break;
-
- case Token.CASE:
- result.append("case ");
- break;
-
- case Token.DEFAULT:
- result.append("default");
- break;
-
- case Token.RETURN:
- result.append("return");
- if (Token.SEMI != getNext(source, length, i))
- result.append(' ');
- break;
-
- case Token.VAR:
- result.append("var ");
- break;
-
- case Token.LET:
- result.append("let ");
- break;
-
- case Token.SEMI:
- result.append(';');
- if (Token.EOL != getNext(source, length, i)) {
- // separators in FOR
- result.append(' ');
- }
- break;
-
- case Token.ASSIGN:
- result.append(" = ");
- break;
-
- case Token.ASSIGN_ADD:
- result.append(" += ");
- break;
-
- case Token.ASSIGN_SUB:
- result.append(" -= ");
- break;
-
- case Token.ASSIGN_MUL:
- result.append(" *= ");
- break;
-
- case Token.ASSIGN_DIV:
- result.append(" /= ");
- break;
-
- case Token.ASSIGN_MOD:
- result.append(" %= ");
- break;
-
- case Token.ASSIGN_BITOR:
- result.append(" |= ");
- break;
-
- case Token.ASSIGN_BITXOR:
- result.append(" ^= ");
- break;
-
- case Token.ASSIGN_BITAND:
- result.append(" &= ");
- break;
-
- case Token.ASSIGN_LSH:
- result.append(" <<= ");
- break;
-
- case Token.ASSIGN_RSH:
- result.append(" >>= ");
- break;
-
- case Token.ASSIGN_URSH:
- result.append(" >>>= ");
- break;
-
- case Token.HOOK:
- result.append(" ? ");
- break;
-
- case Token.OBJECTLIT:
- // pun OBJECTLIT to mean colon in objlit property
- // initialization.
- // This needs to be distinct from COLON in the general case
- // to distinguish from the colon in a ternary... which needs
- // different spacing.
- result.append(':');
- break;
-
- case Token.COLON:
- if (Token.EOL == getNext(source, length, i))
- // it's the end of a label
- result.append(':');
- else
- // it's the middle part of a ternary
- result.append(" : ");
- break;
-
- case Token.OR:
- result.append(" || ");
- break;
-
- case Token.AND:
- result.append(" && ");
- break;
-
- case Token.BITOR:
- result.append(" | ");
- break;
-
- case Token.BITXOR:
- result.append(" ^ ");
- break;
-
- case Token.BITAND:
- result.append(" & ");
- break;
-
- case Token.SHEQ:
- result.append(" === ");
- break;
-
- case Token.SHNE:
- result.append(" !== ");
- break;
-
- case Token.EQ:
- result.append(" == ");
- break;
-
- case Token.NE:
- result.append(" != ");
- break;
-
- case Token.LE:
- result.append(" <= ");
- break;
-
- case Token.LT:
- result.append(" < ");
- break;
-
- case Token.GE:
- result.append(" >= ");
- break;
-
- case Token.GT:
- result.append(" > ");
- break;
-
- case Token.INSTANCEOF:
- result.append(" instanceof ");
- break;
-
- case Token.LSH:
- result.append(" << ");
- break;
-
- case Token.RSH:
- result.append(" >> ");
- break;
-
- case Token.URSH:
- result.append(" >>> ");
- break;
-
- case Token.TYPEOF:
- result.append("typeof ");
- break;
-
- case Token.VOID:
- result.append("void ");
- break;
-
- case Token.CONST:
- result.append("const ");
- break;
-
- case Token.YIELD:
- result.append("yield ");
- break;
-
- case Token.NOT:
- result.append('!');
- break;
-
- case Token.BITNOT:
- result.append('~');
- break;
-
- case Token.POS:
- result.append('+');
- break;
-
- case Token.NEG:
- result.append('-');
- break;
-
- case Token.INC:
- result.append("++");
- break;
-
- case Token.DEC:
- result.append("--");
- break;
-
- case Token.ADD:
- result.append(" + ");
- break;
-
- case Token.SUB:
- result.append(" - ");
- break;
-
- case Token.MUL:
- result.append(" * ");
- break;
-
- case Token.DIV:
- result.append(" / ");
- break;
-
- case Token.MOD:
- result.append(" % ");
- break;
-
- case Token.COLONCOLON:
- result.append("::");
- break;
-
- case Token.DOTDOT:
- result.append("..");
- break;
-
- case Token.DOTQUERY:
- result.append(".(");
- break;
-
- case Token.XMLATTR:
- result.append('@');
- break;
-
- default:
- // If we don't know how to decompile it, raise an exception.
- throw new RuntimeException("Token: " +
- Token.name(source.charAt(i)));
- }
- ++i;
- }
-
- if (!toSource) {
- // add that trailing newline if it's an outermost function.
- if (!justFunctionBody)
- result.append('\n');
- } else {
- if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
- result.append(')');
- }
- }
-
- return result.toString();
- }
-
- private static int getNext(String source, int length, int i)
- {
- return (i + 1 < length) ? source.charAt(i + 1) : Token.EOF;
- }
-
- private static int getSourceStringEnd(String source, int offset)
- {
- return printSourceString(source, offset, false, null);
- }
-
- private static int printSourceString(String source, int offset,
- boolean asQuotedString,
- StringBuffer sb)
- {
- int length = source.charAt(offset);
- ++offset;
- if ((0x8000 & length) != 0) {
- length = ((0x7FFF & length) << 16) | source.charAt(offset);
- ++offset;
- }
- if (sb != null) {
- String str = source.substring(offset, offset + length);
- if (!asQuotedString) {
- sb.append(str);
- } else {
- sb.append('"');
- sb.append(ScriptRuntime.escapeString(str));
- sb.append('"');
- }
- }
- return offset + length;
- }
-
- private static int printSourceNumber(String source, int offset,
- StringBuffer sb)
- {
- double number = 0.0;
- char type = source.charAt(offset);
- ++offset;
- if (type == 'S') {
- if (sb != null) {
- int ival = source.charAt(offset);
- number = ival;
- }
- ++offset;
- } else if (type == 'J' || type == 'D') {
- if (sb != null) {
- long lbits;
- lbits = (long)source.charAt(offset) << 48;
- lbits |= (long)source.charAt(offset + 1) << 32;
- lbits |= (long)source.charAt(offset + 2) << 16;
- lbits |= source.charAt(offset + 3);
- if (type == 'J') {
- number = lbits;
- } else {
- number = Double.longBitsToDouble(lbits);
- }
- }
- offset += 4;
- } else {
- // Bad source
- throw new RuntimeException();
- }
- if (sb != null) {
- sb.append(ScriptRuntime.numberToString(number, 10));
- }
- return offset;
- }
-
- private char[] sourceBuffer = new char[128];
-
-// Per script/function source buffer top: parent source does not include a
-// nested functions source and uses function index as a reference instead.
- private int sourceTop;
-
-// whether to do a debug print of the source information, when decompiling.
- private static final boolean printSource = false;
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefaultErrorReporter.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefaultErrorReporter.java
deleted file mode 100644
index c7d93d4..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefaultErrorReporter.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- 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
- *
- * 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 is the default error reporter for JavaScript.
- *
- * @author Norris Boyd
- */
-class DefaultErrorReporter implements ErrorReporter
-{
- static final DefaultErrorReporter instance = new DefaultErrorReporter();
-
- private boolean forEval;
- private ErrorReporter chainedReporter;
-
- private DefaultErrorReporter() { }
-
- static ErrorReporter forEval(ErrorReporter reporter)
- {
- DefaultErrorReporter r = new DefaultErrorReporter();
- r.forEval = true;
- r.chainedReporter = reporter;
- return r;
- }
-
- public void warning(String message, String sourceURI, int line,
- String lineText, int lineOffset)
- {
- if (chainedReporter != null) {
- chainedReporter.warning(
- message, sourceURI, line, lineText, lineOffset);
- } else {
- // Do nothing
- }
- }
-
- public void error(String message, String sourceURI, int line,
- String lineText, int lineOffset)
- {
- if (forEval) {
- // Assume error message strings that start with "TypeError: "
- // should become TypeError exceptions. A bit of a hack, but we
- // don't want to change the ErrorReporter interface.
- String error = "SyntaxError";
- final String TYPE_ERROR_NAME = "TypeError";
- final String DELIMETER = ": ";
- final String prefix = TYPE_ERROR_NAME + DELIMETER;
- if (message.startsWith(prefix)) {
- error = TYPE_ERROR_NAME;
- message = message.substring(prefix.length());
- }
- throw ScriptRuntime.constructError(error, message, sourceURI,
- line, lineText, lineOffset);
- }
- if (chainedReporter != null) {
- chainedReporter.error(
- message, sourceURI, line, lineText, lineOffset);
- } else {
- throw runtimeError(
- message, sourceURI, line, lineText, lineOffset);
- }
- }
-
- public EvaluatorException runtimeError(String message, String sourceURI,
- int line, String lineText,
- int lineOffset)
- {
- if (chainedReporter != null) {
- return chainedReporter.runtimeError(
- message, sourceURI, line, lineText, lineOffset);
- } else {
- return new EvaluatorException(
- message, sourceURI, line, lineText, lineOffset);
- }
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefiningClassLoader.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefiningClassLoader.java
deleted file mode 100644
index 5864b5d..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefiningClassLoader.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/* ***** 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
- * Roger Lawrence
- * Patrick Beard
- * 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;
-
-/**
- * Load generated classes.
- *
- * @author Norris Boyd
- */
-public class DefiningClassLoader extends ClassLoader
- implements GeneratedClassLoader
-{
- public DefiningClassLoader() {
- this.parentLoader = getClass().getClassLoader();
- }
-
- public DefiningClassLoader(ClassLoader parentLoader) {
- this.parentLoader = parentLoader;
- }
-
- public Class defineClass(String name, byte[] data) {
- // Use our own protection domain for the generated classes.
- // TODO: we might want to use a separate protection domain for classes
- // compiled from scripts, based on where the script was loaded from.
- return super.defineClass(name, data, 0, data.length,
- SecurityUtilities.getProtectionDomain(getClass()));
- }
-
- public void linkClass(Class cl) {
- resolveClass(cl);
- }
-
- public Class loadClass(String name, boolean resolve)
- throws ClassNotFoundException
- {
- Class cl = findLoadedClass(name);
- if (cl == null) {
- if (parentLoader != null) {
- cl = parentLoader.loadClass(name);
- } else {
- cl = findSystemClass(name);
- }
- }
- if (resolve) {
- resolveClass(cl);
- }
- return cl;
- }
-
- private final ClassLoader parentLoader;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Delegator.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Delegator.java
deleted file mode 100644
index e044863..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Delegator.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/* -*- 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 Delegator.java, released
- * Sep 27, 2000.
- *
- * The Initial Developer of the Original Code is
- * Matthias Radestock. <matthias@sorted.org>.
- * Portions created by the Initial Developer are Copyright (C) 2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * This is a helper class for implementing wrappers around Scriptable
- * objects. It implements the Function interface and delegates all
- * invocations to a delegee Scriptable object. The normal use of this
- * class involves creating a sub-class and overriding one or more of
- * the methods.
- *
- * A useful application is the implementation of interceptors,
- * pre/post conditions, debugging.
- *
- * @see Function
- * @see Scriptable
- * @author Matthias Radestock
- */
-
-public class Delegator implements Function {
-
- protected Scriptable obj = null;
-
- /**
- * Create a Delegator prototype.
- *
- * This constructor should only be used for creating prototype
- * objects of Delegator.
- *
- * @see org.mozilla.javascript.Delegator#construct
- */
- public Delegator() {
- }
-
- /**
- * Create a new Delegator that forwards requests to a delegee
- * Scriptable object.
- *
- * @param obj the delegee
- * @see org.mozilla.javascript.Scriptable
- */
- public Delegator(Scriptable obj) {
- this.obj = obj;
- }
-
- /**
- * Crete new Delegator instance.
- * The default implementation calls this.getClass().newInstance().
- *
- * @see #construct(Context cx, Scriptable scope, Object[] args)
- */
- protected Delegator newInstance()
- {
- try {
- return this.getClass().newInstance();
- } catch (Exception ex) {
- throw Context.throwAsScriptRuntimeEx(ex);
- }
- }
-
- /**
- * Retrieve the delegee.
- *
- * @return the delegee
- */
- public Scriptable getDelegee() {
- return obj;
- }
- /**
- * Set the delegee.
- *
- * @param obj the delegee
- * @see org.mozilla.javascript.Scriptable
- */
- public void setDelegee(Scriptable obj) {
- this.obj = obj;
- }
- /**
- * @see org.mozilla.javascript.Scriptable#getClassName
- */
- public String getClassName() {
- return obj.getClassName();
- }
- /**
- * @see org.mozilla.javascript.Scriptable#get(String, Scriptable)
- */
- public Object get(String name, Scriptable start) {
- return obj.get(name,start);
- }
- /**
- * @see org.mozilla.javascript.Scriptable#get(int, Scriptable)
- */
- public Object get(int index, Scriptable start) {
- return obj.get(index,start);
- }
- /**
- * @see org.mozilla.javascript.Scriptable#has(String, Scriptable)
- */
- public boolean has(String name, Scriptable start) {
- return obj.has(name,start);
- }
- /**
- * @see org.mozilla.javascript.Scriptable#has(int, Scriptable)
- */
- public boolean has(int index, Scriptable start) {
- return obj.has(index,start);
- }
- /**
- * @see org.mozilla.javascript.Scriptable#put(String, Scriptable, Object)
- */
- public void put(String name, Scriptable start, Object value) {
- obj.put(name,start,value);
- }
- /**
- * @see org.mozilla.javascript.Scriptable#put(int, Scriptable, Object)
- */
- public void put(int index, Scriptable start, Object value) {
- obj.put(index,start,value);
- }
- /**
- * @see org.mozilla.javascript.Scriptable#delete(String)
- */
- public void delete(String name) {
- obj.delete(name);
- }
- /**
- * @see org.mozilla.javascript.Scriptable#delete(int)
- */
- public void delete(int index) {
- obj.delete(index);
- }
- /**
- * @see org.mozilla.javascript.Scriptable#getPrototype
- */
- public Scriptable getPrototype() {
- return obj.getPrototype();
- }
- /**
- * @see org.mozilla.javascript.Scriptable#setPrototype
- */
- public void setPrototype(Scriptable prototype) {
- obj.setPrototype(prototype);
- }
- /**
- * @see org.mozilla.javascript.Scriptable#getParentScope
- */
- public Scriptable getParentScope() {
- return obj.getParentScope();
- }
- /**
- * @see org.mozilla.javascript.Scriptable#setParentScope
- */
- public void setParentScope(Scriptable parent) {
- obj.setParentScope(parent);
- }
- /**
- * @see org.mozilla.javascript.Scriptable#getIds
- */
- public Object[] getIds() {
- return obj.getIds();
- }
- /**
- * Note that this method does not get forwarded to the delegee if
- * the <code>hint</code> parameter is null,
- * <code>ScriptRuntime.ScriptableClass</code> or
- * <code>ScriptRuntime.FunctionClass</code>. Instead the object
- * itself is returned.
- *
- * @param hint the type hint
- * @return the default value
- *
- * @see org.mozilla.javascript.Scriptable#getDefaultValue
- */
- public Object getDefaultValue(Class hint) {
- return (hint == null ||
- hint == ScriptRuntime.ScriptableClass ||
- hint == ScriptRuntime.FunctionClass) ?
- this : obj.getDefaultValue(hint);
- }
- /**
- * @see org.mozilla.javascript.Scriptable#hasInstance
- */
- public boolean hasInstance(Scriptable instance) {
- return obj.hasInstance(instance);
- }
- /**
- * @see org.mozilla.javascript.Function#call
- */
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- return ((Function)obj).call(cx,scope,thisObj,args);
- }
-
- /**
- * Note that if the <code>delegee</code> is <code>null</code>,
- * this method creates a new instance of the Delegator itself
- * rathert than forwarding the call to the
- * <code>delegee</code>. This permits the use of Delegator
- * prototypes.
- *
- * @param cx the current Context for this thread
- * @param scope an enclosing scope of the caller except
- * when the function is called from a closure.
- * @param args the array of arguments
- * @return the allocated object
- *
- * @see Function#construct(Context, Scriptable, Object[])
- */
- public Scriptable construct(Context cx, Scriptable scope, Object[] args)
- {
- if (obj == null) {
- //this little trick allows us to declare prototype objects for
- //Delegators
- Delegator n = newInstance();
- Scriptable delegee;
- if (args.length == 0) {
- delegee = new NativeObject();
- } else {
- delegee = ScriptRuntime.toObject(cx, scope, args[0]);
- }
- n.setDelegee(delegee);
- return n;
- }
- else {
- return ((Function)obj).construct(cx,scope,args);
- }
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EcmaError.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EcmaError.java
deleted file mode 100644
index 1fd8f03..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EcmaError.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/* -*- 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):
- * Roger Lawrence
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * The class of exceptions raised by the engine as described in
- * ECMA edition 3. See section 15.11.6 in particular.
- */
-public class EcmaError extends RhinoException
-{
- static final long serialVersionUID = -6261226256957286699L;
-
- private String errorName;
- private String errorMessage;
-
- /**
- * Create an exception with the specified detail message.
- *
- * Errors internal to the JavaScript engine will simply throw a
- * RuntimeException.
- *
- * @param sourceName the name of the source reponsible for the error
- * @param lineNumber the line number of the source
- * @param columnNumber the columnNumber of the source (may be zero if
- * unknown)
- * @param lineSource the source of the line containing the error (may be
- * null if unknown)
- */
- EcmaError(String errorName, String errorMessage,
- String sourceName, int lineNumber,
- String lineSource, int columnNumber)
- {
- recordErrorOrigin(sourceName, lineNumber, lineSource, columnNumber);
- this.errorName = errorName;
- this.errorMessage = errorMessage;
- }
-
- /**
- * @deprecated EcmaError error instances should not be constructed
- * explicitly since they are generated by the engine.
- */
- public EcmaError(Scriptable nativeError, String sourceName,
- int lineNumber, int columnNumber, String lineSource)
- {
- this("InternalError", ScriptRuntime.toString(nativeError),
- sourceName, lineNumber, lineSource, columnNumber);
- }
-
- public String details()
- {
- return errorName+": "+errorMessage;
- }
-
- /**
- * Gets the name of the error.
- *
- * ECMA edition 3 defines the following
- * errors: EvalError, RangeError, ReferenceError,
- * SyntaxError, TypeError, and URIError. Additional error names
- * may be added in the future.
- *
- * See ECMA edition 3, 15.11.7.9.
- *
- * @return the name of the error.
- */
- public String getName()
- {
- return errorName;
- }
-
- /**
- * Gets the message corresponding to the error.
- *
- * See ECMA edition 3, 15.11.7.10.
- *
- * @return an implemenation-defined string describing the error.
- */
- public String getErrorMessage()
- {
- return errorMessage;
- }
-
- /**
- * @deprecated Use {@link RhinoException#sourceName()} from the super class.
- */
- public String getSourceName()
- {
- return sourceName();
- }
-
- /**
- * @deprecated Use {@link RhinoException#lineNumber()} from the super class.
- */
- public int getLineNumber()
- {
- return lineNumber();
- }
-
- /**
- * @deprecated
- * Use {@link RhinoException#columnNumber()} from the super class.
- */
- public int getColumnNumber() {
- return columnNumber();
- }
-
- /**
- * @deprecated Use {@link RhinoException#lineSource()} from the super class.
- */
- public String getLineSource() {
- return lineSource();
- }
-
- /**
- * @deprecated
- * Always returns <b>null</b>.
- */
- public Scriptable getErrorObject()
- {
- return null;
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ErrorReporter.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ErrorReporter.java
deleted file mode 100644
index 4649370..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ErrorReporter.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- 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
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * This is interface defines a protocol for the reporting of
- * errors during JavaScript translation or execution.
- *
- * @author Norris Boyd
- */
-
-public interface ErrorReporter {
-
- /**
- * Report a warning.
- *
- * The implementing class may choose to ignore the warning
- * if it desires.
- *
- * @param message a String describing the warning
- * @param sourceName a String describing the JavaScript source
- * where the warning occured; typically a filename or URL
- * @param line the line number associated with the warning
- * @param lineSource the text of the line (may be null)
- * @param lineOffset the offset into lineSource where problem was detected
- */
- void warning(String message, String sourceName, int line,
- String lineSource, int lineOffset);
-
- /**
- * Report an error.
- *
- * The implementing class is free to throw an exception if
- * it desires.
- *
- * If execution has not yet begun, the JavaScript engine is
- * free to find additional errors rather than terminating
- * the translation. It will not execute a script that had
- * errors, however.
- *
- * @param message a String describing the error
- * @param sourceName a String describing the JavaScript source
- * where the error occured; typically a filename or URL
- * @param line the line number associated with the error
- * @param lineSource the text of the line (may be null)
- * @param lineOffset the offset into lineSource where problem was detected
- */
- void error(String message, String sourceName, int line,
- String lineSource, int lineOffset);
-
- /**
- * Creates an EvaluatorException that may be thrown.
- *
- * runtimeErrors, unlike errors, will always terminate the
- * current script.
- *
- * @param message a String describing the error
- * @param sourceName a String describing the JavaScript source
- * where the error occured; typically a filename or URL
- * @param line the line number associated with the error
- * @param lineSource the text of the line (may be null)
- * @param lineOffset the offset into lineSource where problem was detected
- * @return an EvaluatorException that will be thrown.
- */
- EvaluatorException runtimeError(String message, String sourceName,
- int line, String lineSource,
- int lineOffset);
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Evaluator.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Evaluator.java
deleted file mode 100644
index e222af3..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Evaluator.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/* -*- 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.
- *
- * Contributor(s):
- * Norris Boyd
- *
- * 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;
-
-import java.util.List;
-
-/**
- * Abstraction of evaluation, which can be implemented either by an
- * interpreter or compiler.
- */
-public interface Evaluator {
-
- /**
- * Compile the script or function from intermediate representation
- * tree into an executable form.
- *
- * @param compilerEnv Compiler environment
- * @param tree intermediate representation
- * @param encodedSource encoding of the source code for decompilation
- * @param returnFunction if true, compiling a function
- * @return an opaque object that can be passed to either
- * createFunctionObject or createScriptObject, depending on the
- * value of returnFunction
- */
- public Object compile(CompilerEnvirons compilerEnv,
- ScriptOrFnNode tree,
- String encodedSource,
- boolean returnFunction);
-
- /**
- * Create a function object.
- *
- * @param cx Current context
- * @param scope scope of the function
- * @param bytecode opaque object returned by compile
- * @param staticSecurityDomain security domain
- * @return Function object that can be called
- */
- public Function createFunctionObject(Context cx, Scriptable scope,
- Object bytecode, Object staticSecurityDomain);
-
- /**
- * Create a script object.
- *
- * @param bytecode opaque object returned by compile
- * @param staticSecurityDomain security domain
- * @return Script object that can be evaluated
- */
- public Script createScriptObject(Object bytecode,
- Object staticSecurityDomain);
-
- /**
- * Capture stack information from the given exception.
- * @param ex an exception thrown during execution
- */
- public void captureStackInfo(RhinoException ex);
-
- /**
- * Get the source position information by examining the stack.
- * @param cx Context
- * @param linep Array object of length >= 1; getSourcePositionFromStack
- * will assign the line number to linep[0].
- * @return the name of the file or other source container
- */
- public String getSourcePositionFromStack(Context cx, int[] linep);
-
- /**
- * Given a native stack trace, patch it with script-specific source
- * and line information
- * @param ex exception
- * @param nativeStackTrace the native stack trace
- * @return patched stack trace
- */
- public String getPatchedStack(RhinoException ex,
- String nativeStackTrace);
-
- /**
- * Get the script stack for the given exception
- * @param ex exception from execution
- * @return list of strings for the stack trace
- */
- public List getScriptStack(RhinoException ex);
-
- /**
- * Mark the given script to indicate it was created by a call to
- * eval() or to a Function constructor.
- * @param script script to mark as from eval
- */
- public void setEvalScriptFlag(Script script);
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EvaluatorException.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EvaluatorException.java
deleted file mode 100644
index 7b4e7cc..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EvaluatorException.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/* -*- 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
- *
- * 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;
-
-/**
- * The class of exceptions thrown by the JavaScript engine.
- */
-public class EvaluatorException extends RhinoException
-{
- static final long serialVersionUID = -8743165779676009808L;
-
- public EvaluatorException(String detail)
- {
- super(detail);
- }
-
- /**
- * Create an exception with the specified detail message.
- *
- * Errors internal to the JavaScript engine will simply throw a
- * RuntimeException.
- *
- * @param detail the error message
- * @param sourceName the name of the source reponsible for the error
- * @param lineNumber the line number of the source
- */
- public EvaluatorException(String detail, String sourceName,
- int lineNumber)
- {
- this(detail, sourceName, lineNumber, null, 0);
- }
-
- /**
- * Create an exception with the specified detail message.
- *
- * Errors internal to the JavaScript engine will simply throw a
- * RuntimeException.
- *
- * @param detail the error message
- * @param sourceName the name of the source responsible for the error
- * @param lineNumber the line number of the source
- * @param columnNumber the columnNumber of the source (may be zero if
- * unknown)
- * @param lineSource the source of the line containing the error (may be
- * null if unknown)
- */
- public EvaluatorException(String detail, String sourceName, int lineNumber,
- String lineSource, int columnNumber)
- {
- super(detail);
- recordErrorOrigin(sourceName, lineNumber, lineSource, columnNumber);
- }
-
- /**
- * @deprecated Use {@link RhinoException#sourceName()} from the super class.
- */
- public String getSourceName()
- {
- return sourceName();
- }
-
- /**
- * @deprecated Use {@link RhinoException#lineNumber()} from the super class.
- */
- public int getLineNumber()
- {
- return lineNumber();
- }
-
- /**
- * @deprecated Use {@link RhinoException#columnNumber()} from the super class.
- */
- public int getColumnNumber()
- {
- return columnNumber();
- }
-
- /**
- * @deprecated Use {@link RhinoException#lineSource()} from the super class.
- */
- public String getLineSource()
- {
- return lineSource();
- }
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Function.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Function.java
deleted file mode 100644
index a4377e6..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Function.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- 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
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * This is interface that all functions in JavaScript must implement.
- * The interface provides for calling functions and constructors.
- *
- * @see org.mozilla.javascript.Scriptable
- * @author Norris Boyd
- */
-
-public interface Function extends Scriptable, Callable
-{
- /**
- * Call the function.
- *
- * Note that the array of arguments is not guaranteed to have
- * length greater than 0.
- *
- * @param cx the current Context for this thread
- * @param scope the scope to execute the function relative to. This is
- * set to the value returned by getParentScope() except
- * when the function is called from a closure.
- * @param thisObj the JavaScript <code>this</code> object
- * @param args the array of arguments
- * @return the result of the call
- */
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args);
-
- /**
- * Call the function as a constructor.
- *
- * This method is invoked by the runtime in order to satisfy a use
- * of the JavaScript <code>new</code> operator. This method is
- * expected to create a new object and return it.
- *
- * @param cx the current Context for this thread
- * @param scope an enclosing scope of the caller except
- * when the function is called from a closure.
- * @param args the array of arguments
- * @return the allocated object
- */
- public Scriptable construct(Context cx, Scriptable scope, Object[] args);
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionNode.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionNode.java
deleted file mode 100644
index 484167e..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionNode.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- 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
- * Roger Lawrence
- *
- * 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;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class FunctionNode extends ScriptOrFnNode {
-
- public FunctionNode(String name) {
- super(Token.FUNCTION);
- functionName = name;
- }
-
- public String getFunctionName() {
- return functionName;
- }
-
- public boolean requiresActivation() {
- return itsNeedsActivation;
- }
-
- public boolean getIgnoreDynamicScope() {
- return itsIgnoreDynamicScope;
- }
-
- public boolean isGenerator() {
- return itsIsGenerator;
- }
-
- public void addResumptionPoint(Node target) {
- if (generatorResumePoints == null)
- generatorResumePoints = new ArrayList();
- generatorResumePoints.add(target);
- }
-
- public ArrayList getResumptionPoints() {
- return generatorResumePoints;
- }
-
- public HashMap getLiveLocals() {
- return liveLocals;
- }
-
- public void addLiveLocals(Node node, int[] locals) {
- if (liveLocals == null)
- liveLocals = new HashMap();
- liveLocals.put(node, locals);
- }
-
- /**
- * There are three types of functions that can be defined. The first
- * is a function statement. This is a function appearing as a top-level
- * statement (i.e., not nested inside some other statement) in either a
- * script or a function.
- *
- * The second is a function expression, which is a function appearing in
- * an expression except for the third type, which is...
- *
- * The third type is a function expression where the expression is the
- * top-level expression in an expression statement.
- *
- * The three types of functions have different treatment and must be
- * distinguished.
- */
- public static final int FUNCTION_STATEMENT = 1;
- public static final int FUNCTION_EXPRESSION = 2;
- public static final int FUNCTION_EXPRESSION_STATEMENT = 3;
-
- public int getFunctionType() {
- return itsFunctionType;
- }
-
- String functionName;
- int itsFunctionType;
- boolean itsNeedsActivation;
- boolean itsIgnoreDynamicScope;
- boolean itsIsGenerator;
- ArrayList generatorResumePoints;
- HashMap liveLocals;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionObject.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionObject.java
deleted file mode 100644
index 8fa4e68..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionObject.java
+++ /dev/null
@@ -1,569 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- * Igor Bukanov
- * David C. Navas
- * Ted Neward
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-import java.lang.reflect.*;
-import java.io.*;
-
-public class FunctionObject extends BaseFunction
-{
- static final long serialVersionUID = -5332312783643935019L;
-
- /**
- * Create a JavaScript function object from a Java method.
- *
- * <p>The <code>member</code> argument must be either a java.lang.reflect.Method
- * or a java.lang.reflect.Constructor and must match one of two forms.<p>
- *
- * The first form is a member with zero or more parameters
- * of the following types: Object, String, boolean, Scriptable,
- * int, or double. The Long type is not supported
- * because the double representation of a long (which is the
- * EMCA-mandated storage type for Numbers) may lose precision.
- * If the member is a Method, the return value must be void or one
- * of the types allowed for parameters.<p>
- *
- * The runtime will perform appropriate conversions based
- * upon the type of the parameter. A parameter type of
- * Object specifies that no conversions are to be done. A parameter
- * of type String will use Context.toString to convert arguments.
- * Similarly, parameters of type double, boolean, and Scriptable
- * will cause Context.toNumber, Context.toBoolean, and
- * Context.toObject, respectively, to be called.<p>
- *
- * If the method is not static, the Java 'this' value will
- * correspond to the JavaScript 'this' value. Any attempt
- * to call the function with a 'this' value that is not
- * of the right Java type will result in an error.<p>
- *
- * The second form is the variable arguments (or "varargs")
- * form. If the FunctionObject will be used as a constructor,
- * the member must have the following parameters
- * <pre>
- * (Context cx, Object[] args, Function ctorObj,
- * boolean inNewExpr)</pre>
- * and if it is a Method, be static and return an Object result.<p>
- *
- * Otherwise, if the FunctionObject will <i>not</i> be used to define a
- * constructor, the member must be a static Method with parameters
- * (Context cx, Scriptable thisObj, Object[] args,
- * Function funObj) </pre>
- * <pre>
- * and an Object result.<p>
- *
- * When the function varargs form is called as part of a function call,
- * the <code>args</code> parameter contains the
- * arguments, with <code>thisObj</code>
- * set to the JavaScript 'this' value. <code>funObj</code>
- * is the function object for the invoked function.<p>
- *
- * When the constructor varargs form is called or invoked while evaluating
- * a <code>new</code> expression, <code>args</code> contains the
- * arguments, <code>ctorObj</code> refers to this FunctionObject, and
- * <code>inNewExpr</code> is true if and only if a <code>new</code>
- * expression caused the call. This supports defining a function that
- * has different behavior when called as a constructor than when
- * invoked as a normal function call. (For example, the Boolean
- * constructor, when called as a function,
- * will convert to boolean rather than creating a new object.)<p>
- *
- * @param name the name of the function
- * @param methodOrConstructor a java.lang.reflect.Method or a java.lang.reflect.Constructor
- * that defines the object
- * @param scope enclosing scope of function
- * @see org.mozilla.javascript.Scriptable
- */
- public FunctionObject(String name, Member methodOrConstructor,
- Scriptable scope)
- {
- if (methodOrConstructor instanceof Constructor) {
- member = new MemberBox((Constructor) methodOrConstructor);
- isStatic = true; // well, doesn't take a 'this'
- } else {
- member = new MemberBox((Method) methodOrConstructor);
- isStatic = member.isStatic();
- }
- String methodName = member.getName();
- this.functionName = name;
- Class[] types = member.argTypes;
- int arity = types.length;
- if (arity == 4 && (types[1].isArray() || types[2].isArray())) {
- // Either variable args or an error.
- if (types[1].isArray()) {
- if (!isStatic ||
- types[0] != ScriptRuntime.ContextClass ||
- types[1].getComponentType() != ScriptRuntime.ObjectClass ||
- types[2] != ScriptRuntime.FunctionClass ||
- types[3] != Boolean.TYPE)
- {
- throw Context.reportRuntimeError1(
- "msg.varargs.ctor", methodName);
- }
- parmsLength = VARARGS_CTOR;
- } else {
- if (!isStatic ||
- types[0] != ScriptRuntime.ContextClass ||
- types[1] != ScriptRuntime.ScriptableClass ||
- types[2].getComponentType() != ScriptRuntime.ObjectClass ||
- types[3] != ScriptRuntime.FunctionClass)
- {
- throw Context.reportRuntimeError1(
- "msg.varargs.fun", methodName);
- }
- parmsLength = VARARGS_METHOD;
- }
- } else {
- parmsLength = arity;
- if (arity > 0) {
- typeTags = new byte[arity];
- for (int i = 0; i != arity; ++i) {
- int tag = getTypeTag(types[i]);
- if (tag == JAVA_UNSUPPORTED_TYPE) {
- throw Context.reportRuntimeError2(
- "msg.bad.parms", types[i].getName(), methodName);
- }
- typeTags[i] = (byte)tag;
- }
- }
- }
-
- if (member.isMethod()) {
- Method method = member.method();
- Class returnType = method.getReturnType();
- if (returnType == Void.TYPE) {
- hasVoidReturn = true;
- } else {
- returnTypeTag = getTypeTag(returnType);
- }
- } else {
- Class ctorType = member.getDeclaringClass();
- if (!ScriptRuntime.ScriptableClass.isAssignableFrom(ctorType)) {
- throw Context.reportRuntimeError1(
- "msg.bad.ctor.return", ctorType.getName());
- }
- }
-
- ScriptRuntime.setFunctionProtoAndParent(this, scope);
- }
-
- /**
- * @return One of <tt>JAVA_*_TYPE</tt> constants to indicate desired type
- * or {@link #JAVA_UNSUPPORTED_TYPE} if the convertion is not
- * possible
- */
- public static int getTypeTag(Class type)
- {
- if (type == ScriptRuntime.StringClass)
- return JAVA_STRING_TYPE;
- if (type == ScriptRuntime.IntegerClass || type == Integer.TYPE)
- return JAVA_INT_TYPE;
- if (type == ScriptRuntime.BooleanClass || type == Boolean.TYPE)
- return JAVA_BOOLEAN_TYPE;
- if (type == ScriptRuntime.DoubleClass || type == Double.TYPE)
- return JAVA_DOUBLE_TYPE;
- if (ScriptRuntime.ScriptableClass.isAssignableFrom(type))
- return JAVA_SCRIPTABLE_TYPE;
- if (type == ScriptRuntime.ObjectClass)
- return JAVA_OBJECT_TYPE;
-
- // Note that the long type is not supported; see the javadoc for
- // the constructor for this class
-
- return JAVA_UNSUPPORTED_TYPE;
- }
-
- public static Object convertArg(Context cx, Scriptable scope,
- Object arg, int typeTag)
- {
- switch (typeTag) {
- case JAVA_STRING_TYPE:
- if (arg instanceof String)
- return arg;
- return ScriptRuntime.toString(arg);
- case JAVA_INT_TYPE:
- if (arg instanceof Integer)
- return arg;
- return new Integer(ScriptRuntime.toInt32(arg));
- case JAVA_BOOLEAN_TYPE:
- if (arg instanceof Boolean)
- return arg;
- return ScriptRuntime.toBoolean(arg) ? Boolean.TRUE
- : Boolean.FALSE;
- case JAVA_DOUBLE_TYPE:
- if (arg instanceof Double)
- return arg;
- return new Double(ScriptRuntime.toNumber(arg));
- case JAVA_SCRIPTABLE_TYPE:
- if (arg instanceof Scriptable)
- return arg;
- return ScriptRuntime.toObject(cx, scope, arg);
- case JAVA_OBJECT_TYPE:
- return arg;
- default:
- throw new IllegalArgumentException();
- }
- }
-
- /**
- * Return the value defined by the method used to construct the object
- * (number of parameters of the method, or 1 if the method is a "varargs"
- * form).
- */
- public int getArity() {
- return parmsLength < 0 ? 1 : parmsLength;
- }
-
- /**
- * Return the same value as {@link #getArity()}.
- */
- public int getLength() {
- return getArity();
- }
-
- public String getFunctionName()
- {
- return (functionName == null) ? "" : functionName;
- }
-
- /**
- * Get Java method or constructor this function represent.
- */
- public Member getMethodOrConstructor()
- {
- if (member.isMethod()) {
- return member.method();
- } else {
- return member.ctor();
- }
- }
-
- static Method findSingleMethod(Method[] methods, String name)
- {
- Method found = null;
- for (int i = 0, N = methods.length; i != N; ++i) {
- Method method = methods[i];
- if (method != null && name.equals(method.getName())) {
- if (found != null) {
- throw Context.reportRuntimeError2(
- "msg.no.overload", name,
- method.getDeclaringClass().getName());
- }
- found = method;
- }
- }
- return found;
- }
-
- /**
- * Returns all public methods declared by the specified class. This excludes
- * inherited methods.
- *
- * @param clazz the class from which to pull public declared methods
- * @return the public methods declared in the specified class
- * @see Class#getDeclaredMethods()
- */
- static Method[] getMethodList(Class clazz) {
- Method[] methods = null;
- try {
- // getDeclaredMethods may be rejected by the security manager
- // but getMethods is more expensive
- if (!sawSecurityException)
- methods = clazz.getDeclaredMethods();
- } catch (SecurityException e) {
- // If we get an exception once, give up on getDeclaredMethods
- sawSecurityException = true;
- }
- if (methods == null) {
- methods = clazz.getMethods();
- }
- int count = 0;
- for (int i=0; i < methods.length; i++) {
- if (sawSecurityException
- ? methods[i].getDeclaringClass() != clazz
- : !Modifier.isPublic(methods[i].getModifiers()))
- {
- methods[i] = null;
- } else {
- count++;
- }
- }
- Method[] result = new Method[count];
- int j=0;
- for (int i=0; i < methods.length; i++) {
- if (methods[i] != null)
- result[j++] = methods[i];
- }
- return result;
- }
-
- /**
- * Define this function as a JavaScript constructor.
- * <p>
- * Sets up the "prototype" and "constructor" properties. Also
- * calls setParent and setPrototype with appropriate values.
- * Then adds the function object as a property of the given scope, using
- * <code>prototype.getClassName()</code>
- * as the name of the property.
- *
- * @param scope the scope in which to define the constructor (typically
- * the global object)
- * @param prototype the prototype object
- * @see org.mozilla.javascript.Scriptable#setParentScope
- * @see org.mozilla.javascript.Scriptable#setPrototype
- * @see org.mozilla.javascript.Scriptable#getClassName
- */
- public void addAsConstructor(Scriptable scope, Scriptable prototype)
- {
- initAsConstructor(scope, prototype);
- defineProperty(scope, prototype.getClassName(),
- this, ScriptableObject.DONTENUM);
- }
-
- void initAsConstructor(Scriptable scope, Scriptable prototype)
- {
- ScriptRuntime.setFunctionProtoAndParent(this, scope);
- setImmunePrototypeProperty(prototype);
-
- prototype.setParentScope(this);
-
- defineProperty(prototype, "constructor", this,
- ScriptableObject.DONTENUM |
- ScriptableObject.PERMANENT |
- ScriptableObject.READONLY);
- setParentScope(scope);
- }
-
- /**
- * @deprecated Use {@link #getTypeTag(Class)}
- * and {@link #convertArg(Context, Scriptable, Object, int)}
- * for type convertion.
- */
- public static Object convertArg(Context cx, Scriptable scope,
- Object arg, Class desired)
- {
- int tag = getTypeTag(desired);
- if (tag == JAVA_UNSUPPORTED_TYPE) {
- throw Context.reportRuntimeError1
- ("msg.cant.convert", desired.getName());
- }
- return convertArg(cx, scope, arg, tag);
- }
-
- /**
- * Performs conversions on argument types if needed and
- * invokes the underlying Java method or constructor.
- * <p>
- * Implements Function.call.
- *
- * @see org.mozilla.javascript.Function#call(
- * Context, Scriptable, Scriptable, Object[])
- */
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- Object result;
- boolean checkMethodResult = false;
-
- if (parmsLength < 0) {
- if (parmsLength == VARARGS_METHOD) {
- Object[] invokeArgs = { cx, thisObj, args, this };
- result = member.invoke(null, invokeArgs);
- checkMethodResult = true;
- } else {
- boolean inNewExpr = (thisObj == null);
- Boolean b = inNewExpr ? Boolean.TRUE : Boolean.FALSE;
- Object[] invokeArgs = { cx, args, this, b };
- result = (member.isCtor())
- ? member.newInstance(invokeArgs)
- : member.invoke(null, invokeArgs);
- }
-
- } else {
- if (!isStatic) {
- Class clazz = member.getDeclaringClass();
- if (!clazz.isInstance(thisObj)) {
- boolean compatible = false;
- if (thisObj == scope) {
- Scriptable parentScope = getParentScope();
- if (scope != parentScope) {
- // Call with dynamic scope for standalone function,
- // use parentScope as thisObj
- compatible = clazz.isInstance(parentScope);
- if (compatible) {
- thisObj = parentScope;
- }
- }
- }
- if (!compatible) {
- // Couldn't find an object to call this on.
- throw ScriptRuntime.typeError1("msg.incompat.call",
- functionName);
- }
- }
- }
-
- Object[] invokeArgs;
- if (parmsLength == args.length) {
- // Do not allocate new argument array if java arguments are
- // the same as the original js ones.
- invokeArgs = args;
- for (int i = 0; i != parmsLength; ++i) {
- Object arg = args[i];
- Object converted = convertArg(cx, scope, arg, typeTags[i]);
- if (arg != converted) {
- if (invokeArgs == args) {
- invokeArgs = args.clone();
- }
- invokeArgs[i] = converted;
- }
- }
- } else if (parmsLength == 0) {
- invokeArgs = ScriptRuntime.emptyArgs;
- } else {
- invokeArgs = new Object[parmsLength];
- for (int i = 0; i != parmsLength; ++i) {
- Object arg = (i < args.length)
- ? args[i]
- : Undefined.instance;
- invokeArgs[i] = convertArg(cx, scope, arg, typeTags[i]);
- }
- }
-
- if (member.isMethod()) {
- result = member.invoke(thisObj, invokeArgs);
- checkMethodResult = true;
- } else {
- result = member.newInstance(invokeArgs);
- }
-
- }
-
- if (checkMethodResult) {
- if (hasVoidReturn) {
- result = Undefined.instance;
- } else if (returnTypeTag == JAVA_UNSUPPORTED_TYPE) {
- result = cx.getWrapFactory().wrap(cx, scope, result, null);
- }
- // XXX: the code assumes that if returnTypeTag == JAVA_OBJECT_TYPE
- // then the Java method did a proper job of converting the
- // result to JS primitive or Scriptable to avoid
- // potentially costly Context.javaToJS call.
- }
-
- return result;
- }
-
- /**
- * Return new {@link Scriptable} instance using the default
- * constructor for the class of the underlying Java method.
- * Return null to indicate that the call method should be used to create
- * new objects.
- */
- public Scriptable createObject(Context cx, Scriptable scope) {
- if (member.isCtor() || parmsLength == VARARGS_CTOR) {
- return null;
- }
- Scriptable result;
- try {
- result = (Scriptable) member.getDeclaringClass().newInstance();
- } catch (Exception ex) {
- throw Context.throwAsScriptRuntimeEx(ex);
- }
-
- result.setPrototype(getClassPrototype());
- result.setParentScope(getParentScope());
- return result;
- }
-
- boolean isVarArgsMethod() {
- return parmsLength == VARARGS_METHOD;
- }
-
- boolean isVarArgsConstructor() {
- return parmsLength == VARARGS_CTOR;
- }
-
- private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- in.defaultReadObject();
- if (parmsLength > 0) {
- Class[] types = member.argTypes;
- typeTags = new byte[parmsLength];
- for (int i = 0; i != parmsLength; ++i) {
- typeTags[i] = (byte)getTypeTag(types[i]);
- }
- }
- if (member.isMethod()) {
- Method method = member.method();
- Class returnType = method.getReturnType();
- if (returnType == Void.TYPE) {
- hasVoidReturn = true;
- } else {
- returnTypeTag = getTypeTag(returnType);
- }
- }
- }
-
- private static final short VARARGS_METHOD = -1;
- private static final short VARARGS_CTOR = -2;
-
- private static boolean sawSecurityException;
-
- public static final int JAVA_UNSUPPORTED_TYPE = 0;
- public static final int JAVA_STRING_TYPE = 1;
- public static final int JAVA_INT_TYPE = 2;
- public static final int JAVA_BOOLEAN_TYPE = 3;
- public static final int JAVA_DOUBLE_TYPE = 4;
- public static final int JAVA_SCRIPTABLE_TYPE = 5;
- public static final int JAVA_OBJECT_TYPE = 6;
-
- MemberBox member;
- private String functionName;
- private transient byte[] typeTags;
- private int parmsLength;
- private transient boolean hasVoidReturn;
- private transient int returnTypeTag;
- private boolean isStatic;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/GeneratedClassLoader.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/GeneratedClassLoader.java
deleted file mode 100644
index 0f73615..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/GeneratedClassLoader.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- 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):
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * Interface to define classes from generated byte code.
- */
-public interface GeneratedClassLoader {
-
- /**
- * Define a new Java class.
- * Classes created via this method should have the same class loader.
- *
- * @param name fully qualified class name
- * @param data class byte code
- * @return new class object
- */
- public Class defineClass(String name, byte[] data);
-
- /**
- * Link the given class.
- *
- * @param cl Class instance returned from the previous call to
- * {@link #defineClass(String, byte[])}
- * @see java.lang.ClassLoader
- */
- public void linkClass(Class cl);
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IRFactory.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IRFactory.java
deleted file mode 100644
index 1f51cb1..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IRFactory.java
+++ /dev/null
@@ -1,1607 +0,0 @@
-/* -*- 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
- * Ethan Hugg
- * Bob Jervis
- * Terry Lucas
- * Milen Nankov
- *
- * 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;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * This class allows the creation of nodes, and follows the Factory pattern.
- *
- * @see Node
- * @author Mike McCabe
- * @author Norris Boyd
- */
-final class IRFactory
-{
- IRFactory(Parser parser)
- {
- this.parser = parser;
- }
-
- ScriptOrFnNode createScript()
- {
- return new ScriptOrFnNode(Token.SCRIPT);
- }
-
- /**
- * Script (for associating file/url names with toplevel scripts.)
- */
- void initScript(ScriptOrFnNode scriptNode, Node body)
- {
- Node children = body.getFirstChild();
- if (children != null) { scriptNode.addChildrenToBack(children); }
- }
-
- /**
- * Leaf
- */
- Node createLeaf(int nodeType)
- {
- return new Node(nodeType);
- }
-
- /**
- * Statement leaf nodes.
- */
-
- Node createSwitch(Node expr, int lineno)
- {
- //
- // The switch will be rewritten from:
- //
- // switch (expr) {
- // case test1: statements1;
- // ...
- // default: statementsDefault;
- // ...
- // case testN: statementsN;
- // }
- //
- // to:
- //
- // {
- // switch (expr) {
- // case test1: goto label1;
- // ...
- // case testN: goto labelN;
- // }
- // goto labelDefault;
- // label1:
- // statements1;
- // ...
- // labelDefault:
- // statementsDefault;
- // ...
- // labelN:
- // statementsN;
- // breakLabel:
- // }
- //
- // where inside switch each "break;" without label will be replaced
- // by "goto breakLabel".
- //
- // If the original switch does not have the default label, then
- // the transformed code would contain after the switch instead of
- // goto labelDefault;
- // the following goto:
- // goto breakLabel;
- //
-
- Node.Jump switchNode = new Node.Jump(Token.SWITCH, expr, lineno);
- Node block = new Node(Token.BLOCK, switchNode);
- return block;
- }
-
- /**
- * If caseExpression argument is null it indicate default label.
- */
- void addSwitchCase(Node switchBlock, Node caseExpression, Node statements)
- {
- if (switchBlock.getType() != Token.BLOCK) throw Kit.codeBug();
- Node.Jump switchNode = (Node.Jump)switchBlock.getFirstChild();
- if (switchNode.getType() != Token.SWITCH) throw Kit.codeBug();
-
- Node gotoTarget = Node.newTarget();
- if (caseExpression != null) {
- Node.Jump caseNode = new Node.Jump(Token.CASE, caseExpression);
- caseNode.target = gotoTarget;
- switchNode.addChildToBack(caseNode);
- } else {
- switchNode.setDefault(gotoTarget);
- }
- switchBlock.addChildToBack(gotoTarget);
- switchBlock.addChildToBack(statements);
- }
-
- void closeSwitch(Node switchBlock)
- {
- if (switchBlock.getType() != Token.BLOCK) throw Kit.codeBug();
- Node.Jump switchNode = (Node.Jump)switchBlock.getFirstChild();
- if (switchNode.getType() != Token.SWITCH) throw Kit.codeBug();
-
- Node switchBreakTarget = Node.newTarget();
- // switchNode.target is only used by NodeTransformer
- // to detect switch end
- switchNode.target = switchBreakTarget;
-
- Node defaultTarget = switchNode.getDefault();
- if (defaultTarget == null) {
- defaultTarget = switchBreakTarget;
- }
-
- switchBlock.addChildAfter(makeJump(Token.GOTO, defaultTarget),
- switchNode);
- switchBlock.addChildToBack(switchBreakTarget);
- }
-
- Node createVariables(int token, int lineno)
- {
- return new Node(token, lineno);
- }
-
- Node createExprStatement(Node expr, int lineno)
- {
- int type;
- if (parser.insideFunction()) {
- type = Token.EXPR_VOID;
- } else {
- type = Token.EXPR_RESULT;
- }
- return new Node(type, expr, lineno);
- }
-
- Node createExprStatementNoReturn(Node expr, int lineno)
- {
- return new Node(Token.EXPR_VOID, expr, lineno);
- }
-
- Node createDefaultNamespace(Node expr, int lineno)
- {
- // default xml namespace requires activation
- setRequiresActivation();
- Node n = createUnary(Token.DEFAULTNAMESPACE, expr);
- Node result = createExprStatement(n, lineno);
- return result;
- }
-
- /**
- * Name
- */
- Node createName(String name)
- {
- checkActivationName(name, Token.NAME);
- return Node.newString(Token.NAME, name);
- }
-
- private Node createName(int type, String name, Node child)
- {
- Node result = createName(name);
- result.setType(type);
- if (child != null)
- result.addChildToBack(child);
- return result;
- }
-
- /**
- * String (for literals)
- */
- Node createString(String string)
- {
- return Node.newString(string);
- }
-
- /**
- * Number (for literals)
- */
- Node createNumber(double number)
- {
- return Node.newNumber(number);
- }
-
- /**
- * Catch clause of try/catch/finally
- * @param varName the name of the variable to bind to the exception
- * @param catchCond the condition under which to catch the exception.
- * May be null if no condition is given.
- * @param stmts the statements in the catch clause
- * @param lineno the starting line number of the catch clause
- */
- Node createCatch(String varName, Node catchCond, Node stmts, int lineno)
- {
- if (catchCond == null) {
- catchCond = new Node(Token.EMPTY);
- }
- return new Node(Token.CATCH, createName(varName),
- catchCond, stmts, lineno);
- }
-
- /**
- * Throw
- */
- Node createThrow(Node expr, int lineno)
- {
- return new Node(Token.THROW, expr, lineno);
- }
-
- /**
- * Return
- */
- Node createReturn(Node expr, int lineno)
- {
- return expr == null
- ? new Node(Token.RETURN, lineno)
- : new Node(Token.RETURN, expr, lineno);
- }
-
- /**
- * Debugger
- */
- Node createDebugger(int lineno)
- {
- return new Node(Token.DEBUGGER, lineno);
- }
-
- /**
- * Label
- */
- Node createLabel(int lineno)
- {
- return new Node.Jump(Token.LABEL, lineno);
- }
-
- Node getLabelLoop(Node label)
- {
- return ((Node.Jump)label).getLoop();
- }
-
- /**
- * Label
- */
- Node createLabeledStatement(Node labelArg, Node statement)
- {
- Node.Jump label = (Node.Jump)labelArg;
-
- // Make a target and put it _after_ the statement
- // node. And in the LABEL node, so breaks get the
- // right target.
-
- Node breakTarget = Node.newTarget();
- Node block = new Node(Token.BLOCK, label, statement, breakTarget);
- label.target = breakTarget;
-
- return block;
- }
-
- /**
- * Break (possibly labeled)
- */
- Node createBreak(Node breakStatement, int lineno)
- {
- Node.Jump n = new Node.Jump(Token.BREAK, lineno);
- Node.Jump jumpStatement;
- int t = breakStatement.getType();
- if (t == Token.LOOP || t == Token.LABEL) {
- jumpStatement = (Node.Jump)breakStatement;
- } else if (t == Token.BLOCK
- && breakStatement.getFirstChild().getType() == Token.SWITCH)
- {
- jumpStatement = (Node.Jump)breakStatement.getFirstChild();
- } else {
- throw Kit.codeBug();
- }
- n.setJumpStatement(jumpStatement);
- return n;
- }
-
- /**
- * Continue (possibly labeled)
- */
- Node createContinue(Node loop, int lineno)
- {
- if (loop.getType() != Token.LOOP) Kit.codeBug();
- Node.Jump n = new Node.Jump(Token.CONTINUE, lineno);
- n.setJumpStatement((Node.Jump)loop);
- return n;
- }
-
- /**
- * Statement block
- * Creates the empty statement block
- * Must make subsequent calls to add statements to the node
- */
- Node createBlock(int lineno)
- {
- return new Node(Token.BLOCK, lineno);
- }
-
- FunctionNode createFunction(String name)
- {
- return new FunctionNode(name);
- }
-
- Node initFunction(FunctionNode fnNode, int functionIndex,
- Node statements, int functionType)
- {
- fnNode.itsFunctionType = functionType;
- fnNode.addChildToBack(statements);
-
- int functionCount = fnNode.getFunctionCount();
- if (functionCount != 0) {
- // Functions containing other functions require activation objects
- fnNode.itsNeedsActivation = true;
- }
-
- if (functionType == FunctionNode.FUNCTION_EXPRESSION) {
- String name = fnNode.getFunctionName();
- if (name != null && name.length() != 0) {
- // A function expression needs to have its name as a
- // variable (if it isn't already allocated as a variable).
- // See ECMA Ch. 13. We add code to the beginning of the
- // function to initialize a local variable of the
- // function's name to the function value.
- Node setFn = new Node(Token.EXPR_VOID,
- new Node(Token.SETNAME,
- Node.newString(Token.BINDNAME, name),
- new Node(Token.THISFN)));
- statements.addChildrenToFront(setFn);
- }
- }
-
- // Add return to end if needed.
- Node lastStmt = statements.getLastChild();
- if (lastStmt == null || lastStmt.getType() != Token.RETURN) {
- statements.addChildToBack(new Node(Token.RETURN));
- }
-
- Node result = Node.newString(Token.FUNCTION,
- fnNode.getFunctionName());
- result.putIntProp(Node.FUNCTION_PROP, functionIndex);
- return result;
- }
-
- /**
- * Add a child to the back of the given node. This function
- * breaks the Factory abstraction, but it removes a requirement
- * from implementors of Node.
- */
- void addChildToBack(Node parent, Node child)
- {
- parent.addChildToBack(child);
- }
-
- /**
- * Create a node that can be used to hold lexically scoped variable
- * definitions (via let declarations).
- *
- * @param token the token of the node to create
- * @param lineno line number of source
- * @return the created node
- */
- Node createScopeNode(int token, int lineno) {
- return new Node.Scope(token, lineno);
- }
-
- /**
- * Create loop node. The parser will later call
- * createWhile|createDoWhile|createFor|createForIn
- * to finish loop generation.
- */
- Node createLoopNode(Node loopLabel, int lineno)
- {
- Node.Jump result = new Node.Scope(Token.LOOP, lineno);
- if (loopLabel != null) {
- ((Node.Jump)loopLabel).setLoop(result);
- }
- return result;
- }
-
- /**
- * While
- */
- Node createWhile(Node loop, Node cond, Node body)
- {
- return createLoop((Node.Jump)loop, LOOP_WHILE, body, cond,
- null, null);
- }
-
- /**
- * DoWhile
- */
- Node createDoWhile(Node loop, Node body, Node cond)
- {
- return createLoop((Node.Jump)loop, LOOP_DO_WHILE, body, cond,
- null, null);
- }
-
- /**
- * For
- */
- Node createFor(Node loop, Node init, Node test, Node incr, Node body)
- {
- if (init.getType() == Token.LET) {
- // rewrite "for (let i=s; i < N; i++)..." as
- // "let (i=s) { for (; i < N; i++)..." so that "s" is evaluated
- // outside the scope of the for.
- Node.Scope let = Node.Scope.splitScope((Node.Scope)loop);
- let.setType(Token.LET);
- let.addChildrenToBack(init);
- let.addChildToBack(createLoop((Node.Jump)loop, LOOP_FOR, body, test,
- new Node(Token.EMPTY), incr));
- return let;
- }
- return createLoop((Node.Jump)loop, LOOP_FOR, body, test, init, incr);
- }
-
- private Node createLoop(Node.Jump loop, int loopType, Node body, Node cond,
- Node init, Node incr)
- {
- Node bodyTarget = Node.newTarget();
- Node condTarget = Node.newTarget();
- if (loopType == LOOP_FOR && cond.getType() == Token.EMPTY) {
- cond = new Node(Token.TRUE);
- }
- Node.Jump IFEQ = new Node.Jump(Token.IFEQ, cond);
- IFEQ.target = bodyTarget;
- Node breakTarget = Node.newTarget();
-
- loop.addChildToBack(bodyTarget);
- loop.addChildrenToBack(body);
- if (loopType == LOOP_WHILE || loopType == LOOP_FOR) {
- // propagate lineno to condition
- loop.addChildrenToBack(new Node(Token.EMPTY, loop.getLineno()));
- }
- loop.addChildToBack(condTarget);
- loop.addChildToBack(IFEQ);
- loop.addChildToBack(breakTarget);
-
- loop.target = breakTarget;
- Node continueTarget = condTarget;
-
- if (loopType == LOOP_WHILE || loopType == LOOP_FOR) {
- // Just add a GOTO to the condition in the do..while
- loop.addChildToFront(makeJump(Token.GOTO, condTarget));
-
- if (loopType == LOOP_FOR) {
- int initType = init.getType();
- if (initType != Token.EMPTY) {
- if (initType != Token.VAR && initType != Token.LET) {
- init = new Node(Token.EXPR_VOID, init);
- }
- loop.addChildToFront(init);
- }
- Node incrTarget = Node.newTarget();
- loop.addChildAfter(incrTarget, body);
- if (incr.getType() != Token.EMPTY) {
- incr = new Node(Token.EXPR_VOID, incr);
- loop.addChildAfter(incr, incrTarget);
- }
- continueTarget = incrTarget;
- }
- }
-
- loop.setContinue(continueTarget);
-
- return loop;
- }
-
- /**
- * For .. In
- *
- */
- Node createForIn(int declType, Node loop, Node lhs, Node obj, Node body,
- boolean isForEach)
- {
- int destructuring = -1;
- int destructuringLen = 0;
- Node lvalue;
- int type = lhs.getType();
- if (type == Token.VAR || type == Token.LET) {
- Node lastChild = lhs.getLastChild();
- if (lhs.getFirstChild() != lastChild) {
- /*
- * check that there was only one variable given.
- * we can't do this in the parser, because then the
- * parser would have to know something about the
- * 'init' node of the for-in loop.
- */
- parser.reportError("msg.mult.index");
- }
- if (lastChild.getType() == Token.ARRAYLIT ||
- lastChild.getType() == Token.OBJECTLIT)
- {
- type = destructuring = lastChild.getType();
- lvalue = lastChild;
- destructuringLen = lastChild.getIntProp(
- Node.DESTRUCTURING_ARRAY_LENGTH, 0);
- } else if (lastChild.getType() == Token.NAME) {
- lvalue = Node.newString(Token.NAME, lastChild.getString());
- } else {
- parser.reportError("msg.bad.for.in.lhs");
- return obj;
- }
- } else if (type == Token.ARRAYLIT || type == Token.OBJECTLIT) {
- destructuring = type;
- lvalue = lhs;
- destructuringLen = lhs.getIntProp(Node.DESTRUCTURING_ARRAY_LENGTH, 0);
- } else {
- lvalue = makeReference(lhs);
- if (lvalue == null) {
- parser.reportError("msg.bad.for.in.lhs");
- return obj;
- }
- }
-
- Node localBlock = new Node(Token.LOCAL_BLOCK);
- int initType = (isForEach) ? Token.ENUM_INIT_VALUES :
- (destructuring != -1) ? Token.ENUM_INIT_ARRAY :
- Token.ENUM_INIT_KEYS;
- Node init = new Node(initType, obj);
- init.putProp(Node.LOCAL_BLOCK_PROP, localBlock);
- Node cond = new Node(Token.ENUM_NEXT);
- cond.putProp(Node.LOCAL_BLOCK_PROP, localBlock);
- Node id = new Node(Token.ENUM_ID);
- id.putProp(Node.LOCAL_BLOCK_PROP, localBlock);
-
- Node newBody = new Node(Token.BLOCK);
- Node assign;
- if (destructuring != -1) {
- assign = createDestructuringAssignment(declType, lvalue, id);
- if (!isForEach && (destructuring == Token.OBJECTLIT ||
- destructuringLen != 2))
- {
- // destructuring assignment is only allowed in for..each or
- // with an array type of length 2 (to hold key and value)
- parser.reportError("msg.bad.for.in.destruct");
- }
- } else {
- assign = simpleAssignment(lvalue, id);
- }
- newBody.addChildToBack(new Node(Token.EXPR_VOID, assign));
- newBody.addChildToBack(body);
-
- loop = createWhile(loop, cond, newBody);
- loop.addChildToFront(init);
- if (type == Token.VAR || type == Token.LET)
- loop.addChildToFront(lhs);
- localBlock.addChildToBack(loop);
-
- return localBlock;
- }
-
- /**
- * Try/Catch/Finally
- *
- * The IRFactory tries to express as much as possible in the tree;
- * the responsibilities remaining for Codegen are to add the Java
- * handlers: (Either (but not both) of TARGET and FINALLY might not
- * be defined)
-
- * - a catch handler for javascript exceptions that unwraps the
- * exception onto the stack and GOTOes to the catch target
-
- * - a finally handler
-
- * ... and a goto to GOTO around these handlers.
- */
- Node createTryCatchFinally(Node tryBlock, Node catchBlocks,
- Node finallyBlock, int lineno)
- {
- boolean hasFinally = (finallyBlock != null)
- && (finallyBlock.getType() != Token.BLOCK
- || finallyBlock.hasChildren());
-
- // short circuit
- if (tryBlock.getType() == Token.BLOCK && !tryBlock.hasChildren()
- && !hasFinally)
- {
- return tryBlock;
- }
-
- boolean hasCatch = catchBlocks.hasChildren();
-
- // short circuit
- if (!hasFinally && !hasCatch) {
- // bc finally might be an empty block...
- return tryBlock;
- }
-
-
- Node handlerBlock = new Node(Token.LOCAL_BLOCK);
- Node.Jump pn = new Node.Jump(Token.TRY, tryBlock, lineno);
- pn.putProp(Node.LOCAL_BLOCK_PROP, handlerBlock);
-
- if (hasCatch) {
- // jump around catch code
- Node endCatch = Node.newTarget();
- pn.addChildToBack(makeJump(Token.GOTO, endCatch));
-
- // make a TARGET for the catch that the tcf node knows about
- Node catchTarget = Node.newTarget();
- pn.target = catchTarget;
- // mark it
- pn.addChildToBack(catchTarget);
-
- //
- // Given
- //
- // try {
- // tryBlock;
- // } catch (e if condition1) {
- // something1;
- // ...
- //
- // } catch (e if conditionN) {
- // somethingN;
- // } catch (e) {
- // somethingDefault;
- // }
- //
- // rewrite as
- //
- // try {
- // tryBlock;
- // goto after_catch:
- // } catch (x) {
- // with (newCatchScope(e, x)) {
- // if (condition1) {
- // something1;
- // goto after_catch;
- // }
- // }
- // ...
- // with (newCatchScope(e, x)) {
- // if (conditionN) {
- // somethingN;
- // goto after_catch;
- // }
- // }
- // with (newCatchScope(e, x)) {
- // somethingDefault;
- // goto after_catch;
- // }
- // }
- // after_catch:
- //
- // If there is no default catch, then the last with block
- // arround "somethingDefault;" is replaced by "rethrow;"
-
- // It is assumed that catch handler generation will store
- // exeception object in handlerBlock register
-
- // Block with local for exception scope objects
- Node catchScopeBlock = new Node(Token.LOCAL_BLOCK);
-
- // expects catchblocks children to be (cond block) pairs.
- Node cb = catchBlocks.getFirstChild();
- boolean hasDefault = false;
- int scopeIndex = 0;
- while (cb != null) {
- int catchLineNo = cb.getLineno();
-
- Node name = cb.getFirstChild();
- Node cond = name.getNext();
- Node catchStatement = cond.getNext();
- cb.removeChild(name);
- cb.removeChild(cond);
- cb.removeChild(catchStatement);
-
- // Add goto to the catch statement to jump out of catch
- // but prefix it with LEAVEWITH since try..catch produces
- // "with"code in order to limit the scope of the exception
- // object.
- catchStatement.addChildToBack(new Node(Token.LEAVEWITH));
- catchStatement.addChildToBack(makeJump(Token.GOTO, endCatch));
-
- // Create condition "if" when present
- Node condStmt;
- if (cond.getType() == Token.EMPTY) {
- condStmt = catchStatement;
- hasDefault = true;
- } else {
- condStmt = createIf(cond, catchStatement, null,
- catchLineNo);
- }
-
- // Generate code to create the scope object and store
- // it in catchScopeBlock register
- Node catchScope = new Node(Token.CATCH_SCOPE, name,
- createUseLocal(handlerBlock));
- catchScope.putProp(Node.LOCAL_BLOCK_PROP, catchScopeBlock);
- catchScope.putIntProp(Node.CATCH_SCOPE_PROP, scopeIndex);
- catchScopeBlock.addChildToBack(catchScope);
-
- // Add with statement based on catch scope object
- catchScopeBlock.addChildToBack(
- createWith(createUseLocal(catchScopeBlock), condStmt,
- catchLineNo));
-
- // move to next cb
- cb = cb.getNext();
- ++scopeIndex;
- }
- pn.addChildToBack(catchScopeBlock);
- if (!hasDefault) {
- // Generate code to rethrow if no catch clause was executed
- Node rethrow = new Node(Token.RETHROW);
- rethrow.putProp(Node.LOCAL_BLOCK_PROP, handlerBlock);
- pn.addChildToBack(rethrow);
- }
-
- pn.addChildToBack(endCatch);
- }
-
- if (hasFinally) {
- Node finallyTarget = Node.newTarget();
- pn.setFinally(finallyTarget);
-
- // add jsr finally to the try block
- pn.addChildToBack(makeJump(Token.JSR, finallyTarget));
-
- // jump around finally code
- Node finallyEnd = Node.newTarget();
- pn.addChildToBack(makeJump(Token.GOTO, finallyEnd));
-
- pn.addChildToBack(finallyTarget);
- Node fBlock = new Node(Token.FINALLY, finallyBlock);
- fBlock.putProp(Node.LOCAL_BLOCK_PROP, handlerBlock);
- pn.addChildToBack(fBlock);
-
- pn.addChildToBack(finallyEnd);
- }
- handlerBlock.addChildToBack(pn);
- return handlerBlock;
- }
-
- /**
- * Throw, Return, Label, Break and Continue are defined in ASTFactory.
- */
-
- /**
- * With
- */
- Node createWith(Node obj, Node body, int lineno)
- {
- setRequiresActivation();
- Node result = new Node(Token.BLOCK, lineno);
- result.addChildToBack(new Node(Token.ENTERWITH, obj));
- Node bodyNode = new Node(Token.WITH, body, lineno);
- result.addChildrenToBack(bodyNode);
- result.addChildToBack(new Node(Token.LEAVEWITH));
- return result;
- }
-
- /**
- * DOTQUERY
- */
- public Node createDotQuery (Node obj, Node body, int lineno)
- {
- setRequiresActivation();
- Node result = new Node(Token.DOTQUERY, obj, body, lineno);
- return result;
- }
-
- Node createArrayLiteral(ObjArray elems, int skipCount, int destructuringLen)
- {
- int length = elems.size();
- int[] skipIndexes = null;
- if (skipCount != 0) {
- skipIndexes = new int[skipCount];
- }
- Node array = new Node(Token.ARRAYLIT);
- for (int i = 0, j = 0; i != length; ++i) {
- Node elem = (Node)elems.get(i);
- if (elem != null) {
- array.addChildToBack(elem);
- } else {
- skipIndexes[j] = i;
- ++j;
- }
- }
- if (skipCount != 0) {
- array.putProp(Node.SKIP_INDEXES_PROP, skipIndexes);
- }
- array.putIntProp(Node.DESTRUCTURING_ARRAY_LENGTH, destructuringLen);
- return array;
- }
-
- /**
- * Object Literals
- * <BR> createObjectLiteral rewrites its argument as object
- * creation plus object property entries, so later compiler
- * stages don't need to know about object literals.
- */
- Node createObjectLiteral(ObjArray elems)
- {
- int size = elems.size() / 2;
- Node object = new Node(Token.OBJECTLIT);
- Object[] properties;
- if (size == 0) {
- properties = ScriptRuntime.emptyArgs;
- } else {
- properties = new Object[size];
- for (int i = 0; i != size; ++i) {
- properties[i] = elems.get(2 * i);
- Node value = (Node)elems.get(2 * i + 1);
- object.addChildToBack(value);
- }
- }
- object.putProp(Node.OBJECT_IDS_PROP, properties);
- return object;
- }
-
- /**
- * Regular expressions
- */
- Node createRegExp(int regexpIndex)
- {
- Node n = new Node(Token.REGEXP);
- n.putIntProp(Node.REGEXP_PROP, regexpIndex);
- return n;
- }
-
- /**
- * If statement
- */
- Node createIf(Node cond, Node ifTrue, Node ifFalse, int lineno)
- {
- int condStatus = isAlwaysDefinedBoolean(cond);
- if (condStatus == ALWAYS_TRUE_BOOLEAN) {
- return ifTrue;
- } else if (condStatus == ALWAYS_FALSE_BOOLEAN) {
- if (ifFalse != null) {
- return ifFalse;
- }
- // Replace if (false) xxx by empty block
- return new Node(Token.BLOCK, lineno);
- }
-
- Node result = new Node(Token.BLOCK, lineno);
- Node ifNotTarget = Node.newTarget();
- Node.Jump IFNE = new Node.Jump(Token.IFNE, cond);
- IFNE.target = ifNotTarget;
-
- result.addChildToBack(IFNE);
- result.addChildrenToBack(ifTrue);
-
- if (ifFalse != null) {
- Node endTarget = Node.newTarget();
- result.addChildToBack(makeJump(Token.GOTO, endTarget));
- result.addChildToBack(ifNotTarget);
- result.addChildrenToBack(ifFalse);
- result.addChildToBack(endTarget);
- } else {
- result.addChildToBack(ifNotTarget);
- }
-
- return result;
- }
-
- Node createCondExpr(Node cond, Node ifTrue, Node ifFalse)
- {
- int condStatus = isAlwaysDefinedBoolean(cond);
- if (condStatus == ALWAYS_TRUE_BOOLEAN) {
- return ifTrue;
- } else if (condStatus == ALWAYS_FALSE_BOOLEAN) {
- return ifFalse;
- }
- return new Node(Token.HOOK, cond, ifTrue, ifFalse);
- }
-
- /**
- * Unary
- */
- Node createUnary(int nodeType, Node child)
- {
- int childType = child.getType();
- switch (nodeType) {
- case Token.DELPROP: {
- Node n;
- if (childType == Token.NAME) {
- // Transform Delete(Name "a")
- // to Delete(Bind("a"), String("a"))
- child.setType(Token.BINDNAME);
- Node left = child;
- Node right = Node.newString(child.getString());
- n = new Node(nodeType, left, right);
- } else if (childType == Token.GETPROP ||
- childType == Token.GETELEM)
- {
- Node left = child.getFirstChild();
- Node right = child.getLastChild();
- child.removeChild(left);
- child.removeChild(right);
- n = new Node(nodeType, left, right);
- } else if (childType == Token.GET_REF) {
- Node ref = child.getFirstChild();
- child.removeChild(ref);
- n = new Node(Token.DEL_REF, ref);
- } else {
- n = new Node(Token.TRUE);
- }
- return n;
- }
- case Token.TYPEOF:
- if (childType == Token.NAME) {
- child.setType(Token.TYPEOFNAME);
- return child;
- }
- break;
- case Token.BITNOT:
- if (childType == Token.NUMBER) {
- int value = ScriptRuntime.toInt32(child.getDouble());
- child.setDouble(~value);
- return child;
- }
- break;
- case Token.NEG:
- if (childType == Token.NUMBER) {
- child.setDouble(-child.getDouble());
- return child;
- }
- break;
- case Token.NOT: {
- int status = isAlwaysDefinedBoolean(child);
- if (status != 0) {
- int type;
- if (status == ALWAYS_TRUE_BOOLEAN) {
- type = Token.FALSE;
- } else {
- type = Token.TRUE;
- }
- if (childType == Token.TRUE || childType == Token.FALSE) {
- child.setType(type);
- return child;
- }
- return new Node(type);
- }
- break;
- }
- }
- return new Node(nodeType, child);
- }
-
- Node createYield(Node child, int lineno)
- {
- if (!parser.insideFunction()) {
- parser.reportError("msg.bad.yield");
- }
- setRequiresActivation();
- setIsGenerator();
- if (child != null)
- return new Node(Token.YIELD, child, lineno);
- else
- return new Node(Token.YIELD, lineno);
- }
-
- Node createCallOrNew(int nodeType, Node child)
- {
- int type = Node.NON_SPECIALCALL;
- if (child.getType() == Token.NAME) {
- String name = child.getString();
- if (name.equals("eval")) {
- type = Node.SPECIALCALL_EVAL;
- } else if (name.equals("With")) {
- type = Node.SPECIALCALL_WITH;
- }
- } else if (child.getType() == Token.GETPROP) {
- String name = child.getLastChild().getString();
- if (name.equals("eval")) {
- type = Node.SPECIALCALL_EVAL;
- }
- }
- Node node = new Node(nodeType, child);
- if (type != Node.NON_SPECIALCALL) {
- // Calls to these functions require activation objects.
- setRequiresActivation();
- node.putIntProp(Node.SPECIALCALL_PROP, type);
- }
- return node;
- }
-
- Node createIncDec(int nodeType, boolean post, Node child)
- {
- child = makeReference(child);
- if (child == null) {
- String msg;
- if (nodeType == Token.DEC) {
- msg = "msg.bad.decr";
- } else {
- msg = "msg.bad.incr";
- }
- parser.reportError(msg);
- return null;
- }
-
- int childType = child.getType();
-
- switch (childType) {
- case Token.NAME:
- case Token.GETPROP:
- case Token.GETELEM:
- case Token.GET_REF: {
- Node n = new Node(nodeType, child);
- int incrDecrMask = 0;
- if (nodeType == Token.DEC) {
- incrDecrMask |= Node.DECR_FLAG;
- }
- if (post) {
- incrDecrMask |= Node.POST_FLAG;
- }
- n.putIntProp(Node.INCRDECR_PROP, incrDecrMask);
- return n;
- }
- }
- throw Kit.codeBug();
- }
-
- Node createPropertyGet(Node target, String namespace, String name,
- int memberTypeFlags)
- {
- if (namespace == null && memberTypeFlags == 0) {
- if (target == null) {
- return createName(name);
- }
- checkActivationName(name, Token.GETPROP);
- if (ScriptRuntime.isSpecialProperty(name)) {
- Node ref = new Node(Token.REF_SPECIAL, target);
- ref.putProp(Node.NAME_PROP, name);
- return new Node(Token.GET_REF, ref);
- }
- return new Node(Token.GETPROP, target, createString(name));
- }
- Node elem = createString(name);
- memberTypeFlags |= Node.PROPERTY_FLAG;
- return createMemberRefGet(target, namespace, elem, memberTypeFlags);
- }
-
- Node createElementGet(Node target, String namespace, Node elem,
- int memberTypeFlags)
- {
- // OPT: could optimize to createPropertyGet
- // iff elem is string that can not be number
- if (namespace == null && memberTypeFlags == 0) {
- // stand-alone [aaa] as primary expression is array literal
- // declaration and should not come here!
- if (target == null) throw Kit.codeBug();
- return new Node(Token.GETELEM, target, elem);
- }
- return createMemberRefGet(target, namespace, elem, memberTypeFlags);
- }
-
- private Node createMemberRefGet(Node target, String namespace, Node elem,
- int memberTypeFlags)
- {
- Node nsNode = null;
- if (namespace != null) {
- // See 11.1.2 in ECMA 357
- if (namespace.equals("*")) {
- nsNode = new Node(Token.NULL);
- } else {
- nsNode = createName(namespace);
- }
- }
- Node ref;
- if (target == null) {
- if (namespace == null) {
- ref = new Node(Token.REF_NAME, elem);
- } else {
- ref = new Node(Token.REF_NS_NAME, nsNode, elem);
- }
- } else {
- if (namespace == null) {
- ref = new Node(Token.REF_MEMBER, target, elem);
- } else {
- ref = new Node(Token.REF_NS_MEMBER, target, nsNode, elem);
- }
- }
- if (memberTypeFlags != 0) {
- ref.putIntProp(Node.MEMBER_TYPE_PROP, memberTypeFlags);
- }
- return new Node(Token.GET_REF, ref);
- }
-
- /**
- * Binary
- */
- Node createBinary(int nodeType, Node left, Node right)
- {
- switch (nodeType) {
-
- case Token.ADD:
- // numerical addition and string concatenation
- if (left.type == Token.STRING) {
- String s2;
- if (right.type == Token.STRING) {
- s2 = right.getString();
- } else if (right.type == Token.NUMBER) {
- s2 = ScriptRuntime.numberToString(right.getDouble(), 10);
- } else {
- break;
- }
- String s1 = left.getString();
- left.setString(s1.concat(s2));
- return left;
- } else if (left.type == Token.NUMBER) {
- if (right.type == Token.NUMBER) {
- left.setDouble(left.getDouble() + right.getDouble());
- return left;
- } else if (right.type == Token.STRING) {
- String s1, s2;
- s1 = ScriptRuntime.numberToString(left.getDouble(), 10);
- s2 = right.getString();
- right.setString(s1.concat(s2));
- return right;
- }
- }
- // can't do anything if we don't know both types - since
- // 0 + object is supposed to call toString on the object and do
- // string concantenation rather than addition
- break;
-
- case Token.SUB:
- // numerical subtraction
- if (left.type == Token.NUMBER) {
- double ld = left.getDouble();
- if (right.type == Token.NUMBER) {
- //both numbers
- left.setDouble(ld - right.getDouble());
- return left;
- } else if (ld == 0.0) {
- // first 0: 0-x -> -x
- return new Node(Token.NEG, right);
- }
- } else if (right.type == Token.NUMBER) {
- if (right.getDouble() == 0.0) {
- //second 0: x - 0 -> +x
- // can not make simply x because x - 0 must be number
- return new Node(Token.POS, left);
- }
- }
- break;
-
- case Token.MUL:
- // numerical multiplication
- if (left.type == Token.NUMBER) {
- double ld = left.getDouble();
- if (right.type == Token.NUMBER) {
- //both numbers
- left.setDouble(ld * right.getDouble());
- return left;
- } else if (ld == 1.0) {
- // first 1: 1 * x -> +x
- return new Node(Token.POS, right);
- }
- } else if (right.type == Token.NUMBER) {
- if (right.getDouble() == 1.0) {
- //second 1: x * 1 -> +x
- // can not make simply x because x - 0 must be number
- return new Node(Token.POS, left);
- }
- }
- // can't do x*0: Infinity * 0 gives NaN, not 0
- break;
-
- case Token.DIV:
- // number division
- if (right.type == Token.NUMBER) {
- double rd = right.getDouble();
- if (left.type == Token.NUMBER) {
- // both constants -- just divide, trust Java to handle x/0
- left.setDouble(left.getDouble() / rd);
- return left;
- } else if (rd == 1.0) {
- // second 1: x/1 -> +x
- // not simply x to force number convertion
- return new Node(Token.POS, left);
- }
- }
- break;
-
- case Token.AND: {
- // Since x && y gives x, not false, when Boolean(x) is false,
- // and y, not Boolean(y), when Boolean(x) is true, x && y
- // can only be simplified if x is defined. See bug 309957.
-
- int leftStatus = isAlwaysDefinedBoolean(left);
- if (leftStatus == ALWAYS_FALSE_BOOLEAN) {
- // if the first one is false, just return it
- return left;
- } else if (leftStatus == ALWAYS_TRUE_BOOLEAN) {
- // if first is true, set to second
- return right;
- }
- break;
- }
-
- case Token.OR: {
- // Since x || y gives x, not true, when Boolean(x) is true,
- // and y, not Boolean(y), when Boolean(x) is false, x || y
- // can only be simplified if x is defined. See bug 309957.
-
- int leftStatus = isAlwaysDefinedBoolean(left);
- if (leftStatus == ALWAYS_TRUE_BOOLEAN) {
- // if the first one is true, just return it
- return left;
- } else if (leftStatus == ALWAYS_FALSE_BOOLEAN) {
- // if first is false, set to second
- return right;
- }
- break;
- }
- }
-
- return new Node(nodeType, left, right);
- }
-
- private Node simpleAssignment(Node left, Node right)
- {
- int nodeType = left.getType();
- switch (nodeType) {
- case Token.NAME:
- left.setType(Token.BINDNAME);
- return new Node(Token.SETNAME, left, right);
-
- case Token.GETPROP:
- case Token.GETELEM: {
- Node obj = left.getFirstChild();
- Node id = left.getLastChild();
- int type;
- if (nodeType == Token.GETPROP) {
- type = Token.SETPROP;
- } else {
- type = Token.SETELEM;
- }
- return new Node(type, obj, id, right);
- }
- case Token.GET_REF: {
- Node ref = left.getFirstChild();
- checkMutableReference(ref);
- return new Node(Token.SET_REF, ref, right);
- }
- }
-
- throw Kit.codeBug();
- }
-
- private void checkMutableReference(Node n)
- {
- int memberTypeFlags = n.getIntProp(Node.MEMBER_TYPE_PROP, 0);
- if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {
- parser.reportError("msg.bad.assign.left");
- }
- }
-
- Node createAssignment(int assignType, Node left, Node right)
- {
- Node ref = makeReference(left);
- if (ref == null) {
- if (left.getType() == Token.ARRAYLIT ||
- left.getType() == Token.OBJECTLIT)
- {
- if (assignType != Token.ASSIGN) {
- parser.reportError("msg.bad.destruct.op");
- return right;
- }
- return createDestructuringAssignment(-1, left, right);
- }
- parser.reportError("msg.bad.assign.left");
- return right;
- }
- left = ref;
-
- int assignOp;
- switch (assignType) {
- case Token.ASSIGN:
- return simpleAssignment(left, right);
- case Token.ASSIGN_BITOR: assignOp = Token.BITOR; break;
- case Token.ASSIGN_BITXOR: assignOp = Token.BITXOR; break;
- case Token.ASSIGN_BITAND: assignOp = Token.BITAND; break;
- case Token.ASSIGN_LSH: assignOp = Token.LSH; break;
- case Token.ASSIGN_RSH: assignOp = Token.RSH; break;
- case Token.ASSIGN_URSH: assignOp = Token.URSH; break;
- case Token.ASSIGN_ADD: assignOp = Token.ADD; break;
- case Token.ASSIGN_SUB: assignOp = Token.SUB; break;
- case Token.ASSIGN_MUL: assignOp = Token.MUL; break;
- case Token.ASSIGN_DIV: assignOp = Token.DIV; break;
- case Token.ASSIGN_MOD: assignOp = Token.MOD; break;
- default: throw Kit.codeBug();
- }
-
- int nodeType = left.getType();
- switch (nodeType) {
- case Token.NAME: {
- Node op = new Node(assignOp, left, right);
- Node lvalueLeft = Node.newString(Token.BINDNAME, left.getString());
- return new Node(Token.SETNAME, lvalueLeft, op);
- }
- case Token.GETPROP:
- case Token.GETELEM: {
- Node obj = left.getFirstChild();
- Node id = left.getLastChild();
-
- int type = nodeType == Token.GETPROP
- ? Token.SETPROP_OP
- : Token.SETELEM_OP;
-
- Node opLeft = new Node(Token.USE_STACK);
- Node op = new Node(assignOp, opLeft, right);
- return new Node(type, obj, id, op);
- }
- case Token.GET_REF: {
- ref = left.getFirstChild();
- checkMutableReference(ref);
- Node opLeft = new Node(Token.USE_STACK);
- Node op = new Node(assignOp, opLeft, right);
- return new Node(Token.SET_REF_OP, ref, op);
- }
- }
-
- throw Kit.codeBug();
- }
-
- /**
- * Given a destructuring assignment with a left hand side parsed
- * as an array or object literal and a right hand side expression,
- * rewrite as a series of assignments to the variables defined in
- * left from property accesses to the expression on the right.
- * @param type declaration type: Token.VAR or Token.LET or -1
- * @param left array or object literal containing NAME nodes for
- * variables to assign
- * @param right expression to assign from
- * @return expression that performs a series of assignments to
- * the variables defined in left
- */
- Node createDestructuringAssignment(int type, Node left, Node right)
- {
- String tempName = parser.currentScriptOrFn.getNextTempName();
- Node result = destructuringAssignmentHelper(type, left, right,
- tempName);
- Node comma = result.getLastChild();
- comma.addChildToBack(createName(tempName));
- return result;
- }
-
- private Node destructuringAssignmentHelper(int variableType, Node left,
- Node right, String tempName)
- {
- Node result = createScopeNode(Token.LETEXPR,
- parser.getCurrentLineNumber());
- result.addChildToFront(new Node(Token.LET,
- createName(Token.NAME, tempName, right)));
- try {
- parser.pushScope(result);
- parser.defineSymbol(Token.LET, tempName);
- } finally {
- parser.popScope();
- }
- Node comma = new Node(Token.COMMA);
- result.addChildToBack(comma);
- final int setOp = variableType == Token.CONST ? Token.SETCONST
- : Token.SETNAME;
- List<String> destructuringNames = new ArrayList<String>();
- boolean empty = true;
- int type = left.getType();
- if (type == Token.ARRAYLIT) {
- int index = 0;
- int[] skipIndices = (int[])left.getProp(Node.SKIP_INDEXES_PROP);
- int skip = 0;
- Node n = left.getFirstChild();
- for (;;) {
- if (skipIndices != null) {
- while (skip < skipIndices.length &&
- skipIndices[skip] == index) {
- skip++;
- index++;
- }
- }
- if (n == null)
- break;
- Node rightElem = new Node(Token.GETELEM,
- createName(tempName),
- createNumber(index));
- if (n.getType() == Token.NAME) {
- String name = n.getString();
- comma.addChildToBack(new Node(setOp,
- createName(Token.BINDNAME, name, null),
- rightElem));
- if (variableType != -1) {
- parser.defineSymbol(variableType, name);
- destructuringNames.add(name);
- }
- } else {
- comma.addChildToBack(
- destructuringAssignmentHelper(variableType, n,
- rightElem,
- parser.currentScriptOrFn.getNextTempName()));
- }
- index++;
- empty = false;
- n = n.getNext();
- }
- } else if (type == Token.OBJECTLIT) {
- int index = 0;
- Object[] propertyIds = (Object[])
- left.getProp(Node.OBJECT_IDS_PROP);
- for (Node n = left.getFirstChild(); n != null; n = n.getNext())
- {
- Object id = propertyIds[index];
- Node rightElem = id instanceof String
- ? new Node(Token.GETPROP,
- createName(tempName),
- createString((String)id))
- : new Node(Token.GETELEM,
- createName(tempName),
- createNumber(((Number)id).intValue()));
- if (n.getType() == Token.NAME) {
- String name = n.getString();
- comma.addChildToBack(new Node(setOp,
- createName(Token.BINDNAME, name, null),
- rightElem));
- if (variableType != -1) {
- parser.defineSymbol(variableType, name);
- destructuringNames.add(name);
- }
- } else {
- comma.addChildToBack(
- destructuringAssignmentHelper(variableType, n,
- rightElem,
- parser.currentScriptOrFn.getNextTempName()));
- }
- index++;
- empty = false;
- }
- } else if (type == Token.GETPROP || type == Token.GETELEM) {
- comma.addChildToBack(simpleAssignment(left, createName(tempName)));
- } else {
- parser.reportError("msg.bad.assign.left");
- }
- if (empty) {
- // Don't want a COMMA node with no children. Just add a zero.
- comma.addChildToBack(createNumber(0));
- }
- result.putProp(Node.DESTRUCTURING_NAMES, destructuringNames);
- return result;
- }
-
- Node createUseLocal(Node localBlock)
- {
- if (Token.LOCAL_BLOCK != localBlock.getType()) throw Kit.codeBug();
- Node result = new Node(Token.LOCAL_LOAD);
- result.putProp(Node.LOCAL_BLOCK_PROP, localBlock);
- return result;
- }
-
- private Node.Jump makeJump(int type, Node target)
- {
- Node.Jump n = new Node.Jump(type);
- n.target = target;
- return n;
- }
-
- private Node makeReference(Node node)
- {
- int type = node.getType();
- switch (type) {
- case Token.NAME:
- case Token.GETPROP:
- case Token.GETELEM:
- case Token.GET_REF:
- return node;
- case Token.CALL:
- node.setType(Token.REF_CALL);
- return new Node(Token.GET_REF, node);
- }
- // Signal caller to report error
- return null;
- }
-
- // Check if Node always mean true or false in boolean context
- private static int isAlwaysDefinedBoolean(Node node)
- {
- switch (node.getType()) {
- case Token.FALSE:
- case Token.NULL:
- return ALWAYS_FALSE_BOOLEAN;
- case Token.TRUE:
- return ALWAYS_TRUE_BOOLEAN;
- case Token.NUMBER: {
- double num = node.getDouble();
- if (num == num && num != 0.0) {
- return ALWAYS_TRUE_BOOLEAN;
- } else {
- return ALWAYS_FALSE_BOOLEAN;
- }
- }
- }
- return 0;
- }
-
- private void checkActivationName(String name, int token)
- {
- if (parser.insideFunction()) {
- boolean activation = false;
- if ("arguments".equals(name)
- || (parser.compilerEnv.activationNames != null
- && parser.compilerEnv.activationNames.containsKey(name)))
- {
- activation = true;
- } else if ("length".equals(name)) {
- if (token == Token.GETPROP
- && parser.compilerEnv.getLanguageVersion()
- == Context.VERSION_1_2)
- {
- // Use of "length" in 1.2 requires an activation object.
- activation = true;
- }
- }
- if (activation) {
- setRequiresActivation();
- }
- }
- }
-
- private void setRequiresActivation()
- {
- if (parser.insideFunction()) {
- ((FunctionNode)parser.currentScriptOrFn).itsNeedsActivation = true;
- }
- }
-
- private void setIsGenerator()
- {
- if (parser.insideFunction()) {
- ((FunctionNode)parser.currentScriptOrFn).itsIsGenerator = true;
- }
- }
-
- private Parser parser;
-
- private static final int LOOP_DO_WHILE = 0;
- private static final int LOOP_WHILE = 1;
- private static final int LOOP_FOR = 2;
-
- private static final int ALWAYS_TRUE_BOOLEAN = 1;
- private static final int ALWAYS_FALSE_BOOLEAN = -1;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionCall.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionCall.java
deleted file mode 100644
index 713fabf..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionCall.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- 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):
- * 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;
-
-/**
- * Master for id-based functions that knows their properties and how to
- * execute them.
- */
-public interface IdFunctionCall
-{
- /**
- * 'thisObj' will be null if invoked as constructor, in which case
- * instance of Scriptable should be returned
- */
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args);
-
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionObject.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionObject.java
deleted file mode 100644
index c578dfa..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionObject.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/* -*- 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):
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-public class IdFunctionObject extends BaseFunction
-{
-
- static final long serialVersionUID = -5332312783643935019L;
-
- public IdFunctionObject(IdFunctionCall idcall, Object tag, int id, int arity)
- {
- if (arity < 0)
- throw new IllegalArgumentException();
-
- this.idcall = idcall;
- this.tag = tag;
- this.methodId = id;
- this.arity = arity;
- if (arity < 0) throw new IllegalArgumentException();
- }
-
- public IdFunctionObject(IdFunctionCall idcall, Object tag, int id,
- String name, int arity, Scriptable scope)
- {
- super(scope, null);
-
- if (arity < 0)
- throw new IllegalArgumentException();
- if (name == null)
- throw new IllegalArgumentException();
-
- this.idcall = idcall;
- this.tag = tag;
- this.methodId = id;
- this.arity = arity;
- this.functionName = name;
- }
-
- public void initFunction(String name, Scriptable scope)
- {
- if (name == null) throw new IllegalArgumentException();
- if (scope == null) throw new IllegalArgumentException();
- this.functionName = name;
- 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)
- {
- ScriptableObject.defineProperty(target, functionName, this,
- ScriptableObject.DONTENUM);
- }
-
- public void exportAsScopeProperty()
- {
- addAsProperty(getParentScope());
- }
-
- 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)
- {
- return idcall.execIdCall(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 (idcall instanceof Scriptable) {
- Scriptable sobj = (Scriptable)idcall;
- sb.append(sobj.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 String getFunctionName()
- {
- return (functionName == null) ? "" : functionName;
- }
-
- public final RuntimeException unknown()
- {
- // It is program error to call id-like methods for unknown function
- return new IllegalArgumentException(
- "BAD FUNCTION ID="+methodId+" MASTER="+idcall);
- }
-
- private final IdFunctionCall idcall;
- private final Object tag;
- private final int methodId;
- private int arity;
- private boolean useCallAsConstructor;
- private String functionName;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdScriptableObject.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdScriptableObject.java
deleted file mode 100644
index 2b3ecf3..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdScriptableObject.java
+++ /dev/null
@@ -1,734 +0,0 @@
-/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; 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):
- * 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;
-
-import java.io.*;
-
-/**
-Base class for native object implementation that uses IdFunctionObject to export its methods to script via <class-name>.prototype object.
-
-Any descendant should implement at least the following methods:
- findInstanceIdInfo
- getInstanceIdName
- execIdCall
- methodArity
-
-To define non-function properties, the descendant should override
- getInstanceIdValue
- setInstanceIdValue
-to get/set property value and provide its default attributes.
-
-
-To customize initializition of constructor and protype objects, descendant
-may override scopeInit or fillConstructorProperties methods.
-
-*/
-public abstract class IdScriptableObject extends ScriptableObject
- implements IdFunctionCall
-{
- private transient volatile PrototypeValues prototypeValues;
-
- private static final class PrototypeValues implements Serializable
- {
- static final long serialVersionUID = 3038645279153854371L;
-
- private static final int VALUE_SLOT = 0;
- private static final int NAME_SLOT = 1;
- private static final int SLOT_SPAN = 2;
-
- private IdScriptableObject obj;
- 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 IdFunctionObject constructor;
- private short constructorAttrs;
-
- PrototypeValues(IdScriptableObject obj, int maxId)
- {
- if (obj == null) throw new IllegalArgumentException();
- if (maxId < 1) throw new IllegalArgumentException();
- this.obj = obj;
- this.maxId = maxId;
- }
-
- final int getMaxId()
- {
- return 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 IdFunctionObject)) {
- throw new IllegalArgumentException("consructor should be initialized with IdFunctionObject");
- }
- constructor = (IdFunctionObject)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 IdFunctionObject 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];
- }
- 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 IdScriptableObject()
- {
- }
-
- public IdScriptableObject(Scriptable scope, Scriptable prototype)
- {
- super(scope, prototype);
- }
-
- protected final Object defaultGet(String name)
- {
- return super.get(name, this);
- }
-
- protected final void defaultPut(String name, Object value)
- {
- super.put(name, this, value);
- }
-
- public boolean has(String name, Scriptable start)
- {
- 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 prototypeValues.has(id);
- }
- }
- return super.has(name, start);
- }
-
- public Object get(String name, Scriptable start)
- {
- 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) {
- return prototypeValues.get(id);
- }
- }
- return super.get(name, start);
- }
-
- public void put(String name, Scriptable start, Object value)
- {
- int info = findInstanceIdInfo(name);
- if (info != 0) {
- if (start == this && isSealed()) {
- throw Context.reportRuntimeError1("msg.modify.sealed",
- name);
- }
- int attr = (info >>> 16);
- if ((attr & READONLY) == 0) {
- if (start == this) {
- int id = (info & 0xFFFF);
- setInstanceIdValue(id, value);
- }
- else {
- start.put(name, start, value);
- }
- }
- 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)
- {
- int info = findInstanceIdInfo(name);
- if (info != 0) {
- // Let the super class to throw exceptions for sealed objects
- if (!isSealed()) {
- int attr = (info >>> 16);
- if ((attr & PERMANENT) == 0) {
- 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)
- {
- int info = findInstanceIdInfo(name);
- if (info != 0) {
- int attr = (info >>> 16);
- return attr;
- }
- if (prototypeValues != null) {
- int id = prototypeValues.findId(name);
- if (id != 0) {
- return prototypeValues.getAttributes(id);
- }
- }
- return super.getAttributes(name);
- }
-
- public void setAttributes(String name, int attributes)
- {
- ScriptableObject.checkValidAttributes(attributes);
- 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");
- }
- return;
- }
- 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 (prototypeValues != null) {
- result = prototypeValues.getNames(getAll, result);
- }
-
- int maxInstanceId = getMaxInstanceId();
- if (maxInstanceId != 0) {
- Object[] ids = null;
- int count = 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++] = name;
- }
- }
- }
- if (count != 0) {
- if (result.length == 0 && ids.length == count) {
- result = ids;
- }
- else {
- Object[] tmp = new Object[result.length + count];
- System.arraycopy(result, 0, tmp, 0, result.length);
- System.arraycopy(ids, 0, tmp, result.length, count);
- result = tmp;
- }
- }
- }
- return result;
- }
-
- /**
- * Get maximum id findInstanceIdInfo can generate.
- */
- protected int getMaxInstanceId()
- {
- return 0;
- }
-
- 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 getInstanceIdName(int id)
- {
- throw new IllegalArgumentException(String.valueOf(id));
- }
-
- /** Get id value.
- ** If id value is constant, descendant can call cacheIdValue to store
- ** value in the permanent cache.
- ** Default implementation creates IdFunctionObject instance for given id
- ** and cache its value
- */
- protected Object getInstanceIdValue(int id)
- {
- throw new IllegalStateException(String.valueOf(id));
- }
-
- /**
- * Set or delete id value. If value == NOT_FOUND , the implementation
- * should make sure that the following getInstanceIdValue return NOT_FOUND.
- */
- protected void setInstanceIdValue(int id, Object value)
- {
- throw new IllegalStateException(String.valueOf(id));
- }
-
- /** 'thisObj' will be null if invoked as constructor, in which case
- ** instance of Scriptable should be returned. */
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- throw f.unknown();
- }
-
- public final IdFunctionObject exportAsJSClass(int maxPrototypeId,
- Scriptable scope,
- boolean sealed)
- {
- // Set scope and prototype unless this is top level scope itself
- if (scope != this && scope != null) {
- setParentScope(scope);
- setPrototype(getObjectPrototype(scope));
- }
-
- activatePrototypeMap(maxPrototypeId);
- IdFunctionObject ctor = prototypeValues.createPrecachedConstructor();
- if (sealed) {
- sealObject();
- }
- fillConstructorProperties(ctor);
- if (sealed) {
- ctor.sealObject();
- }
- ctor.exportAsScopeProperty();
- return ctor;
- }
-
- 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);
- IdFunctionObject f = newIdFunction(tag, id, name, arity, scope);
- prototypeValues.initValue(id, name, f, DONTENUM);
- }
-
- public final void initPrototypeConstructor(IdFunctionObject 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(IdFunctionObject ctor)
- {
- }
-
- protected void addIdFunctionProperty(Scriptable obj, Object tag, int id,
- String name, int arity)
- {
- Scriptable scope = ScriptableObject.getTopLevelScope(obj);
- IdFunctionObject f = newIdFunction(tag, id, name, arity, scope);
- f.addAsProperty(obj);
- }
-
- /**
- * Utility method to construct type error to indicate incompatible call
- * when converting script thisObj to a particular type is not possible.
- * Possible usage would be to have a private function like realThis:
- * <pre>
- * private static NativeSomething realThis(Scriptable thisObj,
- * IdFunctionObject f)
- * {
- * if (!(thisObj instanceof NativeSomething))
- * throw incompatibleCallError(f);
- * return (NativeSomething)thisObj;
- * }
- * </pre>
- * Note that although such function can be implemented universally via
- * java.lang.Class.isInstance(), it would be much more slower.
- * @param f function that is attempting to convert 'this'
- * object.
- * @return Scriptable object suitable for a check by the instanceof
- * operator.
- * @throws RuntimeException if no more instanceof target can be found
- */
- protected static EcmaError incompatibleCallError(IdFunctionObject f)
- {
- throw ScriptRuntime.typeError1("msg.incompat.call",
- f.getFunctionName());
- }
-
- private IdFunctionObject newIdFunction(Object tag, int id, String name,
- int arity, Scriptable scope)
- {
- IdFunctionObject f = new IdFunctionObject(this, tag, id, name, arity,
- scope);
- if (isSealed()) { f.sealObject(); }
- return f;
- }
-
- private void readObject(ObjectInputStream stream)
- throws IOException, ClassNotFoundException
- {
- stream.defaultReadObject();
- int maxPrototypeId = stream.readInt();
- if (maxPrototypeId != 0) {
- activatePrototypeMap(maxPrototypeId);
- }
- }
-
- private void writeObject(ObjectOutputStream stream)
- throws IOException
- {
- stream.defaultWriteObject();
- int maxPrototypeId = 0;
- if (prototypeValues != null) {
- maxPrototypeId = prototypeValues.getMaxId();
- }
- stream.writeInt(maxPrototypeId);
- }
-
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ImporterTopLevel.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ImporterTopLevel.java
deleted file mode 100644
index 294deab..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ImporterTopLevel.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/* -*- 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) 1999
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- * Igor Bukanov
- * Matthias Radestock
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * Class ImporterTopLevel
- *
- * This class defines a ScriptableObject that can be instantiated
- * as a top-level ("global") object to provide functionality similar
- * to Java's "import" statement.
- * <p>
- * This class can be used to create a top-level scope using the following code:
- * <pre>
- * Scriptable scope = new ImporterTopLevel(cx);
- * </pre>
- * Then JavaScript code will have access to the following methods:
- * <ul>
- * <li>importClass - will "import" a class by making its unqualified name
- * available as a property of the top-level scope
- * <li>importPackage - will "import" all the classes of the package by
- * searching for unqualified names as classes qualified
- * by the given package.
- * </ul>
- * The following code from the shell illustrates this use:
- * <pre>
- * js> importClass(java.io.File)
- * js> f = new File('help.txt')
- * help.txt
- * js> importPackage(java.util)
- * js> v = new Vector()
- * []
- *
- * @author Norris Boyd
- */
-public class ImporterTopLevel extends IdScriptableObject
-{
- static final long serialVersionUID = -9095380847465315412L;
-
- private static final Object IMPORTER_TAG = new Object();
-
- public ImporterTopLevel() { }
-
- public ImporterTopLevel(Context cx) {
- this(cx, false);
- }
-
- public ImporterTopLevel(Context cx, boolean sealed)
- {
- initStandardObjects(cx, sealed);
- }
-
- public String getClassName()
- {
- return (topScopeFlag) ? "global" : "JavaImporter";
- }
-
- public static void init(Context cx, Scriptable scope, boolean sealed)
- {
- ImporterTopLevel obj = new ImporterTopLevel();
- 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);
- topScopeFlag = true;
- // 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.
- IdFunctionObject 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.
- delete("constructor");
- }
-
- public boolean has(String name, Scriptable start) {
- return super.has(name, start)
- || getPackageProperty(name, start) != NOT_FOUND;
- }
-
- public Object get(String name, Scriptable start) {
- Object result = super.get(name, start);
- if (result != NOT_FOUND)
- return result;
- result = getPackageProperty(name, start);
- return result;
- }
-
- private Object getPackageProperty(String name, Scriptable start) {
- Object result = NOT_FOUND;
- Object[] elements;
- synchronized (importedPackages) {
- elements = importedPackages.toArray();
- }
- for (int i=0; i < elements.length; i++) {
- NativeJavaPackage p = (NativeJavaPackage) elements[i];
- Object v = p.getPkgProperty(name, start, false);
- if (v != null && !(v instanceof NativeJavaPackage)) {
- if (result == NOT_FOUND) {
- result = v;
- } else {
- throw Context.reportRuntimeError2(
- "msg.ambig.import", result.toString(), v.toString());
- }
- }
- }
- return result;
- }
-
- /**
- * @deprecated Kept only for compatibility.
- */
- public void importPackage(Context cx, Scriptable thisObj, Object[] args,
- Function funObj)
- {
- js_importPackage(args);
- }
-
- private Object js_construct(Scriptable scope, Object[] args)
- {
- ImporterTopLevel result = new ImporterTopLevel();
- for (int i = 0; i != args.length; ++i) {
- Object arg = args[i];
- if (arg instanceof NativeJavaClass) {
- result.importClass((NativeJavaClass)arg);
- } else if (arg instanceof NativeJavaPackage) {
- result.importPackage((NativeJavaPackage)arg);
- } else {
- throw Context.reportRuntimeError1(
- "msg.not.class.not.pkg", Context.toString(arg));
- }
- }
- // set explicitly prototype and scope
- // 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.
- result.setParentScope(scope);
- result.setPrototype(this);
- return result;
- }
-
- private Object js_importClass(Object[] args)
- {
- for (int i = 0; i != args.length; i++) {
- Object arg = args[i];
- if (!(arg instanceof NativeJavaClass)) {
- throw Context.reportRuntimeError1(
- "msg.not.class", Context.toString(arg));
- }
- importClass((NativeJavaClass)arg);
- }
- return Undefined.instance;
- }
-
- private Object js_importPackage(Object[] args)
- {
- for (int i = 0; i != args.length; i++) {
- Object arg = args[i];
- if (!(arg instanceof NativeJavaPackage)) {
- throw Context.reportRuntimeError1(
- "msg.not.pkg", Context.toString(arg));
- }
- importPackage((NativeJavaPackage)arg);
- }
- return Undefined.instance;
- }
-
- private void importPackage(NativeJavaPackage pkg)
- {
- if(pkg == null) {
- return;
- }
- synchronized (importedPackages) {
- for (int j = 0; j != importedPackages.size(); j++) {
- if (pkg.equals(importedPackages.get(j))) {
- return;
- }
- }
- importedPackages.add(pkg);
- }
- }
-
- private void importClass(NativeJavaClass cl)
- {
- String s = cl.getClassObject().getName();
- String n = s.substring(s.lastIndexOf('.')+1);
- Object val = get(n, this);
- if (val != NOT_FOUND && val != cl) {
- throw Context.reportRuntimeError1("msg.prop.defined", n);
- }
- //defineProperty(n, cl, DONTENUM);
- 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 execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(IMPORTER_TAG)) {
- return super.execIdCall(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 ImporterTopLevel realThis(Scriptable thisObj, IdFunctionObject f)
- {
- if (topScopeFlag) {
- // when used as top scope importPackage and importClass are global
- // function that ignore thisObj
- return this;
- }
- if (!(thisObj instanceof ImporterTopLevel))
- throw incompatibleCallError(f);
- return (ImporterTopLevel)thisObj;
- }
-
-// #string_id_map#
-
- protected int findPrototypeId(String s)
- {
- int id;
-// #generated# Last update: 2007-05-09 08:15:24 EDT
- L0: { id = 0; String X = null; int c;
- int s_length = s.length();
- if (s_length==11) {
- c=s.charAt(0);
- if (c=='c') { X="constructor";id=Id_constructor; }
- else if (c=='i') { X="importClass";id=Id_importClass; }
- }
- else if (s_length==13) { X="importPackage";id=Id_importPackage; }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- Id_constructor = 1,
- Id_importClass = 2,
- Id_importPackage = 3,
- MAX_PROTOTYPE_ID = 3;
-
-// #/string_id_map#
-
- private ObjArray importedPackages = new ObjArray();
- private boolean topScopeFlag;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InformativeParser.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InformativeParser.java
deleted file mode 100644
index c73db34..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InformativeParser.java
+++ /dev/null
@@ -1,225 +0,0 @@
-package org.mozilla.javascript;
-
-import java.io.IOException;
-
-/**
- * Subclass of Rhino's Parser that saves information about the token stream
- * and error message to allow more helpful error messages.
- *
- * @author David Greenspan for AppJet
- */
-
-/*
- This class is written with speed in mind, to some extent. Rhino's tokenizer
- is pretty efficient, and we wouldn't want to slow it down by, for example,
- creating a TokenInfo object on the heap for every token seen.
- */
-
-/*APPJET*/
-public class InformativeParser extends Parser {
-
- public static class InformativeEvaluatorException extends EvaluatorException {
- final ParseErrorInfo pei;
-
- InformativeEvaluatorException(String errorMessage,
- String sourceName, int lineNumber,
- String lineSource, int columnNumber,
- ParseErrorInfo peInfo) {
- super(errorMessage, sourceName,
- lineNumber, lineSource, columnNumber);
- pei = peInfo;
- }
-
- public ParseErrorInfo getParseErrorInfo() {
- return pei;
- }
- }
-
- public static class ParseErrorInfo {
- ParseErrorInfo() {}
-
- String messageId = null;
- String messageArg = null;
-
- final int tokenMaxHistory = 10;
- // ring buffers
- final int[] tokenTypes = new int[tokenMaxHistory];
- final String[] tokenStrings = new String[tokenMaxHistory];
- final double[] tokenNumbers = new double[tokenMaxHistory];
- final int[] tokenLineNumbers = new int[tokenMaxHistory];
- final int[] tokenLineOffsets = new int[tokenMaxHistory];
- int nextBufPos = 0;
- int historyLength = 0;
- boolean tokenPeeking = false;
- int peekSlot;
-
- void reportPeekToken(int type, String str, double num, int lineno,
- int lineOffset) {
- if (! tokenPeeking) {
- peekSlot = nextBufPos;
- tokenTypes[nextBufPos] = type;
- tokenStrings[nextBufPos] = str;
- tokenNumbers[nextBufPos] = num;
- tokenLineNumbers[nextBufPos] = lineno;
- tokenLineOffsets[nextBufPos] = lineOffset;
-
- nextBufPos++;
- if (nextBufPos == tokenMaxHistory) nextBufPos = 0;
- if (historyLength < tokenMaxHistory) historyLength++;
- tokenPeeking = true;
- }
- }
-
- void reportConsumeToken() {
- tokenPeeking = false;
- }
-
- private TokenInfo backToken(int n) {
- // 0 is most recent token added to history
- if (n >= historyLength) return null;
- int i = (nextBufPos - 1 - n);
- while (i < 0) i += tokenMaxHistory;
- return new TokenInfo(tokenTypes[i], tokenStrings[i],
- tokenNumbers[i], tokenLineNumbers[i],
- tokenLineOffsets[i]);
- }
-
- public String getMessageId() { return messageId; }
- public String getMessageArg() { return messageArg; }
- public TokenInfo getPeekToken() {
- if (tokenPeeking) return backToken(0);
- return null;
- }
- public TokenInfo getPrevToken(int n) {
- // 1 = last non-peek token seen, 2 = before that, etc.
- if (! tokenPeeking) n--;
- return backToken(n);
- }
- public TokenInfo getPrevToken() {
- return getPrevToken(1);
- }
- }
-
- public static class TokenInfo {
- private int type, lineno, lineOffset;
- private String str;
- private double num;
- TokenInfo(int type, String str, double num, int lineno,
- int lineOffset) {
- this.type = type; this.str = str; this.num = num;
- this.lineno = lineno; this.lineOffset = lineOffset;
- }
- public int getType() { return type; }
- public int getLineNumber() { return lineno; }
- public int getLineOffset() { return lineOffset; }
- public double getNumber() { return num; }
- public String getString() { return str; }
- }
-
- ParseErrorInfo info = new ParseErrorInfo();
-
- void doErrorReporterError(String message, String sourceURI, int line,
- String lineText, int lineOffset) {
-
- throw new InformativeEvaluatorException(message, sourceURI, line,
- lineText, lineOffset, info);
-
- }
-
- public InformativeParser(CompilerEnvirons compilerEnv) {
- // we override most calls to the parent's ErrorReporter anyway
- super(compilerEnv, DefaultErrorReporter.instance);
- }
-
- @Override int peekToken() throws IOException {
- int tt = super.peekToken();
- info.reportPeekToken(tt, ts.getString(), ts.getNumber(),
- ts.getLineno(), ts.getOffset());
- return tt;
- }
- @Override void consumeToken() {
- super.consumeToken();
- info.reportConsumeToken();
- }
-
- @Override void addWarning(String messageId, String messageArg)
- {
- info.messageId = messageId;
- info.messageArg = messageArg;
-
- String message = ScriptRuntime.getMessage1(messageId, messageArg);
- if (compilerEnv.reportWarningAsError()) {
- ++syntaxErrorCount;
- doErrorReporterError(message, sourceURI, ts.getLineno(),
- ts.getLine(), ts.getOffset());
- }
- else { /* don't report */ }
- }
-
- @Override void addError(String messageId)
- {
- info.messageId = messageId;
-
- ++syntaxErrorCount;
- String message = ScriptRuntime.getMessage0(messageId);
- doErrorReporterError(message, sourceURI, ts.getLineno(),
- ts.getLine(), ts.getOffset());
- }
-
- @Override void addError(String messageId, String messageArg)
- {
- info.messageId = messageId;
- info.messageArg = messageArg;
-
- ++syntaxErrorCount;
- String message = ScriptRuntime.getMessage1(messageId, messageArg);
- doErrorReporterError(message, sourceURI, ts.getLineno(),
- ts.getLine(), ts.getOffset());
- }
-
- @Override protected Decompiler createDecompiler(CompilerEnvirons env) {
- return new MyDecompiler();
- }
-
- public static final ErrorReporter THROW_INFORMATIVE_ERRORS
- = new ErrorReporter() {
- public void warning(String message, String sourceURI, int line,
- String lineText, int lineOffset) {
- DefaultErrorReporter.instance.warning
- (message, sourceURI, line, lineText, lineOffset);
- }
- public void error(String message, String sourceURI, int line,
- String lineText, int lineOffset) {
- DefaultErrorReporter.instance.error
- (message, sourceURI, line, lineText, lineOffset);
- }
- public EvaluatorException runtimeError(String message,
- String sourceURI,
- int line, String lineText,
- int lineOffset) {
- return DefaultErrorReporter.instance.runtimeError
- (message, sourceURI, line, lineText, lineOffset);
- }
-
- };
-
- public static Parser makeParser(CompilerEnvirons compilerEnv,
- ErrorReporter errorReporter) {
- if (errorReporter == THROW_INFORMATIVE_ERRORS) {
- return new InformativeParser(compilerEnv);
- }
- else {
- return new Parser(compilerEnv, errorReporter);
- }
- }
-
- private class MyDecompiler extends Decompiler {
- @Override void addRegexp(String regexp, String flags) {
- super.addRegexp(regexp, flags);
- String str = '/'+regexp+'/'+flags;
- info.reportPeekToken(Token.REGEXP, str, ts.getNumber(),
- ts.getLineno(), ts.getOffset());
- info.reportConsumeToken();
- }
- }
-} \ No newline at end of file
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterfaceAdapter.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterfaceAdapter.java
deleted file mode 100644
index 877e6a2..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterfaceAdapter.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/* -*- 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):
- * 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;
-
-import java.lang.reflect.Method;
-
-/**
- * Adapter to use JS function as implementation of Java interfaces with
- * single method or multiple methods with the same signature.
- */
-public class InterfaceAdapter
-{
- private final Object proxyHelper;
-
- /**
- * Make glue object implementing interface cl that will
- * call the supplied JS function when called.
- * Only interfaces were all methods have the same signature is supported.
- *
- * @return The glue object or null if <tt>cl</tt> is not interface or
- * has methods with different signatures.
- */
- static Object create(Context cx, Class cl, Callable function)
- {
- if (!cl.isInterface()) throw new IllegalArgumentException();
-
- Scriptable topScope = ScriptRuntime.getTopCallScope(cx);
- ClassCache cache = ClassCache.get(topScope);
- InterfaceAdapter adapter;
- adapter = (InterfaceAdapter)cache.getInterfaceAdapter(cl);
- ContextFactory cf = cx.getFactory();
- if (adapter == null) {
- Method[] methods = cl.getMethods();
- if (methods.length == 0) {
- throw Context.reportRuntimeError2(
- "msg.no.empty.interface.conversion",
- String.valueOf(function),
- cl.getClass().getName());
- }
- boolean canCallFunction = false;
- canCallFunctionChecks: {
- Class[] argTypes = methods[0].getParameterTypes();
- // check that the rest of methods has the same signature
- for (int i = 1; i != methods.length; ++i) {
- Class[] types2 = methods[i].getParameterTypes();
- if (types2.length != argTypes.length) {
- break canCallFunctionChecks;
- }
- for (int j = 0; j != argTypes.length; ++j) {
- if (types2[j] != argTypes[j]) {
- break canCallFunctionChecks;
- }
- }
- }
- canCallFunction= true;
- }
- if (!canCallFunction) {
- throw Context.reportRuntimeError2(
- "msg.no.function.interface.conversion",
- String.valueOf(function),
- cl.getClass().getName());
- }
- adapter = new InterfaceAdapter(cf, cl);
- cache.cacheInterfaceAdapter(cl, adapter);
- }
- return VMBridge.instance.newInterfaceProxy(
- adapter.proxyHelper, cf, adapter, function, topScope);
- }
-
- private InterfaceAdapter(ContextFactory cf, Class cl)
- {
- this.proxyHelper
- = VMBridge.instance.getInterfaceProxyHelper(
- cf, new Class[] { cl });
- }
-
- public Object invoke(ContextFactory cf,
- final Object target,
- final Scriptable topScope,
- final Method method,
- final Object[] args)
- {
- ContextAction action = new ContextAction() {
- public Object run(Context cx)
- {
- return invokeImpl(cx, target, topScope, method, args);
- }
- };
- return cf.call(action);
- }
-
- Object invokeImpl(Context cx,
- Object target,
- Scriptable topScope,
- Method method,
- Object[] args)
- {
- int N = (args == null) ? 0 : args.length;
-
- Callable function = (Callable)target;
- Scriptable thisObj = topScope;
- Object[] jsargs = new Object[N + 1];
- jsargs[N] = method.getName();
- if (N != 0) {
- WrapFactory wf = cx.getWrapFactory();
- for (int i = 0; i != N; ++i) {
- jsargs[i] = wf.wrap(cx, topScope, args[i], null);
- }
- }
-
- Object result = function.call(cx, topScope, thisObj, jsargs);
- Class javaResultType = method.getReturnType();
- if (javaResultType == Void.TYPE) {
- result = null;
- } else {
- result = Context.jsToJava(result, javaResultType);
- }
- return result;
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpretedFunction.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpretedFunction.java
deleted file mode 100644
index db84299..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpretedFunction.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Igor Bukanov
- * Bob Jervis
- * Roger Lawrence
- *
- * 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;
-
-import org.mozilla.javascript.debug.DebuggableScript;
-
-final class InterpretedFunction extends NativeFunction implements Script
-{
- static final long serialVersionUID = 541475680333911468L;
-
- InterpreterData idata;
- SecurityController securityController;
- Object securityDomain;
- Scriptable[] functionRegExps;
-
- private InterpretedFunction(InterpreterData idata,
- Object staticSecurityDomain)
- {
- this.idata = idata;
-
- // Always get Context from the current thread to
- // avoid security breaches via passing mangled Context instances
- // with bogus SecurityController
- Context cx = Context.getContext();
- SecurityController sc = cx.getSecurityController();
- Object dynamicDomain;
- if (sc != null) {
- dynamicDomain = sc.getDynamicSecurityDomain(staticSecurityDomain);
- } else {
- if (staticSecurityDomain != null) {
- throw new IllegalArgumentException();
- }
- dynamicDomain = null;
- }
-
- this.securityController = sc;
- this.securityDomain = dynamicDomain;
- }
-
- private InterpretedFunction(InterpretedFunction parent, int index)
- {
- this.idata = parent.idata.itsNestedFunctions[index];
- this.securityController = parent.securityController;
- this.securityDomain = parent.securityDomain;
- }
-
- /**
- * Create script from compiled bytecode.
- */
- static InterpretedFunction createScript(InterpreterData idata,
- Object staticSecurityDomain)
- {
- InterpretedFunction f;
- f = new InterpretedFunction(idata, staticSecurityDomain);
- return f;
- }
-
- /**
- * Create function compiled from Function(...) constructor.
- */
- static InterpretedFunction createFunction(Context cx,Scriptable scope,
- InterpreterData idata,
- Object staticSecurityDomain)
- {
- InterpretedFunction f;
- f = new InterpretedFunction(idata, staticSecurityDomain);
- f.initInterpretedFunction(cx, scope);
- return f;
- }
-
- /**
- * Create function embedded in script or another function.
- */
- static InterpretedFunction createFunction(Context cx, Scriptable scope,
- InterpretedFunction parent,
- int index)
- {
- InterpretedFunction f = new InterpretedFunction(parent, index);
- f.initInterpretedFunction(cx, scope);
- return f;
- }
-
- Scriptable[] createRegExpWraps(Context cx, Scriptable scope)
- {
- if (idata.itsRegExpLiterals == null) Kit.codeBug();
-
- RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx);
- int N = idata.itsRegExpLiterals.length;
- Scriptable[] array = new Scriptable[N];
- for (int i = 0; i != N; ++i) {
- array[i] = rep.wrapRegExp(cx, scope, idata.itsRegExpLiterals[i]);
- }
- return array;
- }
-
- private void initInterpretedFunction(Context cx, Scriptable scope)
- {
- initScriptFunction(cx, scope);
- if (idata.itsRegExpLiterals != null) {
- functionRegExps = createRegExpWraps(cx, scope);
- }
- }
-
- public String getFunctionName()
- {
- return (idata.itsName == null) ? "" : idata.itsName;
- }
-
- /**
- * Calls the function.
- * @param cx the current context
- * @param scope the scope used for the call
- * @param thisObj the value of "this"
- * @param args function arguments. Must not be null. You can use
- * {@link ScriptRuntime#emptyArgs} to pass empty arguments.
- * @return the result of the function call.
- */
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- if (!ScriptRuntime.hasTopCall(cx)) {
- return ScriptRuntime.doTopCall(this, cx, scope, thisObj, args);
- }
- return Interpreter.interpret(this, cx, scope, thisObj, args);
- }
-
- public Object exec(Context cx, Scriptable scope)
- {
- if (idata.itsFunctionType != 0) {
- // Can only be applied to scripts
- throw new IllegalStateException();
- }
- if (!ScriptRuntime.hasTopCall(cx)) {
- // It will go through "call" path. but they are equivalent
- return ScriptRuntime.doTopCall(
- this, cx, scope, scope, ScriptRuntime.emptyArgs);
- }
- return Interpreter.interpret(
- this, cx, scope, scope, ScriptRuntime.emptyArgs);
- }
-
- public String getEncodedSource()
- {
- return Interpreter.getEncodedSource(idata);
- }
-
- public DebuggableScript getDebuggableView()
- {
- return idata;
- }
-
- public Object resumeGenerator(Context cx, Scriptable scope, int operation,
- Object state, Object value)
- {
- return Interpreter.resumeGenerator(cx, scope, operation, state, value);
- }
-
- protected int getLanguageVersion()
- {
- return idata.languageVersion;
- }
-
- protected int getParamCount()
- {
- return idata.argCount;
- }
-
- protected int getParamAndVarCount()
- {
- return idata.argNames.length;
- }
-
- protected String getParamOrVarName(int index)
- {
- return idata.argNames[index];
- }
-
- protected boolean getParamOrVarConst(int index)
- {
- return idata.argIsConst[index];
- }
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Interpreter.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Interpreter.java
deleted file mode 100644
index a68c025..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Interpreter.java
+++ /dev/null
@@ -1,4643 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Beard
- * Norris Boyd
- * Igor Bukanov
- * Ethan Hugg
- * Bob Jervis
- * Terry Lucas
- * Roger Lawrence
- * Milen Nankov
- * Hannes Wallnoefer
- *
- * 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;
-
-import java.io.PrintStream;
-import java.io.Serializable;
-import java.util.List;
-import java.util.ArrayList;
-
-import org.mozilla.javascript.continuations.Continuation;
-import org.mozilla.javascript.debug.DebugFrame;
-
-public class Interpreter implements Evaluator
-{
-
-// Additional interpreter-specific codes
-
- private static final int
-
- // Stack: ... value1 -> ... value1 value1
- Icode_DUP = -1,
-
- // Stack: ... value2 value1 -> ... value2 value1 value2 value1
- Icode_DUP2 = -2,
-
- // Stack: ... value2 value1 -> ... value1 value2
- Icode_SWAP = -3,
-
- // Stack: ... value1 -> ...
- Icode_POP = -4,
-
- // Store stack top into return register and then pop it
- Icode_POP_RESULT = -5,
-
- // To jump conditionally and pop additional stack value
- Icode_IFEQ_POP = -6,
-
- // various types of ++/--
- Icode_VAR_INC_DEC = -7,
- Icode_NAME_INC_DEC = -8,
- Icode_PROP_INC_DEC = -9,
- Icode_ELEM_INC_DEC = -10,
- Icode_REF_INC_DEC = -11,
-
- // load/save scope from/to local
- Icode_SCOPE_LOAD = -12,
- Icode_SCOPE_SAVE = -13,
-
- Icode_TYPEOFNAME = -14,
-
- // helper for function calls
- Icode_NAME_AND_THIS = -15,
- Icode_PROP_AND_THIS = -16,
- Icode_ELEM_AND_THIS = -17,
- Icode_VALUE_AND_THIS = -18,
-
- // Create closure object for nested functions
- Icode_CLOSURE_EXPR = -19,
- Icode_CLOSURE_STMT = -20,
-
- // Special calls
- Icode_CALLSPECIAL = -21,
-
- // To return undefined value
- Icode_RETUNDEF = -22,
-
- // Exception handling implementation
- Icode_GOSUB = -23,
- Icode_STARTSUB = -24,
- Icode_RETSUB = -25,
-
- // To indicating a line number change in icodes.
- Icode_LINE = -26,
-
- // To store shorts and ints inline
- Icode_SHORTNUMBER = -27,
- Icode_INTNUMBER = -28,
-
- // To create and populate array to hold values for [] and {} literals
- Icode_LITERAL_NEW = -29,
- Icode_LITERAL_SET = -30,
-
- // Array literal with skipped index like [1,,2]
- Icode_SPARE_ARRAYLIT = -31,
-
- // Load index register to prepare for the following index operation
- Icode_REG_IND_C0 = -32,
- Icode_REG_IND_C1 = -33,
- Icode_REG_IND_C2 = -34,
- Icode_REG_IND_C3 = -35,
- Icode_REG_IND_C4 = -36,
- Icode_REG_IND_C5 = -37,
- Icode_REG_IND1 = -38,
- Icode_REG_IND2 = -39,
- Icode_REG_IND4 = -40,
-
- // Load string register to prepare for the following string operation
- Icode_REG_STR_C0 = -41,
- Icode_REG_STR_C1 = -42,
- Icode_REG_STR_C2 = -43,
- Icode_REG_STR_C3 = -44,
- Icode_REG_STR1 = -45,
- Icode_REG_STR2 = -46,
- Icode_REG_STR4 = -47,
-
- // Version of getvar/setvar that read var index directly from bytecode
- Icode_GETVAR1 = -48,
- Icode_SETVAR1 = -49,
-
- // Load unefined
- Icode_UNDEF = -50,
- Icode_ZERO = -51,
- Icode_ONE = -52,
-
- // entrance and exit from .()
- Icode_ENTERDQ = -53,
- Icode_LEAVEDQ = -54,
-
- Icode_TAIL_CALL = -55,
-
- // Clear local to allow GC its context
- Icode_LOCAL_CLEAR = -56,
-
- // Literal get/set
- Icode_LITERAL_GETTER = -57,
- Icode_LITERAL_SETTER = -58,
-
- // const
- Icode_SETCONST = -59,
- Icode_SETCONSTVAR = -60,
- Icode_SETCONSTVAR1 = -61,
-
- // Generator opcodes (along with Token.YIELD)
- Icode_GENERATOR = -62,
- Icode_GENERATOR_END = -63,
-
- Icode_DEBUGGER = -64,
-
- // Last icode
- MIN_ICODE = -64;
-
- // data for parsing
-
- private CompilerEnvirons compilerEnv;
-
- private boolean itsInFunctionFlag;
- private boolean itsInTryFlag;
-
- private InterpreterData itsData;
- private ScriptOrFnNode scriptOrFn;
- private int itsICodeTop;
- private int itsStackDepth;
- private int itsLineNumber;
- private int itsDoubleTableTop;
- private ObjToIntMap itsStrings = new ObjToIntMap(20);
- private int itsLocalTop;
-
- private static final int MIN_LABEL_TABLE_SIZE = 32;
- private static final int MIN_FIXUP_TABLE_SIZE = 40;
- private int[] itsLabelTable;
- private int itsLabelTableTop;
-// itsFixupTable[i] = (label_index << 32) | fixup_site
- private long[] itsFixupTable;
- private int itsFixupTableTop;
- private ObjArray itsLiteralIds = new ObjArray();
-
- private int itsExceptionTableTop;
- private static final int EXCEPTION_TRY_START_SLOT = 0;
- private static final int EXCEPTION_TRY_END_SLOT = 1;
- private static final int EXCEPTION_HANDLER_SLOT = 2;
- private static final int EXCEPTION_TYPE_SLOT = 3;
- private static final int EXCEPTION_LOCAL_SLOT = 4;
- private static final int EXCEPTION_SCOPE_SLOT = 5;
- // SLOT_SIZE: space for try start/end, handler, start, handler type,
- // exception local and scope local
- private static final int EXCEPTION_SLOT_SIZE = 6;
-
-// ECF_ or Expression Context Flags constants: for now only TAIL is available
- private static final int ECF_TAIL = 1 << 0;
-
- /**
- * Class to hold data corresponding to one interpreted call stack frame.
- */
- private static class CallFrame implements Cloneable, Serializable
- {
- static final long serialVersionUID = -2843792508994958978L;
-
- CallFrame parentFrame;
- // amount of stack frames before this one on the interpretation stack
- int frameIndex;
- // If true indicates read-only frame that is a part of continuation
- boolean frozen;
-
- InterpretedFunction fnOrScript;
- InterpreterData idata;
-
-// Stack structure
-// stack[0 <= i < localShift]: arguments and local variables
-// stack[localShift <= i <= emptyStackTop]: used for local temporaries
-// stack[emptyStackTop < i < stack.length]: stack data
-// sDbl[i]: if stack[i] is UniqueTag.DOUBLE_MARK, sDbl[i] holds the number value
-
- Object[] stack;
- int[] stackAttributes;
- double[] sDbl;
- CallFrame varSource; // defaults to this unless continuation frame
- int localShift;
- int emptyStackTop;
-
- DebugFrame debuggerFrame;
- boolean useActivation;
-
- Scriptable thisObj;
- Scriptable[] scriptRegExps;
-
-// The values that change during interpretation
-
- Object result;
- double resultDbl;
- int pc;
- int pcPrevBranch;
- int pcSourceLineStart;
- Scriptable scope;
-
- int savedStackTop;
- int savedCallOp;
- Object throwable;
-
- CallFrame cloneFrozen()
- {
- if (!frozen) Kit.codeBug();
-
- CallFrame copy;
- try {
- copy = (CallFrame)clone();
- } catch (CloneNotSupportedException ex) {
- throw new IllegalStateException();
- }
-
- // clone stack but keep varSource to point to values
- // from this frame to share variables.
-
- copy.stack = stack.clone();
- copy.stackAttributes = stackAttributes.clone();
- copy.sDbl = sDbl.clone();
-
- copy.frozen = false;
- return copy;
- }
- }
-
- private static final class ContinuationJump implements Serializable
- {
- static final long serialVersionUID = 7687739156004308247L;
-
- CallFrame capturedFrame;
- CallFrame branchFrame;
- Object result;
- double resultDbl;
-
- ContinuationJump(Continuation c, CallFrame current)
- {
- this.capturedFrame = (CallFrame)c.getImplementation();
- if (this.capturedFrame == null || current == null) {
- // Continuation and current execution does not share
- // any frames if there is nothing to capture or
- // if there is no currently executed frames
- this.branchFrame = null;
- } else {
- // Search for branch frame where parent frame chains starting
- // from captured and current meet.
- CallFrame chain1 = this.capturedFrame;
- CallFrame chain2 = current;
-
- // First work parents of chain1 or chain2 until the same
- // frame depth.
- int diff = chain1.frameIndex - chain2.frameIndex;
- if (diff != 0) {
- if (diff < 0) {
- // swap to make sure that
- // chain1.frameIndex > chain2.frameIndex and diff > 0
- chain1 = current;
- chain2 = this.capturedFrame;
- diff = -diff;
- }
- do {
- chain1 = chain1.parentFrame;
- } while (--diff != 0);
- if (chain1.frameIndex != chain2.frameIndex) Kit.codeBug();
- }
-
- // Now walk parents in parallel until a shared frame is found
- // or until the root is reached.
- while (chain1 != chain2 && chain1 != null) {
- chain1 = chain1.parentFrame;
- chain2 = chain2.parentFrame;
- }
-
- this.branchFrame = chain1;
- if (this.branchFrame != null && !this.branchFrame.frozen)
- Kit.codeBug();
- }
- }
- }
-
- private static CallFrame captureFrameForGenerator(CallFrame frame) {
- frame.frozen = true;
- CallFrame result = frame.cloneFrozen();
- frame.frozen = false;
-
- // now isolate this frame from its previous context
- result.parentFrame = null;
- result.frameIndex = 0;
-
- return result;
- }
-
- static {
- // Checks for byte code consistencies, good compiler can eliminate them
-
- if (Token.LAST_BYTECODE_TOKEN > 127) {
- String str = "Violation of Token.LAST_BYTECODE_TOKEN <= 127";
- System.err.println(str);
- throw new IllegalStateException(str);
- }
- if (MIN_ICODE < -128) {
- String str = "Violation of Interpreter.MIN_ICODE >= -128";
- System.err.println(str);
- throw new IllegalStateException(str);
- }
- }
-
- private static String bytecodeName(int bytecode)
- {
- if (!validBytecode(bytecode)) {
- throw new IllegalArgumentException(String.valueOf(bytecode));
- }
-
- if (!Token.printICode) {
- return String.valueOf(bytecode);
- }
-
- if (validTokenCode(bytecode)) {
- return Token.name(bytecode);
- }
-
- switch (bytecode) {
- case Icode_DUP: return "DUP";
- case Icode_DUP2: return "DUP2";
- case Icode_SWAP: return "SWAP";
- case Icode_POP: return "POP";
- case Icode_POP_RESULT: return "POP_RESULT";
- case Icode_IFEQ_POP: return "IFEQ_POP";
- case Icode_VAR_INC_DEC: return "VAR_INC_DEC";
- case Icode_NAME_INC_DEC: return "NAME_INC_DEC";
- case Icode_PROP_INC_DEC: return "PROP_INC_DEC";
- case Icode_ELEM_INC_DEC: return "ELEM_INC_DEC";
- case Icode_REF_INC_DEC: return "REF_INC_DEC";
- case Icode_SCOPE_LOAD: return "SCOPE_LOAD";
- case Icode_SCOPE_SAVE: return "SCOPE_SAVE";
- case Icode_TYPEOFNAME: return "TYPEOFNAME";
- case Icode_NAME_AND_THIS: return "NAME_AND_THIS";
- case Icode_PROP_AND_THIS: return "PROP_AND_THIS";
- case Icode_ELEM_AND_THIS: return "ELEM_AND_THIS";
- case Icode_VALUE_AND_THIS: return "VALUE_AND_THIS";
- case Icode_CLOSURE_EXPR: return "CLOSURE_EXPR";
- case Icode_CLOSURE_STMT: return "CLOSURE_STMT";
- case Icode_CALLSPECIAL: return "CALLSPECIAL";
- case Icode_RETUNDEF: return "RETUNDEF";
- case Icode_GOSUB: return "GOSUB";
- case Icode_STARTSUB: return "STARTSUB";
- case Icode_RETSUB: return "RETSUB";
- case Icode_LINE: return "LINE";
- case Icode_SHORTNUMBER: return "SHORTNUMBER";
- case Icode_INTNUMBER: return "INTNUMBER";
- case Icode_LITERAL_NEW: return "LITERAL_NEW";
- case Icode_LITERAL_SET: return "LITERAL_SET";
- case Icode_SPARE_ARRAYLIT: return "SPARE_ARRAYLIT";
- case Icode_REG_IND_C0: return "REG_IND_C0";
- case Icode_REG_IND_C1: return "REG_IND_C1";
- case Icode_REG_IND_C2: return "REG_IND_C2";
- case Icode_REG_IND_C3: return "REG_IND_C3";
- case Icode_REG_IND_C4: return "REG_IND_C4";
- case Icode_REG_IND_C5: return "REG_IND_C5";
- case Icode_REG_IND1: return "LOAD_IND1";
- case Icode_REG_IND2: return "LOAD_IND2";
- case Icode_REG_IND4: return "LOAD_IND4";
- case Icode_REG_STR_C0: return "REG_STR_C0";
- case Icode_REG_STR_C1: return "REG_STR_C1";
- case Icode_REG_STR_C2: return "REG_STR_C2";
- case Icode_REG_STR_C3: return "REG_STR_C3";
- case Icode_REG_STR1: return "LOAD_STR1";
- case Icode_REG_STR2: return "LOAD_STR2";
- case Icode_REG_STR4: return "LOAD_STR4";
- case Icode_GETVAR1: return "GETVAR1";
- case Icode_SETVAR1: return "SETVAR1";
- case Icode_UNDEF: return "UNDEF";
- case Icode_ZERO: return "ZERO";
- case Icode_ONE: return "ONE";
- case Icode_ENTERDQ: return "ENTERDQ";
- case Icode_LEAVEDQ: return "LEAVEDQ";
- case Icode_TAIL_CALL: return "TAIL_CALL";
- case Icode_LOCAL_CLEAR: return "LOCAL_CLEAR";
- case Icode_LITERAL_GETTER: return "LITERAL_GETTER";
- case Icode_LITERAL_SETTER: return "LITERAL_SETTER";
- case Icode_SETCONST: return "SETCONST";
- case Icode_SETCONSTVAR: return "SETCONSTVAR";
- case Icode_SETCONSTVAR1: return "SETCONSTVAR1";
- case Icode_GENERATOR: return "GENERATOR";
- case Icode_GENERATOR_END: return "GENERATOR_END";
- case Icode_DEBUGGER: return "DEBUGGER";
- }
-
- // icode without name
- throw new IllegalStateException(String.valueOf(bytecode));
- }
-
- private static boolean validIcode(int icode)
- {
- return MIN_ICODE <= icode && icode <= -1;
- }
-
- private static boolean validTokenCode(int token)
- {
- return Token.FIRST_BYTECODE_TOKEN <= token
- && token <= Token.LAST_BYTECODE_TOKEN;
- }
-
- private static boolean validBytecode(int bytecode)
- {
- return validIcode(bytecode) || validTokenCode(bytecode);
- }
-
- public Object compile(CompilerEnvirons compilerEnv,
- ScriptOrFnNode tree,
- String encodedSource,
- boolean returnFunction)
- {
- this.compilerEnv = compilerEnv;
- new NodeTransformer().transform(tree);
-
- if (Token.printTrees) {
- /*APPJET*///System.out.println(tree.toStringTree(tree));
- }
-
- if (returnFunction) {
- tree = tree.getFunctionNode(0);
- }
-
- scriptOrFn = tree;
- itsData = new InterpreterData(compilerEnv.getLanguageVersion(),
- scriptOrFn.getSourceName(),
- encodedSource);
- itsData.topLevel = true;
-
- if (returnFunction) {
- generateFunctionICode();
- } else {
- generateICodeFromTree(scriptOrFn);
- }
-
- return itsData;
- }
-
- public Script createScriptObject(Object bytecode, Object staticSecurityDomain)
- {
- if(bytecode != itsData)
- {
- Kit.codeBug();
- }
- return InterpretedFunction.createScript(itsData,
- staticSecurityDomain);
- }
-
- public void setEvalScriptFlag(Script script) {
- ((InterpretedFunction)script).idata.evalScriptFlag = true;
- }
-
-
- public Function createFunctionObject(Context cx, Scriptable scope,
- Object bytecode, Object staticSecurityDomain)
- {
- if(bytecode != itsData)
- {
- Kit.codeBug();
- }
- return InterpretedFunction.createFunction(cx, scope, itsData,
- staticSecurityDomain);
- }
-
- private void generateFunctionICode()
- {
- itsInFunctionFlag = true;
-
- FunctionNode theFunction = (FunctionNode)scriptOrFn;
-
- itsData.itsFunctionType = theFunction.getFunctionType();
- itsData.itsNeedsActivation = theFunction.requiresActivation();
- itsData.itsName = theFunction.getFunctionName();
- if (!theFunction.getIgnoreDynamicScope()) {
- if (compilerEnv.isUseDynamicScope()) {
- itsData.useDynamicScope = true;
- }
- }
- if (theFunction.isGenerator()) {
- addIcode(Icode_GENERATOR);
- addUint16(theFunction.getBaseLineno() & 0xFFFF);
- }
-
- generateICodeFromTree(theFunction.getLastChild());
- }
-
- private void generateICodeFromTree(Node tree)
- {
- generateNestedFunctions();
-
- generateRegExpLiterals();
-
- visitStatement(tree, 0);
- fixLabelGotos();
- // add RETURN_RESULT only to scripts as function always ends with RETURN
- if (itsData.itsFunctionType == 0) {
- addToken(Token.RETURN_RESULT);
- }
-
- if (itsData.itsICode.length != itsICodeTop) {
- // Make itsData.itsICode length exactly itsICodeTop to save memory
- // and catch bugs with jumps beyond icode as early as possible
- byte[] tmp = new byte[itsICodeTop];
- System.arraycopy(itsData.itsICode, 0, tmp, 0, itsICodeTop);
- itsData.itsICode = tmp;
- }
- if (itsStrings.size() == 0) {
- itsData.itsStringTable = null;
- } else {
- itsData.itsStringTable = new String[itsStrings.size()];
- ObjToIntMap.Iterator iter = itsStrings.newIterator();
- for (iter.start(); !iter.done(); iter.next()) {
- String str = (String)iter.getKey();
- int index = iter.getValue();
- if (itsData.itsStringTable[index] != null) Kit.codeBug();
- itsData.itsStringTable[index] = str;
- }
- }
- if (itsDoubleTableTop == 0) {
- itsData.itsDoubleTable = null;
- } else if (itsData.itsDoubleTable.length != itsDoubleTableTop) {
- double[] tmp = new double[itsDoubleTableTop];
- System.arraycopy(itsData.itsDoubleTable, 0, tmp, 0,
- itsDoubleTableTop);
- itsData.itsDoubleTable = tmp;
- }
- if (itsExceptionTableTop != 0
- && itsData.itsExceptionTable.length != itsExceptionTableTop)
- {
- int[] tmp = new int[itsExceptionTableTop];
- System.arraycopy(itsData.itsExceptionTable, 0, tmp, 0,
- itsExceptionTableTop);
- itsData.itsExceptionTable = tmp;
- }
-
- itsData.itsMaxVars = scriptOrFn.getParamAndVarCount();
- // itsMaxFrameArray: interpret method needs this amount for its
- // stack and sDbl arrays
- itsData.itsMaxFrameArray = itsData.itsMaxVars
- + itsData.itsMaxLocals
- + itsData.itsMaxStack;
-
- itsData.argNames = scriptOrFn.getParamAndVarNames();
- itsData.argIsConst = scriptOrFn.getParamAndVarConst();
- itsData.argCount = scriptOrFn.getParamCount();
-
- itsData.encodedSourceStart = scriptOrFn.getEncodedSourceStart();
- itsData.encodedSourceEnd = scriptOrFn.getEncodedSourceEnd();
-
- if (itsLiteralIds.size() != 0) {
- itsData.literalIds = itsLiteralIds.toArray();
- }
-
- if (Token.printICode) dumpICode(itsData);
- }
-
- private void generateNestedFunctions()
- {
- int functionCount = scriptOrFn.getFunctionCount();
- if (functionCount == 0) return;
-
- InterpreterData[] array = new InterpreterData[functionCount];
- for (int i = 0; i != functionCount; i++) {
- FunctionNode def = scriptOrFn.getFunctionNode(i);
- Interpreter jsi = new Interpreter();
- jsi.compilerEnv = compilerEnv;
- jsi.scriptOrFn = def;
- jsi.itsData = new InterpreterData(itsData);
- jsi.generateFunctionICode();
- array[i] = jsi.itsData;
- }
- itsData.itsNestedFunctions = array;
- }
-
- private void generateRegExpLiterals()
- {
- int N = scriptOrFn.getRegexpCount();
- if (N == 0) return;
-
- Context cx = Context.getContext();
- RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx);
- Object[] array = new Object[N];
- for (int i = 0; i != N; i++) {
- String string = scriptOrFn.getRegexpString(i);
- String flags = scriptOrFn.getRegexpFlags(i);
- array[i] = rep.compileRegExp(cx, string, flags);
- }
- itsData.itsRegExpLiterals = array;
- }
-
- private void updateLineNumber(Node node)
- {
- int lineno = node.getLineno();
- if (lineno != itsLineNumber && lineno >= 0) {
- if (itsData.firstLinePC < 0) {
- itsData.firstLinePC = lineno;
- }
- itsLineNumber = lineno;
- addIcode(Icode_LINE);
- addUint16(lineno & 0xFFFF);
- }
- }
-
- private RuntimeException badTree(Node node)
- {
- throw new RuntimeException(node.toString());
- }
-
- private void visitStatement(Node node, int initialStackDepth)
- {
- int type = node.getType();
- Node child = node.getFirstChild();
- switch (type) {
-
- case Token.FUNCTION:
- {
- int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP);
- int fnType = scriptOrFn.getFunctionNode(fnIndex).
- getFunctionType();
- // Only function expressions or function expression
- // statements need closure code creating new function
- // object on stack as function statements are initialized
- // at script/function start.
- // In addition, function expressions can not be present here
- // at statement level, they must only be present as expressions.
- if (fnType == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) {
- addIndexOp(Icode_CLOSURE_STMT, fnIndex);
- } else {
- if (fnType != FunctionNode.FUNCTION_STATEMENT) {
- throw Kit.codeBug();
- }
- }
- // For function statements or function expression statements
- // in scripts, we need to ensure that the result of the script
- // is the function if it is the last statement in the script.
- // For example, eval("function () {}") should return a
- // function, not undefined.
- if (!itsInFunctionFlag) {
- addIndexOp(Icode_CLOSURE_EXPR, fnIndex);
- stackChange(1);
- addIcode(Icode_POP_RESULT);
- stackChange(-1);
- }
- }
- break;
-
- case Token.LABEL:
- case Token.LOOP:
- case Token.BLOCK:
- case Token.EMPTY:
- case Token.WITH:
- updateLineNumber(node);
- case Token.SCRIPT:
- // fall through
- while (child != null) {
- visitStatement(child, initialStackDepth);
- child = child.getNext();
- }
- break;
-
- case Token.ENTERWITH:
- visitExpression(child, 0);
- addToken(Token.ENTERWITH);
- stackChange(-1);
- break;
-
- case Token.LEAVEWITH:
- addToken(Token.LEAVEWITH);
- break;
-
- case Token.LOCAL_BLOCK:
- {
- int local = allocLocal();
- node.putIntProp(Node.LOCAL_PROP, local);
- updateLineNumber(node);
- while (child != null) {
- visitStatement(child, initialStackDepth);
- child = child.getNext();
- }
- addIndexOp(Icode_LOCAL_CLEAR, local);
- releaseLocal(local);
- }
- break;
-
- case Token.DEBUGGER:
- addIcode(Icode_DEBUGGER);
- break;
-
- case Token.SWITCH:
- updateLineNumber(node);
- // See comments in IRFactory.createSwitch() for description
- // of SWITCH node
- {
- visitExpression(child, 0);
- for (Node.Jump caseNode = (Node.Jump)child.getNext();
- caseNode != null;
- caseNode = (Node.Jump)caseNode.getNext())
- {
- if (caseNode.getType() != Token.CASE)
- throw badTree(caseNode);
- Node test = caseNode.getFirstChild();
- addIcode(Icode_DUP);
- stackChange(1);
- visitExpression(test, 0);
- addToken(Token.SHEQ);
- stackChange(-1);
- // If true, Icode_IFEQ_POP will jump and remove case
- // value from stack
- addGoto(caseNode.target, Icode_IFEQ_POP);
- stackChange(-1);
- }
- addIcode(Icode_POP);
- stackChange(-1);
- }
- break;
-
- case Token.TARGET:
- markTargetLabel(node);
- break;
-
- case Token.IFEQ :
- case Token.IFNE :
- {
- Node target = ((Node.Jump)node).target;
- visitExpression(child, 0);
- addGoto(target, type);
- stackChange(-1);
- }
- break;
-
- case Token.GOTO:
- {
- Node target = ((Node.Jump)node).target;
- addGoto(target, type);
- }
- break;
-
- case Token.JSR:
- {
- Node target = ((Node.Jump)node).target;
- addGoto(target, Icode_GOSUB);
- }
- break;
-
- case Token.FINALLY:
- {
- // Account for incomming GOTOSUB address
- stackChange(1);
- int finallyRegister = getLocalBlockRef(node);
- addIndexOp(Icode_STARTSUB, finallyRegister);
- stackChange(-1);
- while (child != null) {
- visitStatement(child, initialStackDepth);
- child = child.getNext();
- }
- addIndexOp(Icode_RETSUB, finallyRegister);
- }
- break;
-
- case Token.EXPR_VOID:
- case Token.EXPR_RESULT:
- updateLineNumber(node);
- visitExpression(child, 0);
- addIcode((type == Token.EXPR_VOID) ? Icode_POP : Icode_POP_RESULT);
- stackChange(-1);
- break;
-
- case Token.TRY:
- {
- Node.Jump tryNode = (Node.Jump)node;
- int exceptionObjectLocal = getLocalBlockRef(tryNode);
- int scopeLocal = allocLocal();
-
- addIndexOp(Icode_SCOPE_SAVE, scopeLocal);
-
- int tryStart = itsICodeTop;
- boolean savedFlag = itsInTryFlag;
- itsInTryFlag = true;
- while (child != null) {
- visitStatement(child, initialStackDepth);
- child = child.getNext();
- }
- itsInTryFlag = savedFlag;
-
- Node catchTarget = tryNode.target;
- if (catchTarget != null) {
- int catchStartPC
- = itsLabelTable[getTargetLabel(catchTarget)];
- addExceptionHandler(
- tryStart, catchStartPC, catchStartPC,
- false, exceptionObjectLocal, scopeLocal);
- }
- Node finallyTarget = tryNode.getFinally();
- if (finallyTarget != null) {
- int finallyStartPC
- = itsLabelTable[getTargetLabel(finallyTarget)];
- addExceptionHandler(
- tryStart, finallyStartPC, finallyStartPC,
- true, exceptionObjectLocal, scopeLocal);
- }
-
- addIndexOp(Icode_LOCAL_CLEAR, scopeLocal);
- releaseLocal(scopeLocal);
- }
- break;
-
- case Token.CATCH_SCOPE:
- {
- int localIndex = getLocalBlockRef(node);
- int scopeIndex = node.getExistingIntProp(Node.CATCH_SCOPE_PROP);
- String name = child.getString();
- child = child.getNext();
- visitExpression(child, 0); // load expression object
- addStringPrefix(name);
- addIndexPrefix(localIndex);
- addToken(Token.CATCH_SCOPE);
- addUint8(scopeIndex != 0 ? 1 : 0);
- stackChange(-1);
- }
- break;
-
- case Token.THROW:
- updateLineNumber(node);
- visitExpression(child, 0);
- addToken(Token.THROW);
- addUint16(itsLineNumber & 0xFFFF);
- stackChange(-1);
- break;
-
- case Token.RETHROW:
- updateLineNumber(node);
- addIndexOp(Token.RETHROW, getLocalBlockRef(node));
- break;
-
- case Token.RETURN:
- updateLineNumber(node);
- if (node.getIntProp(Node.GENERATOR_END_PROP, 0) != 0) {
- // We're in a generator, so change RETURN to GENERATOR_END
- addIcode(Icode_GENERATOR_END);
- addUint16(itsLineNumber & 0xFFFF);
- } else if (child != null) {
- visitExpression(child, ECF_TAIL);
- addToken(Token.RETURN);
- stackChange(-1);
- } else {
- addIcode(Icode_RETUNDEF);
- }
- break;
-
- case Token.RETURN_RESULT:
- updateLineNumber(node);
- addToken(Token.RETURN_RESULT);
- break;
-
- case Token.ENUM_INIT_KEYS:
- case Token.ENUM_INIT_VALUES:
- case Token.ENUM_INIT_ARRAY:
- visitExpression(child, 0);
- addIndexOp(type, getLocalBlockRef(node));
- stackChange(-1);
- break;
-
- case Icode_GENERATOR:
- break;
-
- default:
- throw badTree(node);
- }
-
- if (itsStackDepth != initialStackDepth) {
- throw Kit.codeBug();
- }
- }
-
- private void visitExpression(Node node, int contextFlags)
- {
- int type = node.getType();
- Node child = node.getFirstChild();
- int savedStackDepth = itsStackDepth;
- switch (type) {
-
- case Token.FUNCTION:
- {
- int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP);
- FunctionNode fn = scriptOrFn.getFunctionNode(fnIndex);
- // See comments in visitStatement for Token.FUNCTION case
- if (fn.getFunctionType() != FunctionNode.FUNCTION_EXPRESSION) {
- throw Kit.codeBug();
- }
- addIndexOp(Icode_CLOSURE_EXPR, fnIndex);
- stackChange(1);
- }
- break;
-
- case Token.LOCAL_LOAD:
- {
- int localIndex = getLocalBlockRef(node);
- addIndexOp(Token.LOCAL_LOAD, localIndex);
- stackChange(1);
- }
- break;
-
- case Token.COMMA:
- {
- Node lastChild = node.getLastChild();
- while (child != lastChild) {
- visitExpression(child, 0);
- addIcode(Icode_POP);
- stackChange(-1);
- child = child.getNext();
- }
- // Preserve tail context flag if any
- visitExpression(child, contextFlags & ECF_TAIL);
- }
- break;
-
- case Token.USE_STACK:
- // Indicates that stack was modified externally,
- // like placed catch object
- stackChange(1);
- break;
-
- case Token.REF_CALL:
- case Token.CALL:
- case Token.NEW:
- {
- if (type == Token.NEW) {
- visitExpression(child, 0);
- } else {
- generateCallFunAndThis(child);
- }
- int argCount = 0;
- while ((child = child.getNext()) != null) {
- visitExpression(child, 0);
- ++argCount;
- }
- int callType = node.getIntProp(Node.SPECIALCALL_PROP,
- Node.NON_SPECIALCALL);
- if (callType != Node.NON_SPECIALCALL) {
- // embed line number and source filename
- addIndexOp(Icode_CALLSPECIAL, argCount);
- addUint8(callType);
- addUint8(type == Token.NEW ? 1 : 0);
- addUint16(itsLineNumber & 0xFFFF);
- } else {
- // Only use the tail call optimization if we're not in a try
- // or we're not generating debug info (since the
- // optimization will confuse the debugger)
- if (type == Token.CALL && (contextFlags & ECF_TAIL) != 0 &&
- !compilerEnv.isGenerateDebugInfo() && !itsInTryFlag)
- {
- type = Icode_TAIL_CALL;
- }
- addIndexOp(type, argCount);
- }
- // adjust stack
- if (type == Token.NEW) {
- // new: f, args -> result
- stackChange(-argCount);
- } else {
- // call: f, thisObj, args -> result
- // ref_call: f, thisObj, args -> ref
- stackChange(-1 - argCount);
- }
- if (argCount > itsData.itsMaxCalleeArgs) {
- itsData.itsMaxCalleeArgs = argCount;
- }
- }
- break;
-
- case Token.AND:
- case Token.OR:
- {
- visitExpression(child, 0);
- addIcode(Icode_DUP);
- stackChange(1);
- int afterSecondJumpStart = itsICodeTop;
- int jump = (type == Token.AND) ? Token.IFNE : Token.IFEQ;
- addGotoOp(jump);
- stackChange(-1);
- addIcode(Icode_POP);
- stackChange(-1);
- child = child.getNext();
- // Preserve tail context flag if any
- visitExpression(child, contextFlags & ECF_TAIL);
- resolveForwardGoto(afterSecondJumpStart);
- }
- break;
-
- case Token.HOOK:
- {
- Node ifThen = child.getNext();
- Node ifElse = ifThen.getNext();
- visitExpression(child, 0);
- int elseJumpStart = itsICodeTop;
- addGotoOp(Token.IFNE);
- stackChange(-1);
- // Preserve tail context flag if any
- visitExpression(ifThen, contextFlags & ECF_TAIL);
- int afterElseJumpStart = itsICodeTop;
- addGotoOp(Token.GOTO);
- resolveForwardGoto(elseJumpStart);
- itsStackDepth = savedStackDepth;
- // Preserve tail context flag if any
- visitExpression(ifElse, contextFlags & ECF_TAIL);
- resolveForwardGoto(afterElseJumpStart);
- }
- break;
-
- case Token.GETPROP:
- case Token.GETPROPNOWARN:
- visitExpression(child, 0);
- child = child.getNext();
- addStringOp(type, child.getString());
- break;
-
- case Token.GETELEM:
- case Token.DELPROP:
- case Token.BITAND:
- case Token.BITOR:
- case Token.BITXOR:
- case Token.LSH:
- case Token.RSH:
- case Token.URSH:
- case Token.ADD:
- case Token.SUB:
- case Token.MOD:
- case Token.DIV:
- case Token.MUL:
- case Token.EQ:
- case Token.NE:
- case Token.SHEQ:
- case Token.SHNE:
- case Token.IN:
- case Token.INSTANCEOF:
- case Token.LE:
- case Token.LT:
- case Token.GE:
- case Token.GT:
- visitExpression(child, 0);
- child = child.getNext();
- visitExpression(child, 0);
- addToken(type);
- stackChange(-1);
- break;
-
- case Token.POS:
- case Token.NEG:
- case Token.NOT:
- case Token.BITNOT:
- case Token.TYPEOF:
- case Token.VOID:
- visitExpression(child, 0);
- if (type == Token.VOID) {
- addIcode(Icode_POP);
- addIcode(Icode_UNDEF);
- } else {
- addToken(type);
- }
- break;
-
- case Token.GET_REF:
- case Token.DEL_REF:
- visitExpression(child, 0);
- addToken(type);
- break;
-
- case Token.SETPROP:
- case Token.SETPROP_OP:
- {
- visitExpression(child, 0);
- child = child.getNext();
- String property = child.getString();
- child = child.getNext();
- if (type == Token.SETPROP_OP) {
- addIcode(Icode_DUP);
- stackChange(1);
- addStringOp(Token.GETPROP, property);
- // Compensate for the following USE_STACK
- stackChange(-1);
- }
- visitExpression(child, 0);
- addStringOp(Token.SETPROP, property);
- stackChange(-1);
- }
- break;
-
- case Token.SETELEM:
- case Token.SETELEM_OP:
- visitExpression(child, 0);
- child = child.getNext();
- visitExpression(child, 0);
- child = child.getNext();
- if (type == Token.SETELEM_OP) {
- addIcode(Icode_DUP2);
- stackChange(2);
- addToken(Token.GETELEM);
- stackChange(-1);
- // Compensate for the following USE_STACK
- stackChange(-1);
- }
- visitExpression(child, 0);
- addToken(Token.SETELEM);
- stackChange(-2);
- break;
-
- case Token.SET_REF:
- case Token.SET_REF_OP:
- visitExpression(child, 0);
- child = child.getNext();
- if (type == Token.SET_REF_OP) {
- addIcode(Icode_DUP);
- stackChange(1);
- addToken(Token.GET_REF);
- // Compensate for the following USE_STACK
- stackChange(-1);
- }
- visitExpression(child, 0);
- addToken(Token.SET_REF);
- stackChange(-1);
- break;
-
- case Token.SETNAME:
- {
- String name = child.getString();
- visitExpression(child, 0);
- child = child.getNext();
- visitExpression(child, 0);
- addStringOp(Token.SETNAME, name);
- stackChange(-1);
- }
- break;
-
- case Token.SETCONST:
- {
- String name = child.getString();
- visitExpression(child, 0);
- child = child.getNext();
- visitExpression(child, 0);
- addStringOp(Icode_SETCONST, name);
- stackChange(-1);
- }
- break;
-
- case Token.TYPEOFNAME:
- {
- int index = -1;
- // use typeofname if an activation frame exists
- // since the vars all exist there instead of in jregs
- if (itsInFunctionFlag && !itsData.itsNeedsActivation)
- index = scriptOrFn.getIndexForNameNode(node);
- if (index == -1) {
- addStringOp(Icode_TYPEOFNAME, node.getString());
- stackChange(1);
- } else {
- addVarOp(Token.GETVAR, index);
- stackChange(1);
- addToken(Token.TYPEOF);
- }
- }
- break;
-
- case Token.BINDNAME:
- case Token.NAME:
- case Token.STRING:
- addStringOp(type, node.getString());
- stackChange(1);
- break;
-
- case Token.INC:
- case Token.DEC:
- visitIncDec(node, child);
- break;
-
- case Token.NUMBER:
- {
- double num = node.getDouble();
- int inum = (int)num;
- if (inum == num) {
- if (inum == 0) {
- addIcode(Icode_ZERO);
- // Check for negative zero
- if (1.0 / num < 0.0) {
- addToken(Token.NEG);
- }
- } else if (inum == 1) {
- addIcode(Icode_ONE);
- } else if ((short)inum == inum) {
- addIcode(Icode_SHORTNUMBER);
- // write short as uin16 bit pattern
- addUint16(inum & 0xFFFF);
- } else {
- addIcode(Icode_INTNUMBER);
- addInt(inum);
- }
- } else {
- int index = getDoubleIndex(num);
- addIndexOp(Token.NUMBER, index);
- }
- stackChange(1);
- }
- break;
-
- case Token.GETVAR:
- {
- if (itsData.itsNeedsActivation) Kit.codeBug();
- int index = scriptOrFn.getIndexForNameNode(node);
- addVarOp(Token.GETVAR, index);
- stackChange(1);
- }
- break;
-
- case Token.SETVAR:
- {
- if (itsData.itsNeedsActivation) Kit.codeBug();
- int index = scriptOrFn.getIndexForNameNode(child);
- child = child.getNext();
- visitExpression(child, 0);
- addVarOp(Token.SETVAR, index);
- }
- break;
-
- case Token.SETCONSTVAR:
- {
- if (itsData.itsNeedsActivation) Kit.codeBug();
- int index = scriptOrFn.getIndexForNameNode(child);
- child = child.getNext();
- visitExpression(child, 0);
- addVarOp(Token.SETCONSTVAR, index);
- }
- break;
-
- case Token.NULL:
- case Token.THIS:
- case Token.THISFN:
- case Token.FALSE:
- case Token.TRUE:
- addToken(type);
- stackChange(1);
- break;
-
- case Token.ENUM_NEXT:
- case Token.ENUM_ID:
- addIndexOp(type, getLocalBlockRef(node));
- stackChange(1);
- break;
-
- case Token.REGEXP:
- {
- int index = node.getExistingIntProp(Node.REGEXP_PROP);
- addIndexOp(Token.REGEXP, index);
- stackChange(1);
- }
- break;
-
- case Token.ARRAYLIT:
- case Token.OBJECTLIT:
- visitLiteral(node, child);
- break;
-
- case Token.ARRAYCOMP:
- visitArrayComprehension(node, child, child.getNext());
- break;
-
- case Token.REF_SPECIAL:
- visitExpression(child, 0);
- addStringOp(type, (String)node.getProp(Node.NAME_PROP));
- break;
-
- case Token.REF_MEMBER:
- case Token.REF_NS_MEMBER:
- case Token.REF_NAME:
- case Token.REF_NS_NAME:
- {
- int memberTypeFlags = node.getIntProp(Node.MEMBER_TYPE_PROP, 0);
- // generate possible target, possible namespace and member
- int childCount = 0;
- do {
- visitExpression(child, 0);
- ++childCount;
- child = child.getNext();
- } while (child != null);
- addIndexOp(type, memberTypeFlags);
- stackChange(1 - childCount);
- }
- break;
-
- case Token.DOTQUERY:
- {
- int queryPC;
- updateLineNumber(node);
- visitExpression(child, 0);
- addIcode(Icode_ENTERDQ);
- stackChange(-1);
- queryPC = itsICodeTop;
- visitExpression(child.getNext(), 0);
- addBackwardGoto(Icode_LEAVEDQ, queryPC);
- }
- break;
-
- case Token.DEFAULTNAMESPACE :
- case Token.ESCXMLATTR :
- case Token.ESCXMLTEXT :
- visitExpression(child, 0);
- addToken(type);
- break;
-
- case Token.YIELD:
- if (child != null) {
- visitExpression(child, 0);
- } else {
- addIcode(Icode_UNDEF);
- stackChange(1);
- }
- addToken(Token.YIELD);
- addUint16(node.getLineno() & 0xFFFF);
- break;
-
- case Token.WITHEXPR: {
- Node enterWith = node.getFirstChild();
- Node with = enterWith.getNext();
- visitExpression(enterWith.getFirstChild(), 0);
- addToken(Token.ENTERWITH);
- stackChange(-1);
- visitExpression(with.getFirstChild(), 0);
- addToken(Token.LEAVEWITH);
- break;
- }
-
- default:
- throw badTree(node);
- }
- if (savedStackDepth + 1 != itsStackDepth) {
- Kit.codeBug();
- }
- }
-
- private void generateCallFunAndThis(Node left)
- {
- // Generate code to place on stack function and thisObj
- int type = left.getType();
- switch (type) {
- case Token.NAME: {
- String name = left.getString();
- // stack: ... -> ... function thisObj
- addStringOp(Icode_NAME_AND_THIS, name);
- stackChange(2);
- break;
- }
- case Token.GETPROP:
- case Token.GETELEM: {
- Node target = left.getFirstChild();
- visitExpression(target, 0);
- Node id = target.getNext();
- if (type == Token.GETPROP) {
- String property = id.getString();
- // stack: ... target -> ... function thisObj
- addStringOp(Icode_PROP_AND_THIS, property);
- stackChange(1);
- } else {
- visitExpression(id, 0);
- // stack: ... target id -> ... function thisObj
- addIcode(Icode_ELEM_AND_THIS);
- }
- break;
- }
- default:
- // Including Token.GETVAR
- visitExpression(left, 0);
- // stack: ... value -> ... function thisObj
- addIcode(Icode_VALUE_AND_THIS);
- stackChange(1);
- break;
- }
- }
-
- private void visitIncDec(Node node, Node child)
- {
- int incrDecrMask = node.getExistingIntProp(Node.INCRDECR_PROP);
- int childType = child.getType();
- switch (childType) {
- case Token.GETVAR : {
- if (itsData.itsNeedsActivation) Kit.codeBug();
- int i = scriptOrFn.getIndexForNameNode(child);
- addVarOp(Icode_VAR_INC_DEC, i);
- addUint8(incrDecrMask);
- stackChange(1);
- break;
- }
- case Token.NAME : {
- String name = child.getString();
- addStringOp(Icode_NAME_INC_DEC, name);
- addUint8(incrDecrMask);
- stackChange(1);
- break;
- }
- case Token.GETPROP : {
- Node object = child.getFirstChild();
- visitExpression(object, 0);
- String property = object.getNext().getString();
- addStringOp(Icode_PROP_INC_DEC, property);
- addUint8(incrDecrMask);
- break;
- }
- case Token.GETELEM : {
- Node object = child.getFirstChild();
- visitExpression(object, 0);
- Node index = object.getNext();
- visitExpression(index, 0);
- addIcode(Icode_ELEM_INC_DEC);
- addUint8(incrDecrMask);
- stackChange(-1);
- break;
- }
- case Token.GET_REF : {
- Node ref = child.getFirstChild();
- visitExpression(ref, 0);
- addIcode(Icode_REF_INC_DEC);
- addUint8(incrDecrMask);
- break;
- }
- default : {
- throw badTree(node);
- }
- }
- }
-
- private void visitLiteral(Node node, Node child)
- {
- int type = node.getType();
- int count;
- Object[] propertyIds = null;
- if (type == Token.ARRAYLIT) {
- count = 0;
- for (Node n = child; n != null; n = n.getNext()) {
- ++count;
- }
- } else if (type == Token.OBJECTLIT) {
- propertyIds = (Object[])node.getProp(Node.OBJECT_IDS_PROP);
- count = propertyIds.length;
- } else {
- throw badTree(node);
- }
- addIndexOp(Icode_LITERAL_NEW, count);
- stackChange(2);
- while (child != null) {
- int childType = child.getType();
- if (childType == Token.GET) {
- visitExpression(child.getFirstChild(), 0);
- addIcode(Icode_LITERAL_GETTER);
- } else if (childType == Token.SET) {
- visitExpression(child.getFirstChild(), 0);
- addIcode(Icode_LITERAL_SETTER);
- } else {
- visitExpression(child, 0);
- addIcode(Icode_LITERAL_SET);
- }
- stackChange(-1);
- child = child.getNext();
- }
- if (type == Token.ARRAYLIT) {
- int[] skipIndexes = (int[])node.getProp(Node.SKIP_INDEXES_PROP);
- if (skipIndexes == null) {
- addToken(Token.ARRAYLIT);
- } else {
- int index = itsLiteralIds.size();
- itsLiteralIds.add(skipIndexes);
- addIndexOp(Icode_SPARE_ARRAYLIT, index);
- }
- } else {
- int index = itsLiteralIds.size();
- itsLiteralIds.add(propertyIds);
- addIndexOp(Token.OBJECTLIT, index);
- }
- stackChange(-1);
- }
-
- private void visitArrayComprehension(Node node, Node initStmt, Node expr)
- {
- // A bit of a hack: array comprehensions are implemented using
- // statement nodes for the iteration, yet they appear in an
- // expression context. So we pass the current stack depth to
- // visitStatement so it can check that the depth is not altered
- // by statements.
- visitStatement(initStmt, itsStackDepth);
- visitExpression(expr, 0);
- }
-
- private int getLocalBlockRef(Node node)
- {
- Node localBlock = (Node)node.getProp(Node.LOCAL_BLOCK_PROP);
- return localBlock.getExistingIntProp(Node.LOCAL_PROP);
- }
-
- private int getTargetLabel(Node target)
- {
- int label = target.labelId();
- if (label != -1) {
- return label;
- }
- label = itsLabelTableTop;
- if (itsLabelTable == null || label == itsLabelTable.length) {
- if (itsLabelTable == null) {
- itsLabelTable = new int[MIN_LABEL_TABLE_SIZE];
- }else {
- int[] tmp = new int[itsLabelTable.length * 2];
- System.arraycopy(itsLabelTable, 0, tmp, 0, label);
- itsLabelTable = tmp;
- }
- }
- itsLabelTableTop = label + 1;
- itsLabelTable[label] = -1;
-
- target.labelId(label);
- return label;
- }
-
- private void markTargetLabel(Node target)
- {
- int label = getTargetLabel(target);
- if (itsLabelTable[label] != -1) {
- // Can mark label only once
- Kit.codeBug();
- }
- itsLabelTable[label] = itsICodeTop;
- }
-
- private void addGoto(Node target, int gotoOp)
- {
- int label = getTargetLabel(target);
- if (!(label < itsLabelTableTop)) Kit.codeBug();
- int targetPC = itsLabelTable[label];
-
- if (targetPC != -1) {
- addBackwardGoto(gotoOp, targetPC);
- } else {
- int gotoPC = itsICodeTop;
- addGotoOp(gotoOp);
- int top = itsFixupTableTop;
- if (itsFixupTable == null || top == itsFixupTable.length) {
- if (itsFixupTable == null) {
- itsFixupTable = new long[MIN_FIXUP_TABLE_SIZE];
- } else {
- long[] tmp = new long[itsFixupTable.length * 2];
- System.arraycopy(itsFixupTable, 0, tmp, 0, top);
- itsFixupTable = tmp;
- }
- }
- itsFixupTableTop = top + 1;
- itsFixupTable[top] = ((long)label << 32) | gotoPC;
- }
- }
-
- private void fixLabelGotos()
- {
- for (int i = 0; i < itsFixupTableTop; i++) {
- long fixup = itsFixupTable[i];
- int label = (int)(fixup >> 32);
- int jumpSource = (int)fixup;
- int pc = itsLabelTable[label];
- if (pc == -1) {
- // Unlocated label
- throw Kit.codeBug();
- }
- resolveGoto(jumpSource, pc);
- }
- itsFixupTableTop = 0;
- }
-
- private void addBackwardGoto(int gotoOp, int jumpPC)
- {
- int fromPC = itsICodeTop;
- // Ensure that this is a jump backward
- if (fromPC <= jumpPC) throw Kit.codeBug();
- addGotoOp(gotoOp);
- resolveGoto(fromPC, jumpPC);
- }
-
- private void resolveForwardGoto(int fromPC)
- {
- // Ensure that forward jump skips at least self bytecode
- if (itsICodeTop < fromPC + 3) throw Kit.codeBug();
- resolveGoto(fromPC, itsICodeTop);
- }
-
- private void resolveGoto(int fromPC, int jumpPC)
- {
- int offset = jumpPC - fromPC;
- // Ensure that jumps do not overlap
- if (0 <= offset && offset <= 2) throw Kit.codeBug();
- int offsetSite = fromPC + 1;
- if (offset != (short)offset) {
- if (itsData.longJumps == null) {
- itsData.longJumps = new UintMap();
- }
- itsData.longJumps.put(offsetSite, jumpPC);
- offset = 0;
- }
- byte[] array = itsData.itsICode;
- array[offsetSite] = (byte)(offset >> 8);
- array[offsetSite + 1] = (byte)offset;
- }
-
- private void addToken(int token)
- {
- if (!validTokenCode(token)) throw Kit.codeBug();
- addUint8(token);
- }
-
- private void addIcode(int icode)
- {
- if (!validIcode(icode)) throw Kit.codeBug();
- // Write negative icode as uint8 bits
- addUint8(icode & 0xFF);
- }
-
- private void addUint8(int value)
- {
- if ((value & ~0xFF) != 0) throw Kit.codeBug();
- byte[] array = itsData.itsICode;
- int top = itsICodeTop;
- if (top == array.length) {
- array = increaseICodeCapacity(1);
- }
- array[top] = (byte)value;
- itsICodeTop = top + 1;
- }
-
- private void addUint16(int value)
- {
- if ((value & ~0xFFFF) != 0) throw Kit.codeBug();
- byte[] array = itsData.itsICode;
- int top = itsICodeTop;
- if (top + 2 > array.length) {
- array = increaseICodeCapacity(2);
- }
- array[top] = (byte)(value >>> 8);
- array[top + 1] = (byte)value;
- itsICodeTop = top + 2;
- }
-
- private void addInt(int i)
- {
- byte[] array = itsData.itsICode;
- int top = itsICodeTop;
- if (top + 4 > array.length) {
- array = increaseICodeCapacity(4);
- }
- array[top] = (byte)(i >>> 24);
- array[top + 1] = (byte)(i >>> 16);
- array[top + 2] = (byte)(i >>> 8);
- array[top + 3] = (byte)i;
- itsICodeTop = top + 4;
- }
-
- private int getDoubleIndex(double num)
- {
- int index = itsDoubleTableTop;
- if (index == 0) {
- itsData.itsDoubleTable = new double[64];
- } else if (itsData.itsDoubleTable.length == index) {
- double[] na = new double[index * 2];
- System.arraycopy(itsData.itsDoubleTable, 0, na, 0, index);
- itsData.itsDoubleTable = na;
- }
- itsData.itsDoubleTable[index] = num;
- itsDoubleTableTop = index + 1;
- return index;
- }
-
- private void addGotoOp(int gotoOp)
- {
- byte[] array = itsData.itsICode;
- int top = itsICodeTop;
- if (top + 3 > array.length) {
- array = increaseICodeCapacity(3);
- }
- array[top] = (byte)gotoOp;
- // Offset would written later
- itsICodeTop = top + 1 + 2;
- }
-
- private void addVarOp(int op, int varIndex)
- {
- switch (op) {
- case Token.SETCONSTVAR:
- if (varIndex < 128) {
- addIcode(Icode_SETCONSTVAR1);
- addUint8(varIndex);
- return;
- }
- addIndexOp(Icode_SETCONSTVAR, varIndex);
- return;
- case Token.GETVAR:
- case Token.SETVAR:
- if (varIndex < 128) {
- addIcode(op == Token.GETVAR ? Icode_GETVAR1 : Icode_SETVAR1);
- addUint8(varIndex);
- return;
- }
- // fallthrough
- case Icode_VAR_INC_DEC:
- addIndexOp(op, varIndex);
- return;
- }
- throw Kit.codeBug();
- }
-
- private void addStringOp(int op, String str)
- {
- addStringPrefix(str);
- if (validIcode(op)) {
- addIcode(op);
- } else {
- addToken(op);
- }
- }
-
- private void addIndexOp(int op, int index)
- {
- addIndexPrefix(index);
- if (validIcode(op)) {
- addIcode(op);
- } else {
- addToken(op);
- }
- }
-
- private void addStringPrefix(String str)
- {
- int index = itsStrings.get(str, -1);
- if (index == -1) {
- index = itsStrings.size();
- itsStrings.put(str, index);
- }
- if (index < 4) {
- addIcode(Icode_REG_STR_C0 - index);
- } else if (index <= 0xFF) {
- addIcode(Icode_REG_STR1);
- addUint8(index);
- } else if (index <= 0xFFFF) {
- addIcode(Icode_REG_STR2);
- addUint16(index);
- } else {
- addIcode(Icode_REG_STR4);
- addInt(index);
- }
- }
-
- private void addIndexPrefix(int index)
- {
- if (index < 0) Kit.codeBug();
- if (index < 6) {
- addIcode(Icode_REG_IND_C0 - index);
- } else if (index <= 0xFF) {
- addIcode(Icode_REG_IND1);
- addUint8(index);
- } else if (index <= 0xFFFF) {
- addIcode(Icode_REG_IND2);
- addUint16(index);
- } else {
- addIcode(Icode_REG_IND4);
- addInt(index);
- }
- }
-
- private void addExceptionHandler(int icodeStart, int icodeEnd,
- int handlerStart, boolean isFinally,
- int exceptionObjectLocal, int scopeLocal)
- {
- int top = itsExceptionTableTop;
- int[] table = itsData.itsExceptionTable;
- if (table == null) {
- if (top != 0) Kit.codeBug();
- table = new int[EXCEPTION_SLOT_SIZE * 2];
- itsData.itsExceptionTable = table;
- } else if (table.length == top) {
- table = new int[table.length * 2];
- System.arraycopy(itsData.itsExceptionTable, 0, table, 0, top);
- itsData.itsExceptionTable = table;
- }
- table[top + EXCEPTION_TRY_START_SLOT] = icodeStart;
- table[top + EXCEPTION_TRY_END_SLOT] = icodeEnd;
- table[top + EXCEPTION_HANDLER_SLOT] = handlerStart;
- table[top + EXCEPTION_TYPE_SLOT] = isFinally ? 1 : 0;
- table[top + EXCEPTION_LOCAL_SLOT] = exceptionObjectLocal;
- table[top + EXCEPTION_SCOPE_SLOT] = scopeLocal;
-
- itsExceptionTableTop = top + EXCEPTION_SLOT_SIZE;
- }
-
- private byte[] increaseICodeCapacity(int extraSize)
- {
- int capacity = itsData.itsICode.length;
- int top = itsICodeTop;
- if (top + extraSize <= capacity) throw Kit.codeBug();
- capacity *= 2;
- if (top + extraSize > capacity) {
- capacity = top + extraSize;
- }
- byte[] array = new byte[capacity];
- System.arraycopy(itsData.itsICode, 0, array, 0, top);
- itsData.itsICode = array;
- return array;
- }
-
- private void stackChange(int change)
- {
- if (change <= 0) {
- itsStackDepth += change;
- } else {
- int newDepth = itsStackDepth + change;
- if (newDepth > itsData.itsMaxStack) {
- itsData.itsMaxStack = newDepth;
- }
- itsStackDepth = newDepth;
- }
- }
-
- private int allocLocal()
- {
- int localSlot = itsLocalTop;
- ++itsLocalTop;
- if (itsLocalTop > itsData.itsMaxLocals) {
- itsData.itsMaxLocals = itsLocalTop;
- }
- return localSlot;
- }
-
- private void releaseLocal(int localSlot)
- {
- --itsLocalTop;
- if (localSlot != itsLocalTop) Kit.codeBug();
- }
-
- private static int getShort(byte[] iCode, int pc) {
- return (iCode[pc] << 8) | (iCode[pc + 1] & 0xFF);
- }
-
- private static int getIndex(byte[] iCode, int pc) {
- return ((iCode[pc] & 0xFF) << 8) | (iCode[pc + 1] & 0xFF);
- }
-
- private static int getInt(byte[] iCode, int pc) {
- return (iCode[pc] << 24) | ((iCode[pc + 1] & 0xFF) << 16)
- | ((iCode[pc + 2] & 0xFF) << 8) | (iCode[pc + 3] & 0xFF);
- }
-
- private static int getExceptionHandler(CallFrame frame,
- boolean onlyFinally)
- {
- int[] exceptionTable = frame.idata.itsExceptionTable;
- if (exceptionTable == null) {
- // No exception handlers
- return -1;
- }
-
- // Icode switch in the interpreter increments PC immediately
- // and it is necessary to subtract 1 from the saved PC
- // to point it before the start of the next instruction.
- int pc = frame.pc - 1;
-
- // OPT: use binary search
- int best = -1, bestStart = 0, bestEnd = 0;
- for (int i = 0; i != exceptionTable.length; i += EXCEPTION_SLOT_SIZE) {
- int start = exceptionTable[i + EXCEPTION_TRY_START_SLOT];
- int end = exceptionTable[i + EXCEPTION_TRY_END_SLOT];
- if (!(start <= pc && pc < end)) {
- continue;
- }
- if (onlyFinally && exceptionTable[i + EXCEPTION_TYPE_SLOT] != 1) {
- continue;
- }
- if (best >= 0) {
- // Since handlers always nest and they never have shared end
- // although they can share start it is sufficient to compare
- // handlers ends
- if (bestEnd < end) {
- continue;
- }
- // Check the above assumption
- if (bestStart > start) Kit.codeBug(); // should be nested
- if (bestEnd == end) Kit.codeBug(); // no ens sharing
- }
- best = i;
- bestStart = start;
- bestEnd = end;
- }
- return best;
- }
-
- private static void dumpICode(InterpreterData idata)
- {
- if (!Token.printICode) {
- return;
- }
-
- byte iCode[] = idata.itsICode;
- int iCodeLength = iCode.length;
- String[] strings = idata.itsStringTable;
- PrintStream out = System.out;
- out.println("ICode dump, for " + idata.itsName
- + ", length = " + iCodeLength);
- out.println("MaxStack = " + idata.itsMaxStack);
-
- int indexReg = 0;
- for (int pc = 0; pc < iCodeLength; ) {
- out.flush();
- out.print(" [" + pc + "] ");
- int token = iCode[pc];
- int icodeLength = bytecodeSpan(token);
- String tname = bytecodeName(token);
- int old_pc = pc;
- ++pc;
- switch (token) {
- default:
- if (icodeLength != 1) Kit.codeBug();
- out.println(tname);
- break;
-
- case Icode_GOSUB :
- case Token.GOTO :
- case Token.IFEQ :
- case Token.IFNE :
- case Icode_IFEQ_POP :
- case Icode_LEAVEDQ : {
- int newPC = pc + getShort(iCode, pc) - 1;
- out.println(tname + " " + newPC);
- pc += 2;
- break;
- }
- case Icode_VAR_INC_DEC :
- case Icode_NAME_INC_DEC :
- case Icode_PROP_INC_DEC :
- case Icode_ELEM_INC_DEC :
- case Icode_REF_INC_DEC: {
- int incrDecrType = iCode[pc];
- out.println(tname + " " + incrDecrType);
- ++pc;
- break;
- }
-
- case Icode_CALLSPECIAL : {
- int callType = iCode[pc] & 0xFF;
- boolean isNew = (iCode[pc + 1] != 0);
- int line = getIndex(iCode, pc+2);
- out.println(tname+" "+callType+" "+isNew+" "+indexReg+" "+line);
- pc += 4;
- break;
- }
-
- case Token.CATCH_SCOPE:
- {
- boolean afterFisrtFlag = (iCode[pc] != 0);
- out.println(tname+" "+afterFisrtFlag);
- ++pc;
- }
- break;
- case Token.REGEXP :
- out.println(tname+" "+idata.itsRegExpLiterals[indexReg]);
- break;
- case Token.OBJECTLIT :
- case Icode_SPARE_ARRAYLIT :
- out.println(tname+" "+idata.literalIds[indexReg]);
- break;
- case Icode_CLOSURE_EXPR :
- case Icode_CLOSURE_STMT :
- out.println(tname+" "+idata.itsNestedFunctions[indexReg]);
- break;
- case Token.CALL :
- case Icode_TAIL_CALL :
- case Token.REF_CALL :
- case Token.NEW :
- out.println(tname+' '+indexReg);
- break;
- case Token.THROW :
- case Token.YIELD :
- case Icode_GENERATOR :
- case Icode_GENERATOR_END :
- {
- int line = getIndex(iCode, pc);
- out.println(tname + " : " + line);
- pc += 2;
- break;
- }
- case Icode_SHORTNUMBER : {
- int value = getShort(iCode, pc);
- out.println(tname + " " + value);
- pc += 2;
- break;
- }
- case Icode_INTNUMBER : {
- int value = getInt(iCode, pc);
- out.println(tname + " " + value);
- pc += 4;
- break;
- }
- case Token.NUMBER : {
- double value = idata.itsDoubleTable[indexReg];
- out.println(tname + " " + value);
- break;
- }
- case Icode_LINE : {
- int line = getIndex(iCode, pc);
- out.println(tname + " : " + line);
- pc += 2;
- break;
- }
- case Icode_REG_STR1: {
- String str = strings[0xFF & iCode[pc]];
- out.println(tname + " \"" + str + '"');
- ++pc;
- break;
- }
- case Icode_REG_STR2: {
- String str = strings[getIndex(iCode, pc)];
- out.println(tname + " \"" + str + '"');
- pc += 2;
- break;
- }
- case Icode_REG_STR4: {
- String str = strings[getInt(iCode, pc)];
- out.println(tname + " \"" + str + '"');
- pc += 4;
- break;
- }
- case Icode_REG_IND_C0:
- indexReg = 0;
- out.println(tname);
- break;
- case Icode_REG_IND_C1:
- indexReg = 1;
- out.println(tname);
- break;
- case Icode_REG_IND_C2:
- indexReg = 2;
- out.println(tname);
- break;
- case Icode_REG_IND_C3:
- indexReg = 3;
- out.println(tname);
- break;
- case Icode_REG_IND_C4:
- indexReg = 4;
- out.println(tname);
- break;
- case Icode_REG_IND_C5:
- indexReg = 5;
- out.println(tname);
- break;
- case Icode_REG_IND1: {
- indexReg = 0xFF & iCode[pc];
- out.println(tname+" "+indexReg);
- ++pc;
- break;
- }
- case Icode_REG_IND2: {
- indexReg = getIndex(iCode, pc);
- out.println(tname+" "+indexReg);
- pc += 2;
- break;
- }
- case Icode_REG_IND4: {
- indexReg = getInt(iCode, pc);
- out.println(tname+" "+indexReg);
- pc += 4;
- break;
- }
- case Icode_GETVAR1:
- case Icode_SETVAR1:
- case Icode_SETCONSTVAR1:
- indexReg = iCode[pc];
- out.println(tname+" "+indexReg);
- ++pc;
- break;
- }
- if (old_pc + icodeLength != pc) Kit.codeBug();
- }
-
- int[] table = idata.itsExceptionTable;
- if (table != null) {
- out.println("Exception handlers: "
- +table.length / EXCEPTION_SLOT_SIZE);
- for (int i = 0; i != table.length;
- i += EXCEPTION_SLOT_SIZE)
- {
- int tryStart = table[i + EXCEPTION_TRY_START_SLOT];
- int tryEnd = table[i + EXCEPTION_TRY_END_SLOT];
- int handlerStart = table[i + EXCEPTION_HANDLER_SLOT];
- int type = table[i + EXCEPTION_TYPE_SLOT];
- int exceptionLocal = table[i + EXCEPTION_LOCAL_SLOT];
- int scopeLocal = table[i + EXCEPTION_SCOPE_SLOT];
-
- out.println(" tryStart="+tryStart+" tryEnd="+tryEnd
- +" handlerStart="+handlerStart
- +" type="+(type == 0 ? "catch" : "finally")
- +" exceptionLocal="+exceptionLocal);
- }
- }
- out.flush();
- }
-
- private static int bytecodeSpan(int bytecode)
- {
- switch (bytecode) {
- case Token.THROW :
- case Token.YIELD:
- case Icode_GENERATOR:
- case Icode_GENERATOR_END:
- // source line
- return 1 + 2;
-
- case Icode_GOSUB :
- case Token.GOTO :
- case Token.IFEQ :
- case Token.IFNE :
- case Icode_IFEQ_POP :
- case Icode_LEAVEDQ :
- // target pc offset
- return 1 + 2;
-
- case Icode_CALLSPECIAL :
- // call type
- // is new
- // line number
- return 1 + 1 + 1 + 2;
-
- case Token.CATCH_SCOPE:
- // scope flag
- return 1 + 1;
-
- case Icode_VAR_INC_DEC:
- case Icode_NAME_INC_DEC:
- case Icode_PROP_INC_DEC:
- case Icode_ELEM_INC_DEC:
- case Icode_REF_INC_DEC:
- // type of ++/--
- return 1 + 1;
-
- case Icode_SHORTNUMBER :
- // short number
- return 1 + 2;
-
- case Icode_INTNUMBER :
- // int number
- return 1 + 4;
-
- case Icode_REG_IND1:
- // ubyte index
- return 1 + 1;
-
- case Icode_REG_IND2:
- // ushort index
- return 1 + 2;
-
- case Icode_REG_IND4:
- // int index
- return 1 + 4;
-
- case Icode_REG_STR1:
- // ubyte string index
- return 1 + 1;
-
- case Icode_REG_STR2:
- // ushort string index
- return 1 + 2;
-
- case Icode_REG_STR4:
- // int string index
- return 1 + 4;
-
- case Icode_GETVAR1:
- case Icode_SETVAR1:
- case Icode_SETCONSTVAR1:
- // byte var index
- return 1 + 1;
-
- case Icode_LINE :
- // line number
- return 1 + 2;
- }
- if (!validBytecode(bytecode)) throw Kit.codeBug();
- return 1;
- }
-
- static int[] getLineNumbers(InterpreterData data)
- {
- UintMap presentLines = new UintMap();
-
- byte[] iCode = data.itsICode;
- int iCodeLength = iCode.length;
- for (int pc = 0; pc != iCodeLength;) {
- int bytecode = iCode[pc];
- int span = bytecodeSpan(bytecode);
- if (bytecode == Icode_LINE) {
- if (span != 3) Kit.codeBug();
- int line = getIndex(iCode, pc + 1);
- presentLines.put(line, 0);
- }
- pc += span;
- }
-
- return presentLines.getKeys();
- }
-
- public void captureStackInfo(RhinoException ex)
- {
- Context cx = Context.getCurrentContext();
- if (cx == null || cx.lastInterpreterFrame == null) {
- // No interpreter invocations
- ex.interpreterStackInfo = null;
- ex.interpreterLineData = null;
- return;
- }
- // has interpreter frame on the stack
- CallFrame[] array;
- if (cx.previousInterpreterInvocations == null
- || cx.previousInterpreterInvocations.size() == 0)
- {
- array = new CallFrame[1];
- } else {
- int previousCount = cx.previousInterpreterInvocations.size();
- if (cx.previousInterpreterInvocations.peek()
- == cx.lastInterpreterFrame)
- {
- // It can happen if exception was generated after
- // frame was pushed to cx.previousInterpreterInvocations
- // but before assignment to cx.lastInterpreterFrame.
- // In this case frames has to be ignored.
- --previousCount;
- }
- array = new CallFrame[previousCount + 1];
- cx.previousInterpreterInvocations.toArray(array);
- }
- array[array.length - 1] = (CallFrame)cx.lastInterpreterFrame;
-
- int interpreterFrameCount = 0;
- for (int i = 0; i != array.length; ++i) {
- interpreterFrameCount += 1 + array[i].frameIndex;
- }
-
- int[] linePC = new int[interpreterFrameCount];
- // Fill linePC with pc positions from all interpreter frames.
- // Start from the most nested frame
- int linePCIndex = interpreterFrameCount;
- for (int i = array.length; i != 0;) {
- --i;
- CallFrame frame = array[i];
- while (frame != null) {
- --linePCIndex;
- linePC[linePCIndex] = frame.pcSourceLineStart;
- frame = frame.parentFrame;
- }
- }
- if (linePCIndex != 0) Kit.codeBug();
-
- ex.interpreterStackInfo = array;
- ex.interpreterLineData = linePC;
- }
-
- public String getSourcePositionFromStack(Context cx, int[] linep)
- {
- CallFrame frame = (CallFrame)cx.lastInterpreterFrame;
- InterpreterData idata = frame.idata;
- if (frame.pcSourceLineStart >= 0) {
- linep[0] = getIndex(idata.itsICode, frame.pcSourceLineStart);
- } else {
- linep[0] = 0;
- }
- return idata.itsSourceFile;
- }
-
- public String getPatchedStack(RhinoException ex,
- String nativeStackTrace)
- {
- String tag = "org.mozilla.javascript.Interpreter.interpretLoop";
- StringBuffer sb = new StringBuffer(nativeStackTrace.length() + 1000);
- String lineSeparator = SecurityUtilities.getSystemProperty("line.separator");
-
- CallFrame[] array = (CallFrame[])ex.interpreterStackInfo;
- int[] linePC = ex.interpreterLineData;
- int arrayIndex = array.length;
- int linePCIndex = linePC.length;
- int offset = 0;
- while (arrayIndex != 0) {
- --arrayIndex;
- int pos = nativeStackTrace.indexOf(tag, offset);
- if (pos < 0) {
- break;
- }
-
- // Skip tag length
- pos += tag.length();
- // Skip until the end of line
- for (; pos != nativeStackTrace.length(); ++pos) {
- char c = nativeStackTrace.charAt(pos);
- if (c == '\n' || c == '\r') {
- break;
- }
- }
- sb.append(nativeStackTrace.substring(offset, pos));
- offset = pos;
-
- CallFrame frame = array[arrayIndex];
- while (frame != null) {
- if (linePCIndex == 0) Kit.codeBug();
- --linePCIndex;
- InterpreterData idata = frame.idata;
- sb.append(lineSeparator);
- sb.append("\tat script");
- if (idata.itsName != null && idata.itsName.length() != 0) {
- sb.append('.');
- sb.append(idata.itsName);
- }
- sb.append('(');
- sb.append(idata.itsSourceFile);
- int pc = linePC[linePCIndex];
- if (pc >= 0) {
- // Include line info only if available
- sb.append(':');
- sb.append(getIndex(idata.itsICode, pc));
- }
- sb.append(')');
- frame = frame.parentFrame;
- }
- }
- sb.append(nativeStackTrace.substring(offset));
-
- return sb.toString();
- }
-
- public List getScriptStack(RhinoException ex)
- {
- if (ex.interpreterStackInfo == null) {
- return null;
- }
-
- List list = new ArrayList();
- String lineSeparator =
- SecurityUtilities.getSystemProperty("line.separator");
-
- CallFrame[] array = (CallFrame[])ex.interpreterStackInfo;
- int[] linePC = ex.interpreterLineData;
- int arrayIndex = array.length;
- int linePCIndex = linePC.length;
- while (arrayIndex != 0) {
- --arrayIndex;
- StringBuffer sb = new StringBuffer();
- CallFrame frame = array[arrayIndex];
- while (frame != null) {
- if (linePCIndex == 0) Kit.codeBug();
- --linePCIndex;
- InterpreterData idata = frame.idata;
- sb.append("\tat ");
- sb.append(idata.itsSourceFile);
- int pc = linePC[linePCIndex];
- if (pc >= 0) {
- // Include line info only if available
- sb.append(':');
- sb.append(getIndex(idata.itsICode, pc));
- }
- if (idata.itsName != null && idata.itsName.length() != 0) {
- sb.append(" (");
- sb.append(idata.itsName);
- sb.append(')');
- }
- sb.append(lineSeparator);
- frame = frame.parentFrame;
- }
- list.add(sb.toString());
- }
- return list;
- }
-
- static String getEncodedSource(InterpreterData idata)
- {
- if (idata.encodedSource == null) {
- return null;
- }
- return idata.encodedSource.substring(idata.encodedSourceStart,
- idata.encodedSourceEnd);
- }
-
- private static void initFunction(Context cx, Scriptable scope,
- InterpretedFunction parent, int index)
- {
- InterpretedFunction fn;
- fn = InterpretedFunction.createFunction(cx, scope, parent, index);
- ScriptRuntime.initFunction(cx, scope, fn, fn.idata.itsFunctionType,
- parent.idata.evalScriptFlag);
- }
-
- static Object interpret(InterpretedFunction ifun,
- Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!ScriptRuntime.hasTopCall(cx)) Kit.codeBug();
-
- if (cx.interpreterSecurityDomain != ifun.securityDomain) {
- Object savedDomain = cx.interpreterSecurityDomain;
- cx.interpreterSecurityDomain = ifun.securityDomain;
- try {
- return ifun.securityController.callWithDomain(
- ifun.securityDomain, cx, ifun, scope, thisObj, args);
- } finally {
- cx.interpreterSecurityDomain = savedDomain;
- }
- }
-
- CallFrame frame = new CallFrame();
- initFrame(cx, scope, thisObj, args, null, 0, args.length,
- ifun, null, frame);
-
- return interpretLoop(cx, frame, null);
- }
-
- static class GeneratorState {
- GeneratorState(int operation, Object value) {
- this.operation = operation;
- this.value = value;
- }
- int operation;
- Object value;
- RuntimeException returnedException;
- }
-
- public static Object resumeGenerator(Context cx,
- Scriptable scope,
- int operation,
- Object savedState,
- Object value)
- {
- CallFrame frame = (CallFrame) savedState;
- GeneratorState generatorState = new GeneratorState(operation, value);
- if (operation == NativeGenerator.GENERATOR_CLOSE) {
- try {
- return interpretLoop(cx, frame, generatorState);
- } catch (RuntimeException e) {
- // Only propagate exceptions other than closingException
- if (e != value)
- throw e;
- }
- return Undefined.instance;
- }
- Object result = interpretLoop(cx, frame, generatorState);
- if (generatorState.returnedException != null)
- throw generatorState.returnedException;
- return result;
- }
-
- public static Object restartContinuation(Continuation c, Context cx,
- Scriptable scope, Object[] args)
- {
- if (!ScriptRuntime.hasTopCall(cx)) {
- return ScriptRuntime.doTopCall(c, cx, scope, null, args);
- }
-
- Object arg;
- if (args.length == 0) {
- arg = Undefined.instance;
- } else {
- arg = args[0];
- }
-
- CallFrame capturedFrame = (CallFrame)c.getImplementation();
- if (capturedFrame == null) {
- // No frames to restart
- return arg;
- }
-
- ContinuationJump cjump = new ContinuationJump(c, null);
-
- cjump.result = arg;
- return interpretLoop(cx, null, cjump);
- }
-
- private static Object interpretLoop(Context cx, CallFrame frame,
- Object throwable)
- {
- // throwable holds exception object to rethrow or catch
- // It is also used for continuation restart in which case
- // it holds ContinuationJump
-
- final Object DBL_MRK = UniqueTag.DOUBLE_MARK;
- final Object undefined = Undefined.instance;
-
- final boolean instructionCounting = (cx.instructionThreshold != 0);
- // arbitrary number to add to instructionCount when calling
- // other functions
- final int INVOCATION_COST = 100;
- // arbitrary exception cost for instruction counting
- final int EXCEPTION_COST = 100;
-
- String stringReg = null;
- int indexReg = -1;
-
- if (cx.lastInterpreterFrame != null) {
- // save the top frame from the previous interpretLoop
- // invocation on the stack
- if (cx.previousInterpreterInvocations == null) {
- cx.previousInterpreterInvocations = new ObjArray();
- }
- cx.previousInterpreterInvocations.push(cx.lastInterpreterFrame);
- }
-
- // When restarting continuation throwable is not null and to jump
- // to the code that rewind continuation state indexReg should be set
- // to -1.
- // With the normal call throable == null and indexReg == -1 allows to
- // catch bugs with using indeReg to access array eleemnts before
- // initializing indexReg.
-
- GeneratorState generatorState = null;
- if (throwable != null) {
- if (throwable instanceof GeneratorState) {
- generatorState = (GeneratorState) throwable;
-
- // reestablish this call frame
- enterFrame(cx, frame, ScriptRuntime.emptyArgs, true);
- throwable = null;
- } else if (!(throwable instanceof ContinuationJump)) {
- // It should be continuation
- Kit.codeBug();
- }
- }
-
- Object interpreterResult = null;
- double interpreterResultDbl = 0.0;
-
- StateLoop: for (;;) {
- withoutExceptions: try {
-
- if (throwable != null) {
- // Need to return both 'frame' and 'throwable' from
- // 'processThrowable', so just added a 'throwable'
- // member in 'frame'.
- frame = processThrowable(cx, throwable, frame, indexReg,
- instructionCounting);
- throwable = frame.throwable;
- frame.throwable = null;
- } else {
- if (generatorState == null && frame.frozen) Kit.codeBug();
- }
-
- // Use local variables for constant values in frame
- // for faster access
- Object[] stack = frame.stack;
- double[] sDbl = frame.sDbl;
- Object[] vars = frame.varSource.stack;
- double[] varDbls = frame.varSource.sDbl;
- int[] varAttributes = frame.varSource.stackAttributes;
- byte[] iCode = frame.idata.itsICode;
- String[] strings = frame.idata.itsStringTable;
-
- // Use local for stackTop as well. Since execption handlers
- // can only exist at statement level where stack is empty,
- // it is necessary to save/restore stackTop only across
- // function calls and normal returns.
- int stackTop = frame.savedStackTop;
-
- // Store new frame in cx which is used for error reporting etc.
- cx.lastInterpreterFrame = frame;
-
- Loop: for (;;) {
-
- // Exception handler assumes that PC is already incremented
- // pass the instruction start when it searches the
- // exception handler
- int op = iCode[frame.pc++];
- jumplessRun: {
-
- // Back indent to ease implementation reading
-switch (op) {
- case Icode_GENERATOR: {
- if (!frame.frozen) {
- // First time encountering this opcode: create new generator
- // object and return
- frame.pc--; // we want to come back here when we resume
- CallFrame generatorFrame = captureFrameForGenerator(frame);
- generatorFrame.frozen = true;
- NativeGenerator generator = new NativeGenerator(frame.scope,
- generatorFrame.fnOrScript, generatorFrame);
- frame.result = generator;
- break Loop;
- } else {
- // We are now resuming execution. Fall through to YIELD case.
- }
- }
- // fall through...
- case Token.YIELD: {
- if (!frame.frozen) {
- return freezeGenerator(cx, frame, stackTop, generatorState);
- } else {
- Object obj = thawGenerator(frame, stackTop, generatorState, op);
- if (obj != Scriptable.NOT_FOUND) {
- throwable = obj;
- break withoutExceptions;
- }
- continue Loop;
- }
- }
- case Icode_GENERATOR_END: {
- // throw StopIteration
- frame.frozen = true;
- int sourceLine = getIndex(iCode, frame.pc);
- generatorState.returnedException = new JavaScriptException(
- NativeIterator.getStopIterationObject(frame.scope),
- frame.idata.itsSourceFile, sourceLine);
- break Loop;
- }
- case Token.THROW: {
- Object value = stack[stackTop];
- if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
-
- int sourceLine = getIndex(iCode, frame.pc);
- throwable = new JavaScriptException(value,
- frame.idata.itsSourceFile,
- sourceLine);
- break withoutExceptions;
- }
- case Token.RETHROW: {
- indexReg += frame.localShift;
- throwable = stack[indexReg];
- break withoutExceptions;
- }
- case Token.GE :
- case Token.LE :
- case Token.GT :
- case Token.LT : {
- --stackTop;
- Object rhs = stack[stackTop + 1];
- Object lhs = stack[stackTop];
- boolean valBln;
- object_compare:
- {
- number_compare:
- {
- double rDbl, lDbl;
- if (rhs == DBL_MRK) {
- rDbl = sDbl[stackTop + 1];
- lDbl = stack_double(frame, stackTop);
- } else if (lhs == DBL_MRK) {
- rDbl = ScriptRuntime.toNumber(rhs);
- lDbl = sDbl[stackTop];
- } else {
- break number_compare;
- }
- switch (op) {
- case Token.GE:
- valBln = (lDbl >= rDbl);
- break object_compare;
- case Token.LE:
- valBln = (lDbl <= rDbl);
- break object_compare;
- case Token.GT:
- valBln = (lDbl > rDbl);
- break object_compare;
- case Token.LT:
- valBln = (lDbl < rDbl);
- break object_compare;
- default:
- throw Kit.codeBug();
- }
- }
- switch (op) {
- case Token.GE:
- valBln = ScriptRuntime.cmp_LE(rhs, lhs);
- break;
- case Token.LE:
- valBln = ScriptRuntime.cmp_LE(lhs, rhs);
- break;
- case Token.GT:
- valBln = ScriptRuntime.cmp_LT(rhs, lhs);
- break;
- case Token.LT:
- valBln = ScriptRuntime.cmp_LT(lhs, rhs);
- break;
- default:
- throw Kit.codeBug();
- }
- }
- stack[stackTop] = ScriptRuntime.wrapBoolean(valBln);
- continue Loop;
- }
- case Token.IN :
- case Token.INSTANCEOF : {
- Object rhs = stack[stackTop];
- if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- boolean valBln;
- if (op == Token.IN) {
- valBln = ScriptRuntime.in(lhs, rhs, cx);
- } else {
- valBln = ScriptRuntime.instanceOf(lhs, rhs, cx);
- }
- stack[stackTop] = ScriptRuntime.wrapBoolean(valBln);
- continue Loop;
- }
- case Token.EQ :
- case Token.NE : {
- --stackTop;
- boolean valBln;
- Object rhs = stack[stackTop + 1];
- Object lhs = stack[stackTop];
- if (rhs == DBL_MRK) {
- if (lhs == DBL_MRK) {
- valBln = (sDbl[stackTop] == sDbl[stackTop + 1]);
- } else {
- valBln = ScriptRuntime.eqNumber(sDbl[stackTop + 1], lhs);
- }
- } else {
- if (lhs == DBL_MRK) {
- valBln = ScriptRuntime.eqNumber(sDbl[stackTop], rhs);
- } else {
- valBln = ScriptRuntime.eq(lhs, rhs);
- }
- }
- valBln ^= (op == Token.NE);
- stack[stackTop] = ScriptRuntime.wrapBoolean(valBln);
- continue Loop;
- }
- case Token.SHEQ :
- case Token.SHNE : {
- --stackTop;
- Object rhs = stack[stackTop + 1];
- Object lhs = stack[stackTop];
- boolean valBln;
- shallow_compare: {
- double rdbl, ldbl;
- if (rhs == DBL_MRK) {
- rdbl = sDbl[stackTop + 1];
- if (lhs == DBL_MRK) {
- ldbl = sDbl[stackTop];
- } else if (lhs instanceof Number) {
- ldbl = ((Number)lhs).doubleValue();
- } else {
- valBln = false;
- break shallow_compare;
- }
- } else if (lhs == DBL_MRK) {
- ldbl = sDbl[stackTop];
- if (rhs == DBL_MRK) {
- rdbl = sDbl[stackTop + 1];
- } else if (rhs instanceof Number) {
- rdbl = ((Number)rhs).doubleValue();
- } else {
- valBln = false;
- break shallow_compare;
- }
- } else {
- valBln = ScriptRuntime.shallowEq(lhs, rhs);
- break shallow_compare;
- }
- valBln = (ldbl == rdbl);
- }
- valBln ^= (op == Token.SHNE);
- stack[stackTop] = ScriptRuntime.wrapBoolean(valBln);
- continue Loop;
- }
- case Token.IFNE :
- if (stack_boolean(frame, stackTop--)) {
- frame.pc += 2;
- continue Loop;
- }
- break jumplessRun;
- case Token.IFEQ :
- if (!stack_boolean(frame, stackTop--)) {
- frame.pc += 2;
- continue Loop;
- }
- break jumplessRun;
- case Icode_IFEQ_POP :
- if (!stack_boolean(frame, stackTop--)) {
- frame.pc += 2;
- continue Loop;
- }
- stack[stackTop--] = null;
- break jumplessRun;
- case Token.GOTO :
- break jumplessRun;
- case Icode_GOSUB :
- ++stackTop;
- stack[stackTop] = DBL_MRK;
- sDbl[stackTop] = frame.pc + 2;
- break jumplessRun;
- case Icode_STARTSUB :
- if (stackTop == frame.emptyStackTop + 1) {
- // Call from Icode_GOSUB: store return PC address in the local
- indexReg += frame.localShift;
- stack[indexReg] = stack[stackTop];
- sDbl[indexReg] = sDbl[stackTop];
- --stackTop;
- } else {
- // Call from exception handler: exception object is already stored
- // in the local
- if (stackTop != frame.emptyStackTop) Kit.codeBug();
- }
- continue Loop;
- case Icode_RETSUB : {
- // indexReg: local to store return address
- if (instructionCounting) {
- addInstructionCount(cx, frame, 0);
- }
- indexReg += frame.localShift;
- Object value = stack[indexReg];
- if (value != DBL_MRK) {
- // Invocation from exception handler, restore object to rethrow
- throwable = value;
- break withoutExceptions;
- }
- // Normal return from GOSUB
- frame.pc = (int)sDbl[indexReg];
- if (instructionCounting) {
- frame.pcPrevBranch = frame.pc;
- }
- continue Loop;
- }
- case Icode_POP :
- stack[stackTop] = null;
- stackTop--;
- continue Loop;
- case Icode_POP_RESULT :
- frame.result = stack[stackTop];
- frame.resultDbl = sDbl[stackTop];
- stack[stackTop] = null;
- --stackTop;
- continue Loop;
- case Icode_DUP :
- stack[stackTop + 1] = stack[stackTop];
- sDbl[stackTop + 1] = sDbl[stackTop];
- stackTop++;
- continue Loop;
- case Icode_DUP2 :
- stack[stackTop + 1] = stack[stackTop - 1];
- sDbl[stackTop + 1] = sDbl[stackTop - 1];
- stack[stackTop + 2] = stack[stackTop];
- sDbl[stackTop + 2] = sDbl[stackTop];
- stackTop += 2;
- continue Loop;
- case Icode_SWAP : {
- Object o = stack[stackTop];
- stack[stackTop] = stack[stackTop - 1];
- stack[stackTop - 1] = o;
- double d = sDbl[stackTop];
- sDbl[stackTop] = sDbl[stackTop - 1];
- sDbl[stackTop - 1] = d;
- continue Loop;
- }
- case Token.RETURN :
- frame.result = stack[stackTop];
- frame.resultDbl = sDbl[stackTop];
- --stackTop;
- break Loop;
- case Token.RETURN_RESULT :
- break Loop;
- case Icode_RETUNDEF :
- frame.result = undefined;
- break Loop;
- case Token.BITNOT : {
- int rIntValue = stack_int32(frame, stackTop);
- stack[stackTop] = DBL_MRK;
- sDbl[stackTop] = ~rIntValue;
- continue Loop;
- }
- case Token.BITAND :
- case Token.BITOR :
- case Token.BITXOR :
- case Token.LSH :
- case Token.RSH : {
- int lIntValue = stack_int32(frame, stackTop-1);
- int rIntValue = stack_int32(frame, stackTop);
- stack[--stackTop] = DBL_MRK;
- switch (op) {
- case Token.BITAND:
- lIntValue &= rIntValue;
- break;
- case Token.BITOR:
- lIntValue |= rIntValue;
- break;
- case Token.BITXOR:
- lIntValue ^= rIntValue;
- break;
- case Token.LSH:
- lIntValue <<= rIntValue;
- break;
- case Token.RSH:
- lIntValue >>= rIntValue;
- break;
- }
- sDbl[stackTop] = lIntValue;
- continue Loop;
- }
- case Token.URSH : {
- double lDbl = stack_double(frame, stackTop-1);
- int rIntValue = stack_int32(frame, stackTop) & 0x1F;
- stack[--stackTop] = DBL_MRK;
- sDbl[stackTop] = ScriptRuntime.toUint32(lDbl) >>> rIntValue;
- continue Loop;
- }
- case Token.NEG :
- case Token.POS : {
- double rDbl = stack_double(frame, stackTop);
- stack[stackTop] = DBL_MRK;
- if (op == Token.NEG) {
- rDbl = -rDbl;
- }
- sDbl[stackTop] = rDbl;
- continue Loop;
- }
- case Token.ADD :
- --stackTop;
- do_add(stack, sDbl, stackTop, cx);
- continue Loop;
- case Token.SUB :
- case Token.MUL :
- case Token.DIV :
- case Token.MOD : {
- double rDbl = stack_double(frame, stackTop);
- --stackTop;
- double lDbl = stack_double(frame, stackTop);
- stack[stackTop] = DBL_MRK;
- switch (op) {
- case Token.SUB:
- lDbl -= rDbl;
- break;
- case Token.MUL:
- lDbl *= rDbl;
- break;
- case Token.DIV:
- lDbl /= rDbl;
- break;
- case Token.MOD:
- lDbl %= rDbl;
- break;
- }
- sDbl[stackTop] = lDbl;
- continue Loop;
- }
- case Token.NOT :
- stack[stackTop] = ScriptRuntime.wrapBoolean(
- !stack_boolean(frame, stackTop));
- continue Loop;
- case Token.BINDNAME :
- stack[++stackTop] = ScriptRuntime.bind(cx, frame.scope, stringReg);
- continue Loop;
- case Token.SETNAME : {
- Object rhs = stack[stackTop];
- if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- Scriptable lhs = (Scriptable)stack[stackTop];
- stack[stackTop] = ScriptRuntime.setName(lhs, rhs, cx,
- frame.scope, stringReg);
- continue Loop;
- }
- case Icode_SETCONST: {
- Object rhs = stack[stackTop];
- if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- Scriptable lhs = (Scriptable)stack[stackTop];
- stack[stackTop] = ScriptRuntime.setConst(lhs, rhs, cx, stringReg);
- continue Loop;
- }
- case Token.DELPROP : {
- Object rhs = stack[stackTop];
- if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.delete(lhs, rhs, cx);
- continue Loop;
- }
- case Token.GETPROPNOWARN : {
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.getObjectPropNoWarn(lhs, stringReg, cx);
- continue Loop;
- }
- case Token.GETPROP : {
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.getObjectProp(lhs, stringReg, cx);
- continue Loop;
- }
- case Token.SETPROP : {
- Object rhs = stack[stackTop];
- if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.setObjectProp(lhs, stringReg, rhs,
- cx);
- continue Loop;
- }
- case Icode_PROP_INC_DEC : {
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.propIncrDecr(lhs, stringReg,
- cx, iCode[frame.pc]);
- ++frame.pc;
- continue Loop;
- }
- case Token.GETELEM : {
- --stackTop;
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) {
- lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- }
- Object value;
- Object id = stack[stackTop + 1];
- if (id != DBL_MRK) {
- value = ScriptRuntime.getObjectElem(lhs, id, cx);
- } else {
- double d = sDbl[stackTop + 1];
- value = ScriptRuntime.getObjectIndex(lhs, d, cx);
- }
- stack[stackTop] = value;
- continue Loop;
- }
- case Token.SETELEM : {
- stackTop -= 2;
- Object rhs = stack[stackTop + 2];
- if (rhs == DBL_MRK) {
- rhs = ScriptRuntime.wrapNumber(sDbl[stackTop + 2]);
- }
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) {
- lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- }
- Object value;
- Object id = stack[stackTop + 1];
- if (id != DBL_MRK) {
- value = ScriptRuntime.setObjectElem(lhs, id, rhs, cx);
- } else {
- double d = sDbl[stackTop + 1];
- value = ScriptRuntime.setObjectIndex(lhs, d, rhs, cx);
- }
- stack[stackTop] = value;
- continue Loop;
- }
- case Icode_ELEM_INC_DEC: {
- Object rhs = stack[stackTop];
- if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.elemIncrDecr(lhs, rhs, cx,
- iCode[frame.pc]);
- ++frame.pc;
- continue Loop;
- }
- case Token.GET_REF : {
- Ref ref = (Ref)stack[stackTop];
- stack[stackTop] = ScriptRuntime.refGet(ref, cx);
- continue Loop;
- }
- case Token.SET_REF : {
- Object value = stack[stackTop];
- if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- Ref ref = (Ref)stack[stackTop];
- stack[stackTop] = ScriptRuntime.refSet(ref, value, cx);
- continue Loop;
- }
- case Token.DEL_REF : {
- Ref ref = (Ref)stack[stackTop];
- stack[stackTop] = ScriptRuntime.refDel(ref, cx);
- continue Loop;
- }
- case Icode_REF_INC_DEC : {
- Ref ref = (Ref)stack[stackTop];
- stack[stackTop] = ScriptRuntime.refIncrDecr(ref, cx, iCode[frame.pc]);
- ++frame.pc;
- continue Loop;
- }
- case Token.LOCAL_LOAD :
- ++stackTop;
- indexReg += frame.localShift;
- stack[stackTop] = stack[indexReg];
- sDbl[stackTop] = sDbl[indexReg];
- continue Loop;
- case Icode_LOCAL_CLEAR :
- indexReg += frame.localShift;
- stack[indexReg] = null;
- continue Loop;
- case Icode_NAME_AND_THIS :
- // stringReg: name
- ++stackTop;
- stack[stackTop] = ScriptRuntime.getNameFunctionAndThis(stringReg,
- cx, frame.scope);
- ++stackTop;
- stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx);
- continue Loop;
- case Icode_PROP_AND_THIS: {
- Object obj = stack[stackTop];
- if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- // stringReg: property
- stack[stackTop] = ScriptRuntime.getPropFunctionAndThis(obj, stringReg,
- cx);
- ++stackTop;
- stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx);
- continue Loop;
- }
- case Icode_ELEM_AND_THIS: {
- Object obj = stack[stackTop - 1];
- if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop - 1]);
- Object id = stack[stackTop];
- if (id == DBL_MRK) id = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop - 1] = ScriptRuntime.getElemFunctionAndThis(obj, id, cx);
- stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx);
- continue Loop;
- }
- case Icode_VALUE_AND_THIS : {
- Object value = stack[stackTop];
- if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.getValueFunctionAndThis(value, cx);
- ++stackTop;
- stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx);
- continue Loop;
- }
- case Icode_CALLSPECIAL : {
- if (instructionCounting) {
- cx.instructionCount += INVOCATION_COST;
- }
- int callType = iCode[frame.pc] & 0xFF;
- boolean isNew = (iCode[frame.pc + 1] != 0);
- int sourceLine = getIndex(iCode, frame.pc + 2);
-
- // indexReg: number of arguments
- if (isNew) {
- // stack change: function arg0 .. argN -> newResult
- stackTop -= indexReg;
-
- Object function = stack[stackTop];
- if (function == DBL_MRK)
- function = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- Object[] outArgs = getArgsArray(
- stack, sDbl, stackTop + 1, indexReg);
- stack[stackTop] = ScriptRuntime.newSpecial(
- cx, function, outArgs, frame.scope, callType);
- } else {
- // stack change: function thisObj arg0 .. argN -> result
- stackTop -= 1 + indexReg;
-
- // Call code generation ensure that stack here
- // is ... Callable Scriptable
- Scriptable functionThis = (Scriptable)stack[stackTop + 1];
- Callable function = (Callable)stack[stackTop];
- Object[] outArgs = getArgsArray(
- stack, sDbl, stackTop + 2, indexReg);
- stack[stackTop] = ScriptRuntime.callSpecial(
- cx, function, functionThis, outArgs,
- frame.scope, frame.thisObj, callType,
- frame.idata.itsSourceFile, sourceLine);
- }
- frame.pc += 4;
- continue Loop;
- }
- case Token.CALL :
- case Icode_TAIL_CALL :
- case Token.REF_CALL : {
- if (instructionCounting) {
- cx.instructionCount += INVOCATION_COST;
- }
- // stack change: function thisObj arg0 .. argN -> result
- // indexReg: number of arguments
- stackTop -= 1 + indexReg;
-
- // CALL generation ensures that fun and funThisObj
- // are already Scriptable and Callable objects respectively
- Callable fun = (Callable)stack[stackTop];
- Scriptable funThisObj = (Scriptable)stack[stackTop + 1];
- if (op == Token.REF_CALL) {
- Object[] outArgs = getArgsArray(stack, sDbl, stackTop + 2,
- indexReg);
- stack[stackTop] = ScriptRuntime.callRef(fun, funThisObj,
- outArgs, cx);
- continue Loop;
- }
- Scriptable calleeScope = frame.scope;
- if (frame.useActivation) {
- calleeScope = ScriptableObject.getTopLevelScope(frame.scope);
- }
- if (fun instanceof InterpretedFunction) {
- InterpretedFunction ifun = (InterpretedFunction)fun;
- if (frame.fnOrScript.securityDomain == ifun.securityDomain) {
- CallFrame callParentFrame = frame;
- CallFrame calleeFrame = new CallFrame();
- if (op == Icode_TAIL_CALL) {
- // In principle tail call can re-use the current
- // frame and its stack arrays but it is hard to
- // do properly. Any exceptions that can legally
- // happen during frame re-initialization including
- // StackOverflowException during innocent looking
- // System.arraycopy may leave the current frame
- // data corrupted leading to undefined behaviour
- // in the catch code bellow that unwinds JS stack
- // on exceptions. Then there is issue about frame release
- // end exceptions there.
- // To avoid frame allocation a released frame
- // can be cached for re-use which would also benefit
- // non-tail calls but it is not clear that this caching
- // would gain in performance due to potentially
- // bad interaction with GC.
- callParentFrame = frame.parentFrame;
- // Release the current frame. See Bug #344501 to see why
- // it is being done here.
- exitFrame(cx, frame, null);
- }
- initFrame(cx, calleeScope, funThisObj, stack, sDbl,
- stackTop + 2, indexReg, ifun, callParentFrame,
- calleeFrame);
- if (op != Icode_TAIL_CALL) {
- frame.savedStackTop = stackTop;
- frame.savedCallOp = op;
- }
- frame = calleeFrame;
- continue StateLoop;
- }
- }
-
- if (fun instanceof Continuation) {
- // Jump to the captured continuation
- ContinuationJump cjump;
- cjump = new ContinuationJump((Continuation)fun, frame);
-
- // continuation result is the first argument if any
- // of contination call
- if (indexReg == 0) {
- cjump.result = undefined;
- } else {
- cjump.result = stack[stackTop + 2];
- cjump.resultDbl = sDbl[stackTop + 2];
- }
-
- // Start the real unwind job
- throwable = cjump;
- break withoutExceptions;
- }
-
- if (fun instanceof IdFunctionObject) {
- IdFunctionObject ifun = (IdFunctionObject)fun;
- if (Continuation.isContinuationConstructor(ifun)) {
- captureContinuation(cx, frame, stackTop);
- continue Loop;
- }
- // Bug 405654 -- make best effort to keep Function.apply and
- // Function.call within this interpreter loop invocation
- if(BaseFunction.isApplyOrCall(ifun)) {
- Callable applyCallable = ScriptRuntime.getCallable(funThisObj);
- if(applyCallable instanceof InterpretedFunction) {
- InterpretedFunction iApplyCallable = (InterpretedFunction)applyCallable;
- if(frame.fnOrScript.securityDomain == iApplyCallable.securityDomain) {
- frame = initFrameForApplyOrCall(cx, frame, indexReg,
- stack, sDbl, stackTop, op, calleeScope, ifun,
- iApplyCallable);
- continue StateLoop;
- }
- }
- }
- }
-
- stack[stackTop] = fun.call(cx, calleeScope, funThisObj,
- getArgsArray(stack, sDbl, stackTop + 2, indexReg));
-
- continue Loop;
- }
- case Token.NEW : {
- if (instructionCounting) {
- cx.instructionCount += INVOCATION_COST;
- }
- // stack change: function arg0 .. argN -> newResult
- // indexReg: number of arguments
- stackTop -= indexReg;
-
- Object lhs = stack[stackTop];
- if (lhs instanceof InterpretedFunction) {
- InterpretedFunction f = (InterpretedFunction)lhs;
- if (frame.fnOrScript.securityDomain == f.securityDomain) {
- Scriptable newInstance = f.createObject(cx, frame.scope);
- CallFrame calleeFrame = new CallFrame();
- initFrame(cx, frame.scope, newInstance, stack, sDbl,
- stackTop + 1, indexReg, f, frame,
- calleeFrame);
-
- stack[stackTop] = newInstance;
- frame.savedStackTop = stackTop;
- frame.savedCallOp = op;
- frame = calleeFrame;
- continue StateLoop;
- }
- }
- if (!(lhs instanceof Function)) {
- if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- throw ScriptRuntime.notFunctionError(lhs);
- }
- Function fun = (Function)lhs;
-
- if (fun instanceof IdFunctionObject) {
- IdFunctionObject ifun = (IdFunctionObject)fun;
- if (Continuation.isContinuationConstructor(ifun)) {
- captureContinuation(cx, frame, stackTop);
- continue Loop;
- }
- }
-
- Object[] outArgs = getArgsArray(stack, sDbl, stackTop + 1, indexReg);
- stack[stackTop] = fun.construct(cx, frame.scope, outArgs);
- continue Loop;
- }
- case Token.TYPEOF : {
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.typeof(lhs);
- continue Loop;
- }
- case Icode_TYPEOFNAME :
- stack[++stackTop] = ScriptRuntime.typeofName(frame.scope, stringReg);
- continue Loop;
- case Token.STRING :
- stack[++stackTop] = stringReg;
- continue Loop;
- case Icode_SHORTNUMBER :
- ++stackTop;
- stack[stackTop] = DBL_MRK;
- sDbl[stackTop] = getShort(iCode, frame.pc);
- frame.pc += 2;
- continue Loop;
- case Icode_INTNUMBER :
- ++stackTop;
- stack[stackTop] = DBL_MRK;
- sDbl[stackTop] = getInt(iCode, frame.pc);
- frame.pc += 4;
- continue Loop;
- case Token.NUMBER :
- ++stackTop;
- stack[stackTop] = DBL_MRK;
- sDbl[stackTop] = frame.idata.itsDoubleTable[indexReg];
- continue Loop;
- case Token.NAME :
- stack[++stackTop] = ScriptRuntime.name(cx, frame.scope, stringReg);
- continue Loop;
- case Icode_NAME_INC_DEC :
- stack[++stackTop] = ScriptRuntime.nameIncrDecr(frame.scope, stringReg,
- cx, iCode[frame.pc]);
- ++frame.pc;
- continue Loop;
- case Icode_SETCONSTVAR1:
- indexReg = iCode[frame.pc++];
- // fallthrough
- case Token.SETCONSTVAR :
- if (!frame.useActivation) {
- if ((varAttributes[indexReg] & ScriptableObject.READONLY) == 0) {
- throw Context.reportRuntimeError1("msg.var.redecl",
- frame.idata.argNames[indexReg]);
- }
- if ((varAttributes[indexReg] & ScriptableObject.UNINITIALIZED_CONST)
- != 0)
- {
- vars[indexReg] = stack[stackTop];
- varAttributes[indexReg] &= ~ScriptableObject.UNINITIALIZED_CONST;
- varDbls[indexReg] = sDbl[stackTop];
- }
- } else {
- Object val = stack[stackTop];
- if (val == DBL_MRK) val = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stringReg = frame.idata.argNames[indexReg];
- if (frame.scope instanceof ConstProperties) {
- ConstProperties cp = (ConstProperties)frame.scope;
- cp.putConst(stringReg, frame.scope, val);
- } else
- throw Kit.codeBug();
- }
- continue Loop;
- case Icode_SETVAR1:
- indexReg = iCode[frame.pc++];
- // fallthrough
- case Token.SETVAR :
- if (!frame.useActivation) {
- if ((varAttributes[indexReg] & ScriptableObject.READONLY) == 0) {
- vars[indexReg] = stack[stackTop];
- varDbls[indexReg] = sDbl[stackTop];
- }
- } else {
- Object val = stack[stackTop];
- if (val == DBL_MRK) val = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stringReg = frame.idata.argNames[indexReg];
- frame.scope.put(stringReg, frame.scope, val);
- }
- continue Loop;
- case Icode_GETVAR1:
- indexReg = iCode[frame.pc++];
- // fallthrough
- case Token.GETVAR :
- ++stackTop;
- if (!frame.useActivation) {
- stack[stackTop] = vars[indexReg];
- sDbl[stackTop] = varDbls[indexReg];
- } else {
- stringReg = frame.idata.argNames[indexReg];
- stack[stackTop] = frame.scope.get(stringReg, frame.scope);
- }
- continue Loop;
- case Icode_VAR_INC_DEC : {
- // indexReg : varindex
- ++stackTop;
- int incrDecrMask = iCode[frame.pc];
- if (!frame.useActivation) {
- stack[stackTop] = DBL_MRK;
- Object varValue = vars[indexReg];
- double d;
- if (varValue == DBL_MRK) {
- d = varDbls[indexReg];
- } else {
- d = ScriptRuntime.toNumber(varValue);
- vars[indexReg] = DBL_MRK;
- }
- double d2 = ((incrDecrMask & Node.DECR_FLAG) == 0)
- ? d + 1.0 : d - 1.0;
- varDbls[indexReg] = d2;
- sDbl[stackTop] = ((incrDecrMask & Node.POST_FLAG) == 0) ? d2 : d;
- } else {
- String varName = frame.idata.argNames[indexReg];
- stack[stackTop] = ScriptRuntime.nameIncrDecr(frame.scope, varName,
- cx, incrDecrMask);
- }
- ++frame.pc;
- continue Loop;
- }
- case Icode_ZERO :
- ++stackTop;
- stack[stackTop] = DBL_MRK;
- sDbl[stackTop] = 0;
- continue Loop;
- case Icode_ONE :
- ++stackTop;
- stack[stackTop] = DBL_MRK;
- sDbl[stackTop] = 1;
- continue Loop;
- case Token.NULL :
- stack[++stackTop] = null;
- continue Loop;
- case Token.THIS :
- stack[++stackTop] = frame.thisObj;
- continue Loop;
- case Token.THISFN :
- stack[++stackTop] = frame.fnOrScript;
- continue Loop;
- case Token.FALSE :
- stack[++stackTop] = Boolean.FALSE;
- continue Loop;
- case Token.TRUE :
- stack[++stackTop] = Boolean.TRUE;
- continue Loop;
- case Icode_UNDEF :
- stack[++stackTop] = undefined;
- continue Loop;
- case Token.ENTERWITH : {
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- frame.scope = ScriptRuntime.enterWith(lhs, cx, frame.scope);
- continue Loop;
- }
- case Token.LEAVEWITH :
- frame.scope = ScriptRuntime.leaveWith(frame.scope);
- continue Loop;
- case Token.CATCH_SCOPE : {
- // stack top: exception object
- // stringReg: name of exception variable
- // indexReg: local for exception scope
- --stackTop;
- indexReg += frame.localShift;
-
- boolean afterFirstScope = (frame.idata.itsICode[frame.pc] != 0);
- Throwable caughtException = (Throwable)stack[stackTop + 1];
- Scriptable lastCatchScope;
- if (!afterFirstScope) {
- lastCatchScope = null;
- } else {
- lastCatchScope = (Scriptable)stack[indexReg];
- }
- stack[indexReg] = ScriptRuntime.newCatchScope(caughtException,
- lastCatchScope, stringReg,
- cx, frame.scope);
- ++frame.pc;
- continue Loop;
- }
- case Token.ENUM_INIT_KEYS :
- case Token.ENUM_INIT_VALUES :
- case Token.ENUM_INIT_ARRAY : {
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- indexReg += frame.localShift;
- int enumType = op == Token.ENUM_INIT_KEYS
- ? ScriptRuntime.ENUMERATE_KEYS :
- op == Token.ENUM_INIT_VALUES
- ? ScriptRuntime.ENUMERATE_VALUES :
- ScriptRuntime.ENUMERATE_ARRAY;
- stack[indexReg] = ScriptRuntime.enumInit(lhs, cx, enumType);
- continue Loop;
- }
- case Token.ENUM_NEXT :
- case Token.ENUM_ID : {
- indexReg += frame.localShift;
- Object val = stack[indexReg];
- ++stackTop;
- stack[stackTop] = (op == Token.ENUM_NEXT)
- ? (Object)ScriptRuntime.enumNext(val)
- : (Object)ScriptRuntime.enumId(val, cx);
- continue Loop;
- }
- case Token.REF_SPECIAL : {
- //stringReg: name of special property
- Object obj = stack[stackTop];
- if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.specialRef(obj, stringReg, cx);
- continue Loop;
- }
- case Token.REF_MEMBER: {
- //indexReg: flags
- Object elem = stack[stackTop];
- if (elem == DBL_MRK) elem = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- Object obj = stack[stackTop];
- if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.memberRef(obj, elem, cx, indexReg);
- continue Loop;
- }
- case Token.REF_NS_MEMBER: {
- //indexReg: flags
- Object elem = stack[stackTop];
- if (elem == DBL_MRK) elem = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- Object ns = stack[stackTop];
- if (ns == DBL_MRK) ns = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- Object obj = stack[stackTop];
- if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.memberRef(obj, ns, elem, cx, indexReg);
- continue Loop;
- }
- case Token.REF_NAME: {
- //indexReg: flags
- Object name = stack[stackTop];
- if (name == DBL_MRK) name = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.nameRef(name, cx, frame.scope,
- indexReg);
- continue Loop;
- }
- case Token.REF_NS_NAME: {
- //indexReg: flags
- Object name = stack[stackTop];
- if (name == DBL_MRK) name = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- Object ns = stack[stackTop];
- if (ns == DBL_MRK) ns = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.nameRef(ns, name, cx, frame.scope,
- indexReg);
- continue Loop;
- }
- case Icode_SCOPE_LOAD :
- indexReg += frame.localShift;
- frame.scope = (Scriptable)stack[indexReg];
- continue Loop;
- case Icode_SCOPE_SAVE :
- indexReg += frame.localShift;
- stack[indexReg] = frame.scope;
- continue Loop;
- case Icode_CLOSURE_EXPR :
- stack[++stackTop] = InterpretedFunction.createFunction(cx, frame.scope,
- frame.fnOrScript,
- indexReg);
- continue Loop;
- case Icode_CLOSURE_STMT :
- initFunction(cx, frame.scope, frame.fnOrScript, indexReg);
- continue Loop;
- case Token.REGEXP :
- stack[++stackTop] = frame.scriptRegExps[indexReg];
- continue Loop;
- case Icode_LITERAL_NEW :
- // indexReg: number of values in the literal
- ++stackTop;
- stack[stackTop] = new int[indexReg];
- ++stackTop;
- stack[stackTop] = new Object[indexReg];
- sDbl[stackTop] = 0;
- continue Loop;
- case Icode_LITERAL_SET : {
- Object value = stack[stackTop];
- if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- int i = (int)sDbl[stackTop];
- ((Object[])stack[stackTop])[i] = value;
- sDbl[stackTop] = i + 1;
- continue Loop;
- }
- case Icode_LITERAL_GETTER : {
- Object value = stack[stackTop];
- --stackTop;
- int i = (int)sDbl[stackTop];
- ((Object[])stack[stackTop])[i] = value;
- ((int[])stack[stackTop - 1])[i] = -1;
- sDbl[stackTop] = i + 1;
- continue Loop;
- }
- case Icode_LITERAL_SETTER : {
- Object value = stack[stackTop];
- --stackTop;
- int i = (int)sDbl[stackTop];
- ((Object[])stack[stackTop])[i] = value;
- ((int[])stack[stackTop - 1])[i] = +1;
- sDbl[stackTop] = i + 1;
- continue Loop;
- }
- case Token.ARRAYLIT :
- case Icode_SPARE_ARRAYLIT :
- case Token.OBJECTLIT : {
- Object[] data = (Object[])stack[stackTop];
- --stackTop;
- int[] getterSetters = (int[])stack[stackTop];
- Object val;
- if (op == Token.OBJECTLIT) {
- Object[] ids = (Object[])frame.idata.literalIds[indexReg];
- val = ScriptRuntime.newObjectLiteral(ids, data, getterSetters, cx,
- frame.scope);
- } else {
- int[] skipIndexces = null;
- if (op == Icode_SPARE_ARRAYLIT) {
- skipIndexces = (int[])frame.idata.literalIds[indexReg];
- }
- val = ScriptRuntime.newArrayLiteral(data, skipIndexces, cx,
- frame.scope);
- }
- stack[stackTop] = val;
- continue Loop;
- }
- case Icode_ENTERDQ : {
- Object lhs = stack[stackTop];
- if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- --stackTop;
- frame.scope = ScriptRuntime.enterDotQuery(lhs, frame.scope);
- continue Loop;
- }
- case Icode_LEAVEDQ : {
- boolean valBln = stack_boolean(frame, stackTop);
- Object x = ScriptRuntime.updateDotQuery(valBln, frame.scope);
- if (x != null) {
- stack[stackTop] = x;
- frame.scope = ScriptRuntime.leaveDotQuery(frame.scope);
- frame.pc += 2;
- continue Loop;
- }
- // reset stack and PC to code after ENTERDQ
- --stackTop;
- break jumplessRun;
- }
- case Token.DEFAULTNAMESPACE : {
- Object value = stack[stackTop];
- if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
- stack[stackTop] = ScriptRuntime.setDefaultNamespace(value, cx);
- continue Loop;
- }
- case Token.ESCXMLATTR : {
- Object value = stack[stackTop];
- if (value != DBL_MRK) {
- stack[stackTop] = ScriptRuntime.escapeAttributeValue(value, cx);
- }
- continue Loop;
- }
- case Token.ESCXMLTEXT : {
- Object value = stack[stackTop];
- if (value != DBL_MRK) {
- stack[stackTop] = ScriptRuntime.escapeTextValue(value, cx);
- }
- continue Loop;
- }
- case Icode_DEBUGGER:
- if (frame.debuggerFrame != null) {
- frame.debuggerFrame.onDebuggerStatement(cx);
- }
- break Loop;
- case Icode_LINE :
- frame.pcSourceLineStart = frame.pc;
- if (frame.debuggerFrame != null) {
- int line = getIndex(iCode, frame.pc);
- frame.debuggerFrame.onLineChange(cx, line);
- }
- frame.pc += 2;
- continue Loop;
- case Icode_REG_IND_C0:
- indexReg = 0;
- continue Loop;
- case Icode_REG_IND_C1:
- indexReg = 1;
- continue Loop;
- case Icode_REG_IND_C2:
- indexReg = 2;
- continue Loop;
- case Icode_REG_IND_C3:
- indexReg = 3;
- continue Loop;
- case Icode_REG_IND_C4:
- indexReg = 4;
- continue Loop;
- case Icode_REG_IND_C5:
- indexReg = 5;
- continue Loop;
- case Icode_REG_IND1:
- indexReg = 0xFF & iCode[frame.pc];
- ++frame.pc;
- continue Loop;
- case Icode_REG_IND2:
- indexReg = getIndex(iCode, frame.pc);
- frame.pc += 2;
- continue Loop;
- case Icode_REG_IND4:
- indexReg = getInt(iCode, frame.pc);
- frame.pc += 4;
- continue Loop;
- case Icode_REG_STR_C0:
- stringReg = strings[0];
- continue Loop;
- case Icode_REG_STR_C1:
- stringReg = strings[1];
- continue Loop;
- case Icode_REG_STR_C2:
- stringReg = strings[2];
- continue Loop;
- case Icode_REG_STR_C3:
- stringReg = strings[3];
- continue Loop;
- case Icode_REG_STR1:
- stringReg = strings[0xFF & iCode[frame.pc]];
- ++frame.pc;
- continue Loop;
- case Icode_REG_STR2:
- stringReg = strings[getIndex(iCode, frame.pc)];
- frame.pc += 2;
- continue Loop;
- case Icode_REG_STR4:
- stringReg = strings[getInt(iCode, frame.pc)];
- frame.pc += 4;
- continue Loop;
- default :
- dumpICode(frame.idata);
- throw new RuntimeException(
- "Unknown icode : "+op+" @ pc : "+(frame.pc-1));
-} // end of interpreter switch
-
- } // end of jumplessRun label block
-
- // This should be reachable only for jump implementation
- // when pc points to encoded target offset
- if (instructionCounting) {
- addInstructionCount(cx, frame, 2);
- }
- int offset = getShort(iCode, frame.pc);
- if (offset != 0) {
- // -1 accounts for pc pointing to jump opcode + 1
- frame.pc += offset - 1;
- } else {
- frame.pc = frame.idata.longJumps.
- getExistingInt(frame.pc);
- }
- if (instructionCounting) {
- frame.pcPrevBranch = frame.pc;
- }
- continue Loop;
-
- } // end of Loop: for
-
- exitFrame(cx, frame, null);
- interpreterResult = frame.result;
- interpreterResultDbl = frame.resultDbl;
- if (frame.parentFrame != null) {
- frame = frame.parentFrame;
- if (frame.frozen) {
- frame = frame.cloneFrozen();
- }
- setCallResult(
- frame, interpreterResult, interpreterResultDbl);
- interpreterResult = null; // Help GC
- continue StateLoop;
- }
- break StateLoop;
-
- } // end of interpreter withoutExceptions: try
- catch (Throwable ex) {
- if (throwable != null) {
- // This is serious bug and it is better to track it ASAP
- ex.printStackTrace(System.err);
- throw new IllegalStateException();
- }
- throwable = ex;
- }
-
- // This should be reachable only after above catch or from
- // finally when it needs to propagate exception or from
- // explicit throw
- if (throwable == null) Kit.codeBug();
-
- // Exception type
- final int EX_CATCH_STATE = 2; // Can execute JS catch
- final int EX_FINALLY_STATE = 1; // Can execute JS finally
- final int EX_NO_JS_STATE = 0; // Terminate JS execution
-
- int exState;
- ContinuationJump cjump = null;
-
- if (generatorState != null &&
- generatorState.operation == NativeGenerator.GENERATOR_CLOSE &&
- throwable == generatorState.value)
- {
- exState = EX_FINALLY_STATE;
- } else if (throwable instanceof JavaScriptException) {
- exState = EX_CATCH_STATE;
- } else if (throwable instanceof EcmaError) {
- // an offical ECMA error object,
- exState = EX_CATCH_STATE;
- } else if (throwable instanceof EvaluatorException) {
- exState = EX_CATCH_STATE;
- } else if (throwable instanceof RuntimeException) {
- exState = cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS)
- ? EX_CATCH_STATE
- : EX_FINALLY_STATE;
- } else if (throwable instanceof Error) {
- exState = cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS)
- ? EX_CATCH_STATE
- : EX_NO_JS_STATE;
- } else if (throwable instanceof ContinuationJump) {
- // It must be ContinuationJump
- exState = EX_FINALLY_STATE;
- cjump = (ContinuationJump)throwable;
- } else {
- exState = cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS)
- ? EX_CATCH_STATE
- : EX_FINALLY_STATE;
- }
-
- if (instructionCounting) {
- try {
- addInstructionCount(cx, frame, EXCEPTION_COST);
- } catch (RuntimeException ex) {
- throwable = ex;
- exState = EX_FINALLY_STATE;
- } catch (Error ex) {
- // Error from instruction counting
- // => unconditionally terminate JS
- throwable = ex;
- cjump = null;
- exState = EX_NO_JS_STATE;
- }
- }
- if (frame.debuggerFrame != null
- && throwable instanceof RuntimeException)
- {
- // Call debugger only for RuntimeException
- RuntimeException rex = (RuntimeException)throwable;
- try {
- frame.debuggerFrame.onExceptionThrown(cx, rex);
- } catch (Throwable ex) {
- // Any exception from debugger
- // => unconditionally terminate JS
- throwable = ex;
- cjump = null;
- exState = EX_NO_JS_STATE;
- }
- }
-
- for (;;) {
- if (exState != EX_NO_JS_STATE) {
- boolean onlyFinally = (exState != EX_CATCH_STATE);
- indexReg = getExceptionHandler(frame, onlyFinally);
- if (indexReg >= 0) {
- // We caught an exception, restart the loop
- // with exception pending the processing at the loop
- // start
- continue StateLoop;
- }
- }
- // No allowed exception handlers in this frame, unwind
- // to parent and try to look there
-
- exitFrame(cx, frame, throwable);
-
- frame = frame.parentFrame;
- if (frame == null) { break; }
- if (cjump != null && cjump.branchFrame == frame) {
- // Continuation branch point was hit,
- // restart the state loop to reenter continuation
- indexReg = -1;
- continue StateLoop;
- }
- }
-
- // No more frames, rethrow the exception or deal with continuation
- if (cjump != null) {
- if (cjump.branchFrame != null) {
- // The above loop should locate the top frame
- Kit.codeBug();
- }
- if (cjump.capturedFrame != null) {
- // Restarting detached continuation
- indexReg = -1;
- continue StateLoop;
- }
- // Return continuation result to the caller
- interpreterResult = cjump.result;
- interpreterResultDbl = cjump.resultDbl;
- throwable = null;
- }
- break StateLoop;
-
- } // end of StateLoop: for(;;)
-
- // Do cleanups/restorations before the final return or throw
-
- if (cx.previousInterpreterInvocations != null
- && cx.previousInterpreterInvocations.size() != 0)
- {
- cx.lastInterpreterFrame
- = cx.previousInterpreterInvocations.pop();
- } else {
- // It was the last interpreter frame on the stack
- cx.lastInterpreterFrame = null;
- // Force GC of the value cx.previousInterpreterInvocations
- cx.previousInterpreterInvocations = null;
- }
-
- if (throwable != null) {
- if (throwable instanceof RuntimeException) {
- throw (RuntimeException)throwable;
- } else {
- // Must be instance of Error or code bug
- throw (Error)throwable;
- }
- }
-
- return (interpreterResult != DBL_MRK)
- ? interpreterResult
- : ScriptRuntime.wrapNumber(interpreterResultDbl);
- }
-
- private static CallFrame processThrowable(Context cx, Object throwable,
- CallFrame frame, int indexReg,
- boolean instructionCounting)
- {
- // Recovering from exception, indexReg contains
- // the index of handler
-
- if (indexReg >= 0) {
- // Normal exception handler, transfer
- // control appropriately
-
- if (frame.frozen) {
- // XXX Deal with exceptios!!!
- frame = frame.cloneFrozen();
- }
-
- int[] table = frame.idata.itsExceptionTable;
-
- frame.pc = table[indexReg + EXCEPTION_HANDLER_SLOT];
- if (instructionCounting) {
- frame.pcPrevBranch = frame.pc;
- }
-
- frame.savedStackTop = frame.emptyStackTop;
- int scopeLocal = frame.localShift
- + table[indexReg
- + EXCEPTION_SCOPE_SLOT];
- int exLocal = frame.localShift
- + table[indexReg
- + EXCEPTION_LOCAL_SLOT];
- frame.scope = (Scriptable)frame.stack[scopeLocal];
- frame.stack[exLocal] = throwable;
-
- throwable = null;
- } else {
- // Continuation restoration
- ContinuationJump cjump = (ContinuationJump)throwable;
-
- // Clear throwable to indicate that exceptions are OK
- throwable = null;
-
- if (cjump.branchFrame != frame) Kit.codeBug();
-
- // Check that we have at least one frozen frame
- // in the case of detached continuation restoration:
- // unwind code ensure that
- if (cjump.capturedFrame == null) Kit.codeBug();
-
- // Need to rewind branchFrame, capturedFrame
- // and all frames in between
- int rewindCount = cjump.capturedFrame.frameIndex + 1;
- if (cjump.branchFrame != null) {
- rewindCount -= cjump.branchFrame.frameIndex;
- }
-
- int enterCount = 0;
- CallFrame[] enterFrames = null;
-
- CallFrame x = cjump.capturedFrame;
- for (int i = 0; i != rewindCount; ++i) {
- if (!x.frozen) Kit.codeBug();
- if (isFrameEnterExitRequired(x)) {
- if (enterFrames == null) {
- // Allocate enough space to store the rest
- // of rewind frames in case all of them
- // would require to enter
- enterFrames = new CallFrame[rewindCount
- - i];
- }
- enterFrames[enterCount] = x;
- ++enterCount;
- }
- x = x.parentFrame;
- }
-
- while (enterCount != 0) {
- // execute enter: walk enterFrames in the reverse
- // order since they were stored starting from
- // the capturedFrame, not branchFrame
- --enterCount;
- x = enterFrames[enterCount];
- enterFrame(cx, x, ScriptRuntime.emptyArgs, true);
- }
-
- // Continuation jump is almost done: capturedFrame
- // points to the call to the function that captured
- // continuation, so clone capturedFrame and
- // emulate return that function with the suplied result
- frame = cjump.capturedFrame.cloneFrozen();
- setCallResult(frame, cjump.result, cjump.resultDbl);
- // restart the execution
- }
- frame.throwable = throwable;
- return frame;
- }
-
- private static Object freezeGenerator(Context cx, CallFrame frame,
- int stackTop,
- GeneratorState generatorState)
- {
- if (generatorState.operation == NativeGenerator.GENERATOR_CLOSE) {
- // Error: no yields when generator is closing
- throw ScriptRuntime.typeError0("msg.yield.closing");
- }
- // return to our caller (which should be a method of NativeGenerator)
- frame.frozen = true;
- frame.result = frame.stack[stackTop];
- frame.resultDbl = frame.sDbl[stackTop];
- frame.savedStackTop = stackTop;
- frame.pc--; // we want to come back here when we resume
- ScriptRuntime.exitActivationFunction(cx);
- return (frame.result != UniqueTag.DOUBLE_MARK)
- ? frame.result
- : ScriptRuntime.wrapNumber(frame.resultDbl);
- }
-
- private static Object thawGenerator(CallFrame frame, int stackTop,
- GeneratorState generatorState, int op)
- {
- // we are resuming execution
- frame.frozen = false;
- int sourceLine = getIndex(frame.idata.itsICode, frame.pc);
- frame.pc += 2; // skip line number data
- if (generatorState.operation == NativeGenerator.GENERATOR_THROW) {
- // processing a call to <generator>.throw(exception): must
- // act as if exception was thrown from resumption point
- return new JavaScriptException(generatorState.value,
- frame.idata.itsSourceFile,
- sourceLine);
- }
- if (generatorState.operation == NativeGenerator.GENERATOR_CLOSE) {
- return generatorState.value;
- }
- if (generatorState.operation != NativeGenerator.GENERATOR_SEND)
- throw Kit.codeBug();
- if (op == Token.YIELD)
- frame.stack[stackTop] = generatorState.value;
- return Scriptable.NOT_FOUND;
- }
-
- private static CallFrame initFrameForApplyOrCall(Context cx, CallFrame frame,
- int indexReg, Object[] stack, double[] sDbl, int stackTop, int op,
- Scriptable calleeScope, IdFunctionObject ifun,
- InterpretedFunction iApplyCallable)
- {
- Scriptable applyThis;
- if (indexReg != 0) {
- applyThis = ScriptRuntime.toObjectOrNull(cx, stack[stackTop + 2]);
- }
- else {
- applyThis = null;
- }
- if (applyThis == null) {
- // This covers the case of args[0] == (null|undefined) as well.
- applyThis = ScriptRuntime.getTopCallScope(cx);
- }
- if(op == Icode_TAIL_CALL) {
- exitFrame(cx, frame, null);
- frame = frame.parentFrame;
- }
- else {
- frame.savedStackTop = stackTop;
- frame.savedCallOp = op;
- }
- CallFrame calleeFrame = new CallFrame();
- if(BaseFunction.isApply(ifun)) {
- Object[] callArgs = indexReg < 2 ? ScriptRuntime.emptyArgs :
- ScriptRuntime.getApplyArguments(cx, stack[stackTop + 3]);
- initFrame(cx, calleeScope, applyThis, callArgs, null, 0,
- callArgs.length, iApplyCallable, frame, calleeFrame);
- }
- else {
- // Shift args left
- for(int i = 1; i < indexReg; ++i) {
- stack[stackTop + 1 + i] = stack[stackTop + 2 + i];
- sDbl[stackTop + 1 + i] = sDbl[stackTop + 2 + i];
- }
- int argCount = indexReg < 2 ? 0 : indexReg - 1;
- initFrame(cx, calleeScope, applyThis, stack, sDbl, stackTop + 2,
- argCount, iApplyCallable, frame, calleeFrame);
- }
-
- frame = calleeFrame;
- return frame;
- }
-
- private static void initFrame(Context cx, Scriptable callerScope,
- Scriptable thisObj,
- Object[] args, double[] argsDbl,
- int argShift, int argCount,
- InterpretedFunction fnOrScript,
- CallFrame parentFrame, CallFrame frame)
- {
- InterpreterData idata = fnOrScript.idata;
-
- boolean useActivation = idata.itsNeedsActivation;
- DebugFrame debuggerFrame = null;
- if (cx.debugger != null) {
- debuggerFrame = cx.debugger.getFrame(cx, idata);
- if (debuggerFrame != null) {
- useActivation = true;
- }
- }
-
- if (useActivation) {
- // Copy args to new array to pass to enterActivationFunction
- // or debuggerFrame.onEnter
- if (argsDbl != null) {
- args = getArgsArray(args, argsDbl, argShift, argCount);
- }
- argShift = 0;
- argsDbl = null;
- }
-
- Scriptable scope;
- if (idata.itsFunctionType != 0) {
- if (!idata.useDynamicScope) {
- scope = fnOrScript.getParentScope();
- } else {
- scope = callerScope;
- }
-
- if (useActivation) {
- scope = ScriptRuntime.createFunctionActivation(
- fnOrScript, scope, args);
- }
- } else {
- scope = callerScope;
- ScriptRuntime.initScript(fnOrScript, thisObj, cx, scope,
- fnOrScript.idata.evalScriptFlag);
- }
-
- if (idata.itsNestedFunctions != null) {
- if (idata.itsFunctionType != 0 && !idata.itsNeedsActivation)
- Kit.codeBug();
- for (int i = 0; i < idata.itsNestedFunctions.length; i++) {
- InterpreterData fdata = idata.itsNestedFunctions[i];
- if (fdata.itsFunctionType == FunctionNode.FUNCTION_STATEMENT) {
- initFunction(cx, scope, fnOrScript, i);
- }
- }
- }
-
- Scriptable[] scriptRegExps = null;
- if (idata.itsRegExpLiterals != null) {
- // Wrapped regexps for functions are stored in
- // InterpretedFunction
- // but for script which should not contain references to scope
- // the regexps re-wrapped during each script execution
- if (idata.itsFunctionType != 0) {
- scriptRegExps = fnOrScript.functionRegExps;
- } else {
- scriptRegExps = fnOrScript.createRegExpWraps(cx, scope);
- }
- }
-
- // Initialize args, vars, locals and stack
-
- int emptyStackTop = idata.itsMaxVars + idata.itsMaxLocals - 1;
- int maxFrameArray = idata.itsMaxFrameArray;
- if (maxFrameArray != emptyStackTop + idata.itsMaxStack + 1)
- Kit.codeBug();
-
- Object[] stack;
- int[] stackAttributes;
- double[] sDbl;
- boolean stackReuse;
- if (frame.stack != null && maxFrameArray <= frame.stack.length) {
- // Reuse stacks from old frame
- stackReuse = true;
- stack = frame.stack;
- stackAttributes = frame.stackAttributes;
- sDbl = frame.sDbl;
- } else {
- stackReuse = false;
- stack = new Object[maxFrameArray];
- stackAttributes = new int[maxFrameArray];
- sDbl = new double[maxFrameArray];
- }
-
- int varCount = idata.getParamAndVarCount();
- for (int i = 0; i < varCount; i++) {
- if (idata.getParamOrVarConst(i))
- stackAttributes[i] = ScriptableObject.CONST;
- }
- int definedArgs = idata.argCount;
- if (definedArgs > argCount) { definedArgs = argCount; }
-
- // Fill the frame structure
-
- frame.parentFrame = parentFrame;
- frame.frameIndex = (parentFrame == null)
- ? 0 : parentFrame.frameIndex + 1;
- if(frame.frameIndex > cx.getMaximumInterpreterStackDepth())
- {
- throw Context.reportRuntimeError("Exceeded maximum stack depth");
- }
- frame.frozen = false;
-
- frame.fnOrScript = fnOrScript;
- frame.idata = idata;
-
- frame.stack = stack;
- frame.stackAttributes = stackAttributes;
- frame.sDbl = sDbl;
- frame.varSource = frame;
- frame.localShift = idata.itsMaxVars;
- frame.emptyStackTop = emptyStackTop;
-
- frame.debuggerFrame = debuggerFrame;
- frame.useActivation = useActivation;
-
- frame.thisObj = thisObj;
- frame.scriptRegExps = scriptRegExps;
-
- // Initialize initial values of variables that change during
- // interpretation.
- frame.result = Undefined.instance;
- frame.pc = 0;
- frame.pcPrevBranch = 0;
- frame.pcSourceLineStart = idata.firstLinePC;
- frame.scope = scope;
-
- frame.savedStackTop = emptyStackTop;
- frame.savedCallOp = 0;
-
- System.arraycopy(args, argShift, stack, 0, definedArgs);
- if (argsDbl != null) {
- System.arraycopy(argsDbl, argShift, sDbl, 0, definedArgs);
- }
- for (int i = definedArgs; i != idata.itsMaxVars; ++i) {
- stack[i] = Undefined.instance;
- }
- if (stackReuse) {
- // Clean the stack part and space beyond stack if any
- // of the old array to allow to GC objects there
- for (int i = emptyStackTop + 1; i != stack.length; ++i) {
- stack[i] = null;
- }
- }
-
- enterFrame(cx, frame, args, false);
- }
-
- private static boolean isFrameEnterExitRequired(CallFrame frame)
- {
- return frame.debuggerFrame != null || frame.idata.itsNeedsActivation;
- }
-
- private static void enterFrame(Context cx, CallFrame frame, Object[] args,
- boolean continuationRestart)
- {
- boolean usesActivation = frame.idata.itsNeedsActivation;
- boolean isDebugged = frame.debuggerFrame != null;
- if(usesActivation || isDebugged) {
- Scriptable scope = frame.scope;
- if(scope == null) {
- Kit.codeBug();
- } else if (continuationRestart) {
- // Walk the parent chain of frame.scope until a NativeCall is
- // found. Normally, frame.scope is a NativeCall when called
- // from initFrame() for a debugged or activatable function.
- // However, when called from interpretLoop() as part of
- // restarting a continuation, it can also be a NativeWith if
- // the continuation was captured within a "with" or "catch"
- // block ("catch" implicitly uses NativeWith to create a scope
- // to expose the exception variable).
- for(;;) {
- if(scope instanceof NativeWith) {
- scope = scope.getParentScope();
- if (scope == null || (frame.parentFrame != null &&
- frame.parentFrame.scope == scope))
- {
- // If we get here, we didn't find a NativeCall in
- // the call chain before reaching parent frame's
- // scope. This should not be possible.
- Kit.codeBug();
- break; // Never reached, but keeps the static analyzer happy about "scope" not being null 5 lines above.
- }
- }
- else {
- break;
- }
- }
- }
- if (isDebugged) {
- frame.debuggerFrame.onEnter(cx, scope, frame.thisObj, args);
- }
- // Enter activation only when itsNeedsActivation true,
- // since debugger should not interfere with activation
- // chaining
- if (usesActivation) {
- ScriptRuntime.enterActivationFunction(cx, scope);
- }
- }
- }
-
- private static void exitFrame(Context cx, CallFrame frame,
- Object throwable)
- {
- if (frame.idata.itsNeedsActivation) {
- ScriptRuntime.exitActivationFunction(cx);
- }
-
- if (frame.debuggerFrame != null) {
- try {
- if (throwable instanceof Throwable) {
- frame.debuggerFrame.onExit(cx, true, throwable);
- } else {
- Object result;
- ContinuationJump cjump = (ContinuationJump)throwable;
- if (cjump == null) {
- result = frame.result;
- } else {
- result = cjump.result;
- }
- if (result == UniqueTag.DOUBLE_MARK) {
- double resultDbl;
- if (cjump == null) {
- resultDbl = frame.resultDbl;
- } else {
- resultDbl = cjump.resultDbl;
- }
- result = ScriptRuntime.wrapNumber(resultDbl);
- }
- frame.debuggerFrame.onExit(cx, false, result);
- }
- } catch (Throwable ex) {
- System.err.println(
-"RHINO USAGE WARNING: onExit terminated with exception");
- ex.printStackTrace(System.err);
- }
- }
- }
-
- private static void setCallResult(CallFrame frame,
- Object callResult,
- double callResultDbl)
- {
- if (frame.savedCallOp == Token.CALL) {
- frame.stack[frame.savedStackTop] = callResult;
- frame.sDbl[frame.savedStackTop] = callResultDbl;
- } else if (frame.savedCallOp == Token.NEW) {
- // If construct returns scriptable,
- // then it replaces on stack top saved original instance
- // of the object.
- if (callResult instanceof Scriptable) {
- frame.stack[frame.savedStackTop] = callResult;
- }
- } else {
- Kit.codeBug();
- }
- frame.savedCallOp = 0;
- }
-
- private static void captureContinuation(Context cx, CallFrame frame,
- int stackTop)
- {
- Continuation c = new Continuation();
- ScriptRuntime.setObjectProtoAndParent(
- c, ScriptRuntime.getTopCallScope(cx));
-
- // Make sure that all frames upstack frames are frozen
- CallFrame x = frame.parentFrame;
- while (x != null && !x.frozen) {
- x.frozen = true;
- // Allow to GC unused stack space
- for (int i = x.savedStackTop + 1; i != x.stack.length; ++i) {
- // Allow to GC unused stack space
- x.stack[i] = null;
- x.stackAttributes[i] = ScriptableObject.EMPTY;
- }
- if (x.savedCallOp == Token.CALL) {
- // the call will always overwrite the stack top with the result
- x.stack[x.savedStackTop] = null;
- } else {
- if (x.savedCallOp != Token.NEW) Kit.codeBug();
- // the new operator uses stack top to store the constructed
- // object so it shall not be cleared: see comments in
- // setCallResult
- }
- x = x.parentFrame;
- }
-
- c.initImplementation(frame.parentFrame);
- frame.stack[stackTop] = c;
- }
-
- private static int stack_int32(CallFrame frame, int i)
- {
- Object x = frame.stack[i];
- double value;
- if (x == UniqueTag.DOUBLE_MARK) {
- value = frame.sDbl[i];
- } else {
- value = ScriptRuntime.toNumber(x);
- }
- return ScriptRuntime.toInt32(value);
- }
-
- private static double stack_double(CallFrame frame, int i)
- {
- Object x = frame.stack[i];
- if (x != UniqueTag.DOUBLE_MARK) {
- return ScriptRuntime.toNumber(x);
- } else {
- return frame.sDbl[i];
- }
- }
-
- private static boolean stack_boolean(CallFrame frame, int i)
- {
- Object x = frame.stack[i];
- if (x == Boolean.TRUE) {
- return true;
- } else if (x == Boolean.FALSE) {
- return false;
- } else if (x == UniqueTag.DOUBLE_MARK) {
- double d = frame.sDbl[i];
- return d == d && d != 0.0;
- } else if (x == null || x == Undefined.instance) {
- return false;
- } else if (x instanceof Number) {
- double d = ((Number)x).doubleValue();
- return (d == d && d != 0.0);
- } else if (x instanceof Boolean) {
- return ((Boolean)x).booleanValue();
- } else {
- return ScriptRuntime.toBoolean(x);
- }
- }
-
- private static void do_add(Object[] stack, double[] sDbl, int stackTop,
- Context cx)
- {
- Object rhs = stack[stackTop + 1];
- Object lhs = stack[stackTop];
- double d;
- boolean leftRightOrder;
- if (rhs == UniqueTag.DOUBLE_MARK) {
- d = sDbl[stackTop + 1];
- if (lhs == UniqueTag.DOUBLE_MARK) {
- sDbl[stackTop] += d;
- return;
- }
- leftRightOrder = true;
- // fallthrough to object + number code
- } else if (lhs == UniqueTag.DOUBLE_MARK) {
- d = sDbl[stackTop];
- lhs = rhs;
- leftRightOrder = false;
- // fallthrough to object + number code
- } else {
- if (lhs instanceof Scriptable || rhs instanceof Scriptable) {
- stack[stackTop] = ScriptRuntime.add(lhs, rhs, cx);
- } else if (lhs instanceof String) {
- String lstr = (String)lhs;
- String rstr = ScriptRuntime.toString(rhs);
- stack[stackTop] = lstr.concat(rstr);
- } else if (rhs instanceof String) {
- String lstr = ScriptRuntime.toString(lhs);
- String rstr = (String)rhs;
- stack[stackTop] = lstr.concat(rstr);
- } else {
- double lDbl = (lhs instanceof Number)
- ? ((Number)lhs).doubleValue() : ScriptRuntime.toNumber(lhs);
- double rDbl = (rhs instanceof Number)
- ? ((Number)rhs).doubleValue() : ScriptRuntime.toNumber(rhs);
- stack[stackTop] = UniqueTag.DOUBLE_MARK;
- sDbl[stackTop] = lDbl + rDbl;
- }
- return;
- }
-
- // handle object(lhs) + number(d) code
- if (lhs instanceof Scriptable) {
- rhs = ScriptRuntime.wrapNumber(d);
- if (!leftRightOrder) {
- Object tmp = lhs;
- lhs = rhs;
- rhs = tmp;
- }
- stack[stackTop] = ScriptRuntime.add(lhs, rhs, cx);
- } else if (lhs instanceof String) {
- String lstr = (String)lhs;
- String rstr = ScriptRuntime.toString(d);
- if (leftRightOrder) {
- stack[stackTop] = lstr.concat(rstr);
- } else {
- stack[stackTop] = rstr.concat(lstr);
- }
- } else {
- double lDbl = (lhs instanceof Number)
- ? ((Number)lhs).doubleValue() : ScriptRuntime.toNumber(lhs);
- stack[stackTop] = UniqueTag.DOUBLE_MARK;
- sDbl[stackTop] = lDbl + d;
- }
- }
-
- private static Object[] getArgsArray(Object[] stack, double[] sDbl,
- int shift, int count)
- {
- if (count == 0) {
- return ScriptRuntime.emptyArgs;
- }
- Object[] args = new Object[count];
- for (int i = 0; i != count; ++i, ++shift) {
- Object val = stack[shift];
- if (val == UniqueTag.DOUBLE_MARK) {
- val = ScriptRuntime.wrapNumber(sDbl[shift]);
- }
- args[i] = val;
- }
- return args;
- }
-
- private static void addInstructionCount(Context cx, CallFrame frame,
- int extra)
- {
- cx.instructionCount += frame.pc - frame.pcPrevBranch + extra;
- if (cx.instructionCount > cx.instructionThreshold) {
- cx.observeInstructionCount(cx.instructionCount);
- cx.instructionCount = 0;
- }
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpreterData.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpreterData.java
deleted file mode 100644
index 7435b10..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpreterData.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- * Bob Jervis
- * Roger Lawrence
- *
- * 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;
-
-import java.io.Serializable;
-
-import org.mozilla.javascript.debug.DebuggableScript;
-
-final class InterpreterData implements Serializable, DebuggableScript
-{
- static final long serialVersionUID = 5067677351589230234L;
-
- static final int INITIAL_MAX_ICODE_LENGTH = 1024;
- static final int INITIAL_STRINGTABLE_SIZE = 64;
- static final int INITIAL_NUMBERTABLE_SIZE = 64;
-
- InterpreterData(int languageVersion,
- String sourceFile, String encodedSource)
- {
- this.languageVersion = languageVersion;
- this.itsSourceFile = sourceFile;
- this.encodedSource = encodedSource;
-
- init();
- }
-
- InterpreterData(InterpreterData parent)
- {
- this.parentData = parent;
- this.languageVersion = parent.languageVersion;
- this.itsSourceFile = parent.itsSourceFile;
- this.encodedSource = parent.encodedSource;
-
- init();
- }
-
- private void init()
- {
- itsICode = new byte[INITIAL_MAX_ICODE_LENGTH];
- itsStringTable = new String[INITIAL_STRINGTABLE_SIZE];
- }
-
- String itsName;
- String itsSourceFile;
- boolean itsNeedsActivation;
- int itsFunctionType;
-
- String[] itsStringTable;
- double[] itsDoubleTable;
- InterpreterData[] itsNestedFunctions;
- Object[] itsRegExpLiterals;
-
- byte[] itsICode;
-
- int[] itsExceptionTable;
-
- int itsMaxVars;
- int itsMaxLocals;
- int itsMaxStack;
- int itsMaxFrameArray;
-
- // see comments in NativeFuncion for definition of argNames and argCount
- String[] argNames;
- boolean[] argIsConst;
- int argCount;
-
- int itsMaxCalleeArgs;
-
- String encodedSource;
- int encodedSourceStart;
- int encodedSourceEnd;
-
- int languageVersion;
-
- boolean useDynamicScope;
-
- boolean topLevel;
-
- Object[] literalIds;
-
- UintMap longJumps;
-
- int firstLinePC = -1; // PC for the first LINE icode
-
- InterpreterData parentData;
-
- boolean evalScriptFlag; // true if script corresponds to eval() code
-
- public boolean isTopLevel()
- {
- return topLevel;
- }
-
- public boolean isFunction()
- {
- return itsFunctionType != 0;
- }
-
- public String getFunctionName()
- {
- return itsName;
- }
-
- public int getParamCount()
- {
- return argCount;
- }
-
- public int getParamAndVarCount()
- {
- return argNames.length;
- }
-
- public String getParamOrVarName(int index)
- {
- return argNames[index];
- }
-
- public boolean getParamOrVarConst(int index)
- {
- return argIsConst[index];
- }
-
- public String getSourceName()
- {
- return itsSourceFile;
- }
-
- public boolean isGeneratedScript()
- {
- return ScriptRuntime.isGeneratedScript(itsSourceFile);
- }
-
- public int[] getLineNumbers()
- {
- return Interpreter.getLineNumbers(this);
- }
-
- public int getFunctionCount()
- {
- return (itsNestedFunctions == null) ? 0 : itsNestedFunctions.length;
- }
-
- public DebuggableScript getFunction(int index)
- {
- return itsNestedFunctions[index];
- }
-
- public DebuggableScript getParent()
- {
- return parentData;
- }
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaAdapter.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaAdapter.java
deleted file mode 100644
index 6e0a827..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaAdapter.java
+++ /dev/null
@@ -1,1129 +0,0 @@
-/* -*- 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):
- * Patrick Beard
- * Norris Boyd
- * Igor Bukanov
- * Mike McCabe
- * Matthias Radestock
- * Andi Vajda
- * Andrew Wason
- * Kemal Bayram
- *
- * 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;
-
-import org.mozilla.classfile.*;
-import java.lang.reflect.*;
-import java.io.*;
-import java.security.*;
-import java.util.*;
-
-public final class JavaAdapter implements IdFunctionCall
-{
- /**
- * Provides a key with which to distinguish previously generated
- * adapter classes stored in a hash table.
- */
- static class JavaAdapterSignature
- {
- Class superClass;
- Class[] interfaces;
- ObjToIntMap names;
-
- JavaAdapterSignature(Class superClass, Class[] interfaces,
- ObjToIntMap names)
- {
- this.superClass = superClass;
- this.interfaces = interfaces;
- this.names = names;
- }
-
- public boolean equals(Object obj)
- {
- if (!(obj instanceof JavaAdapterSignature))
- return false;
- JavaAdapterSignature sig = (JavaAdapterSignature) obj;
- if (superClass != sig.superClass)
- return false;
- if (interfaces != sig.interfaces) {
- if (interfaces.length != sig.interfaces.length)
- return false;
- for (int i=0; i < interfaces.length; i++)
- if (interfaces[i] != sig.interfaces[i])
- return false;
- }
- if (names.size() != sig.names.size())
- return false;
- ObjToIntMap.Iterator iter = new ObjToIntMap.Iterator(names);
- for (iter.start(); !iter.done(); iter.next()) {
- String name = (String)iter.getKey();
- int arity = iter.getValue();
- if (arity != names.get(name, arity + 1))
- return false;
- }
- return true;
- }
-
- public int hashCode()
- {
- return superClass.hashCode()
- | (0x9e3779b9 * (names.size() | (interfaces.length << 16)));
- }
- }
-
- public static void init(Context cx, Scriptable scope, boolean sealed)
- {
- JavaAdapter obj = new JavaAdapter();
- IdFunctionObject ctor = new IdFunctionObject(obj, FTAG, Id_JavaAdapter,
- "JavaAdapter", 1, scope);
- ctor.markAsConstructor(null);
- if (sealed) {
- ctor.sealObject();
- }
- ctor.exportAsScopeProperty();
- }
-
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (f.hasTag(FTAG)) {
- if (f.methodId() == Id_JavaAdapter) {
- return js_createAdapter(cx, scope, args);
- }
- }
- throw f.unknown();
- }
-
- public static Object convertResult(Object result, Class c)
- {
- if (result == Undefined.instance &&
- (c != ScriptRuntime.ObjectClass &&
- c != ScriptRuntime.StringClass))
- {
- // Avoid an error for an undefined value; return null instead.
- return null;
- }
- return Context.jsToJava(result, c);
- }
-
- public static Scriptable createAdapterWrapper(Scriptable obj,
- Object adapter)
- {
- Scriptable scope = ScriptableObject.getTopLevelScope(obj);
- NativeJavaObject res = new NativeJavaObject(scope, adapter, null, true);
- res.setPrototype(obj);
- return res;
- }
-
- public static Object getAdapterSelf(Class adapterClass, Object adapter)
- throws NoSuchFieldException, IllegalAccessException
- {
- Field self = adapterClass.getDeclaredField("self");
- return self.get(adapter);
- }
-
- static Object js_createAdapter(Context cx, Scriptable scope, Object[] args)
- {
- int N = args.length;
- if (N == 0) {
- throw ScriptRuntime.typeError0("msg.adapter.zero.args");
- }
-
- Class superClass = null;
- Class[] intfs = new Class[N - 1];
- int interfaceCount = 0;
- for (int i = 0; i != N - 1; ++i) {
- Object arg = args[i];
- if (!(arg instanceof NativeJavaClass)) {
- throw ScriptRuntime.typeError2("msg.not.java.class.arg",
- String.valueOf(i),
- ScriptRuntime.toString(arg));
- }
- Class c = ((NativeJavaClass) arg).getClassObject();
- if (!c.isInterface()) {
- if (superClass != null) {
- throw ScriptRuntime.typeError2("msg.only.one.super",
- superClass.getName(), c.getName());
- }
- superClass = c;
- } else {
- intfs[interfaceCount++] = c;
- }
- }
-
- if (superClass == null)
- superClass = ScriptRuntime.ObjectClass;
-
- Class[] interfaces = new Class[interfaceCount];
- System.arraycopy(intfs, 0, interfaces, 0, interfaceCount);
- Scriptable obj = ScriptRuntime.toObject(cx, scope, args[N - 1]);
-
- Class adapterClass = getAdapterClass(scope, superClass, interfaces,
- obj);
-
- Class[] ctorParms = {
- ScriptRuntime.ContextFactoryClass,
- ScriptRuntime.ScriptableClass
- };
- Object[] ctorArgs = { cx.getFactory(), obj };
- try {
- Object adapter = adapterClass.getConstructor(ctorParms).
- newInstance(ctorArgs);
- return getAdapterSelf(adapterClass, adapter);
- } catch (Exception ex) {
- throw Context.throwAsScriptRuntimeEx(ex);
- }
- }
-
- // Needed by NativeJavaObject serializer
- public static void writeAdapterObject(Object javaObject,
- ObjectOutputStream out)
- throws IOException
- {
- Class cl = javaObject.getClass();
- out.writeObject(cl.getSuperclass().getName());
-
- Class[] interfaces = cl.getInterfaces();
- String[] interfaceNames = new String[interfaces.length];
-
- for (int i=0; i < interfaces.length; i++)
- interfaceNames[i] = interfaces[i].getName();
-
- out.writeObject(interfaceNames);
-
- try {
- Object delegee = cl.getField("delegee").get(javaObject);
- out.writeObject(delegee);
- return;
- } catch (IllegalAccessException e) {
- } catch (NoSuchFieldException e) {
- }
- throw new IOException();
- }
-
- // Needed by NativeJavaObject de-serializer
- public static Object readAdapterObject(Scriptable self,
- ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- ContextFactory factory;
- Context cx = Context.getCurrentContext();
- if (cx != null) {
- factory = cx.getFactory();
- } else {
- factory = null;
- }
-
- Class superClass = Class.forName((String)in.readObject());
-
- String[] interfaceNames = (String[])in.readObject();
- Class[] interfaces = new Class[interfaceNames.length];
-
- for (int i=0; i < interfaceNames.length; i++)
- interfaces[i] = Class.forName(interfaceNames[i]);
-
- Scriptable delegee = (Scriptable)in.readObject();
-
- Class adapterClass = getAdapterClass(self, superClass, interfaces,
- delegee);
-
- Class[] ctorParms = {
- ScriptRuntime.ContextFactoryClass,
- ScriptRuntime.ScriptableClass,
- ScriptRuntime.ScriptableClass
- };
- Object[] ctorArgs = { factory, delegee, self };
- try {
- return adapterClass.getConstructor(ctorParms).newInstance(ctorArgs);
- } catch(InstantiationException e) {
- } catch(IllegalAccessException e) {
- } catch(InvocationTargetException e) {
- } catch(NoSuchMethodException e) {
- }
-
- throw new ClassNotFoundException("adapter");
- }
-
- private static ObjToIntMap getObjectFunctionNames(Scriptable obj)
- {
- Object[] ids = ScriptableObject.getPropertyIds(obj);
- ObjToIntMap map = new ObjToIntMap(ids.length);
- for (int i = 0; i != ids.length; ++i) {
- if (!(ids[i] instanceof String))
- continue;
- String id = (String) ids[i];
- Object value = ScriptableObject.getProperty(obj, id);
- if (value instanceof Function) {
- Function f = (Function)value;
- int length = ScriptRuntime.toInt32(
- ScriptableObject.getProperty(f, "length"));
- if (length < 0) {
- length = 0;
- }
- map.put(id, length);
- }
- }
- return map;
- }
-
- private static Class getAdapterClass(Scriptable scope, Class superClass,
- Class[] interfaces, Scriptable obj)
- {
- ClassCache cache = ClassCache.get(scope);
- Map<JavaAdapterSignature,Class<?>> generated
- = cache.getInterfaceAdapterCacheMap();
-
- ObjToIntMap names = getObjectFunctionNames(obj);
- JavaAdapterSignature sig;
- sig = new JavaAdapterSignature(superClass, interfaces, names);
- Class<?> adapterClass = generated.get(sig);
- if (adapterClass == null) {
- String adapterName = "adapter"
- + cache.newClassSerialNumber();
- byte[] code = createAdapterCode(names, adapterName,
- superClass, interfaces, null);
-
- adapterClass = loadAdapterClass(adapterName, code);
- if (cache.isCachingEnabled()) {
- generated.put(sig, adapterClass);
- }
- }
- return adapterClass;
- }
-
- public static byte[] createAdapterCode(ObjToIntMap functionNames,
- String adapterName,
- Class superClass,
- Class[] interfaces,
- String scriptClassName)
- {
- ClassFileWriter cfw = new ClassFileWriter(adapterName,
- superClass.getName(),
- "<adapter>");
- cfw.addField("factory", "Lorg/mozilla/javascript/ContextFactory;",
- (short) (ClassFileWriter.ACC_PUBLIC |
- ClassFileWriter.ACC_FINAL));
- cfw.addField("delegee", "Lorg/mozilla/javascript/Scriptable;",
- (short) (ClassFileWriter.ACC_PUBLIC |
- ClassFileWriter.ACC_FINAL));
- cfw.addField("self", "Lorg/mozilla/javascript/Scriptable;",
- (short) (ClassFileWriter.ACC_PUBLIC |
- ClassFileWriter.ACC_FINAL));
- int interfacesCount = interfaces == null ? 0 : interfaces.length;
- for (int i=0; i < interfacesCount; i++) {
- if (interfaces[i] != null)
- cfw.addInterface(interfaces[i].getName());
- }
-
- String superName = superClass.getName().replace('.', '/');
- generateCtor(cfw, adapterName, superName);
- generateSerialCtor(cfw, adapterName, superName);
- if (scriptClassName != null)
- generateEmptyCtor(cfw, adapterName, superName, scriptClassName);
-
- ObjToIntMap generatedOverrides = new ObjToIntMap();
- ObjToIntMap generatedMethods = new ObjToIntMap();
-
- // generate methods to satisfy all specified interfaces.
- for (int i = 0; i < interfacesCount; i++) {
- Method[] methods = interfaces[i].getMethods();
- for (int j = 0; j < methods.length; j++) {
- Method method = methods[j];
- int mods = method.getModifiers();
- if (Modifier.isStatic(mods) || Modifier.isFinal(mods)) {
- continue;
- }
- String methodName = method.getName();
- Class[] argTypes = method.getParameterTypes();
- if (!functionNames.has(methodName)) {
- try {
- superClass.getMethod(methodName, argTypes);
- // The class we're extending implements this method and
- // the JavaScript object doesn't have an override. See
- // bug 61226.
- continue;
- } catch (NoSuchMethodException e) {
- // Not implemented by superclass; fall through
- }
- }
- // make sure to generate only one instance of a particular
- // method/signature.
- String methodSignature = getMethodSignature(method, argTypes);
- String methodKey = methodName + methodSignature;
- if (! generatedOverrides.has(methodKey)) {
- generateMethod(cfw, adapterName, methodName,
- argTypes, method.getReturnType());
- generatedOverrides.put(methodKey, 0);
- generatedMethods.put(methodName, 0);
- }
- }
- }
-
- // Now, go through the superclass's methods, checking for abstract
- // methods or additional methods to override.
-
- // generate any additional overrides that the object might contain.
- Method[] methods = getOverridableMethods(superClass);
- for (int j = 0; j < methods.length; j++) {
- Method method = methods[j];
- int mods = method.getModifiers();
- // if a method is marked abstract, must implement it or the
- // resulting class won't be instantiable. otherwise, if the object
- // has a property of the same name, then an override is intended.
- boolean isAbstractMethod = Modifier.isAbstract(mods);
- String methodName = method.getName();
- if (isAbstractMethod || functionNames.has(methodName)) {
- // make sure to generate only one instance of a particular
- // method/signature.
- Class[] argTypes = method.getParameterTypes();
- String methodSignature = getMethodSignature(method, argTypes);
- String methodKey = methodName + methodSignature;
- if (! generatedOverrides.has(methodKey)) {
- generateMethod(cfw, adapterName, methodName,
- argTypes, method.getReturnType());
- generatedOverrides.put(methodKey, 0);
- generatedMethods.put(methodName, 0);
-
- // if a method was overridden, generate a "super$method"
- // which lets the delegate call the superclass' version.
- if (!isAbstractMethod) {
- generateSuper(cfw, adapterName, superName,
- methodName, methodSignature,
- argTypes, method.getReturnType());
- }
- }
- }
- }
-
- // Generate Java methods for remaining properties that are not
- // overrides.
- ObjToIntMap.Iterator iter = new ObjToIntMap.Iterator(functionNames);
- for (iter.start(); !iter.done(); iter.next()) {
- String functionName = (String)iter.getKey();
- if (generatedMethods.has(functionName))
- continue;
- int length = iter.getValue();
- Class[] parms = new Class[length];
- for (int k=0; k < length; k++)
- parms[k] = ScriptRuntime.ObjectClass;
- generateMethod(cfw, adapterName, functionName, parms,
- ScriptRuntime.ObjectClass);
- }
- return cfw.toByteArray();
- }
-
- static Method[] getOverridableMethods(Class c)
- {
- ArrayList<Method> list = new ArrayList<Method>();
- HashSet<String> skip = new HashSet<String>();
- while (c != null) {
- Method[] methods = c.getDeclaredMethods();
- for (int i = 0; i < methods.length; i++) {
- String methodKey = methods[i].getName() +
- getMethodSignature(methods[i],
- methods[i].getParameterTypes());
- if (skip.contains(methodKey))
- continue; // skip this method
- int mods = methods[i].getModifiers();
- if (Modifier.isStatic(mods))
- continue;
- if (Modifier.isFinal(mods)) {
- // Make sure we don't add a final method to the list
- // of overridable methods.
- skip.add(methodKey);
- continue;
- }
- if (Modifier.isPublic(mods) || Modifier.isProtected(mods)) {
- list.add(methods[i]);
- skip.add(methodKey);
- }
- }
- c = c.getSuperclass();
- }
- return list.toArray(new Method[list.size()]);
- }
-
- static Class loadAdapterClass(String className, byte[] classBytes)
- {
- Object staticDomain;
- Class domainClass = SecurityController.getStaticSecurityDomainClass();
- if(domainClass == CodeSource.class || domainClass == ProtectionDomain.class) {
- ProtectionDomain protectionDomain = JavaAdapter.class.getProtectionDomain();
- if(domainClass == CodeSource.class) {
- staticDomain = protectionDomain == null ? null : protectionDomain.getCodeSource();
- }
- else {
- staticDomain = protectionDomain;
- }
- }
- else {
- staticDomain = null;
- }
- GeneratedClassLoader loader = SecurityController.createLoader(null,
- staticDomain);
- Class result = loader.defineClass(className, classBytes);
- loader.linkClass(result);
- return result;
- }
-
- public static Function getFunction(Scriptable obj, String functionName)
- {
- Object x = ScriptableObject.getProperty(obj, functionName);
- if (x == Scriptable.NOT_FOUND) {
- // This method used to swallow the exception from calling
- // an undefined method. People have come to depend on this
- // somewhat dubious behavior. It allows people to avoid
- // implementing listener methods that they don't care about,
- // for instance.
- return null;
- }
- if (!(x instanceof Function))
- throw ScriptRuntime.notFunctionError(x, functionName);
-
- return (Function)x;
- }
-
- /**
- * Utility method which dynamically binds a Context to the current thread,
- * if none already exists.
- */
- public static Object callMethod(ContextFactory factory,
- final Scriptable thisObj,
- final Function f, final Object[] args,
- final long argsToWrap)
- {
- if (f == null) {
- // See comments in getFunction
- return Undefined.instance;
- }
- if (factory == null) {
- factory = ContextFactory.getGlobal();
- }
-
- final Scriptable scope = f.getParentScope();
- if (argsToWrap == 0) {
- return Context.call(factory, f, scope, thisObj, args);
- }
-
- Context cx = Context.getCurrentContext();
- if (cx != null) {
- return doCall(cx, scope, thisObj, f, args, argsToWrap);
- } else {
- return factory.call(new ContextAction() {
- public Object run(Context cx)
- {
- return doCall(cx, scope, thisObj, f, args, argsToWrap);
- }
- });
- }
- }
-
- private static Object doCall(Context cx, Scriptable scope,
- Scriptable thisObj, Function f,
- Object[] args, long argsToWrap)
- {
- // Wrap the rest of objects
- for (int i = 0; i != args.length; ++i) {
- if (0 != (argsToWrap & (1 << i))) {
- Object arg = args[i];
- if (!(arg instanceof Scriptable)) {
- args[i] = cx.getWrapFactory().wrap(cx, scope, arg,
- null);
- }
- }
- }
- return f.call(cx, scope, thisObj, args);
- }
-
- public static Scriptable runScript(final Script script)
- {
- return (Scriptable)Context.call(new ContextAction() {
- public Object run(Context cx)
- {
- ScriptableObject global = ScriptRuntime.getGlobal(cx);
- script.exec(cx, global);
- return global;
- }
- });
- }
-
- private static void generateCtor(ClassFileWriter cfw, String adapterName,
- String superName)
- {
- cfw.startMethod("<init>",
- "(Lorg/mozilla/javascript/ContextFactory;"
- +"Lorg/mozilla/javascript/Scriptable;)V",
- ClassFileWriter.ACC_PUBLIC);
-
- // Invoke base class constructor
- cfw.add(ByteCode.ALOAD_0); // this
- cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", "()V");
-
- // Save parameter in instance variable "factory"
- cfw.add(ByteCode.ALOAD_0); // this
- cfw.add(ByteCode.ALOAD_1); // first arg: ContextFactory instance
- cfw.add(ByteCode.PUTFIELD, adapterName, "factory",
- "Lorg/mozilla/javascript/ContextFactory;");
-
- // Save parameter in instance variable "delegee"
- cfw.add(ByteCode.ALOAD_0); // this
- cfw.add(ByteCode.ALOAD_2); // second arg: Scriptable delegee
- cfw.add(ByteCode.PUTFIELD, adapterName, "delegee",
- "Lorg/mozilla/javascript/Scriptable;");
-
- cfw.add(ByteCode.ALOAD_0); // this for the following PUTFIELD for self
- // create a wrapper object to be used as "this" in method calls
- cfw.add(ByteCode.ALOAD_2); // the Scriptable delegee
- cfw.add(ByteCode.ALOAD_0); // this
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/JavaAdapter",
- "createAdapterWrapper",
- "(Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/Object;"
- +")Lorg/mozilla/javascript/Scriptable;");
- cfw.add(ByteCode.PUTFIELD, adapterName, "self",
- "Lorg/mozilla/javascript/Scriptable;");
-
- cfw.add(ByteCode.RETURN);
- cfw.stopMethod((short)3); // 3: this + factory + delegee
- }
-
- private static void generateSerialCtor(ClassFileWriter cfw,
- String adapterName,
- String superName)
- {
- cfw.startMethod("<init>",
- "(Lorg/mozilla/javascript/ContextFactory;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")V",
- ClassFileWriter.ACC_PUBLIC);
-
- // Invoke base class constructor
- cfw.add(ByteCode.ALOAD_0); // this
- cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", "()V");
-
- // Save parameter in instance variable "factory"
- cfw.add(ByteCode.ALOAD_0); // this
- cfw.add(ByteCode.ALOAD_1); // first arg: ContextFactory instance
- cfw.add(ByteCode.PUTFIELD, adapterName, "factory",
- "Lorg/mozilla/javascript/ContextFactory;");
-
- // Save parameter in instance variable "delegee"
- cfw.add(ByteCode.ALOAD_0); // this
- cfw.add(ByteCode.ALOAD_2); // second arg: Scriptable delegee
- cfw.add(ByteCode.PUTFIELD, adapterName, "delegee",
- "Lorg/mozilla/javascript/Scriptable;");
- // save self
- cfw.add(ByteCode.ALOAD_0); // this
- cfw.add(ByteCode.ALOAD_3); // second arg: Scriptable self
- cfw.add(ByteCode.PUTFIELD, adapterName, "self",
- "Lorg/mozilla/javascript/Scriptable;");
-
- cfw.add(ByteCode.RETURN);
- cfw.stopMethod((short)4); // 4: this + factory + delegee + self
- }
-
- private static void generateEmptyCtor(ClassFileWriter cfw,
- String adapterName,
- String superName,
- String scriptClassName)
- {
- cfw.startMethod("<init>", "()V", ClassFileWriter.ACC_PUBLIC);
-
- // Invoke base class constructor
- cfw.add(ByteCode.ALOAD_0); // this
- cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", "()V");
-
- // Set factory to null to use current global when necessary
- cfw.add(ByteCode.ALOAD_0);
- cfw.add(ByteCode.ACONST_NULL);
- cfw.add(ByteCode.PUTFIELD, adapterName, "factory",
- "Lorg/mozilla/javascript/ContextFactory;");
-
- // Load script class
- cfw.add(ByteCode.NEW, scriptClassName);
- cfw.add(ByteCode.DUP);
- cfw.addInvoke(ByteCode.INVOKESPECIAL, scriptClassName, "<init>", "()V");
-
- // Run script and save resulting scope
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/JavaAdapter",
- "runScript",
- "(Lorg/mozilla/javascript/Script;"
- +")Lorg/mozilla/javascript/Scriptable;");
- cfw.add(ByteCode.ASTORE_1);
-
- // Save the Scriptable in instance variable "delegee"
- cfw.add(ByteCode.ALOAD_0); // this
- cfw.add(ByteCode.ALOAD_1); // the Scriptable
- cfw.add(ByteCode.PUTFIELD, adapterName, "delegee",
- "Lorg/mozilla/javascript/Scriptable;");
-
- cfw.add(ByteCode.ALOAD_0); // this for the following PUTFIELD for self
- // create a wrapper object to be used as "this" in method calls
- cfw.add(ByteCode.ALOAD_1); // the Scriptable
- cfw.add(ByteCode.ALOAD_0); // this
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/JavaAdapter",
- "createAdapterWrapper",
- "(Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/Object;"
- +")Lorg/mozilla/javascript/Scriptable;");
- cfw.add(ByteCode.PUTFIELD, adapterName, "self",
- "Lorg/mozilla/javascript/Scriptable;");
-
- cfw.add(ByteCode.RETURN);
- cfw.stopMethod((short)2); // this + delegee
- }
-
- /**
- * Generates code to wrap Java arguments into Object[].
- * Non-primitive Java types are left as-is pending conversion
- * in the helper method. Leaves the array object on the top of the stack.
- */
- static void generatePushWrappedArgs(ClassFileWriter cfw,
- Class[] argTypes,
- int arrayLength)
- {
- // push arguments
- cfw.addPush(arrayLength);
- cfw.add(ByteCode.ANEWARRAY, "java/lang/Object");
- int paramOffset = 1;
- for (int i = 0; i != argTypes.length; ++i) {
- cfw.add(ByteCode.DUP); // duplicate array reference
- cfw.addPush(i);
- paramOffset += generateWrapArg(cfw, paramOffset, argTypes[i]);
- cfw.add(ByteCode.AASTORE);
- }
- }
-
- /**
- * Generates code to wrap Java argument into Object.
- * Non-primitive Java types are left unconverted pending conversion
- * in the helper method. Leaves the wrapper object on the top of the stack.
- */
- private static int generateWrapArg(ClassFileWriter cfw, int paramOffset,
- Class argType)
- {
- int size = 1;
- if (!argType.isPrimitive()) {
- cfw.add(ByteCode.ALOAD, paramOffset);
-
- } else if (argType == Boolean.TYPE) {
- // wrap boolean values with java.lang.Boolean.
- cfw.add(ByteCode.NEW, "java/lang/Boolean");
- cfw.add(ByteCode.DUP);
- cfw.add(ByteCode.ILOAD, paramOffset);
- cfw.addInvoke(ByteCode.INVOKESPECIAL, "java/lang/Boolean",
- "<init>", "(Z)V");
-
- } else if (argType == Character.TYPE) {
- // Create a string of length 1 using the character parameter.
- cfw.add(ByteCode.ILOAD, paramOffset);
- cfw.addInvoke(ByteCode.INVOKESTATIC, "java/lang/String",
- "valueOf", "(C)Ljava/lang/String;");
-
- } else {
- // convert all numeric values to java.lang.Double.
- cfw.add(ByteCode.NEW, "java/lang/Double");
- cfw.add(ByteCode.DUP);
- String typeName = argType.getName();
- switch (typeName.charAt(0)) {
- case 'b':
- case 's':
- case 'i':
- // load an int value, convert to double.
- cfw.add(ByteCode.ILOAD, paramOffset);
- cfw.add(ByteCode.I2D);
- break;
- case 'l':
- // load a long, convert to double.
- cfw.add(ByteCode.LLOAD, paramOffset);
- cfw.add(ByteCode.L2D);
- size = 2;
- break;
- case 'f':
- // load a float, convert to double.
- cfw.add(ByteCode.FLOAD, paramOffset);
- cfw.add(ByteCode.F2D);
- break;
- case 'd':
- cfw.add(ByteCode.DLOAD, paramOffset);
- size = 2;
- break;
- }
- cfw.addInvoke(ByteCode.INVOKESPECIAL, "java/lang/Double",
- "<init>", "(D)V");
- }
- return size;
- }
-
- /**
- * Generates code to convert a wrapped value type to a primitive type.
- * Handles unwrapping java.lang.Boolean, and java.lang.Number types.
- * Generates the appropriate RETURN bytecode.
- */
- static void generateReturnResult(ClassFileWriter cfw, Class retType,
- boolean callConvertResult)
- {
- // wrap boolean values with java.lang.Boolean, convert all other
- // primitive values to java.lang.Double.
- if (retType == Void.TYPE) {
- cfw.add(ByteCode.POP);
- cfw.add(ByteCode.RETURN);
-
- } else if (retType == Boolean.TYPE) {
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/Context",
- "toBoolean", "(Ljava/lang/Object;)Z");
- cfw.add(ByteCode.IRETURN);
-
- } else if (retType == Character.TYPE) {
- // characters are represented as strings in JavaScript.
- // return the first character.
- // first convert the value to a string if possible.
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/Context",
- "toString",
- "(Ljava/lang/Object;)Ljava/lang/String;");
- cfw.add(ByteCode.ICONST_0);
- cfw.addInvoke(ByteCode.INVOKEVIRTUAL, "java/lang/String",
- "charAt", "(I)C");
- cfw.add(ByteCode.IRETURN);
-
- } else if (retType.isPrimitive()) {
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/Context",
- "toNumber", "(Ljava/lang/Object;)D");
- String typeName = retType.getName();
- switch (typeName.charAt(0)) {
- case 'b':
- case 's':
- case 'i':
- cfw.add(ByteCode.D2I);
- cfw.add(ByteCode.IRETURN);
- break;
- case 'l':
- cfw.add(ByteCode.D2L);
- cfw.add(ByteCode.LRETURN);
- break;
- case 'f':
- cfw.add(ByteCode.D2F);
- cfw.add(ByteCode.FRETURN);
- break;
- case 'd':
- cfw.add(ByteCode.DRETURN);
- break;
- default:
- throw new RuntimeException("Unexpected return type " +
- retType.toString());
- }
-
- } else {
- String retTypeStr = retType.getName();
- if (callConvertResult) {
- cfw.addLoadConstant(retTypeStr);
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "java/lang/Class",
- "forName",
- "(Ljava/lang/String;)Ljava/lang/Class;");
-
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/JavaAdapter",
- "convertResult",
- "(Ljava/lang/Object;"
- +"Ljava/lang/Class;"
- +")Ljava/lang/Object;");
- }
- // Now cast to return type
- cfw.add(ByteCode.CHECKCAST, retTypeStr);
- cfw.add(ByteCode.ARETURN);
- }
- }
-
- private static void generateMethod(ClassFileWriter cfw, String genName,
- String methodName, Class[] parms,
- Class returnType)
- {
- StringBuffer sb = new StringBuffer();
- int paramsEnd = appendMethodSignature(parms, returnType, sb);
- String methodSignature = sb.toString();
- cfw.startMethod(methodName, methodSignature,
- ClassFileWriter.ACC_PUBLIC);
-
- // Prepare stack to call method
-
- // push factory
- cfw.add(ByteCode.ALOAD_0);
- cfw.add(ByteCode.GETFIELD, genName, "factory",
- "Lorg/mozilla/javascript/ContextFactory;");
-
- // push self
- cfw.add(ByteCode.ALOAD_0);
- cfw.add(ByteCode.GETFIELD, genName, "self",
- "Lorg/mozilla/javascript/Scriptable;");
-
- // push function
- cfw.add(ByteCode.ALOAD_0);
- cfw.add(ByteCode.GETFIELD, genName, "delegee",
- "Lorg/mozilla/javascript/Scriptable;");
- cfw.addPush(methodName);
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/JavaAdapter",
- "getFunction",
- "(Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/String;"
- +")Lorg/mozilla/javascript/Function;");
-
- // push arguments
- generatePushWrappedArgs(cfw, parms, parms.length);
-
- // push bits to indicate which parameters should be wrapped
- if (parms.length > 64) {
- // If it will be an issue, then passing a static boolean array
- // can be an option, but for now using simple bitmask
- throw Context.reportRuntimeError0(
- "JavaAdapter can not subclass methods with more then"
- +" 64 arguments.");
- }
- long convertionMask = 0;
- for (int i = 0; i != parms.length; ++i) {
- if (!parms[i].isPrimitive()) {
- convertionMask |= (1 << i);
- }
- }
- cfw.addPush(convertionMask);
-
- // go through utility method, which creates a Context to run the
- // method in.
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/JavaAdapter",
- "callMethod",
- "(Lorg/mozilla/javascript/ContextFactory;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Function;"
- +"[Ljava/lang/Object;"
- +"J"
- +")Ljava/lang/Object;");
-
- generateReturnResult(cfw, returnType, true);
-
- cfw.stopMethod((short)paramsEnd);
- }
-
- /**
- * Generates code to push typed parameters onto the operand stack
- * prior to a direct Java method call.
- */
- private static int generatePushParam(ClassFileWriter cfw, int paramOffset,
- Class paramType)
- {
- if (!paramType.isPrimitive()) {
- cfw.addALoad(paramOffset);
- return 1;
- }
- String typeName = paramType.getName();
- switch (typeName.charAt(0)) {
- case 'z':
- case 'b':
- case 'c':
- case 's':
- case 'i':
- // load an int value, convert to double.
- cfw.addILoad(paramOffset);
- return 1;
- case 'l':
- // load a long, convert to double.
- cfw.addLLoad(paramOffset);
- return 2;
- case 'f':
- // load a float, convert to double.
- cfw.addFLoad(paramOffset);
- return 1;
- case 'd':
- cfw.addDLoad(paramOffset);
- return 2;
- }
- throw Kit.codeBug();
- }
-
- /**
- * Generates code to return a Java type, after calling a Java method
- * that returns the same type.
- * Generates the appropriate RETURN bytecode.
- */
- private static void generatePopResult(ClassFileWriter cfw,
- Class retType)
- {
- if (retType.isPrimitive()) {
- String typeName = retType.getName();
- switch (typeName.charAt(0)) {
- case 'b':
- case 'c':
- case 's':
- case 'i':
- case 'z':
- cfw.add(ByteCode.IRETURN);
- break;
- case 'l':
- cfw.add(ByteCode.LRETURN);
- break;
- case 'f':
- cfw.add(ByteCode.FRETURN);
- break;
- case 'd':
- cfw.add(ByteCode.DRETURN);
- break;
- }
- } else {
- cfw.add(ByteCode.ARETURN);
- }
- }
-
- /**
- * Generates a method called "super$methodName()" which can be called
- * from JavaScript that is equivalent to calling "super.methodName()"
- * from Java. Eventually, this may be supported directly in JavaScript.
- */
- private static void generateSuper(ClassFileWriter cfw,
- String genName, String superName,
- String methodName, String methodSignature,
- Class[] parms, Class returnType)
- {
- cfw.startMethod("super$" + methodName, methodSignature,
- ClassFileWriter.ACC_PUBLIC);
-
- // push "this"
- cfw.add(ByteCode.ALOAD, 0);
-
- // push the rest of the parameters.
- int paramOffset = 1;
- for (int i = 0; i < parms.length; i++) {
- paramOffset += generatePushParam(cfw, paramOffset, parms[i]);
- }
-
- // call the superclass implementation of the method.
- cfw.addInvoke(ByteCode.INVOKESPECIAL,
- superName,
- methodName,
- methodSignature);
-
- // now, handle the return type appropriately.
- Class retType = returnType;
- if (!retType.equals(Void.TYPE)) {
- generatePopResult(cfw, retType);
- } else {
- cfw.add(ByteCode.RETURN);
- }
- cfw.stopMethod((short)(paramOffset + 1));
- }
-
- /**
- * Returns a fully qualified method name concatenated with its signature.
- */
- private static String getMethodSignature(Method method, Class[] argTypes)
- {
- StringBuffer sb = new StringBuffer();
- appendMethodSignature(argTypes, method.getReturnType(), sb);
- return sb.toString();
- }
-
- static int appendMethodSignature(Class[] argTypes,
- Class returnType,
- StringBuffer sb)
- {
- sb.append('(');
- int firstLocal = 1 + argTypes.length; // includes this.
- for (int i = 0; i < argTypes.length; i++) {
- Class type = argTypes[i];
- appendTypeString(sb, type);
- if (type == Long.TYPE || type == Double.TYPE) {
- // adjust for duble slot
- ++firstLocal;
- }
- }
- sb.append(')');
- appendTypeString(sb, returnType);
- return firstLocal;
- }
-
- private static StringBuffer appendTypeString(StringBuffer sb, Class type)
- {
- while (type.isArray()) {
- sb.append('[');
- type = type.getComponentType();
- }
- if (type.isPrimitive()) {
- char typeLetter;
- if (type == Boolean.TYPE) {
- typeLetter = 'Z';
- } else if (type == Long.TYPE) {
- typeLetter = 'J';
- } else {
- String typeName = type.getName();
- typeLetter = Character.toUpperCase(typeName.charAt(0));
- }
- sb.append(typeLetter);
- } else {
- sb.append('L');
- sb.append(type.getName().replace('.', '/'));
- sb.append(';');
- }
- return sb;
- }
-
- static int[] getArgsToConvert(Class[] argTypes)
- {
- int count = 0;
- for (int i = 0; i != argTypes.length; ++i) {
- if (!argTypes[i].isPrimitive())
- ++count;
- }
- if (count == 0)
- return null;
- int[] array = new int[count];
- count = 0;
- for (int i = 0; i != argTypes.length; ++i) {
- if (!argTypes[i].isPrimitive())
- array[count++] = i;
- }
- return array;
- }
-
- private static final Object FTAG = new Object();
- private static final int Id_JavaAdapter = 1;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaMembers.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaMembers.java
deleted file mode 100644
index 84ef2d4..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaMembers.java
+++ /dev/null
@@ -1,935 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- * Cameron McCormack
- * Frank Mitchell
- * Mike Shaver
- * Kurt Westerfeld
- *
- * 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;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-/**
- *
- * @author Mike Shaver
- * @author Norris Boyd
- * @see NativeJavaObject
- * @see NativeJavaClass
- */
-class JavaMembers
-{
- JavaMembers(Scriptable scope, Class cl)
- {
- this(scope, cl, false);
- }
-
- JavaMembers(Scriptable scope, Class cl, boolean includeProtected)
- {
- try {
- Context cx = ContextFactory.getGlobal().enterContext();
- ClassShutter shutter = cx.getClassShutter();
- if (shutter != null && !shutter.visibleToScripts(cl.getName())) {
- throw Context.reportRuntimeError1("msg.access.prohibited",
- cl.getName());
- }
- this.includePrivate = cx.hasFeature(
- Context.FEATURE_ENHANCED_JAVA_ACCESS);
- this.members = new Hashtable(23);
- this.staticMembers = new Hashtable(7);
- this.cl = cl;
- reflect(scope, includeProtected);
- } finally {
- Context.exit();
- }
- }
-
- boolean has(String name, boolean isStatic)
- {
- Hashtable ht = isStatic ? staticMembers : members;
- Object obj = ht.get(name);
- if (obj != null) {
- return true;
- }
- return findExplicitFunction(name, isStatic) != null;
- }
-
- Object get(Scriptable scope, String name, Object javaObject,
- boolean isStatic)
- {
- Hashtable ht = isStatic ? staticMembers : members;
- Object member = ht.get(name);
- if (!isStatic && member == null) {
- // Try to get static member from instance (LC3)
- member = staticMembers.get(name);
- }
- if (member == null) {
- member = this.getExplicitFunction(scope, name,
- javaObject, isStatic);
- if (member == null)
- return Scriptable.NOT_FOUND;
- }
- if (member instanceof Scriptable) {
- return member;
- }
- Context cx = Context.getContext();
- Object rval;
- Class type;
- try {
- if (member instanceof BeanProperty) {
- BeanProperty bp = (BeanProperty) member;
- if (bp.getter == null)
- return Scriptable.NOT_FOUND;
- rval = bp.getter.invoke(javaObject, Context.emptyArgs);
- type = bp.getter.method().getReturnType();
- } else {
- Field field = (Field) member;
- rval = field.get(isStatic ? null : javaObject);
- type = field.getType();
- }
- } catch (Exception ex) {
- throw Context.throwAsScriptRuntimeEx(ex);
- }
- // Need to wrap the object before we return it.
- scope = ScriptableObject.getTopLevelScope(scope);
- return cx.getWrapFactory().wrap(cx, scope, rval, type);
- }
-
- void put(Scriptable scope, String name, Object javaObject,
- Object value, boolean isStatic)
- {
- Hashtable ht = isStatic ? staticMembers : members;
- Object member = ht.get(name);
- if (!isStatic && member == null) {
- // Try to get static member from instance (LC3)
- member = staticMembers.get(name);
- }
- if (member == null)
- throw reportMemberNotFound(name);
- if (member instanceof FieldAndMethods) {
- FieldAndMethods fam = (FieldAndMethods) ht.get(name);
- member = fam.field;
- }
-
- // Is this a bean property "set"?
- if (member instanceof BeanProperty) {
- BeanProperty bp = (BeanProperty)member;
- if (bp.setter == null) {
- throw reportMemberNotFound(name);
- }
- // If there's only one setter or if the value is null, use the
- // main setter. Otherwise, let the NativeJavaMethod decide which
- // setter to use:
- if (bp.setters == null || value == null) {
- Class setType = bp.setter.argTypes[0];
- Object[] args = { Context.jsToJava(value, setType) };
- try {
- bp.setter.invoke(javaObject, args);
- } catch (Exception ex) {
- throw Context.throwAsScriptRuntimeEx(ex);
- }
- } else {
- Object[] args = { value };
- bp.setters.call(Context.getContext(),
- ScriptableObject.getTopLevelScope(scope),
- scope, args);
- }
- }
- else {
- if (!(member instanceof Field)) {
- String str = (member == null) ? "msg.java.internal.private"
- : "msg.java.method.assign";
- throw Context.reportRuntimeError1(str, name);
- }
- Field field = (Field)member;
- Object javaValue = Context.jsToJava(value, field.getType());
- try {
- field.set(javaObject, javaValue);
- } catch (IllegalAccessException accessEx) {
- if ((field.getModifiers() & Modifier.FINAL) != 0) {
- // treat Java final the same as JavaScript [[READONLY]]
- return;
- }
- throw Context.throwAsScriptRuntimeEx(accessEx);
- } catch (IllegalArgumentException argEx) {
- throw Context.reportRuntimeError3(
- "msg.java.internal.field.type",
- value.getClass().getName(), field,
- javaObject.getClass().getName());
- }
- }
- }
-
- Object[] getIds(boolean isStatic)
- {
- Hashtable ht = isStatic ? staticMembers : members;
- int len = ht.size();
- Object[] result = new Object[len];
- Enumeration keys = ht.keys();
- for (int i=0; i < len; i++)
- result[i] = keys.nextElement();
- return result;
- }
-
- static String javaSignature(Class type)
- {
- if (!type.isArray()) {
- return type.getName();
- } else {
- int arrayDimension = 0;
- do {
- ++arrayDimension;
- type = type.getComponentType();
- } while (type.isArray());
- String name = type.getName();
- String suffix = "[]";
- if (arrayDimension == 1) {
- return name.concat(suffix);
- } else {
- int length = name.length() + arrayDimension * suffix.length();
- StringBuffer sb = new StringBuffer(length);
- sb.append(name);
- while (arrayDimension != 0) {
- --arrayDimension;
- sb.append(suffix);
- }
- return sb.toString();
- }
- }
- }
-
- static String liveConnectSignature(Class[] argTypes)
- {
- int N = argTypes.length;
- if (N == 0) { return "()"; }
- StringBuffer sb = new StringBuffer();
- sb.append('(');
- for (int i = 0; i != N; ++i) {
- if (i != 0) {
- sb.append(',');
- }
- sb.append(javaSignature(argTypes[i]));
- }
- sb.append(')');
- return sb.toString();
- }
-
- private MemberBox findExplicitFunction(String name, boolean isStatic)
- {
- int sigStart = name.indexOf('(');
- if (sigStart < 0) { return null; }
-
- Hashtable ht = isStatic ? staticMembers : members;
- MemberBox[] methodsOrCtors = null;
- boolean isCtor = (isStatic && sigStart == 0);
-
- if (isCtor) {
- // Explicit request for an overloaded constructor
- methodsOrCtors = ctors;
- } else {
- // Explicit request for an overloaded method
- String trueName = name.substring(0,sigStart);
- Object obj = ht.get(trueName);
- if (!isStatic && obj == null) {
- // Try to get static member from instance (LC3)
- obj = staticMembers.get(trueName);
- }
- if (obj instanceof NativeJavaMethod) {
- NativeJavaMethod njm = (NativeJavaMethod)obj;
- methodsOrCtors = njm.methods;
- }
- }
-
- if (methodsOrCtors != null) {
- for (int i = 0; i < methodsOrCtors.length; i++) {
- Class[] type = methodsOrCtors[i].argTypes;
- String sig = liveConnectSignature(type);
- if (sigStart + sig.length() == name.length()
- && name.regionMatches(sigStart, sig, 0, sig.length()))
- {
- return methodsOrCtors[i];
- }
- }
- }
-
- return null;
- }
-
- private Object getExplicitFunction(Scriptable scope, String name,
- Object javaObject, boolean isStatic)
- {
- Hashtable ht = isStatic ? staticMembers : members;
- Object member = null;
- MemberBox methodOrCtor = findExplicitFunction(name, isStatic);
-
- if (methodOrCtor != null) {
- Scriptable prototype =
- ScriptableObject.getFunctionPrototype(scope);
-
- if (methodOrCtor.isCtor()) {
- NativeJavaConstructor fun =
- new NativeJavaConstructor(methodOrCtor);
- fun.setPrototype(prototype);
- member = fun;
- ht.put(name, fun);
- } else {
- String trueName = methodOrCtor.getName();
- member = ht.get(trueName);
-
- if (member instanceof NativeJavaMethod &&
- ((NativeJavaMethod)member).methods.length > 1 ) {
- NativeJavaMethod fun =
- new NativeJavaMethod(methodOrCtor, name);
- fun.setPrototype(prototype);
- ht.put(name, fun);
- member = fun;
- }
- }
- }
-
- return member;
- }
-
- /**
- * Retrieves mapping of methods to accessible methods for a class.
- * In case the class is not public, retrieves methods with same
- * signature as its public methods from public superclasses and
- * interfaces (if they exist). Basically upcasts every method to the
- * nearest accessible method.
- */
- private static Method[] discoverAccessibleMethods(Class clazz,
- boolean includeProtected,
- boolean includePrivate)
- {
- Map map = new HashMap();
- discoverAccessibleMethods(clazz, map, includeProtected, includePrivate);
- return (Method[])map.values().toArray(new Method[map.size()]);
- }
-
- private static void discoverAccessibleMethods(Class clazz, Map map,
- boolean includeProtected,
- boolean includePrivate)
- {
- if (Modifier.isPublic(clazz.getModifiers()) || includePrivate) {
- try {
- if (includeProtected || includePrivate) {
- while (clazz != null) {
- try {
- Method[] methods = clazz.getDeclaredMethods();
- for (int i = 0; i < methods.length; i++) {
- Method method = methods[i];
- int mods = method.getModifiers();
-
- if (Modifier.isPublic(mods) ||
- Modifier.isProtected(mods) ||
- includePrivate)
- {
- if (includePrivate)
- method.setAccessible(true);
- map.put(new MethodSignature(method), method);
- }
- }
- clazz = clazz.getSuperclass();
- } catch (SecurityException e) {
- // Some security settings (i.e., applets) disallow
- // access to Class.getDeclaredMethods. Fall back to
- // Class.getMethods.
- Method[] methods = clazz.getMethods();
- for (int i = 0; i < methods.length; i++) {
- Method method = methods[i];
- MethodSignature sig
- = new MethodSignature(method);
- if (map.get(sig) == null)
- map.put(sig, method);
- }
- break; // getMethods gets superclass methods, no
- // need to loop any more
- }
- }
- } else {
- Method[] methods = clazz.getMethods();
- for (int i = 0; i < methods.length; i++) {
- Method method = methods[i];
- MethodSignature sig = new MethodSignature(method);
- map.put(sig, method);
- }
- }
- return;
- } catch (SecurityException e) {
- Context.reportWarning(
- "Could not discover accessible methods of class " +
- clazz.getName() + " due to lack of privileges, " +
- "attemping superclasses/interfaces.");
- // Fall through and attempt to discover superclass/interface
- // methods
- }
- }
-
- Class[] interfaces = clazz.getInterfaces();
- for (int i = 0; i < interfaces.length; i++) {
- discoverAccessibleMethods(interfaces[i], map, includeProtected,
- includePrivate);
- }
- Class superclass = clazz.getSuperclass();
- if (superclass != null) {
- discoverAccessibleMethods(superclass, map, includeProtected,
- includePrivate);
- }
- }
-
- private static final class MethodSignature
- {
- private final String name;
- private final Class[] args;
-
- private MethodSignature(String name, Class[] args)
- {
- this.name = name;
- this.args = args;
- }
-
- MethodSignature(Method method)
- {
- this(method.getName(), method.getParameterTypes());
- }
-
- public boolean equals(Object o)
- {
- if(o instanceof MethodSignature)
- {
- MethodSignature ms = (MethodSignature)o;
- return ms.name.equals(name) && Arrays.equals(args, ms.args);
- }
- return false;
- }
-
- public int hashCode()
- {
- return name.hashCode() ^ args.length;
- }
- }
-
- private void reflect(Scriptable scope, boolean includeProtected)
- {
- // We reflect methods first, because we want overloaded field/method
- // names to be allocated to the NativeJavaMethod before the field
- // gets in the way.
-
- Method[] methods = discoverAccessibleMethods(cl, includeProtected,
- includePrivate);
- for (int i = 0; i < methods.length; i++) {
- Method method = methods[i];
- int mods = method.getModifiers();
- boolean isStatic = Modifier.isStatic(mods);
- Hashtable ht = isStatic ? staticMembers : members;
- String name = method.getName();
- Object value = ht.get(name);
- if (value == null) {
- ht.put(name, method);
- } else {
- ObjArray overloadedMethods;
- if (value instanceof ObjArray) {
- overloadedMethods = (ObjArray)value;
- } else {
- if (!(value instanceof Method)) Kit.codeBug();
- // value should be instance of Method as at this stage
- // staticMembers and members can only contain methods
- overloadedMethods = new ObjArray();
- overloadedMethods.add(value);
- ht.put(name, overloadedMethods);
- }
- overloadedMethods.add(method);
- }
- }
-
- // replace Method instances by wrapped NativeJavaMethod objects
- // first in staticMembers and then in members
- for (int tableCursor = 0; tableCursor != 2; ++tableCursor) {
- boolean isStatic = (tableCursor == 0);
- Hashtable ht = (isStatic) ? staticMembers : members;
- Enumeration e = ht.keys();
- while (e.hasMoreElements()) {
- String name = (String)e.nextElement();
- MemberBox[] methodBoxes;
- Object value = ht.get(name);
- if (value instanceof Method) {
- methodBoxes = new MemberBox[1];
- methodBoxes[0] = new MemberBox((Method)value);
- } else {
- ObjArray overloadedMethods = (ObjArray)value;
- int N = overloadedMethods.size();
- if (N < 2) Kit.codeBug();
- methodBoxes = new MemberBox[N];
- for (int i = 0; i != N; ++i) {
- Method method = (Method)overloadedMethods.get(i);
- methodBoxes[i] = new MemberBox(method);
- }
- }
- NativeJavaMethod fun = new NativeJavaMethod(methodBoxes);
- if (scope != null) {
- ScriptRuntime.setFunctionProtoAndParent(fun, scope);
- }
- ht.put(name, fun);
- }
- }
-
- // Reflect fields.
- Field[] fields = getAccessibleFields();
- for (int i = 0; i < fields.length; i++) {
- Field field = fields[i];
- String name = field.getName();
- int mods = field.getModifiers();
- if (!includePrivate && !Modifier.isPublic(mods)) {
- continue;
- }
- try {
- boolean isStatic = Modifier.isStatic(mods);
- Hashtable ht = isStatic ? staticMembers : members;
- Object member = ht.get(name);
- if (member == null) {
- ht.put(name, field);
- } else if (member instanceof NativeJavaMethod) {
- NativeJavaMethod method = (NativeJavaMethod) member;
- FieldAndMethods fam
- = new FieldAndMethods(scope, method.methods, field);
- Hashtable fmht = isStatic ? staticFieldAndMethods
- : fieldAndMethods;
- if (fmht == null) {
- fmht = new Hashtable(4);
- if (isStatic) {
- staticFieldAndMethods = fmht;
- } else {
- fieldAndMethods = fmht;
- }
- }
- fmht.put(name, fam);
- ht.put(name, fam);
- } else if (member instanceof Field) {
- Field oldField = (Field) member;
- // If this newly reflected field shadows an inherited field,
- // then replace it. Otherwise, since access to the field
- // would be ambiguous from Java, no field should be
- // reflected.
- // For now, the first field found wins, unless another field
- // explicitly shadows it.
- if (oldField.getDeclaringClass().
- isAssignableFrom(field.getDeclaringClass()))
- {
- ht.put(name, field);
- }
- } else {
- // "unknown member type"
- Kit.codeBug();
- }
- } catch (SecurityException e) {
- // skip this field
- Context.reportWarning("Could not access field "
- + name + " of class " + cl.getName() +
- " due to lack of privileges.");
- }
- }
-
- // Create bean propeties from corresponding get/set methods first for
- // static members and then for instance members
- for (int tableCursor = 0; tableCursor != 2; ++tableCursor) {
- boolean isStatic = (tableCursor == 0);
- Hashtable ht = (isStatic) ? staticMembers : members;
-
- Hashtable toAdd = new Hashtable();
-
- // Now, For each member, make "bean" properties.
- for (Enumeration e = ht.keys(); e.hasMoreElements(); ) {
-
- // Is this a getter?
- String name = (String) e.nextElement();
- boolean memberIsGetMethod = name.startsWith("get");
- boolean memberIsSetMethod = name.startsWith("set");
- boolean memberIsIsMethod = name.startsWith("is");
- if (memberIsGetMethod || memberIsIsMethod
- || memberIsSetMethod) {
- // Double check name component.
- String nameComponent
- = name.substring(memberIsIsMethod ? 2 : 3);
- if (nameComponent.length() == 0)
- continue;
-
- // Make the bean property name.
- String beanPropertyName = nameComponent;
- char ch0 = nameComponent.charAt(0);
- if (Character.isUpperCase(ch0)) {
- if (nameComponent.length() == 1) {
- beanPropertyName = nameComponent.toLowerCase();
- } else {
- char ch1 = nameComponent.charAt(1);
- if (!Character.isUpperCase(ch1)) {
- beanPropertyName = Character.toLowerCase(ch0)
- +nameComponent.substring(1);
- }
- }
- }
-
- // If we already have a member by this name, don't do this
- // property.
- if (ht.containsKey(beanPropertyName)
- || toAdd.containsKey(beanPropertyName)) {
- continue;
- }
-
- // Find the getter method, or if there is none, the is-
- // method.
- MemberBox getter = null;
- getter = findGetter(isStatic, ht, "get", nameComponent);
- // If there was no valid getter, check for an is- method.
- if (getter == null) {
- getter = findGetter(isStatic, ht, "is", nameComponent);
- }
-
- // setter
- MemberBox setter = null;
- NativeJavaMethod setters = null;
- String setterName = "set".concat(nameComponent);
-
- if (ht.containsKey(setterName)) {
- // Is this value a method?
- Object member = ht.get(setterName);
- if (member instanceof NativeJavaMethod) {
- NativeJavaMethod njmSet = (NativeJavaMethod)member;
- if (getter != null) {
- // We have a getter. Now, do we have a matching
- // setter?
- Class type = getter.method().getReturnType();
- setter = extractSetMethod(type, njmSet.methods,
- isStatic);
- } else {
- // No getter, find any set method
- setter = extractSetMethod(njmSet.methods,
- isStatic);
- }
- if (njmSet.methods.length > 1) {
- setters = njmSet;
- }
- }
- }
- // Make the property.
- BeanProperty bp = new BeanProperty(getter, setter,
- setters);
- toAdd.put(beanPropertyName, bp);
- }
- }
-
- // Add the new bean properties.
- for (Enumeration e = toAdd.keys(); e.hasMoreElements();) {
- Object key = e.nextElement();
- Object value = toAdd.get(key);
- ht.put(key, value);
- }
- }
-
- // Reflect constructors
- Constructor[] constructors = getAccessibleConstructors();
- ctors = new MemberBox[constructors.length];
- for (int i = 0; i != constructors.length; ++i) {
- ctors[i] = new MemberBox(constructors[i]);
- }
- }
-
- private Constructor[] getAccessibleConstructors()
- {
- // The JVM currently doesn't allow changing access on java.lang.Class
- // constructors, so don't try
- if (includePrivate && cl != ScriptRuntime.ClassClass) {
- try {
- Constructor[] cons = cl.getDeclaredConstructors();
- Constructor.setAccessible(cons, true);
-
- return cons;
- } catch (SecurityException e) {
- // Fall through to !includePrivate case
- Context.reportWarning("Could not access constructor " +
- " of class " + cl.getName() +
- " due to lack of privileges.");
- }
- }
- return cl.getConstructors();
- }
-
- private Field[] getAccessibleFields() {
- if (includePrivate) {
- try {
- ArrayList fieldsList = new ArrayList();
- Class currentClass = cl;
-
- while (currentClass != null) {
- // get all declared fields in this class, make them
- // accessible, and save
- Field[] declared = currentClass.getDeclaredFields();
- for (int i = 0; i < declared.length; i++) {
- declared[i].setAccessible(true);
- fieldsList.add(declared[i]);
- }
- // walk up superclass chain. no need to deal specially with
- // interfaces, since they can't have fields
- currentClass = currentClass.getSuperclass();
- }
-
- return (Field[]) fieldsList.toArray(
- new Field[fieldsList.size()]);
- } catch (SecurityException e) {
- // fall through to !includePrivate case
- }
- }
- return cl.getFields();
- }
-
- private MemberBox findGetter(boolean isStatic, Hashtable ht, String prefix,
- String propertyName)
- {
- String getterName = prefix.concat(propertyName);
- if (ht.containsKey(getterName)) {
- // Check that the getter is a method.
- Object member = ht.get(getterName);
- if (member instanceof NativeJavaMethod) {
- NativeJavaMethod njmGet = (NativeJavaMethod) member;
- return extractGetMethod(njmGet.methods, isStatic);
- }
- }
- return null;
- }
-
- private static MemberBox extractGetMethod(MemberBox[] methods,
- boolean isStatic)
- {
- // Inspect the list of all MemberBox for the only one having no
- // parameters
- for (int methodIdx = 0; methodIdx < methods.length; methodIdx++) {
- MemberBox method = methods[methodIdx];
- // Does getter method have an empty parameter list with a return
- // value (eg. a getSomething() or isSomething())?
- if (method.argTypes.length == 0
- && (!isStatic || method.isStatic()))
- {
- Class type = method.method().getReturnType();
- if (type != Void.TYPE) {
- return method;
- }
- break;
- }
- }
- return null;
- }
-
- private static MemberBox extractSetMethod(Class type, MemberBox[] methods,
- boolean isStatic)
- {
- //
- // Note: it may be preferable to allow NativeJavaMethod.findFunction()
- // to find the appropriate setter; unfortunately, it requires an
- // instance of the target arg to determine that.
- //
-
- // Make two passes: one to find a method with direct type assignment,
- // and one to find a widening conversion.
- for (int pass = 1; pass <= 2; ++pass) {
- for (int i = 0; i < methods.length; ++i) {
- MemberBox method = methods[i];
- if (!isStatic || method.isStatic()) {
- Class[] params = method.argTypes;
- if (params.length == 1) {
- if (pass == 1) {
- if (params[0] == type) {
- return method;
- }
- } else {
- if (pass != 2) Kit.codeBug();
- if (params[0].isAssignableFrom(type)) {
- return method;
- }
- }
- }
- }
- }
- }
- return null;
- }
-
- private static MemberBox extractSetMethod(MemberBox[] methods,
- boolean isStatic)
- {
-
- for (int i = 0; i < methods.length; ++i) {
- MemberBox method = methods[i];
- if (!isStatic || method.isStatic()) {
- if (method.method().getReturnType() == Void.TYPE) {
- if (method.argTypes.length == 1) {
- return method;
- }
- }
- }
- }
- return null;
- }
-
- Hashtable getFieldAndMethodsObjects(Scriptable scope, Object javaObject,
- boolean isStatic)
- {
- Hashtable ht = isStatic ? staticFieldAndMethods : fieldAndMethods;
- if (ht == null)
- return null;
- int len = ht.size();
- Hashtable result = new Hashtable(len);
- Enumeration e = ht.elements();
- while (len-- > 0) {
- FieldAndMethods fam = (FieldAndMethods) e.nextElement();
- FieldAndMethods famNew = new FieldAndMethods(scope, fam.methods,
- fam.field);
- famNew.javaObject = javaObject;
- result.put(fam.field.getName(), famNew);
- }
- return result;
- }
-
- static JavaMembers lookupClass(Scriptable scope, Class dynamicType,
- Class staticType, boolean includeProtected)
- {
- JavaMembers members;
- scope = ScriptableObject.getTopLevelScope(scope);
- ClassCache cache = ClassCache.get(scope);
- Map<Class<?>,JavaMembers> ct = cache.getClassCacheMap();
-
- Class cl = dynamicType;
- for (;;) {
- members = ct.get(cl);
- if (members != null) {
- return members;
- }
- try {
- members = new JavaMembers(scope, cl, includeProtected);
- break;
- } catch (SecurityException e) {
- // Reflection may fail for objects that are in a restricted
- // access package (e.g. sun.*). If we get a security
- // exception, try again with the static type if it is interface.
- // Otherwise, try superclass
- if (staticType != null && staticType.isInterface()) {
- cl = staticType;
- staticType = null; // try staticType only once
- } else {
- Class parent = cl.getSuperclass();
- if (parent == null) {
- if (cl.isInterface()) {
- // last resort after failed staticType interface
- parent = ScriptRuntime.ObjectClass;
- } else {
- throw e;
- }
- }
- cl = parent;
- }
- }
- }
-
- if (cache.isCachingEnabled())
- ct.put(cl, members);
- return members;
- }
-
- RuntimeException reportMemberNotFound(String memberName)
- {
- return Context.reportRuntimeError2(
- "msg.java.member.not.found", cl.getName(), memberName);
- }
-
- private Class cl;
- private Hashtable members;
- private Hashtable fieldAndMethods;
- private Hashtable staticMembers;
- private Hashtable staticFieldAndMethods;
- MemberBox[] ctors;
- private boolean includePrivate;
-}
-
-class BeanProperty
-{
- BeanProperty(MemberBox getter, MemberBox setter, NativeJavaMethod setters)
- {
- this.getter = getter;
- this.setter = setter;
- this.setters = setters;
- }
-
- MemberBox getter;
- MemberBox setter;
- NativeJavaMethod setters;
-}
-
-class FieldAndMethods extends NativeJavaMethod
-{
- static final long serialVersionUID = -9222428244284796755L;
-
- FieldAndMethods(Scriptable scope, MemberBox[] methods, Field field)
- {
- super(methods);
- this.field = field;
- setParentScope(scope);
- setPrototype(ScriptableObject.getFunctionPrototype(scope));
- }
-
- public Object getDefaultValue(Class hint)
- {
- if (hint == ScriptRuntime.FunctionClass)
- return this;
- Object rval;
- Class type;
- try {
- rval = field.get(javaObject);
- type = field.getType();
- } catch (IllegalAccessException accEx) {
- throw Context.reportRuntimeError1(
- "msg.java.internal.private", field.getName());
- }
- Context cx = Context.getContext();
- rval = cx.getWrapFactory().wrap(cx, this, rval, type);
- if (rval instanceof Scriptable) {
- rval = ((Scriptable) rval).getDefaultValue(hint);
- }
- return rval;
- }
-
- Field field;
- Object javaObject;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaScriptException.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaScriptException.java
deleted file mode 100644
index 11ebedf..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaScriptException.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- 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
- * Bojan Cekrlic
- * Hannes Wallnoefer
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * Java reflection of JavaScript exceptions.
- * Instances of this class are thrown by the JavaScript 'throw' keyword.
- *
- * @author Mike McCabe
- */
-public class JavaScriptException extends RhinoException
-{
- static final long serialVersionUID = -7666130513694669293L;
-
- /**
- * @deprecated
- * Use {@link WrappedException#WrappedException(Throwable)} to report
- * exceptions in Java code.
- */
- public JavaScriptException(Object value)
- {
- this(value, "", 0);
- }
-
- /**
- * Create a JavaScript exception wrapping the given JavaScript value
- *
- * @param value the JavaScript value thrown.
- */
- public JavaScriptException(Object value, String sourceName, int lineNumber)
- {
- recordErrorOrigin(sourceName, lineNumber, null, 0);
- this.value = value;
- }
-
- public String details()
- {
- try {
- return ScriptRuntime.toString(value);
- } catch (RuntimeException rte) {
- // ScriptRuntime.toString may throw a RuntimeException
- if (value == null) {
- return "null";
- } else if (value instanceof Scriptable) {
- return ScriptRuntime.defaultObjectToString((Scriptable)value);
- } else {
- return value.toString();
- }
- }
- }
-
- /**
- * @return the value wrapped by this exception
- */
- public Object getValue()
- {
- return value;
- }
-
- /**
- * @deprecated Use {@link RhinoException#sourceName()} from the super class.
- */
- public String getSourceName()
- {
- return sourceName();
- }
-
- /**
- * @deprecated Use {@link RhinoException#lineNumber()} from the super class.
- */
- public int getLineNumber()
- {
- return lineNumber();
- }
-
- private Object value;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Kit.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Kit.java
deleted file mode 100644
index f7b4cad..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Kit.java
+++ /dev/null
@@ -1,486 +0,0 @@
-/* -*- 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):
- * Igor Bukanov, igor@fastmail.fm
- *
- * 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;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.lang.reflect.Method;
-import java.util.Hashtable;
-
-/**
- * Collection of utilities
- */
-
-public class Kit
-{
- /**
- * Reflection of Throwable.initCause(Throwable) from JDK 1.4
- * or nul if it is not available.
- */
- private static Method Throwable_initCause = null;
-
- static {
- // Are we running on a JDK 1.4 or later system?
- try {
- Class ThrowableClass = Kit.classOrNull("java.lang.Throwable");
- Class[] signature = { ThrowableClass };
- Throwable_initCause
- = ThrowableClass.getMethod("initCause", signature);
- } catch (Exception ex) {
- // Assume any exceptions means the method does not exist.
- }
- }
-
- public static Class classOrNull(String className)
- {
- try {
- return Class.forName(className);
- } catch (ClassNotFoundException ex) {
- } catch (SecurityException ex) {
- } catch (LinkageError ex) {
- } catch (IllegalArgumentException e) {
- // Can be thrown if name has characters that a class name
- // can not contain
- }
- return null;
- }
-
- public static Class classOrNull(ClassLoader loader, String className)
- {
- try {
- return loader.loadClass(className);
- } catch (ClassNotFoundException ex) {
- } catch (SecurityException ex) {
- } catch (LinkageError ex) {
- } catch (IllegalArgumentException e) {
- // Can be thrown if name has characters that a class name
- // can not contain
- }
- return null;
- }
-
- static Object newInstanceOrNull(Class cl)
- {
- try {
- return cl.newInstance();
- } catch (SecurityException x) {
- } catch (LinkageError ex) {
- } catch (InstantiationException x) {
- } catch (IllegalAccessException x) {
- }
- return null;
- }
-
- /**
- * Check that testClass is accesible from the given loader.
- */
- static boolean testIfCanLoadRhinoClasses(ClassLoader loader)
- {
- Class testClass = ScriptRuntime.ContextFactoryClass;
- Class x = Kit.classOrNull(loader, testClass.getName());
- if (x != testClass) {
- // The check covers the case when x == null =>
- // loader does not know about testClass or the case
- // when x != null && x != testClass =>
- // loader loads a class unrelated to testClass
- return false;
- }
- return true;
- }
-
- /**
- * If initCause methods exists in Throwable, call
- * <tt>ex.initCause(cause)</tt> or otherwise do nothing.
- * @return The <tt>ex</tt> argument.
- */
- public static RuntimeException initCause(RuntimeException ex,
- Throwable cause)
- {
- if (Throwable_initCause != null) {
- Object[] args = { cause };
- try {
- Throwable_initCause.invoke(ex, args);
- } catch (Exception e) {
- // Ignore any exceptions
- }
- }
- return ex;
- }
-
- /**
- * Split string into array of strings using semicolon as string terminator
- * (; after the last string is required).
- */
- public static String[] semicolonSplit(String s)
- {
- String[] array = null;
- for (;;) {
- // loop 2 times: first to count semicolons and then to fill array
- int count = 0;
- int cursor = 0;
- for (;;) {
- int next = s.indexOf(';', cursor);
- if (next < 0) {
- break;
- }
- if (array != null) {
- array[count] = s.substring(cursor, next);
- }
- ++count;
- cursor = next + 1;
- }
- // after the last semicolon
- if (array == null) {
- // array size counting state:
- // check for required terminating ';'
- if (cursor != s.length())
- throw new IllegalArgumentException();
- array = new String[count];
- } else {
- // array filling state: stop the loop
- break;
- }
- }
- return array;
- }
-
- /**
- * If character <tt>c</tt> is a hexadecimal digit, return
- * <tt>accumulator</tt> * 16 plus corresponding
- * number. Otherise return -1.
- */
- public static int xDigitToInt(int c, int accumulator)
- {
- check: {
- // Use 0..9 < A..Z < a..z
- if (c <= '9') {
- c -= '0';
- if (0 <= c) { break check; }
- } else if (c <= 'F') {
- if ('A' <= c) {
- c -= ('A' - 10);
- break check;
- }
- } else if (c <= 'f') {
- if ('a' <= c) {
- c -= ('a' - 10);
- break check;
- }
- }
- return -1;
- }
- return (accumulator << 4) | c;
- }
-
- /**
- * Add <i>listener</i> to <i>bag</i> of listeners.
- * The function does not modify <i>bag</i> and return a new collection
- * containing <i>listener</i> and all listeners from <i>bag</i>.
- * Bag without listeners always represented as the null value.
- * <p>
- * Usage example:
- * <pre>
- * private volatile Object changeListeners;
- *
- * public void addMyListener(PropertyChangeListener l)
- * {
- * synchronized (this) {
- * changeListeners = Kit.addListener(changeListeners, l);
- * }
- * }
- *
- * public void removeTextListener(PropertyChangeListener l)
- * {
- * synchronized (this) {
- * changeListeners = Kit.removeListener(changeListeners, l);
- * }
- * }
- *
- * public void fireChangeEvent(Object oldValue, Object newValue)
- * {
- * // Get immune local copy
- * Object listeners = changeListeners;
- * if (listeners != null) {
- * PropertyChangeEvent e = new PropertyChangeEvent(
- * this, "someProperty" oldValue, newValue);
- * for (int i = 0; ; ++i) {
- * Object l = Kit.getListener(listeners, i);
- * if (l == null)
- * break;
- * ((PropertyChangeListener)l).propertyChange(e);
- * }
- * }
- * }
- * </pre>
- *
- * @param listener Listener to add to <i>bag</i>
- * @param bag Current collection of listeners.
- * @return A new bag containing all listeners from <i>bag</i> and
- * <i>listener</i>.
- * @see #removeListener(Object bag, Object listener)
- * @see #getListener(Object bag, int index)
- */
- public static Object addListener(Object bag, Object listener)
- {
- if (listener == null) throw new IllegalArgumentException();
- if (listener instanceof Object[]) throw new IllegalArgumentException();
-
- if (bag == null) {
- bag = listener;
- } else if (!(bag instanceof Object[])) {
- bag = new Object[] { bag, listener };
- } else {
- Object[] array = (Object[])bag;
- int L = array.length;
- // bag has at least 2 elements if it is array
- if (L < 2) throw new IllegalArgumentException();
- Object[] tmp = new Object[L + 1];
- System.arraycopy(array, 0, tmp, 0, L);
- tmp[L] = listener;
- bag = tmp;
- }
-
- return bag;
- }
-
- /**
- * Remove <i>listener</i> from <i>bag</i> of listeners.
- * The function does not modify <i>bag</i> and return a new collection
- * containing all listeners from <i>bag</i> except <i>listener</i>.
- * If <i>bag</i> does not contain <i>listener</i>, the function returns
- * <i>bag</i>.
- * <p>
- * For usage example, see {@link #addListener(Object bag, Object listener)}.
- *
- * @param listener Listener to remove from <i>bag</i>
- * @param bag Current collection of listeners.
- * @return A new bag containing all listeners from <i>bag</i> except
- * <i>listener</i>.
- * @see #addListener(Object bag, Object listener)
- * @see #getListener(Object bag, int index)
- */
- public static Object removeListener(Object bag, Object listener)
- {
- if (listener == null) throw new IllegalArgumentException();
- if (listener instanceof Object[]) throw new IllegalArgumentException();
-
- if (bag == listener) {
- bag = null;
- } else if (bag instanceof Object[]) {
- Object[] array = (Object[])bag;
- int L = array.length;
- // bag has at least 2 elements if it is array
- if (L < 2) throw new IllegalArgumentException();
- if (L == 2) {
- if (array[1] == listener) {
- bag = array[0];
- } else if (array[0] == listener) {
- bag = array[1];
- }
- } else {
- int i = L;
- do {
- --i;
- if (array[i] == listener) {
- Object[] tmp = new Object[L - 1];
- System.arraycopy(array, 0, tmp, 0, i);
- System.arraycopy(array, i + 1, tmp, i, L - (i + 1));
- bag = tmp;
- break;
- }
- } while (i != 0);
- }
- }
-
- return bag;
- }
-
- /**
- * Get listener at <i>index</i> position in <i>bag</i> or null if
- * <i>index</i> equals to number of listeners in <i>bag</i>.
- * <p>
- * For usage example, see {@link #addListener(Object bag, Object listener)}.
- *
- * @param bag Current collection of listeners.
- * @param index Index of the listener to access.
- * @return Listener at the given index or null.
- * @see #addListener(Object bag, Object listener)
- * @see #removeListener(Object bag, Object listener)
- */
- public static Object getListener(Object bag, int index)
- {
- if (index == 0) {
- if (bag == null)
- return null;
- if (!(bag instanceof Object[]))
- return bag;
- Object[] array = (Object[])bag;
- // bag has at least 2 elements if it is array
- if (array.length < 2) throw new IllegalArgumentException();
- return array[0];
- } else if (index == 1) {
- if (!(bag instanceof Object[])) {
- if (bag == null) throw new IllegalArgumentException();
- return null;
- }
- Object[] array = (Object[])bag;
- // the array access will check for index on its own
- return array[1];
- } else {
- // bag has to array
- Object[] array = (Object[])bag;
- int L = array.length;
- if (L < 2) throw new IllegalArgumentException();
- if (index == L)
- return null;
- return array[index];
- }
- }
-
- static Object initHash(Hashtable h, Object key, Object initialValue)
- {
- synchronized (h) {
- Object current = h.get(key);
- if (current == null) {
- h.put(key, initialValue);
- } else {
- initialValue = current;
- }
- }
- return initialValue;
- }
-
- private final static class ComplexKey
- {
- private Object key1;
- private Object key2;
- private int hash;
-
- ComplexKey(Object key1, Object key2)
- {
- this.key1 = key1;
- this.key2 = key2;
- }
-
- public boolean equals(Object anotherObj)
- {
- if (!(anotherObj instanceof ComplexKey))
- return false;
- ComplexKey another = (ComplexKey)anotherObj;
- return key1.equals(another.key1) && key2.equals(another.key2);
- }
-
- public int hashCode()
- {
- if (hash == 0) {
- hash = key1.hashCode() ^ key2.hashCode();
- }
- return hash;
- }
- }
-
- public static Object makeHashKeyFromPair(Object key1, Object key2)
- {
- if (key1 == null) throw new IllegalArgumentException();
- if (key2 == null) throw new IllegalArgumentException();
- return new ComplexKey(key1, key2);
- }
-
- public static String readReader(Reader r)
- throws IOException
- {
- char[] buffer = new char[512];
- int cursor = 0;
- for (;;) {
- int n = r.read(buffer, cursor, buffer.length - cursor);
- if (n < 0) { break; }
- cursor += n;
- if (cursor == buffer.length) {
- char[] tmp = new char[buffer.length * 2];
- System.arraycopy(buffer, 0, tmp, 0, cursor);
- buffer = tmp;
- }
- }
- return new String(buffer, 0, cursor);
- }
-
- public static byte[] readStream(InputStream is, int initialBufferCapacity)
- throws IOException
- {
- if (initialBufferCapacity <= 0) {
- throw new IllegalArgumentException(
- "Bad initialBufferCapacity: "+initialBufferCapacity);
- }
- byte[] buffer = new byte[initialBufferCapacity];
- int cursor = 0;
- for (;;) {
- int n = is.read(buffer, cursor, buffer.length - cursor);
- if (n < 0) { break; }
- cursor += n;
- if (cursor == buffer.length) {
- byte[] tmp = new byte[buffer.length * 2];
- System.arraycopy(buffer, 0, tmp, 0, cursor);
- buffer = tmp;
- }
- }
- if (cursor != buffer.length) {
- byte[] tmp = new byte[cursor];
- System.arraycopy(buffer, 0, tmp, 0, cursor);
- buffer = tmp;
- }
- return buffer;
- }
-
- /**
- * Throws RuntimeException to indicate failed assertion.
- * The function never returns and its return type is RuntimeException
- * only to be able to write <tt>throw Kit.codeBug()</tt> if plain
- * <tt>Kit.codeBug()</tt> triggers unreachable code error.
- */
- public static RuntimeException codeBug()
- throws RuntimeException
- {
- RuntimeException ex = new IllegalStateException("FAILED ASSERTION");
- // Print stack trace ASAP
- ex.printStackTrace(System.err);
- throw ex;
- }
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/LazilyLoadedCtor.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/LazilyLoadedCtor.java
deleted file mode 100644
index 4153372..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/LazilyLoadedCtor.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- 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-2000
- * 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;
-
-import java.lang.reflect.*;
-
-/**
- * Avoid loading classes unless they are used.
- *
- * <p> This improves startup time and average memory usage.
- */
-public final class LazilyLoadedCtor implements java.io.Serializable {
- private static final long serialVersionUID = 1L;
-
- private static final int STATE_BEFORE_INIT = 0;
- private static final int STATE_INITIALIZING = 1;
- private static final int STATE_WITH_VALUE = 2;
-
- private final ScriptableObject scope;
- private final String propertyName;
- private final String className;
- private final boolean sealed;
- private Object initializedValue;
- private int state;
-
- public LazilyLoadedCtor(ScriptableObject scope, String propertyName,
- String className, boolean sealed)
- {
-
- this.scope = scope;
- this.propertyName = propertyName;
- this.className = className;
- this.sealed = sealed;
- this.state = STATE_BEFORE_INIT;
-
- scope.addLazilyInitializedValue(propertyName, 0, this,
- ScriptableObject.DONTENUM);
- }
-
- void init()
- {
- synchronized (this) {
- if (state == STATE_INITIALIZING)
- throw new IllegalStateException(
- "Recursive initialization for "+propertyName);
- if (state == STATE_BEFORE_INIT) {
- state = STATE_INITIALIZING;
- // Set value now to have something to set in finally block if
- // buildValue throws.
- Object value = Scriptable.NOT_FOUND;
- try {
- value = buildValue();
- } finally {
- initializedValue = value;
- state = STATE_WITH_VALUE;
- }
- }
- }
- }
-
- Object getValue()
- {
- if (state != STATE_WITH_VALUE)
- throw new IllegalStateException(propertyName);
- return initializedValue;
- }
-
- private Object buildValue()
- {
- Class cl = Kit.classOrNull(className);
- if (cl != null) {
- try {
- Object value = ScriptableObject.buildClassCtor(scope, cl,
- sealed, false);
- if (value != null) {
- return value;
- }
- else {
- // cl has own static initializer which is expected
- // to set the property on its own.
- value = scope.get(propertyName, scope);
- if (value != Scriptable.NOT_FOUND)
- return value;
- }
- } catch (InvocationTargetException ex) {
- Throwable target = ex.getTargetException();
- if (target instanceof RuntimeException) {
- throw (RuntimeException)target;
- }
- } catch (RhinoException ex) {
- } catch (InstantiationException ex) {
- } catch (IllegalAccessException ex) {
- } catch (SecurityException ex) {
- }
- }
- return Scriptable.NOT_FOUND;
- }
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/MemberBox.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/MemberBox.java
deleted file mode 100644
index 2d3553f..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/MemberBox.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/* -*- 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):
- * Igor Bukanov
- * Felix Meschberger
- * Norris Boyd
- * Ulrike Mueller <umueller@demandware.com>
- *
- * 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;
-
-import java.lang.reflect.*;
-import java.io.*;
-
-/**
- * Wrappper class for Method and Constructor instances to cache
- * getParameterTypes() results, recover from IllegalAccessException
- * in some cases and provide serialization support.
- *
- * @author Igor Bukanov
- */
-
-final class MemberBox implements Serializable
-{
- static final long serialVersionUID = 6358550398665688245L;
-
- private transient Member memberObject;
- transient Class[] argTypes;
- transient Object delegateTo;
- transient boolean vararg;
-
-
- MemberBox(Method method)
- {
- init(method);
- }
-
- MemberBox(Constructor constructor)
- {
- init(constructor);
- }
-
- private void init(Method method)
- {
- this.memberObject = method;
- this.argTypes = method.getParameterTypes();
- this.vararg = VMBridge.instance.isVarArgs(method);
- }
-
- private void init(Constructor constructor)
- {
- this.memberObject = constructor;
- this.argTypes = constructor.getParameterTypes();
- this.vararg = VMBridge.instance.isVarArgs(constructor);
- }
-
- Method method()
- {
- return (Method)memberObject;
- }
-
- Constructor ctor()
- {
- return (Constructor)memberObject;
- }
-
- Member member()
- {
- return memberObject;
- }
-
- boolean isMethod()
- {
- return memberObject instanceof Method;
- }
-
- boolean isCtor()
- {
- return memberObject instanceof Constructor;
- }
-
- boolean isStatic()
- {
- return Modifier.isStatic(memberObject.getModifiers());
- }
-
- String getName()
- {
- return memberObject.getName();
- }
-
- Class getDeclaringClass()
- {
- return memberObject.getDeclaringClass();
- }
-
- String toJavaDeclaration()
- {
- StringBuffer sb = new StringBuffer();
- if (isMethod()) {
- Method method = method();
- sb.append(method.getReturnType());
- sb.append(' ');
- sb.append(method.getName());
- } else {
- Constructor ctor = ctor();
- String name = ctor.getDeclaringClass().getName();
- int lastDot = name.lastIndexOf('.');
- if (lastDot >= 0) {
- name = name.substring(lastDot + 1);
- }
- sb.append(name);
- }
- sb.append(JavaMembers.liveConnectSignature(argTypes));
- return sb.toString();
- }
-
- public String toString()
- {
- return memberObject.toString();
- }
-
- Object invoke(Object target, Object[] args)
- {
- Method method = method();
- try {
- try {
- return method.invoke(target, args);
- } catch (IllegalAccessException ex) {
- Method accessible = searchAccessibleMethod(method, argTypes);
- if (accessible != null) {
- memberObject = accessible;
- method = accessible;
- } else {
- if (!VMBridge.instance.tryToMakeAccessible(method)) {
- throw Context.throwAsScriptRuntimeEx(ex);
- }
- }
- // Retry after recovery
- return method.invoke(target, args);
- }
- } catch (Exception ex) {
- throw Context.throwAsScriptRuntimeEx(ex);
- }
- }
-
- Object newInstance(Object[] args)
- {
- Constructor ctor = ctor();
- try {
- try {
- return ctor.newInstance(args);
- } catch (IllegalAccessException ex) {
- if (!VMBridge.instance.tryToMakeAccessible(ctor)) {
- throw Context.throwAsScriptRuntimeEx(ex);
- }
- }
- return ctor.newInstance(args);
- } catch (Exception ex) {
- throw Context.throwAsScriptRuntimeEx(ex);
- }
- }
-
- private static Method searchAccessibleMethod(Method method, Class[] params)
- {
- int modifiers = method.getModifiers();
- if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
- Class c = method.getDeclaringClass();
- if (!Modifier.isPublic(c.getModifiers())) {
- String name = method.getName();
- Class[] intfs = c.getInterfaces();
- for (int i = 0, N = intfs.length; i != N; ++i) {
- Class intf = intfs[i];
- if (Modifier.isPublic(intf.getModifiers())) {
- try {
- return intf.getMethod(name, params);
- } catch (NoSuchMethodException ex) {
- } catch (SecurityException ex) { }
- }
- }
- for (;;) {
- c = c.getSuperclass();
- if (c == null) { break; }
- if (Modifier.isPublic(c.getModifiers())) {
- try {
- Method m = c.getMethod(name, params);
- int mModifiers = m.getModifiers();
- if (Modifier.isPublic(mModifiers)
- && !Modifier.isStatic(mModifiers))
- {
- return m;
- }
- } catch (NoSuchMethodException ex) {
- } catch (SecurityException ex) { }
- }
- }
- }
- }
- return null;
- }
-
- private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- in.defaultReadObject();
- Member member = readMember(in);
- if (member instanceof Method) {
- init((Method)member);
- } else {
- init((Constructor)member);
- }
- }
-
- private void writeObject(ObjectOutputStream out)
- throws IOException
- {
- out.defaultWriteObject();
- writeMember(out, memberObject);
- }
-
- /**
- * Writes a Constructor or Method object.
- *
- * Methods and Constructors are not serializable, so we must serialize
- * information about the class, the name, and the parameters and
- * recreate upon deserialization.
- */
- private static void writeMember(ObjectOutputStream out, Member member)
- throws IOException
- {
- if (member == null) {
- out.writeBoolean(false);
- return;
- }
- out.writeBoolean(true);
- if (!(member instanceof Method || member instanceof Constructor))
- throw new IllegalArgumentException("not Method or Constructor");
- out.writeBoolean(member instanceof Method);
- out.writeObject(member.getName());
- out.writeObject(member.getDeclaringClass());
- if (member instanceof Method) {
- writeParameters(out, ((Method) member).getParameterTypes());
- } else {
- writeParameters(out, ((Constructor) member).getParameterTypes());
- }
- }
-
- /**
- * Reads a Method or a Constructor from the stream.
- */
- private static Member readMember(ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- if (!in.readBoolean())
- return null;
- boolean isMethod = in.readBoolean();
- String name = (String) in.readObject();
- Class declaring = (Class) in.readObject();
- Class[] parms = readParameters(in);
- try {
- if (isMethod) {
- return declaring.getMethod(name, parms);
- } else {
- return declaring.getConstructor(parms);
- }
- } catch (NoSuchMethodException e) {
- throw new IOException("Cannot find member: " + e);
- }
- }
-
- private static final Class[] primitives = {
- Boolean.TYPE,
- Byte.TYPE,
- Character.TYPE,
- Double.TYPE,
- Float.TYPE,
- Integer.TYPE,
- Long.TYPE,
- Short.TYPE,
- Void.TYPE
- };
-
- /**
- * Writes an array of parameter types to the stream.
- *
- * Requires special handling because primitive types cannot be
- * found upon deserialization by the default Java implementation.
- */
- private static void writeParameters(ObjectOutputStream out, Class[] parms)
- throws IOException
- {
- out.writeShort(parms.length);
- outer:
- for (int i=0; i < parms.length; i++) {
- Class parm = parms[i];
- boolean primitive = parm.isPrimitive();
- out.writeBoolean(primitive);
- if (!primitive) {
- out.writeObject(parm);
- continue;
- }
- for (int j=0; j < primitives.length; j++) {
- if (parm.equals(primitives[j])) {
- out.writeByte(j);
- continue outer;
- }
- }
- throw new IllegalArgumentException("Primitive " + parm +
- " not found");
- }
- }
-
- /**
- * Reads an array of parameter types from the stream.
- */
- private static Class[] readParameters(ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- Class[] result = new Class[in.readShort()];
- for (int i=0; i < result.length; i++) {
- if (!in.readBoolean()) {
- result[i] = (Class) in.readObject();
- continue;
- }
- result[i] = primitives[in.readByte()];
- }
- return result;
- }
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeArray.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeArray.java
deleted file mode 100644
index b170ff4..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeArray.java
+++ /dev/null
@@ -1,1727 +0,0 @@
-/* -*- 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
- * Mike McCabe
- * 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;
-
-import java.util.Arrays;
-
-/**
- * This class implements the Array native object.
- * @author Norris Boyd
- * @author Mike McCabe
- */
-public class NativeArray extends IdScriptableObject
-{
- static final long serialVersionUID = 7331366857676127338L;
-
- /*
- * Optimization possibilities and open issues:
- * - Long vs. double schizophrenia. I suspect it might be better
- * to use double throughout.
- *
- * - Functions that need a new Array call "new Array" in the
- * current scope rather than using a hardwired constructor;
- * "Array" could be redefined. It turns out that js calls the
- * equivalent of "new Array" in the current scope, except that it
- * always gets at least an object back, even when Array == null.
- */
-
- private static final Object ARRAY_TAG = new Object();
- private static final Integer NEGATIVE_ONE = new Integer(-1);
-
- static void init(Scriptable scope, boolean sealed)
- {
- NativeArray obj = new NativeArray(0);
- obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
- }
-
- static int getMaximumInitialCapacity() {
- return maximumInitialCapacity;
- }
-
- static void setMaximumInitialCapacity(int maximumInitialCapacity) {
- NativeArray.maximumInitialCapacity = maximumInitialCapacity;
- }
-
- public NativeArray(long lengthArg)
- {
- denseOnly = lengthArg <= maximumInitialCapacity;
- if (denseOnly) {
- int intLength = (int) lengthArg;
- if (intLength < DEFAULT_INITIAL_CAPACITY)
- intLength = DEFAULT_INITIAL_CAPACITY;
- dense = new Object[intLength];
- Arrays.fill(dense, Scriptable.NOT_FOUND);
- }
- length = lengthArg;
- }
-
- public NativeArray(Object[] array)
- {
- denseOnly = true;
- dense = array;
- length = array.length;
- }
-
- public String getClassName()
- {
- return "Array";
- }
-
- private static final int
- Id_length = 1,
- MAX_INSTANCE_ID = 1;
-
- protected int getMaxInstanceId()
- {
- return MAX_INSTANCE_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 ScriptRuntime.wrapNumber(length);
- }
- return super.getInstanceIdValue(id);
- }
-
- protected void setInstanceIdValue(int id, Object value)
- {
- if (id == Id_length) {
- setLength(value); return;
- }
- super.setInstanceIdValue(id, value);
- }
-
- protected void fillConstructorProperties(IdFunctionObject ctor)
- {
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_join,
- "join", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_reverse,
- "reverse", 1);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_sort,
- "sort", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_push,
- "push", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_pop,
- "pop", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_shift,
- "shift", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_unshift,
- "unshift", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_splice,
- "splice", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_concat,
- "concat", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_slice,
- "slice", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_indexOf,
- "indexOf", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_lastIndexOf,
- "lastIndexOf", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_every,
- "every", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_filter,
- "filter", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_forEach,
- "forEach", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_map,
- "map", 2);
- addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_some,
- "some", 2);
- 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_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;
- case Id_indexOf: arity=1; s="indexOf"; break;
- case Id_lastIndexOf: arity=1; s="lastIndexOf"; break;
- case Id_every: arity=1; s="every"; break;
- case Id_filter: arity=1; s="filter"; break;
- case Id_forEach: arity=1; s="forEach"; break;
- case Id_map: arity=1; s="map"; break;
- case Id_some: arity=1; s="some"; break;
- default: throw new IllegalArgumentException(String.valueOf(id));
- }
- initPrototypeMethod(ARRAY_TAG, id, s, arity);
- }
-
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(ARRAY_TAG)) {
- return super.execIdCall(f, cx, scope, thisObj, args);
- }
- int id = f.methodId();
- again:
- for (;;) {
- switch (id) {
- case ConstructorId_join:
- case ConstructorId_reverse:
- case ConstructorId_sort:
- case ConstructorId_push:
- case ConstructorId_pop:
- case ConstructorId_shift:
- case ConstructorId_unshift:
- case ConstructorId_splice:
- case ConstructorId_concat:
- case ConstructorId_slice:
- case ConstructorId_indexOf:
- case ConstructorId_lastIndexOf:
- case ConstructorId_every:
- case ConstructorId_filter:
- case ConstructorId_forEach:
- case ConstructorId_map:
- case ConstructorId_some: {
- thisObj = ScriptRuntime.toObject(scope, args[0]);
- Object[] newArgs = new Object[args.length-1];
- for (int i=0; i < newArgs.length; i++)
- newArgs[i] = args[i+1];
- args = newArgs;
- id = -id;
- continue again;
- }
-
- case Id_constructor: {
- boolean inNewExpr = (thisObj == null);
- if (!inNewExpr) {
- // IdFunctionObject.construct will set up parent, proto
- return f.construct(cx, scope, args);
- }
- return jsConstructor(cx, scope, args);
- }
-
- 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);
-
- case Id_indexOf:
- return indexOfHelper(cx, thisObj, args, false);
-
- case Id_lastIndexOf:
- return indexOfHelper(cx, thisObj, args, true);
-
- case Id_every:
- case Id_filter:
- case Id_forEach:
- case Id_map:
- case Id_some:
- return iterativeMethod(cx, id, scope, thisObj, args);
- }
- throw new IllegalArgumentException(String.valueOf(id));
- }
- }
-
- public Object get(int index, Scriptable start)
- {
- if (!denseOnly && isGetterOrSetter(null, index, false))
- return super.get(index, start);
- if (dense != null && 0 <= index && index < dense.length)
- return dense[index];
- return super.get(index, start);
- }
-
- public boolean has(int index, Scriptable start)
- {
- if (!denseOnly && isGetterOrSetter(null, index, false))
- return super.has(index, start);
- if (dense != null && 0 <= index && index < dense.length)
- return dense[index] != NOT_FOUND;
- return super.has(index, start);
- }
-
- // if id is an array index (ECMA 15.4.0), return the number,
- // otherwise return -1L
- private static long toArrayIndex(String id)
- {
- double d = ScriptRuntime.toNumber(id);
- if (d == d) {
- long index = ScriptRuntime.toUint32(d);
- if (index == d && index != 4294967295L) {
- // Assume that ScriptRuntime.toString(index) is the same
- // as java.lang.Long.toString(index) for long
- if (Long.toString(index).equals(id)) {
- return index;
- }
- }
- }
- return -1;
- }
-
- public void put(String id, Scriptable start, Object value)
- {
- super.put(id, start, value);
- if (start == this) {
- // If the object is sealed, super will throw exception
- long index = toArrayIndex(id);
- if (index >= length) {
- length = index + 1;
- denseOnly = false;
- }
- }
- }
-
- private boolean ensureCapacity(int capacity)
- {
- if (capacity > dense.length) {
- if (capacity > MAX_PRE_GROW_SIZE) {
- denseOnly = false;
- return false;
- }
- capacity = Math.max(capacity, (int)(dense.length * GROW_FACTOR));
- Object[] newDense = new Object[capacity];
- System.arraycopy(dense, 0, newDense, 0, dense.length);
- Arrays.fill(newDense, dense.length, newDense.length,
- Scriptable.NOT_FOUND);
- dense = newDense;
- }
- return true;
- }
-
- public void put(int index, Scriptable start, Object value)
- {
- if (start == this && !isSealed() && dense != null && 0 <= index &&
- (denseOnly || !isGetterOrSetter(null, index, true)))
- {
- if (index < dense.length) {
- dense[index] = value;
- if (this.length <= index)
- this.length = (long)index + 1;
- return;
- } else if (denseOnly && index < dense.length * GROW_FACTOR &&
- ensureCapacity(index+1))
- {
- dense[index] = value;
- this.length = (long)index + 1;
- return;
- } else {
- denseOnly = false;
- }
- }
- super.put(index, start, value);
- if (start == this) {
- // only set the array length if given an array index (ECMA 15.4.0)
- if (this.length <= index) {
- // avoid overflowing index!
- this.length = (long)index + 1;
- }
- }
- }
-
- public void delete(int index)
- {
- if (dense != null && 0 <= index && index < dense.length &&
- !isSealed() && (denseOnly || !isGetterOrSetter(null, index, true)))
- {
- dense[index] = NOT_FOUND;
- } else {
- super.delete(index);
- }
- }
-
- public Object[] getIds()
- {
- Object[] superIds = super.getIds();
- if (dense == null) { return superIds; }
- int N = dense.length;
- long currentLength = length;
- if (N > currentLength) {
- N = (int)currentLength;
- }
- if (N == 0) { return superIds; }
- int superLength = superIds.length;
- Object[] ids = new Object[N + superLength];
-
- int presentCount = 0;
- for (int i = 0; i != N; ++i) {
- // Replace existing elements by their indexes
- if (dense[i] != NOT_FOUND) {
- ids[presentCount] = new Integer(i);
- ++presentCount;
- }
- }
- if (presentCount != N) {
- // dense contains deleted elems, need to shrink the result
- Object[] tmp = new Object[presentCount + superLength];
- System.arraycopy(ids, 0, tmp, 0, presentCount);
- ids = tmp;
- }
- System.arraycopy(superIds, 0, ids, presentCount, superLength);
- return ids;
- }
-
- public Object getDefaultValue(Class hint)
- {
- if (hint == ScriptRuntime.NumberClass) {
- Context cx = Context.getContext();
- if (cx.getLanguageVersion() == Context.VERSION_1_2)
- return new Long(length);
- }
- return super.getDefaultValue(hint);
- }
-
- /**
- * See ECMA 15.4.1,2
- */
- private static Object jsConstructor(Context cx, Scriptable scope,
- Object[] args)
- {
- if (args.length == 0)
- return new NativeArray(0);
-
- // Only use 1 arg as first element for version 1.2; for
- // any other version (including 1.3) follow ECMA and use it as
- // a length.
- if (cx.getLanguageVersion() == Context.VERSION_1_2) {
- return new NativeArray(args);
- } else {
- Object arg0 = args[0];
- if (args.length > 1 || !(arg0 instanceof Number)) {
- return new NativeArray(args);
- } else {
- long len = ScriptRuntime.toUint32(arg0);
- if (len != ((Number)arg0).doubleValue())
- throw Context.reportRuntimeError0("msg.arraylength.bad");
- return new NativeArray(len);
- }
- }
- }
-
- public long getLength() {
- return length;
- }
-
- /** @deprecated Use {@link #getLength()} instead. */
- public long jsGet_length() {
- return getLength();
- }
-
- /**
- * Change the value of the internal flag that determines whether all
- * storage is handed by a dense backing array rather than an associative
- * store.
- * @param denseOnly new value for denseOnly flag
- * @throws IllegalArgumentException if an attempt is made to enable
- * denseOnly after it was disabled; NativeArray code is not written
- * to handle switching back to a dense representation
- */
- void setDenseOnly(boolean denseOnly) {
- if (denseOnly && !this.denseOnly)
- throw new IllegalArgumentException();
- this.denseOnly = denseOnly;
- }
-
- private void setLength(Object val) {
- /* XXX do we satisfy this?
- * 15.4.5.1 [[Put]](P, V):
- * 1. Call the [[CanPut]] method of A with name P.
- * 2. If Result(1) is false, return.
- * ?
- */
-
- double d = ScriptRuntime.toNumber(val);
- long longVal = ScriptRuntime.toUint32(d);
- if (longVal != d)
- throw Context.reportRuntimeError0("msg.arraylength.bad");
-
- if (denseOnly) {
- if (longVal < length) {
- // downcast okay because denseOnly
- Arrays.fill(dense, (int) longVal, dense.length, NOT_FOUND);
- length = longVal;
- return;
- } else if (longVal < MAX_PRE_GROW_SIZE &&
- longVal < (length * GROW_FACTOR) &&
- ensureCapacity((int)longVal))
- {
- length = longVal;
- return;
- } else {
- denseOnly = false;
- }
- }
- if (longVal < length) {
- // remove all properties between longVal and length
- if (length - longVal > 0x1000) {
- // assume that the representation is sparse
- Object[] e = getIds(); // will only find in object itself
- for (int i=0; i < e.length; i++) {
- Object id = e[i];
- if (id instanceof String) {
- // > MAXINT will appear as string
- String strId = (String)id;
- long index = toArrayIndex(strId);
- if (index >= longVal)
- delete(strId);
- } else {
- int index = ((Integer)id).intValue();
- if (index >= longVal)
- delete(index);
- }
- }
- } else {
- // assume a dense representation
- for (long i = longVal; i < length; i++) {
- deleteElem(this, i);
- }
- }
- }
- length = longVal;
- }
-
- /* Support for generic Array-ish objects. Most of the Array
- * functions try to be generic; anything that has a length
- * property is assumed to be an array.
- * getLengthProperty returns 0 if obj does not have the length property
- * or its value is not convertible to a number.
- */
- static long getLengthProperty(Context cx, Scriptable obj) {
- // These will both give numeric lengths within Uint32 range.
- if (obj instanceof NativeString) {
- return ((NativeString)obj).getLength();
- } else if (obj instanceof NativeArray) {
- return ((NativeArray)obj).getLength();
- }
- return ScriptRuntime.toUint32(
- ScriptRuntime.getObjectProp(obj, "length", cx));
- }
-
- private static Object setLengthProperty(Context cx, Scriptable target,
- long length)
- {
- return ScriptRuntime.setObjectProp(
- target, "length", ScriptRuntime.wrapNumber(length), cx);
- }
-
- /* Utility functions to encapsulate index > Integer.MAX_VALUE
- * handling. Also avoids unnecessary object creation that would
- * be necessary to use the general ScriptRuntime.get/setElem
- * functions... though this is probably premature optimization.
- */
- private static void deleteElem(Scriptable target, long index) {
- int i = (int)index;
- if (i == index) { target.delete(i); }
- else { target.delete(Long.toString(index)); }
- }
-
- private static Object getElem(Context cx, Scriptable target, long index)
- {
- if (index > Integer.MAX_VALUE) {
- String id = Long.toString(index);
- return ScriptRuntime.getObjectProp(target, id, cx);
- } else {
- return ScriptRuntime.getObjectIndex(target, (int)index, cx);
- }
- }
-
- private static void setElem(Context cx, Scriptable target, long index,
- Object value)
- {
- if (index > Integer.MAX_VALUE) {
- String id = Long.toString(index);
- ScriptRuntime.setObjectProp(target, id, value, cx);
- } else {
- ScriptRuntime.setObjectIndex(target, (int)index, value, cx);
- }
- }
-
- private static String toStringHelper(Context cx, Scriptable scope,
- Scriptable thisObj,
- boolean toSource, boolean toLocale)
- {
- /* It's probably redundant to handle long lengths in this
- * function; StringBuffers are limited to 2^31 in java.
- */
-
- long length = getLengthProperty(cx, thisObj);
-
- StringBuffer result = new StringBuffer(256);
-
- // whether to return '4,unquoted,5' or '[4, "quoted", 5]'
- String separator;
-
- if (toSource) {
- result.append('[');
- separator = ", ";
- } else {
- separator = ",";
- }
-
- boolean haslast = false;
- long i = 0;
-
- boolean toplevel, iterating;
- if (cx.iterating == null) {
- toplevel = true;
- iterating = false;
- cx.iterating = new ObjToIntMap(31);
- } else {
- toplevel = false;
- iterating = cx.iterating.has(thisObj);
- }
-
- // Make sure cx.iterating is set to null when done
- // so we don't leak memory
- try {
- if (!iterating) {
- cx.iterating.put(thisObj, 0); // stop recursion.
- for (i = 0; i < length; i++) {
- if (i > 0) result.append(separator);
- Object elem = getElem(cx, thisObj, i);
- if (elem == null || elem == Undefined.instance) {
- haslast = false;
- continue;
- }
- haslast = true;
-
- if (toSource) {
- result.append(ScriptRuntime.uneval(cx, scope, elem));
-
- } else if (elem instanceof String) {
- String s = (String)elem;
- if (toSource) {
- result.append('\"');
- result.append(ScriptRuntime.escapeString(s));
- result.append('\"');
- } else {
- result.append(s);
- }
-
- } else {
- if (toLocale)
- {
- Callable fun;
- Scriptable funThis;
- fun = ScriptRuntime.getPropFunctionAndThis(
- elem, "toLocaleString", cx);
- funThis = ScriptRuntime.lastStoredScriptable(cx);
- elem = fun.call(cx, scope, funThis,
- ScriptRuntime.emptyArgs);
- }
- result.append(ScriptRuntime.toString(elem));
- }
- }
- }
- } finally {
- if (toplevel) {
- cx.iterating = null;
- }
- }
-
- if (toSource) {
- //for [,,].length behavior; we want toString to be symmetric.
- if (!haslast && i > 0)
- result.append(", ]");
- else
- result.append(']');
- }
- return result.toString();
- }
-
- /**
- * See ECMA 15.4.4.3
- */
- private static String js_join(Context cx, Scriptable thisObj,
- Object[] args)
- {
- long llength = getLengthProperty(cx, thisObj);
- int length = (int)llength;
- if (llength != length) {
- throw Context.reportRuntimeError1(
- "msg.arraylength.too.big", String.valueOf(llength));
- }
- // if no args, use "," as separator
- String separator = (args.length < 1 || args[0] == Undefined.instance)
- ? ","
- : ScriptRuntime.toString(args[0]);
- if (thisObj instanceof NativeArray) {
- NativeArray na = (NativeArray) thisObj;
- if (na.denseOnly) {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < length; i++) {
- if (i != 0) {
- sb.append(separator);
- }
- if (i < na.dense.length) {
- Object temp = na.dense[i];
- if (temp != null && temp != Undefined.instance &&
- temp != Scriptable.NOT_FOUND)
- {
- sb.append(ScriptRuntime.toString(temp));
- }
- }
- }
- return sb.toString();
- }
- }
- if (length == 0) {
- return "";
- }
- String[] buf = new String[length];
- int total_size = 0;
- for (int i = 0; i != length; i++) {
- Object temp = getElem(cx, thisObj, i);
- if (temp != null && temp != Undefined.instance) {
- String str = ScriptRuntime.toString(temp);
- total_size += str.length();
- buf[i] = str;
- }
- }
- total_size += (length - 1) * separator.length();
- StringBuffer sb = new StringBuffer(total_size);
- for (int i = 0; i != length; i++) {
- if (i != 0) {
- sb.append(separator);
- }
- String str = buf[i];
- if (str != null) {
- // str == null for undefined or null
- sb.append(str);
- }
- }
- return sb.toString();
- }
-
- /**
- * See ECMA 15.4.4.4
- */
- private static Scriptable js_reverse(Context cx, Scriptable thisObj,
- Object[] args)
- {
- if (thisObj instanceof NativeArray) {
- NativeArray na = (NativeArray) thisObj;
- if (na.denseOnly) {
- for (int i=0, j=((int)na.length)-1; i < j; i++,j--) {
- Object temp = na.dense[i];
- na.dense[i] = na.dense[j];
- na.dense[j] = temp;
- }
- return thisObj;
- }
- }
- long len = getLengthProperty(cx, thisObj);
-
- long half = len / 2;
- for(long i=0; i < half; i++) {
- long j = len - i - 1;
- Object temp1 = getElem(cx, thisObj, i);
- Object temp2 = getElem(cx, thisObj, j);
- setElem(cx, thisObj, i, temp2);
- setElem(cx, thisObj, j, temp1);
- }
- return thisObj;
- }
-
- /**
- * See ECMA 15.4.4.5
- */
- private static Scriptable js_sort(Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- long length = getLengthProperty(cx, thisObj);
-
- if (length <= 1) { return thisObj; }
-
- Object compare;
- Object[] cmpBuf;
-
- if (args.length > 0 && Undefined.instance != args[0]) {
- // sort with given compare function
- compare = args[0];
- cmpBuf = new Object[2]; // Buffer for cmp arguments
- } else {
- // sort with default compare
- compare = null;
- cmpBuf = null;
- }
- if (thisObj instanceof NativeArray) {
- NativeArray na = (NativeArray) thisObj;
- if (na.denseOnly) {
- int ilength = (int) length;
- heapsort(cx, scope, na.dense, ilength, compare, cmpBuf);
- return thisObj;
- }
- }
-
- // Should we use the extended sort function, or the faster one?
- if (length >= Integer.MAX_VALUE) {
- heapsort_extended(cx, scope, thisObj, length, compare, cmpBuf);
- } else {
- int ilength = (int)length;
- // copy the JS array into a working array, so it can be
- // sorted cheaply.
- Object[] working = new Object[ilength];
- for (int i = 0; i != ilength; ++i) {
- working[i] = getElem(cx, thisObj, i);
- }
-
- heapsort(cx, scope, working, ilength, compare, cmpBuf);
-
- // copy the working array back into thisObj
- for (int i = 0; i != ilength; ++i) {
- setElem(cx, thisObj, i, working[i]);
- }
- }
- return thisObj;
- }
-
- // Return true only if x > y
- private static boolean isBigger(Context cx, Scriptable scope,
- Object x, Object y,
- Object cmp, Object[] cmpBuf)
- {
- if (cmp == null) {
- if (cmpBuf != null) Kit.codeBug();
- } else {
- if (cmpBuf == null || cmpBuf.length != 2) Kit.codeBug();
- }
-
- Object undef = Undefined.instance;
- Object notfound = Scriptable.NOT_FOUND;
-
- // sort undefined to end
- if (y == undef || y == notfound) {
- return false; // x can not be bigger then undef
- } else if (x == undef || x == notfound) {
- return true; // y != undef here, so x > y
- }
-
- if (cmp == null) {
- // if no cmp function supplied, sort lexicographically
- String a = ScriptRuntime.toString(x);
- String b = ScriptRuntime.toString(y);
- return a.compareTo(b) > 0;
- }
- else {
- // assemble args and call supplied JS cmp function
- cmpBuf[0] = x;
- cmpBuf[1] = y;
- Callable fun = ScriptRuntime.getValueFunctionAndThis(cmp, cx);
- Scriptable funThis = ScriptRuntime.lastStoredScriptable(cx);
-
- Object ret = fun.call(cx, scope, funThis, cmpBuf);
- double d = ScriptRuntime.toNumber(ret);
-
- // XXX what to do when cmp function returns NaN? ECMA states
- // that it's then not a 'consistent comparison function'... but
- // then what do we do? Back out and start over with the generic
- // cmp function when we see a NaN? Throw an error?
-
- // for now, just ignore it:
-
- return d > 0;
- }
- }
-
-/** Heapsort implementation.
- * See "Introduction to Algorithms" by Cormen, Leiserson, Rivest for details.
- * Adjusted for zero based indexes.
- */
- private static void heapsort(Context cx, Scriptable scope,
- Object[] array, int length,
- Object cmp, Object[] cmpBuf)
- {
- if (length <= 1) Kit.codeBug();
-
- // Build heap
- for (int i = length / 2; i != 0;) {
- --i;
- Object pivot = array[i];
- heapify(cx, scope, pivot, array, i, length, cmp, cmpBuf);
- }
-
- // Sort heap
- for (int i = length; i != 1;) {
- --i;
- Object pivot = array[i];
- array[i] = array[0];
- heapify(cx, scope, pivot, array, 0, i, cmp, cmpBuf);
- }
- }
-
-/** pivot and child heaps of i should be made into heap starting at i,
- * original array[i] is never used to have less array access during sorting.
- */
- private static void heapify(Context cx, Scriptable scope,
- Object pivot, Object[] array, int i, int end,
- Object cmp, Object[] cmpBuf)
- {
- for (;;) {
- int child = i * 2 + 1;
- if (child >= end) {
- break;
- }
- Object childVal = array[child];
- if (child + 1 < end) {
- Object nextVal = array[child + 1];
- if (isBigger(cx, scope, nextVal, childVal, cmp, cmpBuf)) {
- ++child; childVal = nextVal;
- }
- }
- if (!isBigger(cx, scope, childVal, pivot, cmp, cmpBuf)) {
- break;
- }
- array[i] = childVal;
- i = child;
- }
- array[i] = pivot;
- }
-
-/** Version of heapsort that call getElem/setElem on target to query/assign
- * array elements instead of Java array access
- */
- private static void heapsort_extended(Context cx, Scriptable scope,
- Scriptable target, long length,
- Object cmp, Object[] cmpBuf)
- {
- if (length <= 1) Kit.codeBug();
-
- // Build heap
- for (long i = length / 2; i != 0;) {
- --i;
- Object pivot = getElem(cx, target, i);
- heapify_extended(cx, scope, pivot, target, i, length, cmp, cmpBuf);
- }
-
- // Sort heap
- for (long i = length; i != 1;) {
- --i;
- Object pivot = getElem(cx, target, i);
- setElem(cx, target, i, getElem(cx, target, 0));
- heapify_extended(cx, scope, pivot, target, 0, i, cmp, cmpBuf);
- }
- }
-
- private static void heapify_extended(Context cx, Scriptable scope,
- Object pivot, Scriptable target,
- long i, long end,
- Object cmp, Object[] cmpBuf)
- {
- for (;;) {
- long child = i * 2 + 1;
- if (child >= end) {
- break;
- }
- Object childVal = getElem(cx, target, child);
- if (child + 1 < end) {
- Object nextVal = getElem(cx, target, child + 1);
- if (isBigger(cx, scope, nextVal, childVal, cmp, cmpBuf)) {
- ++child; childVal = nextVal;
- }
- }
- if (!isBigger(cx, scope, childVal, pivot, cmp, cmpBuf)) {
- break;
- }
- setElem(cx, target, i, childVal);
- i = child;
- }
- setElem(cx, target, i, pivot);
- }
-
- /**
- * Non-ECMA methods.
- */
-
- private static Object js_push(Context cx, Scriptable thisObj,
- Object[] args)
- {
- if (thisObj instanceof NativeArray) {
- NativeArray na = (NativeArray) thisObj;
- if (na.denseOnly &&
- na.ensureCapacity((int) na.length + args.length))
- {
- for (int i = 0; i < args.length; i++) {
- na.dense[(int)na.length++] = args[i];
- }
- return ScriptRuntime.wrapNumber(na.length);
- }
- }
- long length = getLengthProperty(cx, thisObj);
- for (int i = 0; i < args.length; i++) {
- setElem(cx, thisObj, length + i, args[i]);
- }
-
- length += args.length;
- Object lengthObj = setLengthProperty(cx, thisObj, length);
-
- /*
- * If JS1.2, follow Perl4 by returning the last thing pushed.
- * Otherwise, return the new array length.
- */
- if (cx.getLanguageVersion() == Context.VERSION_1_2)
- // if JS1.2 && no arguments, return undefined.
- return args.length == 0
- ? Undefined.instance
- : args[args.length - 1];
-
- else
- return lengthObj;
- }
-
- private static Object js_pop(Context cx, Scriptable thisObj,
- Object[] args)
- {
- Object result;
- if (thisObj instanceof NativeArray) {
- NativeArray na = (NativeArray) thisObj;
- if (na.denseOnly && na.length > 0) {
- na.length--;
- result = na.dense[(int)na.length];
- na.dense[(int)na.length] = NOT_FOUND;
- return result;
- }
- }
- long length = getLengthProperty(cx, thisObj);
- if (length > 0) {
- length--;
-
- // Get the to-be-deleted property's value.
- result = getElem(cx, thisObj, length);
-
- // We don't need to delete the last property, because
- // setLength does that for us.
- } else {
- result = Undefined.instance;
- }
- // necessary to match js even when length < 0; js pop will give a
- // length property to any target it is called on.
- setLengthProperty(cx, thisObj, length);
-
- return result;
- }
-
- private static Object js_shift(Context cx, Scriptable thisObj,
- Object[] args)
- {
- if (thisObj instanceof NativeArray) {
- NativeArray na = (NativeArray) thisObj;
- if (na.denseOnly && na.length > 0) {
- na.length--;
- Object result = na.dense[0];
- System.arraycopy(na.dense, 1, na.dense, 0, (int)na.length);
- na.dense[(int)na.length] = NOT_FOUND;
- return result;
- }
- }
- Object result;
- long length = getLengthProperty(cx, thisObj);
- if (length > 0) {
- long i = 0;
- length--;
-
- // Get the to-be-deleted property's value.
- result = getElem(cx, thisObj, i);
-
- /*
- * Slide down the array above the first element. Leave i
- * set to point to the last element.
- */
- if (length > 0) {
- for (i = 1; i <= length; i++) {
- Object temp = getElem(cx, thisObj, i);
- setElem(cx, thisObj, i - 1, temp);
- }
- }
- // We don't need to delete the last property, because
- // setLength does that for us.
- } else {
- result = Undefined.instance;
- }
- setLengthProperty(cx, thisObj, length);
- return result;
- }
-
- private static Object js_unshift(Context cx, Scriptable thisObj,
- Object[] args)
- {
- if (thisObj instanceof NativeArray) {
- NativeArray na = (NativeArray) thisObj;
- if (na.denseOnly &&
- na.ensureCapacity((int)na.length + args.length))
- {
- System.arraycopy(na.dense, 0, na.dense, args.length,
- (int) na.length);
- for (int i = 0; i < args.length; i++) {
- na.dense[i] = args[i];
- }
- na.length += args.length;
- return ScriptRuntime.wrapNumber(na.length);
- }
- }
- long length = getLengthProperty(cx, thisObj);
- int argc = args.length;
-
- if (args.length > 0) {
- /* Slide up the array to make room for args at the bottom */
- if (length > 0) {
- for (long last = length - 1; last >= 0; last--) {
- Object temp = getElem(cx, thisObj, last);
- setElem(cx, thisObj, last + argc, temp);
- }
- }
-
- /* Copy from argv to the bottom of the array. */
- for (int i = 0; i < args.length; i++) {
- setElem(cx, thisObj, i, args[i]);
- }
-
- /* Follow Perl by returning the new array length. */
- length += args.length;
- return setLengthProperty(cx, thisObj, length);
- }
- return ScriptRuntime.wrapNumber(length);
- }
-
- private static Object js_splice(Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- NativeArray na = null;
- boolean denseMode = false;
- if (thisObj instanceof NativeArray) {
- na = (NativeArray) thisObj;
- denseMode = na.denseOnly;
- }
-
- /* create an empty Array to return. */
- scope = getTopLevelScope(scope);
- int argc = args.length;
- if (argc == 0)
- return ScriptRuntime.newObject(cx, scope, "Array", null);
- long length = getLengthProperty(cx, thisObj);
-
- /* Convert the first argument into a starting index. */
- long begin = toSliceIndex(ScriptRuntime.toInteger(args[0]), length);
- argc--;
-
- /* Convert the second argument into count */
- long count;
- if (args.length == 1) {
- count = length - begin;
- } else {
- double dcount = ScriptRuntime.toInteger(args[1]);
- if (dcount < 0) {
- count = 0;
- } else if (dcount > (length - begin)) {
- count = length - begin;
- } else {
- count = (long)dcount;
- }
- argc--;
- }
-
- long end = begin + count;
-
- /* If there are elements to remove, put them into the return value. */
- Object result;
- if (count != 0) {
- if (count == 1
- && (cx.getLanguageVersion() == Context.VERSION_1_2))
- {
- /*
- * JS lacks "list context", whereby in Perl one turns the
- * single scalar that's spliced out into an array just by
- * assigning it to @single instead of $single, or by using it
- * as Perl push's first argument, for instance.
- *
- * JS1.2 emulated Perl too closely and returned a non-Array for
- * the single-splice-out case, requiring callers to test and
- * wrap in [] if necessary. So JS1.3, default, and other
- * versions all return an array of length 1 for uniformity.
- */
- result = getElem(cx, thisObj, begin);
- } else {
- if (denseMode) {
- int intLen = (int) (end - begin);
- Object[] copy = new Object[intLen];
- System.arraycopy(na.dense, (int) begin, copy, 0, intLen);
- result = cx.newArray(scope, copy);
- } else {
- Scriptable resultArray = ScriptRuntime.newObject(cx, scope,
- "Array", null);
- for (long last = begin; last != end; last++) {
- Object temp = getElem(cx, thisObj, last);
- setElem(cx, resultArray, last - begin, temp);
- }
- result = resultArray;
- }
- }
- } else { // (count == 0)
- if (cx.getLanguageVersion() == Context.VERSION_1_2) {
- /* Emulate C JS1.2; if no elements are removed, return undefined. */
- result = Undefined.instance;
- } else {
- result = ScriptRuntime.newObject(cx, scope, "Array", null);
- }
- }
-
- /* Find the direction (up or down) to copy and make way for argv. */
- long delta = argc - count;
- if (denseMode && length + delta < Integer.MAX_VALUE &&
- na.ensureCapacity((int) (length + delta)))
- {
- System.arraycopy(na.dense, (int) end, na.dense,
- (int) (begin + argc), (int) (length - end));
- if (argc > 0) {
- System.arraycopy(args, 2, na.dense, (int) begin, argc);
- }
- if (delta < 0) {
- Arrays.fill(na.dense, (int) (length + delta), (int) length,
- NOT_FOUND);
- }
- na.length = length + delta;
- return result;
- }
-
- if (delta > 0) {
- for (long last = length - 1; last >= end; last--) {
- Object temp = getElem(cx, thisObj, last);
- setElem(cx, thisObj, last + delta, temp);
- }
- } else if (delta < 0) {
- for (long last = end; last < length; last++) {
- Object temp = getElem(cx, thisObj, last);
- setElem(cx, thisObj, last + delta, temp);
- }
- }
-
- /* Copy from argv into the hole to complete the splice. */
- int argoffset = args.length - argc;
- for (int i = 0; i < argc; i++) {
- setElem(cx, thisObj, begin + i, args[i + argoffset]);
- }
-
- /* Update length in case we deleted elements from the end. */
- setLengthProperty(cx, thisObj, length + delta);
- return result;
- }
-
- /*
- * See Ecma 262v3 15.4.4.4
- */
- private static Scriptable js_concat(Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- // create an empty Array to return.
- scope = getTopLevelScope(scope);
- Function ctor = ScriptRuntime.getExistingCtor(cx, scope, "Array");
- Scriptable result = ctor.construct(cx, scope, ScriptRuntime.emptyArgs);
- if (thisObj instanceof NativeArray && result instanceof NativeArray) {
- NativeArray denseThis = (NativeArray) thisObj;
- NativeArray denseResult = (NativeArray) result;
- if (denseThis.denseOnly && denseResult.denseOnly) {
- // First calculate length of resulting array
- boolean canUseDense = true;
- int length = (int) denseThis.length;
- for (int i = 0; i < args.length && canUseDense; i++) {
- if (ScriptRuntime.instanceOf(args[i], ctor, cx)) {
- // only try to use dense approach for Array-like
- // objects that are actually NativeArrays
- canUseDense = args[i] instanceof NativeArray;
- length += ((NativeArray) args[i]).length;
- } else {
- length++;
- }
- }
- if (canUseDense && denseResult.ensureCapacity(length)) {
- System.arraycopy(denseThis.dense, 0, denseResult.dense,
- 0, (int) denseThis.length);
- int cursor = (int) denseThis.length;
- for (int i = 0; i < args.length && canUseDense; i++) {
- if (args[i] instanceof NativeArray) {
- NativeArray arg = (NativeArray) args[i];
- System.arraycopy(arg.dense, 0,
- denseResult.dense, cursor,
- (int)arg.length);
- cursor += (int)arg.length;
- } else {
- denseResult.dense[cursor++] = args[i];
- }
- }
- denseResult.length = length;
- return result;
- }
- }
- }
-
- long length;
- long slot = 0;
-
- /* Put the target in the result array; only add it as an array
- * if it looks like one.
- */
- if (ScriptRuntime.instanceOf(thisObj, ctor, cx)) {
- length = getLengthProperty(cx, thisObj);
-
- // Copy from the target object into the result
- for (slot = 0; slot < length; slot++) {
- Object temp = getElem(cx, thisObj, slot);
- setElem(cx, result, slot, temp);
- }
- } else {
- setElem(cx, result, slot++, thisObj);
- }
-
- /* Copy from the arguments into the result. If any argument
- * has a numeric length property, treat it as an array and add
- * elements separately; otherwise, just copy the argument.
- */
- for (int i = 0; i < args.length; i++) {
- if (ScriptRuntime.instanceOf(args[i], ctor, cx)) {
- // ScriptRuntime.instanceOf => instanceof Scriptable
- Scriptable arg = (Scriptable)args[i];
- length = getLengthProperty(cx, arg);
- for (long j = 0; j < length; j++, slot++) {
- Object temp = getElem(cx, arg, j);
- setElem(cx, result, slot, temp);
- }
- } else {
- setElem(cx, result, slot++, args[i]);
- }
- }
- return result;
- }
-
- private Scriptable js_slice(Context cx, Scriptable thisObj,
- Object[] args)
- {
- Scriptable scope = getTopLevelScope(this);
- Scriptable result = ScriptRuntime.newObject(cx, scope, "Array", null);
- long length = getLengthProperty(cx, thisObj);
-
- long begin, end;
- if (args.length == 0) {
- begin = 0;
- end = length;
- } else {
- begin = toSliceIndex(ScriptRuntime.toInteger(args[0]), length);
- if (args.length == 1) {
- end = length;
- } else {
- end = toSliceIndex(ScriptRuntime.toInteger(args[1]), length);
- }
- }
-
- for (long slot = begin; slot < end; slot++) {
- Object temp = getElem(cx, thisObj, slot);
- setElem(cx, result, slot - begin, temp);
- }
-
- return result;
- }
-
- private static long toSliceIndex(double value, long length) {
- long result;
- if (value < 0.0) {
- if (value + length < 0.0) {
- result = 0;
- } else {
- result = (long)(value + length);
- }
- } else if (value > length) {
- result = length;
- } else {
- result = (long)value;
- }
- return result;
- }
-
- /**
- * Implements the methods "indexOf" and "lastIndexOf".
- */
- private Object indexOfHelper(Context cx, Scriptable thisObj,
- Object[] args, boolean isLast)
- {
- Object compareTo = args.length > 0 ? args[0] : Undefined.instance;
- long length = getLengthProperty(cx, thisObj);
- long start;
- if (isLast) {
- // lastIndexOf
- /*
- * From http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:lastIndexOf
- * The index at which to start searching backwards. Defaults to the
- * array's length, i.e. the whole array will be searched. If the
- * index is greater than or equal to the length of the array, the
- * whole array will be searched. If negative, it is taken as the
- * offset from the end of the array. Note that even when the index
- * is negative, the array is still searched from back to front. If
- * the calculated index is less than 0, -1 is returned, i.e. the
- * array will not be searched.
- */
- if (args.length < 2) {
- // default
- start = length-1;
- } else {
- start = ScriptRuntime.toInt32(ScriptRuntime.toNumber(args[1]));
- if (start >= length)
- start = length-1;
- else if (start < 0)
- start += length;
- // Note that start may be negative, but that's okay
- // as the result of -1 will fall out from the code below
- }
- } else {
- // indexOf
- /*
- * From http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:indexOf
- * The index at which to begin the search. Defaults to 0, i.e. the
- * whole array will be searched. If the index is greater than or
- * equal to the length of the array, -1 is returned, i.e. the array
- * will not be searched. If negative, it is taken as the offset from
- * the end of the array. Note that even when the index is negative,
- * the array is still searched from front to back. If the calculated
- * index is less than 0, the whole array will be searched.
- */
- if (args.length < 2) {
- // default
- start = 0;
- } else {
- start = ScriptRuntime.toInt32(ScriptRuntime.toNumber(args[1]));
- if (start < 0) {
- start += length;
- if (start < 0)
- start = 0;
- }
- // Note that start may be > length-1, but that's okay
- // as the result of -1 will fall out from the code below
- }
- }
- if (thisObj instanceof NativeArray) {
- NativeArray na = (NativeArray) thisObj;
- if (na.denseOnly) {
- if (isLast) {
- for (int i=(int)start; i >= 0; i--) {
- if (na.dense[i] != Scriptable.NOT_FOUND &&
- ScriptRuntime.shallowEq(na.dense[i], compareTo))
- {
- return new Long(i);
- }
- }
- } else {
- for (int i=(int)start; i < length; i++) {
- if (na.dense[i] != Scriptable.NOT_FOUND &&
- ScriptRuntime.shallowEq(na.dense[i], compareTo))
- {
- return new Long(i);
- }
- }
- }
- return NEGATIVE_ONE;
- }
- }
- if (isLast) {
- for (long i=start; i >= 0; i--) {
- if (ScriptRuntime.shallowEq(getElem(cx, thisObj, i), compareTo)) {
- return new Long(i);
- }
- }
- } else {
- for (long i=start; i < length; i++) {
- if (ScriptRuntime.shallowEq(getElem(cx, thisObj, i), compareTo)) {
- return new Long(i);
- }
- }
- }
- return NEGATIVE_ONE;
- }
-
- /**
- * Implements the methods "every", "filter", "forEach", "map", and "some".
- */
- private Object iterativeMethod(Context cx, int id, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- Object callbackArg = args.length > 0 ? args[0] : Undefined.instance;
- if (callbackArg == null || !(callbackArg instanceof Function)) {
- throw ScriptRuntime.notFunctionError(
- ScriptRuntime.toString(callbackArg));
- }
- Function f = (Function) callbackArg;
- Scriptable parent = ScriptableObject.getTopLevelScope(f);
- Scriptable thisArg;
- if (args.length < 2 || args[1] == null || args[1] == Undefined.instance)
- {
- thisArg = parent;
- } else {
- thisArg = ScriptRuntime.toObject(cx, scope, args[1]);
- }
- long length = getLengthProperty(cx, thisObj);
- Scriptable array = ScriptRuntime.newObject(cx, scope, "Array", null);
- long j=0;
- for (long i=0; i < length; i++) {
- Object[] innerArgs = new Object[3];
- Object elem = (i > Integer.MAX_VALUE)
- ? ScriptableObject.getProperty(thisObj, Long.toString(i))
- : ScriptableObject.getProperty(thisObj, (int)i);
- if (elem == Scriptable.NOT_FOUND) {
- continue;
- }
- innerArgs[0] = elem;
- innerArgs[1] = new Long(i);
- innerArgs[2] = thisObj;
- Object result = f.call(cx, parent, thisArg, innerArgs);
- switch (id) {
- case Id_every:
- if (!ScriptRuntime.toBoolean(result))
- return Boolean.FALSE;
- break;
- case Id_filter:
- if (ScriptRuntime.toBoolean(result))
- setElem(cx, array, j++, innerArgs[0]);
- break;
- case Id_forEach:
- break;
- case Id_map:
- setElem(cx, array, i, result);
- break;
- case Id_some:
- if (ScriptRuntime.toBoolean(result))
- return Boolean.TRUE;
- break;
- }
- }
- switch (id) {
- case Id_every:
- return Boolean.TRUE;
- case Id_filter:
- case Id_map:
- return array;
- case Id_some:
- return Boolean.FALSE;
- case Id_forEach:
- default:
- return Undefined.instance;
- }
- }
-
-// #string_id_map#
-
- protected int findPrototypeId(String s)
- {
- int id;
-// #generated# Last update: 2005-09-26 15:47:42 EDT
- L0: { id = 0; String X = null; int c;
- L: switch (s.length()) {
- case 3: c=s.charAt(0);
- if (c=='m') { if (s.charAt(2)=='p' && s.charAt(1)=='a') {id=Id_map; break L0;} }
- else if (c=='p') { if (s.charAt(2)=='p' && s.charAt(1)=='o') {id=Id_pop; break L0;} }
- break L;
- case 4: switch (s.charAt(2)) {
- case 'i': X="join";id=Id_join; break L;
- case 'm': X="some";id=Id_some; break L;
- case 'r': X="sort";id=Id_sort; break L;
- case 's': X="push";id=Id_push; break L;
- } break L;
- case 5: c=s.charAt(1);
- if (c=='h') { X="shift";id=Id_shift; }
- else if (c=='l') { X="slice";id=Id_slice; }
- else if (c=='v') { X="every";id=Id_every; }
- break L;
- case 6: c=s.charAt(0);
- if (c=='c') { X="concat";id=Id_concat; }
- else if (c=='f') { X="filter";id=Id_filter; }
- else if (c=='s') { X="splice";id=Id_splice; }
- break L;
- case 7: switch (s.charAt(0)) {
- case 'f': X="forEach";id=Id_forEach; break L;
- case 'i': X="indexOf";id=Id_indexOf; break L;
- case 'r': X="reverse";id=Id_reverse; break L;
- case 'u': X="unshift";id=Id_unshift; break L;
- } break L;
- case 8: c=s.charAt(3);
- if (c=='o') { X="toSource";id=Id_toSource; }
- else if (c=='t') { X="toString";id=Id_toString; }
- break L;
- case 11: c=s.charAt(0);
- if (c=='c') { X="constructor";id=Id_constructor; }
- else if (c=='l') { X="lastIndexOf";id=Id_lastIndexOf; }
- break L;
- case 14: X="toLocaleString";id=Id_toLocaleString; break L;
- }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- 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,
- Id_indexOf = 15,
- Id_lastIndexOf = 16,
- Id_every = 17,
- Id_filter = 18,
- Id_forEach = 19,
- Id_map = 20,
- Id_some = 21,
-
- MAX_PROTOTYPE_ID = 21;
-
-// #/string_id_map#
-
- private static final int
- ConstructorId_join = -Id_join,
- ConstructorId_reverse = -Id_reverse,
- ConstructorId_sort = -Id_sort,
- ConstructorId_push = -Id_push,
- ConstructorId_pop = -Id_pop,
- ConstructorId_shift = -Id_shift,
- ConstructorId_unshift = -Id_unshift,
- ConstructorId_splice = -Id_splice,
- ConstructorId_concat = -Id_concat,
- ConstructorId_slice = -Id_slice,
- ConstructorId_indexOf = -Id_indexOf,
- ConstructorId_lastIndexOf = -Id_lastIndexOf,
- ConstructorId_every = -Id_every,
- ConstructorId_filter = -Id_filter,
- ConstructorId_forEach = -Id_forEach,
- ConstructorId_map = -Id_map,
- ConstructorId_some = -Id_some;
-
- /**
- * Internal representation of the JavaScript array's length property.
- */
- private long length;
-
- /**
- * Fast storage for dense arrays. Sparse arrays will use the superclass's
- * hashtable storage scheme.
- */
- private Object[] dense;
-
- /**
- * True if all numeric properties are stored in <code>dense</code>.
- */
- private boolean denseOnly;
-
- /**
- * The maximum size of <code>dense</code> that will be allocated initially.
- */
- private static int maximumInitialCapacity = 10000;
-
- /**
- * The default capacity for <code>dense</code>.
- */
- private static final int DEFAULT_INITIAL_CAPACITY = 10;
-
- /**
- * The factor to grow <code>dense</code> by.
- */
- private static final double GROW_FACTOR = 1.5;
- private static final int MAX_PRE_GROW_SIZE = (int)(Integer.MAX_VALUE / GROW_FACTOR);
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeBoolean.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeBoolean.java
deleted file mode 100644
index b6a106a..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeBoolean.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/* -*- 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
- * Mike McCabe
- *
- * 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 Boolean native object.
- * See ECMA 15.6.
- * @author Norris Boyd
- */
-final class NativeBoolean extends IdScriptableObject
-{
- static final long serialVersionUID = -3716996899943880933L;
-
- private static final Object BOOLEAN_TAG = new Object();
-
- static void init(Scriptable scope, boolean sealed)
- {
- NativeBoolean obj = new NativeBoolean(false);
- obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
- }
-
- private NativeBoolean(boolean b)
- {
- booleanValue = b;
- }
-
- public String getClassName()
- {
- return "Boolean";
- }
-
- public Object getDefaultValue(Class typeHint) {
- // This is actually non-ECMA, but will be proposed
- // as a change in round 2.
- if (typeHint == ScriptRuntime.BooleanClass)
- return ScriptRuntime.wrapBoolean(booleanValue);
- 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 execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(BOOLEAN_TAG)) {
- return super.execIdCall(f, cx, scope, thisObj, args);
- }
- int id = f.methodId();
-
- if (id == Id_constructor) {
- boolean b;
- if (args.length == 0) {
- b = false;
- } else {
- b = args[0] instanceof ScriptableObject &&
- ((ScriptableObject) args[0]).avoidObjectDetection()
- ? true
- : 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 ScriptRuntime.wrapBoolean(b);
- }
-
- // The rest of Boolean.prototype methods require thisObj to be Boolean
-
- if (!(thisObj instanceof NativeBoolean))
- throw incompatibleCallError(f);
- boolean value = ((NativeBoolean)thisObj).booleanValue;
-
- switch (id) {
-
- case Id_toString:
- return value ? "true" : "false";
-
- case Id_toSource:
- return value ? "(new Boolean(true))" : "(new Boolean(false))";
-
- case Id_valueOf:
- return ScriptRuntime.wrapBoolean(value);
- }
- throw new IllegalArgumentException(String.valueOf(id));
- }
-
-// #string_id_map#
-
- protected int findPrototypeId(String s)
- {
- int id;
-// #generated# Last update: 2007-05-09 08:15:31 EDT
- L0: { id = 0; String X = null; int c;
- int s_length = s.length();
- if (s_length==7) { X="valueOf";id=Id_valueOf; }
- else if (s_length==8) {
- c=s.charAt(3);
- if (c=='o') { X="toSource";id=Id_toSource; }
- else if (c=='t') { X="toString";id=Id_toString; }
- }
- else if (s_length==11) { X="constructor";id=Id_constructor; }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- Id_constructor = 1,
- Id_toString = 2,
- Id_toSource = 3,
- Id_valueOf = 4,
- MAX_PROTOTYPE_ID = 4;
-
-// #/string_id_map#
-
- private boolean booleanValue;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeCall.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeCall.java
deleted file mode 100644
index b196ac3..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeCall.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/* -*- 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
- * Bob Jervis
- *
- * 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 activation object.
- *
- * See ECMA 10.1.6
- *
- * @see org.mozilla.javascript.Arguments
- * @author Norris Boyd
- */
-public final class NativeCall extends IdScriptableObject
-{
- static final long serialVersionUID = -7471457301304454454L;
-
- private static final Object CALL_TAG = new Object();
-
- static void init(Scriptable scope, boolean sealed)
- {
- NativeCall obj = new NativeCall();
- obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
- }
-
- NativeCall() { }
-
- NativeCall(NativeFunction function, Scriptable scope, Object[] args)
- {
- this.function = function;
-
- setParentScope(scope);
- // leave prototype null
-
- this.originalArgs = (args == null) ? ScriptRuntime.emptyArgs : args;
-
- // initialize values of arguments
- int paramAndVarCount = function.getParamAndVarCount();
- int paramCount = function.getParamCount();
- if (paramAndVarCount != 0) {
- for (int i = 0; i < paramCount; ++i) {
- String name = function.getParamOrVarName(i);
- Object val = i < args.length ? args[i]
- : Undefined.instance;
- defineProperty(name, val, PERMANENT);
- }
- }
-
- // initialize "arguments" property but only if it was not overridden by
- // the parameter with the same name
- if (!super.has("arguments", this)) {
- defineProperty("arguments", new Arguments(this), PERMANENT);
- }
-
- if (paramAndVarCount != 0) {
- for (int i = paramCount; i < paramAndVarCount; ++i) {
- String name = function.getParamOrVarName(i);
- if (!super.has(name, this)) {
- if (function.getParamOrVarConst(i))
- defineProperty(name, Undefined.instance, CONST);
- else
- defineProperty(name, Undefined.instance, PERMANENT);
- }
- }
- }
- }
-
- public String getClassName()
- {
- return "Call";
- }
-
- protected int findPrototypeId(String s)
- {
- return s.equals("constructor") ? Id_constructor : 0;
- }
-
- protected void initPrototypeId(int id)
- {
- 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 execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(CALL_TAG)) {
- return super.execIdCall(f, cx, scope, thisObj, args);
- }
- int id = f.methodId();
- if (id == Id_constructor) {
- if (thisObj != null) {
- throw Context.reportRuntimeError1("msg.only.from.new", "Call");
- }
- ScriptRuntime.checkDeprecated(cx, "Call");
- NativeCall result = new NativeCall();
- result.setPrototype(getObjectPrototype(scope));
- return result;
- }
- throw new IllegalArgumentException(String.valueOf(id));
- }
-
- private static final int
- Id_constructor = 1,
- MAX_PROTOTYPE_ID = 1;
-
- NativeFunction function;
- Object[] originalArgs;
-
- transient NativeCall parentActivationCall;
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeDate.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeDate.java
deleted file mode 100644
index 75d41ab..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeDate.java
+++ /dev/null
@@ -1,1604 +0,0 @@
-/* -*- 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):
- * Peter Annema
- * Norris Boyd
- * Mike McCabe
- * Ilya Frank
- *
- *
- * 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;
-
-import java.util.Date;
-import java.text.DateFormat;
-
-/**
- * This class implements the Date native object.
- * See ECMA 15.9.
- * @author Mike McCabe
- */
-final class NativeDate extends IdScriptableObject
-{
- static final long serialVersionUID = -8307438915861678966L;
-
- private static final Object DATE_TAG = new Object();
-
- private static final String js_NaN_date_str = "Invalid Date";
-
- static void init(Scriptable scope, boolean sealed)
- {
- NativeDate obj = new NativeDate();
- // Set the value of the prototype Date to NaN ('invalid date');
- obj.date = ScriptRuntime.NaN;
- obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
- }
-
- private NativeDate()
- {
- if (thisTimeZone == null) {
- // j.u.TimeZone is synchronized, so setting class statics from it
- // should be OK.
- thisTimeZone = java.util.TimeZone.getDefault();
- LocalTZA = thisTimeZone.getRawOffset();
- }
- }
-
- public String getClassName()
- {
- return "Date";
- }
-
- public Object getDefaultValue(Class typeHint)
- {
- if (typeHint == null)
- typeHint = ScriptRuntime.StringClass;
- return super.getDefaultValue(typeHint);
- }
-
- double getJSTimeValue()
- {
- return date;
- }
-
- protected void fillConstructorProperties(IdFunctionObject ctor)
- {
- 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 execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(DATE_TAG)) {
- return super.execIdCall(f, cx, scope, thisObj, args);
- }
- int id = f.methodId();
- switch (id) {
- case ConstructorId_now:
- return ScriptRuntime.wrapNumber(now());
-
- case ConstructorId_parse:
- {
- String dataStr = ScriptRuntime.toString(args, 0);
- return ScriptRuntime.wrapNumber(date_parseString(dataStr));
- }
-
- case ConstructorId_UTC:
- return ScriptRuntime.wrapNumber(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);
- }
- }
-
- // The rest of Date.prototype methods require thisObj to be Date
-
- if (!(thisObj instanceof NativeDate))
- throw incompatibleCallError(f);
- NativeDate realThis = (NativeDate)thisObj;
- double t = realThis.date;
-
- switch (id) {
-
- case Id_toString:
- case Id_toTimeString:
- case Id_toDateString:
- if (t == t) {
- return date_format(t, id);
- }
- return js_NaN_date_str;
-
- case Id_toLocaleString:
- case Id_toLocaleTimeString:
- case Id_toLocaleDateString:
- if (t == t) {
- return toLocale_helper(t, id);
- }
- return js_NaN_date_str;
-
- case Id_toUTCString:
- if (t == t) {
- return js_toUTCString(t);
- }
- return js_NaN_date_str;
-
- case Id_toSource:
- return "(new Date("+ScriptRuntime.toString(t)+"))";
-
- case Id_valueOf:
- case Id_getTime:
- return ScriptRuntime.wrapNumber(t);
-
- case Id_getYear:
- case Id_getFullYear:
- case Id_getUTCFullYear:
- 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 ScriptRuntime.wrapNumber(t);
-
- case Id_getMonth:
- case Id_getUTCMonth:
- if (t == t) {
- if (id == Id_getMonth) t = LocalTime(t);
- t = MonthFromTime(t);
- }
- return ScriptRuntime.wrapNumber(t);
-
- case Id_getDate:
- case Id_getUTCDate:
- if (t == t) {
- if (id == Id_getDate) t = LocalTime(t);
- t = DateFromTime(t);
- }
- return ScriptRuntime.wrapNumber(t);
-
- case Id_getDay:
- case Id_getUTCDay:
- if (t == t) {
- if (id == Id_getDay) t = LocalTime(t);
- t = WeekDay(t);
- }
- return ScriptRuntime.wrapNumber(t);
-
- case Id_getHours:
- case Id_getUTCHours:
- if (t == t) {
- if (id == Id_getHours) t = LocalTime(t);
- t = HourFromTime(t);
- }
- return ScriptRuntime.wrapNumber(t);
-
- case Id_getMinutes:
- case Id_getUTCMinutes:
- if (t == t) {
- if (id == Id_getMinutes) t = LocalTime(t);
- t = MinFromTime(t);
- }
- return ScriptRuntime.wrapNumber(t);
-
- case Id_getSeconds:
- case Id_getUTCSeconds:
- if (t == t) {
- if (id == Id_getSeconds) t = LocalTime(t);
- t = SecFromTime(t);
- }
- return ScriptRuntime.wrapNumber(t);
-
- case Id_getMilliseconds:
- case Id_getUTCMilliseconds:
- if (t == t) {
- if (id == Id_getMilliseconds) t = LocalTime(t);
- t = msFromTime(t);
- }
- return ScriptRuntime.wrapNumber(t);
-
- case Id_getTimezoneOffset:
- if (t == t) {
- t = (t - LocalTime(t)) / msPerMinute;
- }
- return ScriptRuntime.wrapNumber(t);
-
- case Id_setTime:
- t = TimeClip(ScriptRuntime.toNumber(args, 0));
- realThis.date = t;
- return ScriptRuntime.wrapNumber(t);
-
- case Id_setMilliseconds:
- case Id_setUTCMilliseconds:
- case Id_setSeconds:
- case Id_setUTCSeconds:
- case Id_setMinutes:
- case Id_setUTCMinutes:
- case Id_setHours:
- case Id_setUTCHours:
- t = makeTime(t, args, id);
- realThis.date = t;
- return ScriptRuntime.wrapNumber(t);
-
- case Id_setDate:
- case Id_setUTCDate:
- case Id_setMonth:
- case Id_setUTCMonth:
- case Id_setFullYear:
- case Id_setUTCFullYear:
- t = makeDate(t, args, id);
- realThis.date = t;
- return ScriptRuntime.wrapNumber(t);
-
- case Id_setYear:
- {
- double year = ScriptRuntime.toNumber(args, 0);
-
- if (year != year || Double.isInfinite(year)) {
- t = ScriptRuntime.NaN;
- } else {
- if (t != t) {
- t = 0;
- } else {
- t = LocalTime(t);
- }
-
- if (year >= 0 && year <= 99)
- year += 1900;
-
- double day = MakeDay(year, MonthFromTime(t),
- DateFromTime(t));
- t = MakeDate(day, TimeWithinDay(t));
- t = internalUTC(t);
- t = TimeClip(t);
- }
- }
- realThis.date = t;
- return ScriptRuntime.wrapNumber(t);
-
- default: throw new IllegalArgumentException(String.valueOf(id));
- }
-
- }
-
- /* ECMA helper functions */
-
- private static final double HalfTimeDomain = 8.64e15;
- private static final double HoursPerDay = 24.0;
- private static final double MinutesPerHour = 60.0;
- private static final double SecondsPerMinute = 60.0;
- private static final double msPerSecond = 1000.0;
- private static final double MinutesPerDay = (HoursPerDay * MinutesPerHour);
- private static final double SecondsPerDay = (MinutesPerDay * SecondsPerMinute);
- private static final double SecondsPerHour = (MinutesPerHour * SecondsPerMinute);
- private static final double msPerDay = (SecondsPerDay * msPerSecond);
- private static final double msPerHour = (SecondsPerHour * msPerSecond);
- private static final double msPerMinute = (SecondsPerMinute * msPerSecond);
-
- private static double Day(double t)
- {
- return Math.floor(t / msPerDay);
- }
-
- private static double TimeWithinDay(double t)
- {
- double result;
- result = t % msPerDay;
- if (result < 0)
- result += msPerDay;
- return result;
- }
-
- private static boolean IsLeapYear(int year)
- {
- return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
- }
-
- /* math here has to be f.p, because we need
- * floor((1968 - 1969) / 4) == -1
- */
- private static double DayFromYear(double y)
- {
- return ((365 * ((y)-1970) + Math.floor(((y)-1969)/4.0)
- - Math.floor(((y)-1901)/100.0) + Math.floor(((y)-1601)/400.0)));
- }
-
- private static double TimeFromYear(double y)
- {
- return DayFromYear(y) * msPerDay;
- }
-
- private static int YearFromTime(double t)
- {
- int lo = (int) Math.floor((t / msPerDay) / 366) + 1970;
- int hi = (int) Math.floor((t / msPerDay) / 365) + 1970;
- int mid;
-
- /* above doesn't work for negative dates... */
- if (hi < lo) {
- int temp = lo;
- lo = hi;
- hi = temp;
- }
-
- /* Use a simple binary search algorithm to find the right
- year. This seems like brute force... but the computation
- of hi and lo years above lands within one year of the
- correct answer for years within a thousand years of
- 1970; the loop below only requires six iterations
- for year 270000. */
- while (hi > lo) {
- mid = (hi + lo) / 2;
- if (TimeFromYear(mid) > t) {
- hi = mid - 1;
- } else {
- lo = mid + 1;
- if (TimeFromYear(lo) > t) {
- return mid;
- }
- }
- }
- return lo;
- }
-
- private static double DayFromMonth(int m, int year)
- {
- int day = m * 30;
-
- if (m >= 7) { day += m / 2 - 1; }
- else if (m >= 2) { day += (m - 1) / 2 - 1; }
- else { day += m; }
-
- if (m >= 2 && IsLeapYear(year)) { ++day; }
-
- return day;
- }
-
- private static int MonthFromTime(double t)
- {
- int year = YearFromTime(t);
- int d = (int)(Day(t) - DayFromYear(year));
-
- d -= 31 + 28;
- if (d < 0) {
- return (d < -28) ? 0 : 1;
- }
-
- if (IsLeapYear(year)) {
- if (d == 0)
- return 1; // 29 February
- --d;
- }
-
- // d: date count from 1 March
- int estimate = d / 30; // approx number of month since March
- int mstart;
- switch (estimate) {
- case 0: return 2;
- case 1: mstart = 31; break;
- case 2: mstart = 31+30; break;
- case 3: mstart = 31+30+31; break;
- case 4: mstart = 31+30+31+30; break;
- case 5: mstart = 31+30+31+30+31; break;
- case 6: mstart = 31+30+31+30+31+31; break;
- case 7: mstart = 31+30+31+30+31+31+30; break;
- case 8: mstart = 31+30+31+30+31+31+30+31; break;
- case 9: mstart = 31+30+31+30+31+31+30+31+30; break;
- case 10: return 11; //Late december
- default: throw Kit.codeBug();
- }
- // if d < mstart then real month since March == estimate - 1
- return (d >= mstart) ? estimate + 2 : estimate + 1;
- }
-
- private static int DateFromTime(double t)
- {
- int year = YearFromTime(t);
- int d = (int)(Day(t) - DayFromYear(year));
-
- d -= 31 + 28;
- if (d < 0) {
- return (d < -28) ? d + 31 + 28 + 1 : d + 28 + 1;
- }
-
- if (IsLeapYear(year)) {
- if (d == 0)
- return 29; // 29 February
- --d;
- }
-
- // d: date count from 1 March
- int mdays, mstart;
- switch (d / 30) { // approx number of month since March
- case 0: return d + 1;
- case 1: mdays = 31; mstart = 31; break;
- case 2: mdays = 30; mstart = 31+30; break;
- case 3: mdays = 31; mstart = 31+30+31; break;
- case 4: mdays = 30; mstart = 31+30+31+30; break;
- case 5: mdays = 31; mstart = 31+30+31+30+31; break;
- case 6: mdays = 31; mstart = 31+30+31+30+31+31; break;
- case 7: mdays = 30; mstart = 31+30+31+30+31+31+30; break;
- case 8: mdays = 31; mstart = 31+30+31+30+31+31+30+31; break;
- case 9: mdays = 30; mstart = 31+30+31+30+31+31+30+31+30; break;
- case 10:
- return d - (31+30+31+30+31+31+30+31+30) + 1; //Late december
- default: throw Kit.codeBug();
- }
- d -= mstart;
- if (d < 0) {
- // wrong estimate: sfhift to previous month
- d += mdays;
- }
- return d + 1;
- }
-
- private static int WeekDay(double t)
- {
- double result;
- result = Day(t) + 4;
- result = result % 7;
- if (result < 0)
- result += 7;
- return (int) result;
- }
-
- private static double now()
- {
- return System.currentTimeMillis();
- }
-
- /* Should be possible to determine the need for this dynamically
- * if we go with the workaround... I'm not using it now, because I
- * can't think of any clean way to make toLocaleString() and the
- * time zone (comment) in toString match the generated string
- * values. Currently it's wrong-but-consistent in all but the
- * most recent betas of the JRE - seems to work in 1.1.7.
- */
- private final static boolean TZO_WORKAROUND = false;
- private static double DaylightSavingTA(double t)
- {
- // Another workaround! The JRE doesn't seem to know about DST
- // before year 1 AD, so we map to equivalent dates for the
- // purposes of finding dst. To be safe, we do this for years
- // outside 1970-2038.
- if (t < 0.0 || t > 2145916800000.0) {
- int year = EquivalentYear(YearFromTime(t));
- double day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
- t = MakeDate(day, TimeWithinDay(t));
- }
- if (!TZO_WORKAROUND) {
- Date date = new Date((long) t);
- if (thisTimeZone.inDaylightTime(date))
- return msPerHour;
- else
- return 0;
- } else {
- /* Use getOffset if inDaylightTime() is broken, because it
- * seems to work acceptably. We don't switch over to it
- * entirely, because it requires (expensive) exploded date arguments,
- * and the api makes it impossible to handle dst
- * changeovers cleanly.
- */
-
- // Hardcode the assumption that the changeover always
- // happens at 2:00 AM:
- t += LocalTZA + (HourFromTime(t) <= 2 ? msPerHour : 0);
-
- int year = YearFromTime(t);
- double offset = thisTimeZone.getOffset(year > 0 ? 1 : 0,
- year,
- MonthFromTime(t),
- DateFromTime(t),
- WeekDay(t),
- (int)TimeWithinDay(t));
-
- if ((offset - LocalTZA) != 0)
- return msPerHour;
- else
- return 0;
- // return offset - LocalTZA;
- }
- }
-
- /*
- * Find a year for which any given date will fall on the same weekday.
- *
- * This function should be used with caution when used other than
- * for determining DST; it hasn't been proven not to produce an
- * incorrect year for times near year boundaries.
- */
- private static int EquivalentYear(int year)
- {
- int day = (int) DayFromYear(year) + 4;
- day = day % 7;
- if (day < 0)
- day += 7;
- // Years and leap years on which Jan 1 is a Sunday, Monday, etc.
- if (IsLeapYear(year)) {
- switch (day) {
- case 0: return 1984;
- case 1: return 1996;
- case 2: return 1980;
- case 3: return 1992;
- case 4: return 1976;
- case 5: return 1988;
- case 6: return 1972;
- }
- } else {
- switch (day) {
- case 0: return 1978;
- case 1: return 1973;
- case 2: return 1974;
- case 3: return 1975;
- case 4: return 1981;
- case 5: return 1971;
- case 6: return 1977;
- }
- }
- // Unreachable
- throw Kit.codeBug();
- }
-
- private static double LocalTime(double t)
- {
- return t + LocalTZA + DaylightSavingTA(t);
- }
-
- private static double internalUTC(double t)
- {
- return t - LocalTZA - DaylightSavingTA(t - LocalTZA);
- }
-
- private static int HourFromTime(double t)
- {
- double result;
- result = Math.floor(t / msPerHour) % HoursPerDay;
- if (result < 0)
- result += HoursPerDay;
- return (int) result;
- }
-
- private static int MinFromTime(double t)
- {
- double result;
- result = Math.floor(t / msPerMinute) % MinutesPerHour;
- if (result < 0)
- result += MinutesPerHour;
- return (int) result;
- }
-
- private static int SecFromTime(double t)
- {
- double result;
- result = Math.floor(t / msPerSecond) % SecondsPerMinute;
- if (result < 0)
- result += SecondsPerMinute;
- return (int) result;
- }
-
- private static int msFromTime(double t)
- {
- double result;
- result = t % msPerSecond;
- if (result < 0)
- result += msPerSecond;
- return (int) result;
- }
-
- private static double MakeTime(double hour, double min,
- double sec, double ms)
- {
- return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec)
- * msPerSecond + ms;
- }
-
- private static double MakeDay(double year, double month, double date)
- {
- year += Math.floor(month / 12);
-
- month = month % 12;
- if (month < 0)
- month += 12;
-
- double yearday = Math.floor(TimeFromYear(year) / msPerDay);
- double monthday = DayFromMonth((int)month, (int)year);
-
- return yearday + monthday + date - 1;
- }
-
- private static double MakeDate(double day, double time)
- {
- return day * msPerDay + time;
- }
-
- private static double TimeClip(double d)
- {
- if (d != d ||
- d == Double.POSITIVE_INFINITY ||
- d == Double.NEGATIVE_INFINITY ||
- Math.abs(d) > HalfTimeDomain)
- {
- return ScriptRuntime.NaN;
- }
- if (d > 0.0)
- return Math.floor(d + 0.);
- else
- return Math.ceil(d + 0.);
- }
-
- /* end of ECMA helper functions */
-
- /* find UTC time from given date... no 1900 correction! */
- private static double date_msecFromDate(double year, double mon,
- double mday, double hour,
- double min, double sec,
- double msec)
- {
- double day;
- double time;
- double result;
-
- day = MakeDay(year, mon, mday);
- time = MakeTime(hour, min, sec, msec);
- result = MakeDate(day, time);
- return result;
- }
-
- /* compute the time in msec (unclipped) from the given args */
- private static final int MAXARGS = 7;
- private static double date_msecFromArgs(Object[] args)
- {
- double array[] = new double[MAXARGS];
- int loop;
- double d;
-
- for (loop = 0; loop < MAXARGS; loop++) {
- if (loop < args.length) {
- d = ScriptRuntime.toNumber(args[loop]);
- if (d != d || Double.isInfinite(d)) {
- return ScriptRuntime.NaN;
- }
- array[loop] = ScriptRuntime.toInteger(args[loop]);
- } else {
- if (loop == 2) {
- array[loop] = 1; /* Default the date argument to 1. */
- } else {
- array[loop] = 0;
- }
- }
- }
-
- /* adjust 2-digit years into the 20th century */
- if (array[0] >= 0 && array[0] <= 99)
- array[0] += 1900;
-
- return date_msecFromDate(array[0], array[1], array[2],
- array[3], array[4], array[5], array[6]);
- }
-
- private static double jsStaticFunction_UTC(Object[] args)
- {
- return TimeClip(date_msecFromArgs(args));
- }
-
- private static double date_parseString(String s)
- {
- int year = -1;
- int mon = -1;
- int mday = -1;
- int hour = -1;
- int min = -1;
- int sec = -1;
- char c = 0;
- char si = 0;
- int i = 0;
- int n = -1;
- double tzoffset = -1;
- char prevc = 0;
- int limit = 0;
- boolean seenplusminus = false;
-
- limit = s.length();
- while (i < limit) {
- c = s.charAt(i);
- i++;
- if (c <= ' ' || c == ',' || c == '-') {
- if (i < limit) {
- si = s.charAt(i);
- if (c == '-' && '0' <= si && si <= '9') {
- prevc = c;
- }
- }
- continue;
- }
- if (c == '(') { /* comments) */
- int depth = 1;
- while (i < limit) {
- c = s.charAt(i);
- i++;
- if (c == '(')
- depth++;
- else if (c == ')')
- if (--depth <= 0)
- break;
- }
- continue;
- }
- if ('0' <= c && c <= '9') {
- n = c - '0';
- while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
- n = n * 10 + c - '0';
- i++;
- }
-
- /* allow TZA before the year, so
- * 'Wed Nov 05 21:49:11 GMT-0800 1997'
- * works */
-
- /* uses of seenplusminus allow : in TZA, so Java
- * no-timezone style of GMT+4:30 works
- */
- if ((prevc == '+' || prevc == '-')/* && year>=0 */) {
- /* make ':' case below change tzoffset */
- seenplusminus = true;
-
- /* offset */
- if (n < 24)
- n = n * 60; /* EG. "GMT-3" */
- else
- n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */
- if (prevc == '+') /* plus means east of GMT */
- n = -n;
- if (tzoffset != 0 && tzoffset != -1)
- return ScriptRuntime.NaN;
- tzoffset = n;
- } else if (n >= 70 ||
- (prevc == '/' && mon >= 0 && mday >= 0
- && year < 0))
- {
- if (year >= 0)
- return ScriptRuntime.NaN;
- else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
- year = n < 100 ? n + 1900 : n;
- else
- return ScriptRuntime.NaN;
- } else if (c == ':') {
- if (hour < 0)
- hour = /*byte*/ n;
- else if (min < 0)
- min = /*byte*/ n;
- else
- return ScriptRuntime.NaN;
- } else if (c == '/') {
- if (mon < 0)
- mon = /*byte*/ n-1;
- else if (mday < 0)
- mday = /*byte*/ n;
- else
- return ScriptRuntime.NaN;
- } else if (i < limit && c != ',' && c > ' ' && c != '-') {
- return ScriptRuntime.NaN;
- } else if (seenplusminus && n < 60) { /* handle GMT-3:30 */
- if (tzoffset < 0)
- tzoffset -= n;
- else
- tzoffset += n;
- } else if (hour >= 0 && min < 0) {
- min = /*byte*/ n;
- } else if (min >= 0 && sec < 0) {
- sec = /*byte*/ n;
- } else if (mday < 0) {
- mday = /*byte*/ n;
- } else {
- return ScriptRuntime.NaN;
- }
- prevc = 0;
- } else if (c == '/' || c == ':' || c == '+' || c == '-') {
- prevc = c;
- } else {
- int st = i - 1;
- while (i < limit) {
- c = s.charAt(i);
- if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
- break;
- i++;
- }
- int letterCount = i - st;
- if (letterCount < 2)
- return ScriptRuntime.NaN;
- /*
- * Use ported code from jsdate.c rather than the locale-specific
- * date-parsing code from Java, to keep js and rhino consistent.
- * Is this the right strategy?
- */
- String wtb = "am;pm;"
- +"monday;tuesday;wednesday;thursday;friday;"
- +"saturday;sunday;"
- +"january;february;march;april;may;june;"
- +"july;august;september;october;november;december;"
- +"gmt;ut;utc;est;edt;cst;cdt;mst;mdt;pst;pdt;";
- int index = 0;
- for (int wtbOffset = 0; ;) {
- int wtbNext = wtb.indexOf(';', wtbOffset);
- if (wtbNext < 0)
- return ScriptRuntime.NaN;
- if (wtb.regionMatches(true, wtbOffset, s, st, letterCount))
- break;
- wtbOffset = wtbNext + 1;
- ++index;
- }
- if (index < 2) {
- /*
- * AM/PM. Count 12:30 AM as 00:30, 12:30 PM as
- * 12:30, instead of blindly adding 12 if PM.
- */
- if (hour > 12 || hour < 0) {
- return ScriptRuntime.NaN;
- } else if (index == 0) {
- // AM
- if (hour == 12)
- hour = 0;
- } else {
- // PM
- if (hour != 12)
- hour += 12;
- }
- } else if ((index -= 2) < 7) {
- // ignore week days
- } else if ((index -= 7) < 12) {
- // month
- if (mon < 0) {
- mon = index;
- } else {
- return ScriptRuntime.NaN;
- }
- } else {
- index -= 12;
- // timezones
- switch (index) {
- case 0 /* gmt */: tzoffset = 0; break;
- case 1 /* ut */: tzoffset = 0; break;
- case 2 /* utc */: tzoffset = 0; break;
- case 3 /* est */: tzoffset = 5 * 60; break;
- case 4 /* edt */: tzoffset = 4 * 60; break;
- case 5 /* cst */: tzoffset = 6 * 60; break;
- case 6 /* cdt */: tzoffset = 5 * 60; break;
- case 7 /* mst */: tzoffset = 7 * 60; break;
- case 8 /* mdt */: tzoffset = 6 * 60; break;
- case 9 /* pst */: tzoffset = 8 * 60; break;
- case 10 /* pdt */:tzoffset = 7 * 60; break;
- default: Kit.codeBug();
- }
- }
- }
- }
- if (year < 0 || mon < 0 || mday < 0)
- return ScriptRuntime.NaN;
- if (sec < 0)
- sec = 0;
- if (min < 0)
- min = 0;
- if (hour < 0)
- hour = 0;
-
- double msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
- if (tzoffset == -1) { /* no time zone specified, have to use local */
- return internalUTC(msec);
- } else {
- return msec + tzoffset * msPerMinute;
- }
- }
-
- private static String date_format(double t, int methodId)
- {
- StringBuffer result = new StringBuffer(60);
- double local = LocalTime(t);
-
- /* Tue Oct 31 09:41:40 GMT-0800 (PST) 2000 */
- /* Tue Oct 31 2000 */
- /* 09:41:40 GMT-0800 (PST) */
-
- if (methodId != Id_toTimeString) {
- appendWeekDayName(result, WeekDay(local));
- result.append(' ');
- appendMonthName(result, MonthFromTime(local));
- result.append(' ');
- append0PaddedUint(result, DateFromTime(local), 2);
- result.append(' ');
- int year = YearFromTime(local);
- if (year < 0) {
- result.append('-');
- year = -year;
- }
- append0PaddedUint(result, year, 4);
- if (methodId != Id_toDateString)
- result.append(' ');
- }
-
- if (methodId != Id_toDateString) {
- append0PaddedUint(result, HourFromTime(local), 2);
- result.append(':');
- append0PaddedUint(result, MinFromTime(local), 2);
- result.append(':');
- append0PaddedUint(result, SecFromTime(local), 2);
-
- // offset from GMT in minutes. The offset includes daylight
- // savings, if it applies.
- int minutes = (int) Math.floor((LocalTZA + DaylightSavingTA(t))
- / msPerMinute);
- // map 510 minutes to 0830 hours
- int offset = (minutes / 60) * 100 + minutes % 60;
- if (offset > 0) {
- result.append(" GMT+");
- } else {
- result.append(" GMT-");
- offset = -offset;
- }
- append0PaddedUint(result, offset, 4);
-
- if (timeZoneFormatter == null)
- timeZoneFormatter = new java.text.SimpleDateFormat("zzz");
-
- // Find an equivalent year before getting the timezone
- // comment. See DaylightSavingTA.
- if (t < 0.0 || t > 2145916800000.0) {
- int equiv = EquivalentYear(YearFromTime(local));
- double day = MakeDay(equiv, MonthFromTime(t), DateFromTime(t));
- t = MakeDate(day, TimeWithinDay(t));
- }
- result.append(" (");
- java.util.Date date = new Date((long) t);
- synchronized (timeZoneFormatter) {
- result.append(timeZoneFormatter.format(date));
- }
- result.append(')');
- }
- return result.toString();
- }
-
- /* the javascript constructor */
- private static Object jsConstructor(Object[] args)
- {
- NativeDate obj = new NativeDate();
-
- // if called as a constructor with no args,
- // return a new Date with the current time.
- if (args.length == 0) {
- obj.date = now();
- return obj;
- }
-
- // if called with just one arg -
- if (args.length == 1) {
- Object arg0 = args[0];
- if (arg0 instanceof Scriptable)
- arg0 = ((Scriptable) arg0).getDefaultValue(null);
- double date;
- if (arg0 instanceof String) {
- // it's a string; parse it.
- date = date_parseString((String)arg0);
- } else {
- // if it's not a string, use it as a millisecond date
- date = ScriptRuntime.toNumber(arg0);
- }
- obj.date = TimeClip(date);
- return obj;
- }
-
- double time = date_msecFromArgs(args);
-
- if (!Double.isNaN(time) && !Double.isInfinite(time))
- time = TimeClip(internalUTC(time));
-
- obj.date = time;
-
- return obj;
- }
-
- private static String toLocale_helper(double t, int methodId)
- {
- java.text.DateFormat formatter;
- switch (methodId) {
- case Id_toLocaleString:
- if (localeDateTimeFormatter == null) {
- localeDateTimeFormatter
- = DateFormat.getDateTimeInstance(DateFormat.LONG,
- DateFormat.LONG);
- }
- formatter = localeDateTimeFormatter;
- break;
- case Id_toLocaleTimeString:
- if (localeTimeFormatter == null) {
- localeTimeFormatter
- = DateFormat.getTimeInstance(DateFormat.LONG);
- }
- formatter = localeTimeFormatter;
- break;
- case Id_toLocaleDateString:
- if (localeDateFormatter == null) {
- localeDateFormatter
- = DateFormat.getDateInstance(DateFormat.LONG);
- }
- formatter = localeDateFormatter;
- break;
- default: formatter = null; // unreachable
- }
-
- synchronized (formatter) {
- return formatter.format(new Date((long) t));
- }
- }
-
- private static String js_toUTCString(double date)
- {
- StringBuffer result = new StringBuffer(60);
-
- appendWeekDayName(result, WeekDay(date));
- result.append(", ");
- append0PaddedUint(result, DateFromTime(date), 2);
- result.append(' ');
- appendMonthName(result, MonthFromTime(date));
- result.append(' ');
- int year = YearFromTime(date);
- if (year < 0) {
- result.append('-'); year = -year;
- }
- append0PaddedUint(result, year, 4);
- result.append(' ');
- append0PaddedUint(result, HourFromTime(date), 2);
- result.append(':');
- append0PaddedUint(result, MinFromTime(date), 2);
- result.append(':');
- append0PaddedUint(result, SecFromTime(date), 2);
- result.append(" GMT");
- return result.toString();
- }
-
- private static void append0PaddedUint(StringBuffer sb, int i, int minWidth)
- {
- if (i < 0) Kit.codeBug();
- int scale = 1;
- --minWidth;
- if (i >= 10) {
- if (i < 1000 * 1000 * 1000) {
- for (;;) {
- int newScale = scale * 10;
- if (i < newScale) { break; }
- --minWidth;
- scale = newScale;
- }
- } else {
- // Separated case not to check against 10 * 10^9 overflow
- minWidth -= 9;
- scale = 1000 * 1000 * 1000;
- }
- }
- while (minWidth > 0) {
- sb.append('0');
- --minWidth;
- }
- while (scale != 1) {
- sb.append((char)('0' + (i / scale)));
- i %= scale;
- scale /= 10;
- }
- sb.append((char)('0' + i));
- }
-
- private static void appendMonthName(StringBuffer sb, int index)
- {
- // Take advantage of the fact that all month abbreviations
- // have the same length to minimize amount of strings runtime has
- // to keep in memory
- String months = "Jan"+"Feb"+"Mar"+"Apr"+"May"+"Jun"
- +"Jul"+"Aug"+"Sep"+"Oct"+"Nov"+"Dec";
- index *= 3;
- for (int i = 0; i != 3; ++i) {
- sb.append(months.charAt(index + i));
- }
- }
-
- private static void appendWeekDayName(StringBuffer sb, int index)
- {
- String days = "Sun"+"Mon"+"Tue"+"Wed"+"Thu"+"Fri"+"Sat";
- index *= 3;
- for (int i = 0; i != 3; ++i) {
- sb.append(days.charAt(index + i));
- }
- }
-
- private static double makeTime(double date, Object[] args, int methodId)
- {
- int maxargs;
- boolean local = true;
- switch (methodId) {
- case Id_setUTCMilliseconds:
- local = false;
- // fallthrough
- case Id_setMilliseconds:
- maxargs = 1;
- break;
-
- case Id_setUTCSeconds:
- local = false;
- // fallthrough
- case Id_setSeconds:
- maxargs = 2;
- break;
-
- case Id_setUTCMinutes:
- local = false;
- // fallthrough
- case Id_setMinutes:
- maxargs = 3;
- break;
-
- case Id_setUTCHours:
- local = false;
- // fallthrough
- case Id_setHours:
- maxargs = 4;
- break;
-
- default:
- Kit.codeBug();
- maxargs = 0;
- }
-
- int i;
- double conv[] = new double[4];
- double hour, min, sec, msec;
- double lorutime; /* Local or UTC version of date */
-
- double time;
- double result;
-
- /* just return NaN if the date is already NaN */
- if (date != date)
- return date;
-
- /* Satisfy the ECMA rule that if a function is called with
- * fewer arguments than the specified formal arguments, the
- * remaining arguments are set to undefined. Seems like all
- * the Date.setWhatever functions in ECMA are only varargs
- * beyond the first argument; this should be set to undefined
- * if it's not given. This means that "d = new Date();
- * d.setMilliseconds()" returns NaN. Blech.
- */
- if (args.length == 0)
- args = ScriptRuntime.padArguments(args, 1);
-
- for (i = 0; i < args.length && i < maxargs; i++) {
- conv[i] = ScriptRuntime.toNumber(args[i]);
-
- // limit checks that happen in MakeTime in ECMA.
- if (conv[i] != conv[i] || Double.isInfinite(conv[i])) {
- return ScriptRuntime.NaN;
- }
- conv[i] = ScriptRuntime.toInteger(conv[i]);
- }
-
- if (local)
- lorutime = LocalTime(date);
- else
- lorutime = date;
-
- i = 0;
- int stop = args.length;
-
- if (maxargs >= 4 && i < stop)
- hour = conv[i++];
- else
- hour = HourFromTime(lorutime);
-
- if (maxargs >= 3 && i < stop)
- min = conv[i++];
- else
- min = MinFromTime(lorutime);
-
- if (maxargs >= 2 && i < stop)
- sec = conv[i++];
- else
- sec = SecFromTime(lorutime);
-
- if (maxargs >= 1 && i < stop)
- msec = conv[i++];
- else
- msec = msFromTime(lorutime);
-
- time = MakeTime(hour, min, sec, msec);
- result = MakeDate(Day(lorutime), time);
-
- if (local)
- result = internalUTC(result);
- date = TimeClip(result);
-
- return date;
- }
-
- private static double makeDate(double date, Object[] args, int methodId)
- {
- int maxargs;
- boolean local = true;
- switch (methodId) {
- case Id_setUTCDate:
- local = false;
- // fallthrough
- case Id_setDate:
- maxargs = 1;
- break;
-
- case Id_setUTCMonth:
- local = false;
- // fallthrough
- case Id_setMonth:
- maxargs = 2;
- break;
-
- case Id_setUTCFullYear:
- local = false;
- // fallthrough
- case Id_setFullYear:
- maxargs = 3;
- break;
-
- default:
- Kit.codeBug();
- maxargs = 0;
- }
-
- int i;
- double conv[] = new double[3];
- double year, month, day;
- double lorutime; /* local or UTC version of date */
- double result;
-
- /* See arg padding comment in makeTime.*/
- if (args.length == 0)
- args = ScriptRuntime.padArguments(args, 1);
-
- for (i = 0; i < args.length && i < maxargs; i++) {
- conv[i] = ScriptRuntime.toNumber(args[i]);
-
- // limit checks that happen in MakeDate in ECMA.
- if (conv[i] != conv[i] || Double.isInfinite(conv[i])) {
- return ScriptRuntime.NaN;
- }
- conv[i] = ScriptRuntime.toInteger(conv[i]);
- }
-
- /* return NaN if date is NaN and we're not setting the year,
- * If we are, use 0 as the time. */
- if (date != date) {
- if (args.length < 3) {
- return ScriptRuntime.NaN;
- } else {
- lorutime = 0;
- }
- } else {
- if (local)
- lorutime = LocalTime(date);
- else
- lorutime = date;
- }
-
- i = 0;
- int stop = args.length;
-
- if (maxargs >= 3 && i < stop)
- year = conv[i++];
- else
- year = YearFromTime(lorutime);
-
- if (maxargs >= 2 && i < stop)
- month = conv[i++];
- else
- month = MonthFromTime(lorutime);
-
- if (maxargs >= 1 && i < stop)
- day = conv[i++];
- else
- day = DateFromTime(lorutime);
-
- day = MakeDay(year, month, day); /* day within year */
- result = MakeDate(day, TimeWithinDay(lorutime));
-
- if (local)
- result = internalUTC(result);
-
- date = TimeClip(result);
-
- return date;
- }
-
-// #string_id_map#
-
- protected int findPrototypeId(String s)
- {
- int id;
-// #generated# Last update: 2007-05-09 08:15:38 EDT
- L0: { id = 0; String X = null; int c;
- L: switch (s.length()) {
- case 6: X="getDay";id=Id_getDay; break L;
- case 7: switch (s.charAt(3)) {
- case 'D': c=s.charAt(0);
- if (c=='g') { X="getDate";id=Id_getDate; }
- else if (c=='s') { X="setDate";id=Id_setDate; }
- break L;
- case 'T': c=s.charAt(0);
- if (c=='g') { X="getTime";id=Id_getTime; }
- else if (c=='s') { X="setTime";id=Id_setTime; }
- break L;
- case 'Y': c=s.charAt(0);
- if (c=='g') { X="getYear";id=Id_getYear; }
- else if (c=='s') { X="setYear";id=Id_setYear; }
- break L;
- case 'u': X="valueOf";id=Id_valueOf; break L;
- } break L;
- case 8: switch (s.charAt(3)) {
- case 'H': c=s.charAt(0);
- if (c=='g') { X="getHours";id=Id_getHours; }
- else if (c=='s') { X="setHours";id=Id_setHours; }
- break L;
- case 'M': c=s.charAt(0);
- if (c=='g') { X="getMonth";id=Id_getMonth; }
- else if (c=='s') { X="setMonth";id=Id_setMonth; }
- break L;
- case 'o': X="toSource";id=Id_toSource; break L;
- case 't': X="toString";id=Id_toString; break L;
- } break L;
- case 9: X="getUTCDay";id=Id_getUTCDay; break L;
- case 10: c=s.charAt(3);
- if (c=='M') {
- c=s.charAt(0);
- if (c=='g') { X="getMinutes";id=Id_getMinutes; }
- else if (c=='s') { X="setMinutes";id=Id_setMinutes; }
- }
- else if (c=='S') {
- c=s.charAt(0);
- if (c=='g') { X="getSeconds";id=Id_getSeconds; }
- else if (c=='s') { X="setSeconds";id=Id_setSeconds; }
- }
- else if (c=='U') {
- c=s.charAt(0);
- if (c=='g') { X="getUTCDate";id=Id_getUTCDate; }
- else if (c=='s') { X="setUTCDate";id=Id_setUTCDate; }
- }
- break L;
- case 11: switch (s.charAt(3)) {
- case 'F': c=s.charAt(0);
- if (c=='g') { X="getFullYear";id=Id_getFullYear; }
- else if (c=='s') { X="setFullYear";id=Id_setFullYear; }
- break L;
- case 'M': X="toGMTString";id=Id_toGMTString; break L;
- case 'T': X="toUTCString";id=Id_toUTCString; break L;
- case 'U': c=s.charAt(0);
- if (c=='g') {
- c=s.charAt(9);
- if (c=='r') { X="getUTCHours";id=Id_getUTCHours; }
- else if (c=='t') { X="getUTCMonth";id=Id_getUTCMonth; }
- }
- else if (c=='s') {
- c=s.charAt(9);
- if (c=='r') { X="setUTCHours";id=Id_setUTCHours; }
- else if (c=='t') { X="setUTCMonth";id=Id_setUTCMonth; }
- }
- break L;
- case 's': X="constructor";id=Id_constructor; break L;
- } break L;
- case 12: c=s.charAt(2);
- if (c=='D') { X="toDateString";id=Id_toDateString; }
- else if (c=='T') { X="toTimeString";id=Id_toTimeString; }
- break L;
- case 13: c=s.charAt(0);
- if (c=='g') {
- c=s.charAt(6);
- if (c=='M') { X="getUTCMinutes";id=Id_getUTCMinutes; }
- else if (c=='S') { X="getUTCSeconds";id=Id_getUTCSeconds; }
- }
- else if (c=='s') {
- c=s.charAt(6);
- if (c=='M') { X="setUTCMinutes";id=Id_setUTCMinutes; }
- else if (c=='S') { X="setUTCSeconds";id=Id_setUTCSeconds; }
- }
- break L;
- case 14: c=s.charAt(0);
- if (c=='g') { X="getUTCFullYear";id=Id_getUTCFullYear; }
- else if (c=='s') { X="setUTCFullYear";id=Id_setUTCFullYear; }
- else if (c=='t') { X="toLocaleString";id=Id_toLocaleString; }
- break L;
- case 15: c=s.charAt(0);
- if (c=='g') { X="getMilliseconds";id=Id_getMilliseconds; }
- else if (c=='s') { X="setMilliseconds";id=Id_setMilliseconds; }
- break L;
- case 17: X="getTimezoneOffset";id=Id_getTimezoneOffset; break L;
- case 18: c=s.charAt(0);
- if (c=='g') { X="getUTCMilliseconds";id=Id_getUTCMilliseconds; }
- else if (c=='s') { X="setUTCMilliseconds";id=Id_setUTCMilliseconds; }
- else if (c=='t') {
- c=s.charAt(8);
- if (c=='D') { X="toLocaleDateString";id=Id_toLocaleDateString; }
- else if (c=='T') { X="toLocaleTimeString";id=Id_toLocaleTimeString; }
- }
- break L;
- }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- ConstructorId_now = -3,
- ConstructorId_parse = -2,
- ConstructorId_UTC = -1,
-
- Id_constructor = 1,
- Id_toString = 2,
- Id_toTimeString = 3,
- Id_toDateString = 4,
- Id_toLocaleString = 5,
- Id_toLocaleTimeString = 6,
- Id_toLocaleDateString = 7,
- Id_toUTCString = 8,
- Id_toSource = 9,
- Id_valueOf = 10,
- Id_getTime = 11,
- Id_getYear = 12,
- Id_getFullYear = 13,
- Id_getUTCFullYear = 14,
- Id_getMonth = 15,
- Id_getUTCMonth = 16,
- Id_getDate = 17,
- Id_getUTCDate = 18,
- Id_getDay = 19,
- Id_getUTCDay = 20,
- Id_getHours = 21,
- Id_getUTCHours = 22,
- Id_getMinutes = 23,
- Id_getUTCMinutes = 24,
- Id_getSeconds = 25,
- Id_getUTCSeconds = 26,
- Id_getMilliseconds = 27,
- Id_getUTCMilliseconds = 28,
- Id_getTimezoneOffset = 29,
- Id_setTime = 30,
- Id_setMilliseconds = 31,
- Id_setUTCMilliseconds = 32,
- Id_setSeconds = 33,
- Id_setUTCSeconds = 34,
- Id_setMinutes = 35,
- Id_setUTCMinutes = 36,
- Id_setHours = 37,
- Id_setUTCHours = 38,
- Id_setDate = 39,
- Id_setUTCDate = 40,
- Id_setMonth = 41,
- Id_setUTCMonth = 42,
- Id_setFullYear = 43,
- Id_setUTCFullYear = 44,
- Id_setYear = 45,
-
- MAX_PROTOTYPE_ID = 45;
-
- private static final int
- Id_toGMTString = Id_toUTCString; // Alias, see Ecma B.2.6
-// #/string_id_map#
-
- /* cached values */
- private static java.util.TimeZone thisTimeZone;
- private static double LocalTZA;
- private static java.text.DateFormat timeZoneFormatter;
- private static java.text.DateFormat localeDateTimeFormatter;
- private static java.text.DateFormat localeDateFormatter;
- private static java.text.DateFormat localeTimeFormatter;
-
- private double date;
-}
-
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeError.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeError.java
deleted file mode 100644
index 4aff10c..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeError.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/* -*- 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):
- * Igor Bukanov
- * Roger Lawrence
- *
- * 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;
-
-/**
- *
- * The class of error objects
- *
- * ECMA 15.11
- */
-final class NativeError extends IdScriptableObject
-{
- static final long serialVersionUID = -5338413581437645187L;
-
- private static final Object ERROR_TAG = new Object();
-
- static void init(Scriptable scope, boolean sealed)
- {
- NativeError obj = new NativeError();
- ScriptableObject.putProperty(obj, "name", "Error");
- ScriptableObject.putProperty(obj, "message", "");
- ScriptableObject.putProperty(obj, "fileName", "");
- ScriptableObject.putProperty(obj, "lineNumber", new Integer(0));
- obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
- }
-
- static NativeError make(Context cx, Scriptable scope,
- IdFunctionObject ctorObj, Object[] args)
- {
- Scriptable proto = (Scriptable)(ctorObj.get("prototype", ctorObj));
-
- NativeError obj = new NativeError();
- obj.setPrototype(proto);
- obj.setParentScope(scope);
-
- int arglen = args.length;
- if (arglen >= 1) {
- ScriptableObject.putProperty(obj, "message",
- ScriptRuntime.toString(args[0]));
- if (arglen >= 2) {
- ScriptableObject.putProperty(obj, "fileName", args[1]);
- if (arglen >= 3) {
- int line = ScriptRuntime.toInt32(args[2]);
- ScriptableObject.putProperty(obj, "lineNumber",
- new Integer(line));
- }
- }
- }
- if(arglen < 3 && cx.hasFeature(Context.FEATURE_LOCATION_INFORMATION_IN_ERROR)) {
- // Fill in fileName and lineNumber automatically when not specified
- // explicitly, see Bugzilla issue #342807
- int[] linep = new int[1];
- String fileName = Context.getSourcePositionFromStack(linep);
- ScriptableObject.putProperty(obj, "lineNumber",
- new Integer(linep[0]));
- if(arglen < 2) {
- ScriptableObject.putProperty(obj, "fileName", fileName);
- }
- }
- 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 execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(ERROR_TAG)) {
- return super.execIdCall(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)
- {
- return getString(thisObj, "name")+": "+getString(thisObj, "message");
- }
-
- private static String js_toSource(Context cx, Scriptable scope,
- Scriptable thisObj)
- {
- // Emulation of SpiderMonkey behavior
- Object name = ScriptableObject.getProperty(thisObj, "name");
- Object message = ScriptableObject.getProperty(thisObj, "message");
- Object fileName = ScriptableObject.getProperty(thisObj, "fileName");
- Object lineNumber = ScriptableObject.getProperty(thisObj, "lineNumber");
-
- StringBuffer sb = new StringBuffer();
- sb.append("(new ");
- if (name == NOT_FOUND) {
- name = Undefined.instance;
- }
- sb.append(ScriptRuntime.toString(name));
- sb.append("(");
- if (message != NOT_FOUND
- || fileName != NOT_FOUND
- || lineNumber != NOT_FOUND)
- {
- if (message == NOT_FOUND) {
- message = "";
- }
- sb.append(ScriptRuntime.uneval(cx, scope, message));
- if (fileName != NOT_FOUND || lineNumber != NOT_FOUND) {
- sb.append(", ");
- if (fileName == NOT_FOUND) {
- fileName = "";
- }
- sb.append(ScriptRuntime.uneval(cx, scope, fileName));
- if (lineNumber != NOT_FOUND) {
- int line = ScriptRuntime.toInt32(lineNumber);
- if (line != 0) {
- sb.append(", ");
- sb.append(ScriptRuntime.toString(line));
- }
- }
- }
- }
- sb.append("))");
- return sb.toString();
- }
-
- private static String getString(Scriptable obj, String id)
- {
- Object value = ScriptableObject.getProperty(obj, id);
- if (value == NOT_FOUND) return "";
- return ScriptRuntime.toString(value);
- }
-
- protected int findPrototypeId(String s)
- {
- int id;
-// #string_id_map#
-// #generated# Last update: 2007-05-09 08:15:45 EDT
- L0: { id = 0; String X = null; int c;
- int s_length = s.length();
- if (s_length==8) {
- c=s.charAt(3);
- if (c=='o') { X="toSource";id=Id_toSource; }
- else if (c=='t') { X="toString";id=Id_toString; }
- }
- else if (s_length==11) { X="constructor";id=Id_constructor; }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- Id_constructor = 1,
- Id_toString = 2,
- Id_toSource = 3,
-
- MAX_PROTOTYPE_ID = 3;
-
-// #/string_id_map#
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeFunction.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeFunction.java
deleted file mode 100644
index ac70556..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeFunction.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/* -*- 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
- * Bob Jervis
- * Roger Lawrence
- * Mike McCabe
- *
- * 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;
-
-import org.mozilla.javascript.debug.DebuggableScript;
-
-/**
- * This class implements the Function native object.
- * See ECMA 15.3.
- * @author Norris Boyd
- */
-public abstract class NativeFunction extends BaseFunction
-{
-
- public final void initScriptFunction(Context cx, Scriptable scope)
- {
- ScriptRuntime.setFunctionProtoAndParent(this, scope);
- }
-
- /**
- * @param indent How much to indent the decompiled result
- *
- * @param flags Flags specifying format of decompilation output
- */
- final String decompile(int indent, int flags)
- {
- String encodedSource = getEncodedSource();
- if (encodedSource == null) {
- return super.decompile(indent, flags);
- } else {
- UintMap properties = new UintMap(1);
- properties.put(Decompiler.INITIAL_INDENT_PROP, indent);
- return Decompiler.decompile(encodedSource, flags, properties);
- }
- }
-
- public int getLength()
- {
- int paramCount = getParamCount();
- if (getLanguageVersion() != Context.VERSION_1_2) {
- return paramCount;
- }
- Context cx = Context.getContext();
- NativeCall activation = ScriptRuntime.findFunctionActivation(cx, this);
- if (activation == null) {
- return paramCount;
- }
- return activation.originalArgs.length;
- }
-
- public int getArity()
- {
- return getParamCount();
- }
-
- /**
- * @deprecated Use {@link BaseFunction#getFunctionName()} instead.
- * For backwards compatibility keep an old method name used by
- * Batik and possibly others.
- */
- public String jsGet_name()
- {
- return getFunctionName();
- }
-
- /**
- * Get encoded source string.
- */
- public String getEncodedSource()
- {
- return null;
- }
-
- public DebuggableScript getDebuggableView()
- {
- return null;
- }
-
- /**
- * Resume execution of a suspended generator.
- * @param cx The current context
- * @param scope Scope for the parent generator function
- * @param operation The resumption operation (next, send, etc.. )
- * @param state The generator state (has locals, stack, etc.)
- * @param value The return value of yield (if required).
- * @return The next yielded value (if any)
- */
- public Object resumeGenerator(Context cx, Scriptable scope,
- int operation, Object state, Object value)
- {
- throw new EvaluatorException("resumeGenerator() not implemented");
- }
-
-
- protected abstract int getLanguageVersion();
-
- /**
- * Get number of declared parameters. It should be 0 for scripts.
- */
- protected abstract int getParamCount();
-
- /**
- * Get number of declared parameters and variables defined through var
- * statements.
- */
- protected abstract int getParamAndVarCount();
-
- /**
- * Get parameter or variable name.
- * If <tt>index < {@link #getParamCount()}</tt>, then return the name of the
- * corresponding parameter. Otherwise return the name of variable.
- */
- protected abstract String getParamOrVarName(int index);
-
- /**
- * Get parameter or variable const-ness.
- * If <tt>index < {@link #getParamCount()}</tt>, then return the const-ness
- * of the corresponding parameter. Otherwise return whether the variable is
- * const.
- */
- protected boolean getParamOrVarConst(int index)
- {
- // By default return false to preserve compatibility with existing
- // classes subclassing this class, which are mostly generated by jsc
- // from earlier Rhino versions. See Bugzilla #396117.
- return false;
- }
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGenerator.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGenerator.java
deleted file mode 100644
index 0a8da9f..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGenerator.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/* -*- 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.
- *
- * Contributor(s):
- * Norris Boyd
- *
- * 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 generator objects. See
- * http://developer.mozilla.org/en/docs/New_in_JavaScript_1.7#Generators
- *
- * @author Norris Boyd
- */
-public final class NativeGenerator extends IdScriptableObject {
- private static final Object GENERATOR_TAG = new Object();
-
- static NativeGenerator init(ScriptableObject scope, boolean sealed) {
- // Generator
- // Can't use "NativeGenerator().exportAsJSClass" since we don't want
- // to define "Generator" as a constructor in the top-level scope.
-
- NativeGenerator prototype = new NativeGenerator();
- if (scope != null) {
- prototype.setParentScope(scope);
- prototype.setPrototype(getObjectPrototype(scope));
- }
- prototype.activatePrototypeMap(MAX_PROTOTYPE_ID);
- if (sealed) {
- prototype.sealObject();
- }
-
- // Need to access Generator prototype when constructing
- // Generator instances, but don't have a generator constructor
- // to use to find the prototype. Use the "associateValue"
- // approach instead.
- if (scope != null) {
- scope.associateValue(GENERATOR_TAG, prototype);
- }
-
- return prototype;
- }
-
- /**
- * Only for constructing the prototype object.
- */
- private NativeGenerator() { }
-
- public NativeGenerator(Scriptable scope, NativeFunction function,
- Object savedState)
- {
- this.function = function;
- this.savedState = savedState;
- // Set parent and prototype properties. Since we don't have a
- // "Generator" constructor in the top scope, we stash the
- // prototype in the top scope's associated value.
- Scriptable top = ScriptableObject.getTopLevelScope(scope);
- this.setParentScope(top);
- NativeGenerator prototype = (NativeGenerator)
- ScriptableObject.getTopScopeValue(top, GENERATOR_TAG);
- this.setPrototype(prototype);
- }
-
- public static final int GENERATOR_SEND = 0,
- GENERATOR_THROW = 1,
- GENERATOR_CLOSE = 2;
-
- public String getClassName() {
- return "Generator";
- }
-
- /**
- * Close the generator if it is still open.
- */
- public void finalize() throws Throwable {
- if (savedState != null) {
- // This is a little tricky since we are most likely running in
- // a different thread. We need to get a Context to run this, and
- // we must call "doTopCall" since this will likely be the outermost
- // JavaScript frame on this thread.
- Context cx = Context.getCurrentContext();
- ContextFactory factory = cx != null ? cx.getFactory()
- : ContextFactory.getGlobal();
- Scriptable scope = ScriptableObject.getTopLevelScope(this);
- factory.call(new CloseGeneratorAction(this));
- }
- }
-
- private static class CloseGeneratorAction implements ContextAction {
- private NativeGenerator generator;
-
- CloseGeneratorAction(NativeGenerator generator) {
- this.generator = generator;
- }
-
- public Object run(Context cx) {
- Scriptable scope = ScriptableObject.getTopLevelScope(generator);
- Callable closeGenerator = new Callable() {
- public Object call(Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args) {
- return ((NativeGenerator)thisObj).resume(cx, scope,
- GENERATOR_CLOSE, new GeneratorClosedException());
- }
- };
- return ScriptRuntime.doTopCall(closeGenerator, cx, scope,
- generator, null);
- }
- }
-
- protected void initPrototypeId(int id) {
- String s;
- int arity;
- switch (id) {
- case Id_close: arity=1; s="close"; break;
- case Id_next: arity=1; s="next"; break;
- case Id_send: arity=0; s="send"; break;
- case Id_throw: arity=0; s="throw"; break;
- case Id___iterator__: arity=1; s="__iterator__"; break;
- default: throw new IllegalArgumentException(String.valueOf(id));
- }
- initPrototypeMethod(GENERATOR_TAG, id, s, arity);
- }
-
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(GENERATOR_TAG)) {
- return super.execIdCall(f, cx, scope, thisObj, args);
- }
- int id = f.methodId();
-
- if (!(thisObj instanceof NativeGenerator))
- throw incompatibleCallError(f);
-
- NativeGenerator generator = (NativeGenerator) thisObj;
-
- switch (id) {
-
- case Id_close:
- // need to run any pending finally clauses
- return generator.resume(cx, scope, GENERATOR_CLOSE,
- new GeneratorClosedException());
-
- case Id_next:
- // arguments to next() are ignored
- generator.firstTime = false;
- return generator.resume(cx, scope, GENERATOR_SEND,
- Undefined.instance);
-
- case Id_send: {
- Object arg = args.length > 0 ? args[0] : Undefined.instance;
- if (generator.firstTime && !arg.equals(Undefined.instance)) {
- throw ScriptRuntime.typeError0("msg.send.newborn");
- }
- return generator.resume(cx, scope, GENERATOR_SEND, arg);
- }
-
- case Id_throw:
- return generator.resume(cx, scope, GENERATOR_THROW,
- args.length > 0 ? args[0] : Undefined.instance);
-
- case Id___iterator__:
- return thisObj;
-
- default:
- throw new IllegalArgumentException(String.valueOf(id));
- }
- }
-
- private Object resume(Context cx, Scriptable scope, int operation,
- Object value)
- {
- if (savedState == null) {
- if (operation == GENERATOR_CLOSE)
- return Undefined.instance;
- Object thrown;
- if (operation == GENERATOR_THROW) {
- thrown = value;
- } else {
- thrown = NativeIterator.getStopIterationObject(scope);
- }
- throw new JavaScriptException(thrown, lineSource, lineNumber);
- }
- try {
- synchronized (this) {
- // generator execution is necessarily single-threaded and
- // non-reentrant.
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=349263
- if (locked)
- throw ScriptRuntime.typeError0("msg.already.exec.gen");
- locked = true;
- }
- return function.resumeGenerator(cx, scope, operation, savedState,
- value);
- } catch (GeneratorClosedException e) {
- // On closing a generator in the compile path, the generator
- // throws a special exception. This ensures execution of all pending
- // finalizers and will not get caught by user code.
- return Undefined.instance;
- } catch (RhinoException e) {
- lineNumber = e.lineNumber();
- lineSource = e.lineSource();
- savedState = null;
- throw e;
- } finally {
- synchronized (this) {
- locked = false;
- }
- if (operation == GENERATOR_CLOSE)
- savedState = null;
- }
- }
-
-// #string_id_map#
-
- protected int findPrototypeId(String s) {
- int id;
-// #generated# Last update: 2007-06-14 13:13:03 EDT
- L0: { id = 0; String X = null; int c;
- int s_length = s.length();
- if (s_length==4) {
- c=s.charAt(0);
- if (c=='n') { X="next";id=Id_next; }
- else if (c=='s') { X="send";id=Id_send; }
- }
- else if (s_length==5) {
- c=s.charAt(0);
- if (c=='c') { X="close";id=Id_close; }
- else if (c=='t') { X="throw";id=Id_throw; }
- }
- else if (s_length==12) { X="__iterator__";id=Id___iterator__; }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- Id_close = 1,
- Id_next = 2,
- Id_send = 3,
- Id_throw = 4,
- Id___iterator__ = 5,
- MAX_PROTOTYPE_ID = 5;
-
-// #/string_id_map#
- private NativeFunction function;
- private Object savedState;
- private String lineSource;
- private int lineNumber;
- private boolean firstTime = true;
- private boolean locked;
-
- public static class GeneratorClosedException extends RuntimeException {
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGlobal.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGlobal.java
deleted file mode 100644
index 58faad4..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGlobal.java
+++ /dev/null
@@ -1,790 +0,0 @@
-/* -*- 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
- * Mike McCabe
- *
- * 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;
-
-import java.io.Serializable;
-
-import org.mozilla.javascript.xml.XMLLib;
-
-/**
- * This class implements the global native object (function and value
- * properties only).
- *
- * See ECMA 15.1.[12].
- *
- * @author Mike Shaver
- */
-
-public class NativeGlobal implements Serializable, IdFunctionCall
-{
- static final long serialVersionUID = 6080442165748707530L;
-
- public static void init(Context cx, Scriptable scope, boolean sealed) {
- NativeGlobal obj = new NativeGlobal();
-
- for (int id = 1; id <= LAST_SCOPE_FUNCTION_ID; ++id) {
- String name;
- int arity = 1;
- switch (id) {
- case Id_decodeURI:
- name = "decodeURI";
- break;
- case Id_decodeURIComponent:
- name = "decodeURIComponent";
- break;
- case Id_encodeURI:
- name = "encodeURI";
- break;
- case Id_encodeURIComponent:
- name = "encodeURIComponent";
- break;
- case Id_escape:
- name = "escape";
- break;
- case Id_eval:
- name = "eval";
- break;
- case Id_isFinite:
- name = "isFinite";
- break;
- case Id_isNaN:
- name = "isNaN";
- break;
- case Id_isXMLName:
- name = "isXMLName";
- break;
- case Id_parseFloat:
- name = "parseFloat";
- break;
- case Id_parseInt:
- name = "parseInt";
- arity = 2;
- break;
- case Id_unescape:
- name = "unescape";
- break;
- case Id_uneval:
- name = "uneval";
- break;
- default:
- throw Kit.codeBug();
- }
- IdFunctionObject f = new IdFunctionObject(obj, FTAG, id, name,
- arity, scope);
- if (sealed) {
- f.sealObject();
- }
- f.exportAsScopeProperty();
- }
-
- ScriptableObject.defineProperty(
- scope, "NaN", ScriptRuntime.NaNobj,
- ScriptableObject.DONTENUM);
- ScriptableObject.defineProperty(
- scope, "Infinity",
- ScriptRuntime.wrapNumber(Double.POSITIVE_INFINITY),
- ScriptableObject.DONTENUM);
- ScriptableObject.defineProperty(
- scope, "undefined", Undefined.instance,
- ScriptableObject.DONTENUM);
-
- String[] errorMethods = Kit.semicolonSplit(""
- +"ConversionError;"
- +"EvalError;"
- +"RangeError;"
- +"ReferenceError;"
- +"SyntaxError;"
- +"TypeError;"
- +"URIError;"
- +"InternalError;"
- +"JavaException;"
- );
-
- /*
- Each error constructor gets its own Error object as a prototype,
- with the 'name' property set to the name of the error.
- */
- for (int i = 0; i < errorMethods.length; i++) {
- String name = errorMethods[i];
- Scriptable errorProto = ScriptRuntime.
- newObject(cx, scope, "Error",
- ScriptRuntime.emptyArgs);
- errorProto.put("name", errorProto, name);
- if (sealed) {
- if (errorProto instanceof ScriptableObject) {
- ((ScriptableObject)errorProto).sealObject();
- }
- }
- IdFunctionObject ctor = new IdFunctionObject(obj, FTAG,
- Id_new_CommonError,
- name, 1, scope);
- ctor.markAsConstructor(errorProto);
- if (sealed) {
- ctor.sealObject();
- }
- ctor.exportAsScopeProperty();
- }
- }
-
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (f.hasTag(FTAG)) {
- int methodId = f.methodId();
- switch (methodId) {
- case Id_decodeURI:
- case Id_decodeURIComponent: {
- String str = ScriptRuntime.toString(args, 0);
- return decode(str, methodId == Id_decodeURI);
- }
-
- case Id_encodeURI:
- case Id_encodeURIComponent: {
- String str = ScriptRuntime.toString(args, 0);
- return encode(str, methodId == Id_encodeURI);
- }
-
- case Id_escape:
- return js_escape(args);
-
- case Id_eval:
- return js_eval(cx, scope, args);
-
- case Id_isFinite: {
- boolean result;
- if (args.length < 1) {
- result = false;
- } else {
- double d = ScriptRuntime.toNumber(args[0]);
- result = (d == d
- && d != Double.POSITIVE_INFINITY
- && d != Double.NEGATIVE_INFINITY);
- }
- return ScriptRuntime.wrapBoolean(result);
- }
-
- case Id_isNaN: {
- // The global method isNaN, as per ECMA-262 15.1.2.6.
- boolean result;
- if (args.length < 1) {
- result = true;
- } else {
- double d = ScriptRuntime.toNumber(args[0]);
- result = (d != d);
- }
- return ScriptRuntime.wrapBoolean(result);
- }
-
- case Id_isXMLName: {
- Object name = (args.length == 0)
- ? Undefined.instance : args[0];
- XMLLib xmlLib = XMLLib.extractFromScope(scope);
- return ScriptRuntime.wrapBoolean(
- xmlLib.isXMLName(cx, name));
- }
-
- case Id_parseFloat:
- return js_parseFloat(args);
-
- case Id_parseInt:
- return js_parseInt(args);
-
- case Id_unescape:
- return js_unescape(args);
-
- case Id_uneval: {
- Object value = (args.length != 0)
- ? args[0] : Undefined.instance;
- return ScriptRuntime.uneval(cx, scope, value);
- }
-
- case Id_new_CommonError:
- // The implementation of all the ECMA error constructors
- // (SyntaxError, TypeError, etc.)
- return NativeError.make(cx, scope, f, args);
- }
- }
- throw f.unknown();
- }
-
- /**
- * The global method parseInt, as per ECMA-262 15.1.2.2.
- */
- private Object js_parseInt(Object[] args) {
- String s = ScriptRuntime.toString(args, 0);
- int radix = ScriptRuntime.toInt32(args, 1);
-
- int len = s.length();
- if (len == 0)
- return ScriptRuntime.NaNobj;
-
- boolean negative = false;
- int start = 0;
- char c;
- do {
- c = s.charAt(start);
- if (!Character.isWhitespace(c))
- break;
- start++;
- } while (start < len);
-
- if (c == '+' || (negative = (c == '-')))
- start++;
-
- final int NO_RADIX = -1;
- if (radix == 0) {
- radix = NO_RADIX;
- } else if (radix < 2 || radix > 36) {
- return ScriptRuntime.NaNobj;
- } else if (radix == 16 && len - start > 1 && s.charAt(start) == '0') {
- c = s.charAt(start+1);
- if (c == 'x' || c == 'X')
- start += 2;
- }
-
- if (radix == NO_RADIX) {
- radix = 10;
- if (len - start > 1 && s.charAt(start) == '0') {
- c = s.charAt(start+1);
- if (c == 'x' || c == 'X') {
- radix = 16;
- start += 2;
- } else if ('0' <= c && c <= '9') {
- radix = 8;
- start++;
- }
- }
- }
-
- double d = ScriptRuntime.stringToNumber(s, start, radix);
- return ScriptRuntime.wrapNumber(negative ? -d : d);
- }
-
- /**
- * The global method parseFloat, as per ECMA-262 15.1.2.3.
- *
- * @param args the arguments to parseFloat, ignoring args[>=1]
- */
- private Object js_parseFloat(Object[] args)
- {
- if (args.length < 1)
- return ScriptRuntime.NaNobj;
-
- String s = ScriptRuntime.toString(args[0]);
- int len = s.length();
- int start = 0;
- // Scan forward to skip whitespace
- char c;
- for (;;) {
- if (start == len) {
- return ScriptRuntime.NaNobj;
- }
- c = s.charAt(start);
- if (!TokenStream.isJSSpace(c)) {
- break;
- }
- ++start;
- }
-
- int i = start;
- if (c == '+' || c == '-') {
- ++i;
- if (i == len) {
- return ScriptRuntime.NaNobj;
- }
- c = s.charAt(i);
- }
-
- if (c == 'I') {
- // check for "Infinity"
- if (i+8 <= len && s.regionMatches(i, "Infinity", 0, 8)) {
- double d;
- if (s.charAt(start) == '-') {
- d = Double.NEGATIVE_INFINITY;
- } else {
- d = Double.POSITIVE_INFINITY;
- }
- return ScriptRuntime.wrapNumber(d);
- }
- return ScriptRuntime.NaNobj;
- }
-
- // Find the end of the legal bit
- int decimal = -1;
- int exponent = -1;
- for (; i < len; i++) {
- switch (s.charAt(i)) {
- case '.':
- if (decimal != -1) // Only allow a single decimal point.
- break;
- decimal = i;
- continue;
-
- case 'e':
- case 'E':
- if (exponent != -1)
- break;
- exponent = i;
- continue;
-
- case '+':
- case '-':
- // Only allow '+' or '-' after 'e' or 'E'
- if (exponent != i-1)
- break;
- continue;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- continue;
-
- default:
- break;
- }
- break;
- }
- s = s.substring(start, i);
- try {
- return Double.valueOf(s);
- }
- catch (NumberFormatException ex) {
- return ScriptRuntime.NaNobj;
- }
- }
-
- /**
- * The global method escape, as per ECMA-262 15.1.2.4.
-
- * Includes code for the 'mask' argument supported by the C escape
- * method, which used to be part of the browser imbedding. Blame
- * for the strange constant names should be directed there.
- */
-
- private Object js_escape(Object[] args) {
- final int
- URL_XALPHAS = 1,
- URL_XPALPHAS = 2,
- URL_PATH = 4;
-
- String s = ScriptRuntime.toString(args, 0);
-
- int mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH;
- if (args.length > 1) { // the 'mask' argument. Non-ECMA.
- double d = ScriptRuntime.toNumber(args[1]);
- if (d != d || ((mask = (int) d) != d) ||
- 0 != (mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH)))
- {
- throw Context.reportRuntimeError0("msg.bad.esc.mask");
- }
- }
-
- StringBuffer sb = null;
- for (int k = 0, L = s.length(); k != L; ++k) {
- int c = s.charAt(k);
- if (mask != 0
- && ((c >= '0' && c <= '9')
- || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
- || c == '@' || c == '*' || c == '_' || c == '-' || c == '.'
- || (0 != (mask & URL_PATH) && (c == '/' || c == '+'))))
- {
- if (sb != null) {
- sb.append((char)c);
- }
- } else {
- if (sb == null) {
- sb = new StringBuffer(L + 3);
- sb.append(s);
- sb.setLength(k);
- }
-
- int hexSize;
- if (c < 256) {
- if (c == ' ' && mask == URL_XPALPHAS) {
- sb.append('+');
- continue;
- }
- sb.append('%');
- hexSize = 2;
- } else {
- sb.append('%');
- sb.append('u');
- hexSize = 4;
- }
-
- // append hexadecimal form of c left-padded with 0
- for (int shift = (hexSize - 1) * 4; shift >= 0; shift -= 4) {
- int digit = 0xf & (c >> shift);
- int hc = (digit < 10) ? '0' + digit : 'A' - 10 + digit;
- sb.append((char)hc);
- }
- }
- }
-
- return (sb == null) ? s : sb.toString();
- }
-
- /**
- * The global unescape method, as per ECMA-262 15.1.2.5.
- */
-
- private Object js_unescape(Object[] args)
- {
- String s = ScriptRuntime.toString(args, 0);
- int firstEscapePos = s.indexOf('%');
- if (firstEscapePos >= 0) {
- int L = s.length();
- char[] buf = s.toCharArray();
- int destination = firstEscapePos;
- for (int k = firstEscapePos; k != L;) {
- char c = buf[k];
- ++k;
- if (c == '%' && k != L) {
- int end, start;
- if (buf[k] == 'u') {
- start = k + 1;
- end = k + 5;
- } else {
- start = k;
- end = k + 2;
- }
- if (end <= L) {
- int x = 0;
- for (int i = start; i != end; ++i) {
- x = Kit.xDigitToInt(buf[i], x);
- }
- if (x >= 0) {
- c = (char)x;
- k = end;
- }
- }
- }
- buf[destination] = c;
- ++destination;
- }
- s = new String(buf, 0, destination);
- }
- return s;
- }
-
- private Object js_eval(Context cx, Scriptable scope, Object[] args)
- {
- String m = ScriptRuntime.getMessage1("msg.cant.call.indirect", "eval");
- throw NativeGlobal.constructError(cx, "EvalError", m, scope);
- }
-
- static boolean isEvalFunction(Object functionObj)
- {
- if (functionObj instanceof IdFunctionObject) {
- IdFunctionObject function = (IdFunctionObject)functionObj;
- if (function.hasTag(FTAG) && function.methodId() == Id_eval) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * @deprecated Use {@link ScriptRuntime#constructError(String,String)}
- * instead.
- */
- public static EcmaError constructError(Context cx,
- String error,
- String message,
- Scriptable scope)
- {
- return ScriptRuntime.constructError(error, message);
- }
-
- /**
- * @deprecated Use
- * {@link ScriptRuntime#constructError(String,String,String,int,String,int)}
- * instead.
- */
- public static EcmaError constructError(Context cx,
- String error,
- String message,
- Scriptable scope,
- String sourceName,
- int lineNumber,
- int columnNumber,
- String lineSource)
- {
- return ScriptRuntime.constructError(error, message,
- sourceName, lineNumber,
- lineSource, columnNumber);
- }
-
- /*
- * ECMA 3, 15.1.3 URI Handling Function Properties
- *
- * The following are implementations of the algorithms
- * given in the ECMA specification for the hidden functions
- * 'Encode' and 'Decode'.
- */
- private static String encode(String str, boolean fullUri) {
- byte[] utf8buf = null;
- StringBuffer sb = null;
-
- for (int k = 0, length = str.length(); k != length; ++k) {
- char C = str.charAt(k);
- if (encodeUnescaped(C, fullUri)) {
- if (sb != null) {
- sb.append(C);
- }
- } else {
- if (sb == null) {
- sb = new StringBuffer(length + 3);
- sb.append(str);
- sb.setLength(k);
- utf8buf = new byte[6];
- }
- if (0xDC00 <= C && C <= 0xDFFF) {
- throw Context.reportRuntimeError0("msg.bad.uri");
- }
- int V;
- if (C < 0xD800 || 0xDBFF < C) {
- V = C;
- } else {
- k++;
- if (k == length) {
- throw Context.reportRuntimeError0("msg.bad.uri");
- }
- char C2 = str.charAt(k);
- if (!(0xDC00 <= C2 && C2 <= 0xDFFF)) {
- throw Context.reportRuntimeError0("msg.bad.uri");
- }
- V = ((C - 0xD800) << 10) + (C2 - 0xDC00) + 0x10000;
- }
- int L = oneUcs4ToUtf8Char(utf8buf, V);
- for (int j = 0; j < L; j++) {
- int d = 0xff & utf8buf[j];
- sb.append('%');
- sb.append(toHexChar(d >>> 4));
- sb.append(toHexChar(d & 0xf));
- }
- }
- }
- return (sb == null) ? str : sb.toString();
- }
-
- private static char toHexChar(int i) {
- if (i >> 4 != 0) Kit.codeBug();
- return (char)((i < 10) ? i + '0' : i - 10 + 'a');
- }
-
- private static int unHex(char c) {
- if ('A' <= c && c <= 'F') {
- return c - 'A' + 10;
- } else if ('a' <= c && c <= 'f') {
- return c - 'a' + 10;
- } else if ('0' <= c && c <= '9') {
- return c - '0';
- } else {
- return -1;
- }
- }
-
- private static int unHex(char c1, char c2) {
- int i1 = unHex(c1);
- int i2 = unHex(c2);
- if (i1 >= 0 && i2 >= 0) {
- return (i1 << 4) | i2;
- }
- return -1;
- }
-
- private static String decode(String str, boolean fullUri) {
- char[] buf = null;
- int bufTop = 0;
-
- for (int k = 0, length = str.length(); k != length;) {
- char C = str.charAt(k);
- if (C != '%') {
- if (buf != null) {
- buf[bufTop++] = C;
- }
- ++k;
- } else {
- if (buf == null) {
- // decode always compress so result can not be bigger then
- // str.length()
- buf = new char[length];
- str.getChars(0, k, buf, 0);
- bufTop = k;
- }
- int start = k;
- if (k + 3 > length)
- throw Context.reportRuntimeError0("msg.bad.uri");
- int B = unHex(str.charAt(k + 1), str.charAt(k + 2));
- if (B < 0) throw Context.reportRuntimeError0("msg.bad.uri");
- k += 3;
- if ((B & 0x80) == 0) {
- C = (char)B;
- } else {
- // Decode UTF-8 sequence into ucs4Char and encode it into
- // UTF-16
- int utf8Tail, ucs4Char, minUcs4Char;
- if ((B & 0xC0) == 0x80) {
- // First UTF-8 should be ouside 0x80..0xBF
- throw Context.reportRuntimeError0("msg.bad.uri");
- } else if ((B & 0x20) == 0) {
- utf8Tail = 1; ucs4Char = B & 0x1F;
- minUcs4Char = 0x80;
- } else if ((B & 0x10) == 0) {
- utf8Tail = 2; ucs4Char = B & 0x0F;
- minUcs4Char = 0x800;
- } else if ((B & 0x08) == 0) {
- utf8Tail = 3; ucs4Char = B & 0x07;
- minUcs4Char = 0x10000;
- } else if ((B & 0x04) == 0) {
- utf8Tail = 4; ucs4Char = B & 0x03;
- minUcs4Char = 0x200000;
- } else if ((B & 0x02) == 0) {
- utf8Tail = 5; ucs4Char = B & 0x01;
- minUcs4Char = 0x4000000;
- } else {
- // First UTF-8 can not be 0xFF or 0xFE
- throw Context.reportRuntimeError0("msg.bad.uri");
- }
- if (k + 3 * utf8Tail > length)
- throw Context.reportRuntimeError0("msg.bad.uri");
- for (int j = 0; j != utf8Tail; j++) {
- if (str.charAt(k) != '%')
- throw Context.reportRuntimeError0("msg.bad.uri");
- B = unHex(str.charAt(k + 1), str.charAt(k + 2));
- if (B < 0 || (B & 0xC0) != 0x80)
- throw Context.reportRuntimeError0("msg.bad.uri");
- ucs4Char = (ucs4Char << 6) | (B & 0x3F);
- k += 3;
- }
- // Check for overlongs and other should-not-present codes
- if (ucs4Char < minUcs4Char
- || ucs4Char == 0xFFFE || ucs4Char == 0xFFFF)
- {
- ucs4Char = 0xFFFD;
- }
- if (ucs4Char >= 0x10000) {
- ucs4Char -= 0x10000;
- if (ucs4Char > 0xFFFFF)
- throw Context.reportRuntimeError0("msg.bad.uri");
- char H = (char)((ucs4Char >>> 10) + 0xD800);
- C = (char)((ucs4Char & 0x3FF) + 0xDC00);
- buf[bufTop++] = H;
- } else {
- C = (char)ucs4Char;
- }
- }
- if (fullUri && URI_DECODE_RESERVED.indexOf(C) >= 0) {
- for (int x = start; x != k; x++) {
- buf[bufTop++] = str.charAt(x);
- }
- } else {
- buf[bufTop++] = C;
- }
- }
- }
- return (buf == null) ? str : new String(buf, 0, bufTop);
- }
-
- private static boolean encodeUnescaped(char c, boolean fullUri) {
- if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')
- || ('0' <= c && c <= '9'))
- {
- return true;
- }
- if ("-_.!~*'()".indexOf(c) >= 0)
- return true;
- if (fullUri) {
- return URI_DECODE_RESERVED.indexOf(c) >= 0;
- }
- return false;
- }
-
- private static final String URI_DECODE_RESERVED = ";/?:@&=+$,#";
-
- /* Convert one UCS-4 char and write it into a UTF-8 buffer, which must be
- * at least 6 bytes long. Return the number of UTF-8 bytes of data written.
- */
- private static int oneUcs4ToUtf8Char(byte[] utf8Buffer, int ucs4Char) {
- int utf8Length = 1;
-
- //JS_ASSERT(ucs4Char <= 0x7FFFFFFF);
- if ((ucs4Char & ~0x7F) == 0)
- utf8Buffer[0] = (byte)ucs4Char;
- else {
- int i;
- int a = ucs4Char >>> 11;
- utf8Length = 2;
- while (a != 0) {
- a >>>= 5;
- utf8Length++;
- }
- i = utf8Length;
- while (--i > 0) {
- utf8Buffer[i] = (byte)((ucs4Char & 0x3F) | 0x80);
- ucs4Char >>>= 6;
- }
- utf8Buffer[0] = (byte)(0x100 - (1 << (8-utf8Length)) + ucs4Char);
- }
- return utf8Length;
- }
-
- private static final Object FTAG = new Object();
-
- private static final int
- Id_decodeURI = 1,
- Id_decodeURIComponent = 2,
- Id_encodeURI = 3,
- Id_encodeURIComponent = 4,
- Id_escape = 5,
- Id_eval = 6,
- Id_isFinite = 7,
- Id_isNaN = 8,
- Id_isXMLName = 9,
- Id_parseFloat = 10,
- Id_parseInt = 11,
- Id_unescape = 12,
- Id_uneval = 13,
-
- LAST_SCOPE_FUNCTION_ID = 13,
-
- Id_new_CommonError = 14;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeIterator.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeIterator.java
deleted file mode 100644
index c61f417..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeIterator.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/* -*- 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.
- *
- * Contributor(s):
- * Norris Boyd
- *
- * 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;
-
-import java.util.Iterator;
-
-/**
- * This class implements iterator objects. See
- * http://developer.mozilla.org/en/docs/New_in_JavaScript_1.7#Iterators
- *
- * @author Norris Boyd
- */
-public final class NativeIterator extends IdScriptableObject {
- private static final Object ITERATOR_TAG = new Object();
-
- static void init(ScriptableObject scope, boolean sealed) {
- // Iterator
- NativeIterator iterator = new NativeIterator();
- iterator.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
-
- // Generator
- NativeGenerator.init(scope, sealed);
-
- // StopIteration
- NativeObject obj = new StopIteration();
- obj.setPrototype(getObjectPrototype(scope));
- obj.setParentScope(scope);
- if (sealed) { obj.sealObject(); }
- ScriptableObject.defineProperty(scope, STOP_ITERATION, obj,
- ScriptableObject.DONTENUM);
- // Use "associateValue" so that generators can continue to
- // throw StopIteration even if the property of the global
- // scope is replaced or deleted.
- scope.associateValue(ITERATOR_TAG, obj);
- }
-
- /**
- * Only for constructing the prototype object.
- */
- private NativeIterator() {
- }
-
- private NativeIterator(Object objectIterator) {
- this.objectIterator = objectIterator;
- }
-
- /**
- * Get the value of the "StopIteration" object. Note that this value
- * is stored in the top-level scope using "associateValue" so the
- * value can still be found even if a script overwrites or deletes
- * the global "StopIteration" property.
- * @param scope a scope whose parent chain reaches a top-level scope
- * @return the StopIteration object
- */
- public static Object getStopIterationObject(Scriptable scope) {
- Scriptable top = ScriptableObject.getTopLevelScope(scope);
- return ScriptableObject.getTopScopeValue(top, ITERATOR_TAG);
- }
-
- private static final String STOP_ITERATION = "StopIteration";
- public static final String ITERATOR_PROPERTY_NAME = "__iterator__";
-
- static class StopIteration extends NativeObject {
- public String getClassName() {
- return STOP_ITERATION;
- }
-
- /* StopIteration has custom instanceof behavior since it
- * doesn't have a constructor.
- */
- public boolean hasInstance(Scriptable instance) {
- return instance instanceof StopIteration;
- }
- }
-
- public String getClassName() {
- return "Iterator";
- }
-
- protected void initPrototypeId(int id) {
- String s;
- int arity;
- switch (id) {
- case Id_constructor: arity=2; s="constructor"; break;
- case Id_next: arity=0; s="next"; break;
- case Id___iterator__: arity=1; s=ITERATOR_PROPERTY_NAME; break;
- default: throw new IllegalArgumentException(String.valueOf(id));
- }
- initPrototypeMethod(ITERATOR_TAG, id, s, arity);
- }
-
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(ITERATOR_TAG)) {
- return super.execIdCall(f, cx, scope, thisObj, args);
- }
- int id = f.methodId();
-
- if (id == Id_constructor) {
- return jsConstructor(cx, scope, thisObj, args);
- }
-
- if (!(thisObj instanceof NativeIterator))
- throw incompatibleCallError(f);
-
- NativeIterator iterator = (NativeIterator) thisObj;
-
- switch (id) {
-
- case Id_next:
- return iterator.next(cx, scope);
-
- case Id___iterator__:
- /// XXX: what about argument? SpiderMonkey apparently ignores it
- return thisObj;
-
- default:
- throw new IllegalArgumentException(String.valueOf(id));
- }
- }
-
- /* the javascript constructor */
- private static Object jsConstructor(Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (args.length == 0 || args[0] == null ||
- args[0] == Undefined.instance)
- {
- throw ScriptRuntime.typeError1("msg.no.properties",
- ScriptRuntime.toString(args[0]));
- }
- Scriptable obj = ScriptRuntime.toObject(scope, args[0]);
- boolean keyOnly = args.length > 1 && ScriptRuntime.toBoolean(args[1]);
- if (thisObj != null) {
- // Called as a function. Convert to iterator if possible.
-
- // For objects that implement java.lang.Iterable or
- // java.util.Iterator, have JavaScript Iterator call the underlying
- // iteration methods
- Iterator iterator =
- VMBridge.instance.getJavaIterator(cx, scope, obj);
- if (iterator != null) {
- scope = ScriptableObject.getTopLevelScope(scope);
- return cx.getWrapFactory().wrap(cx, scope,
- new WrappedJavaIterator(iterator, scope),
- WrappedJavaIterator.class);
- }
-
- // Otherwise, just call the runtime routine
- Scriptable jsIterator = ScriptRuntime.toIterator(cx, scope, obj,
- keyOnly);
- if (jsIterator != null) {
- return jsIterator;
- }
- }
-
- // Otherwise, just set up to iterate over the properties of the object.
- // Do not call __iterator__ method.
- Object objectIterator = ScriptRuntime.enumInit(obj, cx,
- keyOnly ? ScriptRuntime.ENUMERATE_KEYS_NO_ITERATOR
- : ScriptRuntime.ENUMERATE_ARRAY_NO_ITERATOR);
- ScriptRuntime.setEnumNumbers(objectIterator, true);
- NativeIterator result = new NativeIterator(objectIterator);
- result.setPrototype(NativeIterator.getClassPrototype(scope,
- result.getClassName()));
- result.setParentScope(scope);
- return result;
- }
-
- private Object next(Context cx, Scriptable scope) {
- Boolean b = ScriptRuntime.enumNext(this.objectIterator);
- if (!b.booleanValue()) {
- // Out of values. Throw StopIteration.
- throw new JavaScriptException(
- NativeIterator.getStopIterationObject(scope), null, 0);
- }
- return ScriptRuntime.enumId(this.objectIterator, cx);
- }
-
- static public class WrappedJavaIterator
- {
- WrappedJavaIterator(Iterator iterator, Scriptable scope) {
- this.iterator = iterator;
- this.scope = scope;
- }
-
- public Object next() {
- if (!iterator.hasNext()) {
- // Out of values. Throw StopIteration.
- throw new JavaScriptException(
- NativeIterator.getStopIterationObject(scope), null, 0);
- }
- return iterator.next();
- }
-
- public Object __iterator__(boolean b) {
- return this;
- }
-
- private Iterator iterator;
- private Scriptable scope;
- }
-
-// #string_id_map#
-
- protected int findPrototypeId(String s) {
- int id;
-// #generated# Last update: 2007-06-11 09:43:19 EDT
- L0: { id = 0; String X = null;
- int s_length = s.length();
- if (s_length==4) { X="next";id=Id_next; }
- else if (s_length==11) { X="constructor";id=Id_constructor; }
- else if (s_length==12) { X="__iterator__";id=Id___iterator__; }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- Id_constructor = 1,
- Id_next = 2,
- Id___iterator__ = 3,
- MAX_PROTOTYPE_ID = 3;
-
-// #/string_id_map#
-
- private Object objectIterator;
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaArray.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaArray.java
deleted file mode 100644
index 2f711a0..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaArray.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- 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
- * Frank Mitchell
- * Mike Shaver
- * Kemal Bayram
- *
- * 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;
-
-import java.lang.reflect.Array;
-
-/**
- * This class reflects Java arrays into the JavaScript environment.
- *
- * @author Mike Shaver
- * @see NativeJavaClass
- * @see NativeJavaObject
- * @see NativeJavaPackage
- */
-
-public class NativeJavaArray extends NativeJavaObject
-{
- static final long serialVersionUID = -924022554283675333L;
-
- public String getClassName() {
- return "JavaArray";
- }
-
- public static NativeJavaArray wrap(Scriptable scope, Object array) {
- return new NativeJavaArray(scope, array);
- }
-
- public Object unwrap() {
- return array;
- }
-
- public NativeJavaArray(Scriptable scope, Object array) {
- super(scope, null, ScriptRuntime.ObjectClass);
- Class cl = array.getClass();
- if (!cl.isArray()) {
- throw new RuntimeException("Array expected");
- }
- this.array = array;
- this.length = Array.getLength(array);
- this.cls = cl.getComponentType();
- }
-
- public boolean has(String id, Scriptable start) {
- return id.equals("length") || super.has(id, start);
- }
-
- public boolean has(int index, Scriptable start) {
- return 0 <= index && index < length;
- }
-
- public Object get(String id, Scriptable start) {
- if (id.equals("length"))
- return new Integer(length);
- Object result = super.get(id, start);
- if (result == NOT_FOUND &&
- !ScriptableObject.hasProperty(getPrototype(), id))
- {
- throw Context.reportRuntimeError2(
- "msg.java.member.not.found", array.getClass().getName(), id);
- }
- return result;
- }
-
- public Object get(int index, Scriptable start) {
- if (0 <= index && index < length) {
- Context cx = Context.getContext();
- Object obj = Array.get(array, index);
- return cx.getWrapFactory().wrap(cx, this, obj, cls);
- }
- return Undefined.instance;
- }
-
- public void put(String id, Scriptable start, Object value) {
- // Ignore assignments to "length"--it's readonly.
- if (!id.equals("length"))
- throw Context.reportRuntimeError1(
- "msg.java.array.member.not.found", id);
- }
-
- public void put(int index, Scriptable start, Object value) {
- if (0 <= index && index < length) {
- Array.set(array, index, Context.jsToJava(value, cls));
- }
- else {
- throw Context.reportRuntimeError2(
- "msg.java.array.index.out.of.bounds", String.valueOf(index),
- String.valueOf(length - 1));
- }
- }
-
- public Object getDefaultValue(Class hint) {
- if (hint == null || hint == ScriptRuntime.StringClass)
- return array.toString();
- if (hint == ScriptRuntime.BooleanClass)
- return Boolean.TRUE;
- if (hint == ScriptRuntime.NumberClass)
- return ScriptRuntime.NaNobj;
- return this;
- }
-
- public Object[] getIds() {
- Object[] result = new Object[length];
- int i = length;
- while (--i >= 0)
- result[i] = new Integer(i);
- return result;
- }
-
- public boolean hasInstance(Scriptable value) {
- if (!(value instanceof Wrapper))
- return false;
- Object instance = ((Wrapper)value).unwrap();
- return cls.isInstance(instance);
- }
-
- public Scriptable getPrototype() {
- if (prototype == null) {
- prototype =
- ScriptableObject.getClassPrototype(this.getParentScope(),
- "Array");
- }
- return prototype;
- }
-
- Object array;
- int length;
- Class cls;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaClass.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaClass.java
deleted file mode 100644
index ab8af5c..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaClass.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/* -*- 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
- * Frank Mitchell
- * Mike Shaver
- * Kurt Westerfeld
- * Kemal Bayram
- * Ulrike Mueller <umueller@demandware.com>
- *
- * 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;
-
-import java.lang.reflect.*;
-import java.util.Hashtable;
-
-/**
- * This class reflects Java classes into the JavaScript environment, mainly
- * for constructors and static members. We lazily reflect properties,
- * and currently do not guarantee that a single j.l.Class is only
- * reflected once into the JS environment, although we should.
- * The only known case where multiple reflections
- * are possible occurs when a j.l.Class is wrapped as part of a
- * method return or property access, rather than by walking the
- * Packages/java tree.
- *
- * @author Mike Shaver
- * @see NativeJavaArray
- * @see NativeJavaObject
- * @see NativeJavaPackage
- */
-
-public class NativeJavaClass extends NativeJavaObject implements Function
-{
- static final long serialVersionUID = -6460763940409461664L;
-
- // Special property for getting the underlying Java class object.
- static final String javaClassPropertyName = "__javaObject__";
-
- public NativeJavaClass() {
- }
-
- public NativeJavaClass(Scriptable scope, Class cl) {
- this.parent = scope;
- this.javaObject = cl;
- initMembers();
- }
-
- protected void initMembers() {
- Class cl = (Class)javaObject;
- members = JavaMembers.lookupClass(parent, cl, cl, false);
- staticFieldAndMethods
- = members.getFieldAndMethodsObjects(this, cl, true);
- }
-
- public String getClassName() {
- return "JavaClass";
- }
-
- public boolean has(String name, Scriptable start) {
- return members.has(name, true) || javaClassPropertyName.equals(name);
- }
-
- public Object get(String name, Scriptable start) {
- // When used as a constructor, ScriptRuntime.newObject() asks
- // for our prototype to create an object of the correct type.
- // We don't really care what the object is, since we're returning
- // one constructed out of whole cloth, so we return null.
- if (name.equals("prototype"))
- return null;
-
- if (staticFieldAndMethods != null) {
- Object result = staticFieldAndMethods.get(name);
- if (result != null)
- return result;
- }
-
- if (members.has(name, true)) {
- return members.get(this, name, javaObject, true);
- }
-
- if (javaClassPropertyName.equals(name)) {
- Context cx = Context.getContext();
- Scriptable scope = ScriptableObject.getTopLevelScope(start);
- return cx.getWrapFactory().wrap(cx, scope, javaObject,
- ScriptRuntime.ClassClass);
- }
-
- // experimental: look for nested classes by appending $name to
- // current class' name.
- Class nestedClass = findNestedClass(getClassObject(), name);
- if (nestedClass != null) {
- NativeJavaClass nestedValue = new NativeJavaClass
- (ScriptableObject.getTopLevelScope(this), nestedClass);
- nestedValue.setParentScope(this);
- return nestedValue;
- }
-
- throw members.reportMemberNotFound(name);
- }
-
- public void put(String name, Scriptable start, Object value) {
- members.put(this, name, javaObject, value, true);
- }
-
- public Object[] getIds() {
- return members.getIds(true);
- }
-
- public Class getClassObject() {
- return (Class) super.unwrap();
- }
-
- public Object getDefaultValue(Class hint) {
- if (hint == null || hint == ScriptRuntime.StringClass)
- return this.toString();
- if (hint == ScriptRuntime.BooleanClass)
- return Boolean.TRUE;
- if (hint == ScriptRuntime.NumberClass)
- return ScriptRuntime.NaNobj;
- return this;
- }
-
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- // If it looks like a "cast" of an object to this class type,
- // walk the prototype chain to see if there's a wrapper of a
- // object that's an instanceof this class.
- if (args.length == 1 && args[0] instanceof Scriptable) {
- Class c = getClassObject();
- Scriptable p = (Scriptable) args[0];
- do {
- if (p instanceof Wrapper) {
- Object o = ((Wrapper) p).unwrap();
- if (c.isInstance(o))
- return p;
- }
- p = p.getPrototype();
- } while (p != null);
- }
- return construct(cx, scope, args);
- }
-
- public Scriptable construct(Context cx, Scriptable scope, Object[] args)
- {
- Class classObject = getClassObject();
- int modifiers = classObject.getModifiers();
- if (! (Modifier.isInterface(modifiers) ||
- Modifier.isAbstract(modifiers)))
- {
- MemberBox[] ctors = members.ctors;
- int index = NativeJavaMethod.findFunction(cx, ctors, args);
- if (index < 0) {
- String sig = NativeJavaMethod.scriptSignature(args);
- throw Context.reportRuntimeError2(
- "msg.no.java.ctor", classObject.getName(), sig);
- }
-
- // Found the constructor, so try invoking it.
- return constructSpecific(cx, scope, args, ctors[index]);
- } else {
- Scriptable topLevel = ScriptableObject.getTopLevelScope(this);
- String msg = "";
- try {
- // trying to construct an interface; use JavaAdapter to
- // construct a new class on the fly that implements this
- // interface.
- Object v = topLevel.get("JavaAdapter", topLevel);
- if (v != NOT_FOUND) {
- Function f = (Function) v;
- Object[] adapterArgs = { this, args[0] };
- return f.construct(cx, topLevel,adapterArgs);
- }
- } catch (Exception ex) {
- // fall through to error
- String m = ex.getMessage();
- if (m != null)
- msg = m;
- }
- throw Context.reportRuntimeError2(
- "msg.cant.instantiate", msg, classObject.getName());
- }
- }
-
- static Scriptable constructSpecific(Context cx, Scriptable scope,
- Object[] args, MemberBox ctor)
- {
- Scriptable topLevel = ScriptableObject.getTopLevelScope(scope);
- Class[] argTypes = ctor.argTypes;
-
- if (ctor.vararg) {
- // marshall the explicit parameter
- Object[] newArgs = new Object[argTypes.length];
- for (int i = 0; i < argTypes.length-1; i++) {
- newArgs[i] = Context.jsToJava(args[i], argTypes[i]);
- }
-
- Object varArgs;
-
- // Handle special situation where a single variable parameter
- // is given and it is a Java or ECMA array.
- if (args.length == argTypes.length &&
- (args[args.length-1] == null ||
- args[args.length-1] instanceof NativeArray ||
- args[args.length-1] instanceof NativeJavaArray))
- {
- // convert the ECMA array into a native array
- varArgs = Context.jsToJava(args[args.length-1],
- argTypes[argTypes.length - 1]);
- } else {
- // marshall the variable parameter
- Class componentType = argTypes[argTypes.length - 1].
- getComponentType();
- varArgs = Array.newInstance(componentType,
- args.length - argTypes.length + 1);
- for (int i=0; i < Array.getLength(varArgs); i++) {
- Object value = Context.jsToJava(args[argTypes.length-1 + i],
- componentType);
- Array.set(varArgs, i, value);
- }
- }
-
- // add varargs
- newArgs[argTypes.length-1] = varArgs;
- // replace the original args with the new one
- args = newArgs;
- } else {
- Object[] origArgs = args;
- for (int i = 0; i < args.length; i++) {
- Object arg = args[i];
- Object x = Context.jsToJava(arg, argTypes[i]);
- if (x != arg) {
- if (args == origArgs) {
- args = origArgs.clone();
- }
- args[i] = x;
- }
- }
- }
-
- Object instance = ctor.newInstance(args);
- // we need to force this to be wrapped, because construct _has_
- // to return a scriptable
- return cx.getWrapFactory().wrapNewObject(cx, topLevel, instance);
- }
-
- public String toString() {
- return "[JavaClass " + getClassObject().getName() + "]";
- }
-
- /**
- * Determines if prototype is a wrapped Java object and performs
- * a Java "instanceof".
- * Exception: if value is an instance of NativeJavaClass, it isn't
- * considered an instance of the Java class; this forestalls any
- * name conflicts between java.lang.Class's methods and the
- * static methods exposed by a JavaNativeClass.
- */
- public boolean hasInstance(Scriptable value) {
-
- if (value instanceof Wrapper &&
- !(value instanceof NativeJavaClass)) {
- Object instance = ((Wrapper)value).unwrap();
-
- return getClassObject().isInstance(instance);
- }
-
- // value wasn't something we understand
- return false;
- }
-
- private static Class findNestedClass(Class parentClass, String name) {
- String nestedClassName = parentClass.getName() + '$' + name;
- ClassLoader loader = parentClass.getClassLoader();
- if (loader == null) {
- // ALERT: if loader is null, nested class should be loaded
- // via system class loader which can be different from the
- // loader that brought Rhino classes that Class.forName() would
- // use, but ClassLoader.getSystemClassLoader() is Java 2 only
- return Kit.classOrNull(nestedClassName);
- } else {
- return Kit.classOrNull(loader, nestedClassName);
- }
- }
-
- private Hashtable staticFieldAndMethods;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaConstructor.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaConstructor.java
deleted file mode 100644
index 530bf81..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaConstructor.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- 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
- * Frank Mitchell
- * Mike Shaver
- *
- * 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 reflects a single Java constructor into the JavaScript
- * environment. It satisfies a request for an overloaded constructor,
- * as introduced in LiveConnect 3.
- * All NativeJavaConstructors behave as JSRef `bound' methods, in that they
- * always construct the same NativeJavaClass regardless of any reparenting
- * that may occur.
- *
- * @author Frank Mitchell
- * @see NativeJavaMethod
- * @see NativeJavaPackage
- * @see NativeJavaClass
- */
-
-public class NativeJavaConstructor extends BaseFunction
-{
- static final long serialVersionUID = -8149253217482668463L;
-
- MemberBox ctor;
-
- public NativeJavaConstructor(MemberBox ctor)
- {
- this.ctor = ctor;
- }
-
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- return NativeJavaClass.constructSpecific(cx, scope, args, ctor);
- }
-
- public String getFunctionName()
- {
- String sig = JavaMembers.liveConnectSignature(ctor.argTypes);
- return "<init>".concat(sig);
- }
-
- public String toString()
- {
- return "[JavaConstructor " + ctor.getName() + "]";
- }
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaMethod.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaMethod.java
deleted file mode 100644
index eb66f40..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaMethod.java
+++ /dev/null
@@ -1,576 +0,0 @@
-/* -*- 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
- * Frank Mitchell
- * Mike Shaver
- * Ulrike Mueller <umueller@demandware.com>
- *
- * 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;
-
-import java.lang.reflect.*;
-
-/**
- * This class reflects Java methods into the JavaScript environment and
- * handles overloading of methods.
- *
- * @author Mike Shaver
- * @see NativeJavaArray
- * @see NativeJavaPackage
- * @see NativeJavaClass
- */
-
-public class NativeJavaMethod extends BaseFunction
-{
- static final long serialVersionUID = -3440381785576412928L;
-
- NativeJavaMethod(MemberBox[] methods)
- {
- this.functionName = methods[0].getName();
- this.methods = methods;
- }
-
- NativeJavaMethod(MemberBox method, String name)
- {
- this.functionName = name;
- this.methods = new MemberBox[] { method };
- }
-
- public NativeJavaMethod(Method method, String name)
- {
- this(new MemberBox(method), name);
- }
-
- public String getFunctionName()
- {
- return functionName;
- }
-
- static String scriptSignature(Object[] values)
- {
- StringBuffer sig = new StringBuffer();
- for (int i = 0; i != values.length; ++i) {
- Object value = values[i];
-
- String s;
- if (value == null) {
- s = "null";
- } else if (value instanceof Boolean) {
- s = "boolean";
- } else if (value instanceof String) {
- s = "string";
- } else if (value instanceof Number) {
- s = "number";
- } else if (value instanceof Scriptable) {
- if (value instanceof Undefined) {
- s = "undefined";
- } else if (value instanceof Wrapper) {
- Object wrapped = ((Wrapper)value).unwrap();
- s = wrapped.getClass().getName();
- } else if (value instanceof Function) {
- s = "function";
- } else {
- s = "object";
- }
- } else {
- s = JavaMembers.javaSignature(value.getClass());
- }
-
- if (i != 0) {
- sig.append(',');
- }
- sig.append(s);
- }
- return sig.toString();
- }
-
- 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("/*\n");
- sb.append(toString());
- sb.append(justbody ? "*/\n" : "*/}\n");
- return sb.toString();
- }
-
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
- for (int i = 0, N = methods.length; i != N; ++i) {
- Method method = methods[i].method();
- sb.append(JavaMembers.javaSignature(method.getReturnType()));
- sb.append(' ');
- sb.append(method.getName());
- sb.append(JavaMembers.liveConnectSignature(methods[i].argTypes));
- sb.append('\n');
- }
- return sb.toString();
- }
-
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- // Find a method that matches the types given.
- if (methods.length == 0) {
- throw new RuntimeException("No methods defined for call");
- }
-
- int index = findFunction(cx, methods, args);
- if (index < 0) {
- Class c = methods[0].method().getDeclaringClass();
- String sig = c.getName() + '.' + getFunctionName() + '(' +
- scriptSignature(args) + ')';
- throw Context.reportRuntimeError1("msg.java.no_such_method", sig);
- }
-
- MemberBox meth = methods[index];
- Class[] argTypes = meth.argTypes;
-
- if (meth.vararg) {
- // marshall the explicit parameters
- Object[] newArgs = new Object[argTypes.length];
- for (int i = 0; i < argTypes.length-1; i++) {
- newArgs[i] = Context.jsToJava(args[i], argTypes[i]);
- }
-
- Object varArgs;
-
- // Handle special situation where a single variable parameter
- // is given and it is a Java or ECMA array or is null.
- if (args.length == argTypes.length &&
- (args[args.length-1] == null ||
- args[args.length-1] instanceof NativeArray ||
- args[args.length-1] instanceof NativeJavaArray))
- {
- // convert the ECMA array into a native array
- varArgs = Context.jsToJava(args[args.length-1],
- argTypes[argTypes.length - 1]);
- } else {
- // marshall the variable parameters
- Class componentType = argTypes[argTypes.length - 1].
- getComponentType();
- varArgs = Array.newInstance(componentType,
- args.length - argTypes.length + 1);
- for (int i = 0; i < Array.getLength(varArgs); i++) {
- Object value = Context.jsToJava(args[argTypes.length-1 + i],
- componentType);
- Array.set(varArgs, i, value);
- }
- }
-
- // add varargs
- newArgs[argTypes.length-1] = varArgs;
- // replace the original args with the new one
- args = newArgs;
- } else {
- // First, we marshall the args.
- Object[] origArgs = args;
- for (int i = 0; i < args.length; i++) {
- Object arg = args[i];
- Object coerced = Context.jsToJava(arg, argTypes[i]);
- if (coerced != arg) {
- if (origArgs == args) {
- args = args.clone();
- }
- args[i] = coerced;
- }
- }
- }
- Object javaObject;
- if (meth.isStatic()) {
- javaObject = null; // don't need an object
- } else {
- Scriptable o = thisObj;
- Class c = meth.getDeclaringClass();
- for (;;) {
- if (o == null) {
- throw Context.reportRuntimeError3(
- "msg.nonjava.method", getFunctionName(),
- ScriptRuntime.toString(thisObj), c.getName());
- }
- if (o instanceof Wrapper) {
- javaObject = ((Wrapper)o).unwrap();
- if (c.isInstance(javaObject)) {
- break;
- }
- }
- o = o.getPrototype();
- }
- }
- if (debug) {
- printDebug("Calling ", meth, args);
- }
-
- Object retval = meth.invoke(javaObject, args);
- Class staticType = meth.method().getReturnType();
-
- if (debug) {
- Class actualType = (retval == null) ? null
- : retval.getClass();
- System.err.println(" ----- Returned " + retval +
- " actual = " + actualType +
- " expect = " + staticType);
- }
-
- Object wrapped = cx.getWrapFactory().wrap(cx, scope,
- retval, staticType);
- if (debug) {
- Class actualType = (wrapped == null) ? null
- : wrapped.getClass();
- System.err.println(" ----- Wrapped as " + wrapped +
- " class = " + actualType);
- }
-
- if (wrapped == null && staticType == Void.TYPE) {
- wrapped = Undefined.instance;
- }
- return wrapped;
- }
-
- /**
- * Find the index of the correct function to call given the set of methods
- * or constructors and the arguments.
- * If no function can be found to call, return -1.
- */
- static int findFunction(Context cx,
- MemberBox[] methodsOrCtors, Object[] args)
- {
- if (methodsOrCtors.length == 0) {
- return -1;
- } else if (methodsOrCtors.length == 1) {
- MemberBox member = methodsOrCtors[0];
- Class[] argTypes = member.argTypes;
- int alength = argTypes.length;
-
- if (member.vararg) {
- alength--;
- if ( alength > args.length) {
- return -1;
- }
- } else {
- if (alength != args.length) {
- return -1;
- }
- }
- for (int j = 0; j != alength; ++j) {
- if (!NativeJavaObject.canConvert(args[j], argTypes[j])) {
- if (debug) printDebug("Rejecting (args can't convert) ",
- member, args);
- return -1;
- }
- }
- if (debug) printDebug("Found ", member, args);
- return 0;
- }
-
- int firstBestFit = -1;
- int[] extraBestFits = null;
- int extraBestFitsCount = 0;
-
- search:
- for (int i = 0; i < methodsOrCtors.length; i++) {
- MemberBox member = methodsOrCtors[i];
- Class[] argTypes = member.argTypes;
- int alength = argTypes.length;
- if (member.vararg) {
- alength--;
- if ( alength > args.length) {
- continue search;
- }
- } else {
- if (alength != args.length) {
- continue search;
- }
- }
- for (int j = 0; j < alength; j++) {
- if (!NativeJavaObject.canConvert(args[j], argTypes[j])) {
- if (debug) printDebug("Rejecting (args can't convert) ",
- member, args);
- continue search;
- }
- }
- if (firstBestFit < 0) {
- if (debug) printDebug("Found first applicable ", member, args);
- firstBestFit = i;
- } else {
- // Compare with all currently fit methods.
- // The loop starts from -1 denoting firstBestFit and proceed
- // until extraBestFitsCount to avoid extraBestFits allocation
- // in the most common case of no ambiguity
- int betterCount = 0; // number of times member was prefered over
- // best fits
- int worseCount = 0; // number of times best fits were prefered
- // over member
- for (int j = -1; j != extraBestFitsCount; ++j) {
- int bestFitIndex;
- if (j == -1) {
- bestFitIndex = firstBestFit;
- } else {
- bestFitIndex = extraBestFits[j];
- }
- MemberBox bestFit = methodsOrCtors[bestFitIndex];
- if (cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS) &&
- (bestFit.member().getModifiers() & Modifier.PUBLIC) !=
- (member.member().getModifiers() & Modifier.PUBLIC))
- {
- // When FEATURE_ENHANCED_JAVA_ACCESS gives us access
- // to non-public members, continue to prefer public
- // methods in overloading
- if ((bestFit.member().getModifiers() & Modifier.PUBLIC) == 0)
- ++betterCount;
- else
- ++worseCount;
- } else {
- int preference = preferSignature(args, argTypes,
- member.vararg,
- bestFit.argTypes,
- bestFit.vararg );
- if (preference == PREFERENCE_AMBIGUOUS) {
- break;
- } else if (preference == PREFERENCE_FIRST_ARG) {
- ++betterCount;
- } else if (preference == PREFERENCE_SECOND_ARG) {
- ++worseCount;
- } else {
- if (preference != PREFERENCE_EQUAL) Kit.codeBug();
- // This should not happen in theory
- // but on some JVMs, Class.getMethods will return all
- // static methods of the class heirarchy, even if
- // a derived class's parameters match exactly.
- // We want to call the dervied class's method.
- if (bestFit.isStatic()
- && bestFit.getDeclaringClass().isAssignableFrom(
- member.getDeclaringClass()))
- {
- // On some JVMs, Class.getMethods will return all
- // static methods of the class heirarchy, even if
- // a derived class's parameters match exactly.
- // We want to call the dervied class's method.
- if (debug) printDebug(
- "Substituting (overridden static)",
- member, args);
- if (j == -1) {
- firstBestFit = i;
- } else {
- extraBestFits[j] = i;
- }
- } else {
- if (debug) printDebug(
- "Ignoring same signature member ",
- member, args);
- }
- continue search;
- }
- }
- }
- if (betterCount == 1 + extraBestFitsCount) {
- // member was prefered over all best fits
- if (debug) printDebug(
- "New first applicable ", member, args);
- firstBestFit = i;
- extraBestFitsCount = 0;
- } else if (worseCount == 1 + extraBestFitsCount) {
- // all best fits were prefered over member, ignore it
- if (debug) printDebug(
- "Rejecting (all current bests better) ", member, args);
- } else {
- // some ambiguity was present, add member to best fit set
- if (debug) printDebug(
- "Added to best fit set ", member, args);
- if (extraBestFits == null) {
- // Allocate maximum possible array
- extraBestFits = new int[methodsOrCtors.length - 1];
- }
- extraBestFits[extraBestFitsCount] = i;
- ++extraBestFitsCount;
- }
- }
- }
-
- if (firstBestFit < 0) {
- // Nothing was found
- return -1;
- } else if (extraBestFitsCount == 0) {
- // single best fit
- return firstBestFit;
- }
-
- // report remaining ambiguity
- StringBuffer buf = new StringBuffer();
- for (int j = -1; j != extraBestFitsCount; ++j) {
- int bestFitIndex;
- if (j == -1) {
- bestFitIndex = firstBestFit;
- } else {
- bestFitIndex = extraBestFits[j];
- }
- buf.append("\n ");
- buf.append(methodsOrCtors[bestFitIndex].toJavaDeclaration());
- }
-
- MemberBox firstFitMember = methodsOrCtors[firstBestFit];
- String memberName = firstFitMember.getName();
- String memberClass = firstFitMember.getDeclaringClass().getName();
-
- if (methodsOrCtors[0].isMethod()) {
- throw Context.reportRuntimeError3(
- "msg.constructor.ambiguous",
- memberName, scriptSignature(args), buf.toString());
- } else {
- throw Context.reportRuntimeError4(
- "msg.method.ambiguous", memberClass,
- memberName, scriptSignature(args), buf.toString());
- }
- }
-
- /** Types are equal */
- private static final int PREFERENCE_EQUAL = 0;
- private static final int PREFERENCE_FIRST_ARG = 1;
- private static final int PREFERENCE_SECOND_ARG = 2;
- /** No clear "easy" conversion */
- private static final int PREFERENCE_AMBIGUOUS = 3;
-
- /**
- * Determine which of two signatures is the closer fit.
- * Returns one of PREFERENCE_EQUAL, PREFERENCE_FIRST_ARG,
- * PREFERENCE_SECOND_ARG, or PREFERENCE_AMBIGUOUS.
- */
- private static int preferSignature(Object[] args,
- Class[] sig1,
- boolean vararg1,
- Class[] sig2,
- boolean vararg2 )
- {
- // TODO: This test is pretty primitive. It bascially prefers
- // a matching no vararg method over a vararg method independent
- // of the type conversion cost. This can lead to unexpected results.
- int alength = args.length;
- if (!vararg1 && vararg2) {
- // prefer the no vararg signature
- return PREFERENCE_FIRST_ARG;
- } else if (vararg1 && !vararg2) {
- // prefer the no vararg signature
- return PREFERENCE_SECOND_ARG;
- } else if (vararg1 && vararg2) {
- if (sig1.length < sig2.length) {
- // prefer the signature with more explicit types
- return PREFERENCE_SECOND_ARG;
- } else if (sig1.length > sig2.length) {
- // prefer the signature with more explicit types
- return PREFERENCE_FIRST_ARG;
- } else {
- // Both are varargs and have the same length, so make the
- // decision with the explicit args.
- alength = Math.min(args.length, sig1.length-1);
- }
- }
-
- int totalPreference = 0;
- for (int j = 0; j < alength; j++) {
- Class type1 = sig1[j];
- Class type2 = sig2[j];
- if (type1 == type2) {
- continue;
- }
- Object arg = args[j];
-
- // Determine which of type1, type2 is easier to convert from arg.
-
- int rank1 = NativeJavaObject.getConversionWeight(arg, type1);
- int rank2 = NativeJavaObject.getConversionWeight(arg, type2);
-
- int preference;
- if (rank1 < rank2) {
- preference = PREFERENCE_FIRST_ARG;
- } else if (rank1 > rank2) {
- preference = PREFERENCE_SECOND_ARG;
- } else {
- // Equal ranks
- if (rank1 == NativeJavaObject.CONVERSION_NONTRIVIAL) {
- if (type1.isAssignableFrom(type2)) {
- preference = PREFERENCE_SECOND_ARG;
- } else if (type2.isAssignableFrom(type1)) {
- preference = PREFERENCE_FIRST_ARG;
- } else {
- preference = PREFERENCE_AMBIGUOUS;
- }
- } else {
- preference = PREFERENCE_AMBIGUOUS;
- }
- }
-
- totalPreference |= preference;
-
- if (totalPreference == PREFERENCE_AMBIGUOUS) {
- break;
- }
- }
- return totalPreference;
- }
-
-
- private static final boolean debug = false;
-
- private static void printDebug(String msg, MemberBox member,
- Object[] args)
- {
- if (debug) {
- StringBuffer sb = new StringBuffer();
- sb.append(" ----- ");
- sb.append(msg);
- sb.append(member.getDeclaringClass().getName());
- sb.append('.');
- if (member.isMethod()) {
- sb.append(member.getName());
- }
- sb.append(JavaMembers.liveConnectSignature(member.argTypes));
- sb.append(" for arguments (");
- sb.append(scriptSignature(args));
- sb.append(')');
- System.out.println(sb);
- }
- }
-
- MemberBox[] methods;
- private String functionName;
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java
deleted file mode 100644
index 3d27852..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java
+++ /dev/null
@@ -1,1002 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- * Igor Bukanov
- * Frank Mitchell
- * Mike Shaver
- * Kemal Bayram
- *
- * 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;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.Hashtable;
-import java.util.Date;
-
-/**
- * This class reflects non-Array Java objects into the JavaScript environment. It
- * reflect fields directly, and uses NativeJavaMethod objects to reflect (possibly
- * overloaded) methods.<p>
- *
- * @author Mike Shaver
- * @see NativeJavaArray
- * @see NativeJavaPackage
- * @see NativeJavaClass
- */
-
-public class NativeJavaObject implements Scriptable, Wrapper, Serializable
-{
- static final long serialVersionUID = -6948590651130498591L;
-
- public NativeJavaObject() { }
-
- public NativeJavaObject(Scriptable scope, Object javaObject,
- Class staticType)
- {
- this(scope, javaObject, staticType, false);
- }
-
- public NativeJavaObject(Scriptable scope, Object javaObject,
- Class staticType, boolean isAdapter)
- {
- this.parent = ScriptableObject.getVeryTopLevelScope(scope); // APPJET
- this.javaObject = javaObject;
- this.staticType = staticType;
- this.isAdapter = isAdapter;
- initMembers();
- }
-
- protected void initMembers() {
- Class dynamicType;
- if (javaObject != null) {
- dynamicType = javaObject.getClass();
- } else {
- dynamicType = staticType;
- }
- members = JavaMembers.lookupClass(parent, dynamicType, staticType,
- isAdapter);
- fieldAndMethods
- = members.getFieldAndMethodsObjects(this, javaObject, false);
- }
-
- public boolean has(String name, Scriptable start) {
- return members.has(name, false);
- }
-
- public boolean has(int index, Scriptable start) {
- return false;
- }
-
- public Object get(String name, Scriptable start) {
- if (fieldAndMethods != null) {
- Object result = fieldAndMethods.get(name);
- if (result != null) {
- return result;
- }
- }
- // TODO: passing 'this' as the scope is bogus since it has
- // no parent scope
- return members.get(this, name, javaObject, false);
- }
-
- public Object get(int index, Scriptable start) {
- throw members.reportMemberNotFound(Integer.toString(index));
- }
-
- public void put(String name, Scriptable start, Object value) {
- // We could be asked to modify the value of a property in the
- // prototype. Since we can't add a property to a Java object,
- // we modify it in the prototype rather than copy it down.
- if (prototype == null || members.has(name, false))
- members.put(this, name, javaObject, value, false);
- else
- prototype.put(name, prototype, value);
- }
-
- public void put(int index, Scriptable start, Object value) {
- throw members.reportMemberNotFound(Integer.toString(index));
- }
-
- public boolean hasInstance(Scriptable value) {
- // This is an instance of a Java class, so always return false
- return false;
- }
-
- public void delete(String name) {
- }
-
- public void delete(int index) {
- }
-
- public Scriptable getPrototype() {
- if (prototype == null && javaObject instanceof String) {
- return ScriptableObject.getClassPrototype(parent, "String");
- }
- return prototype;
- }
-
- /**
- * Sets the prototype of the object.
- */
- public void setPrototype(Scriptable m) {
- prototype = m;
- }
-
- /**
- * Returns the parent (enclosing) scope of the object.
- */
- public Scriptable getParentScope() {
- return parent;
- }
-
- /**
- * Sets the parent (enclosing) scope of the object.
- */
- public void setParentScope(Scriptable m) {
- parent = m;
- }
-
- public Object[] getIds() {
- return members.getIds(false);
- }
-
-/**
-@deprecated Use {@link Context#getWrapFactory()} together with calling {@link
-WrapFactory#wrap(Context, Scriptable, Object, Class)}
-*/
- public static Object wrap(Scriptable scope, Object obj, Class staticType) {
-
- Context cx = Context.getContext();
- return cx.getWrapFactory().wrap(cx, scope, obj, staticType);
- }
-
- public Object unwrap() {
- return javaObject;
- }
-
- public String getClassName() {
- return "JavaObject";
- }
-
- public Object getDefaultValue(Class hint)
- {
- Object value;
- if (hint == null) {
- if (javaObject instanceof Boolean) {
- hint = ScriptRuntime.BooleanClass;
- }
- }
- if (hint == null || hint == ScriptRuntime.StringClass) {
- value = javaObject.toString();
- } else {
- String converterName;
- if (hint == ScriptRuntime.BooleanClass) {
- converterName = "booleanValue";
- } else if (hint == ScriptRuntime.NumberClass) {
- converterName = "doubleValue";
- } else {
- throw Context.reportRuntimeError0("msg.default.value");
- }
- Object converterObject = get(converterName, this);
- if (converterObject instanceof Function) {
- Function f = (Function)converterObject;
- value = f.call(Context.getContext(), f.getParentScope(),
- this, ScriptRuntime.emptyArgs);
- } else {
- if (hint == ScriptRuntime.NumberClass
- && javaObject instanceof Boolean)
- {
- boolean b = ((Boolean)javaObject).booleanValue();
- value = ScriptRuntime.wrapNumber(b ? 1.0 : 0.0);
- } else {
- value = javaObject.toString();
- }
- }
- }
- return value;
- }
-
- /**
- * Determine whether we can/should convert between the given type and the
- * desired one. This should be superceded by a conversion-cost calculation
- * function, but for now I'll hide behind precedent.
- */
- public static boolean canConvert(Object fromObj, Class to) {
- int weight = getConversionWeight(fromObj, to);
-
- return (weight < CONVERSION_NONE);
- }
-
- private static final int JSTYPE_UNDEFINED = 0; // undefined type
- private static final int JSTYPE_NULL = 1; // null
- private static final int JSTYPE_BOOLEAN = 2; // boolean
- private static final int JSTYPE_NUMBER = 3; // number
- private static final int JSTYPE_STRING = 4; // string
- private static final int JSTYPE_JAVA_CLASS = 5; // JavaClass
- private static final int JSTYPE_JAVA_OBJECT = 6; // JavaObject
- private static final int JSTYPE_JAVA_ARRAY = 7; // JavaArray
- private static final int JSTYPE_OBJECT = 8; // Scriptable
-
- static final byte CONVERSION_TRIVIAL = 1;
- static final byte CONVERSION_NONTRIVIAL = 0;
- static final byte CONVERSION_NONE = 99;
-
- /**
- * Derive a ranking based on how "natural" the conversion is.
- * The special value CONVERSION_NONE means no conversion is possible,
- * and CONVERSION_NONTRIVIAL signals that more type conformance testing
- * is required.
- * Based on
- * <a href="http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html">
- * "preferred method conversions" from Live Connect 3</a>
- */
- static int getConversionWeight(Object fromObj, Class to) {
- int fromCode = getJSTypeCode(fromObj);
-
- switch (fromCode) {
-
- case JSTYPE_UNDEFINED:
- if (to == ScriptRuntime.StringClass ||
- to == ScriptRuntime.ObjectClass) {
- return 1;
- }
- break;
-
- case JSTYPE_NULL:
- if (!to.isPrimitive()) {
- return 1;
- }
- break;
-
- case JSTYPE_BOOLEAN:
- // "boolean" is #1
- if (to == Boolean.TYPE) {
- return 1;
- }
- else if (to == ScriptRuntime.BooleanClass) {
- return 2;
- }
- else if (to == ScriptRuntime.ObjectClass) {
- return 3;
- }
- else if (to == ScriptRuntime.StringClass) {
- return 4;
- }
- break;
-
- case JSTYPE_NUMBER:
- if (to.isPrimitive()) {
- if (to == Double.TYPE) {
- return 1;
- }
- else if (to != Boolean.TYPE) {
- return 1 + getSizeRank(to);
- }
- }
- else {
- if (to == ScriptRuntime.StringClass) {
- // native numbers are #1-8
- return 9;
- }
- else if (to == ScriptRuntime.ObjectClass) {
- return 10;
- }
- else if (ScriptRuntime.NumberClass.isAssignableFrom(to)) {
- // "double" is #1
- return 2;
- }
- }
- break;
-
- case JSTYPE_STRING:
- if (to == ScriptRuntime.StringClass) {
- return 1;
- }
- else if (to.isInstance(fromObj)) {
- return 2;
- }
- else if (to.isPrimitive()) {
- if (to == Character.TYPE) {
- return 3;
- } else if (to != Boolean.TYPE) {
- return 4;
- }
- }
- break;
-
- case JSTYPE_JAVA_CLASS:
- if (to == ScriptRuntime.ClassClass) {
- return 1;
- }
- else if (to == ScriptRuntime.ObjectClass) {
- return 3;
- }
- else if (to == ScriptRuntime.StringClass) {
- return 4;
- }
- break;
-
- case JSTYPE_JAVA_OBJECT:
- case JSTYPE_JAVA_ARRAY:
- Object javaObj = fromObj;
- if (javaObj instanceof Wrapper) {
- javaObj = ((Wrapper)javaObj).unwrap();
- }
- if (to.isInstance(javaObj)) {
- return CONVERSION_NONTRIVIAL;
- }
- if (to == ScriptRuntime.StringClass) {
- return 2;
- }
- else if (to.isPrimitive() && to != Boolean.TYPE) {
- return (fromCode == JSTYPE_JAVA_ARRAY)
- ? CONVERSION_NONE : 2 + getSizeRank(to);
- }
- break;
-
- case JSTYPE_OBJECT:
- // Other objects takes #1-#3 spots
- if (to == fromObj.getClass()) {
- // No conversion required
- return 1;
- }
- if (to.isArray()) {
- if (fromObj instanceof NativeArray) {
- // This is a native array conversion to a java array
- // Array conversions are all equal, and preferable to object
- // and string conversion, per LC3.
- return 1;
- }
- }
- else if (to == ScriptRuntime.ObjectClass) {
- return 2;
- }
- else if (to == ScriptRuntime.StringClass) {
- return 3;
- }
- else if (to == ScriptRuntime.DateClass) {
- if (fromObj instanceof NativeDate) {
- // This is a native date to java date conversion
- return 1;
- }
- }
- else if (to.isInterface()) {
- if (fromObj instanceof Function) {
- // See comments in coerceType
- if (to.getMethods().length == 1) {
- return 1;
- }
- }
- return 11;
- }
- else if (to.isPrimitive() && to != Boolean.TYPE) {
- return 3 + getSizeRank(to);
- }
- break;
- }
-
- return CONVERSION_NONE;
- }
-
- static int getSizeRank(Class aType) {
- if (aType == Double.TYPE) {
- return 1;
- }
- else if (aType == Float.TYPE) {
- return 2;
- }
- else if (aType == Long.TYPE) {
- return 3;
- }
- else if (aType == Integer.TYPE) {
- return 4;
- }
- else if (aType == Short.TYPE) {
- return 5;
- }
- else if (aType == Character.TYPE) {
- return 6;
- }
- else if (aType == Byte.TYPE) {
- return 7;
- }
- else if (aType == Boolean.TYPE) {
- return CONVERSION_NONE;
- }
- else {
- return 8;
- }
- }
-
- private static int getJSTypeCode(Object value) {
- if (value == null) {
- return JSTYPE_NULL;
- }
- else if (value == Undefined.instance) {
- return JSTYPE_UNDEFINED;
- }
- else if (value instanceof String) {
- return JSTYPE_STRING;
- }
- else if (value instanceof Number) {
- return JSTYPE_NUMBER;
- }
- else if (value instanceof Boolean) {
- return JSTYPE_BOOLEAN;
- }
- else if (value instanceof Scriptable) {
- if (value instanceof NativeJavaClass) {
- return JSTYPE_JAVA_CLASS;
- }
- else if (value instanceof NativeJavaArray) {
- return JSTYPE_JAVA_ARRAY;
- }
- else if (value instanceof Wrapper) {
- return JSTYPE_JAVA_OBJECT;
- }
- else {
- return JSTYPE_OBJECT;
- }
- }
- else if (value instanceof Class) {
- return JSTYPE_JAVA_CLASS;
- }
- else {
- Class valueClass = value.getClass();
- if (valueClass.isArray()) {
- return JSTYPE_JAVA_ARRAY;
- }
- else {
- return JSTYPE_JAVA_OBJECT;
- }
- }
- }
-
- /**
- * Not intended for public use. Callers should use the
- * public API Context.toType.
- * @deprecated as of 1.5 Release 4
- * @see org.mozilla.javascript.Context#jsToJava(Object, Class)
- */
- public static Object coerceType(Class type, Object value)
- {
- return coerceTypeImpl(type, value);
- }
-
- /**
- * Type-munging for field setting and method invocation.
- * Conforms to LC3 specification
- */
- static Object coerceTypeImpl(Class type, Object value)
- {
- if (value != null && value.getClass() == type) {
- return value;
- }
-
- switch (getJSTypeCode(value)) {
-
- case JSTYPE_NULL:
- // raise error if type.isPrimitive()
- if (type.isPrimitive()) {
- reportConversionError(value, type);
- }
- return null;
-
- case JSTYPE_UNDEFINED:
- if (type == ScriptRuntime.StringClass ||
- type == ScriptRuntime.ObjectClass) {
- return "undefined";
- }
- else {
- reportConversionError("undefined", type);
- }
- break;
-
- case JSTYPE_BOOLEAN:
- // Under LC3, only JS Booleans can be coerced into a Boolean value
- if (type == Boolean.TYPE ||
- type == ScriptRuntime.BooleanClass ||
- type == ScriptRuntime.ObjectClass) {
- return value;
- }
- else if (type == ScriptRuntime.StringClass) {
- return value.toString();
- }
- else {
- reportConversionError(value, type);
- }
- break;
-
- case JSTYPE_NUMBER:
- if (type == ScriptRuntime.StringClass) {
- return ScriptRuntime.toString(value);
- }
- else if (type == ScriptRuntime.ObjectClass) {
- return coerceToNumber(Double.TYPE, value);
- }
- else if ((type.isPrimitive() && type != Boolean.TYPE) ||
- ScriptRuntime.NumberClass.isAssignableFrom(type)) {
- return coerceToNumber(type, value);
- }
- else {
- reportConversionError(value, type);
- }
- break;
-
- case JSTYPE_STRING:
- if (type == ScriptRuntime.StringClass || type.isInstance(value)) {
- return value;
- }
- else if (type == Character.TYPE
- || type == ScriptRuntime.CharacterClass)
- {
- // Special case for converting a single char string to a
- // character
- // Placed here because it applies *only* to JS strings,
- // not other JS objects converted to strings
- if (((String)value).length() == 1) {
- return new Character(((String)value).charAt(0));
- }
- else {
- return coerceToNumber(type, value);
- }
- }
- else if ((type.isPrimitive() && type != Boolean.TYPE)
- || ScriptRuntime.NumberClass.isAssignableFrom(type))
- {
- return coerceToNumber(type, value);
- }
- else {
- reportConversionError(value, type);
- }
- break;
-
- case JSTYPE_JAVA_CLASS:
- if (value instanceof Wrapper) {
- value = ((Wrapper)value).unwrap();
- }
-
- if (type == ScriptRuntime.ClassClass ||
- type == ScriptRuntime.ObjectClass) {
- return value;
- }
- else if (type == ScriptRuntime.StringClass) {
- return value.toString();
- }
- else {
- reportConversionError(value, type);
- }
- break;
-
- case JSTYPE_JAVA_OBJECT:
- case JSTYPE_JAVA_ARRAY:
- if (value instanceof Wrapper) {
- value = ((Wrapper)value).unwrap();
- }
- if (type.isPrimitive()) {
- if (type == Boolean.TYPE) {
- reportConversionError(value, type);
- }
- return coerceToNumber(type, value);
- }
- else {
- if (type == ScriptRuntime.StringClass) {
- return value.toString();
- }
- else {
- if (type.isInstance(value)) {
- return value;
- }
- else {
- reportConversionError(value, type);
- }
- }
- }
- break;
-
- case JSTYPE_OBJECT:
- if (type == ScriptRuntime.StringClass) {
- return ScriptRuntime.toString(value);
- }
- else if (type.isPrimitive()) {
- if (type == Boolean.TYPE) {
- reportConversionError(value, type);
- }
- return coerceToNumber(type, value);
- }
- else if (type.isInstance(value)) {
- return value;
- }
- else if (type == ScriptRuntime.DateClass
- && value instanceof NativeDate)
- {
- double time = ((NativeDate)value).getJSTimeValue();
- // XXX: This will replace NaN by 0
- return new Date((long)time);
- }
- else if (type.isArray() && value instanceof NativeArray) {
- // Make a new java array, and coerce the JS array components
- // to the target (component) type.
- NativeArray array = (NativeArray) value;
- long length = array.getLength();
- Class arrayType = type.getComponentType();
- Object Result = Array.newInstance(arrayType, (int)length);
- for (int i = 0 ; i < length ; ++i) {
- try {
- Array.set(Result, i, coerceType(arrayType,
- array.get(i, array)));
- }
- catch (EvaluatorException ee) {
- reportConversionError(value, type);
- }
- }
-
- return Result;
- }
- else if (value instanceof Wrapper) {
- value = ((Wrapper)value).unwrap();
- if (type.isInstance(value))
- return value;
- reportConversionError(value, type);
- }
- else if (type.isInterface() && value instanceof Callable) {
- // Try to use function as implementation of Java interface.
- //
- // XXX: Curently only instances of ScriptableObject are
- // supported since the resulting interface proxies should
- // be reused next time conversion is made and generic
- // Callable has no storage for it. Weak references can
- // address it but for now use this restriction.
- if (value instanceof ScriptableObject) {
- ScriptableObject so = (ScriptableObject)value;
- Object key = Kit.makeHashKeyFromPair(
- COERCED_INTERFACE_KEY, type);
- Object old = so.getAssociatedValue(key);
- if (old != null) {
- // Function was already wrapped
- return old;
- }
- Context cx = Context.getContext();
- Object glue
- = InterfaceAdapter.create(cx, type, (Callable)value);
- // Store for later retrival
- glue = so.associateValue(key, glue);
- return glue;
- }
- reportConversionError(value, type);
- } else {
- reportConversionError(value, type);
- }
- break;
- }
-
- return value;
- }
-
- private static Object coerceToNumber(Class type, Object value)
- {
- Class valueClass = value.getClass();
-
- // Character
- if (type == Character.TYPE || type == ScriptRuntime.CharacterClass) {
- if (valueClass == ScriptRuntime.CharacterClass) {
- return value;
- }
- return new Character((char)toInteger(value,
- ScriptRuntime.CharacterClass,
- Character.MIN_VALUE,
- Character.MAX_VALUE));
- }
-
- // Double, Float
- if (type == ScriptRuntime.ObjectClass ||
- type == ScriptRuntime.DoubleClass || type == Double.TYPE) {
- return valueClass == ScriptRuntime.DoubleClass
- ? value
- : new Double(toDouble(value));
- }
-
- if (type == ScriptRuntime.FloatClass || type == Float.TYPE) {
- if (valueClass == ScriptRuntime.FloatClass) {
- return value;
- }
- else {
- double number = toDouble(value);
- if (Double.isInfinite(number) || Double.isNaN(number)
- || number == 0.0) {
- return new Float((float)number);
- }
- else {
- double absNumber = Math.abs(number);
- if (absNumber < Float.MIN_VALUE) {
- return new Float((number > 0.0) ? +0.0 : -0.0);
- }
- else if (absNumber > Float.MAX_VALUE) {
- return new Float((number > 0.0) ?
- Float.POSITIVE_INFINITY :
- Float.NEGATIVE_INFINITY);
- }
- else {
- return new Float((float)number);
- }
- }
- }
- }
-
- // Integer, Long, Short, Byte
- if (type == ScriptRuntime.IntegerClass || type == Integer.TYPE) {
- if (valueClass == ScriptRuntime.IntegerClass) {
- return value;
- }
- else {
- return new Integer((int)toInteger(value,
- ScriptRuntime.IntegerClass,
- Integer.MIN_VALUE,
- Integer.MAX_VALUE));
- }
- }
-
- if (type == ScriptRuntime.LongClass || type == Long.TYPE) {
- if (valueClass == ScriptRuntime.LongClass) {
- return value;
- } else {
- /* Long values cannot be expressed exactly in doubles.
- * We thus use the largest and smallest double value that
- * has a value expressible as a long value. We build these
- * numerical values from their hexidecimal representations
- * to avoid any problems caused by attempting to parse a
- * decimal representation.
- */
- final double max = Double.longBitsToDouble(0x43dfffffffffffffL);
- final double min = Double.longBitsToDouble(0xc3e0000000000000L);
- return new Long(toInteger(value,
- ScriptRuntime.LongClass,
- min,
- max));
- }
- }
-
- if (type == ScriptRuntime.ShortClass || type == Short.TYPE) {
- if (valueClass == ScriptRuntime.ShortClass) {
- return value;
- }
- else {
- return new Short((short)toInteger(value,
- ScriptRuntime.ShortClass,
- Short.MIN_VALUE,
- Short.MAX_VALUE));
- }
- }
-
- if (type == ScriptRuntime.ByteClass || type == Byte.TYPE) {
- if (valueClass == ScriptRuntime.ByteClass) {
- return value;
- }
- else {
- return new Byte((byte)toInteger(value,
- ScriptRuntime.ByteClass,
- Byte.MIN_VALUE,
- Byte.MAX_VALUE));
- }
- }
-
- return new Double(toDouble(value));
- }
-
-
- private static double toDouble(Object value)
- {
- if (value instanceof Number) {
- return ((Number)value).doubleValue();
- }
- else if (value instanceof String) {
- return ScriptRuntime.toNumber((String)value);
- }
- else if (value instanceof Scriptable) {
- if (value instanceof Wrapper) {
- // XXX: optimize tail-recursion?
- return toDouble(((Wrapper)value).unwrap());
- }
- else {
- return ScriptRuntime.toNumber(value);
- }
- }
- else {
- Method meth;
- try {
- meth = value.getClass().getMethod("doubleValue",
- (Class [])null);
- }
- catch (NoSuchMethodException e) {
- meth = null;
- }
- catch (SecurityException e) {
- meth = null;
- }
- if (meth != null) {
- try {
- return ((Number)meth.invoke(value,
- (Object [])null)).doubleValue();
- }
- catch (IllegalAccessException e) {
- // XXX: ignore, or error message?
- reportConversionError(value, Double.TYPE);
- }
- catch (InvocationTargetException e) {
- // XXX: ignore, or error message?
- reportConversionError(value, Double.TYPE);
- }
- }
- return ScriptRuntime.toNumber(value.toString());
- }
- }
-
- private static long toInteger(Object value, Class type,
- double min, double max)
- {
- double d = toDouble(value);
-
- if (Double.isInfinite(d) || Double.isNaN(d)) {
- // Convert to string first, for more readable message
- reportConversionError(ScriptRuntime.toString(value), type);
- }
-
- if (d > 0.0) {
- d = Math.floor(d);
- }
- else {
- d = Math.ceil(d);
- }
-
- if (d < min || d > max) {
- // Convert to string first, for more readable message
- reportConversionError(ScriptRuntime.toString(value), type);
- }
- return (long)d;
- }
-
- static void reportConversionError(Object value, Class type)
- {
- // It uses String.valueOf(value), not value.toString() since
- // value can be null, bug 282447.
- throw Context.reportRuntimeError2(
- "msg.conversion.not.allowed",
- String.valueOf(value),
- JavaMembers.javaSignature(type));
- }
-
- private void writeObject(ObjectOutputStream out)
- throws IOException
- {
- out.defaultWriteObject();
-
- out.writeBoolean(isAdapter);
- if (isAdapter) {
- if (adapter_writeAdapterObject == null) {
- throw new IOException();
- }
- Object[] args = { javaObject, out };
- try {
- adapter_writeAdapterObject.invoke(null, args);
- } catch (Exception ex) {
- throw new IOException();
- }
- } else {
- out.writeObject(javaObject);
- }
-
- if (staticType != null) {
- out.writeObject(staticType.getClass().getName());
- } else {
- out.writeObject(null);
- }
- }
-
- private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- in.defaultReadObject();
-
- isAdapter = in.readBoolean();
- if (isAdapter) {
- if (adapter_readAdapterObject == null)
- throw new ClassNotFoundException();
- Object[] args = { this, in };
- try {
- javaObject = adapter_readAdapterObject.invoke(null, args);
- } catch (Exception ex) {
- throw new IOException();
- }
- } else {
- javaObject = in.readObject();
- }
-
- String className = (String)in.readObject();
- if (className != null) {
- staticType = Class.forName(className);
- } else {
- staticType = null;
- }
-
- initMembers();
- }
-
- /**
- * The prototype of this object.
- */
- protected Scriptable prototype;
-
- /**
- * The parent scope of this object.
- */
- protected Scriptable parent;
-
- protected transient Object javaObject;
-
- protected transient Class staticType;
- protected transient JavaMembers members;
- private transient Hashtable fieldAndMethods;
- private transient boolean isAdapter;
-
- private static final Object COERCED_INTERFACE_KEY = new Object();
- private static Method adapter_writeAdapterObject;
- private static Method adapter_readAdapterObject;
-
- static {
- // Reflection in java is verbose
- Class[] sig2 = new Class[2];
- Class cl = Kit.classOrNull("org.mozilla.javascript.JavaAdapter");
- if (cl != null) {
- try {
- sig2[0] = ScriptRuntime.ObjectClass;
- sig2[1] = Kit.classOrNull("java.io.ObjectOutputStream");
- adapter_writeAdapterObject = cl.getMethod("writeAdapterObject",
- sig2);
-
- sig2[0] = ScriptRuntime.ScriptableClass;
- sig2[1] = Kit.classOrNull("java.io.ObjectInputStream");
- adapter_readAdapterObject = cl.getMethod("readAdapterObject",
- sig2);
-
- } catch (Exception ex) {
- adapter_writeAdapterObject = null;
- adapter_readAdapterObject = null;
- }
- }
- }
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaPackage.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaPackage.java
deleted file mode 100644
index 71f09f7..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaPackage.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/* -*- 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
- * Frank Mitchell
- * Mike Shaver
- *
- * 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 reflects Java packages into the JavaScript environment. We
- * lazily reflect classes and subpackages, and use a caching/sharing
- * system to ensure that members reflected into one JavaPackage appear
- * in all other references to the same package (as with Packages.java.lang
- * and java.lang).
- *
- * @author Mike Shaver
- * @see NativeJavaArray
- * @see NativeJavaObject
- * @see NativeJavaClass
- */
-
-public class NativeJavaPackage extends ScriptableObject
-{
- static final long serialVersionUID = 7445054382212031523L;
-
- NativeJavaPackage(boolean internalUsage,
- String packageName, ClassLoader classLoader)
- {
- this.packageName = packageName;
- this.classLoader = classLoader;
- }
-
- /**
- * @deprecated NativeJavaPackage is an internal class, do not use
- * it directly.
- */
- public NativeJavaPackage(String packageName, ClassLoader classLoader) {
- this(false, packageName, classLoader);
- }
-
- /**
- * @deprecated NativeJavaPackage is an internal class, do not use
- * it directly.
- */
- public NativeJavaPackage(String packageName) {
- this(false, packageName,
- Context.getCurrentContext().getApplicationClassLoader());
- }
-
- public String getClassName() {
- return "JavaPackage";
- }
-
- public boolean has(String id, Scriptable start) {
- return true;
- }
-
- public boolean has(int index, Scriptable start) {
- return false;
- }
-
- public void put(String id, Scriptable start, Object value) {
- // Can't add properties to Java packages. Sorry.
- }
-
- public void put(int index, Scriptable start, Object value) {
- throw Context.reportRuntimeError0("msg.pkg.int");
- }
-
- public Object get(String id, Scriptable start) {
- return getPkgProperty(id, start, true);
- }
-
- public Object get(int index, Scriptable start) {
- return NOT_FOUND;
- }
-
- // set up a name which is known to be a package so we don't
- // need to look for a class by that name
- void forcePackage(String name, Scriptable scope)
- {
- NativeJavaPackage pkg;
- int end = name.indexOf('.');
- if (end == -1) {
- end = name.length();
- }
-
- String id = name.substring(0, end);
- Object cached = super.get(id, this);
- if (cached != null && cached instanceof NativeJavaPackage) {
- pkg = (NativeJavaPackage) cached;
- } else {
- String newPackage = packageName.length() == 0
- ? id
- : packageName + "." + id;
- pkg = new NativeJavaPackage(true, newPackage, classLoader);
- ScriptRuntime.setObjectProtoAndParent(pkg, scope);
- super.put(id, this, pkg);
- }
- if (end < name.length()) {
- pkg.forcePackage(name.substring(end+1), scope);
- }
- }
-
- synchronized Object getPkgProperty(String name, Scriptable start,
- boolean createPkg)
- {
- Object cached = super.get(name, start);
- if (cached != NOT_FOUND)
- return cached;
-
- String className = (packageName.length() == 0)
- ? name : packageName + '.' + name;
- Context cx = Context.getContext();
- ClassShutter shutter = cx.getClassShutter();
- Scriptable newValue = null;
- if (shutter == null || shutter.visibleToScripts(className)) {
- Class cl = null;
- if (classLoader != null) {
- cl = Kit.classOrNull(classLoader, className);
- } else {
- cl = Kit.classOrNull(className);
- }
- if (cl != null) {
- newValue = new NativeJavaClass(getTopLevelScope(this), cl);
- newValue.setPrototype(getPrototype());
- }
- }
- if (newValue == null && createPkg) {
- NativeJavaPackage pkg;
- pkg = new NativeJavaPackage(true, className, classLoader);
- ScriptRuntime.setObjectProtoAndParent(pkg, getParentScope());
- newValue = pkg;
- }
- if (newValue != null) {
- // Make it available for fast lookup and sharing of
- // lazily-reflected constructors and static members.
- super.put(name, start, newValue);
- }
- return newValue;
- }
-
- public Object getDefaultValue(Class ignored) {
- return toString();
- }
-
- public String toString() {
- return "[JavaPackage " + packageName + "]";
- }
-
- public boolean equals(Object obj) {
- if(obj instanceof NativeJavaPackage) {
- NativeJavaPackage njp = (NativeJavaPackage)obj;
- return packageName.equals(njp.packageName) && classLoader == njp.classLoader;
- }
- return false;
- }
-
- public int hashCode() {
- return packageName.hashCode() ^ (classLoader == null ? 0 : classLoader.hashCode());
- }
-
- private String packageName;
- private ClassLoader classLoader;
-} \ No newline at end of file
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaTopPackage.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaTopPackage.java
deleted file mode 100644
index b5c9b49..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaTopPackage.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/* -*- 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
- * Frank Mitchell
- * Mike Shaver
- *
- * 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 reflects Java packages into the JavaScript environment. We
- * lazily reflect classes and subpackages, and use a caching/sharing
- * system to ensure that members reflected into one JavaPackage appear
- * in all other references to the same package (as with Packages.java.lang
- * and java.lang).
- *
- * @author Mike Shaver
- * @see NativeJavaArray
- * @see NativeJavaObject
- * @see NativeJavaClass
- */
-
-public class NativeJavaTopPackage
- extends NativeJavaPackage implements Function, IdFunctionCall
-{
- static final long serialVersionUID = -1455787259477709999L;
-
- // we know these are packages so we can skip the class check
- // note that this is ok even if the package isn't present.
- private static final String commonPackages = ""
- +"java.lang;"
- +"java.lang.reflect;"
- +"java.io;"
- +"java.math;"
- +"java.net;"
- +"java.util;"
- +"java.util.zip;"
- +"java.text;"
- +"java.text.resources;"
- +"java.applet;"
- +"javax.swing;"
- ;
-
- NativeJavaTopPackage(ClassLoader loader)
- {
- super(true, "", loader);
- }
-
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- return construct(cx, scope, args);
- }
-
- public Scriptable construct(Context cx, Scriptable scope, Object[] args)
- {
- ClassLoader loader = null;
- if (args.length != 0) {
- Object arg = args[0];
- if (arg instanceof Wrapper) {
- arg = ((Wrapper)arg).unwrap();
- }
- if (arg instanceof ClassLoader) {
- loader = (ClassLoader)arg;
- }
- }
- if (loader == null) {
- Context.reportRuntimeError0("msg.not.classloader");
- return null;
- }
- return new NativeJavaPackage(true, "", loader);
- }
-
- public static void init(Context cx, Scriptable scope, boolean sealed)
- {
- ClassLoader loader = cx.getApplicationClassLoader();
- final NativeJavaTopPackage top = new NativeJavaTopPackage(loader);
- top.setPrototype(getObjectPrototype(scope));
- top.setParentScope(scope);
-
- String[] names = Kit.semicolonSplit(commonPackages);
- for (int i = 0; i != names.length; ++i) {
- top.forcePackage(names[i], scope);
- }
-
- // getClass implementation
- IdFunctionObject getClass = new IdFunctionObject(top, FTAG, Id_getClass,
- "getClass", 1, scope);
-
- // We want to get a real alias, and not a distinct JavaPackage
- // with the same packageName, so that we share classes and top
- // that are underneath.
- String[] topNames = { "java", "javax", "org", "com", "edu", "net" };
- NativeJavaPackage[] topPackages = new NativeJavaPackage[topNames.length];
- for (int i=0; i < topNames.length; i++) {
- topPackages[i] = (NativeJavaPackage)top.get(topNames[i], top);
- }
-
- // It's safe to downcast here since initStandardObjects takes
- // a ScriptableObject.
- ScriptableObject global = (ScriptableObject) scope;
-
- if (sealed) {
- getClass.sealObject();
- }
- getClass.exportAsScopeProperty();
- global.defineProperty("Packages", top, ScriptableObject.DONTENUM);
- for (int i=0; i < topNames.length; i++) {
- global.defineProperty(topNames[i], topPackages[i],
- ScriptableObject.DONTENUM);
- }
- }
-
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (f.hasTag(FTAG)) {
- if (f.methodId() == Id_getClass) {
- return js_getClass(cx, scope, args);
- }
- }
- throw f.unknown();
- }
-
- private Scriptable js_getClass(Context cx, Scriptable scope, Object[] args)
- {
- if (args.length > 0 && args[0] instanceof Wrapper) {
- Scriptable result = this;
- Class cl = ((Wrapper) args[0]).unwrap().getClass();
- // Evaluate the class name by getting successive properties of
- // the string to find the appropriate NativeJavaClass object
- String name = cl.getName();
- int offset = 0;
- for (;;) {
- int index = name.indexOf('.', offset);
- String propName = index == -1
- ? name.substring(offset)
- : name.substring(offset, index);
- Object prop = result.get(propName, result);
- if (!(prop instanceof Scriptable))
- break; // fall through to error
- result = (Scriptable) prop;
- if (index == -1)
- return result;
- offset = index+1;
- }
- }
- throw Context.reportRuntimeError0("msg.not.java.obj");
- }
-
- private static final Object FTAG = new Object();
- private static final int Id_getClass = 1;
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeMath.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeMath.java
deleted file mode 100644
index 36b66b4..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeMath.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; 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 Math native object.
- * See ECMA 15.8.
- * @author Norris Boyd
- */
-
-final class NativeMath extends IdScriptableObject
-{
- static final long serialVersionUID = -8838847185801131569L;
-
- private static final Object MATH_TAG = new Object();
-
- static void init(Scriptable scope, boolean sealed)
- {
- NativeMath obj = new NativeMath();
- obj.activatePrototypeMap(MAX_ID);
- obj.setPrototype(getObjectPrototype(scope));
- obj.setParentScope(scope);
- if (sealed) { obj.sealObject(); }
- ScriptableObject.defineProperty(scope, "Math", obj,
- ScriptableObject.DONTENUM);
- }
-
- private NativeMath()
- {
- }
-
- public String getClassName() { return "Math"; }
-
- protected void initPrototypeId(int 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; 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));
- }
- initPrototypeValue(id, name, ScriptRuntime.wrapNumber(x),
- DONTENUM | READONLY | PERMANENT);
- }
- }
-
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(MATH_TAG)) {
- return super.execIdCall(f, cx, scope, thisObj, args);
- }
- double x;
- int methodId = f.methodId();
- switch (methodId) {
- case Id_toSource:
- return "Math";
-
- case Id_abs:
- x = ScriptRuntime.toNumber(args, 0);
- // abs(-0.0) should be 0.0, but -0.0 < 0.0 == false
- x = (x == 0.0) ? 0.0 : (x < 0.0) ? -x : x;
- break;
-
- case Id_acos:
- case Id_asin:
- x = ScriptRuntime.toNumber(args, 0);
- if (x == x && -1.0 <= x && x <= 1.0) {
- x = (methodId == Id_acos) ? Math.acos(x) : Math.asin(x);
- } else {
- x = Double.NaN;
- }
- break;
-
- case Id_atan:
- x = ScriptRuntime.toNumber(args, 0);
- x = Math.atan(x);
- break;
-
- case Id_atan2:
- x = ScriptRuntime.toNumber(args, 0);
- x = Math.atan2(x, ScriptRuntime.toNumber(args, 1));
- break;
-
- case Id_ceil:
- x = ScriptRuntime.toNumber(args, 0);
- x = Math.ceil(x);
- break;
-
- case Id_cos:
- x = ScriptRuntime.toNumber(args, 0);
- x = (x == Double.POSITIVE_INFINITY
- || x == Double.NEGATIVE_INFINITY)
- ? Double.NaN : Math.cos(x);
- break;
-
- case Id_exp:
- x = ScriptRuntime.toNumber(args, 0);
- x = (x == Double.POSITIVE_INFINITY) ? x
- : (x == Double.NEGATIVE_INFINITY) ? 0.0
- : Math.exp(x);
- break;
-
- case Id_floor:
- x = ScriptRuntime.toNumber(args, 0);
- x = Math.floor(x);
- break;
-
- case Id_log:
- x = ScriptRuntime.toNumber(args, 0);
- // Java's log(<0) = -Infinity; we need NaN
- x = (x < 0) ? Double.NaN : Math.log(x);
- break;
-
- case Id_max:
- case Id_min:
- x = (methodId == Id_max)
- ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
- for (int i = 0; i != args.length; ++i) {
- double d = ScriptRuntime.toNumber(args[i]);
- if (d != d) {
- x = d; // NaN
- break;
- }
- if (methodId == Id_max) {
- // if (x < d) x = d; does not work due to -0.0 >= +0.0
- x = Math.max(x, d);
- } else {
- x = Math.min(x, d);
- }
- }
- break;
-
- case Id_pow:
- x = ScriptRuntime.toNumber(args, 0);
- x = js_pow(x, ScriptRuntime.toNumber(args, 1));
- break;
-
- case Id_random:
- x = Math.random();
- break;
-
- case Id_round:
- x = ScriptRuntime.toNumber(args, 0);
- if (x == x && x != Double.POSITIVE_INFINITY
- && x != Double.NEGATIVE_INFINITY)
- {
- // Round only finite x
- long l = Math.round(x);
- if (l != 0) {
- x = l;
- } else {
- // We must propagate the sign of d into the result
- if (x < 0.0) {
- x = ScriptRuntime.negativeZero;
- } else if (x != 0.0) {
- x = 0.0;
- }
- }
- }
- break;
-
- case Id_sin:
- x = ScriptRuntime.toNumber(args, 0);
- x = (x == Double.POSITIVE_INFINITY
- || x == Double.NEGATIVE_INFINITY)
- ? Double.NaN : Math.sin(x);
- break;
-
- case Id_sqrt:
- x = ScriptRuntime.toNumber(args, 0);
- x = Math.sqrt(x);
- break;
-
- case Id_tan:
- x = ScriptRuntime.toNumber(args, 0);
- x = Math.tan(x);
- break;
-
- default: throw new IllegalStateException(String.valueOf(methodId));
- }
- return ScriptRuntime.wrapNumber(x);
- }
-
- // See Ecma 15.8.2.13
- private double js_pow(double x, double y) {
- double result;
- if (y != y) {
- // y is NaN, result is always NaN
- result = y;
- } else if (y == 0) {
- // Java's pow(NaN, 0) = NaN; we need 1
- result = 1.0;
- } else if (x == 0) {
- // Many dirrerences from Java's Math.pow
- if (1 / x > 0) {
- result = (y > 0) ? 0 : Double.POSITIVE_INFINITY;
- } else {
- // x is -0, need to check if y is an odd integer
- long y_long = (long)y;
- if (y_long == y && (y_long & 0x1) != 0) {
- result = (y > 0) ? -0.0 : Double.NEGATIVE_INFINITY;
- } else {
- result = (y > 0) ? 0.0 : Double.POSITIVE_INFINITY;
- }
- }
- } else {
- result = Math.pow(x, y);
- if (result != result) {
- // Check for broken Java implementations that gives NaN
- // when they should return something else
- if (y == Double.POSITIVE_INFINITY) {
- if (x < -1.0 || 1.0 < x) {
- result = Double.POSITIVE_INFINITY;
- } else if (-1.0 < x && x < 1.0) {
- result = 0;
- }
- } else if (y == Double.NEGATIVE_INFINITY) {
- if (x < -1.0 || 1.0 < x) {
- result = 0;
- } else if (-1.0 < x && x < 1.0) {
- result = Double.POSITIVE_INFINITY;
- }
- } else if (x == Double.POSITIVE_INFINITY) {
- result = (y > 0) ? Double.POSITIVE_INFINITY : 0.0;
- } else if (x == Double.NEGATIVE_INFINITY) {
- long y_long = (long)y;
- if (y_long == y && (y_long & 0x1) != 0) {
- // y is odd integer
- result = (y > 0) ? Double.NEGATIVE_INFINITY : -0.0;
- } else {
- result = (y > 0) ? Double.POSITIVE_INFINITY : 0.0;
- }
- }
- }
- }
- return result;
- }
-
-// #string_id_map#
-
- protected int findPrototypeId(String s)
- {
- int id;
-// #generated# Last update: 2004-03-17 13:51:32 CET
- L0: { id = 0; String X = null; int c;
- L: switch (s.length()) {
- case 1: if (s.charAt(0)=='E') {id=Id_E; break L0;} break L;
- case 2: if (s.charAt(0)=='P' && s.charAt(1)=='I') {id=Id_PI; break L0;} break L;
- case 3: switch (s.charAt(0)) {
- case 'L': if (s.charAt(2)=='2' && s.charAt(1)=='N') {id=Id_LN2; break L0;} break L;
- case 'a': if (s.charAt(2)=='s' && s.charAt(1)=='b') {id=Id_abs; break L0;} break L;
- case 'c': if (s.charAt(2)=='s' && s.charAt(1)=='o') {id=Id_cos; break L0;} break L;
- case 'e': if (s.charAt(2)=='p' && s.charAt(1)=='x') {id=Id_exp; break L0;} break L;
- case 'l': if (s.charAt(2)=='g' && s.charAt(1)=='o') {id=Id_log; break L0;} break L;
- case 'm': c=s.charAt(2);
- if (c=='n') { if (s.charAt(1)=='i') {id=Id_min; break L0;} }
- else if (c=='x') { if (s.charAt(1)=='a') {id=Id_max; break L0;} }
- break L;
- case 'p': if (s.charAt(2)=='w' && s.charAt(1)=='o') {id=Id_pow; break L0;} break L;
- case 's': if (s.charAt(2)=='n' && s.charAt(1)=='i') {id=Id_sin; break L0;} break L;
- case 't': if (s.charAt(2)=='n' && s.charAt(1)=='a') {id=Id_tan; break L0;} break L;
- } break L;
- case 4: switch (s.charAt(1)) {
- case 'N': X="LN10";id=Id_LN10; break L;
- case 'c': X="acos";id=Id_acos; break L;
- case 'e': X="ceil";id=Id_ceil; break L;
- case 'q': X="sqrt";id=Id_sqrt; break L;
- case 's': X="asin";id=Id_asin; break L;
- case 't': X="atan";id=Id_atan; break L;
- } break L;
- case 5: switch (s.charAt(0)) {
- case 'L': X="LOG2E";id=Id_LOG2E; break L;
- case 'S': X="SQRT2";id=Id_SQRT2; break L;
- case 'a': X="atan2";id=Id_atan2; break L;
- case 'f': X="floor";id=Id_floor; break L;
- case 'r': X="round";id=Id_round; break L;
- } break L;
- case 6: c=s.charAt(0);
- if (c=='L') { X="LOG10E";id=Id_LOG10E; }
- else if (c=='r') { X="random";id=Id_random; }
- break L;
- case 7: X="SQRT1_2";id=Id_SQRT1_2; break L;
- case 8: X="toSource";id=Id_toSource; break L;
- }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- Id_toSource = 1,
- Id_abs = 2,
- Id_acos = 3,
- Id_asin = 4,
- Id_atan = 5,
- Id_atan2 = 6,
- Id_ceil = 7,
- Id_cos = 8,
- Id_exp = 9,
- Id_floor = 10,
- Id_log = 11,
- Id_max = 12,
- Id_min = 13,
- Id_pow = 14,
- Id_random = 15,
- Id_round = 16,
- Id_sin = 17,
- Id_sqrt = 18,
- Id_tan = 19,
-
- LAST_METHOD_ID = 19;
-
- private static final int
- Id_E = LAST_METHOD_ID + 1,
- Id_PI = LAST_METHOD_ID + 2,
- Id_LN10 = LAST_METHOD_ID + 3,
- Id_LN2 = LAST_METHOD_ID + 4,
- Id_LOG2E = LAST_METHOD_ID + 5,
- Id_LOG10E = LAST_METHOD_ID + 6,
- Id_SQRT1_2 = LAST_METHOD_ID + 7,
- Id_SQRT2 = LAST_METHOD_ID + 8,
-
- MAX_ID = LAST_METHOD_ID + 8;
-
-// #/string_id_map#
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeNumber.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeNumber.java
deleted file mode 100644
index 8fc9fb0..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeNumber.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/* -*- 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
- * Mike McCabe
- *
- * 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 Number native object.
- *
- * See ECMA 15.7.
- *
- * @author Norris Boyd
- */
-final class NativeNumber extends IdScriptableObject
-{
- static final long serialVersionUID = 3504516769741512101L;
-
- private static final Object NUMBER_TAG = new Object();
-
- private static final int MAX_PRECISION = 100;
-
- static void init(Scriptable scope, boolean sealed)
- {
- NativeNumber obj = new NativeNumber(0.0);
- obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
- }
-
- private NativeNumber(double number)
- {
- doubleValue = number;
- }
-
- public String getClassName()
- {
- return "Number";
- }
-
- protected void fillConstructorProperties(IdFunctionObject ctor)
- {
- final int attr = ScriptableObject.DONTENUM |
- ScriptableObject.PERMANENT |
- ScriptableObject.READONLY;
-
- ctor.defineProperty("NaN", ScriptRuntime.NaNobj, attr);
- ctor.defineProperty("POSITIVE_INFINITY",
- ScriptRuntime.wrapNumber(Double.POSITIVE_INFINITY),
- attr);
- ctor.defineProperty("NEGATIVE_INFINITY",
- ScriptRuntime.wrapNumber(Double.NEGATIVE_INFINITY),
- attr);
- ctor.defineProperty("MAX_VALUE",
- ScriptRuntime.wrapNumber(Double.MAX_VALUE),
- attr);
- ctor.defineProperty("MIN_VALUE",
- ScriptRuntime.wrapNumber(Double.MIN_VALUE),
- attr);
-
- 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 execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(NUMBER_TAG)) {
- return super.execIdCall(f, cx, scope, thisObj, args);
- }
- int id = f.methodId();
- if (id == 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 ScriptRuntime.wrapNumber(val);
- }
-
- // The rest of Number.prototype methods require thisObj to be Number
-
- if (!(thisObj instanceof NativeNumber))
- throw incompatibleCallError(f);
- double value = ((NativeNumber)thisObj).doubleValue;
-
- switch (id) {
-
- case Id_toString:
- case Id_toLocaleString:
- {
- // toLocaleString is just an alias for toString for now
- int base = (args.length == 0)
- ? 10 : ScriptRuntime.toInt32(args[0]);
- return ScriptRuntime.numberToString(value, base);
- }
-
- case Id_toSource:
- return "(new Number("+ScriptRuntime.toString(value)+"))";
-
- case Id_valueOf:
- return ScriptRuntime.wrapNumber(value);
-
- case Id_toFixed:
- return num_to(value, args, DToA.DTOSTR_FIXED,
- DToA.DTOSTR_FIXED, -20, 0);
-
- case Id_toExponential:
- return num_to(value, args, DToA.DTOSTR_STANDARD_EXPONENTIAL,
- DToA.DTOSTR_EXPONENTIAL, 0, 1);
-
- case Id_toPrecision:
- return num_to(value, args, DToA.DTOSTR_STANDARD,
- DToA.DTOSTR_PRECISION, 1, 0);
-
- default: throw new IllegalArgumentException(String.valueOf(id));
- }
- }
-
- public String toString() {
- return ScriptRuntime.numberToString(doubleValue, 10);
- }
-
- private static String num_to(double val,
- Object[] args,
- int zeroArgMode, int oneArgMode,
- int precisionMin, int precisionOffset)
- {
- int precision;
- if (args.length == 0) {
- precision = 0;
- oneArgMode = zeroArgMode;
- } else {
- /* We allow a larger range of precision than
- ECMA requires; this is permitted by ECMA. */
- precision = ScriptRuntime.toInt32(args[0]);
- if (precision < precisionMin || precision > MAX_PRECISION) {
- String msg = ScriptRuntime.getMessage1(
- "msg.bad.precision", ScriptRuntime.toString(args[0]));
- throw ScriptRuntime.constructError("RangeError", msg);
- }
- }
- StringBuffer sb = new StringBuffer();
- DToA.JS_dtostr(sb, oneArgMode, precision + precisionOffset, val);
- return sb.toString();
- }
-
-// #string_id_map#
-
- protected int findPrototypeId(String s)
- {
- int id;
-// #generated# Last update: 2007-05-09 08:15:50 EDT
- L0: { id = 0; String X = null; int c;
- L: switch (s.length()) {
- case 7: c=s.charAt(0);
- if (c=='t') { X="toFixed";id=Id_toFixed; }
- else if (c=='v') { X="valueOf";id=Id_valueOf; }
- break L;
- case 8: c=s.charAt(3);
- if (c=='o') { X="toSource";id=Id_toSource; }
- else if (c=='t') { X="toString";id=Id_toString; }
- break L;
- case 11: c=s.charAt(0);
- if (c=='c') { X="constructor";id=Id_constructor; }
- else if (c=='t') { X="toPrecision";id=Id_toPrecision; }
- break L;
- case 13: X="toExponential";id=Id_toExponential; break L;
- case 14: X="toLocaleString";id=Id_toLocaleString; break L;
- }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- Id_constructor = 1,
- Id_toString = 2,
- Id_toLocaleString = 3,
- Id_toSource = 4,
- Id_valueOf = 5,
- Id_toFixed = 6,
- Id_toExponential = 7,
- Id_toPrecision = 8,
- MAX_PROTOTYPE_ID = 8;
-
-// #/string_id_map#
-
- private double doubleValue;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeObject.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeObject.java
deleted file mode 100644
index 19aff63..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeObject.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/* -*- 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
- * Bob Jervis
- * Mike McCabe
- *
- * 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 Object native object.
- * See ECMA 15.2.
- * @author Norris Boyd
- */
-public class NativeObject extends IdScriptableObject
-{
- static final long serialVersionUID = -6345305608474346996L;
-
- private static final Object OBJECT_TAG = new Object();
-
- static void init(Scriptable scope, boolean sealed)
- {
- NativeObject obj = new NativeObject();
- obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
- }
-
- public String getClassName()
- {
- return "Object";
- }
-
- public String toString()
- {
- return ScriptRuntime.defaultObjectToString(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_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;
- case Id___defineGetter__:
- arity=2; s="__defineGetter__"; break;
- case Id___defineSetter__:
- arity=2; s="__defineSetter__"; break;
- case Id___lookupGetter__:
- arity=1; s="__lookupGetter__"; break;
- case Id___lookupSetter__:
- arity=1; s="__lookupSetter__"; break;
- default: throw new IllegalArgumentException(String.valueOf(id));
- }
- initPrototypeMethod(OBJECT_TAG, id, s, arity);
- }
-
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(OBJECT_TAG)) {
- return super.execIdCall(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);
- }
- if (args.length == 0 || args[0] == null
- || args[0] == Undefined.instance)
- {
- return new NativeObject();
- }
- return ScriptRuntime.toObject(cx, scope, args[0]);
- }
-
- 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);
- }
-
- case Id_valueOf:
- return thisObj;
-
- case Id_hasOwnProperty: {
- boolean result;
- if (args.length == 0) {
- result = false;
- } else {
- String s = ScriptRuntime.toStringIdOrIndex(cx, args[0]);
- if (s == null) {
- int index = ScriptRuntime.lastIndexResult(cx);
- result = thisObj.has(index, thisObj);
- } else {
- result = thisObj.has(s, thisObj);
- }
- }
- return ScriptRuntime.wrapBoolean(result);
- }
-
- case Id_propertyIsEnumerable: {
- boolean result;
- if (args.length == 0) {
- result = false;
- } else {
- String s = ScriptRuntime.toStringIdOrIndex(cx, args[0]);
- if (s == null) {
- int index = ScriptRuntime.lastIndexResult(cx);
- result = thisObj.has(index, thisObj);
- if (result && thisObj instanceof ScriptableObject) {
- ScriptableObject so = (ScriptableObject)thisObj;
- int attrs = so.getAttributes(index);
- result = ((attrs & ScriptableObject.DONTENUM) == 0);
- }
- } else {
- result = thisObj.has(s, thisObj);
- if (result && thisObj instanceof ScriptableObject) {
- ScriptableObject so = (ScriptableObject)thisObj;
- int attrs = so.getAttributes(s);
- result = ((attrs & ScriptableObject.DONTENUM) == 0);
- }
- }
- }
- return ScriptRuntime.wrapBoolean(result);
- }
-
- case Id_isPrototypeOf: {
- boolean result = false;
- if (args.length != 0 && args[0] instanceof Scriptable) {
- Scriptable v = (Scriptable) args[0];
- do {
- v = v.getPrototype();
- if (v == thisObj) {
- result = true;
- break;
- }
- } while (v != null);
- }
- return ScriptRuntime.wrapBoolean(result);
- }
-
- case Id_toSource:
- return ScriptRuntime.defaultObjectToSource(cx, scope, thisObj,
- args);
- case Id___defineGetter__:
- case Id___defineSetter__:
- {
- if (args.length < 2 || !(args[1] instanceof Callable)) {
- Object badArg = (args.length >= 2 ? args[1]
- : Undefined.instance);
- throw ScriptRuntime.notFunctionError(badArg);
- }
- if (!(thisObj instanceof ScriptableObject)) {
- throw Context.reportRuntimeError2(
- "msg.extend.scriptable",
- thisObj.getClass().getName(),
- String.valueOf(args[0]));
- }
- ScriptableObject so = (ScriptableObject)thisObj;
- String name = ScriptRuntime.toStringIdOrIndex(cx, args[0]);
- int index = (name != null ? 0
- : ScriptRuntime.lastIndexResult(cx));
- Callable getterOrSetter = (Callable)args[1];
- boolean isSetter = (id == Id___defineSetter__);
- so.setGetterOrSetter(name, index, getterOrSetter, isSetter);
- if (so instanceof NativeArray)
- ((NativeArray)so).setDenseOnly(false);
- }
- return Undefined.instance;
-
- case Id___lookupGetter__:
- case Id___lookupSetter__:
- {
- if (args.length < 1 ||
- !(thisObj instanceof ScriptableObject))
- return Undefined.instance;
-
- ScriptableObject so = (ScriptableObject)thisObj;
- String name = ScriptRuntime.toStringIdOrIndex(cx, args[0]);
- int index = (name != null ? 0
- : ScriptRuntime.lastIndexResult(cx));
- boolean isSetter = (id == Id___lookupSetter__);
- Object gs;
- for (;;) {
- gs = so.getGetterOrSetter(name, index, isSetter);
- if (gs != null)
- break;
- // If there is no getter or setter for the object itself,
- // how about the prototype?
- Scriptable v = so.getPrototype();
- if (v == null)
- break;
- if (v instanceof ScriptableObject)
- so = (ScriptableObject)v;
- else
- break;
- }
- if (gs != null)
- return gs;
- }
- return Undefined.instance;
-
- default:
- throw new IllegalArgumentException(String.valueOf(id));
- }
- }
-
-// #string_id_map#
-
- protected int findPrototypeId(String s)
- {
- int id;
-// #generated# Last update: 2007-05-09 08:15:55 EDT
- L0: { id = 0; String X = null; int c;
- L: switch (s.length()) {
- case 7: X="valueOf";id=Id_valueOf; break L;
- case 8: c=s.charAt(3);
- if (c=='o') { X="toSource";id=Id_toSource; }
- else if (c=='t') { X="toString";id=Id_toString; }
- break L;
- case 11: X="constructor";id=Id_constructor; break L;
- case 13: X="isPrototypeOf";id=Id_isPrototypeOf; break L;
- case 14: c=s.charAt(0);
- if (c=='h') { X="hasOwnProperty";id=Id_hasOwnProperty; }
- else if (c=='t') { X="toLocaleString";id=Id_toLocaleString; }
- break L;
- case 16: c=s.charAt(2);
- if (c=='d') {
- c=s.charAt(8);
- if (c=='G') { X="__defineGetter__";id=Id___defineGetter__; }
- else if (c=='S') { X="__defineSetter__";id=Id___defineSetter__; }
- }
- else if (c=='l') {
- c=s.charAt(8);
- if (c=='G') { X="__lookupGetter__";id=Id___lookupGetter__; }
- else if (c=='S') { X="__lookupSetter__";id=Id___lookupSetter__; }
- }
- break L;
- case 20: X="propertyIsEnumerable";id=Id_propertyIsEnumerable; break L;
- }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- Id_constructor = 1,
- Id_toString = 2,
- Id_toLocaleString = 3,
- Id_valueOf = 4,
- Id_hasOwnProperty = 5,
- Id_propertyIsEnumerable = 6,
- Id_isPrototypeOf = 7,
- Id_toSource = 8,
- Id___defineGetter__ = 9,
- Id___defineSetter__ = 10,
- Id___lookupGetter__ = 11,
- Id___lookupSetter__ = 12,
- MAX_PROTOTYPE_ID = 12;
-
-// #/string_id_map#
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeScript.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeScript.java
deleted file mode 100644
index 7b5191e..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeScript.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/* -*- 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
- * Roger Lawrence
- * Mike McCabe
- *
- * 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;
-
-/**
- * The JavaScript Script object.
- *
- * Note that the C version of the engine uses XDR as the format used
- * by freeze and thaw. Since this depends on the internal format of
- * structures in the C runtime, we cannot duplicate it.
- *
- * Since we cannot replace 'this' as a result of the compile method,
- * will forward requests to execute to the nonnull 'script' field.
- *
- * @since 1.3
- * @author Norris Boyd
- */
-
-class NativeScript extends BaseFunction
-{
- static final long serialVersionUID = -6795101161980121700L;
-
- private static final Object SCRIPT_TAG = new Object();
-
- static void init(Scriptable scope, boolean sealed)
- {
- NativeScript obj = new NativeScript(null);
- obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
- }
-
- private NativeScript(Script script)
- {
- this.script = script;
- }
-
- /**
- * Returns the name of this JavaScript class, "Script".
- */
- public String getClassName()
- {
- return "Script";
- }
-
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- if (script != null) {
- return script.exec(cx, scope);
- }
- return Undefined.instance;
- }
-
- public Scriptable construct(Context cx, Scriptable scope, Object[] args)
- {
- throw Context.reportRuntimeError0("msg.script.is.not.constructor");
- }
-
- public int getLength()
- {
- return 0;
- }
-
- public int getArity()
- {
- return 0;
- }
-
- String decompile(int indent, int flags)
- {
- if (script instanceof NativeFunction) {
- return ((NativeFunction)script).decompile(indent, flags);
- }
- return super.decompile(indent, flags);
- }
-
- 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 execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(SCRIPT_TAG)) {
- return super.execIdCall(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);
- ScriptRuntime.setObjectProtoAndParent(nscript, scope);
- return nscript;
- }
-
- case Id_toString: {
- NativeScript real = realThis(thisObj, f);
- Script realScript = real.script;
- if (realScript == null) { return ""; }
- return cx.decompileScript(realScript, 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, IdFunctionObject f)
- {
- if (!(thisObj instanceof NativeScript))
- throw incompatibleCallError(f);
- return (NativeScript)thisObj;
- }
-
- private static Script compile(Context cx, String source)
- {
- int[] linep = { 0 };
- String filename = Context.getSourcePositionFromStack(linep);
- if (filename == null) {
- filename = "<Script object>";
- linep[0] = 1;
- }
- ErrorReporter reporter;
- reporter = DefaultErrorReporter.forEval(cx.getErrorReporter());
- return cx.compileString(source, null, reporter, filename,
- linep[0], null);
- }
-
-// #string_id_map#
-
- protected int findPrototypeId(String s)
- {
- int id;
-// #generated# Last update: 2007-05-09 08:16:01 EDT
- L0: { id = 0; String X = null;
- L: switch (s.length()) {
- case 4: X="exec";id=Id_exec; break L;
- case 7: X="compile";id=Id_compile; break L;
- case 8: X="toString";id=Id_toString; break L;
- case 11: X="constructor";id=Id_constructor; break L;
- }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- Id_constructor = 1,
- Id_toString = 2,
- Id_compile = 3,
- Id_exec = 4,
- MAX_PROTOTYPE_ID = 4;
-
-// #/string_id_map#
-
- private Script script;
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeString.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeString.java
deleted file mode 100644
index 972415d..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeString.java
+++ /dev/null
@@ -1,983 +0,0 @@
-/* -*- 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):
- * Tom Beauvais
- * Norris Boyd
- * Mike McCabe
- *
- * 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;
-
-import java.text.Collator;
-
-/**
- * This class implements the String native object.
- *
- * See ECMA 15.5.
- *
- * String methods for dealing with regular expressions are
- * ported directly from C. Latest port is from version 1.40.12.19
- * in the JSFUN13_BRANCH.
- *
- * @author Mike McCabe
- * @author Norris Boyd
- */
-final class NativeString extends IdScriptableObject
-{
- static final long serialVersionUID = 920268368584188687L;
-
- private static final Object STRING_TAG = new Object();
-
- static void init(Scriptable scope, boolean sealed)
- {
- NativeString obj = new NativeString("");
- obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
- }
-
- private NativeString(String s) {
- string = s;
- }
-
- public String getClassName() {
- return "String";
- }
-
- private static final int
- Id_length = 1,
- MAX_INSTANCE_ID = 1;
-
- protected int getMaxInstanceId()
- {
- return MAX_INSTANCE_ID;
- }
-
- protected int findInstanceIdInfo(String s)
- {
- if (s.equals("length")) {
- return instanceIdInfo(DONTENUM | READONLY | 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 ScriptRuntime.wrapInt(string.length());
- }
- return super.getInstanceIdValue(id);
- }
-
- protected void fillConstructorProperties(IdFunctionObject ctor)
- {
- addIdFunctionProperty(ctor, STRING_TAG, ConstructorId_fromCharCode,
- "fromCharCode", 1);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_charAt, "charAt", 2);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_charCodeAt, "charCodeAt", 2);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_indexOf, "indexOf", 2);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_lastIndexOf, "lastIndexOf", 2);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_split, "split", 3);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_substring, "substring", 3);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_toLowerCase, "toLowerCase", 1);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_toUpperCase, "toUpperCase", 1);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_substr, "substr", 3);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_concat, "concat", 2);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_slice, "slice", 3);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_equalsIgnoreCase, "equalsIgnoreCase", 2);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_match, "match", 2);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_search, "search", 2);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_replace, "replace", 2);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_localeCompare, "localeCompare", 2);
- addIdFunctionProperty(ctor, STRING_TAG,
- ConstructorId_toLocaleLowerCase, "toLocaleLowerCase", 1);
- 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;
- case Id_localeCompare: arity=1; s="localeCompare"; break;
- case Id_toLocaleLowerCase: arity=0; s="toLocaleLowerCase"; break;
- case Id_toLocaleUpperCase: arity=0; s="toLocaleUpperCase"; break;
- default: throw new IllegalArgumentException(String.valueOf(id));
- }
- initPrototypeMethod(STRING_TAG, id, s, arity);
- }
-
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(STRING_TAG)) {
- return super.execIdCall(f, cx, scope, thisObj, args);
- }
- int id = f.methodId();
- again:
- for(;;) {
- switch (id) {
- case ConstructorId_charAt:
- case ConstructorId_charCodeAt:
- case ConstructorId_indexOf:
- case ConstructorId_lastIndexOf:
- case ConstructorId_split:
- case ConstructorId_substring:
- case ConstructorId_toLowerCase:
- case ConstructorId_toUpperCase:
- case ConstructorId_substr:
- case ConstructorId_concat:
- case ConstructorId_slice:
- case ConstructorId_equalsIgnoreCase:
- case ConstructorId_match:
- case ConstructorId_search:
- case ConstructorId_replace:
- case ConstructorId_localeCompare:
- case ConstructorId_toLocaleLowerCase: {
- thisObj = ScriptRuntime.toObject(scope,
- ScriptRuntime.toString(args[0]));
- Object[] newArgs = new Object[args.length-1];
- for (int i=0; i < newArgs.length; i++)
- newArgs[i] = args[i+1];
- args = newArgs;
- id = -id;
- continue again;
- }
-
- 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 ScriptRuntime.wrapInt(c);
- }
-
- case Id_indexOf:
- return ScriptRuntime.wrapInt(js_indexOf(
- ScriptRuntime.toString(thisObj), args));
-
- case Id_lastIndexOf:
- return ScriptRuntime.wrapInt(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 ScriptRuntime.wrapBoolean(
- (id == Id_equals) ? s1.equals(s2)
- : s1.equalsIgnoreCase(s2));
- }
-
- case Id_match:
- case Id_search:
- case Id_replace:
- {
- int actionType;
- if (id == Id_match) {
- actionType = RegExpProxy.RA_MATCH;
- } else if (id == Id_search) {
- actionType = RegExpProxy.RA_SEARCH;
- } else {
- actionType = RegExpProxy.RA_REPLACE;
- }
- return ScriptRuntime.checkRegExpProxy(cx).
- action(cx, scope, thisObj, args, actionType);
- }
- // ECMA-262 1 5.5.4.9
- case Id_localeCompare:
- {
- // For now, create and configure a collator instance. I can't
- // actually imagine that this'd be slower than caching them
- // a la ClassCache, so we aren't trying to outsmart ourselves
- // with a caching mechanism for now.
- Collator collator = Collator.getInstance(cx.getLocale());
- collator.setStrength(Collator.IDENTICAL);
- collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
- return ScriptRuntime.wrapNumber(collator.compare(
- ScriptRuntime.toString(thisObj),
- ScriptRuntime.toString(args, 0)));
- }
- case Id_toLocaleLowerCase:
- {
- return ScriptRuntime.toString(thisObj)
- .toLowerCase(cx.getLocale());
- }
- case Id_toLocaleUpperCase:
- {
- return ScriptRuntime.toString(thisObj)
- .toUpperCase(cx.getLocale());
- }
- }
- throw new IllegalArgumentException(String.valueOf(id));
- }
- }
-
- private static NativeString realThis(Scriptable thisObj, IdFunctionObject f)
- {
- if (!(thisObj instanceof NativeString))
- throw incompatibleCallError(f);
- return (NativeString)thisObj;
- }
-
- /*
- * HTML composition aids.
- */
- private static String tagify(Object thisObj, String tag,
- String attribute, Object[] args)
- {
- String str = ScriptRuntime.toString(thisObj);
- StringBuffer result = new StringBuffer();
- result.append('<');
- result.append(tag);
- if (attribute != null) {
- result.append(' ');
- result.append(attribute);
- result.append("=\"");
- result.append(ScriptRuntime.toString(args, 0));
- result.append('"');
- }
- result.append('>');
- result.append(str);
- result.append("</");
- result.append(tag);
- result.append('>');
- return result.toString();
- }
-
- public String toString() {
- return string;
- }
-
- /* Make array-style property lookup work for strings.
- * XXX is this ECMA? A version check is probably needed. In js too.
- */
- public Object get(int index, Scriptable start) {
- if (0 <= index && index < string.length()) {
- return string.substring(index, index + 1);
- }
- return super.get(index, start);
- }
-
- public void put(int index, Scriptable start, Object value) {
- if (0 <= index && index < string.length()) {
- return;
- }
- super.put(index, start, value);
- }
-
- /*
- *
- * See ECMA 15.5.4.6. Uses Java String.indexOf()
- * OPT to add - BMH searching from jsstr.c.
- */
- private static int js_indexOf(String target, Object[] args) {
- String search = ScriptRuntime.toString(args, 0);
- double begin = ScriptRuntime.toInteger(args, 1);
-
- if (begin > target.length()) {
- return -1;
- } else {
- if (begin < 0)
- begin = 0;
- return target.indexOf(search, (int)begin);
- }
- }
-
- /*
- *
- * See ECMA 15.5.4.7
- *
- */
- private static int js_lastIndexOf(String target, Object[] args) {
- String search = ScriptRuntime.toString(args, 0);
- double end = ScriptRuntime.toNumber(args, 1);
-
- if (end != end || end > target.length())
- end = target.length();
- else if (end < 0)
- end = 0;
-
- return target.lastIndexOf(search, (int)end);
- }
-
- /*
- * Used by js_split to find the next split point in target,
- * starting at offset ip and looking either for the given
- * separator substring, or for the next re match. ip and
- * matchlen must be reference variables (assumed to be arrays of
- * length 1) so they can be updated in the leading whitespace or
- * re case.
- *
- * Return -1 on end of string, >= 0 for a valid index of the next
- * separator occurrence if found, or the string length if no
- * separator is found.
- */
- private static int find_split(Context cx, Scriptable scope, String target,
- String separator, int version,
- RegExpProxy reProxy, Scriptable re,
- int[] ip, int[] matchlen, boolean[] matched,
- String[][] parensp)
- {
- int i = ip[0];
- int length = target.length();
-
- /*
- * Perl4 special case for str.split(' '), only if the user has selected
- * JavaScript1.2 explicitly. Split on whitespace, and skip leading w/s.
- * Strange but true, apparently modeled after awk.
- */
- if (version == Context.VERSION_1_2 &&
- re == null && separator.length() == 1 && separator.charAt(0) == ' ')
- {
- /* Skip leading whitespace if at front of str. */
- if (i == 0) {
- while (i < length && Character.isWhitespace(target.charAt(i)))
- i++;
- ip[0] = i;
- }
-
- /* Don't delimit whitespace at end of string. */
- if (i == length)
- return -1;
-
- /* Skip over the non-whitespace chars. */
- while (i < length
- && !Character.isWhitespace(target.charAt(i)))
- i++;
-
- /* Now skip the next run of whitespace. */
- int j = i;
- while (j < length && Character.isWhitespace(target.charAt(j)))
- j++;
-
- /* Update matchlen to count delimiter chars. */
- matchlen[0] = j - i;
- return i;
- }
-
- /*
- * Stop if past end of string. If at end of string, we will
- * return target length, so that
- *
- * "ab,".split(',') => new Array("ab", "")
- *
- * and the resulting array converts back to the string "ab,"
- * for symmetry. NB: This differs from perl, which drops the
- * trailing empty substring if the LIMIT argument is omitted.
- */
- if (i > length)
- return -1;
-
- /*
- * Match a regular expression against the separator at or
- * above index i. Return -1 at end of string instead of
- * trying for a match, so we don't get stuck in a loop.
- */
- if (re != null) {
- return reProxy.find_split(cx, scope, target, separator, re,
- ip, matchlen, matched, parensp);
- }
-
- /*
- * Deviate from ECMA by never splitting an empty string by any separator
- * string into a non-empty array (an array of length 1 that contains the
- * empty string).
- */
- if (version != Context.VERSION_DEFAULT && version < Context.VERSION_1_3
- && length == 0)
- return -1;
-
- /*
- * Special case: if sep is the empty string, split str into
- * one character substrings. Let our caller worry about
- * whether to split once at end of string into an empty
- * substring.
- *
- * For 1.2 compatibility, at the end of the string, we return the length as
- * the result, and set the separator length to 1 -- this allows the caller
- * to include an additional null string at the end of the substring list.
- */
- if (separator.length() == 0) {
- if (version == Context.VERSION_1_2) {
- if (i == length) {
- matchlen[0] = 1;
- return i;
- }
- return i + 1;
- }
- return (i == length) ? -1 : i + 1;
- }
-
- /* Punt to j.l.s.indexOf; return target length if separator is
- * not found.
- */
- if (ip[0] >= length)
- return length;
-
- i = target.indexOf(separator, ip[0]);
-
- return (i != -1) ? i : length;
- }
-
- /*
- * See ECMA 15.5.4.8. Modified to match JS 1.2 - optionally takes
- * a limit argument and accepts a regular expression as the split
- * argument.
- */
- private static Object js_split(Context cx, Scriptable scope,
- String target, Object[] args)
- {
- // create an empty Array to return;
- Scriptable top = getTopLevelScope(scope);
- Scriptable result = ScriptRuntime.newObject(cx, top, "Array", null);
-
- // return an array consisting of the target if no separator given
- // don't check against undefined, because we want
- // 'fooundefinedbar'.split(void 0) to split to ['foo', 'bar']
- if (args.length < 1) {
- result.put(0, result, target);
- return result;
- }
-
- // Use the second argument as the split limit, if given.
- boolean limited = (args.length > 1) && (args[1] != Undefined.instance);
- long limit = 0; // Initialize to avoid warning.
- if (limited) {
- /* Clamp limit between 0 and 1 + string length. */
- limit = ScriptRuntime.toUint32(args[1]);
- if (limit > target.length())
- limit = 1 + target.length();
- }
-
- String separator = null;
- int[] matchlen = new int[1];
- Scriptable re = null;
- RegExpProxy reProxy = null;
- if (args[0] instanceof Scriptable) {
- reProxy = ScriptRuntime.getRegExpProxy(cx);
- if (reProxy != null) {
- Scriptable test = (Scriptable)args[0];
- if (reProxy.isRegExp(test)) {
- re = test;
- }
- }
- }
- if (re == null) {
- separator = ScriptRuntime.toString(args[0]);
- matchlen[0] = separator.length();
- }
-
- // split target with separator or re
- int[] ip = { 0 };
- int match;
- int len = 0;
- boolean[] matched = { false };
- String[][] parens = { null };
- int version = cx.getLanguageVersion();
- while ((match = find_split(cx, scope, target, separator, version,
- reProxy, re, ip, matchlen, matched, parens))
- >= 0)
- {
- if ((limited && len >= limit) || (match > target.length()))
- break;
-
- String substr;
- if (target.length() == 0)
- substr = target;
- else
- substr = target.substring(ip[0], match);
-
- result.put(len, result, substr);
- len++;
- /*
- * Imitate perl's feature of including parenthesized substrings
- * that matched part of the delimiter in the new array, after the
- * split substring that was delimited.
- */
- if (re != null && matched[0] == true) {
- int size = parens[0].length;
- for (int num = 0; num < size; num++) {
- if (limited && len >= limit)
- break;
- result.put(len, result, parens[0][num]);
- len++;
- }
- matched[0] = false;
- }
- ip[0] = match + matchlen[0];
-
- if (version < Context.VERSION_1_3
- && version != Context.VERSION_DEFAULT)
- {
- /*
- * Deviate from ECMA to imitate Perl, which omits a final
- * split unless a limit argument is given and big enough.
- */
- if (!limited && ip[0] == target.length())
- break;
- }
- }
- return result;
- }
-
- /*
- * See ECMA 15.5.4.15
- */
- private static String js_substring(Context cx, String target,
- Object[] args)
- {
- int length = target.length();
- double start = ScriptRuntime.toInteger(args, 0);
- double end;
-
- if (start < 0)
- start = 0;
- else if (start > length)
- start = length;
-
- if (args.length <= 1 || args[1] == Undefined.instance) {
- end = length;
- } else {
- end = ScriptRuntime.toInteger(args[1]);
- if (end < 0)
- end = 0;
- else if (end > length)
- end = length;
-
- // swap if end < start
- if (end < start) {
- if (cx.getLanguageVersion() != Context.VERSION_1_2) {
- double temp = start;
- start = end;
- end = temp;
- } else {
- // Emulate old JDK1.0 java.lang.String.substring()
- end = start;
- }
- }
- }
- return target.substring((int)start, (int)end);
- }
-
- int getLength() {
- return string.length();
- }
-
- /*
- * Non-ECMA methods.
- */
- private static String js_substr(String target, Object[] args) {
- if (args.length < 1)
- return target;
-
- double begin = ScriptRuntime.toInteger(args[0]);
- double end;
- int length = target.length();
-
- if (begin < 0) {
- begin += length;
- if (begin < 0)
- begin = 0;
- } else if (begin > length) {
- begin = length;
- }
-
- if (args.length == 1) {
- end = length;
- } else {
- end = ScriptRuntime.toInteger(args[1]);
- if (end < 0)
- end = 0;
- end += begin;
- if (end > length)
- end = length;
- }
-
- return target.substring((int)begin, (int)end);
- }
-
- /*
- * Python-esque sequence operations.
- */
- private static String js_concat(String target, Object[] args) {
- int N = args.length;
- if (N == 0) { return target; }
- else if (N == 1) {
- String arg = ScriptRuntime.toString(args[0]);
- return target.concat(arg);
- }
-
- // Find total capacity for the final string to avoid unnecessary
- // re-allocations in StringBuffer
- int size = target.length();
- String[] argsAsStrings = new String[N];
- for (int i = 0; i != N; ++i) {
- String s = ScriptRuntime.toString(args[i]);
- argsAsStrings[i] = s;
- size += s.length();
- }
-
- StringBuffer result = new StringBuffer(size);
- result.append(target);
- for (int i = 0; i != N; ++i) {
- result.append(argsAsStrings[i]);
- }
- return result.toString();
- }
-
- private static String js_slice(String target, Object[] args) {
- if (args.length != 0) {
- double begin = ScriptRuntime.toInteger(args[0]);
- double end;
- int length = target.length();
- if (begin < 0) {
- begin += length;
- if (begin < 0)
- begin = 0;
- } else if (begin > length) {
- begin = length;
- }
-
- if (args.length == 1) {
- end = length;
- } else {
- end = ScriptRuntime.toInteger(args[1]);
- if (end < 0) {
- end += length;
- if (end < 0)
- end = 0;
- } else if (end > length) {
- end = length;
- }
- if (end < begin)
- end = begin;
- }
- return target.substring((int)begin, (int)end);
- }
- return target;
- }
-
-// #string_id_map#
-
- protected int findPrototypeId(String s)
- {
- int id;
-// #generated# Last update: 2007-05-01 22:11:49 EDT
- L0: { id = 0; String X = null; int c;
- L: switch (s.length()) {
- case 3: c=s.charAt(2);
- if (c=='b') { if (s.charAt(0)=='s' && s.charAt(1)=='u') {id=Id_sub; break L0;} }
- else if (c=='g') { if (s.charAt(0)=='b' && s.charAt(1)=='i') {id=Id_big; break L0;} }
- else if (c=='p') { if (s.charAt(0)=='s' && s.charAt(1)=='u') {id=Id_sup; break L0;} }
- break L;
- case 4: c=s.charAt(0);
- if (c=='b') { X="bold";id=Id_bold; }
- else if (c=='l') { X="link";id=Id_link; }
- break L;
- case 5: switch (s.charAt(4)) {
- case 'd': X="fixed";id=Id_fixed; break L;
- case 'e': X="slice";id=Id_slice; break L;
- case 'h': X="match";id=Id_match; break L;
- case 'k': X="blink";id=Id_blink; break L;
- case 'l': X="small";id=Id_small; break L;
- case 't': X="split";id=Id_split; break L;
- } break L;
- case 6: switch (s.charAt(1)) {
- case 'e': X="search";id=Id_search; break L;
- case 'h': X="charAt";id=Id_charAt; break L;
- case 'n': X="anchor";id=Id_anchor; break L;
- case 'o': X="concat";id=Id_concat; break L;
- case 'q': X="equals";id=Id_equals; break L;
- case 't': X="strike";id=Id_strike; break L;
- case 'u': X="substr";id=Id_substr; break L;
- } break L;
- case 7: switch (s.charAt(1)) {
- case 'a': X="valueOf";id=Id_valueOf; break L;
- case 'e': X="replace";id=Id_replace; break L;
- case 'n': X="indexOf";id=Id_indexOf; break L;
- case 't': X="italics";id=Id_italics; break L;
- } break L;
- case 8: c=s.charAt(4);
- if (c=='r') { X="toString";id=Id_toString; }
- else if (c=='s') { X="fontsize";id=Id_fontsize; }
- else if (c=='u') { X="toSource";id=Id_toSource; }
- break L;
- case 9: c=s.charAt(0);
- if (c=='f') { X="fontcolor";id=Id_fontcolor; }
- else if (c=='s') { X="substring";id=Id_substring; }
- break L;
- case 10: X="charCodeAt";id=Id_charCodeAt; break L;
- case 11: switch (s.charAt(2)) {
- case 'L': X="toLowerCase";id=Id_toLowerCase; break L;
- case 'U': X="toUpperCase";id=Id_toUpperCase; break L;
- case 'n': X="constructor";id=Id_constructor; break L;
- case 's': X="lastIndexOf";id=Id_lastIndexOf; break L;
- } break L;
- case 13: X="localeCompare";id=Id_localeCompare; break L;
- case 16: X="equalsIgnoreCase";id=Id_equalsIgnoreCase; break L;
- case 17: c=s.charAt(8);
- if (c=='L') { X="toLocaleLowerCase";id=Id_toLocaleLowerCase; }
- else if (c=='U') { X="toLocaleUpperCase";id=Id_toLocaleUpperCase; }
- break L;
- }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- ConstructorId_fromCharCode = -1,
-
- 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,
- Id_localeCompare = 34,
- Id_toLocaleLowerCase = 35,
- Id_toLocaleUpperCase = 36,
- MAX_PROTOTYPE_ID = 36;
-
-// #/string_id_map#
-
- private static final int
- ConstructorId_charAt = -Id_charAt,
- ConstructorId_charCodeAt = -Id_charCodeAt,
- ConstructorId_indexOf = -Id_indexOf,
- ConstructorId_lastIndexOf = -Id_lastIndexOf,
- ConstructorId_split = -Id_split,
- ConstructorId_substring = -Id_substring,
- ConstructorId_toLowerCase = -Id_toLowerCase,
- ConstructorId_toUpperCase = -Id_toUpperCase,
- ConstructorId_substr = -Id_substr,
- ConstructorId_concat = -Id_concat,
- ConstructorId_slice = -Id_slice,
- ConstructorId_equalsIgnoreCase = -Id_equalsIgnoreCase,
- ConstructorId_match = -Id_match,
- ConstructorId_search = -Id_search,
- ConstructorId_replace = -Id_replace,
- ConstructorId_localeCompare = -Id_localeCompare,
- ConstructorId_toLocaleLowerCase = -Id_toLocaleLowerCase;
-
- private String string;
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeWith.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeWith.java
deleted file mode 100644
index 83683b2..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeWith.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/* -*- 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;
-
-import java.io.Serializable;
-
-/**
- * This class implements the object lookup required for the
- * <code>with</code> statement.
- * It simply delegates every action to its prototype except
- * for operations on its parent.
- */
-public class NativeWith implements Scriptable, IdFunctionCall, Serializable {
-
- private static final long serialVersionUID = 1L;
-
- static void init(Scriptable scope, boolean sealed)
- {
- NativeWith obj = new NativeWith();
-
- obj.setParentScope(scope);
- obj.setPrototype(ScriptableObject.getObjectPrototype(scope));
-
- IdFunctionObject ctor = new IdFunctionObject(obj, FTAG, Id_constructor,
- "With", 0, scope);
- ctor.markAsConstructor(obj);
- if (sealed) {
- ctor.sealObject();
- }
- ctor.exportAsScopeProperty();
- }
-
- private NativeWith() {
- }
-
- protected NativeWith(Scriptable parent, Scriptable prototype) {
- this.parent = parent;
- this.prototype = prototype;
- }
-
- public String getClassName() {
- return "With";
- }
-
- public boolean has(String id, Scriptable start)
- {
- return prototype.has(id, prototype);
- }
-
- public boolean has(int index, Scriptable start)
- {
- return prototype.has(index, prototype);
- }
-
- public Object get(String id, Scriptable start)
- {
- if (start == this)
- start = prototype;
- return prototype.get(id, start);
- }
-
- public Object get(int index, Scriptable start)
- {
- if (start == this)
- start = prototype;
- return prototype.get(index, start);
- }
-
- public void put(String id, Scriptable start, Object value)
- {
- if (start == this)
- start = prototype;
- prototype.put(id, start, value);
- }
-
- public void put(int index, Scriptable start, Object value)
- {
- if (start == this)
- start = prototype;
- prototype.put(index, start, value);
- }
-
- public void delete(String id)
- {
- prototype.delete(id);
- }
-
- public void delete(int index)
- {
- prototype.delete(index);
- }
-
- public Scriptable getPrototype() {
- return prototype;
- }
-
- public void setPrototype(Scriptable prototype) {
- this.prototype = prototype;
- }
-
- public Scriptable getParentScope() {
- return parent;
- }
-
- public void setParentScope(Scriptable parent) {
- this.parent = parent;
- }
-
- public Object[] getIds() {
- return prototype.getIds();
- }
-
- public Object getDefaultValue(Class typeHint) {
- return prototype.getDefaultValue(typeHint);
- }
-
- public boolean hasInstance(Scriptable value) {
- return prototype.hasInstance(value);
- }
-
- /**
- * Must return null to continue looping or the final collection result.
- */
- protected Object updateDotQuery(boolean value)
- {
- // NativeWith itself does not support it
- throw new IllegalStateException();
- }
-
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (f.hasTag(FTAG)) {
- if (f.methodId() == Id_constructor) {
- throw Context.reportRuntimeError1("msg.cant.call.indirect", "With");
- }
- }
- throw f.unknown();
- }
-
- static boolean isWithFunction(Object functionObj)
- {
- if (functionObj instanceof IdFunctionObject) {
- IdFunctionObject f = (IdFunctionObject)functionObj;
- return f.hasTag(FTAG) && f.methodId() == Id_constructor;
- }
- return false;
- }
-
- static Object newWithSpecial(Context cx, Scriptable scope, Object[] args)
- {
- ScriptRuntime.checkDeprecated(cx, "With");
- scope = ScriptableObject.getTopLevelScope(scope);
- NativeWith thisObj = new NativeWith();
- thisObj.setPrototype(args.length == 0
- ? ScriptableObject.getClassPrototype(scope,
- "Object")
- : ScriptRuntime.toObject(cx, scope, args[0]));
- thisObj.setParentScope(scope);
- return thisObj;
- }
-
- private static final Object FTAG = new Object();
-
- private static final int
- Id_constructor = 1;
-
- protected Scriptable prototype;
- protected Scriptable parent;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Node.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Node.java
deleted file mode 100644
index 4298388..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Node.java
+++ /dev/null
@@ -1,1394 +0,0 @@
-/* -*- 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
- * Roshan James
- * Roger Lawrence
- * Mike McCabe
- *
- * 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;
-
-import java.util.Map;
-import java.util.LinkedHashMap;
-import java.util.Iterator;
-import java.util.Collections;
-
-/**
- * This class implements the root of the intermediate representation.
- *
- * @author Norris Boyd
- * @author Mike McCabe
- */
-
-public class Node
-{
- public static final int
- FUNCTION_PROP = 1,
- LOCAL_PROP = 2,
- LOCAL_BLOCK_PROP = 3,
- REGEXP_PROP = 4,
- CASEARRAY_PROP = 5,
- /*
- the following properties are defined and manipulated by the
- optimizer -
- TARGETBLOCK_PROP - the block referenced by a branch node
- VARIABLE_PROP - the variable referenced by a BIND or NAME node
- ISNUMBER_PROP - this node generates code on Number children and
- delivers a Number result (as opposed to Objects)
- DIRECTCALL_PROP - this call node should emit code to test the function
- object against the known class and call diret if it
- matches.
- */
-
- TARGETBLOCK_PROP = 6,
- VARIABLE_PROP = 7,
- ISNUMBER_PROP = 8,
- DIRECTCALL_PROP = 9,
- SPECIALCALL_PROP = 10,
- SKIP_INDEXES_PROP = 11, // array of skipped indexes of array literal
- OBJECT_IDS_PROP = 12, // array of properties for object literal
- INCRDECR_PROP = 13, // pre or post type of increment/decerement
- CATCH_SCOPE_PROP = 14, // index of catch scope block in catch
- LABEL_ID_PROP = 15, // label id: code generation uses it
- MEMBER_TYPE_PROP = 16, // type of element access operation
- NAME_PROP = 17, // property name
- CONTROL_BLOCK_PROP = 18, // flags a control block that can drop off
- PARENTHESIZED_PROP = 19, // expression is parenthesized
- GENERATOR_END_PROP = 20,
- DESTRUCTURING_ARRAY_LENGTH = 21,
- DESTRUCTURING_NAMES= 22,
- LAST_PROP = 22;
-
- // values of ISNUMBER_PROP to specify
- // which of the children are Number types
- public static final int
- BOTH = 0,
- LEFT = 1,
- RIGHT = 2;
-
- public static final int // values for SPECIALCALL_PROP
- NON_SPECIALCALL = 0,
- SPECIALCALL_EVAL = 1,
- SPECIALCALL_WITH = 2;
-
- public static final int // flags for INCRDECR_PROP
- DECR_FLAG = 0x1,
- POST_FLAG = 0x2;
-
- public static final int // flags for MEMBER_TYPE_PROP
- PROPERTY_FLAG = 0x1, // property access: element is valid name
- ATTRIBUTE_FLAG = 0x2, // x.@y or x..@y
- DESCENDANTS_FLAG = 0x4; // x..y or x..@i
-
- private static class NumberNode extends Node
- {
- NumberNode(double number)
- {
- super(Token.NUMBER);
- this.number = number;
- }
-
- double number;
- }
-
- private static class StringNode extends Node
- {
- StringNode(int type, String str) {
- super(type);
- this.str = str;
- }
-
- String str;
- Node.Scope scope;
- }
-
- public static class Jump extends Node
- {
- public Jump(int type)
- {
- super(type);
- }
-
- Jump(int type, int lineno)
- {
- super(type, lineno);
- }
-
- Jump(int type, Node child)
- {
- super(type, child);
- }
-
- Jump(int type, Node child, int lineno)
- {
- super(type, child, lineno);
- }
-
- public final Jump getJumpStatement()
- {
- if (!(type == Token.BREAK || type == Token.CONTINUE)) Kit.codeBug();
- return jumpNode;
- }
-
- public final void setJumpStatement(Jump jumpStatement)
- {
- if (!(type == Token.BREAK || type == Token.CONTINUE)) Kit.codeBug();
- if (jumpStatement == null) Kit.codeBug();
- if (this.jumpNode != null) Kit.codeBug(); //only once
- this.jumpNode = jumpStatement;
- }
-
- public final Node getDefault()
- {
- if (!(type == Token.SWITCH)) Kit.codeBug();
- return target2;
- }
-
- public final void setDefault(Node defaultTarget)
- {
- if (!(type == Token.SWITCH)) Kit.codeBug();
- if (defaultTarget.type != Token.TARGET) Kit.codeBug();
- if (target2 != null) Kit.codeBug(); //only once
- target2 = defaultTarget;
- }
-
- public final Node getFinally()
- {
- if (!(type == Token.TRY)) Kit.codeBug();
- return target2;
- }
-
- public final void setFinally(Node finallyTarget)
- {
- if (!(type == Token.TRY)) Kit.codeBug();
- if (finallyTarget.type != Token.TARGET) Kit.codeBug();
- if (target2 != null) Kit.codeBug(); //only once
- target2 = finallyTarget;
- }
-
- public final Jump getLoop()
- {
- if (!(type == Token.LABEL)) Kit.codeBug();
- return jumpNode;
- }
-
- public final void setLoop(Jump loop)
- {
- if (!(type == Token.LABEL)) Kit.codeBug();
- if (loop == null) Kit.codeBug();
- if (jumpNode != null) Kit.codeBug(); //only once
- jumpNode = loop;
- }
-
- public final Node getContinue()
- {
- if (type != Token.LOOP) Kit.codeBug();
- return target2;
- }
-
- public final void setContinue(Node continueTarget)
- {
- if (type != Token.LOOP) Kit.codeBug();
- if (continueTarget.type != Token.TARGET) Kit.codeBug();
- if (target2 != null) Kit.codeBug(); //only once
- target2 = continueTarget;
- }
-
- public Node target;
- private Node target2;
- private Jump jumpNode;
- }
-
- static class Symbol {
- Symbol(int declType, String name) {
- this.declType = declType;
- this.name = name;
- this.index = -1;
- }
- /**
- * One of Token.FUNCTION, Token.LP (for parameters), Token.VAR,
- * Token.LET, or Token.CONST
- */
- int declType;
- int index;
- String name;
- Node.Scope containingTable;
- }
-
- static class Scope extends Jump {
- public Scope(int nodeType) {
- super(nodeType);
- }
-
- public Scope(int nodeType, int lineno) {
- super(nodeType, lineno);
- }
-
- public Scope(int nodeType, Node n, int lineno) {
- super(nodeType, n, lineno);
- }
-
- /*
- * Creates a new scope node, moving symbol table information
- * from "scope" to the new node, and making "scope" a nested
- * scope contained by the new node.
- * Useful for injecting a new scope in a scope chain.
- */
- public static Scope splitScope(Scope scope) {
- Scope result = new Scope(scope.getType());
- result.symbolTable = scope.symbolTable;
- scope.symbolTable = null;
- result.parent = scope.parent;
- scope.parent = result;
- result.top = scope.top;
- return result;
- }
-
- public static void joinScopes(Scope source, Scope dest) {
- source.ensureSymbolTable();
- dest.ensureSymbolTable();
- if (!Collections.disjoint(source.symbolTable.keySet(),
- dest.symbolTable.keySet()))
- {
- throw Kit.codeBug();
- }
- dest.symbolTable.putAll(source.symbolTable);
- }
-
- public void setParent(Scope parent) {
- this.parent = parent;
- this.top = parent == null ? (ScriptOrFnNode)this : parent.top;
- }
-
- public Scope getParentScope() {
- return parent;
- }
-
- public Scope getDefiningScope(String name) {
- for (Scope sn=this; sn != null; sn = sn.parent) {
- if (sn.symbolTable == null)
- continue;
- if (sn.symbolTable.containsKey(name))
- return sn;
- }
- return null;
- }
-
- public Symbol getSymbol(String name) {
- return symbolTable == null ? null : symbolTable.get(name);
- }
-
- public void putSymbol(String name, Symbol symbol) {
- ensureSymbolTable();
- symbolTable.put(name, symbol);
- symbol.containingTable = this;
- top.addSymbol(symbol);
- }
-
- public Map<String,Symbol> getSymbolTable() {
- return symbolTable;
- }
-
- private void ensureSymbolTable() {
- if (symbolTable == null) {
- symbolTable = new LinkedHashMap<String,Symbol>(5);
- }
- }
-
- // Use LinkedHashMap so that the iteration order is the insertion order
- protected LinkedHashMap<String,Symbol> symbolTable;
- private Scope parent;
- private ScriptOrFnNode top;
- }
-
- private static class PropListItem
- {
- PropListItem next;
- int type;
- int intValue;
- Object objectValue;
- }
-
-
- public Node(int nodeType) {
- type = nodeType;
- }
-
- public Node(int nodeType, Node child) {
- type = nodeType;
- first = last = child;
- child.next = null;
- }
-
- public Node(int nodeType, Node left, Node right) {
- type = nodeType;
- first = left;
- last = right;
- left.next = right;
- right.next = null;
- }
-
- public Node(int nodeType, Node left, Node mid, Node right) {
- type = nodeType;
- first = left;
- last = right;
- left.next = mid;
- mid.next = right;
- right.next = null;
- }
-
- public Node(int nodeType, int line) {
- type = nodeType;
- lineno = line;
- }
-
- public Node(int nodeType, Node child, int line) {
- this(nodeType, child);
- lineno = line;
- }
-
- public Node(int nodeType, Node left, Node right, int line) {
- this(nodeType, left, right);
- lineno = line;
- }
-
- public Node(int nodeType, Node left, Node mid, Node right, int line) {
- this(nodeType, left, mid, right);
- lineno = line;
- }
-
- public static Node newNumber(double number) {
- return new NumberNode(number);
- }
-
- public static Node newString(String str) {
- return new StringNode(Token.STRING, str);
- }
-
- public static Node newString(int type, String str) {
- return new StringNode(type, str);
- }
-
- public int getType() {
- return type;
- }
-
- public void setType(int type) {
- this.type = type;
- }
-
- public boolean hasChildren() {
- return first != null;
- }
-
- public Node getFirstChild() {
- return first;
- }
-
- public Node getLastChild() {
- return last;
- }
-
- public Node getNext() {
- return next;
- }
-
- public Node getChildBefore(Node child) {
- if (child == first)
- return null;
- Node n = first;
- while (n.next != child) {
- n = n.next;
- if (n == null)
- throw new RuntimeException("node is not a child");
- }
- return n;
- }
-
- public Node getLastSibling() {
- Node n = this;
- while (n.next != null) {
- n = n.next;
- }
- return n;
- }
-
- public void addChildToFront(Node child) {
- child.next = first;
- first = child;
- if (last == null) {
- last = child;
- }
- }
-
- public void addChildToBack(Node child) {
- child.next = null;
- if (last == null) {
- first = last = child;
- return;
- }
- last.next = child;
- last = child;
- }
-
- public void addChildrenToFront(Node children) {
- Node lastSib = children.getLastSibling();
- lastSib.next = first;
- first = children;
- if (last == null) {
- last = lastSib;
- }
- }
-
- public void addChildrenToBack(Node children) {
- if (last != null) {
- last.next = children;
- }
- last = children.getLastSibling();
- if (first == null) {
- first = children;
- }
- }
-
- /**
- * Add 'child' before 'node'.
- */
- public void addChildBefore(Node newChild, Node node) {
- if (newChild.next != null)
- throw new RuntimeException(
- "newChild had siblings in addChildBefore");
- if (first == node) {
- newChild.next = first;
- first = newChild;
- return;
- }
- Node prev = getChildBefore(node);
- addChildAfter(newChild, prev);
- }
-
- /**
- * Add 'child' after 'node'.
- */
- public void addChildAfter(Node newChild, Node node) {
- if (newChild.next != null)
- throw new RuntimeException(
- "newChild had siblings in addChildAfter");
- newChild.next = node.next;
- node.next = newChild;
- if (last == node)
- last = newChild;
- }
-
- public void removeChild(Node child) {
- Node prev = getChildBefore(child);
- if (prev == null)
- first = first.next;
- else
- prev.next = child.next;
- if (child == last) last = prev;
- child.next = null;
- }
-
- public void replaceChild(Node child, Node newChild) {
- newChild.next = child.next;
- if (child == first) {
- first = newChild;
- } else {
- Node prev = getChildBefore(child);
- prev.next = newChild;
- }
- if (child == last)
- last = newChild;
- child.next = null;
- }
-
- public void replaceChildAfter(Node prevChild, Node newChild) {
- Node child = prevChild.next;
- newChild.next = child.next;
- prevChild.next = newChild;
- if (child == last)
- last = newChild;
- child.next = null;
- }
-
- private static final String propToString(int propType)
- {
- if (Token.printTrees) {
- // If Context.printTrees is false, the compiler
- // can remove all these strings.
- switch (propType) {
- case FUNCTION_PROP: return "function";
- case LOCAL_PROP: return "local";
- case LOCAL_BLOCK_PROP: return "local_block";
- case REGEXP_PROP: return "regexp";
- case CASEARRAY_PROP: return "casearray";
-
- case TARGETBLOCK_PROP: return "targetblock";
- case VARIABLE_PROP: return "variable";
- case ISNUMBER_PROP: return "isnumber";
- case DIRECTCALL_PROP: return "directcall";
-
- case SPECIALCALL_PROP: return "specialcall";
- case SKIP_INDEXES_PROP: return "skip_indexes";
- case OBJECT_IDS_PROP: return "object_ids_prop";
- case INCRDECR_PROP: return "incrdecr_prop";
- case CATCH_SCOPE_PROP: return "catch_scope_prop";
- case LABEL_ID_PROP: return "label_id_prop";
- case MEMBER_TYPE_PROP: return "member_type_prop";
- case NAME_PROP: return "name_prop";
- case CONTROL_BLOCK_PROP: return "control_block_prop";
- case PARENTHESIZED_PROP: return "parenthesized_prop";
- case GENERATOR_END_PROP: return "generator_end";
- case DESTRUCTURING_ARRAY_LENGTH:
- return "destructuring_array_length";
- case DESTRUCTURING_NAMES:return "destructuring_names";
-
- default: Kit.codeBug();
- }
- }
- return null;
- }
-
- private PropListItem lookupProperty(int propType)
- {
- PropListItem x = propListHead;
- while (x != null && propType != x.type) {
- x = x.next;
- }
- return x;
- }
-
- private PropListItem ensureProperty(int propType)
- {
- PropListItem item = lookupProperty(propType);
- if (item == null) {
- item = new PropListItem();
- item.type = propType;
- item.next = propListHead;
- propListHead = item;
- }
- return item;
- }
-
- public void removeProp(int propType)
- {
- PropListItem x = propListHead;
- if (x != null) {
- PropListItem prev = null;
- while (x.type != propType) {
- prev = x;
- x = x.next;
- if (x == null) { return; }
- }
- if (prev == null) {
- propListHead = x.next;
- } else {
- prev.next = x.next;
- }
- }
- }
-
- public Object getProp(int propType)
- {
- PropListItem item = lookupProperty(propType);
- if (item == null) { return null; }
- return item.objectValue;
- }
-
- public int getIntProp(int propType, int defaultValue)
- {
- PropListItem item = lookupProperty(propType);
- if (item == null) { return defaultValue; }
- return item.intValue;
- }
-
- public int getExistingIntProp(int propType)
- {
- PropListItem item = lookupProperty(propType);
- if (item == null) { Kit.codeBug(); }
- return item.intValue;
- }
-
- public void putProp(int propType, Object prop)
- {
- if (prop == null) {
- removeProp(propType);
- } else {
- PropListItem item = ensureProperty(propType);
- item.objectValue = prop;
- }
- }
-
- public void putIntProp(int propType, int prop)
- {
- PropListItem item = ensureProperty(propType);
- item.intValue = prop;
- }
-
- public int getLineno() {
- return lineno;
- }
-
- /** Can only be called when <tt>getType() == Token.NUMBER</tt> */
- public final double getDouble() {
- return ((NumberNode)this).number;
- }
-
- public final void setDouble(double number) {
- ((NumberNode)this).number = number;
- }
-
- /** Can only be called when node has String context. */
- public final String getString() {
- return ((StringNode)this).str;
- }
-
- /** Can only be called when node has String context. */
- public final void setString(String s) {
- if (s == null) Kit.codeBug();
- ((StringNode)this).str = s;
- }
-
- /** Can only be called when node has String context. */
- public final Scope getScope() {
- return ((StringNode)this).scope;
- }
-
- /** Can only be called when node has String context. */
- public final void setScope(Scope s) {
- if (s == null) Kit.codeBug();
- if (!(this instanceof StringNode)) {
- throw Kit.codeBug();
- }
- ((StringNode)this).scope = s;
- }
-
- public static Node newTarget()
- {
- return new Node(Token.TARGET);
- }
-
- public final int labelId()
- {
- if (type != Token.TARGET && type != Token.YIELD) Kit.codeBug();
- return getIntProp(LABEL_ID_PROP, -1);
- }
-
- public void labelId(int labelId)
- {
- if (type != Token.TARGET && type != Token.YIELD) Kit.codeBug();
- putIntProp(LABEL_ID_PROP, labelId);
- }
-
-
- /**
- * Does consistent-return analysis on the function body when strict mode is
- * enabled.
- *
- * function (x) { return (x+1) }
- * is ok, but
- * function (x) { if (x < 0) return (x+1); }
- * is not becuase the function can potentially return a value when the
- * condition is satisfied and if not, the function does not explicitly
- * return value.
- *
- * This extends to checking mismatches such as "return" and "return <value>"
- * used in the same function. Warnings are not emitted if inconsistent
- * returns exist in code that can be statically shown to be unreachable.
- * Ex.
- * function (x) { while (true) { ... if (..) { return value } ... } }
- * emits no warning. However if the loop had a break statement, then a
- * warning would be emitted.
- *
- * The consistency analysis looks at control structures such as loops, ifs,
- * switch, try-catch-finally blocks, examines the reachable code paths and
- * warns the user about an inconsistent set of termination possibilities.
- *
- * Caveat: Since the parser flattens many control structures into almost
- * straight-line code with gotos, it makes such analysis hard. Hence this
- * analyser is written to taken advantage of patterns of code generated by
- * the parser (for loops, try blocks and such) and does not do a full
- * control flow analysis of the gotos and break/continue statements.
- * Future changes to the parser will affect this analysis.
- */
-
- /**
- * These flags enumerate the possible ways a statement/function can
- * terminate. These flags are used by endCheck() and by the Parser to
- * detect inconsistent return usage.
- *
- * END_UNREACHED is reserved for code paths that are assumed to always be
- * able to execute (example: throw, continue)
- *
- * END_DROPS_OFF indicates if the statement can transfer control to the
- * next one. Statement such as return dont. A compound statement may have
- * some branch that drops off control to the next statement.
- *
- * END_RETURNS indicates that the statement can return (without arguments)
- * END_RETURNS_VALUE indicates that the statement can return a value.
- *
- * A compound statement such as
- * if (condition) {
- * return value;
- * }
- * Will be detected as (END_DROPS_OFF | END_RETURN_VALUE) by endCheck()
- */
- static final int END_UNREACHED = 0;
- static final int END_DROPS_OFF = 1;
- static final int END_RETURNS = 2;
- static final int END_RETURNS_VALUE = 4;
- static final int END_YIELDS = 8;
-
- /**
- * Checks that every return usage in a function body is consistent with the
- * requirements of strict-mode.
- * @return true if the function satisfies strict mode requirement.
- */
- public boolean hasConsistentReturnUsage()
- {
- int n = endCheck();
- return (n & END_RETURNS_VALUE) == 0 ||
- (n & (END_DROPS_OFF|END_RETURNS|END_YIELDS)) == 0;
- }
-
- /**
- * Returns in the then and else blocks must be consistent with each other.
- * If there is no else block, then the return statement can fall through.
- * @return logical OR of END_* flags
- */
- private int endCheckIf()
- {
- Node th, el;
- int rv = END_UNREACHED;
-
- th = next;
- el = ((Jump)this).target;
-
- rv = th.endCheck();
-
- if (el != null)
- rv |= el.endCheck();
- else
- rv |= END_DROPS_OFF;
-
- return rv;
- }
-
- /**
- * Consistency of return statements is checked between the case statements.
- * If there is no default, then the switch can fall through. If there is a
- * default,we check to see if all code paths in the default return or if
- * there is a code path that can fall through.
- * @return logical OR of END_* flags
- */
- private int endCheckSwitch()
- {
- Node n;
- int rv = END_UNREACHED;
-
- // examine the cases
- for (n = first.next; n != null; n = n.next)
- {
- if (n.type == Token.CASE) {
- rv |= ((Jump)n).target.endCheck();
- } else
- break;
- }
-
- // we don't care how the cases drop into each other
- rv &= ~END_DROPS_OFF;
-
- // examine the default
- n = ((Jump)this).getDefault();
- if (n != null)
- rv |= n.endCheck();
- else
- rv |= END_DROPS_OFF;
-
- // remove the switch block
- rv |= getIntProp(CONTROL_BLOCK_PROP, END_UNREACHED);
-
- return rv;
- }
-
- /**
- * If the block has a finally, return consistency is checked in the
- * finally block. If all code paths in the finally returns, then the
- * returns in the try-catch blocks don't matter. If there is a code path
- * that does not return or if there is no finally block, the returns
- * of the try and catch blocks are checked for mismatch.
- * @return logical OR of END_* flags
- */
- private int endCheckTry()
- {
- Node n;
- int rv = END_UNREACHED;
-
- // check the finally if it exists
- n = ((Jump)this).getFinally();
- if(n != null) {
- rv = n.next.first.endCheck();
- } else {
- rv = END_DROPS_OFF;
- }
-
- // if the finally block always returns, then none of the returns
- // in the try or catch blocks matter
- if ((rv & END_DROPS_OFF) != 0) {
- rv &= ~END_DROPS_OFF;
-
- // examine the try block
- rv |= first.endCheck();
-
- // check each catch block
- n = ((Jump)this).target;
- if (n != null)
- {
- // point to the first catch_scope
- for (n = n.next.first; n != null; n = n.next.next)
- {
- // check the block of user code in the catch_scope
- rv |= n.next.first.next.first.endCheck();
- }
- }
- }
-
- return rv;
- }
-
- /**
- * Return statement in the loop body must be consistent. The default
- * assumption for any kind of a loop is that it will eventually terminate.
- * The only exception is a loop with a constant true condition. Code that
- * follows such a loop is examined only if one can statically determine
- * that there is a break out of the loop.
- * for(<> ; <>; <>) {}
- * for(<> in <> ) {}
- * while(<>) { }
- * do { } while(<>)
- * @return logical OR of END_* flags
- */
- private int endCheckLoop()
- {
- Node n;
- int rv = END_UNREACHED;
-
- // To find the loop body, we look at the second to last node of the
- // loop node, which should be the predicate that the loop should
- // satisfy.
- // The target of the predicate is the loop-body for all 4 kinds of
- // loops.
- for (n = first; n.next != last; n = n.next) {
- /* skip */
- }
- if (n.type != Token.IFEQ)
- return END_DROPS_OFF;
-
- // The target's next is the loop body block
- rv = ((Jump)n).target.next.endCheck();
-
- // check to see if the loop condition is true
- if (n.first.type == Token.TRUE)
- rv &= ~END_DROPS_OFF;
-
- // look for effect of breaks
- rv |= getIntProp(CONTROL_BLOCK_PROP, END_UNREACHED);
-
- return rv;
- }
-
-
- /**
- * A general block of code is examined statement by statement. If any
- * statement (even compound ones) returns in all branches, then subsequent
- * statements are not examined.
- * @return logical OR of END_* flags
- */
- private int endCheckBlock()
- {
- Node n;
- int rv = END_DROPS_OFF;
-
- // check each statment and if the statement can continue onto the next
- // one, then check the next statement
- for (n=first; ((rv & END_DROPS_OFF) != 0) && n != null; n = n.next)
- {
- rv &= ~END_DROPS_OFF;
- rv |= n.endCheck();
- }
- return rv;
- }
-
- /**
- * A labelled statement implies that there maybe a break to the label. The
- * function processes the labelled statement and then checks the
- * CONTROL_BLOCK_PROP property to see if there is ever a break to the
- * particular label.
- * @return logical OR of END_* flags
- */
- private int endCheckLabel()
- {
- int rv = END_UNREACHED;
-
- rv = next.endCheck();
- rv |= getIntProp(CONTROL_BLOCK_PROP, END_UNREACHED);
-
- return rv;
- }
-
- /**
- * When a break is encountered annotate the statement being broken
- * out of by setting its CONTROL_BLOCK_PROP property.
- * @return logical OR of END_* flags
- */
- private int endCheckBreak()
- {
- Node n = ((Jump) this).jumpNode;
- n.putIntProp(CONTROL_BLOCK_PROP, END_DROPS_OFF);
- return END_UNREACHED;
- }
-
- /**
- * endCheck() examines the body of a function, doing a basic reachability
- * analysis and returns a combination of flags END_* flags that indicate
- * how the function execution can terminate. These constitute only the
- * pessimistic set of termination conditions. It is possible that at
- * runtime certain code paths will never be actually taken. Hence this
- * analysis will flag errors in cases where there may not be errors.
- * @return logical OR of END_* flags
- */
- private int endCheck()
- {
- switch(type)
- {
- case Token.BREAK:
- return endCheckBreak();
-
- case Token.EXPR_VOID:
- if (this.first != null)
- return first.endCheck();
- return END_DROPS_OFF;
-
- case Token.YIELD:
- return END_YIELDS;
-
- case Token.CONTINUE:
- case Token.THROW:
- return END_UNREACHED;
-
- case Token.RETURN:
- if (this.first != null)
- return END_RETURNS_VALUE;
- else
- return END_RETURNS;
-
- case Token.TARGET:
- if (next != null)
- return next.endCheck();
- else
- return END_DROPS_OFF;
-
- case Token.LOOP:
- return endCheckLoop();
-
- case Token.LOCAL_BLOCK:
- case Token.BLOCK:
- // there are several special kinds of blocks
- if (first == null)
- return END_DROPS_OFF;
-
- switch(first.type) {
- case Token.LABEL:
- return first.endCheckLabel();
-
- case Token.IFNE:
- return first.endCheckIf();
-
- case Token.SWITCH:
- return first.endCheckSwitch();
-
- case Token.TRY:
- return first.endCheckTry();
-
- default:
- return endCheckBlock();
- }
-
- default:
- return END_DROPS_OFF;
- }
- }
-
- public boolean hasSideEffects()
- {
- switch (type) {
- case Token.EXPR_VOID:
- case Token.COMMA:
- if (last != null)
- return last.hasSideEffects();
- else
- return true;
-
- case Token.HOOK:
- if (first == null ||
- first.next == null ||
- first.next.next == null)
- Kit.codeBug();
- return first.next.hasSideEffects() &&
- first.next.next.hasSideEffects();
-
- case Token.ERROR: // Avoid cascaded error messages
- case Token.EXPR_RESULT:
- case Token.ASSIGN:
- case Token.ASSIGN_ADD:
- case Token.ASSIGN_SUB:
- case Token.ASSIGN_MUL:
- case Token.ASSIGN_DIV:
- case Token.ASSIGN_MOD:
- case Token.ASSIGN_BITOR:
- case Token.ASSIGN_BITXOR:
- case Token.ASSIGN_BITAND:
- case Token.ASSIGN_LSH:
- case Token.ASSIGN_RSH:
- case Token.ASSIGN_URSH:
- case Token.ENTERWITH:
- case Token.LEAVEWITH:
- case Token.RETURN:
- case Token.GOTO:
- case Token.IFEQ:
- case Token.IFNE:
- case Token.NEW:
- case Token.DELPROP:
- case Token.SETNAME:
- case Token.SETPROP:
- case Token.SETELEM:
- case Token.CALL:
- case Token.THROW:
- case Token.RETHROW:
- case Token.SETVAR:
- case Token.CATCH_SCOPE:
- case Token.RETURN_RESULT:
- case Token.SET_REF:
- case Token.DEL_REF:
- case Token.REF_CALL:
- case Token.TRY:
- case Token.SEMI:
- case Token.INC:
- case Token.DEC:
- case Token.EXPORT:
- case Token.IMPORT:
- case Token.IF:
- case Token.ELSE:
- case Token.SWITCH:
- case Token.WHILE:
- case Token.DO:
- case Token.FOR:
- case Token.BREAK:
- case Token.CONTINUE:
- case Token.VAR:
- case Token.CONST:
- case Token.LET:
- case Token.LETEXPR:
- case Token.WITH:
- case Token.WITHEXPR:
- case Token.CATCH:
- case Token.FINALLY:
- case Token.BLOCK:
- case Token.LABEL:
- case Token.TARGET:
- case Token.LOOP:
- case Token.JSR:
- case Token.SETPROP_OP:
- case Token.SETELEM_OP:
- case Token.LOCAL_BLOCK:
- case Token.SET_REF_OP:
- case Token.YIELD:
- return true;
-
- default:
- return false;
- }
- }
-
- public String toString()
- {
- if (Token.printTrees) {
- StringBuffer sb = new StringBuffer();
- toString(new ObjToIntMap(), sb);
- return sb.toString();
- }
- return String.valueOf(type);
- }
-
- private void toString(ObjToIntMap printIds, StringBuffer sb)
- {
- if (Token.printTrees) {
- sb.append(Token.name(type));
- if (this instanceof StringNode) {
- sb.append(' ');
- sb.append(getString());
- Scope scope = getScope();
- if (scope != null) {
- sb.append("[scope: ");
- appendPrintId(scope, printIds, sb);
- sb.append("]");
- }
- } else if (this instanceof Node.Scope) {
- if (this instanceof ScriptOrFnNode) {
- ScriptOrFnNode sof = (ScriptOrFnNode)this;
- if (this instanceof FunctionNode) {
- FunctionNode fn = (FunctionNode)this;
- sb.append(' ');
- sb.append(fn.getFunctionName());
- }
- sb.append(" [source name: ");
- sb.append(sof.getSourceName());
- sb.append("] [encoded source length: ");
- sb.append(sof.getEncodedSourceEnd()
- - sof.getEncodedSourceStart());
- sb.append("] [base line: ");
- sb.append(sof.getBaseLineno());
- sb.append("] [end line: ");
- sb.append(sof.getEndLineno());
- sb.append(']');
- }
- if (((Node.Scope)this).symbolTable != null) {
- sb.append(" [scope ");
- appendPrintId(this, printIds, sb);
- sb.append(": ");
- Iterator iter = ((Node.Scope) this).symbolTable.keySet()
- .iterator();
- while (iter.hasNext()) {
- sb.append(iter.next());
- sb.append(" ");
- }
- sb.append("]");
- }
- } else if (this instanceof Jump) {
- Jump jump = (Jump)this;
- if (type == Token.BREAK || type == Token.CONTINUE) {
- sb.append(" [label: ");
- appendPrintId(jump.getJumpStatement(), printIds, sb);
- sb.append(']');
- } else if (type == Token.TRY) {
- Node catchNode = jump.target;
- Node finallyTarget = jump.getFinally();
- if (catchNode != null) {
- sb.append(" [catch: ");
- appendPrintId(catchNode, printIds, sb);
- sb.append(']');
- }
- if (finallyTarget != null) {
- sb.append(" [finally: ");
- appendPrintId(finallyTarget, printIds, sb);
- sb.append(']');
- }
- } else if (type == Token.LABEL || type == Token.LOOP
- || type == Token.SWITCH)
- {
- sb.append(" [break: ");
- appendPrintId(jump.target, printIds, sb);
- sb.append(']');
- if (type == Token.LOOP) {
- sb.append(" [continue: ");
- appendPrintId(jump.getContinue(), printIds, sb);
- sb.append(']');
- }
- } else {
- sb.append(" [target: ");
- appendPrintId(jump.target, printIds, sb);
- sb.append(']');
- }
- } else if (type == Token.NUMBER) {
- sb.append(' ');
- sb.append(getDouble());
- } else if (type == Token.TARGET) {
- sb.append(' ');
- appendPrintId(this, printIds, sb);
- }
- if (lineno != -1) {
- sb.append(' ');
- sb.append(lineno);
- }
-
- for (PropListItem x = propListHead; x != null; x = x.next) {
- int type = x.type;
- sb.append(" [");
- sb.append(propToString(type));
- sb.append(": ");
- String value;
- switch (type) {
- case TARGETBLOCK_PROP : // can't add this as it recurses
- value = "target block property";
- break;
- case LOCAL_BLOCK_PROP : // can't add this as it is dull
- value = "last local block";
- break;
- case ISNUMBER_PROP:
- switch (x.intValue) {
- case BOTH:
- value = "both";
- break;
- case RIGHT:
- value = "right";
- break;
- case LEFT:
- value = "left";
- break;
- default:
- throw Kit.codeBug();
- }
- break;
- case SPECIALCALL_PROP:
- switch (x.intValue) {
- case SPECIALCALL_EVAL:
- value = "eval";
- break;
- case SPECIALCALL_WITH:
- value = "with";
- break;
- default:
- // NON_SPECIALCALL should not be stored
- throw Kit.codeBug();
- }
- break;
- case OBJECT_IDS_PROP: {
- Object[] a = (Object[]) x.objectValue;
- value = "[";
- for (int i=0; i < a.length; i++) {
- value += a[i].toString();
- if (i+1 < a.length)
- value += ", ";
- }
- value += "]";
- break;
- }
- default :
- Object obj = x.objectValue;
- if (obj != null) {
- value = obj.toString();
- } else {
- value = String.valueOf(x.intValue);
- }
- break;
- }
- sb.append(value);
- sb.append(']');
- }
- }
- }
-
- public String toStringTree(ScriptOrFnNode treeTop) {
- if (Token.printTrees) {
- StringBuffer sb = new StringBuffer();
- toStringTreeHelper(treeTop, this, null, 0, sb);
- return sb.toString();
- }
- return null;
- }
-
- private static void toStringTreeHelper(ScriptOrFnNode treeTop, Node n,
- ObjToIntMap printIds,
- int level, StringBuffer sb)
- {
- if (Token.printTrees) {
- if (printIds == null) {
- printIds = new ObjToIntMap();
- generatePrintIds(treeTop, printIds);
- }
- for (int i = 0; i != level; ++i) {
- sb.append(" ");
- }
- n.toString(printIds, sb);
- sb.append('\n');
- for (Node cursor = n.getFirstChild(); cursor != null;
- cursor = cursor.getNext())
- {
- if (cursor.getType() == Token.FUNCTION) {
- int fnIndex = cursor.getExistingIntProp(Node.FUNCTION_PROP);
- FunctionNode fn = treeTop.getFunctionNode(fnIndex);
- toStringTreeHelper(fn, fn, null, level + 1, sb);
- } else {
- toStringTreeHelper(treeTop, cursor, printIds, level + 1, sb);
- }
- }
- }
- }
-
- private static void generatePrintIds(Node n, ObjToIntMap map)
- {
- if (Token.printTrees) {
- map.put(n, map.size());
- for (Node cursor = n.getFirstChild(); cursor != null;
- cursor = cursor.getNext())
- {
- generatePrintIds(cursor, map);
- }
- }
- }
-
- private static void appendPrintId(Node n, ObjToIntMap printIds,
- StringBuffer sb)
- {
- if (Token.printTrees) {
- if (n != null) {
- int id = printIds.get(n, -1);
- sb.append('#');
- if (id != -1) {
- sb.append(id + 1);
- } else {
- sb.append("<not_available>");
- }
- }
- }
- }
-
- int type; // type of the node; Token.NAME for example
- Node next; // next sibling
- private Node first; // first element of a linked list of children
- private Node last; // last element of a linked list of children
- protected int lineno = -1;
-
- /*APPJET*/public int statementEndLineNum = -1;
-
- /**
- * Linked list of properties. Since vast majority of nodes would have
- * no more then 2 properties, linked list saves memory and provides
- * fast lookup. If this does not holds, propListHead can be replaced
- * by UintMap.
- */
- private PropListItem propListHead;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NodeTransformer.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NodeTransformer.java
deleted file mode 100644
index 201c6f2..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NodeTransformer.java
+++ /dev/null
@@ -1,565 +0,0 @@
-/* -*- 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
- * Bob Jervis
- * Roger Lawrence
- * Mike McCabe
- *
- * 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;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class transforms a tree to a lower-level representation for codegen.
- *
- * @see Node
- * @author Norris Boyd
- */
-
-public class NodeTransformer
-{
-
- public NodeTransformer()
- {
- }
-
- public final void transform(ScriptOrFnNode tree)
- {
- transformCompilationUnit(tree);
- for (int i = 0; i != tree.getFunctionCount(); ++i) {
- FunctionNode fn = tree.getFunctionNode(i);
- transform(fn);
- }
- }
-
- private void transformCompilationUnit(ScriptOrFnNode tree)
- {
- loops = new ObjArray();
- loopEnds = new ObjArray();
-
- // to save against upchecks if no finally blocks are used.
- hasFinally = false;
-
- // Flatten all only if we are not using scope objects for block scope
- boolean createScopeObjects = tree.getType() != Token.FUNCTION ||
- ((FunctionNode)tree).requiresActivation();
- tree.flattenSymbolTable(!createScopeObjects);
-
- //uncomment to print tree before transformation
- //if (Token.printTrees) System.out.println(tree.toStringTree(tree));
- transformCompilationUnit_r(tree, tree, tree, createScopeObjects);
- }
-
- private void transformCompilationUnit_r(final ScriptOrFnNode tree,
- final Node parent,
- Node.Scope scope,
- boolean createScopeObjects)
- {
- Node node = null;
- siblingLoop:
- for (;;) {
- Node previous = null;
- if (node == null) {
- node = parent.getFirstChild();
- } else {
- previous = node;
- node = node.getNext();
- }
- if (node == null) {
- break;
- }
-
- int type = node.getType();
- if (createScopeObjects &&
- (type == Token.BLOCK || type == Token.LOOP ||
- type == Token.ARRAYCOMP) &&
- (node instanceof Node.Scope))
- {
- Node.Scope newScope = (Node.Scope) node;
- if (newScope.symbolTable != null) {
- // transform to let statement so we get a with statement
- // created to contain scoped let variables
- Node let = new Node(type == Token.ARRAYCOMP ? Token.LETEXPR
- : Token.LET);
- Node innerLet = new Node(Token.LET);
- let.addChildToBack(innerLet);
- for (String name: newScope.symbolTable.keySet()) {
- innerLet.addChildToBack(Node.newString(Token.NAME, name));
- }
- newScope.symbolTable = null; // so we don't transform again
- Node oldNode = node;
- node = replaceCurrent(parent, previous, node, let);
- type = node.getType();
- let.addChildToBack(oldNode);
- }
- }
-
- switch (type) {
-
- case Token.LABEL:
- case Token.SWITCH:
- case Token.LOOP:
- loops.push(node);
- loopEnds.push(((Node.Jump)node).target);
- break;
-
- case Token.WITH:
- {
- loops.push(node);
- Node leave = node.getNext();
- if (leave.getType() != Token.LEAVEWITH) {
- Kit.codeBug();
- }
- loopEnds.push(leave);
- break;
- }
-
- case Token.TRY:
- {
- Node.Jump jump = (Node.Jump)node;
- Node finallytarget = jump.getFinally();
- if (finallytarget != null) {
- hasFinally = true;
- loops.push(node);
- loopEnds.push(finallytarget);
- }
- break;
- }
-
- case Token.TARGET:
- case Token.LEAVEWITH:
- if (!loopEnds.isEmpty() && loopEnds.peek() == node) {
- loopEnds.pop();
- loops.pop();
- }
- break;
-
- case Token.YIELD:
- ((FunctionNode)tree).addResumptionPoint(node);
- break;
-
- case Token.RETURN:
- {
- boolean isGenerator = tree.getType() == Token.FUNCTION
- && ((FunctionNode)tree).isGenerator();
- if (isGenerator) {
- node.putIntProp(Node.GENERATOR_END_PROP, 1);
- }
- /* If we didn't support try/finally, it wouldn't be
- * necessary to put LEAVEWITH nodes here... but as
- * we do need a series of JSR FINALLY nodes before
- * each RETURN, we need to ensure that each finally
- * block gets the correct scope... which could mean
- * that some LEAVEWITH nodes are necessary.
- */
- if (!hasFinally)
- break; // skip the whole mess.
- Node unwindBlock = null;
- for (int i=loops.size()-1; i >= 0; i--) {
- Node n = (Node) loops.get(i);
- int elemtype = n.getType();
- if (elemtype == Token.TRY || elemtype == Token.WITH) {
- Node unwind;
- if (elemtype == Token.TRY) {
- Node.Jump jsrnode = new Node.Jump(Token.JSR);
- Node jsrtarget = ((Node.Jump)n).getFinally();
- jsrnode.target = jsrtarget;
- unwind = jsrnode;
- } else {
- unwind = new Node(Token.LEAVEWITH);
- }
- if (unwindBlock == null) {
- unwindBlock = new Node(Token.BLOCK,
- node.getLineno());
- }
- unwindBlock.addChildToBack(unwind);
- }
- }
- if (unwindBlock != null) {
- Node returnNode = node;
- Node returnExpr = returnNode.getFirstChild();
- node = replaceCurrent(parent, previous, node, unwindBlock);
- if (returnExpr == null || isGenerator) {
- unwindBlock.addChildToBack(returnNode);
- } else {
- Node store = new Node(Token.EXPR_RESULT, returnExpr);
- unwindBlock.addChildToFront(store);
- returnNode = new Node(Token.RETURN_RESULT);
- unwindBlock.addChildToBack(returnNode);
- // transform return expression
- transformCompilationUnit_r(tree, store, scope,
- createScopeObjects);
- }
- // skip transformCompilationUnit_r to avoid infinite loop
- continue siblingLoop;
- }
- break;
- }
-
- case Token.BREAK:
- case Token.CONTINUE:
- {
- Node.Jump jump = (Node.Jump)node;
- Node.Jump jumpStatement = jump.getJumpStatement();
- if (jumpStatement == null) Kit.codeBug();
-
- for (int i = loops.size(); ;) {
- if (i == 0) {
- // Parser/IRFactory ensure that break/continue
- // always has a jump statement associated with it
- // which should be found
- throw Kit.codeBug();
- }
- --i;
- Node n = (Node) loops.get(i);
- if (n == jumpStatement) {
- break;
- }
-
- int elemtype = n.getType();
- if (elemtype == Token.WITH) {
- Node leave = new Node(Token.LEAVEWITH);
- previous = addBeforeCurrent(parent, previous, node,
- leave);
- } else if (elemtype == Token.TRY) {
- Node.Jump tryNode = (Node.Jump)n;
- Node.Jump jsrFinally = new Node.Jump(Token.JSR);
- jsrFinally.target = tryNode.getFinally();
- previous = addBeforeCurrent(parent, previous, node,
- jsrFinally);
- }
- }
-
- if (type == Token.BREAK) {
- jump.target = jumpStatement.target;
- } else {
- jump.target = jumpStatement.getContinue();
- }
- jump.setType(Token.GOTO);
-
- break;
- }
-
- case Token.CALL:
- visitCall(node, tree);
- break;
-
- case Token.NEW:
- visitNew(node, tree);
- break;
-
- case Token.LETEXPR:
- case Token.LET: {
- Node child = node.getFirstChild();
- if (child.getType() == Token.LET) {
- // We have a let statement or expression rather than a
- // let declaration
- boolean createWith = tree.getType() != Token.FUNCTION
- || ((FunctionNode)tree).requiresActivation();
- node = visitLet(createWith, parent, previous, node);
- break;
- } else {
- // fall through to process let declaration...
- }
- }
- /* fall through */
- case Token.CONST:
- case Token.VAR:
- {
- Node result = new Node(Token.BLOCK);
- for (Node cursor = node.getFirstChild(); cursor != null;) {
- // Move cursor to next before createAssignment gets chance
- // to change n.next
- Node n = cursor;
- cursor = cursor.getNext();
- if (n.getType() == Token.NAME) {
- if (!n.hasChildren())
- continue;
- Node init = n.getFirstChild();
- n.removeChild(init);
- n.setType(Token.BINDNAME);
- n = new Node(type == Token.CONST ?
- Token.SETCONST :
- Token.SETNAME,
- n, init);
- } else {
- // May be a destructuring assignment already transformed
- // to a LETEXPR
- if (n.getType() != Token.LETEXPR)
- throw Kit.codeBug();
- }
- Node pop = new Node(Token.EXPR_VOID, n, node.getLineno());
- result.addChildToBack(pop);
- }
- node = replaceCurrent(parent, previous, node, result);
- break;
- }
-
- case Token.TYPEOFNAME: {
- Node.Scope defining = scope.getDefiningScope(node.getString());
- if (defining != null) {
- node.setScope(defining);
- }
- }
- break;
-
- case Token.TYPEOF:
- case Token.IFNE: {
- /* We want to suppress warnings for undefined property o.p
- * for the following constructs: typeof o.p, if (o.p),
- * if (!o.p), if (o.p == undefined), if (undefined == o.p)
- */
- Node child = node.getFirstChild();
- if (type == Token.IFNE) {
- while (child.getType() == Token.NOT) {
- child = child.getFirstChild();
- }
- if (child.getType() == Token.EQ ||
- child.getType() == Token.NE)
- {
- Node first = child.getFirstChild();
- Node last = child.getLastChild();
- if (first.getType() == Token.NAME &&
- first.getString().equals("undefined"))
- child = last;
- else if (last.getType() == Token.NAME &&
- last.getString().equals("undefined"))
- child = first;
- }
- }
- if (child.getType() == Token.GETPROP)
- child.setType(Token.GETPROPNOWARN);
- break;
- }
-
- case Token.NAME:
- case Token.SETNAME:
- case Token.SETCONST:
- case Token.DELPROP:
- {
- // Turn name to var for faster access if possible
- if (createScopeObjects) {
- break;
- }
- Node nameSource;
- if (type == Token.NAME) {
- nameSource = node;
- } else {
- nameSource = node.getFirstChild();
- if (nameSource.getType() != Token.BINDNAME) {
- if (type == Token.DELPROP) {
- break;
- }
- throw Kit.codeBug();
- }
- }
- if (nameSource.getScope() != null) {
- break; // already have a scope set
- }
- String name = nameSource.getString();
- Node.Scope defining = scope.getDefiningScope(name);
- if (defining != null) {
- nameSource.setScope(defining);
- if (type == Token.NAME) {
- node.setType(Token.GETVAR);
- } else if (type == Token.SETNAME) {
- node.setType(Token.SETVAR);
- nameSource.setType(Token.STRING);
- } else if (type == Token.SETCONST) {
- node.setType(Token.SETCONSTVAR);
- nameSource.setType(Token.STRING);
- } else if (type == Token.DELPROP) {
- // Local variables are by definition permanent
- Node n = new Node(Token.FALSE);
- node = replaceCurrent(parent, previous, node, n);
- } else {
- throw Kit.codeBug();
- }
- }
- break;
- }
- }
-
- transformCompilationUnit_r(tree, node,
- node instanceof Node.Scope ? (Node.Scope)node : scope,
- createScopeObjects);
- }
- }
-
- protected void visitNew(Node node, ScriptOrFnNode tree) {
- }
-
- protected void visitCall(Node node, ScriptOrFnNode tree) {
- }
-
- protected Node visitLet(boolean createWith, Node parent, Node previous,
- Node scopeNode)
- {
- Node vars = scopeNode.getFirstChild();
- Node body = vars.getNext();
- scopeNode.removeChild(vars);
- scopeNode.removeChild(body);
- boolean isExpression = scopeNode.getType() == Token.LETEXPR;
- Node result;
- Node newVars;
- if (createWith) {
- result = new Node(isExpression ? Token.WITHEXPR : Token.BLOCK);
- result = replaceCurrent(parent, previous, scopeNode, result);
- ArrayList<Object> list = new ArrayList<Object>();
- Node objectLiteral = new Node(Token.OBJECTLIT);
- for (Node v=vars.getFirstChild(); v != null; v = v.getNext()) {
- Node current = v;
- if (current.getType() == Token.LETEXPR) {
- // destructuring in let expr, e.g. let ([x, y] = [3, 4]) {}
- List<?> destructuringNames = (List<?>)
- current.getProp(Node.DESTRUCTURING_NAMES);
- Node c = current.getFirstChild();
- if (c.getType() != Token.LET) throw Kit.codeBug();
- // Add initialization code to front of body
- if (isExpression) {
- body = new Node(Token.COMMA, c.getNext(), body);
- } else {
- body = new Node(Token.BLOCK,
- new Node(Token.EXPR_VOID, c.getNext()),
- body);
- }
- // Update "list" and "objectLiteral" for the variables
- // defined in the destructuring assignment
- if (destructuringNames != null) {
- list.addAll(destructuringNames);
- for (int i=0; i < destructuringNames.size(); i++) {
- objectLiteral.addChildToBack(
- new Node(Token.VOID, Node.newNumber(0.0)));
- }
- }
- current = c.getFirstChild(); // should be a NAME, checked below
- }
- if (current.getType() != Token.NAME) throw Kit.codeBug();
- list.add(ScriptRuntime.getIndexObject(current.getString()));
- Node init = current.getFirstChild();
- if (init == null) {
- init = new Node(Token.VOID, Node.newNumber(0.0));
- }
- objectLiteral.addChildToBack(init);
- }
- objectLiteral.putProp(Node.OBJECT_IDS_PROP, list.toArray());
- newVars = new Node(Token.ENTERWITH, objectLiteral);
- result.addChildToBack(newVars);
- result.addChildToBack(new Node(Token.WITH, body));
- result.addChildToBack(new Node(Token.LEAVEWITH));
- } else {
- result = new Node(isExpression ? Token.COMMA : Token.BLOCK);
- result = replaceCurrent(parent, previous, scopeNode, result);
- newVars = new Node(Token.COMMA);
- for (Node v=vars.getFirstChild(); v != null; v = v.getNext()) {
- Node current = v;
- if (current.getType() == Token.LETEXPR) {
- // destructuring in let expr, e.g. let ([x, y] = [3, 4]) {}
- Node c = current.getFirstChild();
- if (c.getType() != Token.LET) throw Kit.codeBug();
- // Add initialization code to front of body
- if (isExpression) {
- body = new Node(Token.COMMA, c.getNext(), body);
- } else {
- body = new Node(Token.BLOCK,
- new Node(Token.EXPR_VOID, c.getNext()),
- body);
- }
- // We're removing the LETEXPR, so move the symbols
- Node.Scope.joinScopes((Node.Scope)current,
- (Node.Scope)scopeNode);
- current = c.getFirstChild(); // should be a NAME, checked below
- }
- if (current.getType() != Token.NAME) throw Kit.codeBug();
- Node stringNode = Node.newString(current.getString());
- stringNode.setScope((Node.Scope)scopeNode);
- Node init = current.getFirstChild();
- if (init == null) {
- init = new Node(Token.VOID, Node.newNumber(0.0));
- }
- newVars.addChildToBack(new Node(Token.SETVAR, stringNode, init));
- }
- if (isExpression) {
- result.addChildToBack(newVars);
- scopeNode.setType(Token.COMMA);
- result.addChildToBack(scopeNode);
- scopeNode.addChildToBack(body);
- } else {
- result.addChildToBack(new Node(Token.EXPR_VOID, newVars));
- scopeNode.setType(Token.BLOCK);
- result.addChildToBack(scopeNode);
- scopeNode.addChildrenToBack(body);
- }
- }
- return result;
- }
-
- private static Node addBeforeCurrent(Node parent, Node previous,
- Node current, Node toAdd)
- {
- if (previous == null) {
- if (!(current == parent.getFirstChild())) Kit.codeBug();
- parent.addChildToFront(toAdd);
- } else {
- if (!(current == previous.getNext())) Kit.codeBug();
- parent.addChildAfter(toAdd, previous);
- }
- return toAdd;
- }
-
- private static Node replaceCurrent(Node parent, Node previous,
- Node current, Node replacement)
- {
- if (previous == null) {
- if (!(current == parent.getFirstChild())) Kit.codeBug();
- parent.replaceChild(current, replacement);
- } else if (previous.next == current) {
- // Check cachedPrev.next == current is necessary due to possible
- // tree mutations
- parent.replaceChildAfter(previous, replacement);
- } else {
- parent.replaceChild(current, replacement);
- }
- return replacement;
- }
-
- private ObjArray loops;
- private ObjArray loopEnds;
- private boolean hasFinally;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjArray.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjArray.java
deleted file mode 100644
index a9636a3..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjArray.java
+++ /dev/null
@@ -1,388 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * 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;
-
-import java.io.Serializable;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-/**
-Implementation of resizable array with focus on minimizing memory usage by storing few initial array elements in object fields. Can also be used as a stack.
-*/
-
-public class ObjArray implements Serializable
-{
- static final long serialVersionUID = 4174889037736658296L;
-
- public ObjArray() { }
-
- public final boolean isSealed()
- {
- return sealed;
- }
-
- public final void seal()
- {
- sealed = true;
- }
-
- public final boolean isEmpty()
- {
- return size == 0;
- }
-
- public final int size()
- {
- return size;
- }
-
- public final void setSize(int newSize)
- {
- if (newSize < 0) throw new IllegalArgumentException();
- if (sealed) throw onSeledMutation();
- int N = size;
- if (newSize < N) {
- for (int i = newSize; i != N; ++i) {
- setImpl(i, null);
- }
- } else if (newSize > N) {
- if (newSize > FIELDS_STORE_SIZE) {
- ensureCapacity(newSize);
- }
- }
- size = newSize;
- }
-
- public final Object get(int index)
- {
- if (!(0 <= index && index < size)) throw onInvalidIndex(index, size);
- return getImpl(index);
- }
-
- public final void set(int index, Object value)
- {
- if (!(0 <= index && index < size)) throw onInvalidIndex(index, size);
- if (sealed) throw onSeledMutation();
- setImpl(index, value);
- }
-
- private Object getImpl(int index)
- {
- switch (index) {
- case 0: return f0;
- case 1: return f1;
- case 2: return f2;
- case 3: return f3;
- case 4: return f4;
- }
- return data[index - FIELDS_STORE_SIZE];
- }
-
- private void setImpl(int index, Object value)
- {
- switch (index) {
- case 0: f0 = value; break;
- case 1: f1 = value; break;
- case 2: f2 = value; break;
- case 3: f3 = value; break;
- case 4: f4 = value; break;
- default: data[index - FIELDS_STORE_SIZE] = value;
- }
-
- }
-
- public int indexOf(Object obj)
- {
- int N = size;
- for (int i = 0; i != N; ++i) {
- Object current = getImpl(i);
- if (current == obj || (current != null && current.equals(obj))) {
- return i;
- }
- }
- return -1;
- }
-
- public int lastIndexOf(Object obj)
- {
- for (int i = size; i != 0;) {
- --i;
- Object current = getImpl(i);
- if (current == obj || (current != null && current.equals(obj))) {
- return i;
- }
- }
- return -1;
- }
-
- public final Object peek()
- {
- int N = size;
- if (N == 0) throw onEmptyStackTopRead();
- return getImpl(N - 1);
- }
-
- public final Object pop()
- {
- if (sealed) throw onSeledMutation();
- int N = size;
- --N;
- Object top;
- switch (N) {
- case -1: throw onEmptyStackTopRead();
- case 0: top = f0; f0 = null; break;
- case 1: top = f1; f1 = null; break;
- case 2: top = f2; f2 = null; break;
- case 3: top = f3; f3 = null; break;
- case 4: top = f4; f4 = null; break;
- default:
- top = data[N - FIELDS_STORE_SIZE];
- data[N - FIELDS_STORE_SIZE] = null;
- }
- size = N;
- return top;
- }
-
- public final void push(Object value)
- {
- add(value);
- }
-
- public final void add(Object value)
- {
- if (sealed) throw onSeledMutation();
- int N = size;
- if (N >= FIELDS_STORE_SIZE) {
- ensureCapacity(N + 1);
- }
- size = N + 1;
- setImpl(N, value);
- }
-
- public final void add(int index, Object value)
- {
- int N = size;
- if (!(0 <= index && index <= N)) throw onInvalidIndex(index, N + 1);
- if (sealed) throw onSeledMutation();
- Object tmp;
- switch (index) {
- case 0:
- if (N == 0) { f0 = value; break; }
- tmp = f0; f0 = value; value = tmp;
- case 1:
- if (N == 1) { f1 = value; break; }
- tmp = f1; f1 = value; value = tmp;
- case 2:
- if (N == 2) { f2 = value; break; }
- tmp = f2; f2 = value; value = tmp;
- case 3:
- if (N == 3) { f3 = value; break; }
- tmp = f3; f3 = value; value = tmp;
- case 4:
- if (N == 4) { f4 = value; break; }
- tmp = f4; f4 = value; value = tmp;
-
- index = FIELDS_STORE_SIZE;
- default:
- ensureCapacity(N + 1);
- if (index != N) {
- System.arraycopy(data, index - FIELDS_STORE_SIZE,
- data, index - FIELDS_STORE_SIZE + 1,
- N - index);
- }
- data[index - FIELDS_STORE_SIZE] = value;
- }
- size = N + 1;
- }
-
- public final void remove(int index)
- {
- int N = size;
- if (!(0 <= index && index < N)) throw onInvalidIndex(index, N);
- if (sealed) throw onSeledMutation();
- --N;
- switch (index) {
- case 0:
- if (N == 0) { f0 = null; break; }
- f0 = f1;
- case 1:
- if (N == 1) { f1 = null; break; }
- f1 = f2;
- case 2:
- if (N == 2) { f2 = null; break; }
- f2 = f3;
- case 3:
- if (N == 3) { f3 = null; break; }
- f3 = f4;
- case 4:
- if (N == 4) { f4 = null; break; }
- f4 = data[0];
-
- index = FIELDS_STORE_SIZE;
- default:
- if (index != N) {
- System.arraycopy(data, index - FIELDS_STORE_SIZE + 1,
- data, index - FIELDS_STORE_SIZE,
- N - index);
- }
- data[N - FIELDS_STORE_SIZE] = null;
- }
- size = N;
- }
-
- public final void clear()
- {
- if (sealed) throw onSeledMutation();
- int N = size;
- for (int i = 0; i != N; ++i) {
- setImpl(i, null);
- }
- size = 0;
- }
-
- public final Object[] toArray()
- {
- Object[] array = new Object[size];
- toArray(array, 0);
- return array;
- }
-
- public final void toArray(Object[] array)
- {
- toArray(array, 0);
- }
-
- public final void toArray(Object[] array, int offset)
- {
- int N = size;
- switch (N) {
- default:
- System.arraycopy(data, 0, array, offset + FIELDS_STORE_SIZE,
- N - FIELDS_STORE_SIZE);
- case 5: array[offset + 4] = f4;
- case 4: array[offset + 3] = f3;
- case 3: array[offset + 2] = f2;
- case 2: array[offset + 1] = f1;
- case 1: array[offset + 0] = f0;
- case 0: break;
- }
- }
-
- private void ensureCapacity(int minimalCapacity)
- {
- int required = minimalCapacity - FIELDS_STORE_SIZE;
- if (required <= 0) throw new IllegalArgumentException();
- if (data == null) {
- int alloc = FIELDS_STORE_SIZE * 2;
- if (alloc < required) {
- alloc = required;
- }
- data = new Object[alloc];
- } else {
- int alloc = data.length;
- if (alloc < required) {
- if (alloc <= FIELDS_STORE_SIZE) {
- alloc = FIELDS_STORE_SIZE * 2;
- } else {
- alloc *= 2;
- }
- if (alloc < required) {
- alloc = required;
- }
- Object[] tmp = new Object[alloc];
- if (size > FIELDS_STORE_SIZE) {
- System.arraycopy(data, 0, tmp, 0,
- size - FIELDS_STORE_SIZE);
- }
- data = tmp;
- }
- }
- }
-
- private static RuntimeException onInvalidIndex(int index, int upperBound)
- {
- // \u2209 is "NOT ELEMENT OF"
- String msg = index+" \u2209 [0, "+upperBound+')';
- throw new IndexOutOfBoundsException(msg);
- }
-
- private static RuntimeException onEmptyStackTopRead()
- {
- throw new RuntimeException("Empty stack");
- }
-
- private static RuntimeException onSeledMutation()
- {
- throw new IllegalStateException("Attempt to modify sealed array");
- }
-
- private void writeObject(ObjectOutputStream os) throws IOException
- {
- os.defaultWriteObject();
- int N = size;
- for (int i = 0; i != N; ++i) {
- Object obj = getImpl(i);
- os.writeObject(obj);
- }
- }
-
- private void readObject(ObjectInputStream is)
- throws IOException, ClassNotFoundException
- {
- is.defaultReadObject(); // It reads size
- int N = size;
- if (N > FIELDS_STORE_SIZE) {
- data = new Object[N - FIELDS_STORE_SIZE];
- }
- for (int i = 0; i != N; ++i) {
- Object obj = is.readObject();
- setImpl(i, obj);
- }
- }
-
-// Number of data elements
- private int size;
-
- private boolean sealed;
-
- private static final int FIELDS_STORE_SIZE = 5;
- private transient Object f0, f1, f2, f3, f4;
- private transient Object[] data;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjToIntMap.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjToIntMap.java
deleted file mode 100644
index 4aa7d23..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjToIntMap.java
+++ /dev/null
@@ -1,697 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * 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;
-
-import java.io.Serializable;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-/**
- * Map to associate objects to integers.
- * The map does not synchronize any of its operation, so either use
- * it from a single thread or do own synchronization or perform all mutation
- * operations on one thread before passing the map to others
- *
- * @author Igor Bukanov
- *
- */
-
-public class ObjToIntMap implements Serializable
-{
- static final long serialVersionUID = -1542220580748809402L;
-
-// Map implementation via hashtable,
-// follows "The Art of Computer Programming" by Donald E. Knuth
-
-// ObjToIntMap is a copy cat of ObjToIntMap with API adjusted to object keys
-
- public static class Iterator {
-
- Iterator(ObjToIntMap master) {
- this.master = master;
- }
-
- final void init(Object[] keys, int[] values, int keyCount) {
- this.keys = keys;
- this.values = values;
- this.cursor = -1;
- this.remaining = keyCount;
- }
-
- public void start() {
- master.initIterator(this);
- next();
- }
-
- public boolean done() {
- return remaining < 0;
- }
-
- public void next() {
- if (remaining == -1) Kit.codeBug();
- if (remaining == 0) {
- remaining = -1;
- cursor = -1;
- }else {
- for (++cursor; ; ++cursor) {
- Object key = keys[cursor];
- if (key != null && key != DELETED) {
- --remaining;
- break;
- }
- }
- }
- }
-
- public Object getKey() {
- Object key = keys[cursor];
- if (key == UniqueTag.NULL_VALUE) { key = null; }
- return key;
- }
-
- public int getValue() {
- return values[cursor];
- }
-
- public void setValue(int value) {
- values[cursor] = value;
- }
-
- ObjToIntMap master;
- private int cursor;
- private int remaining;
- private Object[] keys;
- private int[] values;
- }
-
- public ObjToIntMap() {
- this(4);
- }
-
- public ObjToIntMap(int keyCountHint) {
- if (keyCountHint < 0) Kit.codeBug();
- // Table grow when number of stored keys >= 3/4 of max capacity
- int minimalCapacity = keyCountHint * 4 / 3;
- int i;
- for (i = 2; (1 << i) < minimalCapacity; ++i) { }
- power = i;
- if (check && power < 2) Kit.codeBug();
- }
-
- public boolean isEmpty() {
- return keyCount == 0;
- }
-
- public int size() {
- return keyCount;
- }
-
- public boolean has(Object key) {
- if (key == null) { key = UniqueTag.NULL_VALUE; }
- return 0 <= findIndex(key);
- }
-
- /**
- * Get integer value assigned with key.
- * @return key integer value or defaultValue if key is absent
- */
- public int get(Object key, int defaultValue) {
- if (key == null) { key = UniqueTag.NULL_VALUE; }
- int index = findIndex(key);
- if (0 <= index) {
- return values[index];
- }
- return defaultValue;
- }
-
- /**
- * Get integer value assigned with key.
- * @return key integer value
- * @throws RuntimeException if key does not exist
- */
- public int getExisting(Object key) {
- if (key == null) { key = UniqueTag.NULL_VALUE; }
- int index = findIndex(key);
- if (0 <= index) {
- return values[index];
- }
- // Key must exist
- Kit.codeBug();
- return 0;
- }
-
- public void put(Object key, int value) {
- if (key == null) { key = UniqueTag.NULL_VALUE; }
- int index = ensureIndex(key);
- values[index] = value;
- }
-
- /**
- * If table already contains a key that equals to keyArg, return that key
- * while setting its value to zero, otherwise add keyArg with 0 value to
- * the table and return it.
- */
- public Object intern(Object keyArg) {
- boolean nullKey = false;
- if (keyArg == null) {
- nullKey = true;
- keyArg = UniqueTag.NULL_VALUE;
- }
- int index = ensureIndex(keyArg);
- values[index] = 0;
- return (nullKey) ? null : keys[index];
- }
-
- public void remove(Object key) {
- if (key == null) { key = UniqueTag.NULL_VALUE; }
- int index = findIndex(key);
- if (0 <= index) {
- keys[index] = DELETED;
- --keyCount;
- }
- }
-
- public void clear() {
- int i = keys.length;
- while (i != 0) {
- keys[--i] = null;
- }
- keyCount = 0;
- occupiedCount = 0;
- }
-
- public Iterator newIterator() {
- return new Iterator(this);
- }
-
- // The sole purpose of the method is to avoid accessing private fields
- // from the Iterator inner class to workaround JDK 1.1 compiler bug which
- // generates code triggering VerifierError on recent JVMs
- final void initIterator(Iterator i) {
- i.init(keys, values, keyCount);
- }
-
- /** Return array of present keys */
- public Object[] getKeys() {
- Object[] array = new Object[keyCount];
- getKeys(array, 0);
- return array;
- }
-
- public void getKeys(Object[] array, int offset) {
- int count = keyCount;
- for (int i = 0; count != 0; ++i) {
- Object key = keys[i];
- if (key != null && key != DELETED) {
- if (key == UniqueTag.NULL_VALUE) { key = null; }
- array[offset] = key;
- ++offset;
- --count;
- }
- }
- }
-
- private static int tableLookupStep(int fraction, int mask, int power) {
- int shift = 32 - 2 * power;
- if (shift >= 0) {
- return ((fraction >>> shift) & mask) | 1;
- }
- else {
- return (fraction & (mask >>> -shift)) | 1;
- }
- }
-
- private int findIndex(Object key) {
- if (keys != null) {
- int hash = key.hashCode();
- int fraction = hash * A;
- int index = fraction >>> (32 - power);
- Object test = keys[index];
- if (test != null) {
- int N = 1 << power;
- if (test == key
- || (values[N + index] == hash && test.equals(key)))
- {
- return index;
- }
- // Search in table after first failed attempt
- int mask = N - 1;
- int step = tableLookupStep(fraction, mask, power);
- int n = 0;
- for (;;) {
- if (check) {
- if (n >= occupiedCount) Kit.codeBug();
- ++n;
- }
- index = (index + step) & mask;
- test = keys[index];
- if (test == null) {
- break;
- }
- if (test == key
- || (values[N + index] == hash && test.equals(key)))
- {
- return index;
- }
- }
- }
- }
- return -1;
- }
-
-// Insert key that is not present to table without deleted entries
-// and enough free space
- private int insertNewKey(Object key, int hash) {
- if (check && occupiedCount != keyCount) Kit.codeBug();
- if (check && keyCount == 1 << power) Kit.codeBug();
- int fraction = hash * A;
- int index = fraction >>> (32 - power);
- int N = 1 << power;
- if (keys[index] != null) {
- int mask = N - 1;
- int step = tableLookupStep(fraction, mask, power);
- int firstIndex = index;
- do {
- if (check && keys[index] == DELETED) Kit.codeBug();
- index = (index + step) & mask;
- if (check && firstIndex == index) Kit.codeBug();
- } while (keys[index] != null);
- }
- keys[index] = key;
- values[N + index] = hash;
- ++occupiedCount;
- ++keyCount;
-
- return index;
- }
-
- private void rehashTable() {
- if (keys == null) {
- if (check && keyCount != 0) Kit.codeBug();
- if (check && occupiedCount != 0) Kit.codeBug();
- int N = 1 << power;
- keys = new Object[N];
- values = new int[2 * N];
- }
- else {
- // Check if removing deleted entries would free enough space
- if (keyCount * 2 >= occupiedCount) {
- // Need to grow: less then half of deleted entries
- ++power;
- }
- int N = 1 << power;
- Object[] oldKeys = keys;
- int[] oldValues = values;
- int oldN = oldKeys.length;
- keys = new Object[N];
- values = new int[2 * N];
-
- int remaining = keyCount;
- occupiedCount = keyCount = 0;
- for (int i = 0; remaining != 0; ++i) {
- Object key = oldKeys[i];
- if (key != null && key != DELETED) {
- int keyHash = oldValues[oldN + i];
- int index = insertNewKey(key, keyHash);
- values[index] = oldValues[i];
- --remaining;
- }
- }
- }
- }
-
-// Ensure key index creating one if necessary
- private int ensureIndex(Object key) {
- int hash = key.hashCode();
- int index = -1;
- int firstDeleted = -1;
- if (keys != null) {
- int fraction = hash * A;
- index = fraction >>> (32 - power);
- Object test = keys[index];
- if (test != null) {
- int N = 1 << power;
- if (test == key
- || (values[N + index] == hash && test.equals(key)))
- {
- return index;
- }
- if (test == DELETED) {
- firstDeleted = index;
- }
-
- // Search in table after first failed attempt
- int mask = N - 1;
- int step = tableLookupStep(fraction, mask, power);
- int n = 0;
- for (;;) {
- if (check) {
- if (n >= occupiedCount) Kit.codeBug();
- ++n;
- }
- index = (index + step) & mask;
- test = keys[index];
- if (test == null) {
- break;
- }
- if (test == key
- || (values[N + index] == hash && test.equals(key)))
- {
- return index;
- }
- if (test == DELETED && firstDeleted < 0) {
- firstDeleted = index;
- }
- }
- }
- }
- // Inserting of new key
- if (check && keys != null && keys[index] != null)
- Kit.codeBug();
- if (firstDeleted >= 0) {
- index = firstDeleted;
- }
- else {
- // Need to consume empty entry: check occupation level
- if (keys == null || occupiedCount * 4 >= (1 << power) * 3) {
- // Too litle unused entries: rehash
- rehashTable();
- return insertNewKey(key, hash);
- }
- ++occupiedCount;
- }
- keys[index] = key;
- values[(1 << power) + index] = hash;
- ++keyCount;
- return index;
- }
-
- private void writeObject(ObjectOutputStream out)
- throws IOException
- {
- out.defaultWriteObject();
-
- int count = keyCount;
- for (int i = 0; count != 0; ++i) {
- Object key = keys[i];
- if (key != null && key != DELETED) {
- --count;
- out.writeObject(key);
- out.writeInt(values[i]);
- }
- }
- }
-
- private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- in.defaultReadObject();
-
- int writtenKeyCount = keyCount;
- if (writtenKeyCount != 0) {
- keyCount = 0;
- int N = 1 << power;
- keys = new Object[N];
- values = new int[2 * N];
- for (int i = 0; i != writtenKeyCount; ++i) {
- Object key = in.readObject();
- int hash = key.hashCode();
- int index = insertNewKey(key, hash);
- values[index] = in.readInt();
- }
- }
- }
-
-// A == golden_ratio * (1 << 32) = ((sqrt(5) - 1) / 2) * (1 << 32)
-// See Knuth etc.
- private static final int A = 0x9e3779b9;
-
- private static final Object DELETED = new Object();
-
-// Structure of kyes and values arrays (N == 1 << power):
-// keys[0 <= i < N]: key value or null or DELETED mark
-// values[0 <= i < N]: value of key at keys[i]
-// values[N <= i < 2*N]: hash code of key at keys[i-N]
-
- private transient Object[] keys;
- private transient int[] values;
-
- private int power;
- private int keyCount;
- private transient int occupiedCount; // == keyCount + deleted_count
-
-// If true, enables consitency checks
- private static final boolean check = false;
-
-/* TEST START
-
- public static void main(String[] args) {
- if (!check) {
- System.err.println("Set check to true and re-run");
- throw new RuntimeException("Set check to true and re-run");
- }
-
- ObjToIntMap map;
- map = new ObjToIntMap(0);
- testHash(map, 3);
- map = new ObjToIntMap(0);
- testHash(map, 10 * 1000);
- map = new ObjToIntMap();
- testHash(map, 10 * 1000);
- map = new ObjToIntMap(30 * 1000);
- testHash(map, 10 * 100);
- map.clear();
- testHash(map, 4);
- map = new ObjToIntMap(0);
- testHash(map, 10 * 100);
- }
-
- private static void testHash(ObjToIntMap map, int N) {
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- Object key = testKey(i);
- check(-1 == map.get(key, -1));
- map.put(key, i);
- check(i == map.get(key, -1));
- }
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- Object key = testKey(i);
- map.put(key, i);
- check(i == map.get(key, -1));
- }
-
- check(map.size() == N);
-
- System.out.print("."); System.out.flush();
- Object[] keys = map.getKeys();
- check(keys.length == N);
- for (int i = 0; i != N; ++i) {
- Object key = keys[i];
- check(map.has(key));
- }
-
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- Object key = testKey(i);
- check(i == map.get(key, -1));
- }
-
- int Nsqrt = -1;
- for (int i = 0; ; ++i) {
- if (i * i >= N) {
- Nsqrt = i;
- break;
- }
- }
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- Object key = testKey(i * i);
- map.put(key, i);
- check(i == map.get(key, -1));
- }
-
- check(map.size() == 2 * N - Nsqrt);
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- Object key = testKey(i * i);
- check(i == map.get(key, -1));
- }
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- Object key = testKey(-1 - i * i);
- map.put(key, i);
- check(i == map.get(key, -1));
- }
-
- check(map.size() == 3 * N - Nsqrt);
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- Object key = testKey(-1 - i * i);
- map.remove(key);
- check(!map.has(key));
- }
-
- check(map.size() == 2 * N - Nsqrt);
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- Object key = testKey(i * i);
- check(i == map.get(key, -1));
- }
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- Object key = testKey(i);
- int j = intSqrt(i);
- if (j * j == i) {
- check(j == map.get(key, -1));
- }else {
- check(i == map.get(key, -1));
- }
- }
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- Object key = testKey(i * i);
- map.remove(key);
- check(-2 == map.get(key, -2));
- }
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- Object key = testKey(i);
- map.put(key, i);
- check(i == map.get(key, -2));
- }
-
- check(map.size() == N);
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- Object key = testKey(i);
- check(i == map.get(key, -1));
- }
-
- System.out.print("."); System.out.flush();
- ObjToIntMap copy = (ObjToIntMap)writeAndRead(map);
- check(copy.size() == N);
-
- for (int i = 0; i != N; ++i) {
- Object key = testKey(i);
- check(i == copy.get(key, -1));
- }
-
- System.out.print("."); System.out.flush();
- checkSameMaps(copy, map);
-
- System.out.println(); System.out.flush();
- }
-
- private static void checkSameMaps(ObjToIntMap map1, ObjToIntMap map2) {
- check(map1.size() == map2.size());
- Object[] keys = map1.getKeys();
- check(keys.length == map1.size());
- for (int i = 0; i != keys.length; ++i) {
- check(map1.get(keys[i], -1) == map2.get(keys[i], -1));
- }
- }
-
- private static void check(boolean condition) {
- if (!condition) Kit.codeBug();
- }
-
- private static Object[] testPool;
-
- private static Object testKey(int i) {
- int MAX_POOL = 100;
- if (0 <= i && i < MAX_POOL) {
- if (testPool != null && testPool[i] != null) {
- return testPool[i];
- }
- }
- Object x = new Double(i + 0.5);
- if (0 <= i && i < MAX_POOL) {
- if (testPool == null) {
- testPool = new Object[MAX_POOL];
- }
- testPool[i] = x;
- }
- return x;
- }
-
- private static int intSqrt(int i) {
- int approx = (int)Math.sqrt(i) + 1;
- while (approx * approx > i) {
- --approx;
- }
- return approx;
- }
-
- private static Object writeAndRead(Object obj) {
- try {
- java.io.ByteArrayOutputStream
- bos = new java.io.ByteArrayOutputStream();
- java.io.ObjectOutputStream
- out = new java.io.ObjectOutputStream(bos);
- out.writeObject(obj);
- out.close();
- byte[] data = bos.toByteArray();
- java.io.ByteArrayInputStream
- bis = new java.io.ByteArrayInputStream(data);
- java.io.ObjectInputStream
- in = new java.io.ObjectInputStream(bis);
- Object result = in.readObject();
- in.close();
- return result;
- }catch (Exception ex) {
- throw new RuntimeException("Unexpected");
- }
- }
-
-// TEST END */
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Parser.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Parser.java
deleted file mode 100644
index 80cb937..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Parser.java
+++ /dev/null
@@ -1,2554 +0,0 @@
-/* -*- 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):
- * Mike Ang
- * Igor Bukanov
- * Yuh-Ruey Chen
- * Ethan Hugg
- * Bob Jervis
- * Terry Lucas
- * Mike McCabe
- * Milen Nankov
- * Norris Boyd
- *
- * 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;
-
-import java.io.Reader;
-import java.io.IOException;
-import java.util.Hashtable;
-
-/**
- * This class implements the JavaScript parser.
- *
- * It is based on the C source files jsparse.c and jsparse.h
- * in the jsref package.
- *
- * @see TokenStream
- *
- * @author Mike McCabe
- * @author Brendan Eich
- */
-
-public class Parser
-{
- // TokenInformation flags : currentFlaggedToken stores them together
- // with token type
- final static int
- CLEAR_TI_MASK = 0xFFFF, // mask to clear token information bits
- TI_AFTER_EOL = 1 << 16, // first token of the source line
- TI_CHECK_LABEL = 1 << 17; // indicates to check for label
-
- CompilerEnvirons compilerEnv;
- private ErrorReporter errorReporter;
- /*APPJET*//*no longer:private*/ String sourceURI;
- boolean calledByCompileFunction;
-
- /*APPJET*//*no longer:private*/ TokenStream ts;
- private int currentFlaggedToken;
- /*APPJET*//*no longer:private*/ int syntaxErrorCount;
-
- private IRFactory nf;
-
- private int nestingOfFunction;
-
- private Decompiler decompiler;
- private String encodedSource;
-
-// The following are per function variables and should be saved/restored
-// during function parsing.
-// XXX Move to separated class?
- ScriptOrFnNode currentScriptOrFn;
- Node.Scope currentScope;
- private int nestingOfWith;
- private Hashtable labelSet; // map of label names into nodes
- private ObjArray loopSet;
- private ObjArray loopAndSwitchSet;
- private boolean hasReturnValue;
- private int endFlags;
-// end of per function variables
-
- /*APPJET*/public int lastConsumedTokenLine = -1;
-
- public int getCurrentLineNumber() {
- return ts.getLineno();
- }
-
- // Exception to unwind
- private static class ParserException extends RuntimeException
- {
- static final long serialVersionUID = 5882582646773765630L;
- }
-
- public Parser(CompilerEnvirons compilerEnv, ErrorReporter errorReporter)
- {
- this.compilerEnv = compilerEnv;
- this.errorReporter = errorReporter;
- }
-
- protected Decompiler createDecompiler(CompilerEnvirons compilerEnv)
- {
- return new Decompiler();
- }
-
- void addStrictWarning(String messageId, String messageArg)
- {
- if (compilerEnv.isStrictMode())
- addWarning(messageId, messageArg);
- }
-
- void addWarning(String messageId, String messageArg)
- {
- String message = ScriptRuntime.getMessage1(messageId, messageArg);
- if (compilerEnv.reportWarningAsError()) {
- ++syntaxErrorCount;
- errorReporter.error(message, sourceURI, ts.getLineno(),
- ts.getLine(), ts.getOffset());
- } else
- errorReporter.warning(message, sourceURI, ts.getLineno(),
- ts.getLine(), ts.getOffset());
- }
-
- void addError(String messageId)
- {
- ++syntaxErrorCount;
- String message = ScriptRuntime.getMessage0(messageId);
- errorReporter.error(message, sourceURI, ts.getLineno(),
- ts.getLine(), ts.getOffset());
- }
-
- void addError(String messageId, String messageArg)
- {
- ++syntaxErrorCount;
- String message = ScriptRuntime.getMessage1(messageId, messageArg);
- errorReporter.error(message, sourceURI, ts.getLineno(),
- ts.getLine(), ts.getOffset());
- }
-
- RuntimeException reportError(String messageId)
- {
- addError(messageId);
-
- // Throw a ParserException exception to unwind the recursive descent
- // parse.
- throw new ParserException();
- }
-
- /*APPJET*//*added method*/
- RuntimeException reportError(String messageId, String messageArg)
- {
- addError(messageId, messageArg);
-
- // Throw a ParserException exception to unwind the recursive descent
- // parse.
- throw new ParserException();
- }
-
- /*APPJET*//*no longer: private*/int peekToken()
- throws IOException
- {
- int tt = currentFlaggedToken;
- if (tt == Token.EOF) {
- tt = ts.getToken();
- if (tt == Token.EOL) {
- do {
- tt = ts.getToken();
- } while (tt == Token.EOL);
- tt |= TI_AFTER_EOL;
- }
- currentFlaggedToken = tt;
- }
- return tt & CLEAR_TI_MASK;
- }
-
- private int peekFlaggedToken()
- throws IOException
- {
- peekToken();
- return currentFlaggedToken;
- }
-
- /*APPJET*//*no longer:private*/ void consumeToken()
- {
- currentFlaggedToken = Token.EOF;
- /*APPJET*/lastConsumedTokenLine = ts.getLineno();
- }
-
- private int nextToken()
- throws IOException
- {
- int tt = peekToken();
- consumeToken();
- return tt;
- }
-
- private int nextFlaggedToken()
- throws IOException
- {
- peekToken();
- int ttFlagged = currentFlaggedToken;
- consumeToken();
- return ttFlagged;
- }
-
- private boolean matchToken(int toMatch)
- throws IOException
- {
- int tt = peekToken();
- if (tt != toMatch) {
- return false;
- }
- consumeToken();
- return true;
- }
-
- private int peekTokenOrEOL()
- throws IOException
- {
- int tt = peekToken();
- // Check for last peeked token flags
- if ((currentFlaggedToken & TI_AFTER_EOL) != 0) {
- tt = Token.EOL;
- }
- return tt;
- }
-
- private void setCheckForLabel()
- {
- if ((currentFlaggedToken & CLEAR_TI_MASK) != Token.NAME)
- throw Kit.codeBug();
- currentFlaggedToken |= TI_CHECK_LABEL;
- }
-
- private void mustMatchToken(int toMatch, String messageId)
- throws IOException, ParserException
- {
- if (!matchToken(toMatch)) {
- reportError(messageId);
- }
- }
-
- /*APPJET*//*added method*/
- private void mustMatchToken(int toMatch, String messageId, String messageArg)
- throws IOException, ParserException
- {
- if (!matchToken(toMatch)) {
- reportError(messageId, messageArg);
- }
- }
-
- private void mustHaveXML()
- {
- if (!compilerEnv.isXmlAvailable()) {
- reportError("msg.XML.not.available");
- }
- }
-
- public String getEncodedSource()
- {
- return encodedSource;
- }
-
- public boolean eof()
- {
- return ts.eof();
- }
-
- boolean insideFunction()
- {
- return nestingOfFunction != 0;
- }
-
- void pushScope(Node node) {
- Node.Scope scopeNode = (Node.Scope) node;
- if (scopeNode.getParentScope() != null) throw Kit.codeBug();
- scopeNode.setParent(currentScope);
- currentScope = scopeNode;
- }
-
- void popScope() {
- currentScope = currentScope.getParentScope();
- }
-
- private Node enterLoop(Node loopLabel, boolean doPushScope)
- {
- Node loop = nf.createLoopNode(loopLabel, ts.getLineno());
- if (loopSet == null) {
- loopSet = new ObjArray();
- if (loopAndSwitchSet == null) {
- loopAndSwitchSet = new ObjArray();
- }
- }
- loopSet.push(loop);
- loopAndSwitchSet.push(loop);
- if (doPushScope) {
- pushScope(loop);
- }
- return loop;
- }
-
- private void exitLoop(boolean doPopScope)
- {
- loopSet.pop();
- loopAndSwitchSet.pop();
- if (doPopScope) {
- popScope();
- }
- }
-
- private Node enterSwitch(Node switchSelector, int lineno)
- {
- Node switchNode = nf.createSwitch(switchSelector, lineno);
- if (loopAndSwitchSet == null) {
- loopAndSwitchSet = new ObjArray();
- }
- loopAndSwitchSet.push(switchNode);
- return switchNode;
- }
-
- private void exitSwitch()
- {
- loopAndSwitchSet.pop();
- }
-
- /*
- * Build a parse tree from the given sourceString.
- *
- * @return an Object representing the parsed
- * program. If the parse fails, null will be returned. (The
- * parse failure will result in a call to the ErrorReporter from
- * CompilerEnvirons.)
- */
- public ScriptOrFnNode parse(String sourceString,
- String sourceURI, int lineno)
- {
- this.sourceURI = sourceURI;
- this.ts = new TokenStream(this, null, sourceString, lineno);
- try {
- return parse();
- } catch (IOException ex) {
- // Should never happen
- throw new IllegalStateException();
- }
- }
-
- /*
- * Build a parse tree from the given sourceString.
- *
- * @return an Object representing the parsed
- * program. If the parse fails, null will be returned. (The
- * parse failure will result in a call to the ErrorReporter from
- * CompilerEnvirons.)
- */
- public ScriptOrFnNode parse(Reader sourceReader,
- String sourceURI, int lineno)
- throws IOException
- {
- this.sourceURI = sourceURI;
- this.ts = new TokenStream(this, sourceReader, null, lineno);
- return parse();
- }
-
- private ScriptOrFnNode parse()
- throws IOException
- {
- this.decompiler = createDecompiler(compilerEnv);
- this.nf = new IRFactory(this);
- currentScriptOrFn = nf.createScript();
- currentScope = currentScriptOrFn;
- int sourceStartOffset = decompiler.getCurrentOffset();
- this.encodedSource = null;
- decompiler.addToken(Token.SCRIPT);
-
- this.currentFlaggedToken = Token.EOF;
- this.syntaxErrorCount = 0;
-
- int baseLineno = ts.getLineno(); // line number where source starts
-
- /*APPJET*/lastConsumedTokenLine = baseLineno;
-
- /* so we have something to add nodes to until
- * we've collected all the source */
- Node pn = nf.createLeaf(Token.BLOCK);
-
- try {
- for (;;) {
- int tt = peekToken();
-
- if (tt <= Token.EOF) {
- break;
- }
-
- Node n;
- if (tt == Token.FUNCTION) {
- consumeToken();
- try {
- n = function(calledByCompileFunction
- ? FunctionNode.FUNCTION_EXPRESSION
- : FunctionNode.FUNCTION_STATEMENT);
- } catch (ParserException e) {
- break;
- }
- } else {
- n = statement();
- }
- nf.addChildToBack(pn, n);
- }
- } catch (StackOverflowError ex) {
- String msg = ScriptRuntime.getMessage0(
- "msg.too.deep.parser.recursion");
- throw Context.reportRuntimeError(msg, sourceURI,
- ts.getLineno(), null, 0);
- }
-
- if (this.syntaxErrorCount != 0) {
- String msg = String.valueOf(this.syntaxErrorCount);
- msg = ScriptRuntime.getMessage1("msg.got.syntax.errors", msg);
- throw errorReporter.runtimeError(msg, sourceURI, baseLineno,
- null, 0);
- }
-
- currentScriptOrFn.setSourceName(sourceURI);
- currentScriptOrFn.setBaseLineno(baseLineno);
- currentScriptOrFn.setEndLineno(ts.getLineno());
-
- int sourceEndOffset = decompiler.getCurrentOffset();
- currentScriptOrFn.setEncodedSourceBounds(sourceStartOffset,
- sourceEndOffset);
-
- nf.initScript(currentScriptOrFn, pn);
-
- if (compilerEnv.isGeneratingSource()) {
- encodedSource = decompiler.getEncodedSource();
- }
- this.decompiler = null; // It helps GC
-
- return currentScriptOrFn;
- }
-
- /*
- * The C version of this function takes an argument list,
- * which doesn't seem to be needed for tree generation...
- * it'd only be useful for checking argument hiding, which
- * I'm not doing anyway...
- */
- private Node parseFunctionBody()
- throws IOException
- {
- ++nestingOfFunction;
- Node pn = nf.createBlock(ts.getLineno());
- try {
- bodyLoop: for (;;) {
- Node n;
- int tt = peekToken();
- switch (tt) {
- case Token.ERROR:
- case Token.EOF:
- case Token.RC:
- break bodyLoop;
-
- case Token.FUNCTION:
- consumeToken();
- n = function(FunctionNode.FUNCTION_STATEMENT);
- break;
- default:
- n = statement();
- break;
- }
- nf.addChildToBack(pn, n);
- }
- } catch (ParserException e) {
- // Ignore it
- } finally {
- --nestingOfFunction;
- }
-
- return pn;
- }
-
- private Node function(int functionType)
- throws IOException, ParserException
- {
- int syntheticType = functionType;
- int baseLineno = ts.getLineno(); // line number where source starts
-
- int functionSourceStart = decompiler.markFunctionStart(functionType);
- String name;
- Node memberExprNode = null;
- if (matchToken(Token.NAME)) {
- name = ts.getString();
- decompiler.addName(name);
- if (!matchToken(Token.LP)) {
- if (compilerEnv.isAllowMemberExprAsFunctionName()) {
- // Extension to ECMA: if 'function <name>' does not follow
- // by '(', assume <name> starts memberExpr
- Node memberExprHead = nf.createName(name);
- name = "";
- memberExprNode = memberExprTail(false, memberExprHead);
- }
- mustMatchToken(Token.LP, "msg.no.paren.parms");
- }
- } else if (matchToken(Token.LP)) {
- // Anonymous function
- name = "";
- } else {
- name = "";
- if (compilerEnv.isAllowMemberExprAsFunctionName()) {
- // Note that memberExpr can not start with '(' like
- // in function (1+2).toString(), because 'function (' already
- // processed as anonymous function
- memberExprNode = memberExpr(false);
- }
- mustMatchToken(Token.LP, "msg.no.paren.parms");
- }
-
- if (memberExprNode != null) {
- syntheticType = FunctionNode.FUNCTION_EXPRESSION;
- }
-
- if (syntheticType != FunctionNode.FUNCTION_EXPRESSION &&
- name.length() > 0)
- {
- // Function statements define a symbol in the enclosing scope
- defineSymbol(Token.FUNCTION, name);
- }
-
- boolean nested = insideFunction();
-
- FunctionNode fnNode = nf.createFunction(name);
- if (nested || nestingOfWith > 0) {
- // 1. Nested functions are not affected by the dynamic scope flag
- // as dynamic scope is already a parent of their scope.
- // 2. Functions defined under the with statement also immune to
- // this setup, in which case dynamic scope is ignored in favor
- // of with object.
- fnNode.itsIgnoreDynamicScope = true;
- }
- int functionIndex = currentScriptOrFn.addFunction(fnNode);
-
- int functionSourceEnd;
-
- ScriptOrFnNode savedScriptOrFn = currentScriptOrFn;
- currentScriptOrFn = fnNode;
- Node.Scope savedCurrentScope = currentScope;
- currentScope = fnNode;
- int savedNestingOfWith = nestingOfWith;
- nestingOfWith = 0;
- Hashtable savedLabelSet = labelSet;
- labelSet = null;
- ObjArray savedLoopSet = loopSet;
- loopSet = null;
- ObjArray savedLoopAndSwitchSet = loopAndSwitchSet;
- loopAndSwitchSet = null;
- boolean savedHasReturnValue = hasReturnValue;
- int savedFunctionEndFlags = endFlags;
-
- Node destructuring = null;
- Node body;
- try {
- decompiler.addToken(Token.LP);
- if (!matchToken(Token.RP)) {
- boolean first = true;
- do {
- if (!first)
- decompiler.addToken(Token.COMMA);
- first = false;
- int tt = peekToken();
- if (tt == Token.LB || tt == Token.LC) {
- // Destructuring assignment for parameters: add a
- // dummy parameter name, and add a statement to the
- // body to initialize variables from the destructuring
- // assignment
- if (destructuring == null) {
- destructuring = new Node(Token.COMMA);
- }
- String parmName = currentScriptOrFn.getNextTempName();
- defineSymbol(Token.LP, parmName);
- destructuring.addChildToBack(
- nf.createDestructuringAssignment(Token.VAR,
- primaryExpr(), nf.createName(parmName)));
- } else {
- mustMatchToken(Token.NAME, "msg.no.parm");
- String s = ts.getString();
- defineSymbol(Token.LP, s);
- decompiler.addName(s);
- }
- } while (matchToken(Token.COMMA));
-
- mustMatchToken(Token.RP, "msg.no.paren.after.parms");
- }
- decompiler.addToken(Token.RP);
-
- mustMatchToken(Token.LC, "msg.no.brace.body");
- decompiler.addEOL(Token.LC);
- body = parseFunctionBody();
- if (destructuring != null) {
- body.addChildToFront(
- new Node(Token.EXPR_VOID, destructuring, ts.getLineno()));
- }
- mustMatchToken(Token.RC, "msg.no.brace.after.body");
-
- if (compilerEnv.isStrictMode() && !body.hasConsistentReturnUsage())
- {
- String msg = name.length() > 0 ? "msg.no.return.value"
- : "msg.anon.no.return.value";
- addStrictWarning(msg, name);
- }
-
- if (syntheticType == FunctionNode.FUNCTION_EXPRESSION &&
- name.length() > 0 && currentScope.getSymbol(name) == null)
- {
- // Function expressions define a name only in the body of the
- // function, and only if not hidden by a parameter name
- defineSymbol(Token.FUNCTION, name);
- }
-
- decompiler.addToken(Token.RC);
- functionSourceEnd = decompiler.markFunctionEnd(functionSourceStart);
- if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
- // Add EOL only if function is not part of expression
- // since it gets SEMI + EOL from Statement in that case
- decompiler.addToken(Token.EOL);
- }
- }
- finally {
- hasReturnValue = savedHasReturnValue;
- endFlags = savedFunctionEndFlags;
- loopAndSwitchSet = savedLoopAndSwitchSet;
- loopSet = savedLoopSet;
- labelSet = savedLabelSet;
- nestingOfWith = savedNestingOfWith;
- currentScriptOrFn = savedScriptOrFn;
- currentScope = savedCurrentScope;
- }
-
- fnNode.setEncodedSourceBounds(functionSourceStart, functionSourceEnd);
- fnNode.setSourceName(sourceURI);
- fnNode.setBaseLineno(baseLineno);
- fnNode.setEndLineno(ts.getLineno());
-
- Node pn = nf.initFunction(fnNode, functionIndex, body, syntheticType);
- if (memberExprNode != null) {
- pn = nf.createAssignment(Token.ASSIGN, memberExprNode, pn);
- if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
- // XXX check JScript behavior: should it be createExprStatement?
- pn = nf.createExprStatementNoReturn(pn, baseLineno);
- }
- }
- return pn;
- }
-
- private Node statements(Node scope)
- throws IOException
- {
- Node pn = scope != null ? scope : nf.createBlock(ts.getLineno());
-
- int tt;
- while ((tt = peekToken()) > Token.EOF && tt != Token.RC) {
- nf.addChildToBack(pn, statement());
- }
-
- return pn;
- }
-
- private Node condition()
- throws IOException, ParserException
- {
- mustMatchToken(Token.LP, "msg.no.paren.cond");
- decompiler.addToken(Token.LP);
- Node pn = expr(false);
- mustMatchToken(Token.RP, "msg.no.paren.after.cond");
- decompiler.addToken(Token.RP);
-
- // Report strict warning on code like "if (a = 7) ...". Suppress the
- // warning if the condition is parenthesized, like "if ((a = 7)) ...".
- if (pn.getProp(Node.PARENTHESIZED_PROP) == null &&
- (pn.getType() == Token.SETNAME || pn.getType() == Token.SETPROP ||
- pn.getType() == Token.SETELEM))
- {
- addStrictWarning("msg.equal.as.assign", "");
- }
- return pn;
- }
-
- // match a NAME; return null if no match.
- private Node matchJumpLabelName()
- throws IOException, ParserException
- {
- Node label = null;
-
- int tt = peekTokenOrEOL();
- if (tt == Token.NAME) {
- consumeToken();
- String name = ts.getString();
- decompiler.addName(name);
- if (labelSet != null) {
- label = (Node)labelSet.get(name);
- }
- if (label == null) {
- reportError("msg.undef.label");
- }
- }
-
- return label;
- }
-
- private Node statement()
- throws IOException
- {
- try {
- Node pn = statementHelper(null);
- if (pn != null) {
- if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
- addStrictWarning("msg.no.side.effects", "");
- return pn;
- }
- } catch (ParserException e) { }
-
- // skip to end of statement
- int lineno = ts.getLineno();
- guessingStatementEnd: for (;;) {
- int tt = peekTokenOrEOL();
- consumeToken();
- switch (tt) {
- case Token.ERROR:
- case Token.EOF:
- case Token.EOL:
- case Token.SEMI:
- break guessingStatementEnd;
- }
- }
- return nf.createExprStatement(nf.createName("error"), lineno);
- }
-
- /*APPJET*/ /*begin*/
- private Node statementHelper(Node statementLabel)
- throws IOException, ParserException {
-
- Node pn = statementHelper0(statementLabel);
- if (pn != null && pn.getType() != Token.BLOCK && pn.getType() != Token.LOOP) {
- pn.statementEndLineNum = lastConsumedTokenLine;
- }
- return pn;
- }
- /*end*/
-
- private Node statementHelper0(Node statementLabel) /*APPJET*/
- throws IOException, ParserException
- {
- Node pn = null;
- int tt = peekToken();
-
- switch (tt) {
- case Token.IF: {
- consumeToken();
-
- decompiler.addToken(Token.IF);
- int lineno = ts.getLineno();
- Node cond = condition();
- /*APPJET*/cond.lineno = lineno;
- /*APPJET*/cond.statementEndLineNum = lastConsumedTokenLine;
- decompiler.addEOL(Token.LC);
- Node ifTrue = statement();
- Node ifFalse = null;
- if (matchToken(Token.ELSE)) {
- decompiler.addToken(Token.RC);
- decompiler.addToken(Token.ELSE);
- decompiler.addEOL(Token.LC);
- ifFalse = statement();
- }
- decompiler.addEOL(Token.RC);
- pn = nf.createIf(cond, ifTrue, ifFalse, lineno);
- return pn;
- }
-
- case Token.SWITCH: {
- consumeToken();
-
- decompiler.addToken(Token.SWITCH);
- int lineno = ts.getLineno();
- mustMatchToken(Token.LP, "msg.no.paren.switch");
- decompiler.addToken(Token.LP);
- /*APPJET*/Node toSwitchOn = expr(false);
- /*APPJET*/toSwitchOn.lineno = lineno;
- /*APPJET*/toSwitchOn.statementEndLineNum = lastConsumedTokenLine;
- pn = enterSwitch(toSwitchOn, lineno); /*APPJET*/
- try {
- mustMatchToken(Token.RP, "msg.no.paren.after.switch");
- decompiler.addToken(Token.RP);
- mustMatchToken(Token.LC, "msg.no.brace.switch");
- decompiler.addEOL(Token.LC);
-
- boolean hasDefault = false;
- switchLoop: for (;;) {
- tt = nextToken();
- Node caseExpression;
- switch (tt) {
- case Token.RC:
- break switchLoop;
-
- case Token.CASE:
- decompiler.addToken(Token.CASE);
- caseExpression = expr(false);
- mustMatchToken(Token.COLON, "msg.no.colon.case");
- decompiler.addEOL(Token.COLON);
- break;
-
- case Token.DEFAULT:
- if (hasDefault) {
- reportError("msg.double.switch.default");
- }
- decompiler.addToken(Token.DEFAULT);
- hasDefault = true;
- caseExpression = null;
- mustMatchToken(Token.COLON, "msg.no.colon.case");
- decompiler.addEOL(Token.COLON);
- break;
-
- default:
- reportError("msg.bad.switch");
- break switchLoop;
- }
-
- Node block = nf.createLeaf(Token.BLOCK);
- while ((tt = peekToken()) != Token.RC
- && tt != Token.CASE
- && tt != Token.DEFAULT
- && tt != Token.EOF)
- {
- nf.addChildToBack(block, statement());
- }
-
- // caseExpression == null => add default label
- nf.addSwitchCase(pn, caseExpression, block);
- }
- decompiler.addEOL(Token.RC);
- nf.closeSwitch(pn);
- } finally {
- exitSwitch();
- }
- return pn;
- }
-
- case Token.WHILE: {
- consumeToken();
- decompiler.addToken(Token.WHILE);
-
- Node loop = enterLoop(statementLabel, true);
- try {
- /*APPJET*/int lineno = ts.getLineno();
- Node cond = condition();
- /*APPJET*/cond.lineno = lineno;
- /*APPJET*/cond.statementEndLineNum = lastConsumedTokenLine;
- decompiler.addEOL(Token.LC);
- Node body = statement();
- decompiler.addEOL(Token.RC);
- pn = nf.createWhile(loop, cond, body);
- } finally {
- exitLoop(true);
- }
- return pn;
- }
-
- case Token.DO: {
- consumeToken();
- decompiler.addToken(Token.DO);
- decompiler.addEOL(Token.LC);
-
- Node loop = enterLoop(statementLabel, true);
- try {
- Node body = statement();
- decompiler.addToken(Token.RC);
- mustMatchToken(Token.WHILE, "msg.no.while.do");
- decompiler.addToken(Token.WHILE);
- Node cond = condition();
- pn = nf.createDoWhile(loop, body, cond);
- } finally {
- exitLoop(true);
- }
- // Always auto-insert semicolon to follow SpiderMonkey:
- // It is required by ECMAScript but is ignored by the rest of
- // world, see bug 238945
- matchToken(Token.SEMI);
- decompiler.addEOL(Token.SEMI);
- return pn;
- }
-
- case Token.FOR: {
- consumeToken();
- boolean isForEach = false;
- decompiler.addToken(Token.FOR);
-
- Node loop = enterLoop(statementLabel, true);
- try {
- Node init; // Node init is also foo in 'foo in object'
- Node cond; // Node cond is also object in 'foo in object'
- Node incr = null;
- Node body;
- int declType = -1;
-
- // See if this is a for each () instead of just a for ()
- if (matchToken(Token.NAME)) {
- decompiler.addName(ts.getString());
- if (ts.getString().equals("each")) {
- isForEach = true;
- } else {
- reportError("msg.no.paren.for");
- }
- }
-
- mustMatchToken(Token.LP, "msg.no.paren.for");
- decompiler.addToken(Token.LP);
- tt = peekToken();
- if (tt == Token.SEMI) {
- init = nf.createLeaf(Token.EMPTY);
- } else {
- if (tt == Token.VAR || tt == Token.LET) {
- // set init to a var list or initial
- consumeToken(); // consume the token
- decompiler.addToken(tt);
- init = variables(true, tt);
- declType = tt;
- }
- else {
- init = expr(true);
- }
- }
-
- if (matchToken(Token.IN)) {
- decompiler.addToken(Token.IN);
- // 'cond' is the object over which we're iterating
- cond = expr(false);
- } else { // ordinary for loop
- mustMatchToken(Token.SEMI, "msg.no.semi.for");
- decompiler.addToken(Token.SEMI);
- if (peekToken() == Token.SEMI) {
- // no loop condition
- cond = nf.createLeaf(Token.EMPTY);
- } else {
- cond = expr(false);
- }
-
- mustMatchToken(Token.SEMI, "msg.no.semi.for.cond");
- decompiler.addToken(Token.SEMI);
- if (peekToken() == Token.RP) {
- incr = nf.createLeaf(Token.EMPTY);
- } else {
- incr = expr(false);
- }
- }
-
- mustMatchToken(Token.RP, "msg.no.paren.for.ctrl");
- decompiler.addToken(Token.RP);
- decompiler.addEOL(Token.LC);
- /*APPJET*/int parenEndLine = lastConsumedTokenLine;
- body = statement();
- decompiler.addEOL(Token.RC);
-
- if (incr == null) {
- // cond could be null if 'in obj' got eaten
- // by the init node.
- pn = nf.createForIn(declType, loop, init, cond, body,
- isForEach);
- } else {
- pn = nf.createFor(loop, init, cond, incr, body);
- }
- /*APPJET*/ // use the LOOP object to hold the range of the paren'd expr
- /*APPJET*/pn.statementEndLineNum = parenEndLine;
- } finally {
- exitLoop(true);
- }
- return pn;
- }
-
- case Token.TRY: {
- consumeToken();
- int lineno = ts.getLineno();
-
- Node tryblock;
- Node catchblocks = null;
- Node finallyblock = null;
-
- decompiler.addToken(Token.TRY);
- if (peekToken() != Token.LC) {
- reportError("msg.no.brace.try");
- }
- decompiler.addEOL(Token.LC);
- tryblock = statement();
- decompiler.addEOL(Token.RC);
-
- catchblocks = nf.createLeaf(Token.BLOCK);
-
- boolean sawDefaultCatch = false;
- int peek = peekToken();
- if (peek == Token.CATCH) {
- while (matchToken(Token.CATCH)) {
- if (sawDefaultCatch) {
- reportError("msg.catch.unreachable");
- }
- decompiler.addToken(Token.CATCH);
- mustMatchToken(Token.LP, "msg.no.paren.catch");
- decompiler.addToken(Token.LP);
-
- mustMatchToken(Token.NAME, "msg.bad.catchcond");
- String varName = ts.getString();
- decompiler.addName(varName);
-
- Node catchCond = null;
- if (matchToken(Token.IF)) {
- decompiler.addToken(Token.IF);
- catchCond = expr(false);
- } else {
- sawDefaultCatch = true;
- }
-
- mustMatchToken(Token.RP, "msg.bad.catchcond");
- decompiler.addToken(Token.RP);
- mustMatchToken(Token.LC, "msg.no.brace.catchblock");
- decompiler.addEOL(Token.LC);
-
- nf.addChildToBack(catchblocks,
- nf.createCatch(varName, catchCond,
- statements(null),
- ts.getLineno()));
-
- mustMatchToken(Token.RC, "msg.no.brace.after.body");
- decompiler.addEOL(Token.RC);
- }
- } else if (peek != Token.FINALLY) {
- mustMatchToken(Token.FINALLY, "msg.try.no.catchfinally");
- }
-
- if (matchToken(Token.FINALLY)) {
- decompiler.addToken(Token.FINALLY);
- decompiler.addEOL(Token.LC);
- finallyblock = statement();
- decompiler.addEOL(Token.RC);
- }
-
- pn = nf.createTryCatchFinally(tryblock, catchblocks,
- finallyblock, lineno);
-
- return pn;
- }
-
- case Token.THROW: {
- consumeToken();
- if (peekTokenOrEOL() == Token.EOL) {
- // ECMAScript does not allow new lines before throw expression,
- // see bug 256617
- reportError("msg.bad.throw.eol");
- }
-
- int lineno = ts.getLineno();
- decompiler.addToken(Token.THROW);
- pn = nf.createThrow(expr(false), lineno);
- break;
- }
-
- case Token.BREAK: {
- consumeToken();
- int lineno = ts.getLineno();
-
- decompiler.addToken(Token.BREAK);
-
- // matchJumpLabelName only matches if there is one
- Node breakStatement = matchJumpLabelName();
- if (breakStatement == null) {
- if (loopAndSwitchSet == null || loopAndSwitchSet.size() == 0) {
- reportError("msg.bad.break");
- return null;
- }
- breakStatement = (Node)loopAndSwitchSet.peek();
- }
- pn = nf.createBreak(breakStatement, lineno);
- break;
- }
-
- case Token.CONTINUE: {
- consumeToken();
- int lineno = ts.getLineno();
-
- decompiler.addToken(Token.CONTINUE);
-
- Node loop;
- // matchJumpLabelName only matches if there is one
- Node label = matchJumpLabelName();
- if (label == null) {
- if (loopSet == null || loopSet.size() == 0) {
- reportError("msg.continue.outside");
- return null;
- }
- loop = (Node)loopSet.peek();
- } else {
- loop = nf.getLabelLoop(label);
- if (loop == null) {
- reportError("msg.continue.nonloop");
- return null;
- }
- }
- pn = nf.createContinue(loop, lineno);
- break;
- }
-
- case Token.WITH: {
- consumeToken();
-
- decompiler.addToken(Token.WITH);
- int lineno = ts.getLineno();
- mustMatchToken(Token.LP, "msg.no.paren.with");
- decompiler.addToken(Token.LP);
- Node obj = expr(false);
- /*APPJET*/obj.lineno = lineno;
- /*APPJET*/obj.statementEndLineNum = lastConsumedTokenLine;
- mustMatchToken(Token.RP, "msg.no.paren.after.with");
- decompiler.addToken(Token.RP);
- decompiler.addEOL(Token.LC);
-
- ++nestingOfWith;
- Node body;
- try {
- body = statement();
- } finally {
- --nestingOfWith;
- }
-
- decompiler.addEOL(Token.RC);
-
- pn = nf.createWith(obj, body, lineno);
- return pn;
- }
-
- case Token.CONST:
- case Token.VAR: {
- consumeToken();
- decompiler.addToken(tt);
- pn = variables(false, tt);
- break;
- }
-
- case Token.LET: {
- consumeToken();
- decompiler.addToken(Token.LET);
- if (peekToken() == Token.LP) {
- pn = let(true);
- } else {
- pn = variables(false, tt);
- }
- return pn;
- }
-
- case Token.RETURN:
- case Token.YIELD: {
- pn = returnOrYield(tt, false);
- break;
- }
-
- case Token.DEBUGGER:
- consumeToken();
- decompiler.addToken(Token.DEBUGGER);
- pn = nf.createDebugger(ts.getLineno());
- break;
-
- case Token.LC:
- consumeToken();
- if (statementLabel != null) {
- decompiler.addToken(Token.LC);
- }
- Node scope = nf.createScopeNode(Token.BLOCK, ts.getLineno());
- pushScope(scope);
- try {
- statements(scope);
- mustMatchToken(Token.RC, "msg.no.brace.block");
- if (statementLabel != null) {
- decompiler.addEOL(Token.RC);
- }
- return scope;
- } finally {
- popScope();
- }
-
- case Token.ERROR:
- // Fall thru, to have a node for error recovery to work on
- case Token.SEMI:
- consumeToken();
- pn = nf.createLeaf(Token.EMPTY);
- return pn;
-
- case Token.FUNCTION: {
- consumeToken();
- pn = function(FunctionNode.FUNCTION_EXPRESSION_STATEMENT);
- return pn;
- }
-
- case Token.DEFAULT :
- consumeToken();
- mustHaveXML();
-
- decompiler.addToken(Token.DEFAULT);
- int nsLine = ts.getLineno();
-
- if (!(matchToken(Token.NAME)
- && ts.getString().equals("xml")))
- {
- reportError("msg.bad.namespace");
- }
- decompiler.addName(" xml");
-
- if (!(matchToken(Token.NAME)
- && ts.getString().equals("namespace")))
- {
- reportError("msg.bad.namespace");
- }
- decompiler.addName(" namespace");
-
- if (!matchToken(Token.ASSIGN)) {
- reportError("msg.bad.namespace");
- }
- decompiler.addToken(Token.ASSIGN);
-
- Node expr = expr(false);
- pn = nf.createDefaultNamespace(expr, nsLine);
- break;
-
- case Token.NAME: {
- int lineno = ts.getLineno();
- String name = ts.getString();
- setCheckForLabel();
- pn = expr(false);
- if (pn.getType() != Token.LABEL) {
- pn = nf.createExprStatement(pn, lineno);
- } else {
- // Parsed the label: push back token should be
- // colon that primaryExpr left untouched.
- if (peekToken() != Token.COLON) Kit.codeBug();
- consumeToken();
- // depend on decompiling lookahead to guess that that
- // last name was a label.
- decompiler.addName(name);
- decompiler.addEOL(Token.COLON);
-
- if (labelSet == null) {
- labelSet = new Hashtable();
- } else if (labelSet.containsKey(name)) {
- reportError("msg.dup.label");
- }
-
- boolean firstLabel;
- if (statementLabel == null) {
- firstLabel = true;
- statementLabel = pn;
- } else {
- // Discard multiple label nodes and use only
- // the first: it allows to simplify IRFactory
- firstLabel = false;
- }
- labelSet.put(name, statementLabel);
- try {
- pn = statementHelper(statementLabel);
- } finally {
- labelSet.remove(name);
- }
- if (firstLabel) {
- pn = nf.createLabeledStatement(statementLabel, pn);
- }
- return pn;
- }
- break;
- }
-
- default: {
- int lineno = ts.getLineno();
- pn = expr(false);
- pn = nf.createExprStatement(pn, lineno);
- break;
- }
- }
-
- int ttFlagged = peekFlaggedToken();
- switch (ttFlagged & CLEAR_TI_MASK) {
- case Token.SEMI:
- // Consume ';' as a part of expression
- consumeToken();
- break;
- case Token.ERROR:
- case Token.EOF:
- case Token.RC:
- // Autoinsert ;
- break;
- default:
- if ((ttFlagged & TI_AFTER_EOL) == 0) {
- // Report error if no EOL or autoinsert ; otherwise
- reportError("msg.no.semi.stmt");
- }
- break;
- }
- decompiler.addEOL(Token.SEMI);
-
- return pn;
- }
-
- /**
- * Returns whether or not the bits in the mask have changed to all set.
- * @param before bits before change
- * @param after bits after change
- * @param mask mask for bits
- * @return true if all the bits in the mask are set in "after" but not
- * "before"
- */
- private static final boolean nowAllSet(int before, int after, int mask)
- {
- return ((before & mask) != mask) && ((after & mask) == mask);
- }
-
- private Node returnOrYield(int tt, boolean exprContext)
- throws IOException, ParserException
- {
- if (!insideFunction()) {
- reportError(tt == Token.RETURN ? "msg.bad.return"
- : "msg.bad.yield");
- }
- consumeToken();
- decompiler.addToken(tt);
- int lineno = ts.getLineno();
-
- Node e;
- /* This is ugly, but we don't want to require a semicolon. */
- switch (peekTokenOrEOL()) {
- case Token.SEMI:
- case Token.RC:
- case Token.EOF:
- case Token.EOL:
- case Token.ERROR:
- case Token.RB:
- case Token.RP:
- case Token.YIELD:
- e = null;
- break;
- default:
- e = expr(false);
- break;
- }
-
- int before = endFlags;
- Node ret;
-
- if (tt == Token.RETURN) {
- if (e == null ) {
- endFlags |= Node.END_RETURNS;
- } else {
- endFlags |= Node.END_RETURNS_VALUE;
- hasReturnValue = true;
- }
- ret = nf.createReturn(e, lineno);
-
- // see if we need a strict mode warning
- if (nowAllSet(before, endFlags,
- Node.END_RETURNS|Node.END_RETURNS_VALUE))
- {
- addStrictWarning("msg.return.inconsistent", "");
- }
- } else {
- endFlags |= Node.END_YIELDS;
- ret = nf.createYield(e, lineno);
- if (!exprContext)
- ret = new Node(Token.EXPR_VOID, ret, lineno);
- }
-
- // see if we are mixing yields and value returns.
- if (nowAllSet(before, endFlags,
- Node.END_YIELDS|Node.END_RETURNS_VALUE))
- {
- String name = ((FunctionNode)currentScriptOrFn).getFunctionName();
- if (name.length() == 0)
- addError("msg.anon.generator.returns", "");
- else
- addError("msg.generator.returns", name);
- }
-
- return ret;
- }
-
- /**
- * Parse a 'var' or 'const' statement, or a 'var' init list in a for
- * statement.
- * @param inFor true if we are currently in the midst of the init
- * clause of a for.
- * @param inStatement true if called in a statement (as opposed to an
- * expression) context
- * @param declType A token value: either VAR, CONST, or LET depending on
- * context.
- * @return The parsed statement
- * @throws IOException
- * @throws ParserException
- */
- private Node variables(boolean inFor, int declType)
- throws IOException, ParserException
- {
- Node result = nf.createVariables(declType, ts.getLineno());
- boolean first = true;
- for (;;) {
- Node destructuring = null;
- String s = null;
- int tt = peekToken();
- if (tt == Token.LB || tt == Token.LC) {
- // Destructuring assignment, e.g., var [a,b] = ...
- destructuring = primaryExpr();
- } else {
- // Simple variable name
- mustMatchToken(Token.NAME, "msg.bad.var",
- Token.name(declType).toLowerCase());
- s = ts.getString();
-
- if (!first)
- decompiler.addToken(Token.COMMA);
- first = false;
-
- decompiler.addName(s);
- defineSymbol(declType, s);
- }
-
- Node init = null;
- if (matchToken(Token.ASSIGN)) {
- decompiler.addToken(Token.ASSIGN);
- init = assignExpr(inFor);
- }
-
- if (destructuring != null) {
- if (init == null) {
- if (!inFor)
- reportError("msg.destruct.assign.no.init");
- nf.addChildToBack(result, destructuring);
- } else {
- nf.addChildToBack(result,
- nf.createDestructuringAssignment(declType,
- destructuring, init));
- }
- } else {
- Node name = nf.createName(s);
- if (init != null)
- nf.addChildToBack(name, init);
- nf.addChildToBack(result, name);
- }
-
- if (!matchToken(Token.COMMA))
- break;
- }
- return result;
- }
-
-
- private Node let(boolean isStatement)
- throws IOException, ParserException
- {
- mustMatchToken(Token.LP, "msg.no.paren.after.let");
- decompiler.addToken(Token.LP);
- Node result = nf.createScopeNode(Token.LET, ts.getLineno());
- pushScope(result);
- try {
- Node vars = variables(false, Token.LET);
- nf.addChildToBack(result, vars);
- mustMatchToken(Token.RP, "msg.no.paren.let");
- decompiler.addToken(Token.RP);
- if (isStatement && peekToken() == Token.LC) {
- // let statement
- consumeToken();
- decompiler.addEOL(Token.LC);
- nf.addChildToBack(result, statements(null));
- mustMatchToken(Token.RC, "msg.no.curly.let");
- decompiler.addToken(Token.RC);
- } else {
- // let expression
- result.setType(Token.LETEXPR);
- nf.addChildToBack(result, expr(false));
- if (isStatement) {
- // let expression in statement context
- result = nf.createExprStatement(result, ts.getLineno());
- }
- }
- } finally {
- popScope();
- }
- return result;
- }
-
- void defineSymbol(int declType, String name) {
- Node.Scope definingScope = currentScope.getDefiningScope(name);
- Node.Scope.Symbol symbol = definingScope != null
- ? definingScope.getSymbol(name)
- : null;
- boolean error = false;
- if (symbol != null && (symbol.declType == Token.CONST ||
- declType == Token.CONST))
- {
- error = true;
- } else {
- switch (declType) {
- case Token.LET:
- if (symbol != null && definingScope == currentScope) {
- error = symbol.declType == Token.LET;
- }
- currentScope.putSymbol(name,
- new Node.Scope.Symbol(declType, name));
- break;
-
- case Token.VAR:
- case Token.CONST:
- case Token.FUNCTION:
- if (symbol != null) {
- if (symbol.declType == Token.VAR)
- addStrictWarning("msg.var.redecl", name);
- else if (symbol.declType == Token.LP) {
- addStrictWarning("msg.var.hides.arg", name);
- }
- } else {
- currentScriptOrFn.putSymbol(name,
- new Node.Scope.Symbol(declType, name));
- }
- break;
-
- case Token.LP:
- if (symbol != null) {
- // must be duplicate parameter. Second parameter hides the
- // first, so go ahead and add the second pararameter
- addWarning("msg.dup.parms", name);
- }
- currentScriptOrFn.putSymbol(name,
- new Node.Scope.Symbol(declType, name));
- break;
-
- default:
- throw Kit.codeBug();
- }
- }
- if (error) {
- addError(symbol.declType == Token.CONST ? "msg.const.redecl" :
- symbol.declType == Token.LET ? "msg.let.redecl" :
- symbol.declType == Token.VAR ? "msg.var.redecl" :
- symbol.declType == Token.FUNCTION ? "msg.fn.redecl" :
- "msg.parm.redecl", name);
- }
- }
-
- private Node expr(boolean inForInit)
- throws IOException, ParserException
- {
- Node pn = assignExpr(inForInit);
- while (matchToken(Token.COMMA)) {
- decompiler.addToken(Token.COMMA);
- if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
- addStrictWarning("msg.no.side.effects", "");
- if (peekToken() == Token.YIELD) {
- reportError("msg.yield.parenthesized");
- }
- pn = nf.createBinary(Token.COMMA, pn, assignExpr(inForInit));
- }
- return pn;
- }
-
- private Node assignExpr(boolean inForInit)
- throws IOException, ParserException
- {
- int tt = peekToken();
- if (tt == Token.YIELD) {
- consumeToken();
- return returnOrYield(tt, true);
- }
- Node pn = condExpr(inForInit);
-
- tt = peekToken();
- if (Token.FIRST_ASSIGN <= tt && tt <= Token.LAST_ASSIGN) {
- consumeToken();
- decompiler.addToken(tt);
- pn = nf.createAssignment(tt, pn, assignExpr(inForInit));
- }
-
- return pn;
- }
-
- private Node condExpr(boolean inForInit)
- throws IOException, ParserException
- {
- Node pn = orExpr(inForInit);
-
- if (matchToken(Token.HOOK)) {
- decompiler.addToken(Token.HOOK);
- Node ifTrue = assignExpr(false);
- mustMatchToken(Token.COLON, "msg.no.colon.cond");
- decompiler.addToken(Token.COLON);
- Node ifFalse = assignExpr(inForInit);
- return nf.createCondExpr(pn, ifTrue, ifFalse);
- }
-
- return pn;
- }
-
- private Node orExpr(boolean inForInit)
- throws IOException, ParserException
- {
- Node pn = andExpr(inForInit);
- if (matchToken(Token.OR)) {
- decompiler.addToken(Token.OR);
- pn = nf.createBinary(Token.OR, pn, orExpr(inForInit));
- }
-
- return pn;
- }
-
- private Node andExpr(boolean inForInit)
- throws IOException, ParserException
- {
- Node pn = bitOrExpr(inForInit);
- if (matchToken(Token.AND)) {
- decompiler.addToken(Token.AND);
- pn = nf.createBinary(Token.AND, pn, andExpr(inForInit));
- }
-
- return pn;
- }
-
- private Node bitOrExpr(boolean inForInit)
- throws IOException, ParserException
- {
- Node pn = bitXorExpr(inForInit);
- while (matchToken(Token.BITOR)) {
- decompiler.addToken(Token.BITOR);
- pn = nf.createBinary(Token.BITOR, pn, bitXorExpr(inForInit));
- }
- return pn;
- }
-
- private Node bitXorExpr(boolean inForInit)
- throws IOException, ParserException
- {
- Node pn = bitAndExpr(inForInit);
- while (matchToken(Token.BITXOR)) {
- decompiler.addToken(Token.BITXOR);
- pn = nf.createBinary(Token.BITXOR, pn, bitAndExpr(inForInit));
- }
- return pn;
- }
-
- private Node bitAndExpr(boolean inForInit)
- throws IOException, ParserException
- {
- Node pn = eqExpr(inForInit);
- while (matchToken(Token.BITAND)) {
- decompiler.addToken(Token.BITAND);
- pn = nf.createBinary(Token.BITAND, pn, eqExpr(inForInit));
- }
- return pn;
- }
-
- private Node eqExpr(boolean inForInit)
- throws IOException, ParserException
- {
- Node pn = relExpr(inForInit);
- for (;;) {
- int tt = peekToken();
- switch (tt) {
- case Token.EQ:
- case Token.NE:
- case Token.SHEQ:
- case Token.SHNE:
- consumeToken();
- int decompilerToken = tt;
- int parseToken = tt;
- if (compilerEnv.getLanguageVersion() == Context.VERSION_1_2) {
- // JavaScript 1.2 uses shallow equality for == and != .
- // In addition, convert === and !== for decompiler into
- // == and != since the decompiler is supposed to show
- // canonical source and in 1.2 ===, !== are allowed
- // only as an alias to ==, !=.
- switch (tt) {
- case Token.EQ:
- parseToken = Token.SHEQ;
- break;
- case Token.NE:
- parseToken = Token.SHNE;
- break;
- case Token.SHEQ:
- decompilerToken = Token.EQ;
- break;
- case Token.SHNE:
- decompilerToken = Token.NE;
- break;
- }
- }
- decompiler.addToken(decompilerToken);
- pn = nf.createBinary(parseToken, pn, relExpr(inForInit));
- continue;
- }
- break;
- }
- return pn;
- }
-
- private Node relExpr(boolean inForInit)
- throws IOException, ParserException
- {
- Node pn = shiftExpr();
- for (;;) {
- int tt = peekToken();
- switch (tt) {
- case Token.IN:
- if (inForInit)
- break;
- // fall through
- case Token.INSTANCEOF:
- case Token.LE:
- case Token.LT:
- case Token.GE:
- case Token.GT:
- consumeToken();
- decompiler.addToken(tt);
- pn = nf.createBinary(tt, pn, shiftExpr());
- continue;
- }
- break;
- }
- return pn;
- }
-
- private Node shiftExpr()
- throws IOException, ParserException
- {
- Node pn = addExpr();
- for (;;) {
- int tt = peekToken();
- switch (tt) {
- case Token.LSH:
- case Token.URSH:
- case Token.RSH:
- consumeToken();
- decompiler.addToken(tt);
- pn = nf.createBinary(tt, pn, addExpr());
- continue;
- }
- break;
- }
- return pn;
- }
-
- private Node addExpr()
- throws IOException, ParserException
- {
- Node pn = mulExpr();
- for (;;) {
- int tt = peekToken();
- if (tt == Token.ADD || tt == Token.SUB) {
- consumeToken();
- decompiler.addToken(tt);
- // flushNewLines
- pn = nf.createBinary(tt, pn, mulExpr());
- continue;
- }
- break;
- }
-
- return pn;
- }
-
- private Node mulExpr()
- throws IOException, ParserException
- {
- Node pn = unaryExpr();
- for (;;) {
- int tt = peekToken();
- switch (tt) {
- case Token.MUL:
- case Token.DIV:
- case Token.MOD:
- consumeToken();
- decompiler.addToken(tt);
- pn = nf.createBinary(tt, pn, unaryExpr());
- continue;
- }
- break;
- }
-
- return pn;
- }
-
- private Node unaryExpr()
- throws IOException, ParserException
- {
- int tt;
-
- tt = peekToken();
-
- switch(tt) {
- case Token.VOID:
- case Token.NOT:
- case Token.BITNOT:
- case Token.TYPEOF:
- consumeToken();
- decompiler.addToken(tt);
- return nf.createUnary(tt, unaryExpr());
-
- case Token.ADD:
- consumeToken();
- // Convert to special POS token in decompiler and parse tree
- decompiler.addToken(Token.POS);
- return nf.createUnary(Token.POS, unaryExpr());
-
- case Token.SUB:
- consumeToken();
- // Convert to special NEG token in decompiler and parse tree
- decompiler.addToken(Token.NEG);
- return nf.createUnary(Token.NEG, unaryExpr());
-
- case Token.INC:
- case Token.DEC:
- consumeToken();
- decompiler.addToken(tt);
- return nf.createIncDec(tt, false, memberExpr(true));
-
- case Token.DELPROP:
- consumeToken();
- decompiler.addToken(Token.DELPROP);
- return nf.createUnary(Token.DELPROP, unaryExpr());
-
- case Token.ERROR:
- consumeToken();
- break;
-
- // XML stream encountered in expression.
- case Token.LT:
- if (compilerEnv.isXmlAvailable()) {
- consumeToken();
- Node pn = xmlInitializer();
- return memberExprTail(true, pn);
- }
- // Fall thru to the default handling of RELOP
-
- default:
- Node pn = memberExpr(true);
-
- // Don't look across a newline boundary for a postfix incop.
- tt = peekTokenOrEOL();
- if (tt == Token.INC || tt == Token.DEC) {
- consumeToken();
- decompiler.addToken(tt);
- return nf.createIncDec(tt, true, pn);
- }
- return pn;
- }
- return nf.createName("error"); // Only reached on error.Try to continue.
-
- }
-
- private Node xmlInitializer() throws IOException
- {
- int tt = ts.getFirstXMLToken();
- if (tt != Token.XML && tt != Token.XMLEND) {
- reportError("msg.syntax");
- return null;
- }
-
- /* Make a NEW node to append to. */
- Node pnXML = nf.createLeaf(Token.NEW);
-
- String xml = ts.getString();
- boolean fAnonymous = xml.trim().startsWith("<>");
-
- Node pn = nf.createName(fAnonymous ? "XMLList" : "XML");
- nf.addChildToBack(pnXML, pn);
-
- pn = null;
- Node expr;
- for (;;tt = ts.getNextXMLToken()) {
- switch (tt) {
- case Token.XML:
- xml = ts.getString();
- decompiler.addName(xml);
- mustMatchToken(Token.LC, "msg.syntax");
- decompiler.addToken(Token.LC);
- expr = (peekToken() == Token.RC)
- ? nf.createString("")
- : expr(false);
- mustMatchToken(Token.RC, "msg.syntax");
- decompiler.addToken(Token.RC);
- if (pn == null) {
- pn = nf.createString(xml);
- } else {
- pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
- }
- if (ts.isXMLAttribute()) {
- /* Need to put the result in double quotes */
- expr = nf.createUnary(Token.ESCXMLATTR, expr);
- Node prepend = nf.createBinary(Token.ADD,
- nf.createString("\""),
- expr);
- expr = nf.createBinary(Token.ADD,
- prepend,
- nf.createString("\""));
- } else {
- expr = nf.createUnary(Token.ESCXMLTEXT, expr);
- }
- pn = nf.createBinary(Token.ADD, pn, expr);
- break;
- case Token.XMLEND:
- xml = ts.getString();
- decompiler.addName(xml);
- if (pn == null) {
- pn = nf.createString(xml);
- } else {
- pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
- }
-
- nf.addChildToBack(pnXML, pn);
- return pnXML;
- default:
- reportError("msg.syntax");
- return null;
- }
- }
- }
-
- private void argumentList(Node listNode)
- throws IOException, ParserException
- {
- boolean matched;
- matched = matchToken(Token.RP);
- if (!matched) {
- boolean first = true;
- do {
- if (!first)
- decompiler.addToken(Token.COMMA);
- first = false;
- if (peekToken() == Token.YIELD) {
- reportError("msg.yield.parenthesized");
- }
- nf.addChildToBack(listNode, assignExpr(false));
- } while (matchToken(Token.COMMA));
-
- mustMatchToken(Token.RP, "msg.no.paren.arg");
- }
- decompiler.addToken(Token.RP);
- }
-
- private Node memberExpr(boolean allowCallSyntax)
- throws IOException, ParserException
- {
- int tt;
-
- Node pn;
-
- /* Check for new expressions. */
- tt = peekToken();
- if (tt == Token.NEW) {
- /* Eat the NEW token. */
- consumeToken();
- decompiler.addToken(Token.NEW);
-
- /* Make a NEW node to append to. */
- pn = nf.createCallOrNew(Token.NEW, memberExpr(false));
-
- if (matchToken(Token.LP)) {
- decompiler.addToken(Token.LP);
- /* Add the arguments to pn, if any are supplied. */
- argumentList(pn);
- }
-
- /* XXX there's a check in the C source against
- * "too many constructor arguments" - how many
- * do we claim to support?
- */
-
- /* Experimental syntax: allow an object literal to follow a new expression,
- * which will mean a kind of anonymous class built with the JavaAdapter.
- * the object literal will be passed as an additional argument to the constructor.
- */
- tt = peekToken();
- if (tt == Token.LC) {
- nf.addChildToBack(pn, primaryExpr());
- }
- } else {
- pn = primaryExpr();
- }
-
- return memberExprTail(allowCallSyntax, pn);
- }
-
- private Node memberExprTail(boolean allowCallSyntax, Node pn)
- throws IOException, ParserException
- {
- tailLoop:
- for (;;) {
- int tt = peekToken();
- switch (tt) {
-
- case Token.DOT:
- case Token.DOTDOT:
- {
- int memberTypeFlags;
- String s;
-
- consumeToken();
- decompiler.addToken(tt);
- memberTypeFlags = 0;
- if (tt == Token.DOTDOT) {
- mustHaveXML();
- memberTypeFlags = Node.DESCENDANTS_FLAG;
- }
- if (!compilerEnv.isXmlAvailable()) {
- mustMatchToken(Token.NAME, "msg.no.name.after.dot");
- s = ts.getString();
- decompiler.addName(s);
- pn = nf.createPropertyGet(pn, null, s, memberTypeFlags);
- break;
- }
-
- tt = nextToken();
- switch (tt) {
-
- // needed for generator.throw();
- case Token.THROW:
- decompiler.addName("throw");
- pn = propertyName(pn, "throw", memberTypeFlags);
- break;
-
- // handles: name, ns::name, ns::*, ns::[expr]
- case Token.NAME:
- s = ts.getString();
- decompiler.addName(s);
- pn = propertyName(pn, s, memberTypeFlags);
- break;
-
- // handles: *, *::name, *::*, *::[expr]
- case Token.MUL:
- decompiler.addName("*");
- pn = propertyName(pn, "*", memberTypeFlags);
- break;
-
- // handles: '@attr', '@ns::attr', '@ns::*', '@ns::*',
- // '@::attr', '@::*', '@*', '@*::attr', '@*::*'
- case Token.XMLATTR:
- decompiler.addToken(Token.XMLATTR);
- pn = attributeAccess(pn, memberTypeFlags);
- break;
-
- default:
- reportError("msg.no.name.after.dot");
- }
- }
- break;
-
- case Token.DOTQUERY:
- consumeToken();
- mustHaveXML();
- decompiler.addToken(Token.DOTQUERY);
- pn = nf.createDotQuery(pn, expr(false), ts.getLineno());
- mustMatchToken(Token.RP, "msg.no.paren");
- decompiler.addToken(Token.RP);
- break;
-
- case Token.LB:
- consumeToken();
- decompiler.addToken(Token.LB);
- pn = nf.createElementGet(pn, null, expr(false), 0);
- mustMatchToken(Token.RB, "msg.no.bracket.index");
- decompiler.addToken(Token.RB);
- break;
-
- case Token.LP:
- if (!allowCallSyntax) {
- break tailLoop;
- }
- consumeToken();
- decompiler.addToken(Token.LP);
- pn = nf.createCallOrNew(Token.CALL, pn);
- /* Add the arguments to pn, if any are supplied. */
- argumentList(pn);
- break;
-
- default:
- break tailLoop;
- }
- }
- return pn;
- }
-
- /*
- * Xml attribute expression:
- * '@attr', '@ns::attr', '@ns::*', '@ns::*', '@*', '@*::attr', '@*::*'
- */
- private Node attributeAccess(Node pn, int memberTypeFlags)
- throws IOException
- {
- memberTypeFlags |= Node.ATTRIBUTE_FLAG;
- int tt = nextToken();
-
- switch (tt) {
- // handles: @name, @ns::name, @ns::*, @ns::[expr]
- case Token.NAME:
- {
- String s = ts.getString();
- decompiler.addName(s);
- pn = propertyName(pn, s, memberTypeFlags);
- }
- break;
-
- // handles: @*, @*::name, @*::*, @*::[expr]
- case Token.MUL:
- decompiler.addName("*");
- pn = propertyName(pn, "*", memberTypeFlags);
- break;
-
- // handles @[expr]
- case Token.LB:
- decompiler.addToken(Token.LB);
- pn = nf.createElementGet(pn, null, expr(false), memberTypeFlags);
- mustMatchToken(Token.RB, "msg.no.bracket.index");
- decompiler.addToken(Token.RB);
- break;
-
- default:
- reportError("msg.no.name.after.xmlAttr");
- pn = nf.createPropertyGet(pn, null, "?", memberTypeFlags);
- break;
- }
-
- return pn;
- }
-
- /**
- * Check if :: follows name in which case it becomes qualified name
- */
- private Node propertyName(Node pn, String name, int memberTypeFlags)
- throws IOException, ParserException
- {
- String namespace = null;
- if (matchToken(Token.COLONCOLON)) {
- decompiler.addToken(Token.COLONCOLON);
- namespace = name;
-
- int tt = nextToken();
- switch (tt) {
- // handles name::name
- case Token.NAME:
- name = ts.getString();
- decompiler.addName(name);
- break;
-
- // handles name::*
- case Token.MUL:
- decompiler.addName("*");
- name = "*";
- break;
-
- // handles name::[expr]
- case Token.LB:
- decompiler.addToken(Token.LB);
- pn = nf.createElementGet(pn, namespace, expr(false),
- memberTypeFlags);
- mustMatchToken(Token.RB, "msg.no.bracket.index");
- decompiler.addToken(Token.RB);
- return pn;
-
- default:
- reportError("msg.no.name.after.coloncolon");
- name = "?";
- }
- }
-
- pn = nf.createPropertyGet(pn, namespace, name, memberTypeFlags);
- return pn;
- }
-
- private Node arrayComprehension(String arrayName, Node expr)
- throws IOException, ParserException
- {
- if (nextToken() != Token.FOR)
- throw Kit.codeBug(); // shouldn't be here if next token isn't 'for'
- decompiler.addName(" "); // space after array literal expr
- decompiler.addToken(Token.FOR);
- boolean isForEach = false;
- if (matchToken(Token.NAME)) {
- decompiler.addName(ts.getString());
- if (ts.getString().equals("each")) {
- isForEach = true;
- } else {
- reportError("msg.no.paren.for");
- }
- }
- mustMatchToken(Token.LP, "msg.no.paren.for");
- decompiler.addToken(Token.LP);
- String name;
- int tt = peekToken();
- if (tt == Token.LB || tt == Token.LC) {
- // handle destructuring assignment
- name = currentScriptOrFn.getNextTempName();
- defineSymbol(Token.LP, name);
- expr = nf.createBinary(Token.COMMA,
- nf.createAssignment(Token.ASSIGN, primaryExpr(),
- nf.createName(name)),
- expr);
- } else if (tt == Token.NAME) {
- consumeToken();
- name = ts.getString();
- decompiler.addName(name);
- } else {
- reportError("msg.bad.var");
- return nf.createNumber(0);
- }
-
- Node init = nf.createName(name);
- // Define as a let since we want the scope of the variable to
- // be restricted to the array comprehension
- defineSymbol(Token.LET, name);
-
- mustMatchToken(Token.IN, "msg.in.after.for.name");
- decompiler.addToken(Token.IN);
- Node iterator = expr(false);
- mustMatchToken(Token.RP, "msg.no.paren.for.ctrl");
- decompiler.addToken(Token.RP);
-
- Node body;
- tt = peekToken();
- if (tt == Token.FOR) {
- body = arrayComprehension(arrayName, expr);
- } else {
- Node call = nf.createCallOrNew(Token.CALL,
- nf.createPropertyGet(nf.createName(arrayName), null,
- "push", 0));
- call.addChildToBack(expr);
- body = new Node(Token.EXPR_VOID, call, ts.getLineno());
- if (tt == Token.IF) {
- consumeToken();
- decompiler.addToken(Token.IF);
- int lineno = ts.getLineno();
- Node cond = condition();
- body = nf.createIf(cond, body, null, lineno);
- }
- mustMatchToken(Token.RB, "msg.no.bracket.arg");
- decompiler.addToken(Token.RB);
- }
-
- Node loop = enterLoop(null, true);
- try {
- return nf.createForIn(Token.LET, loop, init, iterator, body,
- isForEach);
- } finally {
- exitLoop(false);
- }
- }
-
- private Node primaryExpr()
- throws IOException, ParserException
- {
- Node pn;
-
- int ttFlagged = nextFlaggedToken();
- int tt = ttFlagged & CLEAR_TI_MASK;
-
- switch(tt) {
-
- case Token.FUNCTION:
- return function(FunctionNode.FUNCTION_EXPRESSION);
-
- case Token.LB: {
- ObjArray elems = new ObjArray();
- int skipCount = 0;
- int destructuringLen = 0;
- decompiler.addToken(Token.LB);
- boolean after_lb_or_comma = true;
- for (;;) {
- tt = peekToken();
-
- if (tt == Token.COMMA) {
- consumeToken();
- decompiler.addToken(Token.COMMA);
- if (!after_lb_or_comma) {
- after_lb_or_comma = true;
- } else {
- elems.add(null);
- ++skipCount;
- }
- } else if (tt == Token.RB) {
- consumeToken();
- decompiler.addToken(Token.RB);
- // for ([a,] in obj) is legal, but for ([a] in obj) is
- // not since we have both key and value supplied. The
- // trick is that [a,] and [a] are equivalent in other
- // array literal contexts. So we calculate a special
- // length value just for destructuring assignment.
- destructuringLen = elems.size() +
- (after_lb_or_comma ? 1 : 0);
- break;
- } else if (skipCount == 0 && elems.size() == 1 &&
- tt == Token.FOR)
- {
- Node scopeNode = nf.createScopeNode(Token.ARRAYCOMP,
- ts.getLineno());
- String tempName = currentScriptOrFn.getNextTempName();
- pushScope(scopeNode);
- try {
- defineSymbol(Token.LET, tempName);
- Node expr = (Node) elems.get(0);
- Node block = nf.createBlock(ts.getLineno());
- Node init = new Node(Token.EXPR_VOID,
- nf.createAssignment(Token.ASSIGN,
- nf.createName(tempName),
- nf.createCallOrNew(Token.NEW,
- nf.createName("Array"))), ts.getLineno());
- block.addChildToBack(init);
- block.addChildToBack(arrayComprehension(tempName,
- expr));
- scopeNode.addChildToBack(block);
- scopeNode.addChildToBack(nf.createName(tempName));
- return scopeNode;
- } finally {
- popScope();
- }
- } else {
- if (!after_lb_or_comma) {
- reportError("msg.no.bracket.arg");
- }
- elems.add(assignExpr(false));
- after_lb_or_comma = false;
- }
- }
- return nf.createArrayLiteral(elems, skipCount, destructuringLen);
- }
-
- case Token.LC: {
- ObjArray elems = new ObjArray();
- decompiler.addToken(Token.LC);
- if (!matchToken(Token.RC)) {
-
- boolean first = true;
- commaloop:
- do {
- Object property;
-
- if (!first)
- decompiler.addToken(Token.COMMA);
- else
- first = false;
-
- tt = peekToken();
- switch(tt) {
- case Token.NAME:
- case Token.STRING:
- consumeToken();
- // map NAMEs to STRINGs in object literal context
- // but tell the decompiler the proper type
- String s = ts.getString();
- if (tt == Token.NAME) {
- if (s.equals("get") &&
- peekToken() == Token.NAME) {
- decompiler.addToken(Token.GET);
- consumeToken();
- s = ts.getString();
- decompiler.addName(s);
- property = ScriptRuntime.getIndexObject(s);
- if (!getterSetterProperty(elems, property,
- true))
- break commaloop;
- break;
- } else if (s.equals("set") &&
- peekToken() == Token.NAME) {
- decompiler.addToken(Token.SET);
- consumeToken();
- s = ts.getString();
- decompiler.addName(s);
- property = ScriptRuntime.getIndexObject(s);
- if (!getterSetterProperty(elems, property,
- false))
- break commaloop;
- break;
- }
- decompiler.addName(s);
- } else {
- decompiler.addString(s);
- }
- property = ScriptRuntime.getIndexObject(s);
- plainProperty(elems, property);
- break;
-
- case Token.NUMBER:
- consumeToken();
- double n = ts.getNumber();
- decompiler.addNumber(n);
- property = ScriptRuntime.getIndexObject(n);
- plainProperty(elems, property);
- break;
-
- case Token.RC:
- // trailing comma is OK.
- break commaloop;
- default:
- reportError("msg.bad.prop");
- break commaloop;
- }
- } while (matchToken(Token.COMMA));
-
- mustMatchToken(Token.RC, "msg.no.brace.prop");
- }
- decompiler.addToken(Token.RC);
- return nf.createObjectLiteral(elems);
- }
-
- case Token.LET:
- decompiler.addToken(Token.LET);
- return let(false);
-
- case Token.LP:
-
- /* Brendan's IR-jsparse.c makes a new node tagged with
- * TOK_LP here... I'm not sure I understand why. Isn't
- * the grouping already implicit in the structure of the
- * parse tree? also TOK_LP is already overloaded (I
- * think) in the C IR as 'function call.' */
- decompiler.addToken(Token.LP);
- pn = expr(false);
- pn.putProp(Node.PARENTHESIZED_PROP, Boolean.TRUE);
- decompiler.addToken(Token.RP);
- mustMatchToken(Token.RP, "msg.no.paren");
- return pn;
-
- case Token.XMLATTR:
- mustHaveXML();
- decompiler.addToken(Token.XMLATTR);
- pn = attributeAccess(null, 0);
- return pn;
-
- case Token.NAME: {
- String name = ts.getString();
- if ((ttFlagged & TI_CHECK_LABEL) != 0) {
- if (peekToken() == Token.COLON) {
- // Do not consume colon, it is used as unwind indicator
- // to return to statementHelper.
- // XXX Better way?
- return nf.createLabel(ts.getLineno());
- }
- }
-
- decompiler.addName(name);
- if (compilerEnv.isXmlAvailable()) {
- pn = propertyName(null, name, 0);
- } else {
- pn = nf.createName(name);
- }
- return pn;
- }
-
- case Token.NUMBER: {
- double n = ts.getNumber();
- decompiler.addNumber(n);
- return nf.createNumber(n);
- }
-
- case Token.STRING: {
- String s = ts.getString();
- decompiler.addString(s);
- return nf.createString(s);
- }
-
- case Token.DIV:
- case Token.ASSIGN_DIV: {
- // Got / or /= which should be treated as regexp in fact
- ts.readRegExp(tt);
- String flags = ts.regExpFlags;
- ts.regExpFlags = null;
- String re = ts.getString();
- decompiler.addRegexp(re, flags);
- /*APPJET*/
- int index = currentScriptOrFn.addRegexp
- (re, flags, getCurrentLineNumber());
- return nf.createRegExp(index);
- }
-
- case Token.NULL:
- case Token.THIS:
- case Token.FALSE:
- case Token.TRUE:
- decompiler.addToken(tt);
- return nf.createLeaf(tt);
-
- case Token.RESERVED:
- reportError("msg.reserved.id");
- break;
-
- case Token.ERROR:
- /* the scanner or one of its subroutines reported the error. */
- break;
-
- case Token.EOF:
- reportError("msg.unexpected.eof");
- break;
-
- default:
- reportError("msg.syntax");
- break;
- }
- return null; // should never reach here
- }
-
- private void plainProperty(ObjArray elems, Object property)
- throws IOException {
- mustMatchToken(Token.COLON, "msg.no.colon.prop");
-
- // OBJLIT is used as ':' in object literal for
- // decompilation to solve spacing ambiguity.
- decompiler.addToken(Token.OBJECTLIT);
- elems.add(property);
- elems.add(assignExpr(false));
- }
-
- private boolean getterSetterProperty(ObjArray elems, Object property,
- boolean isGetter) throws IOException {
- Node f = function(FunctionNode.FUNCTION_EXPRESSION);
- if (f.getType() != Token.FUNCTION) {
- reportError("msg.bad.prop");
- return false;
- }
- int fnIndex = f.getExistingIntProp(Node.FUNCTION_PROP);
- FunctionNode fn = currentScriptOrFn.getFunctionNode(fnIndex);
- if (fn.getFunctionName().length() != 0) {
- reportError("msg.bad.prop");
- return false;
- }
- elems.add(property);
- if (isGetter) {
- elems.add(nf.createUnary(Token.GET, f));
- } else {
- elems.add(nf.createUnary(Token.SET, f));
- }
- return true;
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/PolicySecurityController.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/PolicySecurityController.java
deleted file mode 100644
index c4d3d7e..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/PolicySecurityController.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/* ***** 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):
- *
- * 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;
-
-import java.lang.ref.SoftReference;
-import java.lang.reflect.UndeclaredThrowableException;
-import java.security.AccessController;
-import java.security.CodeSource;
-import java.security.Policy;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.security.SecureClassLoader;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import org.mozilla.classfile.ByteCode;
-import org.mozilla.classfile.ClassFileWriter;
-
-/**
- * A security controller relying on Java {@link Policy} in effect. When you use
- * this security controller, your securityDomain objects must be instances of
- * {@link CodeSource} representing the location from where you load your
- * scripts. Any Java policy "grant" statements matching the URL and certificate
- * in code sources will apply to the scripts. If you specify any certificates
- * within your {@link CodeSource} objects, it is your responsibility to verify
- * (or not) that the script source files are signed in whatever
- * implementation-specific way you're using.
- * @author Attila Szegedi
- */
-public class PolicySecurityController extends SecurityController
-{
- private static final byte[] secureCallerImplBytecode = loadBytecode();
-
- // We're storing a CodeSource -> (ClassLoader -> SecureRenderer), since we
- // need to have one renderer per class loader. We're using weak hash maps
- // and soft references all the way, since we don't want to interfere with
- // cleanup of either CodeSource or ClassLoader objects.
- private static final Map callers = new WeakHashMap();
-
- public Class getStaticSecurityDomainClassInternal() {
- return CodeSource.class;
- }
-
- private static class Loader extends SecureClassLoader
- implements GeneratedClassLoader
- {
- private final CodeSource codeSource;
-
- Loader(ClassLoader parent, CodeSource codeSource)
- {
- super(parent);
- this.codeSource = codeSource;
- }
-
- public Class defineClass(String name, byte[] data)
- {
- return defineClass(name, data, 0, data.length, codeSource);
- }
-
- public void linkClass(Class cl)
- {
- resolveClass(cl);
- }
- }
-
- public GeneratedClassLoader createClassLoader(final ClassLoader parent,
- final Object securityDomain)
- {
- return (Loader)AccessController.doPrivileged(
- new PrivilegedAction()
- {
- public Object run()
- {
- return new Loader(parent, (CodeSource)securityDomain);
- }
- });
- }
-
- public Object getDynamicSecurityDomain(Object securityDomain)
- {
- // No separate notion of dynamic security domain - just return what was
- // passed in.
- return securityDomain;
- }
-
- public Object callWithDomain(final Object securityDomain, final Context cx,
- Callable callable, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- // Run in doPrivileged as we might be checked for "getClassLoader"
- // runtime permission
- final ClassLoader classLoader = (ClassLoader)AccessController.doPrivileged(
- new PrivilegedAction() {
- public Object run() {
- return cx.getApplicationClassLoader();
- }
- });
- final CodeSource codeSource = (CodeSource)securityDomain;
- Map classLoaderMap;
- synchronized(callers)
- {
- classLoaderMap = (Map)callers.get(codeSource);
- if(classLoaderMap == null)
- {
- classLoaderMap = new WeakHashMap();
- callers.put(codeSource, classLoaderMap);
- }
- }
- SecureCaller caller;
- synchronized(classLoaderMap)
- {
- SoftReference ref = (SoftReference)classLoaderMap.get(classLoader);
- if(ref != null)
- {
- caller = (SecureCaller)ref.get();
- }
- else
- {
- caller = null;
- }
- if(caller == null)
- {
- try
- {
- // Run in doPrivileged as we'll be checked for
- // "createClassLoader" runtime permission
- caller = (SecureCaller)AccessController.doPrivileged(
- new PrivilegedExceptionAction()
- {
- public Object run() throws Exception
- {
- Loader loader = new Loader(classLoader,
- codeSource);
- Class c = loader.defineClass(
- SecureCaller.class.getName() + "Impl",
- secureCallerImplBytecode);
- return c.newInstance();
- }
- });
- classLoaderMap.put(classLoader, new SoftReference(caller));
- }
- catch(PrivilegedActionException ex)
- {
- throw new UndeclaredThrowableException(ex.getCause());
- }
- }
- }
- return caller.call(callable, cx, scope, thisObj, args);
- }
-
- public abstract static class SecureCaller
- {
- public abstract Object call(Callable callable, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args);
- }
-
-
- private static byte[] loadBytecode()
- {
- String secureCallerClassName = SecureCaller.class.getName();
- ClassFileWriter cfw = new ClassFileWriter(
- secureCallerClassName + "Impl", secureCallerClassName,
- "<generated>");
- cfw.startMethod("<init>", "()V", ClassFileWriter.ACC_PUBLIC);
- cfw.addALoad(0);
- cfw.addInvoke(ByteCode.INVOKESPECIAL, secureCallerClassName,
- "<init>", "()V");
- cfw.add(ByteCode.RETURN);
- cfw.stopMethod((short)1);
- String callableCallSig =
- "Lorg/mozilla/javascript/Context;" +
- "Lorg/mozilla/javascript/Scriptable;" +
- "Lorg/mozilla/javascript/Scriptable;" +
- "[Ljava/lang/Object;)Ljava/lang/Object;";
-
- cfw.startMethod("call",
- "(Lorg/mozilla/javascript/Callable;" + callableCallSig,
- (short)(ClassFileWriter.ACC_PUBLIC
- | ClassFileWriter.ACC_FINAL));
- for(int i = 1; i < 6; ++i) {
- cfw.addALoad(i);
- }
- cfw.addInvoke(ByteCode.INVOKEINTERFACE,
- "org/mozilla/javascript/Callable", "call",
- "(" + callableCallSig);
- cfw.add(ByteCode.ARETURN);
- cfw.stopMethod((short)6);
- return cfw.toByteArray();
- }
-} \ No newline at end of file
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Ref.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Ref.java
deleted file mode 100644
index 1e237bc..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Ref.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- 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):
- * Igor Bukanov, igor@fastmail.fm
- *
- * 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;
-
-import java.io.Serializable;
-
-/**
- * Generic notion of reference object that know how to query/modify the
- * target objects based on some property/index.
- */
-public abstract class Ref implements Serializable
-{
- public boolean has(Context cx)
- {
- return true;
- }
-
- public abstract Object get(Context cx);
-
- public abstract Object set(Context cx, Object value);
-
- public boolean delete(Context cx)
- {
- return false;
- }
-
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RefCallable.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RefCallable.java
deleted file mode 100644
index 6d4b61c..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RefCallable.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- 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):
- * Igor Bukanov, igor@mir2.org
- *
- * 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;
-
-/**
- * Object that can allows assignments to the result of function calls.
- */
-public interface RefCallable extends Callable
-{
- /**
- * Perform function call in reference context.
- * The args array reference should not be stored in any object that is
- * can be GC-reachable after this method returns. If this is necessary,
- * for example, to implement {@link Ref} methods, then store args.clone(),
- * not args array itself.
- *
- * @param cx the current Context for this thread
- * @param thisObj the JavaScript <code>this</code> object
- * @param args the array of arguments
- */
- public Ref refCall(Context cx, Scriptable thisObj, Object[] args);
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RegExpProxy.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RegExpProxy.java
deleted file mode 100644
index ac29c6e..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RegExpProxy.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- 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
- * Roger Lawrence
- *
- * 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;
-
-/**
- * A proxy for the regexp package, so that the regexp package can be
- * loaded optionally.
- *
- * @author Norris Boyd
- */
-public interface RegExpProxy
-{
- // Types of regexp actions
-
- public static final int RA_MATCH = 1;
- public static final int RA_REPLACE = 2;
- public static final int RA_SEARCH = 3;
-
- public boolean isRegExp(Scriptable obj);
-
- public Object compileRegExp(Context cx, String source, String flags);
-
- public Scriptable wrapRegExp(Context cx, Scriptable scope,
- Object compiled);
-
- public Object action(Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args,
- int actionType);
-
- public int find_split(Context cx, Scriptable scope, String target,
- String separator, Scriptable re,
- int[] ip, int[] matchlen,
- boolean[] matched, String[][] parensp);
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RhinoException.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RhinoException.java
deleted file mode 100644
index b7f4a4d..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RhinoException.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/* -*- 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;
-
-import java.io.CharArrayWriter;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * The class of exceptions thrown by the JavaScript engine.
- */
-public abstract class RhinoException extends RuntimeException
-{
- RhinoException()
- {
- Evaluator e = Context.createInterpreter();
- if (e != null)
- e.captureStackInfo(this);
- }
-
- RhinoException(String details)
- {
- super(details);
- Evaluator e = Context.createInterpreter();
- if (e != null)
- e.captureStackInfo(this);
- }
-
- public final String getMessage()
- {
- String details = details();
- if (sourceName == null || lineNumber <= 0) {
- return details;
- }
- StringBuffer buf = new StringBuffer(details);
- buf.append(" (");
- if (sourceName != null) {
- buf.append(sourceName);
- }
- if (lineNumber > 0) {
- buf.append('#');
- buf.append(lineNumber);
- }
- buf.append(')');
- return buf.toString();
- }
-
- public String details()
- {
- return super.getMessage();
- }
-
- /**
- * Get the uri of the script source containing the error, or null
- * if that information is not available.
- */
- public final String sourceName()
- {
- return sourceName;
- }
-
- /**
- * Initialize the uri of the script source containing the error.
- *
- * @param sourceName the uri of the script source responsible for the error.
- * It should not be <tt>null</tt>.
- *
- * @throws IllegalStateException if the method is called more then once.
- */
- public final void initSourceName(String sourceName)
- {
- if (sourceName == null) throw new IllegalArgumentException();
- if (this.sourceName != null) throw new IllegalStateException();
- this.sourceName = sourceName;
- }
-
- /**
- * Returns the line number of the statement causing the error,
- * or zero if not available.
- */
- public final int lineNumber()
- {
- return lineNumber;
- }
-
- /**
- * Initialize the line number of the script statement causing the error.
- *
- * @param lineNumber the line number in the script source.
- * It should be positive number.
- *
- * @throws IllegalStateException if the method is called more then once.
- */
- public final void initLineNumber(int lineNumber)
- {
- if (lineNumber <= 0) throw new IllegalArgumentException(String.valueOf(lineNumber));
- if (this.lineNumber > 0) throw new IllegalStateException();
- this.lineNumber = lineNumber;
- }
-
- /**
- * The column number of the location of the error, or zero if unknown.
- */
- public final int columnNumber()
- {
- return columnNumber;
- }
-
- /**
- * Initialize the column number of the script statement causing the error.
- *
- * @param columnNumber the column number in the script source.
- * It should be positive number.
- *
- * @throws IllegalStateException if the method is called more then once.
- */
- public final void initColumnNumber(int columnNumber)
- {
- if (columnNumber <= 0) throw new IllegalArgumentException(String.valueOf(columnNumber));
- if (this.columnNumber > 0) throw new IllegalStateException();
- this.columnNumber = columnNumber;
- }
-
- /**
- * The source text of the line causing the error, or null if unknown.
- */
- public final String lineSource()
- {
- return lineSource;
- }
-
- /**
- * Initialize the text of the source line containing the error.
- *
- * @param lineSource the text of the source line responsible for the error.
- * It should not be <tt>null</tt>.
- *
- * @throws IllegalStateException if the method is called more then once.
- */
- public final void initLineSource(String lineSource)
- {
- if (lineSource == null) throw new IllegalArgumentException();
- if (this.lineSource != null) throw new IllegalStateException();
- this.lineSource = lineSource;
- }
-
- final void recordErrorOrigin(String sourceName, int lineNumber,
- String lineSource, int columnNumber)
- {
- // XXX: for compatibility allow for now -1 to mean 0
- if (lineNumber == -1) {
- lineNumber = 0;
- }
-
- if (sourceName != null) {
- initSourceName(sourceName);
- }
- if (lineNumber != 0) {
- initLineNumber(lineNumber);
- }
- if (lineSource != null) {
- initLineSource(lineSource);
- }
- if (columnNumber != 0) {
- initColumnNumber(columnNumber);
- }
- }
-
- private String generateStackTrace()
- {
- // Get stable reference to work properly with concurrent access
- CharArrayWriter writer = new CharArrayWriter();
- super.printStackTrace(new PrintWriter(writer));
- String origStackTrace = writer.toString();
- Evaluator e = Context.createInterpreter();
- if (e != null)
- return e.getPatchedStack(this, origStackTrace);
- return null;
- }
-
- /**
- * Get a string representing the script stack of this exception.
- * If optimization is enabled, this corresponds to all java stack elements
- * with a source name ending with ".js".
- * @return a script stack dump
- * @since 1.6R6
- */
- public String getScriptStackTrace()
- {
- return getScriptStackTrace(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.endsWith(".js");
- }
- });
- }
-
- /**
- * Get a string representing the script stack of this exception.
- * If optimization is enabled, this corresponds to all java stack elements
- * with a source name matching the <code>filter</code>.
- * @param filter the file name filter to determine whether a file is a
- * script file
- * @return a script stack dump
- * @since 1.6R6
- */
- public String getScriptStackTrace(FilenameFilter filter)
- {
- List interpreterStack;
- Evaluator interpreter = Context.createInterpreter();
- if (interpreter != null)
- interpreterStack = interpreter.getScriptStack(this);
- else
- interpreterStack = new ArrayList();
- int interpreterStackIndex = 0;
- StringBuffer buffer = new StringBuffer();
- String lineSeparator = SecurityUtilities.getSystemProperty("line.separator");
- StackTraceElement[] stack = getStackTrace();
- for (int i = 0; i < stack.length; i++) {
- StackTraceElement e = stack[i];
- String name = e.getFileName();
- if (e.getLineNumber() > -1 && name != null &&
- filter.accept(null, name))
- {
- buffer.append("\tat ");
- buffer.append(e.getFileName());
- buffer.append(':');
- buffer.append(e.getLineNumber());
- buffer.append(lineSeparator);
- } else if (interpreterStack != null &&
- "org.mozilla.javascript.Interpreter".equals(e.getClassName()) &&
- "interpretLoop".equals(e.getMethodName()))
- {
- buffer.append(interpreterStack.get(interpreterStackIndex++));
- }
- }
- return buffer.toString();
- }
-
- public void printStackTrace(PrintWriter s)
- {
- if (interpreterStackInfo == null) {
- super.printStackTrace(s);
- } else {
- s.print(generateStackTrace());
- }
- }
-
- public void printStackTrace(PrintStream s)
- {
- if (interpreterStackInfo == null) {
- super.printStackTrace(s);
- } else {
- s.print(generateStackTrace());
- }
- }
-
- private String sourceName;
- private int lineNumber;
- private String lineSource;
- private int columnNumber;
-
- Object interpreterStackInfo;
- int[] interpreterLineData;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Script.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Script.java
deleted file mode 100644
index 4721ead..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Script.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- 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
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * All compiled scripts implement this interface.
- * <p>
- * This class encapsulates script execution relative to an
- * object scope.
- * @since 1.3
- * @author Norris Boyd
- */
-
-public interface Script {
-
- /**
- * Execute the script.
- * <p>
- * The script is executed in a particular runtime Context, which
- * must be associated with the current thread.
- * The script is executed relative to a scope--definitions and
- * uses of global top-level variables and functions will access
- * properties of the scope object. For compliant ECMA
- * programs, the scope must be an object that has been initialized
- * as a global object using <code>Context.initStandardObjects</code>.
- * <p>
- *
- * @param cx the Context associated with the current thread
- * @param scope the scope to execute relative to
- * @return the result of executing the script
- * @see org.mozilla.javascript.Context#initStandardObjects()
- */
- public Object exec(Context cx, Scriptable scope);
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptOrFnNode.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptOrFnNode.java
deleted file mode 100644
index 9ea6d1f..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptOrFnNode.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/* -*- 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):
- * Igor Bukanov
- * Bob Jervis
- * Norris Boyd
- *
- * 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;
-
-import java.util.ArrayList;
-
-public class ScriptOrFnNode extends Node.Scope {
-
- public ScriptOrFnNode(int nodeType) {
- super(nodeType);
- symbols = new ArrayList(4);
- setParent(null);
- }
-
- public final String getSourceName() { return sourceName; }
-
- public final void setSourceName(String sourceName) {
- this.sourceName = sourceName;
- }
-
- public final int getEncodedSourceStart() { return encodedSourceStart; }
-
- public final int getEncodedSourceEnd() { return encodedSourceEnd; }
-
- public final void setEncodedSourceBounds(int start, int end) {
- this.encodedSourceStart = start;
- this.encodedSourceEnd = end;
- }
-
- public final int getBaseLineno() { return this.lineno; }
-
- public final void setBaseLineno(int lineno) {
- // One time action
- if (lineno < 0 || this.lineno >= 0) Kit.codeBug();
- this.lineno = lineno;
- }
-
- public final int getEndLineno() { return endLineno; }
-
- public final void setEndLineno(int lineno) {
- // One time action
- if (lineno < 0 || endLineno >= 0) Kit.codeBug();
- endLineno = lineno;
- }
-
- public final int getFunctionCount() {
- if (functions == null) { return 0; }
- return functions.size();
- }
-
- public final FunctionNode getFunctionNode(int i) {
- return (FunctionNode)functions.get(i);
- }
-
- public final int addFunction(FunctionNode fnNode) {
- if (fnNode == null) Kit.codeBug();
- if (functions == null) { functions = new ObjArray(); }
- functions.add(fnNode);
- return functions.size() - 1;
- }
-
- public final int getRegexpCount() {
- if (regexps == null) { return 0; }
- return regexps.size() / 2;
- }
-
- public final String getRegexpString(int index) {
- return (String)regexps.get(index * 2);
- }
-
- public final String getRegexpFlags(int index) {
- return (String)regexps.get(index * 2 + 1);
- }
-
- /*APPJET*/public final int getRegexpLineno(int index) {
- return (Integer)regexpLinenos.get(index);
- }
-
- public final int addRegexp(String string, String flags, /*APPJET*/
- int lineno) {
- if (string == null) Kit.codeBug();
- if (regexps == null) {
- /*APPJET*/
- regexps = new ObjArray();
- regexpLinenos = new ObjArray();
- }
- regexps.add(string);
- regexps.add(flags);
- /*APPJET*/regexpLinenos.add(lineno);
- return regexps.size() / 2 - 1;
- }
-
- public int getIndexForNameNode(Node nameNode) {
- if (variableNames == null) throw Kit.codeBug();
- Node.Scope node = nameNode.getScope();
- Symbol symbol = node == null ? null
- : node.getSymbol(nameNode.getString());
- if (symbol == null)
- return -1;
- return symbol.index;
- }
-
- public final String getParamOrVarName(int index) {
- if (variableNames == null) throw Kit.codeBug();
- return variableNames[index];
- }
-
- public final int getParamCount() {
- return paramCount;
- }
-
- public final int getParamAndVarCount() {
- if (variableNames == null) throw Kit.codeBug();
- return symbols.size();
- }
-
- public final String[] getParamAndVarNames() {
- if (variableNames == null) throw Kit.codeBug();
- return variableNames;
- }
-
- public final boolean[] getParamAndVarConst() {
- if (variableNames == null) throw Kit.codeBug();
- return isConsts;
- }
-
- void addSymbol(Symbol symbol) {
- if (variableNames != null) throw Kit.codeBug();
- if (symbol.declType == Token.LP) {
- paramCount++;
- }
- symbols.add(symbol);
- }
-
- /**
- * Assign every symbol a unique integer index. Generate arrays of variable
- * names and constness that can be indexed by those indices.
- *
- * @param flattenAllTables if true, flatten all symbol tables, included
- * nested block scope symbol tables. If false, just flatten the script's
- * or function's symbol table.
- */
- void flattenSymbolTable(boolean flattenAllTables) {
- if (!flattenAllTables) {
- ArrayList newSymbols = new ArrayList();
- if (this.symbolTable != null) {
- // Just replace "symbols" with the symbols in this object's
- // symbol table. Can't just work from symbolTable map since
- // we need to retain duplicate parameters.
- for (int i=0; i < symbols.size(); i++) {
- Symbol symbol = (Symbol) symbols.get(i);
- if (symbol.containingTable == this) {
- newSymbols.add(symbol);
- }
- }
- }
- symbols = newSymbols;
- }
- variableNames = new String[symbols.size()];
- isConsts = new boolean[symbols.size()];
- for (int i=0; i < symbols.size(); i++) {
- Symbol symbol = (Symbol) symbols.get(i);
- variableNames[i] = symbol.name;
- isConsts[i] = symbol.declType == Token.CONST;
- symbol.index = i;
- }
- }
-
- public final Object getCompilerData()
- {
- return compilerData;
- }
-
- public final void setCompilerData(Object data)
- {
- if (data == null) throw new IllegalArgumentException();
- // Can only call once
- if (compilerData != null) throw new IllegalStateException();
- compilerData = data;
- }
-
- public String getNextTempName()
- {
- return "$" + tempNumber++;
- }
-
- private int encodedSourceStart;
- private int encodedSourceEnd;
- private String sourceName;
- private int endLineno = -1;
-
- private ObjArray functions;
- private ObjArray regexps;
- /*APPJET*/ private ObjArray regexpLinenos;
-
- private ArrayList symbols;
- private int paramCount = 0;
- private String[] variableNames;
- private boolean[] isConsts;
-
- private Object compilerData;
- private int tempNumber = 0;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptRuntime.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptRuntime.java
deleted file mode 100644
index f879581..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptRuntime.java
+++ /dev/null
@@ -1,3830 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Beard
- * Norris Boyd
- * Igor Bukanov
- * Ethan Hugg
- * Bob Jervis
- * Roger Lawrence
- * Terry Lucas
- * Frank Mitchell
- * Milen Nankov
- * Hannes Wallnoefer
- * Andrew Wason
- *
- * 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;
-
-import java.io.Serializable;
-import java.lang.reflect.*;
-import java.text.MessageFormat;
-import java.util.Locale;
-import java.util.ResourceBundle;
-
-import org.mozilla.javascript.xml.XMLObject;
-import org.mozilla.javascript.xml.XMLLib;
-
-/**
- * This is the class that implements the runtime.
- *
- * @author Norris Boyd
- */
-
-public class ScriptRuntime {
-
- /**
- * No instances should be created.
- */
- protected ScriptRuntime() {
- }
-
- private static class NoSuchMethodShim implements Callable {
- String methodName;
- Callable noSuchMethodMethod;
-
- NoSuchMethodShim(Callable noSuchMethodMethod, String methodName)
- {
- this.noSuchMethodMethod = noSuchMethodMethod;
- this.methodName = methodName;
- }
- /**
- * Perform the call.
- *
- * @param cx the current Context for this thread
- * @param scope the scope to use to resolve properties.
- * @param thisObj the JavaScript <code>this</code> object
- * @param args the array of arguments
- * @return the result of the call
- */
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- Object[] nestedArgs = new Object[2];
-
- nestedArgs[0] = methodName;
- nestedArgs[1] = newArrayLiteral(args, null, cx, scope);
- return noSuchMethodMethod.call(cx, scope, thisObj, nestedArgs);
- }
-
- }
- /*
- * There's such a huge space (and some time) waste for the Foo.class
- * syntax: the compiler sticks in a test of a static field in the
- * enclosing class for null and the code for creating the class value.
- * It has to do this since the reference has to get pushed off until
- * execution time (i.e. can't force an early load), but for the
- * 'standard' classes - especially those in java.lang, we can trust
- * that they won't cause problems by being loaded early.
- */
-
- public final static Class
- BooleanClass = Kit.classOrNull("java.lang.Boolean"),
- ByteClass = Kit.classOrNull("java.lang.Byte"),
- CharacterClass = Kit.classOrNull("java.lang.Character"),
- ClassClass = Kit.classOrNull("java.lang.Class"),
- DoubleClass = Kit.classOrNull("java.lang.Double"),
- FloatClass = Kit.classOrNull("java.lang.Float"),
- IntegerClass = Kit.classOrNull("java.lang.Integer"),
- LongClass = Kit.classOrNull("java.lang.Long"),
- NumberClass = Kit.classOrNull("java.lang.Number"),
- ObjectClass = Kit.classOrNull("java.lang.Object"),
- ShortClass = Kit.classOrNull("java.lang.Short"),
- StringClass = Kit.classOrNull("java.lang.String"),
- DateClass = Kit.classOrNull("java.util.Date");
-
- public final static Class
- ContextClass
- = Kit.classOrNull("org.mozilla.javascript.Context"),
- ContextFactoryClass
- = Kit.classOrNull("org.mozilla.javascript.ContextFactory"),
- FunctionClass
- = Kit.classOrNull("org.mozilla.javascript.Function"),
- ScriptableClass
- = Kit.classOrNull("org.mozilla.javascript.Scriptable"),
- ScriptableObjectClass
- = Kit.classOrNull("org.mozilla.javascript.ScriptableObject");
-
- private static final String[] lazilyNames = {
- "RegExp", "org.mozilla.javascript.regexp.NativeRegExp",
- "Packages", "org.mozilla.javascript.NativeJavaTopPackage",
- "java", "org.mozilla.javascript.NativeJavaTopPackage",
- "javax", "org.mozilla.javascript.NativeJavaTopPackage",
- "org", "org.mozilla.javascript.NativeJavaTopPackage",
- "com", "org.mozilla.javascript.NativeJavaTopPackage",
- "edu", "org.mozilla.javascript.NativeJavaTopPackage",
- "net", "org.mozilla.javascript.NativeJavaTopPackage",
- "getClass", "org.mozilla.javascript.NativeJavaTopPackage",
- "JavaAdapter", "org.mozilla.javascript.JavaAdapter",
- "JavaImporter", "org.mozilla.javascript.ImporterTopLevel",
- "Continuation", "org.mozilla.javascript.continuations.Continuation",
- // TODO Grotesque hack using literal string (xml) just to minimize
- // changes for now
- "XML", "(xml)",
- "XMLList", "(xml)",
- "Namespace", "(xml)",
- "QName", "(xml)",
- };
-
- private static final Object LIBRARY_SCOPE_KEY = new Object();
-
- public static boolean isRhinoRuntimeType(Class cl)
- {
- if (cl.isPrimitive()) {
- return (cl != Character.TYPE);
- } else {
- return (cl == StringClass || cl == BooleanClass
- || NumberClass.isAssignableFrom(cl)
- || ScriptableClass.isAssignableFrom(cl));
- }
- }
-
- public static ScriptableObject initStandardObjects(Context cx,
- ScriptableObject scope,
- boolean sealed)
- {
- if (scope == null) {
- scope = new NativeObject();
- }
- scope.associateValue(LIBRARY_SCOPE_KEY, scope);
- (new ClassCache()).associate(scope);
-
- BaseFunction.init(scope, sealed);
- NativeObject.init(scope, sealed);
-
- Scriptable objectProto = ScriptableObject.getObjectPrototype(scope);
-
- // Function.prototype.__proto__ should be Object.prototype
- Scriptable functionProto = ScriptableObject.getFunctionPrototype(scope);
- functionProto.setPrototype(objectProto);
-
- // Set the prototype of the object passed in if need be
- if (scope.getPrototype() == null)
- scope.setPrototype(objectProto);
-
- // must precede NativeGlobal since it's needed therein
- NativeError.init(scope, sealed);
- NativeGlobal.init(cx, scope, sealed);
-
- NativeArray.init(scope, sealed);
- if (cx.getOptimizationLevel() > 0) {
- // When optimizing, attempt to fulfill all requests for new Array(N)
- // with a higher threshold before switching to a sparse
- // representation
- NativeArray.setMaximumInitialCapacity(200000);
- }
- NativeString.init(scope, sealed);
- NativeBoolean.init(scope, sealed);
- NativeNumber.init(scope, sealed);
- NativeDate.init(scope, sealed);
- NativeMath.init(scope, sealed);
-
- NativeWith.init(scope, sealed);
- NativeCall.init(scope, sealed);
- NativeScript.init(scope, sealed);
-
- NativeIterator.init(scope, sealed); // Also initializes NativeGenerator
-
- boolean withXml = cx.hasFeature(Context.FEATURE_E4X) &&
- cx.getE4xImplementationFactory() != null;
-
- for (int i = 0; i != lazilyNames.length; i += 2) {
- String topProperty = lazilyNames[i];
- String className = lazilyNames[i + 1];
- if (!withXml && className.equals("(xml)")) {
- continue;
- } else if (withXml && className.equals("(xml)")) {
- className = cx.getE4xImplementationFactory().
- getImplementationClassName();
- }
- new LazilyLoadedCtor(scope, topProperty, className, sealed);
- }
-
- return scope;
- }
-
- public static ScriptableObject getLibraryScopeOrNull(Scriptable scope)
- {
- ScriptableObject libScope;
- libScope = (ScriptableObject)ScriptableObject.
- getTopScopeValue(scope, LIBRARY_SCOPE_KEY);
- return libScope;
- }
-
- // It is public so NativeRegExp can access it.
- public static boolean isJSLineTerminator(int c)
- {
- // Optimization for faster check for eol character:
- // they do not have 0xDFD0 bits set
- if ((c & 0xDFD0) != 0) {
- return false;
- }
- return c == '\n' || c == '\r' || c == 0x2028 || c == 0x2029;
- }
-
- public static Boolean wrapBoolean(boolean b)
- {
- return b ? Boolean.TRUE : Boolean.FALSE;
- }
-
- public static Integer wrapInt(int i)
- {
- return new Integer(i);
- }
-
- public static Number wrapNumber(double x)
- {
- if (x != x) {
- return ScriptRuntime.NaNobj;
- }
- return new Double(x);
- }
-
- /**
- * Convert the value to a boolean.
- *
- * See ECMA 9.2.
- */
- public static boolean toBoolean(Object val)
- {
- for (;;) {
- if (val instanceof Boolean)
- return ((Boolean) val).booleanValue();
- if (val == null || val == Undefined.instance)
- return false;
- if (val instanceof String)
- return ((String) val).length() != 0;
- if (val instanceof Number) {
- double d = ((Number) val).doubleValue();
- return (d == d && d != 0.0);
- }
- if (val instanceof Scriptable) {
- if (val instanceof ScriptableObject &&
- ((ScriptableObject) val).avoidObjectDetection())
- {
- return false;
- }
- if (Context.getContext().isVersionECMA1()) {
- // pure ECMA
- return true;
- }
- // ECMA extension
- val = ((Scriptable) val).getDefaultValue(BooleanClass);
- if (val instanceof Scriptable)
- throw errorWithClassName("msg.primitive.expected", val);
- continue;
- }
- warnAboutNonJSObject(val);
- return true;
- }
- }
-
- /**
- * Convert the value to a number.
- *
- * See ECMA 9.3.
- */
- public static double toNumber(Object val)
- {
- for (;;) {
- if (val instanceof Number)
- return ((Number) val).doubleValue();
- if (val == null)
- return +0.0;
- if (val == Undefined.instance)
- return NaN;
- if (val instanceof String)
- return toNumber((String) val);
- if (val instanceof Boolean)
- return ((Boolean) val).booleanValue() ? 1 : +0.0;
- if (val instanceof Scriptable) {
- val = ((Scriptable) val).getDefaultValue(NumberClass);
- if (val instanceof Scriptable)
- throw errorWithClassName("msg.primitive.expected", val);
- continue;
- }
- warnAboutNonJSObject(val);
- return NaN;
- }
- }
-
- public static double toNumber(Object[] args, int index) {
- return (index < args.length) ? toNumber(args[index]) : NaN;
- }
-
- // Can not use Double.NaN defined as 0.0d / 0.0 as under the Microsoft VM,
- // versions 2.01 and 3.0P1, that causes some uses (returns at least) of
- // Double.NaN to be converted to 1.0.
- // So we use ScriptRuntime.NaN instead of Double.NaN.
- public static final double
- NaN = Double.longBitsToDouble(0x7ff8000000000000L);
-
- // A similar problem exists for negative zero.
- public static final double
- negativeZero = Double.longBitsToDouble(0x8000000000000000L);
-
- public static final Double NaNobj = new Double(NaN);
-
- /*
- * Helper function for toNumber, parseInt, and TokenStream.getToken.
- */
- static double stringToNumber(String s, int start, int radix) {
- char digitMax = '9';
- char lowerCaseBound = 'a';
- char upperCaseBound = 'A';
- int len = s.length();
- if (radix < 10) {
- digitMax = (char) ('0' + radix - 1);
- }
- if (radix > 10) {
- lowerCaseBound = (char) ('a' + radix - 10);
- upperCaseBound = (char) ('A' + radix - 10);
- }
- int end;
- double sum = 0.0;
- for (end=start; end < len; end++) {
- char c = s.charAt(end);
- int newDigit;
- if ('0' <= c && c <= digitMax)
- newDigit = c - '0';
- else if ('a' <= c && c < lowerCaseBound)
- newDigit = c - 'a' + 10;
- else if ('A' <= c && c < upperCaseBound)
- newDigit = c - 'A' + 10;
- else
- break;
- sum = sum*radix + newDigit;
- }
- if (start == end) {
- return NaN;
- }
- if (sum >= 9007199254740992.0) {
- if (radix == 10) {
- /* If we're accumulating a decimal number and the number
- * is >= 2^53, then the result from the repeated multiply-add
- * above may be inaccurate. Call Java to get the correct
- * answer.
- */
- try {
- return Double.valueOf(s.substring(start, end)).doubleValue();
- } catch (NumberFormatException nfe) {
- return NaN;
- }
- } else if (radix == 2 || radix == 4 || radix == 8 ||
- radix == 16 || radix == 32)
- {
- /* The number may also be inaccurate for one of these bases.
- * This happens if the addition in value*radix + digit causes
- * a round-down to an even least significant mantissa bit
- * when the first dropped bit is a one. If any of the
- * following digits in the number (which haven't been added
- * in yet) are nonzero then the correct action would have
- * been to round up instead of down. An example of this
- * occurs when reading the number 0x1000000000000081, which
- * rounds to 0x1000000000000000 instead of 0x1000000000000100.
- */
- int bitShiftInChar = 1;
- int digit = 0;
-
- final int SKIP_LEADING_ZEROS = 0;
- final int FIRST_EXACT_53_BITS = 1;
- final int AFTER_BIT_53 = 2;
- final int ZEROS_AFTER_54 = 3;
- final int MIXED_AFTER_54 = 4;
-
- int state = SKIP_LEADING_ZEROS;
- int exactBitsLimit = 53;
- double factor = 0.0;
- boolean bit53 = false;
- // bit54 is the 54th bit (the first dropped from the mantissa)
- boolean bit54 = false;
-
- for (;;) {
- if (bitShiftInChar == 1) {
- if (start == end)
- break;
- digit = s.charAt(start++);
- if ('0' <= digit && digit <= '9')
- digit -= '0';
- else if ('a' <= digit && digit <= 'z')
- digit -= 'a' - 10;
- else
- digit -= 'A' - 10;
- bitShiftInChar = radix;
- }
- bitShiftInChar >>= 1;
- boolean bit = (digit & bitShiftInChar) != 0;
-
- switch (state) {
- case SKIP_LEADING_ZEROS:
- if (bit) {
- --exactBitsLimit;
- sum = 1.0;
- state = FIRST_EXACT_53_BITS;
- }
- break;
- case FIRST_EXACT_53_BITS:
- sum *= 2.0;
- if (bit)
- sum += 1.0;
- --exactBitsLimit;
- if (exactBitsLimit == 0) {
- bit53 = bit;
- state = AFTER_BIT_53;
- }
- break;
- case AFTER_BIT_53:
- bit54 = bit;
- factor = 2.0;
- state = ZEROS_AFTER_54;
- break;
- case ZEROS_AFTER_54:
- if (bit) {
- state = MIXED_AFTER_54;
- }
- // fallthrough
- case MIXED_AFTER_54:
- factor *= 2;
- break;
- }
- }
- switch (state) {
- case SKIP_LEADING_ZEROS:
- sum = 0.0;
- break;
- case FIRST_EXACT_53_BITS:
- case AFTER_BIT_53:
- // do nothing
- break;
- case ZEROS_AFTER_54:
- // x1.1 -> x1 + 1 (round up)
- // x0.1 -> x0 (round down)
- if (bit54 & bit53)
- sum += 1.0;
- sum *= factor;
- break;
- case MIXED_AFTER_54:
- // x.100...1.. -> x + 1 (round up)
- // x.0anything -> x (round down)
- if (bit54)
- sum += 1.0;
- sum *= factor;
- break;
- }
- }
- /* We don't worry about inaccurate numbers for any other base. */
- }
- return sum;
- }
-
-
- /**
- * ToNumber applied to the String type
- *
- * See ECMA 9.3.1
- */
- public static double toNumber(String s) {
- int len = s.length();
- int start = 0;
- char startChar;
- for (;;) {
- if (start == len) {
- // Empty or contains only whitespace
- return +0.0;
- }
- startChar = s.charAt(start);
- if (!Character.isWhitespace(startChar))
- break;
- start++;
- }
-
- if (startChar == '0') {
- if (start + 2 < len) {
- int c1 = s.charAt(start + 1);
- if (c1 == 'x' || c1 == 'X') {
- // A hexadecimal number
- return stringToNumber(s, start + 2, 16);
- }
- }
- } else if (startChar == '+' || startChar == '-') {
- if (start + 3 < len && s.charAt(start + 1) == '0') {
- int c2 = s.charAt(start + 2);
- if (c2 == 'x' || c2 == 'X') {
- // A hexadecimal number with sign
- double val = stringToNumber(s, start + 3, 16);
- return startChar == '-' ? -val : val;
- }
- }
- }
-
- int end = len - 1;
- char endChar;
- while (Character.isWhitespace(endChar = s.charAt(end)))
- end--;
- if (endChar == 'y') {
- // check for "Infinity"
- if (startChar == '+' || startChar == '-')
- start++;
- if (start + 7 == end && s.regionMatches(start, "Infinity", 0, 8))
- return startChar == '-'
- ? Double.NEGATIVE_INFINITY
- : Double.POSITIVE_INFINITY;
- return NaN;
- }
- // A non-hexadecimal, non-infinity number:
- // just try a normal floating point conversion
- String sub = s.substring(start, end+1);
- if (MSJVM_BUG_WORKAROUNDS) {
- // The MS JVM will accept non-conformant strings
- // rather than throwing a NumberFormatException
- // as it should.
- for (int i=sub.length()-1; i >= 0; i--) {
- char c = sub.charAt(i);
- if (('0' <= c && c <= '9') || c == '.' ||
- c == 'e' || c == 'E' ||
- c == '+' || c == '-')
- continue;
- return NaN;
- }
- }
- try {
- return Double.valueOf(sub).doubleValue();
- } catch (NumberFormatException ex) {
- return NaN;
- }
- }
-
- /**
- * Helper function for builtin objects that use the varargs form.
- * ECMA function formal arguments are undefined if not supplied;
- * this function pads the argument array out to the expected
- * length, if necessary.
- */
- public static Object[] padArguments(Object[] args, int count) {
- if (count < args.length)
- return args;
-
- int i;
- Object[] result = new Object[count];
- for (i = 0; i < args.length; i++) {
- result[i] = args[i];
- }
-
- for (; i < count; i++) {
- result[i] = Undefined.instance;
- }
-
- return result;
- }
-
- /* Work around Microsoft Java VM bugs. */
- private final static boolean MSJVM_BUG_WORKAROUNDS = true;
-
- public static String escapeString(String s)
- {
- return escapeString(s, '"');
- }
-
- /**
- * For escaping strings printed by object and array literals; not quite
- * the same as 'escape.'
- */
- public static String escapeString(String s, char escapeQuote)
- {
- if (!(escapeQuote == '"' || escapeQuote == '\'')) Kit.codeBug();
- StringBuffer sb = null;
-
- for(int i = 0, L = s.length(); i != L; ++i) {
- int c = s.charAt(i);
-
- if (' ' <= c && c <= '~' && c != escapeQuote && c != '\\') {
- // an ordinary print character (like C isprint()) and not "
- // or \ .
- if (sb != null) {
- sb.append((char)c);
- }
- continue;
- }
- if (sb == null) {
- sb = new StringBuffer(L + 3);
- sb.append(s);
- sb.setLength(i);
- }
-
- int escape = -1;
- switch (c) {
- case '\b': escape = 'b'; break;
- case '\f': escape = 'f'; break;
- case '\n': escape = 'n'; break;
- case '\r': escape = 'r'; break;
- case '\t': escape = 't'; break;
- case 0xb: escape = 'v'; break; // Java lacks \v.
- case ' ': escape = ' '; break;
- case '\\': escape = '\\'; break;
- }
- if (escape >= 0) {
- // an \escaped sort of character
- sb.append('\\');
- sb.append((char)escape);
- } else if (c == escapeQuote) {
- sb.append('\\');
- sb.append(escapeQuote);
- } else {
- int hexSize;
- if (c < 256) {
- // 2-digit hex
- sb.append("\\x");
- hexSize = 2;
- } else {
- // Unicode.
- sb.append("\\u");
- hexSize = 4;
- }
- // append hexadecimal form of c left-padded with 0
- for (int shift = (hexSize - 1) * 4; shift >= 0; shift -= 4) {
- int digit = 0xf & (c >> shift);
- int hc = (digit < 10) ? '0' + digit : 'a' - 10 + digit;
- sb.append((char)hc);
- }
- }
- }
- return (sb == null) ? s : sb.toString();
- }
-
- static boolean isValidIdentifierName(String s)
- {
- int L = s.length();
- if (L == 0)
- return false;
- if (!Character.isJavaIdentifierStart(s.charAt(0)))
- return false;
- for (int i = 1; i != L; ++i) {
- if (!Character.isJavaIdentifierPart(s.charAt(i)))
- return false;
- }
- return !TokenStream.isKeyword(s);
- }
-
- /**
- * Convert the value to a string.
- *
- * See ECMA 9.8.
- */
- public static String toString(Object val) {
- for (;;) {
- if (val == null) {
- return "null";
- }
- if (val == Undefined.instance) {
- return "undefined";
- }
- if (val instanceof String) {
- return (String)val;
- }
- if (val instanceof Number) {
- // XXX should we just teach NativeNumber.stringValue()
- // about Numbers?
- return numberToString(((Number)val).doubleValue(), 10);
- }
- if (val instanceof Scriptable) {
- val = ((Scriptable) val).getDefaultValue(StringClass);
- if (val instanceof Scriptable) {
- throw errorWithClassName("msg.primitive.expected", val);
- }
- continue;
- }
- return val.toString();
- }
- }
-
- static String defaultObjectToString(Scriptable obj)
- {
- return "[object " + obj.getClassName() + ']';
- }
-
- public static String toString(Object[] args, int index)
- {
- return (index < args.length) ? toString(args[index]) : "undefined";
- }
-
- /**
- * Optimized version of toString(Object) for numbers.
- */
- public static String toString(double val) {
- return numberToString(val, 10);
- }
-
- public static String numberToString(double d, int base) {
- if (d != d)
- return "NaN";
- if (d == Double.POSITIVE_INFINITY)
- return "Infinity";
- if (d == Double.NEGATIVE_INFINITY)
- return "-Infinity";
- if (d == 0.0)
- return "0";
-
- if ((base < 2) || (base > 36)) {
- throw Context.reportRuntimeError1(
- "msg.bad.radix", Integer.toString(base));
- }
-
- if (base != 10) {
- return DToA.JS_dtobasestr(base, d);
- } else {
- StringBuffer result = new StringBuffer();
- DToA.JS_dtostr(result, DToA.DTOSTR_STANDARD, 0, d);
- return result.toString();
- }
-
- }
-
- static String uneval(Context cx, Scriptable scope, Object value)
- {
- if (value == null) {
- return "null";
- }
- if (value == Undefined.instance) {
- return "undefined";
- }
- if (value instanceof String) {
- String escaped = escapeString((String)value);
- StringBuffer sb = new StringBuffer(escaped.length() + 2);
- sb.append('\"');
- sb.append(escaped);
- sb.append('\"');
- return sb.toString();
- }
- if (value instanceof Number) {
- double d = ((Number)value).doubleValue();
- if (d == 0 && 1 / d < 0) {
- return "-0";
- }
- return toString(d);
- }
- if (value instanceof Boolean) {
- return toString(value);
- }
- if (value instanceof Scriptable) {
- Scriptable obj = (Scriptable)value;
- // Wrapped Java objects won't have "toSource" and will report
- // errors for get()s of nonexistent name, so use has() first
- if (ScriptableObject.hasProperty(obj, "toSource")) {
- Object v = ScriptableObject.getProperty(obj, "toSource");
- if (v instanceof Function) {
- Function f = (Function)v;
- return toString(f.call(cx, scope, obj, emptyArgs));
- }
- }
- return toString(value);
- }
- warnAboutNonJSObject(value);
- return value.toString();
- }
-
- static String defaultObjectToSource(Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- boolean toplevel, iterating;
- if (cx.iterating == null) {
- toplevel = true;
- iterating = false;
- cx.iterating = new ObjToIntMap(31);
- } else {
- toplevel = false;
- iterating = cx.iterating.has(thisObj);
- }
-
- StringBuffer result = new StringBuffer(128);
- if (toplevel) {
- result.append("(");
- }
- result.append('{');
-
- // Make sure cx.iterating is set to null when done
- // so we don't leak memory
- try {
- if (!iterating) {
- cx.iterating.intern(thisObj); // stop recursion.
- Object[] ids = thisObj.getIds();
- for (int i=0; i < ids.length; i++) {
- Object id = ids[i];
- Object value;
- if (id instanceof Integer) {
- int intId = ((Integer)id).intValue();
- value = thisObj.get(intId, thisObj);
- if (value == Scriptable.NOT_FOUND)
- continue; // a property has been removed
- if (i > 0)
- result.append(", ");
- result.append(intId);
- } else {
- String strId = (String)id;
- value = thisObj.get(strId, thisObj);
- if (value == Scriptable.NOT_FOUND)
- continue; // a property has been removed
- if (i > 0)
- result.append(", ");
- if (ScriptRuntime.isValidIdentifierName(strId)) {
- result.append(strId);
- } else {
- result.append('\'');
- result.append(
- ScriptRuntime.escapeString(strId, '\''));
- result.append('\'');
- }
- }
- result.append(':');
- result.append(ScriptRuntime.uneval(cx, scope, value));
- }
- }
- } finally {
- if (toplevel) {
- cx.iterating = null;
- }
- }
-
- result.append('}');
- if (toplevel) {
- result.append(')');
- }
- return result.toString();
- }
-
- public static Scriptable toObject(Scriptable scope, Object val)
- {
- if (val instanceof Scriptable) {
- return (Scriptable)val;
- }
- return toObject(Context.getContext(), scope, val);
- }
-
- public static Scriptable toObjectOrNull(Context cx, Object obj)
- {
- if (obj instanceof Scriptable) {
- return (Scriptable)obj;
- } else if (obj != null && obj != Undefined.instance) {
- return toObject(cx, getTopCallScope(cx), obj);
- }
- return null;
- }
-
- /**
- * @deprecated Use {@link #toObject(Scriptable, Object)} instead.
- */
- public static Scriptable toObject(Scriptable scope, Object val,
- Class staticClass)
- {
- if (val instanceof Scriptable) {
- return (Scriptable)val;
- }
- return toObject(Context.getContext(), scope, val);
- }
-
- /**
- * Convert the value to an object.
- *
- * See ECMA 9.9.
- */
- public static Scriptable toObject(Context cx, Scriptable scope, Object val)
- {
- if (val instanceof Scriptable) {
- return (Scriptable) val;
- }
- if (val == null) {
- throw typeError0("msg.null.to.object");
- }
- if (val == Undefined.instance) {
- throw typeError0("msg.undef.to.object");
- }
- String className = val instanceof String ? "String" :
- val instanceof Number ? "Number" :
- val instanceof Boolean ? "Boolean" :
- null;
- if (className != null) {
- Object[] args = { val };
- scope = ScriptableObject.getTopLevelScope(scope);
- return newObject(cx, scope, className, args);
- }
-
- // Extension: Wrap as a LiveConnect object.
- Object wrapped = cx.getWrapFactory().wrap(cx, scope, val, null);
- if (wrapped instanceof Scriptable)
- return (Scriptable) wrapped;
- throw errorWithClassName("msg.invalid.type", val);
- }
-
- /**
- * @deprecated Use {@link #toObject(Context, Scriptable, Object)} instead.
- */
- public static Scriptable toObject(Context cx, Scriptable scope, Object val,
- Class staticClass)
- {
- return toObject(cx, scope, val);
- }
-
- /**
- * @deprecated The method is only present for compatibility.
- */
- public static Object call(Context cx, Object fun, Object thisArg,
- Object[] args, Scriptable scope)
- {
- if (!(fun instanceof Function)) {
- throw notFunctionError(toString(fun));
- }
- Function function = (Function)fun;
- Scriptable thisObj = toObjectOrNull(cx, thisArg);
- if (thisObj == null) {
- throw undefCallError(thisObj, "function");
- }
- return function.call(cx, scope, thisObj, args);
- }
-
- public static Scriptable newObject(Context cx, Scriptable scope,
- String constructorName, Object[] args)
- {
- scope = ScriptableObject.getVeryTopLevelScope(scope); // APPJET
- Function ctor = getExistingCtor(cx, scope, constructorName);
- if (args == null) { args = ScriptRuntime.emptyArgs; }
- return ctor.construct(cx, scope, args);
- }
-
- /**
- *
- * See ECMA 9.4.
- */
- public static double toInteger(Object val) {
- return toInteger(toNumber(val));
- }
-
- // convenience method
- public static double toInteger(double d) {
- // if it's NaN
- if (d != d)
- return +0.0;
-
- if (d == 0.0 ||
- d == Double.POSITIVE_INFINITY ||
- d == Double.NEGATIVE_INFINITY)
- return d;
-
- if (d > 0.0)
- return Math.floor(d);
- else
- return Math.ceil(d);
- }
-
- public static double toInteger(Object[] args, int index) {
- return (index < args.length) ? toInteger(args[index]) : +0.0;
- }
-
- /**
- *
- * See ECMA 9.5.
- */
- public static int toInt32(Object val)
- {
- // short circuit for common integer values
- if (val instanceof Integer)
- return ((Integer)val).intValue();
-
- return toInt32(toNumber(val));
- }
-
- public static int toInt32(Object[] args, int index) {
- return (index < args.length) ? toInt32(args[index]) : 0;
- }
-
- public static int toInt32(double d) {
- int id = (int)d;
- if (id == d) {
- // This covers -0.0 as well
- return id;
- }
-
- if (d != d
- || d == Double.POSITIVE_INFINITY
- || d == Double.NEGATIVE_INFINITY)
- {
- return 0;
- }
-
- d = (d >= 0) ? Math.floor(d) : Math.ceil(d);
-
- double two32 = 4294967296.0;
- d = Math.IEEEremainder(d, two32);
- // (double)(long)d == d should hold here
-
- long l = (long)d;
- // returning (int)d does not work as d can be outside int range
- // but the result must always be 32 lower bits of l
- return (int)l;
- }
-
- /**
- * See ECMA 9.6.
- * @return long value representing 32 bits unsigned integer
- */
- public static long toUint32(double d) {
- long l = (long)d;
- if (l == d) {
- // This covers -0.0 as well
- return l & 0xffffffffL;
- }
-
- if (d != d
- || d == Double.POSITIVE_INFINITY
- || d == Double.NEGATIVE_INFINITY)
- {
- return 0;
- }
-
- d = (d >= 0) ? Math.floor(d) : Math.ceil(d);
-
- // 0x100000000 gives me a numeric overflow...
- double two32 = 4294967296.0;
- l = (long)Math.IEEEremainder(d, two32);
-
- return l & 0xffffffffL;
- }
-
- public static long toUint32(Object val) {
- return toUint32(toNumber(val));
- }
-
- /**
- *
- * See ECMA 9.7.
- */
- public static char toUint16(Object val) {
- double d = toNumber(val);
-
- int i = (int)d;
- if (i == d) {
- return (char)i;
- }
-
- if (d != d
- || d == Double.POSITIVE_INFINITY
- || d == Double.NEGATIVE_INFINITY)
- {
- return 0;
- }
-
- d = (d >= 0) ? Math.floor(d) : Math.ceil(d);
-
- int int16 = 0x10000;
- i = (int)Math.IEEEremainder(d, int16);
-
- return (char)i;
- }
-
- // XXX: this is until setDefaultNamespace will learn how to store NS
- // properly and separates namespace form Scriptable.get etc.
- private static final String DEFAULT_NS_TAG = "__default_namespace__";
-
- public static Object setDefaultNamespace(Object namespace, Context cx)
- {
- Scriptable scope = cx.currentActivationCall;
- if (scope == null) {
- scope = getTopCallScope(cx);
- }
-
- XMLLib xmlLib = currentXMLLib(cx);
- Object ns = xmlLib.toDefaultXmlNamespace(cx, namespace);
-
- // XXX : this should be in separated namesapce from Scriptable.get/put
- if (!scope.has(DEFAULT_NS_TAG, scope)) {
- // XXX: this is racy of cause
- ScriptableObject.defineProperty(scope, DEFAULT_NS_TAG, ns,
- ScriptableObject.PERMANENT
- | ScriptableObject.DONTENUM);
- } else {
- scope.put(DEFAULT_NS_TAG, scope, ns);
- }
-
- return Undefined.instance;
- }
-
- public static Object searchDefaultNamespace(Context cx)
- {
- Scriptable scope = cx.currentActivationCall;
- if (scope == null) {
- scope = getTopCallScope(cx);
- }
- Object nsObject;
- for (;;) {
- Scriptable parent = scope.getParentScope();
- if (parent == null) {
- nsObject = ScriptableObject.getProperty(scope, DEFAULT_NS_TAG);
- if (nsObject == Scriptable.NOT_FOUND) {
- return null;
- }
- break;
- }
- nsObject = scope.get(DEFAULT_NS_TAG, scope);
- if (nsObject != Scriptable.NOT_FOUND) {
- break;
- }
- scope = parent;
- }
- return nsObject;
- }
-
- public static Object getTopLevelProp(Scriptable scope, String id) {
- scope = ScriptableObject.getTopLevelScope(scope);
- return ScriptableObject.getProperty(scope, id);
- }
-
- static Function getExistingCtor(Context cx, Scriptable scope,
- String constructorName)
- {
- Object ctorVal = ScriptableObject.getProperty(scope, constructorName);
- if (ctorVal instanceof Function) {
- return (Function)ctorVal;
- }
- if (ctorVal == Scriptable.NOT_FOUND) {
- throw Context.reportRuntimeError1(
- "msg.ctor.not.found", constructorName);
- } else {
- throw Context.reportRuntimeError1(
- "msg.not.ctor", constructorName);
- }
- }
-
- /**
- * Return -1L if str is not an index or the index value as lower 32
- * bits of the result.
- */
- private static long indexFromString(String str)
- {
- // The length of the decimal string representation of
- // Integer.MAX_VALUE, 2147483647
- final int MAX_VALUE_LENGTH = 10;
-
- int len = str.length();
- if (len > 0) {
- int i = 0;
- boolean negate = false;
- int c = str.charAt(0);
- if (c == '-') {
- if (len > 1) {
- c = str.charAt(1);
- i = 1;
- negate = true;
- }
- }
- c -= '0';
- if (0 <= c && c <= 9
- && len <= (negate ? MAX_VALUE_LENGTH + 1 : MAX_VALUE_LENGTH))
- {
- // Use negative numbers to accumulate index to handle
- // Integer.MIN_VALUE that is greater by 1 in absolute value
- // then Integer.MAX_VALUE
- int index = -c;
- int oldIndex = 0;
- i++;
- if (index != 0) {
- // Note that 00, 01, 000 etc. are not indexes
- while (i != len && 0 <= (c = str.charAt(i) - '0') && c <= 9)
- {
- oldIndex = index;
- index = 10 * index - c;
- i++;
- }
- }
- // Make sure all characters were consumed and that it couldn't
- // have overflowed.
- if (i == len &&
- (oldIndex > (Integer.MIN_VALUE / 10) ||
- (oldIndex == (Integer.MIN_VALUE / 10) &&
- c <= (negate ? -(Integer.MIN_VALUE % 10)
- : (Integer.MAX_VALUE % 10)))))
- {
- return 0xFFFFFFFFL & (negate ? index : -index);
- }
- }
- }
- return -1L;
- }
-
- /**
- * If str is a decimal presentation of Uint32 value, return it as long.
- * Othewise return -1L;
- */
- public static long testUint32String(String str)
- {
- // The length of the decimal string representation of
- // UINT32_MAX_VALUE, 4294967296
- final int MAX_VALUE_LENGTH = 10;
-
- int len = str.length();
- if (1 <= len && len <= MAX_VALUE_LENGTH) {
- int c = str.charAt(0);
- c -= '0';
- if (c == 0) {
- // Note that 00,01 etc. are not valid Uint32 presentations
- return (len == 1) ? 0L : -1L;
- }
- if (1 <= c && c <= 9) {
- long v = c;
- for (int i = 1; i != len; ++i) {
- c = str.charAt(i) - '0';
- if (!(0 <= c && c <= 9)) {
- return -1;
- }
- v = 10 * v + c;
- }
- // Check for overflow
- if ((v >>> 32) == 0) {
- return v;
- }
- }
- }
- return -1;
- }
-
- /**
- * If s represents index, then return index value wrapped as Integer
- * and othewise return s.
- */
- static Object getIndexObject(String s)
- {
- long indexTest = indexFromString(s);
- if (indexTest >= 0) {
- return new Integer((int)indexTest);
- }
- return s;
- }
-
- /**
- * If d is exact int value, return its value wrapped as Integer
- * and othewise return d converted to String.
- */
- static Object getIndexObject(double d)
- {
- int i = (int)d;
- if (i == d) {
- return new Integer(i);
- }
- return toString(d);
- }
-
- /**
- * If toString(id) is a decimal presentation of int32 value, then id
- * is index. In this case return null and make the index available
- * as ScriptRuntime.lastIndexResult(cx). Otherwise return toString(id).
- */
- static String toStringIdOrIndex(Context cx, Object id)
- {
- if (id instanceof Number) {
- double d = ((Number)id).doubleValue();
- int index = (int)d;
- if (index == d) {
- storeIndexResult(cx, index);
- return null;
- }
- return toString(id);
- } else {
- String s;
- if (id instanceof String) {
- s = (String)id;
- } else {
- s = toString(id);
- }
- long indexTest = indexFromString(s);
- if (indexTest >= 0) {
- storeIndexResult(cx, (int)indexTest);
- return null;
- }
- return s;
- }
- }
-
- /**
- * Call obj.[[Get]](id)
- */
- public static Object getObjectElem(Object obj, Object elem, Context cx)
- {
- Scriptable sobj = toObjectOrNull(cx, obj);
- if (sobj == null) {
- throw undefReadError(obj, elem);
- }
- return getObjectElem(sobj, elem, cx);
- }
-
- public static Object getObjectElem(Scriptable obj, Object elem,
- Context cx)
- {
- if (obj instanceof XMLObject) {
- XMLObject xmlObject = (XMLObject)obj;
- return xmlObject.ecmaGet(cx, elem);
- }
-
- Object result;
-
- String s = toStringIdOrIndex(cx, elem);
- if (s == null) {
- int index = lastIndexResult(cx);
- result = ScriptableObject.getProperty(obj, index);
- } else {
- result = ScriptableObject.getProperty(obj, s);
- }
-
- if (result == Scriptable.NOT_FOUND) {
- result = Undefined.instance;
- }
-
- return result;
- }
-
- /**
- * Version of getObjectElem when elem is a valid JS identifier name.
- */
- public static Object getObjectProp(Object obj, String property,
- Context cx)
- {
- Scriptable sobj = toObjectOrNull(cx, obj);
- if (sobj == null) {
- throw undefReadError(obj, property);
- }
- return getObjectProp(sobj, property, cx);
- }
-
- public static Object getObjectProp(Scriptable obj, String property,
- Context cx)
- {
- if (obj instanceof XMLObject) {
- // TODO: Change XMLObject to just use Scriptable interface
- // to avoid paying cost of instanceof check on *every property
- // lookup* !
- XMLObject xmlObject = (XMLObject)obj;
- return xmlObject.ecmaGet(cx, property);
- }
-
- Object result = ScriptableObject.getProperty(obj, property);
- if (result == Scriptable.NOT_FOUND) {
- if (cx.hasFeature(Context.FEATURE_STRICT_MODE)) {
- Context.reportWarning(ScriptRuntime.getMessage1(
- "msg.ref.undefined.prop", property));
- }
- result = Undefined.instance;
- }
-
- return result;
- }
-
- public static Object getObjectPropNoWarn(Object obj, String property,
- Context cx)
- {
- Scriptable sobj = toObjectOrNull(cx, obj);
- if (sobj == null) {
- throw undefReadError(obj, property);
- }
- if (obj instanceof XMLObject) {
- // TODO: fix as mentioned in note in method above
- getObjectProp(sobj, property, cx);
- }
- Object result = ScriptableObject.getProperty(sobj, property);
- if (result == Scriptable.NOT_FOUND) {
- return Undefined.instance;
- }
- return result;
- }
-
- /*
- * A cheaper and less general version of the above for well-known argument
- * types.
- */
- public static Object getObjectIndex(Object obj, double dblIndex,
- Context cx)
- {
- Scriptable sobj = toObjectOrNull(cx, obj);
- if (sobj == null) {
- throw undefReadError(obj, toString(dblIndex));
- }
-
- int index = (int)dblIndex;
- if (index == dblIndex) {
- return getObjectIndex(sobj, index, cx);
- } else {
- String s = toString(dblIndex);
- return getObjectProp(sobj, s, cx);
- }
- }
-
- public static Object getObjectIndex(Scriptable obj, int index,
- Context cx)
- {
- if (obj instanceof XMLObject) {
- XMLObject xmlObject = (XMLObject)obj;
- return xmlObject.ecmaGet(cx, new Integer(index));
- }
-
- Object result = ScriptableObject.getProperty(obj, index);
- if (result == Scriptable.NOT_FOUND) {
- result = Undefined.instance;
- }
-
- return result;
- }
-
- /*
- * Call obj.[[Put]](id, value)
- */
- public static Object setObjectElem(Object obj, Object elem, Object value,
- Context cx)
- {
- Scriptable sobj = toObjectOrNull(cx, obj);
- if (sobj == null) {
- throw undefWriteError(obj, elem, value);
- }
- return setObjectElem(sobj, elem, value, cx);
- }
-
- public static Object setObjectElem(Scriptable obj, Object elem,
- Object value, Context cx)
- {
- if (obj instanceof XMLObject) {
- XMLObject xmlObject = (XMLObject)obj;
- xmlObject.ecmaPut(cx, elem, value);
- return value;
- }
-
- String s = toStringIdOrIndex(cx, elem);
- if (s == null) {
- int index = lastIndexResult(cx);
- ScriptableObject.putProperty(obj, index, value);
- } else {
- ScriptableObject.putProperty(obj, s, value);
- }
-
- return value;
- }
-
- /**
- * Version of setObjectElem when elem is a valid JS identifier name.
- */
- public static Object setObjectProp(Object obj, String property,
- Object value, Context cx)
- {
- Scriptable sobj = toObjectOrNull(cx, obj);
- if (sobj == null) {
- throw undefWriteError(obj, property, value);
- }
- return setObjectProp(sobj, property, value, cx);
- }
-
- public static Object setObjectProp(Scriptable obj, String property,
- Object value, Context cx)
- {
- if (obj instanceof XMLObject) {
- XMLObject xmlObject = (XMLObject)obj;
- xmlObject.ecmaPut(cx, property, value);
- } else {
- ScriptableObject.putProperty(obj, property, value);
- }
- return value;
- }
-
- /*
- * A cheaper and less general version of the above for well-known argument
- * types.
- */
- public static Object setObjectIndex(Object obj, double dblIndex,
- Object value, Context cx)
- {
- Scriptable sobj = toObjectOrNull(cx, obj);
- if (sobj == null) {
- throw undefWriteError(obj, String.valueOf(dblIndex), value);
- }
-
- int index = (int)dblIndex;
- if (index == dblIndex) {
- return setObjectIndex(sobj, index, value, cx);
- } else {
- String s = toString(dblIndex);
- return setObjectProp(sobj, s, value, cx);
- }
- }
-
- public static Object setObjectIndex(Scriptable obj, int index, Object value,
- Context cx)
- {
- if (obj instanceof XMLObject) {
- XMLObject xmlObject = (XMLObject)obj;
- xmlObject.ecmaPut(cx, new Integer(index), value);
- } else {
- ScriptableObject.putProperty(obj, index, value);
- }
- return value;
- }
-
- public static boolean deleteObjectElem(Scriptable target, Object elem,
- Context cx)
- {
- boolean result;
- if (target instanceof XMLObject) {
- XMLObject xmlObject = (XMLObject)target;
- result = xmlObject.ecmaDelete(cx, elem);
- } else {
- String s = toStringIdOrIndex(cx, elem);
- if (s == null) {
- int index = lastIndexResult(cx);
- result = ScriptableObject.deleteProperty(target, index);
- } else {
- result = ScriptableObject.deleteProperty(target, s);
- }
- }
- return result;
- }
-
- public static boolean hasObjectElem(Scriptable target, Object elem,
- Context cx)
- {
- boolean result;
-
- if (target instanceof XMLObject) {
- XMLObject xmlObject = (XMLObject)target;
- result = xmlObject.ecmaHas(cx, elem);
- } else {
- String s = toStringIdOrIndex(cx, elem);
- if (s == null) {
- int index = lastIndexResult(cx);
- result = ScriptableObject.hasProperty(target, index);
- } else {
- result = ScriptableObject.hasProperty(target, s);
- }
- }
-
- return result;
- }
-
- public static Object refGet(Ref ref, Context cx)
- {
- return ref.get(cx);
- }
-
- public static Object refSet(Ref ref, Object value, Context cx)
- {
- return ref.set(cx, value);
- }
-
- public static Object refDel(Ref ref, Context cx)
- {
- return wrapBoolean(ref.delete(cx));
- }
-
- static boolean isSpecialProperty(String s)
- {
- return s.equals("__proto__") || s.equals("__parent__");
- }
-
- public static Ref specialRef(Object obj, String specialProperty,
- Context cx)
- {
- return SpecialRef.createSpecial(cx, obj, specialProperty);
- }
-
- /**
- * The delete operator
- *
- * See ECMA 11.4.1
- *
- * In ECMA 0.19, the description of the delete operator (11.4.1)
- * assumes that the [[Delete]] method returns a value. However,
- * the definition of the [[Delete]] operator (8.6.2.5) does not
- * define a return value. Here we assume that the [[Delete]]
- * method doesn't return a value.
- */
- public static Object delete(Object obj, Object id, Context cx)
- {
- Scriptable sobj = toObjectOrNull(cx, obj);
- if (sobj == null) {
- String idStr = (id == null) ? "null" : id.toString();
- throw typeError2("msg.undef.prop.delete", toString(obj), idStr);
- }
- boolean result = deleteObjectElem(sobj, id, cx);
- return wrapBoolean(result);
- }
-
- /**
- * Looks up a name in the scope chain and returns its value.
- */
- public static Object name(Context cx, Scriptable scope, String name)
- {
- Scriptable parent = scope.getParentScope();
- if (parent == null) {
- Object result = topScopeName(cx, scope, name);
- if (result == Scriptable.NOT_FOUND) {
- throw notFoundError(scope, name);
- }
- return result;
- }
-
- return nameOrFunction(cx, scope, parent, name, false);
- }
-
- private static Object nameOrFunction(Context cx, Scriptable scope,
- Scriptable parentScope, String name,
- boolean asFunctionCall)
- {
- Object result;
- Scriptable thisObj = scope; // It is used only if asFunctionCall==true.
-
- XMLObject firstXMLObject = null;
- for (;;) {
- if (scope instanceof NativeWith) {
- Scriptable withObj = scope.getPrototype();
- if (withObj instanceof XMLObject) {
- XMLObject xmlObj = (XMLObject)withObj;
- if (xmlObj.ecmaHas(cx, name)) {
- // function this should be the target object of with
- thisObj = xmlObj;
- result = xmlObj.ecmaGet(cx, name);
- break;
- }
- if (firstXMLObject == null) {
- firstXMLObject = xmlObj;
- }
- } else {
- result = ScriptableObject.getProperty(withObj, name);
- if (result != Scriptable.NOT_FOUND) {
- // function this should be the target object of with
- thisObj = withObj;
- break;
- }
- }
- } else if (scope instanceof NativeCall) {
- // NativeCall does not prototype chain and Scriptable.get
- // can be called directly.
- result = scope.get(name, scope);
- if (result != Scriptable.NOT_FOUND) {
- if (asFunctionCall) {
- // ECMA 262 requires that this for nested funtions
- // should be top scope
- thisObj = ScriptableObject.
- getTopLevelScope(parentScope);
- }
- break;
- }
- } else {
- // Can happen if Rhino embedding decided that nested
- // scopes are useful for what ever reasons.
- result = ScriptableObject.getProperty(scope, name);
- if (result != Scriptable.NOT_FOUND) {
- thisObj = scope;
- break;
- }
- }
- scope = parentScope;
- parentScope = parentScope.getParentScope();
- if (parentScope == null) {
- result = topScopeName(cx, scope, name);
- if (result == Scriptable.NOT_FOUND) {
- if (firstXMLObject == null || asFunctionCall) {
- throw notFoundError(scope, name);
- }
- // The name was not found, but we did find an XML
- // object in the scope chain and we are looking for name,
- // not function. The result should be an empty XMLList
- // in name context.
- result = firstXMLObject.ecmaGet(cx, name);
- }
- // For top scope thisObj for functions is always scope itself.
- thisObj = scope;
- break;
- }
- }
-
- if (asFunctionCall) {
- if (!(result instanceof Callable)) {
- throw notFunctionError(result, name);
- }
- storeScriptable(cx, thisObj);
- }
-
- return result;
- }
-
- private static Object topScopeName(Context cx, Scriptable scope,
- String name)
- {
- if (cx.useDynamicScope) {
- scope = checkDynamicScope(cx.topCallScope, scope);
- }
- return ScriptableObject.getProperty(scope, name);
- }
-
-
- /**
- * Returns the object in the scope chain that has a given property.
- *
- * The order of evaluation of an assignment expression involves
- * evaluating the lhs to a reference, evaluating the rhs, and then
- * modifying the reference with the rhs value. This method is used
- * to 'bind' the given name to an object containing that property
- * so that the side effects of evaluating the rhs do not affect
- * which property is modified.
- * Typically used in conjunction with setName.
- *
- * See ECMA 10.1.4
- */
- public static Scriptable bind(Context cx, Scriptable scope, String id)
- {
- Scriptable firstXMLObject = null;
- Scriptable parent = scope.getParentScope();
- childScopesChecks: if (parent != null) {
- // Check for possibly nested "with" scopes first
- while (scope instanceof NativeWith) {
- Scriptable withObj = scope.getPrototype();
- if (withObj instanceof XMLObject) {
- XMLObject xmlObject = (XMLObject)withObj;
- if (xmlObject.ecmaHas(cx, id)) {
- return xmlObject;
- }
- if (firstXMLObject == null) {
- firstXMLObject = xmlObject;
- }
- } else {
- if (ScriptableObject.hasProperty(withObj, id)) {
- return withObj;
- }
- }
- scope = parent;
- parent = parent.getParentScope();
- if (parent == null) {
- break childScopesChecks;
- }
- }
- for (;;) {
- if (ScriptableObject.hasProperty(scope, id)) {
- return scope;
- }
- scope = parent;
- parent = parent.getParentScope();
- if (parent == null) {
- break childScopesChecks;
- }
- }
- }
- // scope here is top scope
- if (cx.useDynamicScope) {
- scope = checkDynamicScope(cx.topCallScope, scope);
- }
- if (ScriptableObject.hasProperty(scope, id)) {
- return scope;
- }
- // Nothing was found, but since XML objects always bind
- // return one if found
- return firstXMLObject;
- }
-
- public static Object setName(Scriptable bound, Object value,
- Context cx, Scriptable scope, String id)
- {
- if (bound != null) {
- if (bound instanceof XMLObject) {
- XMLObject xmlObject = (XMLObject)bound;
- xmlObject.ecmaPut(cx, id, value);
- } else {
- ScriptableObject.putProperty(bound, id, value);
- }
- } else {
- // "newname = 7;", where 'newname' has not yet
- // been defined, creates a new property in the
- // top scope unless strict mode is specified.
- if (cx.hasFeature(Context.FEATURE_STRICT_MODE) ||
- cx.hasFeature(Context.FEATURE_STRICT_VARS))
- {
- Context.reportWarning(
- ScriptRuntime.getMessage1("msg.assn.create.strict", id));
- }
- // Find the top scope by walking up the scope chain.
- bound = ScriptableObject.getTopLevelScope(scope);
- if (cx.useDynamicScope) {
- bound = checkDynamicScope(cx.topCallScope, bound);
- }
- bound.put(id, bound, value);
- }
- return value;
- }
-
- public static Object setConst(Scriptable bound, Object value,
- Context cx, String id)
- {
- if (bound instanceof XMLObject) {
- XMLObject xmlObject = (XMLObject)bound;
- xmlObject.ecmaPut(cx, id, value);
- } else {
- ScriptableObject.putConstProperty(bound, id, value);
- }
- return value;
- }
-
- /**
- * This is the enumeration needed by the for..in statement.
- *
- * See ECMA 12.6.3.
- *
- * IdEnumeration maintains a ObjToIntMap to make sure a given
- * id is enumerated only once across multiple objects in a
- * prototype chain.
- *
- * XXX - ECMA delete doesn't hide properties in the prototype,
- * but js/ref does. This means that the js/ref for..in can
- * avoid maintaining a hash table and instead perform lookups
- * to see if a given property has already been enumerated.
- *
- */
- private static class IdEnumeration implements Serializable
- {
- private static final long serialVersionUID = 1L;
- Scriptable obj;
- Object[] ids;
- int index;
- ObjToIntMap used;
- Object currentId;
- int enumType; /* one of ENUM_INIT_KEYS, ENUM_INIT_VALUES,
- ENUM_INIT_ARRAY */
-
- // if true, integer ids will be returned as numbers rather than strings
- boolean enumNumbers;
-
- Scriptable iterator;
- }
-
- public static Scriptable toIterator(Context cx, Scriptable scope,
- Scriptable obj, boolean keyOnly)
- {
- /*APPJET 1.6*//*
- if (ScriptableObject.hasProperty(obj,
- NativeIterator.ITERATOR_PROPERTY_NAME))
- {
- Object v = ScriptableObject.getProperty(obj,
- NativeIterator.ITERATOR_PROPERTY_NAME);
- if (!(v instanceof Callable)) {
- throw typeError0("msg.invalid.iterator");
- }
- Callable f = (Callable) v;
- Object[] args = new Object[] { keyOnly ? Boolean.TRUE
- : Boolean.FALSE };
- v = f.call(cx, scope, obj, args);
- if (!(v instanceof Scriptable)) {
- throw typeError0("msg.iterator.primitive");
- }
- return (Scriptable) v;
- }*/
- return null;
- }
-
- // for backwards compatibility with generated class files
- public static Object enumInit(Object value, Context cx, boolean enumValues)
- {
- return enumInit(value, cx, enumValues ? ENUMERATE_VALUES
- : ENUMERATE_KEYS);
- }
-
- public static final int ENUMERATE_KEYS = 0;
- public static final int ENUMERATE_VALUES = 1;
- public static final int ENUMERATE_ARRAY = 2;
- public static final int ENUMERATE_KEYS_NO_ITERATOR = 3;
- public static final int ENUMERATE_VALUES_NO_ITERATOR = 4;
- public static final int ENUMERATE_ARRAY_NO_ITERATOR = 5;
-
- public static Object enumInit(Object value, Context cx, int enumType)
- {
- IdEnumeration x = new IdEnumeration();
- x.obj = toObjectOrNull(cx, value);
- if (x.obj == null) {
- // null or undefined do not cause errors but rather lead to empty
- // "for in" loop
- return x;
- }
- x.enumType = enumType;
- x.iterator = null;
- if (enumType != ENUMERATE_KEYS_NO_ITERATOR &&
- enumType != ENUMERATE_VALUES_NO_ITERATOR &&
- enumType != ENUMERATE_ARRAY_NO_ITERATOR)
- {
- x.iterator = toIterator(cx, x.obj.getParentScope(), x.obj, true);
- }
- if (x.iterator == null) {
- // enumInit should read all initial ids before returning
- // or "for (a.i in a)" would wrongly enumerate i in a as well
- enumChangeObject(x);
- }
-
- return x;
- }
-
- public static void setEnumNumbers(Object enumObj, boolean enumNumbers) {
- ((IdEnumeration)enumObj).enumNumbers = enumNumbers;
- }
-
- public static Boolean enumNext(Object enumObj)
- {
- IdEnumeration x = (IdEnumeration)enumObj;
- if (x.iterator != null) {
- Object v = ScriptableObject.getProperty(x.iterator, "next");
- if (!(v instanceof Callable))
- return Boolean.FALSE;
- Callable f = (Callable) v;
- Context cx = Context.enter();
- try {
- x.currentId = f.call(cx, x.iterator.getParentScope(),
- x.iterator, emptyArgs);
- return Boolean.TRUE;
- } catch (JavaScriptException e) {
- if (e.getValue() instanceof NativeIterator.StopIteration) {
- return Boolean.FALSE;
- }
- throw e;
- } finally {
- Context.exit();
- }
- }
- for (;;) {
- if (x.obj == null) {
- return Boolean.FALSE;
- }
- if (x.index == x.ids.length) {
- x.obj = x.obj.getPrototype();
- enumChangeObject(x);
- continue;
- }
- Object id = x.ids[x.index++];
- if (x.used != null && x.used.has(id)) {
- continue;
- }
- if (id instanceof String) {
- String strId = (String)id;
- if (!x.obj.has(strId, x.obj))
- continue; // must have been deleted
- x.currentId = strId;
- } else {
- int intId = ((Number)id).intValue();
- if (!x.obj.has(intId, x.obj))
- continue; // must have been deleted
- x.currentId = x.enumNumbers ? (Object) (new Integer(intId))
- : String.valueOf(intId);
- }
- return Boolean.TRUE;
- }
- }
-
- public static Object enumId(Object enumObj, Context cx)
- {
- IdEnumeration x = (IdEnumeration)enumObj;
- if (x.iterator != null) {
- return x.currentId;
- }
- switch (x.enumType) {
- case ENUMERATE_KEYS:
- case ENUMERATE_KEYS_NO_ITERATOR:
- return x.currentId;
- case ENUMERATE_VALUES:
- case ENUMERATE_VALUES_NO_ITERATOR:
- return enumValue(enumObj, cx);
- case ENUMERATE_ARRAY:
- case ENUMERATE_ARRAY_NO_ITERATOR:
- Object[] elements = { x.currentId, enumValue(enumObj, cx) };
- return cx.newArray(x.obj.getParentScope(), elements);
- default:
- throw Kit.codeBug();
- }
- }
-
- public static Object enumValue(Object enumObj, Context cx) {
- IdEnumeration x = (IdEnumeration)enumObj;
-
- Object result;
-
- String s = toStringIdOrIndex(cx, x.currentId);
- if (s == null) {
- int index = lastIndexResult(cx);
- result = x.obj.get(index, x.obj);
- } else {
- result = x.obj.get(s, x.obj);
- }
-
- return result;
- }
-
- private static void enumChangeObject(IdEnumeration x)
- {
- Object[] ids = null;
- while (x.obj != null) {
- ids = x.obj.getIds();
- if (ids.length != 0) {
- break;
- }
- x.obj = x.obj.getPrototype();
- }
- if (x.obj != null && x.ids != null) {
- Object[] previous = x.ids;
- int L = previous.length;
- if (x.used == null) {
- x.used = new ObjToIntMap(L);
- }
- for (int i = 0; i != L; ++i) {
- x.used.intern(previous[i]);
- }
- }
- x.ids = ids;
- x.index = 0;
- }
-
- /**
- * Prepare for calling name(...): return function corresponding to
- * name and make current top scope available
- * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj.
- * The caller must call ScriptRuntime.lastStoredScriptable() immediately
- * after calling this method.
- */
- public static Callable getNameFunctionAndThis(String name,
- Context cx,
- Scriptable scope)
- {
- Scriptable parent = scope.getParentScope();
- if (parent == null) {
- Object result = topScopeName(cx, scope, name);
- if (!(result instanceof Callable)) {
- if (result == Scriptable.NOT_FOUND) {
- throw notFoundError(scope, name);
- } else {
- throw notFunctionError(result, name);
- }
- }
- // Top scope is not NativeWith or NativeCall => thisObj == scope
- Scriptable thisObj = scope;
- storeScriptable(cx, thisObj);
- return (Callable)result;
- }
-
- // name will call storeScriptable(cx, thisObj);
- return (Callable)nameOrFunction(cx, scope, parent, name, true);
- }
-
- /**
- * Prepare for calling obj[id](...): return function corresponding to
- * obj[id] and make obj properly converted to Scriptable available
- * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj.
- * The caller must call ScriptRuntime.lastStoredScriptable() immediately
- * after calling this method.
- */
- public static Callable getElemFunctionAndThis(Object obj,
- Object elem,
- Context cx)
- {
- String s = toStringIdOrIndex(cx, elem);
- if (s != null) {
- return getPropFunctionAndThis(obj, s, cx);
- }
- int index = lastIndexResult(cx);
-
- Scriptable thisObj = toObjectOrNull(cx, obj);
- if (thisObj == null) {
- throw undefCallError(obj, String.valueOf(index));
- }
-
- Object value;
- for (;;) {
- // Ignore XML lookup as requred by ECMA 357, 11.2.2.1
- value = ScriptableObject.getProperty(thisObj, index);
- if (value != Scriptable.NOT_FOUND) {
- break;
- }
- if (!(thisObj instanceof XMLObject)) {
- break;
- }
- XMLObject xmlObject = (XMLObject)thisObj;
- Scriptable extra = xmlObject.getExtraMethodSource(cx);
- if (extra == null) {
- break;
- }
- thisObj = extra;
- }
- if (!(value instanceof Callable)) {
- throw notFunctionError(value, elem);
- }
-
- storeScriptable(cx, thisObj);
- return (Callable)value;
- }
-
- /**
- * Prepare for calling obj.property(...): return function corresponding to
- * obj.property and make obj properly converted to Scriptable available
- * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj.
- * The caller must call ScriptRuntime.lastStoredScriptable() immediately
- * after calling this method.
- */
- public static Callable getPropFunctionAndThis(Object obj,
- String property,
- Context cx)
- {
- Scriptable thisObj = toObjectOrNull(cx, obj);
- if (thisObj == null) {
- throw undefCallError(obj, property);
- }
-
- Object value;
- for (;;) {
- // Ignore XML lookup as required by ECMA 357, 11.2.2.1
- value = ScriptableObject.getProperty(thisObj, property);
- if (value != Scriptable.NOT_FOUND) {
- break;
- }
- if (!(thisObj instanceof XMLObject)) {
- break;
- }
- XMLObject xmlObject = (XMLObject)thisObj;
- Scriptable extra = xmlObject.getExtraMethodSource(cx);
- if (extra == null) {
- break;
- }
- thisObj = extra;
- }
-
- if (!(value instanceof Callable)) {
- Object noSuchMethod = ScriptableObject.getProperty(thisObj, "__noSuchMethod__");
- if (noSuchMethod instanceof Callable)
- value = new NoSuchMethodShim((Callable)noSuchMethod, property);
- else
- throw notFunctionError(thisObj, value, property);
- }
-
- storeScriptable(cx, thisObj);
- return (Callable)value;
- }
-
- /**
- * Prepare for calling <expression>(...): return function corresponding to
- * <expression> and make parent scope of the function available
- * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj.
- * The caller must call ScriptRuntime.lastStoredScriptable() immediately
- * after calling this method.
- */
- public static Callable getValueFunctionAndThis(Object value, Context cx)
- {
- if (!(value instanceof Callable)) {
- throw notFunctionError(value);
- }
-
- Callable f = (Callable)value;
- Scriptable thisObj = null;
- if (f instanceof Scriptable) {
- thisObj = ((Scriptable)f).getParentScope();
- }
- if (thisObj == null) {
- if (cx.topCallScope == null) throw new IllegalStateException();
- thisObj = cx.topCallScope;
- }
- if (thisObj.getParentScope() != null) {
- if (thisObj instanceof NativeWith) {
- // functions defined inside with should have with target
- // as their thisObj
- } else if (thisObj instanceof NativeCall) {
- // nested functions should have top scope as their thisObj
- thisObj = ScriptableObject.getTopLevelScope(thisObj);
- }
- }
- storeScriptable(cx, thisObj);
- return f;
- }
-
- /**
- * Perform function call in reference context. Should always
- * return value that can be passed to
- * {@link #refGet(Ref, Context)} or {@link #refSet(Ref, Object, Context)}
- * arbitrary number of times.
- * The args array reference should not be stored in any object that is
- * can be GC-reachable after this method returns. If this is necessary,
- * store args.clone(), not args array itself.
- */
- public static Ref callRef(Callable function, Scriptable thisObj,
- Object[] args, Context cx)
- {
- if (function instanceof RefCallable) {
- RefCallable rfunction = (RefCallable)function;
- Ref ref = rfunction.refCall(cx, thisObj, args);
- if (ref == null) {
- throw new IllegalStateException(rfunction.getClass().getName()+".refCall() returned null");
- }
- return ref;
- }
- // No runtime support for now
- String msg = getMessage1("msg.no.ref.from.function",
- toString(function));
- throw constructError("ReferenceError", msg);
- }
-
- /**
- * Operator new.
- *
- * See ECMA 11.2.2
- */
- public static Scriptable newObject(Object fun, Context cx,
- Scriptable scope, Object[] args)
- {
- if (!(fun instanceof Function)) {
- throw notFunctionError(fun);
- }
- Function function = (Function)fun;
- return function.construct(cx, scope, args);
- }
-
- public static Object callSpecial(Context cx, Callable fun,
- Scriptable thisObj,
- Object[] args, Scriptable scope,
- Scriptable callerThis, int callType,
- String filename, int lineNumber)
- {
- if (callType == Node.SPECIALCALL_EVAL) {
- if (NativeGlobal.isEvalFunction(fun)) {
- return evalSpecial(cx, scope, callerThis, args,
- filename, lineNumber);
- }
- } else if (callType == Node.SPECIALCALL_WITH) {
- if (NativeWith.isWithFunction(fun)) {
- throw Context.reportRuntimeError1("msg.only.from.new",
- "With");
- }
- } else {
- throw Kit.codeBug();
- }
-
- return fun.call(cx, scope, thisObj, args);
- }
-
- public static Object newSpecial(Context cx, Object fun,
- Object[] args, Scriptable scope,
- int callType)
- {
- if (callType == Node.SPECIALCALL_EVAL) {
- if (NativeGlobal.isEvalFunction(fun)) {
- throw typeError1("msg.not.ctor", "eval");
- }
- } else if (callType == Node.SPECIALCALL_WITH) {
- if (NativeWith.isWithFunction(fun)) {
- return NativeWith.newWithSpecial(cx, scope, args);
- }
- } else {
- throw Kit.codeBug();
- }
-
- return newObject(fun, cx, scope, args);
- }
-
- /**
- * Function.prototype.apply and Function.prototype.call
- *
- * See Ecma 15.3.4.[34]
- */
- public static Object applyOrCall(boolean isApply,
- Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- int L = args.length;
- Callable function = getCallable(thisObj);
-
- Scriptable callThis = null;
- if (L != 0) {
- callThis = toObjectOrNull(cx, args[0]);
- }
- if (callThis == null) {
- // This covers the case of args[0] == (null|undefined) as well.
- callThis = getTopCallScope(cx);
- }
-
- Object[] callArgs;
- if (isApply) {
- // Follow Ecma 15.3.4.3
- callArgs = L <= 1 ? ScriptRuntime.emptyArgs :
- getApplyArguments(cx, args[1]);
- } else {
- // Follow Ecma 15.3.4.4
- if (L <= 1) {
- callArgs = ScriptRuntime.emptyArgs;
- } else {
- callArgs = new Object[L - 1];
- System.arraycopy(args, 1, callArgs, 0, L - 1);
- }
- }
-
- return function.call(cx, scope, callThis, callArgs);
- }
-
- static Object[] getApplyArguments(Context cx, Object arg1)
- {
- if (arg1 == null || arg1 == Undefined.instance) {
- return ScriptRuntime.emptyArgs;
- } else if (arg1 instanceof NativeArray || arg1 instanceof Arguments) {
- return cx.getElements((Scriptable) arg1);
- } else {
- throw ScriptRuntime.typeError0("msg.arg.isnt.array");
- }
- }
-
- static Callable getCallable(Scriptable thisObj)
- {
- Callable function;
- if (thisObj instanceof Callable) {
- function = (Callable)thisObj;
- } else {
- Object value = thisObj.getDefaultValue(ScriptRuntime.FunctionClass);
- if (!(value instanceof Callable)) {
- throw ScriptRuntime.notFunctionError(value, thisObj);
- }
- function = (Callable)value;
- }
- return function;
- }
-
- /**
- * The eval function property of the global object.
- *
- * See ECMA 15.1.2.1
- */
- public static Object evalSpecial(Context cx, Scriptable scope,
- Object thisArg, Object[] args,
- String filename, int lineNumber)
- {
- if (args.length < 1)
- return Undefined.instance;
- Object x = args[0];
- if (!(x instanceof String)) {
- if (cx.hasFeature(Context.FEATURE_STRICT_MODE) ||
- cx.hasFeature(Context.FEATURE_STRICT_EVAL))
- {
- throw Context.reportRuntimeError0("msg.eval.nonstring.strict");
- }
- String message = ScriptRuntime.getMessage0("msg.eval.nonstring");
- Context.reportWarning(message);
- return x;
- }
- if (filename == null) {
- int[] linep = new int[1];
- filename = Context.getSourcePositionFromStack(linep);
- if (filename != null) {
- lineNumber = linep[0];
- } else {
- filename = "";
- }
- }
- String sourceName = ScriptRuntime.
- makeUrlForGeneratedScript(true, filename, lineNumber);
-
- ErrorReporter reporter;
- reporter = DefaultErrorReporter.forEval(cx.getErrorReporter());
-
- Evaluator evaluator = Context.createInterpreter();
- if (evaluator == null) {
- throw new JavaScriptException("Interpreter not present",
- filename, lineNumber);
- }
-
- // Compile with explicit interpreter instance to force interpreter
- // mode.
- Script script = cx.compileString((String)x, evaluator,
- reporter, sourceName, 1, null);
- evaluator.setEvalScriptFlag(script);
- Callable c = (Callable)script;
- return c.call(cx, scope, (Scriptable)thisArg, ScriptRuntime.emptyArgs);
- }
-
- /**
- * The typeof operator
- */
- public static String typeof(Object value)
- {
- if (value == null)
- return "object";
- if (value == Undefined.instance)
- return "undefined";
- if (value instanceof Scriptable)
- {
- if (value instanceof ScriptableObject &&
- ((ScriptableObject)value).avoidObjectDetection())
- {
- return "undefined";
- }
- if (value instanceof XMLObject)
- return "xml";
- return (value instanceof Callable) ? "function" : "object";
- }
- if (value instanceof String)
- return "string";
- if (value instanceof Number)
- return "number";
- if (value instanceof Boolean)
- return "boolean";
- throw errorWithClassName("msg.invalid.type", value);
- }
-
- /**
- * The typeof operator that correctly handles the undefined case
- */
- public static String typeofName(Scriptable scope, String id)
- {
- Context cx = Context.getContext();
- Scriptable val = bind(cx, scope, id);
- if (val == null)
- return "undefined";
- return typeof(getObjectProp(val, id, cx));
- }
-
- // neg:
- // implement the '-' operator inline in the caller
- // as "-toNumber(val)"
-
- // not:
- // implement the '!' operator inline in the caller
- // as "!toBoolean(val)"
-
- // bitnot:
- // implement the '~' operator inline in the caller
- // as "~toInt32(val)"
-
- public static Object add(Object val1, Object val2, Context cx)
- {
- if(val1 instanceof Number && val2 instanceof Number) {
- return wrapNumber(((Number)val1).doubleValue() +
- ((Number)val2).doubleValue());
- }
- if (val1 instanceof XMLObject) {
- Object test = ((XMLObject)val1).addValues(cx, true, val2);
- if (test != Scriptable.NOT_FOUND) {
- return test;
- }
- }
- if (val2 instanceof XMLObject) {
- Object test = ((XMLObject)val2).addValues(cx, false, val1);
- if (test != Scriptable.NOT_FOUND) {
- return test;
- }
- }
- if (val1 instanceof Scriptable)
- val1 = ((Scriptable) val1).getDefaultValue(null);
- if (val2 instanceof Scriptable)
- val2 = ((Scriptable) val2).getDefaultValue(null);
- if (!(val1 instanceof String) && !(val2 instanceof String))
- if ((val1 instanceof Number) && (val2 instanceof Number))
- return wrapNumber(((Number)val1).doubleValue() +
- ((Number)val2).doubleValue());
- else
- return wrapNumber(toNumber(val1) + toNumber(val2));
- return toString(val1).concat(toString(val2));
- }
-
- public static String add(String val1, Object val2) {
- return val1.concat(toString(val2));
- }
-
- public static String add(Object val1, String val2) {
- return toString(val1).concat(val2);
- }
-
- /**
- * @deprecated The method is only present for compatibility.
- */
- public static Object nameIncrDecr(Scriptable scopeChain, String id,
- int incrDecrMask)
- {
- return nameIncrDecr(scopeChain, id, Context.getContext(), incrDecrMask);
- }
-
- public static Object nameIncrDecr(Scriptable scopeChain, String id,
- Context cx, int incrDecrMask)
- {
- Scriptable target;
- Object value;
- search: {
- do {
- if (cx.useDynamicScope && scopeChain.getParentScope() == null) {
- scopeChain = checkDynamicScope(cx.topCallScope, scopeChain);
- }
- target = scopeChain;
- do {
- value = target.get(id, scopeChain);
- if (value != Scriptable.NOT_FOUND) {
- break search;
- }
- target = target.getPrototype();
- } while (target != null);
- scopeChain = scopeChain.getParentScope();
- } while (scopeChain != null);
- throw notFoundError(scopeChain, id);
- }
- return doScriptableIncrDecr(target, id, scopeChain, value,
- incrDecrMask);
- }
-
- public static Object propIncrDecr(Object obj, String id,
- Context cx, int incrDecrMask)
- {
- Scriptable start = toObjectOrNull(cx, obj);
- if (start == null) {
- throw undefReadError(obj, id);
- }
-
- Scriptable target = start;
- Object value;
- search: {
- do {
- value = target.get(id, start);
- if (value != Scriptable.NOT_FOUND) {
- break search;
- }
- target = target.getPrototype();
- } while (target != null);
- start.put(id, start, NaNobj);
- return NaNobj;
- }
- return doScriptableIncrDecr(target, id, start, value,
- incrDecrMask);
- }
-
- private static Object doScriptableIncrDecr(Scriptable target,
- String id,
- Scriptable protoChainStart,
- Object value,
- int incrDecrMask)
- {
- boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
- double number;
- if (value instanceof Number) {
- number = ((Number)value).doubleValue();
- } else {
- number = toNumber(value);
- if (post) {
- // convert result to number
- value = wrapNumber(number);
- }
- }
- if ((incrDecrMask & Node.DECR_FLAG) == 0) {
- ++number;
- } else {
- --number;
- }
- Number result = wrapNumber(number);
- target.put(id, protoChainStart, result);
- if (post) {
- return value;
- } else {
- return result;
- }
- }
-
- public static Object elemIncrDecr(Object obj, Object index,
- Context cx, int incrDecrMask)
- {
- Object value = getObjectElem(obj, index, cx);
- boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
- double number;
- if (value instanceof Number) {
- number = ((Number)value).doubleValue();
- } else {
- number = toNumber(value);
- if (post) {
- // convert result to number
- value = wrapNumber(number);
- }
- }
- if ((incrDecrMask & Node.DECR_FLAG) == 0) {
- ++number;
- } else {
- --number;
- }
- Number result = wrapNumber(number);
- setObjectElem(obj, index, result, cx);
- if (post) {
- return value;
- } else {
- return result;
- }
- }
-
- public static Object refIncrDecr(Ref ref, Context cx, int incrDecrMask)
- {
- Object value = ref.get(cx);
- boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
- double number;
- if (value instanceof Number) {
- number = ((Number)value).doubleValue();
- } else {
- number = toNumber(value);
- if (post) {
- // convert result to number
- value = wrapNumber(number);
- }
- }
- if ((incrDecrMask & Node.DECR_FLAG) == 0) {
- ++number;
- } else {
- --number;
- }
- Number result = wrapNumber(number);
- ref.set(cx, result);
- if (post) {
- return value;
- } else {
- return result;
- }
- }
-
- private static Object toPrimitive(Object val)
- {
- if (!(val instanceof Scriptable)) {
- return val;
- }
- Scriptable s = (Scriptable)val;
- Object result = s.getDefaultValue(null);
- if (result instanceof Scriptable)
- throw typeError0("msg.bad.default.value");
- return result;
- }
-
- /**
- * Equality
- *
- * See ECMA 11.9
- */
- public static boolean eq(Object x, Object y)
- {
- if (x == null || x == Undefined.instance) {
- if (y == null || y == Undefined.instance) {
- return true;
- }
- if (y instanceof ScriptableObject) {
- Object test = ((ScriptableObject)y).equivalentValues(x);
- if (test != Scriptable.NOT_FOUND) {
- return ((Boolean)test).booleanValue();
- }
- }
- return false;
- } else if (x instanceof Number) {
- return eqNumber(((Number)x).doubleValue(), y);
- } else if (x instanceof String) {
- return eqString((String)x, y);
- } else if (x instanceof Boolean) {
- boolean b = ((Boolean)x).booleanValue();
- if (y instanceof Boolean) {
- return b == ((Boolean)y).booleanValue();
- }
- if (y instanceof ScriptableObject) {
- Object test = ((ScriptableObject)y).equivalentValues(x);
- if (test != Scriptable.NOT_FOUND) {
- return ((Boolean)test).booleanValue();
- }
- }
- return eqNumber(b ? 1.0 : 0.0, y);
- } else if (x instanceof Scriptable) {
- if (y instanceof Scriptable) {
- if (x == y) {
- return true;
- }
- if (x instanceof ScriptableObject) {
- Object test = ((ScriptableObject)x).equivalentValues(y);
- if (test != Scriptable.NOT_FOUND) {
- return ((Boolean)test).booleanValue();
- }
- }
- if (y instanceof ScriptableObject) {
- Object test = ((ScriptableObject)y).equivalentValues(x);
- if (test != Scriptable.NOT_FOUND) {
- return ((Boolean)test).booleanValue();
- }
- }
- if (x instanceof Wrapper && y instanceof Wrapper) {
- // See bug 413838. Effectively an extension to ECMA for
- // the LiveConnect case.
- Object unwrappedX = ((Wrapper)x).unwrap();
- Object unwrappedY = ((Wrapper)y).unwrap();
- return unwrappedX == unwrappedY ||
- (isPrimitive(unwrappedX) &&
- isPrimitive(unwrappedY) &&
- eq(unwrappedX, unwrappedY));
- }
- return false;
- } else if (y instanceof Boolean) {
- if (x instanceof ScriptableObject) {
- Object test = ((ScriptableObject)x).equivalentValues(y);
- if (test != Scriptable.NOT_FOUND) {
- return ((Boolean)test).booleanValue();
- }
- }
- double d = ((Boolean)y).booleanValue() ? 1.0 : 0.0;
- return eqNumber(d, x);
- } else if (y instanceof Number) {
- return eqNumber(((Number)y).doubleValue(), x);
- } else if (y instanceof String) {
- return eqString((String)y, x);
- }
- // covers the case when y == Undefined.instance as well
- return false;
- } else {
- warnAboutNonJSObject(x);
- return x == y;
- }
- }
-
- private static boolean isPrimitive(Object obj) {
- return (obj instanceof Number) || (obj instanceof String) ||
- (obj instanceof Boolean);
- }
-
- static boolean eqNumber(double x, Object y)
- {
- for (;;) {
- if (y == null || y == Undefined.instance) {
- return false;
- } else if (y instanceof Number) {
- return x == ((Number)y).doubleValue();
- } else if (y instanceof String) {
- return x == toNumber(y);
- } else if (y instanceof Boolean) {
- return x == (((Boolean)y).booleanValue() ? 1.0 : +0.0);
- } else if (y instanceof Scriptable) {
- if (y instanceof ScriptableObject) {
- Object xval = wrapNumber(x);
- Object test = ((ScriptableObject)y).equivalentValues(xval);
- if (test != Scriptable.NOT_FOUND) {
- return ((Boolean)test).booleanValue();
- }
- }
- y = toPrimitive(y);
- } else {
- warnAboutNonJSObject(y);
- return false;
- }
- }
- }
-
- private static boolean eqString(String x, Object y)
- {
- for (;;) {
- if (y == null || y == Undefined.instance) {
- return false;
- } else if (y instanceof String) {
- return x.equals(y);
- } else if (y instanceof Number) {
- return toNumber(x) == ((Number)y).doubleValue();
- } else if (y instanceof Boolean) {
- return toNumber(x) == (((Boolean)y).booleanValue() ? 1.0 : 0.0);
- } else if (y instanceof Scriptable) {
- if (y instanceof ScriptableObject) {
- Object test = ((ScriptableObject)y).equivalentValues(x);
- if (test != Scriptable.NOT_FOUND) {
- return ((Boolean)test).booleanValue();
- }
- }
- y = toPrimitive(y);
- continue;
- } else {
- warnAboutNonJSObject(y);
- return false;
- }
- }
- }
- public static boolean shallowEq(Object x, Object y)
- {
- if (x == y) {
- if (!(x instanceof Number)) {
- return true;
- }
- // NaN check
- double d = ((Number)x).doubleValue();
- return d == d;
- }
- if (x == null || x == Undefined.instance) {
- return false;
- } else if (x instanceof Number) {
- if (y instanceof Number) {
- return ((Number)x).doubleValue() == ((Number)y).doubleValue();
- }
- } else if (x instanceof String) {
- if (y instanceof String) {
- return x.equals(y);
- }
- } else if (x instanceof Boolean) {
- if (y instanceof Boolean) {
- return x.equals(y);
- }
- } else if (x instanceof Scriptable) {
- if (x instanceof Wrapper && y instanceof Wrapper) {
- return ((Wrapper)x).unwrap() == ((Wrapper)y).unwrap();
- }
- } else {
- warnAboutNonJSObject(x);
- return x == y;
- }
- return false;
- }
-
- /**
- * The instanceof operator.
- *
- * @return a instanceof b
- */
- public static boolean instanceOf(Object a, Object b, Context cx)
- {
- // Check RHS is an object
- if (! (b instanceof Scriptable)) {
- throw typeError0("msg.instanceof.not.object");
- }
-
- // for primitive values on LHS, return false
- // XXX we may want to change this so that
- // 5 instanceof Number == true
- if (! (a instanceof Scriptable))
- return false;
-
- return ((Scriptable)b).hasInstance((Scriptable)a);
- }
-
- /**
- * Delegates to
- *
- * @return true iff rhs appears in lhs' proto chain
- */
- public static boolean jsDelegatesTo(Scriptable lhs, Scriptable rhs) {
- Scriptable proto = lhs.getPrototype();
-
- while (proto != null) {
- if (proto.equals(rhs)) return true;
- proto = proto.getPrototype();
- }
-
- return false;
- }
-
- /**
- * The in operator.
- *
- * This is a new JS 1.3 language feature. The in operator mirrors
- * the operation of the for .. in construct, and tests whether the
- * rhs has the property given by the lhs. It is different from the
- * for .. in construct in that:
- * <BR> - it doesn't perform ToObject on the right hand side
- * <BR> - it returns true for DontEnum properties.
- * @param a the left hand operand
- * @param b the right hand operand
- *
- * @return true if property name or element number a is a property of b
- */
- public static boolean in(Object a, Object b, Context cx)
- {
- if (!(b instanceof Scriptable)) {
- throw typeError0("msg.instanceof.not.object");
- }
-
- return hasObjectElem((Scriptable)b, a, cx);
- }
-
- public static boolean cmp_LT(Object val1, Object val2)
- {
- double d1, d2;
- if (val1 instanceof Number && val2 instanceof Number) {
- d1 = ((Number)val1).doubleValue();
- d2 = ((Number)val2).doubleValue();
- } else {
- if (val1 instanceof Scriptable)
- val1 = ((Scriptable) val1).getDefaultValue(NumberClass);
- if (val2 instanceof Scriptable)
- val2 = ((Scriptable) val2).getDefaultValue(NumberClass);
- if (val1 instanceof String && val2 instanceof String) {
- return ((String)val1).compareTo((String)val2) < 0;
- }
- d1 = toNumber(val1);
- d2 = toNumber(val2);
- }
- return d1 < d2;
- }
-
- public static boolean cmp_LE(Object val1, Object val2)
- {
- double d1, d2;
- if (val1 instanceof Number && val2 instanceof Number) {
- d1 = ((Number)val1).doubleValue();
- d2 = ((Number)val2).doubleValue();
- } else {
- if (val1 instanceof Scriptable)
- val1 = ((Scriptable) val1).getDefaultValue(NumberClass);
- if (val2 instanceof Scriptable)
- val2 = ((Scriptable) val2).getDefaultValue(NumberClass);
- if (val1 instanceof String && val2 instanceof String) {
- return ((String)val1).compareTo((String)val2) <= 0;
- }
- d1 = toNumber(val1);
- d2 = toNumber(val2);
- }
- return d1 <= d2;
- }
-
- // ------------------
- // Statements
- // ------------------
-
- public static ScriptableObject getGlobal(Context cx) {
- final String GLOBAL_CLASS = "org.mozilla.javascript.tools.shell.Global";
- Class globalClass = Kit.classOrNull(GLOBAL_CLASS);
- if (globalClass != null) {
- try {
- Class[] parm = { ScriptRuntime.ContextClass };
- Constructor globalClassCtor = globalClass.getConstructor(parm);
- Object[] arg = { cx };
- return (ScriptableObject) globalClassCtor.newInstance(arg);
- } catch (Exception e) {
- // fall through...
- }
- }
- return new ImporterTopLevel(cx);
- }
-
- public static boolean hasTopCall(Context cx)
- {
- return (cx.topCallScope != null);
- }
-
- public static Scriptable getTopCallScope(Context cx)
- {
- Scriptable scope = cx.topCallScope;
- if (scope == null) {
- throw new IllegalStateException();
- }
- return scope;
- }
-
- public static Object doTopCall(Callable callable,
- Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (scope == null) throw new IllegalArgumentException();
- if (cx.topCallScope != null) throw new IllegalStateException();
-
- Object result;
- cx.topCallScope = ScriptableObject.getTopLevelScope(scope);
- cx.useDynamicScope = cx.hasFeature(Context.FEATURE_DYNAMIC_SCOPE);
- ContextFactory f = cx.getFactory();
- try {
- result = f.doTopCall(callable, cx, scope, thisObj, args);
- } finally {
- cx.topCallScope = null;
- // Cleanup cached references
- cx.cachedXMLLib = null;
-
- if (cx.currentActivationCall != null) {
- // Function should always call exitActivationFunction
- // if it creates activation record
- throw new IllegalStateException();
- }
- }
- return result;
- }
-
- /**
- * Return <tt>possibleDynamicScope</tt> if <tt>staticTopScope</tt>
- * is present on its prototype chain and return <tt>staticTopScope</tt>
- * otherwise.
- * Should only be called when <tt>staticTopScope</tt> is top scope.
- */
- static Scriptable checkDynamicScope(Scriptable possibleDynamicScope,
- Scriptable staticTopScope)
- {
- // Return cx.topCallScope if scope
- if (possibleDynamicScope == staticTopScope) {
- return possibleDynamicScope;
- }
- Scriptable proto = possibleDynamicScope;
- for (;;) {
- proto = proto.getPrototype();
- if (proto == staticTopScope) {
- return possibleDynamicScope;
- }
- if (proto == null) {
- return staticTopScope;
- }
- }
- }
-
- public static void addInstructionCount(Context cx, int instructionsToAdd)
- {
- cx.instructionCount += instructionsToAdd;
- if (cx.instructionCount > cx.instructionThreshold)
- {
- cx.observeInstructionCount(cx.instructionCount);
- cx.instructionCount = 0;
- }
- }
-
- public static void initScript(NativeFunction funObj, Scriptable thisObj,
- Context cx, Scriptable scope,
- boolean evalScript)
- {
- if (cx.topCallScope == null)
- throw new IllegalStateException();
-
- int varCount = funObj.getParamAndVarCount();
- if (varCount != 0) {
-
- Scriptable varScope = scope;
- // Never define any variables from var statements inside with
- // object. See bug 38590.
- while (varScope instanceof NativeWith) {
- varScope = varScope.getParentScope();
- }
-
- for (int i = varCount; i-- != 0;) {
- String name = funObj.getParamOrVarName(i);
- boolean isConst = funObj.getParamOrVarConst(i);
- // Don't overwrite existing def if already defined in object
- // or prototypes of object.
- if (!ScriptableObject.hasProperty(scope, name)) {
- if (!evalScript) {
- // Global var definitions are supposed to be DONTDELETE
- if (isConst)
- ScriptableObject.defineConstProperty(varScope, name);
- else
- ScriptableObject.defineProperty(
- varScope, name, Undefined.instance,
- ScriptableObject.PERMANENT);
- } else {
- varScope.put(name, varScope, Undefined.instance);
- }
- } else {
- ScriptableObject.redefineProperty(scope, name, isConst);
- }
- }
- }
- }
-
- public static Scriptable createFunctionActivation(NativeFunction funObj,
- Scriptable scope,
- Object[] args)
- {
- return new NativeCall(funObj, scope, args);
- }
-
-
- public static void enterActivationFunction(Context cx,
- Scriptable scope)
- {
- if (cx.topCallScope == null)
- throw new IllegalStateException();
- NativeCall call = (NativeCall)scope;
- call.parentActivationCall = cx.currentActivationCall;
- cx.currentActivationCall = call;
- }
-
- public static void exitActivationFunction(Context cx)
- {
- NativeCall call = cx.currentActivationCall;
- cx.currentActivationCall = call.parentActivationCall;
- call.parentActivationCall = null;
- }
-
- static NativeCall findFunctionActivation(Context cx, Function f)
- {
- NativeCall call = cx.currentActivationCall;
- while (call != null) {
- if (call.function == f)
- return call;
- call = call.parentActivationCall;
- }
- return null;
- }
-
- public static Scriptable newCatchScope(Throwable t,
- Scriptable lastCatchScope,
- String exceptionName,
- Context cx, Scriptable scope)
- {
- Object obj;
- boolean cacheObj;
-
- getObj:
- if (t instanceof JavaScriptException) {
- cacheObj = false;
- obj = ((JavaScriptException)t).getValue();
- } else {
- cacheObj = true;
-
- // Create wrapper object unless it was associated with
- // the previous scope object
-
- if (lastCatchScope != null) {
- NativeObject last = (NativeObject)lastCatchScope;
- obj = last.getAssociatedValue(t);
- if (obj == null) Kit.codeBug();
- break getObj;
- }
-
- RhinoException re;
- String errorName;
- String errorMsg;
- Throwable javaException = null;
-
- if (t instanceof EcmaError) {
- EcmaError ee = (EcmaError)t;
- re = ee;
- errorName = ee.getName();
- errorMsg = ee.getErrorMessage();
- } else if (t instanceof WrappedException) {
- WrappedException we = (WrappedException)t;
- re = we;
- javaException = we.getWrappedException();
- errorName = "JavaException";
- errorMsg = javaException.getClass().getName()
- +": "+javaException.getMessage();
- } else if (t instanceof EvaluatorException) {
- // Pure evaluator exception, nor WrappedException instance
- EvaluatorException ee = (EvaluatorException)t;
- re = ee;
- errorName = "InternalError";
- errorMsg = ee.getMessage();
- } else if (cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS)) {
- // With FEATURE_ENHANCED_JAVA_ACCESS, scripts can catch
- // all exception types
- re = new WrappedException(t);
- errorName = "JavaException";
- errorMsg = t.toString();
- } else {
- // Script can catch only instances of JavaScriptException,
- // EcmaError and EvaluatorException
- throw Kit.codeBug();
- }
-
- String sourceUri = re.sourceName();
- if (sourceUri == null) {
- sourceUri = "";
- }
- int line = re.lineNumber();
- Object args[];
- if (line > 0) {
- args = new Object[] { errorMsg, sourceUri, new Integer(line) };
- } else {
- args = new Object[] { errorMsg, sourceUri };
- }
-
- Scriptable errorObject = cx.newObject(scope, errorName, args);
- ScriptableObject.putProperty(errorObject, "name", errorName);
-
- if (javaException != null) {
- Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException,
- null);
- ScriptableObject.defineProperty(
- errorObject, "javaException", wrap,
- ScriptableObject.PERMANENT | ScriptableObject.READONLY);
- }
- Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null);
- ScriptableObject.defineProperty(
- errorObject, "rhinoException", wrap,
- ScriptableObject.PERMANENT | ScriptableObject.READONLY);
-
- obj = errorObject;
- }
-
- NativeObject catchScopeObject = new NativeObject();
- // See ECMA 12.4
- catchScopeObject.defineProperty(
- exceptionName, obj, ScriptableObject.PERMANENT);
-
- // Add special Rhino object __exception__ defined in the catch
- // scope that can be used to retrieve the Java exception associated
- // with the JavaScript exception (to get stack trace info, etc.)
- /*APPJET NOJAVA*/
- /*catchScopeObject.defineProperty(
- "__exception__", Context.javaToJS(t, scope),
- ScriptableObject.PERMANENT|ScriptableObject.DONTENUM);*/
-
- if (cacheObj) {
- catchScopeObject.associateValue(t, obj);
- }
- return catchScopeObject;
- }
-
- public static Scriptable enterWith(Object obj, Context cx,
- Scriptable scope)
- {
- Scriptable sobj = toObjectOrNull(cx, obj);
- if (sobj == null) {
- throw typeError1("msg.undef.with", toString(obj));
- }
- if (sobj instanceof XMLObject) {
- XMLObject xmlObject = (XMLObject)sobj;
- return xmlObject.enterWith(scope);
- }
- return new NativeWith(scope, sobj);
- }
-
- public static Scriptable leaveWith(Scriptable scope)
- {
- NativeWith nw = (NativeWith)scope;
- return nw.getParentScope();
- }
-
- public static Scriptable enterDotQuery(Object value, Scriptable scope)
- {
- if (!(value instanceof XMLObject)) {
- throw notXmlError(value);
- }
- XMLObject object = (XMLObject)value;
- return object.enterDotQuery(scope);
- }
-
- public static Object updateDotQuery(boolean value, Scriptable scope)
- {
- // Return null to continue looping
- NativeWith nw = (NativeWith)scope;
- return nw.updateDotQuery(value);
- }
-
- public static Scriptable leaveDotQuery(Scriptable scope)
- {
- NativeWith nw = (NativeWith)scope;
- return nw.getParentScope();
- }
-
- public static void setFunctionProtoAndParent(BaseFunction fn,
- Scriptable scope)
- {
- fn.setParentScope(scope);
- fn.setPrototype(ScriptableObject.getFunctionPrototype(scope));
- }
-
- public static void setObjectProtoAndParent(ScriptableObject object,
- Scriptable scope)
- {
- // Compared with function it always sets the scope to top scope
- scope = ScriptableObject.getVeryTopLevelScope(scope); // APPJET
- object.setParentScope(scope);
- Scriptable proto
- = ScriptableObject.getClassPrototype(scope, object.getClassName());
- object.setPrototype(proto);
- }
-
- public static void initFunction(Context cx, Scriptable scope,
- NativeFunction function, int type,
- boolean fromEvalCode)
- {
- if (type == FunctionNode.FUNCTION_STATEMENT) {
- String name = function.getFunctionName();
- if (name != null && name.length() != 0) {
- if (!fromEvalCode) {
- // ECMA specifies that functions defined in global and
- // function scope outside eval should have DONTDELETE set.
- ScriptableObject.defineProperty
- (scope, name, function, ScriptableObject.PERMANENT);
- } else {
- scope.put(name, scope, function);
- }
- }
- } else if (type == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) {
- String name = function.getFunctionName();
- if (name != null && name.length() != 0) {
- // Always put function expression statements into initial
- // activation object ignoring the with statement to follow
- // SpiderMonkey
- while (scope instanceof NativeWith) {
- scope = scope.getParentScope();
- }
- scope.put(name, scope, function);
- }
- } else {
- throw Kit.codeBug();
- }
- }
-
- public static Scriptable newArrayLiteral(Object[] objects,
- int[] skipIndices,
- Context cx, Scriptable scope)
- {
- final int SKIP_DENSITY = 2;
- int count = objects.length;
- int skipCount = 0;
- if (skipIndices != null) {
- skipCount = skipIndices.length;
- }
- int length = count + skipCount;
- if (length > 1 && skipCount * SKIP_DENSITY < length) {
- // If not too sparse, create whole array for constructor
- Object[] sparse;
- if (skipCount == 0) {
- sparse = objects;
- } else {
- sparse = new Object[length];
- int skip = 0;
- for (int i = 0, j = 0; i != length; ++i) {
- if (skip != skipCount && skipIndices[skip] == i) {
- sparse[i] = Scriptable.NOT_FOUND;
- ++skip;
- continue;
- }
- sparse[i] = objects[j];
- ++j;
- }
- }
- return cx.newObject(scope, "Array", sparse);
- }
-
- Scriptable arrayObj = cx.newObject(scope, "Array",
- ScriptRuntime.emptyArgs);
- int skip = 0;
- for (int i = 0, j = 0; i != length; ++i) {
- if (skip != skipCount && skipIndices[skip] == i) {
- ++skip;
- continue;
- }
- ScriptableObject.putProperty(arrayObj, i, objects[j]);
- ++j;
- }
- return arrayObj;
- }
-
- /**
- * This method is here for backward compat with existing compiled code. It
- * is called when an object literal is compiled. The next instance will be
- * the version called from new code.
- * @deprecated This method only present for compatibility.
- */
- public static Scriptable newObjectLiteral(Object[] propertyIds,
- Object[] propertyValues,
- Context cx, Scriptable scope)
- {
- // This will initialize to all zeros, exactly what we need for old-style
- // getterSetters values (no getters or setters in the list)
- int [] getterSetters = new int[propertyIds.length];
- return newObjectLiteral(propertyIds, propertyValues, getterSetters,
- cx, scope);
- }
-
- public static Scriptable newObjectLiteral(Object[] propertyIds,
- Object[] propertyValues,
- int [] getterSetters,
- Context cx, Scriptable scope)
- {
- Scriptable object = cx.newObject(scope);
- for (int i = 0, end = propertyIds.length; i != end; ++i) {
- Object id = propertyIds[i];
- int getterSetter = getterSetters[i];
- Object value = propertyValues[i];
- if (id instanceof String) {
- if (getterSetter == 0)
- ScriptableObject.putProperty(object, (String)id, value);
- else {
- Callable fun;
- String definer;
- if (getterSetter < 0) // < 0 means get foo() ...
- definer = "__defineGetter__";
- else
- definer = "__defineSetter__";
- fun = getPropFunctionAndThis(object, definer, cx);
- // Must consume the last scriptable object in cx
- lastStoredScriptable(cx);
- Object[] outArgs = new Object[2];
- outArgs[0] = id;
- outArgs[1] = value;
- fun.call(cx, scope, object, outArgs);
- }
- } else {
- int index = ((Integer)id).intValue();
- ScriptableObject.putProperty(object, index, value);
- }
- }
- return object;
- }
-
- public static boolean isArrayObject(Object obj)
- {
- return obj instanceof NativeArray || obj instanceof Arguments;
- }
-
- public static Object[] getArrayElements(Scriptable object)
- {
- Context cx = Context.getContext();
- long longLen = NativeArray.getLengthProperty(cx, object);
- if (longLen > Integer.MAX_VALUE) {
- // arrays beyond MAX_INT is not in Java in any case
- throw new IllegalArgumentException();
- }
- int len = (int) longLen;
- if (len == 0) {
- return ScriptRuntime.emptyArgs;
- } else {
- Object[] result = new Object[len];
- for (int i=0; i < len; i++) {
- Object elem = ScriptableObject.getProperty(object, i);
- result[i] = (elem == Scriptable.NOT_FOUND) ? Undefined.instance
- : elem;
- }
- return result;
- }
- }
-
- static void checkDeprecated(Context cx, String name) {
- int version = cx.getLanguageVersion();
- if (version >= Context.VERSION_1_4 || version == Context.VERSION_DEFAULT) {
- String msg = getMessage1("msg.deprec.ctor", name);
- if (version == Context.VERSION_DEFAULT)
- Context.reportWarning(msg);
- else
- throw Context.reportRuntimeError(msg);
- }
- }
-
- public static String getMessage0(String messageId)
- {
- return getMessage(messageId, null);
- }
-
- public static String getMessage1(String messageId, Object arg1)
- {
- Object[] arguments = {arg1};
- return getMessage(messageId, arguments);
- }
-
- public static String getMessage2(
- String messageId, Object arg1, Object arg2)
- {
- Object[] arguments = {arg1, arg2};
- return getMessage(messageId, arguments);
- }
-
- public static String getMessage3(
- String messageId, Object arg1, Object arg2, Object arg3)
- {
- Object[] arguments = {arg1, arg2, arg3};
- return getMessage(messageId, arguments);
- }
-
- public static String getMessage4(
- String messageId, Object arg1, Object arg2, Object arg3, Object arg4)
- {
- Object[] arguments = {arg1, arg2, arg3, arg4};
- return getMessage(messageId, arguments);
- }
-
- /* OPT there's a noticable delay for the first error! Maybe it'd
- * make sense to use a ListResourceBundle instead of a properties
- * file to avoid (synchronized) text parsing.
- */
- public static String getMessage(String messageId, Object[] arguments)
- {
- final String defaultResource
- = "org.mozilla.javascript.resources.Messages";
-
- Context cx = Context.getCurrentContext();
- Locale locale = cx != null ? cx.getLocale() : Locale.getDefault();
-
- // ResourceBundle does cacheing.
- ResourceBundle rb = ResourceBundle.getBundle(defaultResource, locale);
-
- String formatString;
- try {
- formatString = rb.getString(messageId);
- } catch (java.util.MissingResourceException mre) {
- throw new RuntimeException
- ("no message resource found for message property "+ messageId);
- }
-
- /*
- * It's OK to format the string, even if 'arguments' is null;
- * we need to format it anyway, to make double ''s collapse to
- * single 's.
- */
- MessageFormat formatter = new MessageFormat(formatString);
- return formatter.format(arguments);
- }
-
- public static EcmaError constructError(String error, String message)
- {
- int[] linep = new int[1];
- String filename = Context.getSourcePositionFromStack(linep);
- return constructError(error, message, filename, linep[0], null, 0);
- }
-
- public static EcmaError constructError(String error,
- String message,
- int lineNumberDelta)
- {
- int[] linep = new int[1];
- String filename = Context.getSourcePositionFromStack(linep);
- if (linep[0] != 0) {
- linep[0] += lineNumberDelta;
- }
- return constructError(error, message, filename, linep[0], null, 0);
- }
-
- public static EcmaError constructError(String error,
- String message,
- String sourceName,
- int lineNumber,
- String lineSource,
- int columnNumber)
- {
- return new EcmaError(error, message, sourceName,
- lineNumber, lineSource, columnNumber);
- }
-
- public static EcmaError typeError(String message)
- {
- return constructError("TypeError", message);
- }
-
- public static EcmaError typeError0(String messageId)
- {
- String msg = getMessage0(messageId);
- return typeError(msg);
- }
-
- public static EcmaError typeError1(String messageId, String arg1)
- {
- String msg = getMessage1(messageId, arg1);
- return typeError(msg);
- }
-
- public static EcmaError typeError2(String messageId, String arg1,
- String arg2)
- {
- String msg = getMessage2(messageId, arg1, arg2);
- return typeError(msg);
- }
-
- public static EcmaError typeError3(String messageId, String arg1,
- String arg2, String arg3)
- {
- String msg = getMessage3(messageId, arg1, arg2, arg3);
- return typeError(msg);
- }
-
- public static RuntimeException undefReadError(Object object, Object id)
- {
- String idStr = (id == null) ? "null" : id.toString();
- return typeError2("msg.undef.prop.read", toString(object), idStr);
- }
-
- public static RuntimeException undefCallError(Object object, Object id)
- {
- String idStr = (id == null) ? "null" : id.toString();
- return typeError2("msg.undef.method.call", toString(object), idStr);
- }
-
- public static RuntimeException undefWriteError(Object object,
- Object id,
- Object value)
- {
- String idStr = (id == null) ? "null" : id.toString();
- String valueStr = (value instanceof Scriptable)
- ? value.toString() : toString(value);
- return typeError3("msg.undef.prop.write", toString(object), idStr,
- valueStr);
- }
-
- public static RuntimeException notFoundError(Scriptable object,
- String property)
- {
- // XXX: use object to improve the error message
- String msg = getMessage1("msg.is.not.defined", property);
- throw constructError("ReferenceError", msg);
- }
-
- public static RuntimeException notFunctionError(Object value)
- {
- return notFunctionError(value, value);
- }
-
- public static RuntimeException notFunctionError(Object value,
- Object messageHelper)
- {
- // Use value for better error reporting
- String msg = (messageHelper == null)
- ? "null" : messageHelper.toString();
- if (value == Scriptable.NOT_FOUND) {
- return typeError1("msg.function.not.found", msg);
- }
- return typeError2("msg.isnt.function", msg, typeof(value));
- }
-
- public static RuntimeException notFunctionError(Object obj, Object value,
- String propertyName)
- {
- // Use obj and value for better error reporting
- String objString = toString(obj);
- if (value == Scriptable.NOT_FOUND) {
- return typeError2("msg.function.not.found.in", propertyName,
- objString);
- }
- return typeError3("msg.isnt.function.in", propertyName, objString,
- typeof(value));
- }
-
- private static RuntimeException notXmlError(Object value)
- {
- throw typeError1("msg.isnt.xml.object", toString(value));
- }
-
- private static void warnAboutNonJSObject(Object nonJSObject)
- {
- String message =
-"RHINO USAGE WARNING: Missed Context.javaToJS() conversion:\n"
-+"Rhino runtime detected object "+nonJSObject+" of class "+nonJSObject.getClass().getName()+" where it expected String, Number, Boolean or Scriptable instance. Please check your code for missing Context.javaToJS() call.";
- Context.reportWarning(message);
- // Just to be sure that it would be noticed
- System.err.println(message);
- }
-
- public static RegExpProxy getRegExpProxy(Context cx)
- {
- return cx.getRegExpProxy();
- }
-
- public static void setRegExpProxy(Context cx, RegExpProxy proxy)
- {
- if (proxy == null) throw new IllegalArgumentException();
- cx.regExpProxy = proxy;
- }
-
- public static RegExpProxy checkRegExpProxy(Context cx)
- {
- RegExpProxy result = getRegExpProxy(cx);
- if (result == null) {
- throw Context.reportRuntimeError0("msg.no.regexp");
- }
- return result;
- }
-
- private static XMLLib currentXMLLib(Context cx)
- {
- // Scripts should be running to access this
- if (cx.topCallScope == null)
- throw new IllegalStateException();
-
- XMLLib xmlLib = cx.cachedXMLLib;
- if (xmlLib == null) {
- xmlLib = XMLLib.extractFromScope(cx.topCallScope);
- if (xmlLib == null)
- throw new IllegalStateException();
- cx.cachedXMLLib = xmlLib;
- }
-
- return xmlLib;
- }
-
- /**
- * Escapes the reserved characters in a value of an attribute
- *
- * @param value Unescaped text
- * @return The escaped text
- */
- public static String escapeAttributeValue(Object value, Context cx)
- {
- XMLLib xmlLib = currentXMLLib(cx);
- return xmlLib.escapeAttributeValue(value);
- }
-
- /**
- * Escapes the reserved characters in a value of a text node
- *
- * @param value Unescaped text
- * @return The escaped text
- */
- public static String escapeTextValue(Object value, Context cx)
- {
- XMLLib xmlLib = currentXMLLib(cx);
- return xmlLib.escapeTextValue(value);
- }
-
- public static Ref memberRef(Object obj, Object elem,
- Context cx, int memberTypeFlags)
- {
- if (!(obj instanceof XMLObject)) {
- throw notXmlError(obj);
- }
- XMLObject xmlObject = (XMLObject)obj;
- return xmlObject.memberRef(cx, elem, memberTypeFlags);
- }
-
- public static Ref memberRef(Object obj, Object namespace, Object elem,
- Context cx, int memberTypeFlags)
- {
- if (!(obj instanceof XMLObject)) {
- throw notXmlError(obj);
- }
- XMLObject xmlObject = (XMLObject)obj;
- return xmlObject.memberRef(cx, namespace, elem, memberTypeFlags);
- }
-
- public static Ref nameRef(Object name, Context cx,
- Scriptable scope, int memberTypeFlags)
- {
- XMLLib xmlLib = currentXMLLib(cx);
- return xmlLib.nameRef(cx, name, scope, memberTypeFlags);
- }
-
- public static Ref nameRef(Object namespace, Object name, Context cx,
- Scriptable scope, int memberTypeFlags)
- {
- XMLLib xmlLib = currentXMLLib(cx);
- return xmlLib.nameRef(cx, namespace, name, scope, memberTypeFlags);
- }
-
- private static void storeIndexResult(Context cx, int index)
- {
- cx.scratchIndex = index;
- }
-
- static int lastIndexResult(Context cx)
- {
- return cx.scratchIndex;
- }
-
- public static void storeUint32Result(Context cx, long value)
- {
- if ((value >>> 32) != 0)
- throw new IllegalArgumentException();
- cx.scratchUint32 = value;
- }
-
- public static long lastUint32Result(Context cx)
- {
- long value = cx.scratchUint32;
- if ((value >>> 32) != 0)
- throw new IllegalStateException();
- return value;
- }
-
- private static void storeScriptable(Context cx, Scriptable value)
- {
- // The previosly stored scratchScriptable should be consumed
- if (cx.scratchScriptable != null)
- throw new IllegalStateException();
- cx.scratchScriptable = value;
- }
-
- public static Scriptable lastStoredScriptable(Context cx)
- {
- Scriptable result = cx.scratchScriptable;
- cx.scratchScriptable = null;
- return result;
- }
-
- static String makeUrlForGeneratedScript
- (boolean isEval, String masterScriptUrl, int masterScriptLine)
- {
- if (isEval) {
- return masterScriptUrl+'#'+masterScriptLine+"(eval)";
- } else {
- return masterScriptUrl+'#'+masterScriptLine+"(Function)";
- }
- }
-
- static boolean isGeneratedScript(String sourceUrl) {
- // ALERT: this may clash with a valid URL containing (eval) or
- // (Function)
- return sourceUrl.indexOf("(eval)") >= 0
- || sourceUrl.indexOf("(Function)") >= 0;
- }
-
- private static RuntimeException errorWithClassName(String msg, Object val)
- {
- return Context.reportRuntimeError1(msg, val.getClass().getName());
- }
-
- public static final Object[] emptyArgs = new Object[0];
- public static final String[] emptyStrings = new String[0];
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Scriptable.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Scriptable.java
deleted file mode 100644
index 74e5ba7..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Scriptable.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/* -*- 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
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * This is interface that all objects in JavaScript must implement.
- * The interface provides for the management of properties and for
- * performing conversions.
- * <p>
- * Host system implementors may find it easier to extend the ScriptableObject
- * class rather than implementing Scriptable when writing host objects.
- * <p>
- * There are many static methods defined in ScriptableObject that perform
- * the multiple calls to the Scriptable interface needed in order to
- * manipulate properties in prototype chains.
- * <p>
- *
- * @see org.mozilla.javascript.ScriptableObject
- * @author Norris Boyd
- * @author Nick Thompson
- * @author Brendan Eich
- */
-
-public interface Scriptable {
-
- /**
- * Get the name of the set of objects implemented by this Java class.
- * This corresponds to the [[Class]] operation in ECMA and is used
- * by Object.prototype.toString() in ECMA.<p>
- * See ECMA 8.6.2 and 15.2.4.2.
- */
- public String getClassName();
-
- /**
- * Value returned from <code>get</code> if the property is not
- * found.
- */
- public static final Object NOT_FOUND = UniqueTag.NOT_FOUND;
-
- /**
- * Get a named property from the object.
- *
- * Looks property up in this object and returns the associated value
- * if found. Returns NOT_FOUND if not found.
- * Note that this method is not expected to traverse the prototype
- * chain. This is different from the ECMA [[Get]] operation.
- *
- * Depending on the property selector, the runtime will call
- * this method or the form of <code>get</code> that takes an
- * integer:
- * <table>
- * <tr><th>JavaScript code</th><th>Java code</th></tr>
- * <tr><td>a.b </td><td>a.get("b", a)</td></tr>
- * <tr><td>a["foo"] </td><td>a.get("foo", a)</td></tr>
- * <tr><td>a[3] </td><td>a.get(3, a)</td></tr>
- * <tr><td>a["3"] </td><td>a.get(3, a)</td></tr>
- * <tr><td>a[3.0] </td><td>a.get(3, a)</td></tr>
- * <tr><td>a["3.0"] </td><td>a.get("3.0", a)</td></tr>
- * <tr><td>a[1.1] </td><td>a.get("1.1", a)</td></tr>
- * <tr><td>a[-4] </td><td>a.get(-4, a)</td></tr>
- * </table>
- * <p>
- * The values that may be returned are limited to the following:
- * <UL>
- * <LI>java.lang.Boolean objects</LI>
- * <LI>java.lang.String objects</LI>
- * <LI>java.lang.Number objects</LI>
- * <LI>org.mozilla.javascript.Scriptable objects</LI>
- * <LI>null</LI>
- * <LI>The value returned by Context.getUndefinedValue()</LI>
- * <LI>NOT_FOUND</LI>
- * </UL>
- * @param name the name of the property
- * @param start the object in which the lookup began
- * @return the value of the property (may be null), or NOT_FOUND
- * @see org.mozilla.javascript.Context#getUndefinedValue
- */
- public Object get(String name, Scriptable start);
-
- /**
- * Get a property from the object selected by an integral index.
- *
- * Identical to <code>get(String, Scriptable)</code> except that
- * an integral index is used to select the property.
- *
- * @param index the numeric index for the property
- * @param start the object in which the lookup began
- * @return the value of the property (may be null), or NOT_FOUND
- * @see org.mozilla.javascript.Scriptable#get(String,Scriptable)
- */
- public Object get(int index, Scriptable start);
-
- /**
- * Indicates whether or not a named property is defined in an object.
- *
- * Does not traverse the prototype chain.<p>
- *
- * The property is specified by a String name
- * as defined for the <code>get</code> method.<p>
- *
- * @param name the name of the property
- * @param start the object in which the lookup began
- * @return true if and only if the named property is found in the object
- * @see org.mozilla.javascript.Scriptable#get(String, Scriptable)
- * @see org.mozilla.javascript.ScriptableObject#getProperty(Scriptable, String)
- */
- public boolean has(String name, Scriptable start);
-
- /**
- * Indicates whether or not an indexed property is defined in an object.
- *
- * Does not traverse the prototype chain.<p>
- *
- * The property is specified by an integral index
- * as defined for the <code>get</code> method.<p>
- *
- * @param index the numeric index for the property
- * @param start the object in which the lookup began
- * @return true if and only if the indexed property is found in the object
- * @see org.mozilla.javascript.Scriptable#get(int, Scriptable)
- * @see org.mozilla.javascript.ScriptableObject#getProperty(Scriptable, int)
- */
- public boolean has(int index, Scriptable start);
-
- /**
- * Sets a named property in this object.
- * <p>
- * The property is specified by a string name
- * as defined for <code>get</code>.
- * <p>
- * The possible values that may be passed in are as defined for
- * <code>get</code>. A class that implements this method may choose
- * to ignore calls to set certain properties, in which case those
- * properties are effectively read-only.<p>
- * For properties defined in a prototype chain,
- * use <code>putProperty</code> in ScriptableObject. <p>
- * Note that if a property <i>a</i> is defined in the prototype <i>p</i>
- * of an object <i>o</i>, then evaluating <code>o.a = 23</code> will cause
- * <code>set</code> to be called on the prototype <i>p</i> with
- * <i>o</i> as the <i>start</i> parameter.
- * To preserve JavaScript semantics, it is the Scriptable
- * object's responsibility to modify <i>o</i>. <p>
- * This design allows properties to be defined in prototypes and implemented
- * in terms of getters and setters of Java values without consuming slots
- * in each instance.<p>
- * <p>
- * The values that may be set are limited to the following:
- * <UL>
- * <LI>java.lang.Boolean objects</LI>
- * <LI>java.lang.String objects</LI>
- * <LI>java.lang.Number objects</LI>
- * <LI>org.mozilla.javascript.Scriptable objects</LI>
- * <LI>null</LI>
- * <LI>The value returned by Context.getUndefinedValue()</LI>
- * </UL><p>
- * Arbitrary Java objects may be wrapped in a Scriptable by first calling
- * <code>Context.toObject</code>. This allows the property of a JavaScript
- * object to contain an arbitrary Java object as a value.<p>
- * Note that <code>has</code> will be called by the runtime first before
- * <code>set</code> is called to determine in which object the
- * property is defined.
- * Note that this method is not expected to traverse the prototype chain,
- * which is different from the ECMA [[Put]] operation.
- * @param name the name of the property
- * @param start the object whose property is being set
- * @param value value to set the property to
- * @see org.mozilla.javascript.Scriptable#has(String, Scriptable)
- * @see org.mozilla.javascript.Scriptable#get(String, Scriptable)
- * @see org.mozilla.javascript.ScriptableObject#putProperty(Scriptable, String, Object)
- * @see org.mozilla.javascript.Context#toObject(Object, Scriptable)
- */
- public void put(String name, Scriptable start, Object value);
-
- /**
- * Sets an indexed property in this object.
- * <p>
- * The property is specified by an integral index
- * as defined for <code>get</code>.<p>
- *
- * Identical to <code>put(String, Scriptable, Object)</code> except that
- * an integral index is used to select the property.
- *
- * @param index the numeric index for the property
- * @param start the object whose property is being set
- * @param value value to set the property to
- * @see org.mozilla.javascript.Scriptable#has(int, Scriptable)
- * @see org.mozilla.javascript.Scriptable#get(int, Scriptable)
- * @see org.mozilla.javascript.ScriptableObject#putProperty(Scriptable, int, Object)
- * @see org.mozilla.javascript.Context#toObject(Object, Scriptable)
- */
- public void put(int index, Scriptable start, Object value);
-
- /**
- * Removes a property from this object.
- * This operation corresponds to the ECMA [[Delete]] except that
- * the no result is returned. The runtime will guarantee that this
- * method is called only if the property exists. After this method
- * is called, the runtime will call Scriptable.has to see if the
- * property has been removed in order to determine the boolean
- * result of the delete operator as defined by ECMA 11.4.1.
- * <p>
- * A property can be made permanent by ignoring calls to remove
- * it.<p>
- * The property is specified by a String name
- * as defined for <code>get</code>.
- * <p>
- * To delete properties defined in a prototype chain,
- * see deleteProperty in ScriptableObject.
- * @param name the identifier for the property
- * @see org.mozilla.javascript.Scriptable#get(String, Scriptable)
- * @see org.mozilla.javascript.ScriptableObject#deleteProperty(Scriptable, String)
- */
- public void delete(String name);
-
- /**
- * Removes a property from this object.
- *
- * The property is specified by an integral index
- * as defined for <code>get</code>.
- * <p>
- * To delete properties defined in a prototype chain,
- * see deleteProperty in ScriptableObject.
- *
- * Identical to <code>delete(String)</code> except that
- * an integral index is used to select the property.
- *
- * @param index the numeric index for the property
- * @see org.mozilla.javascript.Scriptable#get(int, Scriptable)
- * @see org.mozilla.javascript.ScriptableObject#deleteProperty(Scriptable, int)
- */
- public void delete(int index);
-
- /**
- * Get the prototype of the object.
- * @return the prototype
- */
- public Scriptable getPrototype();
-
- /**
- * Set the prototype of the object.
- * @param prototype the prototype to set
- */
- public void setPrototype(Scriptable prototype);
-
- /**
- * Get the parent scope of the object.
- * @return the parent scope
- */
- public Scriptable getParentScope();
-
- /**
- * Set the parent scope of the object.
- * @param parent the parent scope to set
- */
- public void setParentScope(Scriptable parent);
-
- /**
- * Get an array of property ids.
- *
- * Not all property ids need be returned. Those properties
- * whose ids are not returned are considered non-enumerable.
- *
- * @return an array of Objects. Each entry in the array is either
- * a java.lang.String or a java.lang.Number
- */
- public Object[] getIds();
-
- /**
- * Get the default value of the object with a given hint.
- * The hints are String.class for type String, Number.class for type
- * Number, Scriptable.class for type Object, and Boolean.class for
- * type Boolean. <p>
- *
- * A <code>hint</code> of null means "no hint".
- *
- * See ECMA 8.6.2.6.
- *
- * @param hint the type hint
- * @return the default value
- */
- public Object getDefaultValue(Class hint);
-
- /**
- * The instanceof operator.
- *
- * <p>
- * The JavaScript code "lhs instanceof rhs" causes rhs.hasInstance(lhs) to
- * be called.
- *
- * <p>
- * The return value is implementation dependent so that embedded host objects can
- * return an appropriate value. See the JS 1.3 language documentation for more
- * detail.
- *
- * <p>This operator corresponds to the proposed EMCA [[HasInstance]] operator.
- *
- * @param instance The value that appeared on the LHS of the instanceof
- * operator
- *
- * @return an implementation dependent value
- */
- public boolean hasInstance(Scriptable instance);
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptableObject.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptableObject.java
deleted file mode 100644
index 53de1fc..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptableObject.java
+++ /dev/null
@@ -1,2428 +0,0 @@
-/* -*- 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
- * Bob Jervis
- * Roger Lawrence
- * Steve Weiss
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-import java.lang.reflect.*;
-import java.util.Hashtable;
-import java.io.*;
-import org.mozilla.javascript.debug.DebuggableObject;
-
-/**
- * This is the default implementation of the Scriptable interface. This
- * class provides convenient default behavior that makes it easier to
- * define host objects.
- * <p>
- * Various properties and methods of JavaScript objects can be conveniently
- * defined using methods of ScriptableObject.
- * <p>
- * Classes extending ScriptableObject must define the getClassName method.
- *
- * @see org.mozilla.javascript.Scriptable
- * @author Norris Boyd
- */
-
-public abstract class ScriptableObject implements Scriptable, Serializable,
- DebuggableObject,
- ConstProperties
-{
-
- /**
- * The empty property attribute.
- *
- * Used by getAttributes() and setAttributes().
- *
- * @see org.mozilla.javascript.ScriptableObject#getAttributes(String)
- * @see org.mozilla.javascript.ScriptableObject#setAttributes(String, int)
- */
- public static final int EMPTY = 0x00;
-
- /**
- * Property attribute indicating assignment to this property is ignored.
- *
- * @see org.mozilla.javascript.ScriptableObject
- * #put(String, Scriptable, Object)
- * @see org.mozilla.javascript.ScriptableObject#getAttributes(String)
- * @see org.mozilla.javascript.ScriptableObject#setAttributes(String, int)
- */
- public static final int READONLY = 0x01;
-
- /**
- * Property attribute indicating property is not enumerated.
- *
- * Only enumerated properties will be returned by getIds().
- *
- * @see org.mozilla.javascript.ScriptableObject#getIds()
- * @see org.mozilla.javascript.ScriptableObject#getAttributes(String)
- * @see org.mozilla.javascript.ScriptableObject#setAttributes(String, int)
- */
- public static final int DONTENUM = 0x02;
-
- /**
- * Property attribute indicating property cannot be deleted.
- *
- * @see org.mozilla.javascript.ScriptableObject#delete(String)
- * @see org.mozilla.javascript.ScriptableObject#getAttributes(String)
- * @see org.mozilla.javascript.ScriptableObject#setAttributes(String, int)
- */
- public static final int PERMANENT = 0x04;
-
- /**
- * Property attribute indicating that this is a const property that has not
- * been assigned yet. The first 'const' assignment to the property will
- * clear this bit.
- */
- public static final int UNINITIALIZED_CONST = 0x08;
-
- public static final int CONST = PERMANENT|READONLY|UNINITIALIZED_CONST;
- /**
- * The prototype of this object.
- */
- private Scriptable prototypeObject;
-
- /**
- * The parent scope of this object.
- */
- private Scriptable parentScopeObject;
-
- private static final Slot REMOVED = new Slot(null, 0, READONLY);
-
- static {
- REMOVED.wasDeleted = 1;
- }
-
- private transient Slot[] slots;
- // If count >= 0, it gives number of keys or if count < 0,
- // it indicates sealed object where ~count gives number of keys
- private int count;
-
- // cache; may be removed for smaller memory footprint
- private transient Slot lastAccess = REMOVED;
-
- // associated values are not serialized
- private transient volatile Hashtable associatedValues;
-
- private static final int SLOT_QUERY = 1;
- private static final int SLOT_MODIFY = 2;
- private static final int SLOT_REMOVE = 3;
- private static final int SLOT_MODIFY_GETTER_SETTER = 4;
- private static final int SLOT_MODIFY_CONST = 5;
-
- private static class Slot implements Serializable
- {
- static final long serialVersionUID = -3539051633409902634L;
-
- String name; // This can change due to caching
- int indexOrHash;
- private volatile short attributes;
- transient volatile byte wasDeleted;
- volatile Object value;
- transient volatile Slot next;
-
- Slot(String name, int indexOrHash, int attributes)
- {
- this.name = name;
- this.indexOrHash = indexOrHash;
- this.attributes = (short)attributes;
- }
-
- private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- in.defaultReadObject();
- if (name != null) {
- indexOrHash = name.hashCode();
- }
- }
-
- final int getAttributes()
- {
- return attributes;
- }
-
- final synchronized void setAttributes(int value)
- {
- checkValidAttributes(value);
- attributes = (short)value;
- }
-
- final void checkNotReadonly()
- {
- if ((attributes & READONLY) != 0) {
- String str = (name != null ? name
- : Integer.toString(indexOrHash));
- throw Context.reportRuntimeError1("msg.modify.readonly", str);
- }
- }
-
- }
-
- private static final class GetterSlot extends Slot
- {
- static final long serialVersionUID = -4900574849788797588L;
-
- Object getter;
- Object setter;
-
- GetterSlot(String name, int indexOrHash, int attributes)
- {
- super(name, indexOrHash, attributes);
- }
- }
-
- static void checkValidAttributes(int attributes)
- {
- final int mask = READONLY | DONTENUM | PERMANENT | UNINITIALIZED_CONST;
- if ((attributes & ~mask) != 0) {
- throw new IllegalArgumentException(String.valueOf(attributes));
- }
- }
-
- public ScriptableObject()
- {
- }
-
- public ScriptableObject(Scriptable scope, Scriptable prototype)
- {
- if (scope == null)
- throw new IllegalArgumentException();
-
- parentScopeObject = scope;
- prototypeObject = prototype;
- }
-
- /**
- * Return the name of the class.
- *
- * This is typically the same name as the constructor.
- * Classes extending ScriptableObject must implement this abstract
- * method.
- */
- public abstract String getClassName();
-
- /**
- * Returns true if the named property is defined.
- *
- * @param name the name of the property
- * @param start the object in which the lookup began
- * @return true if and only if the property was found in the object
- */
- public boolean has(String name, Scriptable start)
- {
- return null != getSlot(name, 0, SLOT_QUERY);
- }
-
- /**
- * Returns true if the property index is defined.
- *
- * @param index the numeric index for the property
- * @param start the object in which the lookup began
- * @return true if and only if the property was found in the object
- */
- public boolean has(int index, Scriptable start)
- {
- return null != getSlot(null, index, SLOT_QUERY);
- }
-
- /**
- * Returns the value of the named property or NOT_FOUND.
- *
- * If the property was created using defineProperty, the
- * appropriate getter method is called.
- *
- * @param name the name of the property
- * @param start the object in which the lookup began
- * @return the value of the property (may be null), or NOT_FOUND
- */
- public Object get(String name, Scriptable start)
- {
- return getImpl(name, 0, start);
- }
-
- /**
- * Returns the value of the indexed property or NOT_FOUND.
- *
- * @param index the numeric index for the property
- * @param start the object in which the lookup began
- * @return the value of the property (may be null), or NOT_FOUND
- */
- public Object get(int index, Scriptable start)
- {
- return getImpl(null, index, start);
- }
-
- /**
- * Sets the value of the named property, creating it if need be.
- *
- * If the property was created using defineProperty, the
- * appropriate setter method is called. <p>
- *
- * If the property's attributes include READONLY, no action is
- * taken.
- * This method will actually set the property in the start
- * object.
- *
- * @param name the name of the property
- * @param start the object whose property is being set
- * @param value value to set the property to
- */
- public void put(String name, Scriptable start, Object value)
- {
- if (putImpl(name, 0, start, value, EMPTY))
- return;
-
- if (start == this) throw Kit.codeBug();
- start.put(name, start, value);
- }
-
- /**
- * Sets the value of the indexed property, creating it if need be.
- *
- * @param index the numeric index for the property
- * @param start the object whose property is being set
- * @param value value to set the property to
- */
- public void put(int index, Scriptable start, Object value)
- {
- if (putImpl(null, index, start, value, EMPTY))
- return;
-
- if (start == this) throw Kit.codeBug();
- start.put(index, start, value);
- }
-
- /**
- * Removes a named property from the object.
- *
- * If the property is not found, or it has the PERMANENT attribute,
- * no action is taken.
- *
- * @param name the name of the property
- */
- public void delete(String name)
- {
- checkNotSealed(name, 0);
- accessSlot(name, 0, SLOT_REMOVE);
- }
-
- /**
- * Removes the indexed property from the object.
- *
- * If the property is not found, or it has the PERMANENT attribute,
- * no action is taken.
- *
- * @param index the numeric index for the property
- */
- public void delete(int index)
- {
- checkNotSealed(null, index);
- accessSlot(null, index, SLOT_REMOVE);
- }
-
- /**
- * Sets the value of the named const property, creating it if need be.
- *
- * If the property was created using defineProperty, the
- * appropriate setter method is called. <p>
- *
- * If the property's attributes include READONLY, no action is
- * taken.
- * This method will actually set the property in the start
- * object.
- *
- * @param name the name of the property
- * @param start the object whose property is being set
- * @param value value to set the property to
- */
- public void putConst(String name, Scriptable start, Object value)
- {
- if (putImpl(name, 0, start, value, READONLY))
- return;
-
- if (start == this) throw Kit.codeBug();
- if (start instanceof ConstProperties)
- ((ConstProperties)start).putConst(name, start, value);
- else
- start.put(name, start, value);
- }
-
- public void defineConst(String name, Scriptable start)
- {
- if (putImpl(name, 0, start, Undefined.instance, UNINITIALIZED_CONST))
- return;
-
- if (start == this) throw Kit.codeBug();
- if (start instanceof ConstProperties)
- ((ConstProperties)start).defineConst(name, start);
- }
- /**
- * Returns true if the named property is defined as a const on this object.
- * @param name
- * @return true if the named property is defined as a const, false
- * otherwise.
- */
- public boolean isConst(String name)
- {
- Slot slot = getSlot(name, 0, SLOT_QUERY);
- if (slot == null) {
- return false;
- }
- return (slot.getAttributes() & (PERMANENT|READONLY)) ==
- (PERMANENT|READONLY);
-
- }
- /**
- * @deprecated Use {@link #getAttributes(String name)}. The engine always
- * ignored the start argument.
- */
- public final int getAttributes(String name, Scriptable start)
- {
- return getAttributes(name);
- }
-
- /**
- * @deprecated Use {@link #getAttributes(int index)}. The engine always
- * ignored the start argument.
- */
- public final int getAttributes(int index, Scriptable start)
- {
- return getAttributes(index);
- }
-
- /**
- * @deprecated Use {@link #setAttributes(String name, int attributes)}.
- * The engine always ignored the start argument.
- */
- public final void setAttributes(String name, Scriptable start,
- int attributes)
- {
- setAttributes(name, attributes);
- }
-
- /**
- * @deprecated Use {@link #setAttributes(int index, int attributes)}.
- * The engine always ignored the start argument.
- */
- public void setAttributes(int index, Scriptable start,
- int attributes)
- {
- setAttributes(index, attributes);
- }
-
- /**
- * Get the attributes of a named property.
- *
- * The property is specified by <code>name</code>
- * as defined for <code>has</code>.<p>
- *
- * @param name the identifier for the property
- * @return the bitset of attributes
- * @exception EvaluatorException if the named property is not found
- * @see org.mozilla.javascript.ScriptableObject#has(String, Scriptable)
- * @see org.mozilla.javascript.ScriptableObject#READONLY
- * @see org.mozilla.javascript.ScriptableObject#DONTENUM
- * @see org.mozilla.javascript.ScriptableObject#PERMANENT
- * @see org.mozilla.javascript.ScriptableObject#EMPTY
- */
- public int getAttributes(String name)
- {
- return findAttributeSlot(name, 0, SLOT_QUERY).getAttributes();
- }
-
- /**
- * Get the attributes of an indexed property.
- *
- * @param index the numeric index for the property
- * @exception EvaluatorException if the named property is not found
- * is not found
- * @return the bitset of attributes
- * @see org.mozilla.javascript.ScriptableObject#has(String, Scriptable)
- * @see org.mozilla.javascript.ScriptableObject#READONLY
- * @see org.mozilla.javascript.ScriptableObject#DONTENUM
- * @see org.mozilla.javascript.ScriptableObject#PERMANENT
- * @see org.mozilla.javascript.ScriptableObject#EMPTY
- */
- public int getAttributes(int index)
- {
- return findAttributeSlot(null, index, SLOT_QUERY).getAttributes();
- }
-
- /**
- * Set the attributes of a named property.
- *
- * The property is specified by <code>name</code>
- * as defined for <code>has</code>.<p>
- *
- * The possible attributes are READONLY, DONTENUM,
- * and PERMANENT. Combinations of attributes
- * are expressed by the bitwise OR of attributes.
- * EMPTY is the state of no attributes set. Any unused
- * bits are reserved for future use.
- *
- * @param name the name of the property
- * @param attributes the bitset of attributes
- * @exception EvaluatorException if the named property is not found
- * @see org.mozilla.javascript.Scriptable#has(String, Scriptable)
- * @see org.mozilla.javascript.ScriptableObject#READONLY
- * @see org.mozilla.javascript.ScriptableObject#DONTENUM
- * @see org.mozilla.javascript.ScriptableObject#PERMANENT
- * @see org.mozilla.javascript.ScriptableObject#EMPTY
- */
- public void setAttributes(String name, int attributes)
- {
- checkNotSealed(name, 0);
- findAttributeSlot(name, 0, SLOT_MODIFY).setAttributes(attributes);
- }
-
- /**
- * Set the attributes of an indexed property.
- *
- * @param index the numeric index for the property
- * @param attributes the bitset of attributes
- * @exception EvaluatorException if the named property is not found
- * @see org.mozilla.javascript.Scriptable#has(String, Scriptable)
- * @see org.mozilla.javascript.ScriptableObject#READONLY
- * @see org.mozilla.javascript.ScriptableObject#DONTENUM
- * @see org.mozilla.javascript.ScriptableObject#PERMANENT
- * @see org.mozilla.javascript.ScriptableObject#EMPTY
- */
- public void setAttributes(int index, int attributes)
- {
- checkNotSealed(null, index);
- findAttributeSlot(null, index, SLOT_MODIFY).setAttributes(attributes);
- }
-
- /**
- * XXX: write docs.
- */
- public void setGetterOrSetter(String name, int index,
- Callable getterOrSeter, boolean isSetter)
- {
- if (name != null && index != 0)
- throw new IllegalArgumentException(name);
-
- checkNotSealed(name, index);
- GetterSlot gslot = (GetterSlot)getSlot(name, index,
- SLOT_MODIFY_GETTER_SETTER);
- gslot.checkNotReadonly();
- if (isSetter) {
- gslot.setter = getterOrSeter;
- } else {
- gslot.getter = getterOrSeter;
- }
- gslot.value = Undefined.instance;
- }
-
- /**
- * Get the getter or setter for a given property. Used by __lookupGetter__
- * and __lookupSetter__.
- *
- * @param name Name of the object. If nonnull, index must be 0.
- * @param index Index of the object. If nonzero, name must be null.
- * @param isSetter If true, return the setter, otherwise return the getter.
- * @exception IllegalArgumentException if both name and index are nonnull
- * and nonzero respectively.
- * @return Null if the property does not exist. Otherwise returns either
- * the getter or the setter for the property, depending on
- * the value of isSetter (may be undefined if unset).
- */
- public Object getGetterOrSetter(String name, int index, boolean isSetter)
- {
- if (name != null && index != 0)
- throw new IllegalArgumentException(name);
- Slot slot = getSlot(name, index, SLOT_QUERY);
- if (slot == null)
- return null;
- if (slot instanceof GetterSlot) {
- GetterSlot gslot = (GetterSlot)slot;
- Object result = isSetter ? gslot.setter : gslot.getter;
- return result != null ? result : Undefined.instance;
- } else
- return Undefined.instance;
- }
-
- /**
- * Returns whether a property is a getter or a setter
- * @param name property name
- * @param index property index
- * @param setter true to check for a setter, false for a getter
- * @return whether the property is a getter or a setter
- */
- protected boolean isGetterOrSetter(String name, int index, boolean setter) {
- Slot slot = getSlot(name, index, SLOT_QUERY);
- if (slot instanceof GetterSlot) {
- if (setter && ((GetterSlot)slot).setter != null) return true;
- if (!setter && ((GetterSlot)slot).getter != null) return true;
- }
- return false;
- }
-
- void addLazilyInitializedValue(String name, int index,
- LazilyLoadedCtor init, int attributes)
- {
- if (name != null && index != 0)
- throw new IllegalArgumentException(name);
- checkNotSealed(name, index);
- GetterSlot gslot = (GetterSlot)getSlot(name, index,
- SLOT_MODIFY_GETTER_SETTER);
- gslot.setAttributes(attributes);
- gslot.getter = null;
- gslot.setter = null;
- gslot.value = init;
- }
-
- /**
- * Returns the prototype of the object.
- */
- public Scriptable getPrototype()
- {
- return prototypeObject;
- }
-
- /**
- * Sets the prototype of the object.
- */
- public void setPrototype(Scriptable m)
- {
- prototypeObject = m;
- }
-
- /**
- * Returns the parent (enclosing) scope of the object.
- */
- public Scriptable getParentScope()
- {
- return parentScopeObject;
- }
-
- /**
- * Sets the parent (enclosing) scope of the object.
- */
- public void setParentScope(Scriptable m)
- {
- parentScopeObject = m;
- }
-
- /**
- * Returns an array of ids for the properties of the object.
- *
- * <p>Any properties with the attribute DONTENUM are not listed. <p>
- *
- * @return an array of java.lang.Objects with an entry for every
- * listed property. Properties accessed via an integer index will
- * have a corresponding
- * Integer entry in the returned array. Properties accessed by
- * a String will have a String entry in the returned array.
- */
- public Object[] getIds() {
- return getIds(false);
- }
-
- /**
- * Returns an array of ids for the properties of the object.
- *
- * <p>All properties, even those with attribute DONTENUM, are listed. <p>
- *
- * @return an array of java.lang.Objects with an entry for every
- * listed property. Properties accessed via an integer index will
- * have a corresponding
- * Integer entry in the returned array. Properties accessed by
- * a String will have a String entry in the returned array.
- */
- public Object[] getAllIds() {
- return getIds(true);
- }
-
- /**
- * Implements the [[DefaultValue]] internal method.
- *
- * <p>Note that the toPrimitive conversion is a no-op for
- * every type other than Object, for which [[DefaultValue]]
- * is called. See ECMA 9.1.<p>
- *
- * A <code>hint</code> of null means "no hint".
- *
- * @param typeHint the type hint
- * @return the default value for the object
- *
- * See ECMA 8.6.2.6.
- */
- public Object getDefaultValue(Class typeHint)
- {
- return getDefaultValue(this, typeHint);
- }
-
- public static Object getDefaultValue(Scriptable object, Class typeHint)
- {
- Context cx = null;
- for (int i=0; i < 2; i++) {
- boolean tryToString;
- if (typeHint == ScriptRuntime.StringClass) {
- tryToString = (i == 0);
- } else {
- tryToString = (i == 1);
- }
-
- String methodName;
- Object[] args;
- if (tryToString) {
- methodName = "toString";
- args = ScriptRuntime.emptyArgs;
- } else {
- methodName = "valueOf";
- args = new Object[1];
- String hint;
- if (typeHint == null) {
- hint = "undefined";
- } else if (typeHint == ScriptRuntime.StringClass) {
- hint = "string";
- } else if (typeHint == ScriptRuntime.ScriptableClass) {
- hint = "object";
- } else if (typeHint == ScriptRuntime.FunctionClass) {
- hint = "function";
- } else if (typeHint == ScriptRuntime.BooleanClass
- || typeHint == Boolean.TYPE)
- {
- hint = "boolean";
- } else if (typeHint == ScriptRuntime.NumberClass ||
- typeHint == ScriptRuntime.ByteClass ||
- typeHint == Byte.TYPE ||
- typeHint == ScriptRuntime.ShortClass ||
- typeHint == Short.TYPE ||
- typeHint == ScriptRuntime.IntegerClass ||
- typeHint == Integer.TYPE ||
- typeHint == ScriptRuntime.FloatClass ||
- typeHint == Float.TYPE ||
- typeHint == ScriptRuntime.DoubleClass ||
- typeHint == Double.TYPE)
- {
- hint = "number";
- } else {
- throw Context.reportRuntimeError1(
- "msg.invalid.type", typeHint.toString());
- }
- args[0] = hint;
- }
- Object v = getProperty(object, methodName);
- if (!(v instanceof Function))
- continue;
- Function fun = (Function) v;
- if (cx == null)
- cx = Context.getContext();
- v = fun.call(cx, fun.getParentScope(), object, args);
- if (v != null) {
- if (!(v instanceof Scriptable)) {
- return v;
- }
- if (typeHint == ScriptRuntime.ScriptableClass
- || typeHint == ScriptRuntime.FunctionClass)
- {
- return v;
- }
- if (tryToString && v instanceof Wrapper) {
- // Let a wrapped java.lang.String pass for a primitive
- // string.
- Object u = ((Wrapper)v).unwrap();
- if (u instanceof String)
- return u;
- }
- }
- }
- // fall through to error
- String arg = (typeHint == null) ? "undefined" : typeHint.getName();
- throw ScriptRuntime.typeError1("msg.default.value", arg);
- }
-
- /**
- * Implements the instanceof operator.
- *
- * <p>This operator has been proposed to ECMA.
- *
- * @param instance The value that appeared on the LHS of the instanceof
- * operator
- * @return true if "this" appears in value's prototype chain
- *
- */
- public boolean hasInstance(Scriptable instance) {
- // Default for JS objects (other than Function) is to do prototype
- // chasing. This will be overridden in NativeFunction and non-JS
- // objects.
-
- return ScriptRuntime.jsDelegatesTo(instance, this);
- }
-
- /**
- * Emulate the SpiderMonkey (and Firefox) feature of allowing
- * custom objects to avoid detection by normal "object detection"
- * code patterns. This is used to implement document.all.
- * See https://bugzilla.mozilla.org/show_bug.cgi?id=412247.
- * This is an analog to JOF_DETECTING from SpiderMonkey; see
- * https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
- * Other than this special case, embeddings should return false.
- * @return true if this object should avoid object detection
- * @since 1.7R1
- */
- public boolean avoidObjectDetection() {
- return false;
- }
-
- /**
- * Custom <tt>==</tt> operator.
- * Must return {@link Scriptable#NOT_FOUND} if this object does not
- * have custom equality operator for the given value,
- * <tt>Boolean.TRUE</tt> if this object is equivalent to <tt>value</tt>,
- * <tt>Boolean.FALSE</tt> if this object is not equivalent to
- * <tt>value</tt>.
- * <p>
- * The default implementation returns Boolean.TRUE
- * if <tt>this == value</tt> or {@link Scriptable#NOT_FOUND} otherwise.
- * It indicates that by default custom equality is available only if
- * <tt>value</tt> is <tt>this</tt> in which case true is returned.
- */
- protected Object equivalentValues(Object value)
- {
- return (this == value) ? Boolean.TRUE : Scriptable.NOT_FOUND;
- }
-
- /**
- * Defines JavaScript objects from a Java class that implements Scriptable.
- *
- * If the given class has a method
- * <pre>
- * static void init(Context cx, Scriptable scope, boolean sealed);</pre>
- *
- * or its compatibility form
- * <pre>
- * static void init(Scriptable scope);</pre>
- *
- * then it is invoked and no further initialization is done.<p>
- *
- * However, if no such a method is found, then the class's constructors and
- * methods are used to initialize a class in the following manner.<p>
- *
- * First, the zero-parameter constructor of the class is called to
- * create the prototype. If no such constructor exists,
- * a {@link EvaluatorException} is thrown. <p>
- *
- * Next, all methods are scanned for special prefixes that indicate that they
- * have special meaning for defining JavaScript objects.
- * These special prefixes are
- * <ul>
- * <li><code>jsFunction_</code> for a JavaScript function
- * <li><code>jsStaticFunction_</code> for a JavaScript function that
- * is a property of the constructor
- * <li><code>jsGet_</code> for a getter of a JavaScript property
- * <li><code>jsSet_</code> for a setter of a JavaScript property
- * <li><code>jsConstructor</code> for a JavaScript function that
- * is the constructor
- * </ul><p>
- *
- * If the method's name begins with "jsFunction_", a JavaScript function
- * is created with a name formed from the rest of the Java method name
- * following "jsFunction_". So a Java method named "jsFunction_foo" will
- * define a JavaScript method "foo". Calling this JavaScript function
- * will cause the Java method to be called. The parameters of the method
- * must be of number and types as defined by the FunctionObject class.
- * The JavaScript function is then added as a property
- * of the prototype. <p>
- *
- * If the method's name begins with "jsStaticFunction_", it is handled
- * similarly except that the resulting JavaScript function is added as a
- * property of the constructor object. The Java method must be static.
- *
- * If the method's name begins with "jsGet_" or "jsSet_", the method is
- * considered to define a property. Accesses to the defined property
- * will result in calls to these getter and setter methods. If no
- * setter is defined, the property is defined as READONLY.<p>
- *
- * If the method's name is "jsConstructor", the method is
- * considered to define the body of the constructor. Only one
- * method of this name may be defined.
- * If no method is found that can serve as constructor, a Java
- * constructor will be selected to serve as the JavaScript
- * constructor in the following manner. If the class has only one
- * Java constructor, that constructor is used to define
- * the JavaScript constructor. If the the class has two constructors,
- * one must be the zero-argument constructor (otherwise an
- * {@link EvaluatorException} would have already been thrown
- * when the prototype was to be created). In this case
- * the Java constructor with one or more parameters will be used
- * to define the JavaScript constructor. If the class has three
- * or more constructors, an {@link EvaluatorException}
- * will be thrown.<p>
- *
- * Finally, if there is a method
- * <pre>
- * static void finishInit(Scriptable scope, FunctionObject constructor,
- * Scriptable prototype)</pre>
- *
- * it will be called to finish any initialization. The <code>scope</code>
- * argument will be passed, along with the newly created constructor and
- * the newly created prototype.<p>
- *
- * @param scope The scope in which to define the constructor.
- * @param clazz The Java class to use to define the JavaScript objects
- * and properties.
- * @exception IllegalAccessException if access is not available
- * to a reflected class member
- * @exception InstantiationException if unable to instantiate
- * the named class
- * @exception InvocationTargetException if an exception is thrown
- * during execution of methods of the named class
- * @see org.mozilla.javascript.Function
- * @see org.mozilla.javascript.FunctionObject
- * @see org.mozilla.javascript.ScriptableObject#READONLY
- * @see org.mozilla.javascript.ScriptableObject
- * #defineProperty(String, Class, int)
- */
- public static void defineClass(Scriptable scope, Class clazz)
- throws IllegalAccessException, InstantiationException,
- InvocationTargetException
- {
- defineClass(scope, clazz, false, false);
- }
-
- /**
- * Defines JavaScript objects from a Java class, optionally
- * allowing sealing.
- *
- * Similar to <code>defineClass(Scriptable scope, Class clazz)</code>
- * except that sealing is allowed. An object that is sealed cannot have
- * properties added or removed. Note that sealing is not allowed in
- * the current ECMA/ISO language specification, but is likely for
- * the next version.
- *
- * @param scope The scope in which to define the constructor.
- * @param clazz The Java class to use to define the JavaScript objects
- * and properties. The class must implement Scriptable.
- * @param sealed Whether or not to create sealed standard objects that
- * cannot be modified.
- * @exception IllegalAccessException if access is not available
- * to a reflected class member
- * @exception InstantiationException if unable to instantiate
- * the named class
- * @exception InvocationTargetException if an exception is thrown
- * during execution of methods of the named class
- * @since 1.4R3
- */
- public static void defineClass(Scriptable scope, Class clazz,
- boolean sealed)
- throws IllegalAccessException, InstantiationException,
- InvocationTargetException
- {
- defineClass(scope, clazz, sealed, false);
- }
-
- /**
- * Defines JavaScript objects from a Java class, optionally
- * allowing sealing and mapping of Java inheritance to JavaScript
- * prototype-based inheritance.
- *
- * Similar to <code>defineClass(Scriptable scope, Class clazz)</code>
- * except that sealing and inheritance mapping are allowed. An object
- * that is sealed cannot have properties added or removed. Note that
- * sealing is not allowed in the current ECMA/ISO language specification,
- * but is likely for the next version.
- *
- * @param scope The scope in which to define the constructor.
- * @param clazz The Java class to use to define the JavaScript objects
- * and properties. The class must implement Scriptable.
- * @param sealed Whether or not to create sealed standard objects that
- * cannot be modified.
- * @param mapInheritance Whether or not to map Java inheritance to
- * JavaScript prototype-based inheritance.
- * @return the class name for the prototype of the specified class
- * @exception IllegalAccessException if access is not available
- * to a reflected class member
- * @exception InstantiationException if unable to instantiate
- * the named class
- * @exception InvocationTargetException if an exception is thrown
- * during execution of methods of the named class
- * @since 1.6R2
- */
- public static String defineClass(Scriptable scope, Class clazz,
- boolean sealed, boolean mapInheritance)
- throws IllegalAccessException, InstantiationException,
- InvocationTargetException
- {
- BaseFunction ctor = buildClassCtor(scope, clazz, sealed,
- mapInheritance);
- if (ctor == null)
- return null;
- String name = ctor.getClassPrototype().getClassName();
- defineProperty(scope, name, ctor, ScriptableObject.DONTENUM);
- return name;
- }
-
- static BaseFunction buildClassCtor(Scriptable scope, Class clazz,
- boolean sealed,
- boolean mapInheritance)
- throws IllegalAccessException, InstantiationException,
- InvocationTargetException
- {
- Method[] methods = FunctionObject.getMethodList(clazz);
- for (int i=0; i < methods.length; i++) {
- Method method = methods[i];
- if (!method.getName().equals("init"))
- continue;
- Class[] parmTypes = method.getParameterTypes();
- if (parmTypes.length == 3 &&
- parmTypes[0] == ScriptRuntime.ContextClass &&
- parmTypes[1] == ScriptRuntime.ScriptableClass &&
- parmTypes[2] == Boolean.TYPE &&
- Modifier.isStatic(method.getModifiers()))
- {
- Object args[] = { Context.getContext(), scope,
- sealed ? Boolean.TRUE : Boolean.FALSE };
- method.invoke(null, args);
- return null;
- }
- if (parmTypes.length == 1 &&
- parmTypes[0] == ScriptRuntime.ScriptableClass &&
- Modifier.isStatic(method.getModifiers()))
- {
- Object args[] = { scope };
- method.invoke(null, args);
- return null;
- }
-
- }
-
- // If we got here, there isn't an "init" method with the right
- // parameter types.
-
- Constructor[] ctors = clazz.getConstructors();
- Constructor protoCtor = null;
- for (int i=0; i < ctors.length; i++) {
- if (ctors[i].getParameterTypes().length == 0) {
- protoCtor = ctors[i];
- break;
- }
- }
- if (protoCtor == null) {
- throw Context.reportRuntimeError1(
- "msg.zero.arg.ctor", clazz.getName());
- }
-
- Scriptable proto = (Scriptable) protoCtor.newInstance(ScriptRuntime.emptyArgs);
- String className = proto.getClassName();
-
- // Set the prototype's prototype, trying to map Java inheritance to JS
- // prototype-based inheritance if requested to do so.
- Scriptable superProto = null;
- if (mapInheritance) {
- Class superClass = clazz.getSuperclass();
- if (ScriptRuntime.ScriptableClass.isAssignableFrom(superClass)
- && !Modifier.isAbstract(superClass.getModifiers())) {
- String name = ScriptableObject.defineClass(scope, superClass, sealed, mapInheritance);
- if (name != null) {
- superProto = ScriptableObject.getClassPrototype(scope, name);
- }
- }
- }
- if (superProto == null) {
- superProto = ScriptableObject.getObjectPrototype(scope);
- }
- proto.setPrototype(superProto);
-
- // Find out whether there are any methods that begin with
- // "js". If so, then only methods that begin with special
- // prefixes will be defined as JavaScript entities.
- final String functionPrefix = "jsFunction_";
- final String staticFunctionPrefix = "jsStaticFunction_";
- final String getterPrefix = "jsGet_";
- final String setterPrefix = "jsSet_";
- final String ctorName = "jsConstructor";
-
- Member ctorMember = FunctionObject.findSingleMethod(methods, ctorName);
-
- if (ctorMember == null) {
- if (ctors.length == 1) {
- ctorMember = ctors[0];
- } else if (ctors.length == 2) {
- if (ctors[0].getParameterTypes().length == 0)
- ctorMember = ctors[1];
- else if (ctors[1].getParameterTypes().length == 0)
- ctorMember = ctors[0];
- }
- if (ctorMember == null) {
- throw Context.reportRuntimeError1(
- "msg.ctor.multiple.parms", clazz.getName());
- }
- }
-
- FunctionObject ctor = new FunctionObject(className, ctorMember, scope);
- if (ctor.isVarArgsMethod()) {
- throw Context.reportRuntimeError1
- ("msg.varargs.ctor", ctorMember.getName());
- }
- ctor.initAsConstructor(scope, proto);
-
- Method finishInit = null;
- for (int i=0; i < methods.length; i++) {
- if (methods[i] == ctorMember) {
- continue;
- }
- String name = methods[i].getName();
- if (name.equals("finishInit")) {
- Class[] parmTypes = methods[i].getParameterTypes();
- if (parmTypes.length == 3 &&
- parmTypes[0] == ScriptRuntime.ScriptableClass &&
- parmTypes[1] == FunctionObject.class &&
- parmTypes[2] == ScriptRuntime.ScriptableClass &&
- Modifier.isStatic(methods[i].getModifiers()))
- {
- finishInit = methods[i];
- continue;
- }
- }
- // ignore any compiler generated methods.
- if (name.indexOf('$') != -1)
- continue;
- if (name.equals(ctorName))
- continue;
-
- String prefix = null;
- if (name.startsWith(functionPrefix)) {
- prefix = functionPrefix;
- } else if (name.startsWith(staticFunctionPrefix)) {
- prefix = staticFunctionPrefix;
- if (!Modifier.isStatic(methods[i].getModifiers())) {
- throw Context.reportRuntimeError(
- "jsStaticFunction must be used with static method.");
- }
- } else if (name.startsWith(getterPrefix)) {
- prefix = getterPrefix;
- } else if (name.startsWith(setterPrefix)) {
- prefix = setterPrefix;
- } else {
- continue;
- }
- name = name.substring(prefix.length());
- if (prefix == setterPrefix)
- continue; // deal with set when we see get
- if (prefix == getterPrefix) {
- if (!(proto instanceof ScriptableObject)) {
- throw Context.reportRuntimeError2(
- "msg.extend.scriptable",
- proto.getClass().toString(), name);
- }
- Method setter = FunctionObject.findSingleMethod(
- methods,
- setterPrefix + name);
- int attr = ScriptableObject.PERMANENT |
- ScriptableObject.DONTENUM |
- (setter != null ? 0
- : ScriptableObject.READONLY);
- ((ScriptableObject) proto).defineProperty(name, null,
- methods[i], setter,
- attr);
- continue;
- }
-
- FunctionObject f = new FunctionObject(name, methods[i], proto);
- if (f.isVarArgsConstructor()) {
- throw Context.reportRuntimeError1
- ("msg.varargs.fun", ctorMember.getName());
- }
- Scriptable dest = prefix == staticFunctionPrefix
- ? ctor
- : proto;
- defineProperty(dest, name, f, DONTENUM);
- if (sealed) {
- f.sealObject();
- }
- }
-
- // Call user code to complete initialization if necessary.
- if (finishInit != null) {
- Object[] finishArgs = { scope, ctor, proto };
- finishInit.invoke(null, finishArgs);
- }
-
- // Seal the object if necessary.
- if (sealed) {
- ctor.sealObject();
- if (proto instanceof ScriptableObject) {
- ((ScriptableObject) proto).sealObject();
- }
- }
-
- return ctor;
- }
-
- /**
- * Define a JavaScript property.
- *
- * Creates the property with an initial value and sets its attributes.
- *
- * @param propertyName the name of the property to define.
- * @param value the initial value of the property
- * @param attributes the attributes of the JavaScript property
- * @see org.mozilla.javascript.Scriptable#put(String, Scriptable, Object)
- */
- public void defineProperty(String propertyName, Object value,
- int attributes)
- {
- checkNotSealed(propertyName, 0);
- put(propertyName, this, value);
- setAttributes(propertyName, attributes);
- }
-
- /**
- * Utility method to add properties to arbitrary Scriptable object.
- * If destination is instance of ScriptableObject, calls
- * defineProperty there, otherwise calls put in destination
- * ignoring attributes
- */
- public static void defineProperty(Scriptable destination,
- String propertyName, Object value,
- int attributes)
- {
- if (!(destination instanceof ScriptableObject)) {
- destination.put(propertyName, destination, value);
- return;
- }
- ScriptableObject so = (ScriptableObject)destination;
- so.defineProperty(propertyName, value, attributes);
- }
-
- /**
- * Utility method to add properties to arbitrary Scriptable object.
- * If destination is instance of ScriptableObject, calls
- * defineProperty there, otherwise calls put in destination
- * ignoring attributes
- */
- public static void defineConstProperty(Scriptable destination,
- String propertyName)
- {
- if (destination instanceof ConstProperties) {
- ConstProperties cp = (ConstProperties)destination;
- cp.defineConst(propertyName, destination);
- } else
- defineProperty(destination, propertyName, Undefined.instance, CONST);
- }
-
- /**
- * Define a JavaScript property with getter and setter side effects.
- *
- * If the setter is not found, the attribute READONLY is added to
- * the given attributes. <p>
- *
- * The getter must be a method with zero parameters, and the setter, if
- * found, must be a method with one parameter.<p>
- *
- * @param propertyName the name of the property to define. This name
- * also affects the name of the setter and getter
- * to search for. If the propertyId is "foo", then
- * <code>clazz</code> will be searched for "getFoo"
- * and "setFoo" methods.
- * @param clazz the Java class to search for the getter and setter
- * @param attributes the attributes of the JavaScript property
- * @see org.mozilla.javascript.Scriptable#put(String, Scriptable, Object)
- */
- public void defineProperty(String propertyName, Class clazz,
- int attributes)
- {
- int length = propertyName.length();
- if (length == 0) throw new IllegalArgumentException();
- char[] buf = new char[3 + length];
- propertyName.getChars(0, length, buf, 3);
- buf[3] = Character.toUpperCase(buf[3]);
- buf[0] = 'g';
- buf[1] = 'e';
- buf[2] = 't';
- String getterName = new String(buf);
- buf[0] = 's';
- String setterName = new String(buf);
-
- Method[] methods = FunctionObject.getMethodList(clazz);
- Method getter = FunctionObject.findSingleMethod(methods, getterName);
- Method setter = FunctionObject.findSingleMethod(methods, setterName);
- if (setter == null)
- attributes |= ScriptableObject.READONLY;
- defineProperty(propertyName, null, getter,
- setter == null ? null : setter, attributes);
- }
-
- /**
- * Define a JavaScript property.
- *
- * Use this method only if you wish to define getters and setters for
- * a given property in a ScriptableObject. To create a property without
- * special getter or setter side effects, use
- * <code>defineProperty(String,int)</code>.
- *
- * If <code>setter</code> is null, the attribute READONLY is added to
- * the given attributes.<p>
- *
- * Several forms of getters or setters are allowed. In all cases the
- * type of the value parameter can be any one of the following types:
- * Object, String, boolean, Scriptable, byte, short, int, long, float,
- * or double. The runtime will perform appropriate conversions based
- * upon the type of the parameter (see description in FunctionObject).
- * The first forms are nonstatic methods of the class referred to
- * by 'this':
- * <pre>
- * Object getFoo();
- * void setFoo(SomeType value);</pre>
- * Next are static methods that may be of any class; the object whose
- * property is being accessed is passed in as an extra argument:
- * <pre>
- * static Object getFoo(Scriptable obj);
- * static void setFoo(Scriptable obj, SomeType value);</pre>
- * Finally, it is possible to delegate to another object entirely using
- * the <code>delegateTo</code> parameter. In this case the methods are
- * nonstatic methods of the class delegated to, and the object whose
- * property is being accessed is passed in as an extra argument:
- * <pre>
- * Object getFoo(Scriptable obj);
- * void setFoo(Scriptable obj, SomeType value);</pre>
- *
- * @param propertyName the name of the property to define.
- * @param delegateTo an object to call the getter and setter methods on,
- * or null, depending on the form used above.
- * @param getter the method to invoke to get the value of the property
- * @param setter the method to invoke to set the value of the property
- * @param attributes the attributes of the JavaScript property
- */
- public void defineProperty(String propertyName, Object delegateTo,
- Method getter, Method setter, int attributes)
- {
- MemberBox getterBox = null;
- if (getter != null) {
- getterBox = new MemberBox(getter);
-
- boolean delegatedForm;
- if (!Modifier.isStatic(getter.getModifiers())) {
- delegatedForm = (delegateTo != null);
- getterBox.delegateTo = delegateTo;
- } else {
- delegatedForm = true;
- // Ignore delegateTo for static getter but store
- // non-null delegateTo indicator.
- getterBox.delegateTo = Void.TYPE;
- }
-
- String errorId = null;
- Class[] parmTypes = getter.getParameterTypes();
- if (parmTypes.length == 0) {
- if (delegatedForm) {
- errorId = "msg.obj.getter.parms";
- }
- } else if (parmTypes.length == 1) {
- Object argType = parmTypes[0];
- // Allow ScriptableObject for compatibility
- if (!(argType == ScriptRuntime.ScriptableClass ||
- argType == ScriptRuntime.ScriptableObjectClass))
- {
- errorId = "msg.bad.getter.parms";
- } else if (!delegatedForm) {
- errorId = "msg.bad.getter.parms";
- }
- } else {
- errorId = "msg.bad.getter.parms";
- }
- if (errorId != null) {
- throw Context.reportRuntimeError1(errorId, getter.toString());
- }
- }
-
- MemberBox setterBox = null;
- if (setter != null) {
- if (setter.getReturnType() != Void.TYPE)
- throw Context.reportRuntimeError1("msg.setter.return",
- setter.toString());
-
- setterBox = new MemberBox(setter);
-
- boolean delegatedForm;
- if (!Modifier.isStatic(setter.getModifiers())) {
- delegatedForm = (delegateTo != null);
- setterBox.delegateTo = delegateTo;
- } else {
- delegatedForm = true;
- // Ignore delegateTo for static setter but store
- // non-null delegateTo indicator.
- setterBox.delegateTo = Void.TYPE;
- }
-
- String errorId = null;
- Class[] parmTypes = setter.getParameterTypes();
- if (parmTypes.length == 1) {
- if (delegatedForm) {
- errorId = "msg.setter2.expected";
- }
- } else if (parmTypes.length == 2) {
- Object argType = parmTypes[0];
- // Allow ScriptableObject for compatibility
- if (!(argType == ScriptRuntime.ScriptableClass ||
- argType == ScriptRuntime.ScriptableObjectClass))
- {
- errorId = "msg.setter2.parms";
- } else if (!delegatedForm) {
- errorId = "msg.setter1.parms";
- }
- } else {
- errorId = "msg.setter.parms";
- }
- if (errorId != null) {
- throw Context.reportRuntimeError1(errorId, setter.toString());
- }
- }
-
- GetterSlot gslot = (GetterSlot)getSlot(propertyName, 0,
- SLOT_MODIFY_GETTER_SETTER);
- gslot.setAttributes(attributes);
- gslot.getter = getterBox;
- gslot.setter = setterBox;
- }
-
- /**
- * Search for names in a class, adding the resulting methods
- * as properties.
- *
- * <p> Uses reflection to find the methods of the given names. Then
- * FunctionObjects are constructed from the methods found, and
- * are added to this object as properties with the given names.
- *
- * @param names the names of the Methods to add as function properties
- * @param clazz the class to search for the Methods
- * @param attributes the attributes of the new properties
- * @see org.mozilla.javascript.FunctionObject
- */
- public void defineFunctionProperties(String[] names, Class clazz,
- int attributes)
- {
- Method[] methods = FunctionObject.getMethodList(clazz);
- for (int i=0; i < names.length; i++) {
- String name = names[i];
- Method m = FunctionObject.findSingleMethod(methods, name);
- if (m == null) {
- throw Context.reportRuntimeError2(
- "msg.method.not.found", name, clazz.getName());
- }
- FunctionObject f = new FunctionObject(name, m, this);
- defineProperty(name, f, attributes);
- }
- }
-
- /**
- * Get the Object.prototype property.
- * See ECMA 15.2.4.
- */
- public static Scriptable getObjectPrototype(Scriptable scope) {
- return getClassPrototype(scope, "Object");
- }
-
- /**
- * Get the Function.prototype property.
- * See ECMA 15.3.4.
- */
- public static Scriptable getFunctionPrototype(Scriptable scope) {
- return getClassPrototype(scope, "Function");
- }
-
- /**
- * Get the prototype for the named class.
- *
- * For example, <code>getClassPrototype(s, "Date")</code> will first
- * walk up the parent chain to find the outermost scope, then will
- * search that scope for the Date constructor, and then will
- * return Date.prototype. If any of the lookups fail, or
- * the prototype is not a JavaScript object, then null will
- * be returned.
- *
- * @param scope an object in the scope chain
- * @param className the name of the constructor
- * @return the prototype for the named class, or null if it
- * cannot be found.
- */
- public static Scriptable getClassPrototype(Scriptable scope,
- String className)
- {
- scope = getTopLevelScope(scope);
- Object ctor = getProperty(scope, className);
- Object proto;
- if (ctor instanceof BaseFunction) {
- proto = ((BaseFunction)ctor).getPrototypeProperty();
- } else if (ctor instanceof Scriptable) {
- Scriptable ctorObj = (Scriptable)ctor;
- proto = ctorObj.get("prototype", ctorObj);
- } else {
- return null;
- }
- if (proto instanceof Scriptable) {
- return (Scriptable)proto;
- }
- return null;
- }
-
- /**
- * Get the global scope.
- *
- * <p>Walks the parent scope chain to find an object with a null
- * parent scope (the global object).
- *
- * @param obj a JavaScript object
- * @return the corresponding global scope
- */
- public static Scriptable getTopLevelScope(Scriptable obj)
- {
- for (;;) {
- Scriptable parent = obj.getParentScope();
- if (parent == null) {
- return obj;
- }
- obj = parent;
- }
- }
-
- // APPJET
- public static Scriptable getVeryTopLevelScope(Scriptable obj) {
- return ScriptRuntime.getLibraryScopeOrNull(obj);
- }
-
- /**
- * Seal this object.
- *
- * A sealed object may not have properties added or removed. Once
- * an object is sealed it may not be unsealed.
- *
- * @since 1.4R3
- */
- public synchronized void sealObject() {
- if (count >= 0) {
- count = ~count;
- }
- }
-
- /**
- * Return true if this object is sealed.
- *
- * It is an error to attempt to add or remove properties to
- * a sealed object.
- *
- * @return true if sealed, false otherwise.
- * @since 1.4R3
- */
- public final boolean isSealed() {
- return count < 0;
- }
-
- private void checkNotSealed(String name, int index)
- {
- if (!isSealed())
- return;
-
- String str = (name != null) ? name : Integer.toString(index);
- throw Context.reportRuntimeError1("msg.modify.sealed", str);
- }
-
- /**
- * Gets a named property from an object or any object in its prototype chain.
- * <p>
- * Searches the prototype chain for a property named <code>name</code>.
- * <p>
- * @param obj a JavaScript object
- * @param name a property name
- * @return the value of a property with name <code>name</code> found in
- * <code>obj</code> or any object in its prototype chain, or
- * <code>Scriptable.NOT_FOUND</code> if not found
- * @since 1.5R2
- */
- public static Object getProperty(Scriptable obj, String name)
- {
- Scriptable start = obj;
- Object result;
- do {
- result = obj.get(name, start);
- if (result != Scriptable.NOT_FOUND)
- break;
- obj = obj.getPrototype();
- } while (obj != null);
- return result;
- }
-
- /**
- * Gets an indexed property from an object or any object in its prototype chain.
- * <p>
- * Searches the prototype chain for a property with integral index
- * <code>index</code>. Note that if you wish to look for properties with numerical
- * but non-integral indicies, you should use getProperty(Scriptable,String) with
- * the string value of the index.
- * <p>
- * @param obj a JavaScript object
- * @param index an integral index
- * @return the value of a property with index <code>index</code> found in
- * <code>obj</code> or any object in its prototype chain, or
- * <code>Scriptable.NOT_FOUND</code> if not found
- * @since 1.5R2
- */
- public static Object getProperty(Scriptable obj, int index)
- {
- Scriptable start = obj;
- Object result;
- do {
- result = obj.get(index, start);
- if (result != Scriptable.NOT_FOUND)
- break;
- obj = obj.getPrototype();
- } while (obj != null);
- return result;
- }
-
- /**
- * Returns whether a named property is defined in an object or any object
- * in its prototype chain.
- * <p>
- * Searches the prototype chain for a property named <code>name</code>.
- * <p>
- * @param obj a JavaScript object
- * @param name a property name
- * @return the true if property was found
- * @since 1.5R2
- */
- public static boolean hasProperty(Scriptable obj, String name)
- {
- return null != getBase(obj, name);
- }
-
- /**
- * If hasProperty(obj, name) would return true, then if the property that
- * was found is compatible with the new property, this method just returns.
- * If the property is not compatible, then an exception is thrown.
- *
- * A property redefinition is incompatible if the first definition was a
- * const declaration or if this one is. They are compatible only if neither
- * was const.
- */
- public static void redefineProperty(Scriptable obj, String name,
- boolean isConst)
- {
- Scriptable base = getBase(obj, name);
- if (base == null)
- return;
- if (base instanceof ConstProperties) {
- ConstProperties cp = (ConstProperties)base;
-
- if (cp.isConst(name))
- throw Context.reportRuntimeError1("msg.const.redecl", name);
- }
- if (isConst)
- throw Context.reportRuntimeError1("msg.var.redecl", name);
- }
- /**
- * Returns whether an indexed property is defined in an object or any object
- * in its prototype chain.
- * <p>
- * Searches the prototype chain for a property with index <code>index</code>.
- * <p>
- * @param obj a JavaScript object
- * @param index a property index
- * @return the true if property was found
- * @since 1.5R2
- */
- public static boolean hasProperty(Scriptable obj, int index)
- {
- return null != getBase(obj, index);
- }
-
- /**
- * Puts a named property in an object or in an object in its prototype chain.
- * <p>
- * Searches for the named property in the prototype chain. If it is found,
- * the value of the property in <code>obj</code> is changed through a call
- * to {@link Scriptable#put(String, Scriptable, Object)} on the
- * prototype passing <code>obj</code> as the <code>start</code> argument.
- * This allows the prototype to veto the property setting in case the
- * prototype defines the property with [[ReadOnly]] attribute. If the
- * property is not found, it is added in <code>obj</code>.
- * @param obj a JavaScript object
- * @param name a property name
- * @param value any JavaScript value accepted by Scriptable.put
- * @since 1.5R2
- */
- public static void putProperty(Scriptable obj, String name, Object value)
- {
- Scriptable base = getBase(obj, name);
- if (base == null)
- base = obj;
- base.put(name, obj, value);
- }
-
- /**
- * Puts a named property in an object or in an object in its prototype chain.
- * <p>
- * Searches for the named property in the prototype chain. If it is found,
- * the value of the property in <code>obj</code> is changed through a call
- * to {@link Scriptable#put(String, Scriptable, Object)} on the
- * prototype passing <code>obj</code> as the <code>start</code> argument.
- * This allows the prototype to veto the property setting in case the
- * prototype defines the property with [[ReadOnly]] attribute. If the
- * property is not found, it is added in <code>obj</code>.
- * @param obj a JavaScript object
- * @param name a property name
- * @param value any JavaScript value accepted by Scriptable.put
- * @since 1.5R2
- */
- public static void putConstProperty(Scriptable obj, String name, Object value)
- {
- Scriptable base = getBase(obj, name);
- if (base == null)
- base = obj;
- if (base instanceof ConstProperties)
- ((ConstProperties)base).putConst(name, obj, value);
- }
-
- /**
- * Puts an indexed property in an object or in an object in its prototype chain.
- * <p>
- * Searches for the indexed property in the prototype chain. If it is found,
- * the value of the property in <code>obj</code> is changed through a call
- * to {@link Scriptable#put(int, Scriptable, Object)} on the prototype
- * passing <code>obj</code> as the <code>start</code> argument. This allows
- * the prototype to veto the property setting in case the prototype defines
- * the property with [[ReadOnly]] attribute. If the property is not found,
- * it is added in <code>obj</code>.
- * @param obj a JavaScript object
- * @param index a property index
- * @param value any JavaScript value accepted by Scriptable.put
- * @since 1.5R2
- */
- public static void putProperty(Scriptable obj, int index, Object value)
- {
- Scriptable base = getBase(obj, index);
- if (base == null)
- base = obj;
- base.put(index, obj, value);
- }
-
- /**
- * Removes the property from an object or its prototype chain.
- * <p>
- * Searches for a property with <code>name</code> in obj or
- * its prototype chain. If it is found, the object's delete
- * method is called.
- * @param obj a JavaScript object
- * @param name a property name
- * @return true if the property doesn't exist or was successfully removed
- * @since 1.5R2
- */
- public static boolean deleteProperty(Scriptable obj, String name)
- {
- Scriptable base = getBase(obj, name);
- if (base == null)
- return true;
- base.delete(name);
- return !base.has(name, obj);
- }
-
- /**
- * Removes the property from an object or its prototype chain.
- * <p>
- * Searches for a property with <code>index</code> in obj or
- * its prototype chain. If it is found, the object's delete
- * method is called.
- * @param obj a JavaScript object
- * @param index a property index
- * @return true if the property doesn't exist or was successfully removed
- * @since 1.5R2
- */
- public static boolean deleteProperty(Scriptable obj, int index)
- {
- Scriptable base = getBase(obj, index);
- if (base == null)
- return true;
- base.delete(index);
- return !base.has(index, obj);
- }
-
- /**
- * Returns an array of all ids from an object and its prototypes.
- * <p>
- * @param obj a JavaScript object
- * @return an array of all ids from all object in the prototype chain.
- * If a given id occurs multiple times in the prototype chain,
- * it will occur only once in this list.
- * @since 1.5R2
- */
- public static Object[] getPropertyIds(Scriptable obj)
- {
- if (obj == null) {
- return ScriptRuntime.emptyArgs;
- }
- Object[] result = obj.getIds();
- ObjToIntMap map = null;
- for (;;) {
- obj = obj.getPrototype();
- if (obj == null) {
- break;
- }
- Object[] ids = obj.getIds();
- if (ids.length == 0) {
- continue;
- }
- if (map == null) {
- if (result.length == 0) {
- result = ids;
- continue;
- }
- map = new ObjToIntMap(result.length + ids.length);
- for (int i = 0; i != result.length; ++i) {
- map.intern(result[i]);
- }
- result = null; // Allow to GC the result
- }
- for (int i = 0; i != ids.length; ++i) {
- map.intern(ids[i]);
- }
- }
- if (map != null) {
- result = map.getKeys();
- }
- return result;
- }
-
- /**
- * Call a method of an object.
- * @param obj the JavaScript object
- * @param methodName the name of the function property
- * @param args the arguments for the call
- *
- * @see Context#getCurrentContext()
- */
- public static Object callMethod(Scriptable obj, String methodName,
- Object[] args)
- {
- return callMethod(null, obj, methodName, args);
- }
-
- /**
- * Call a method of an object.
- * @param cx the Context object associated with the current thread.
- * @param obj the JavaScript object
- * @param methodName the name of the function property
- * @param args the arguments for the call
- */
- public static Object callMethod(Context cx, Scriptable obj,
- String methodName,
- Object[] args)
- {
- Object funObj = getProperty(obj, methodName);
- if (!(funObj instanceof Function)) {
- throw ScriptRuntime.notFunctionError(obj, methodName);
- }
- Function fun = (Function)funObj;
- // XXX: What should be the scope when calling funObj?
- // The following favor scope stored in the object on the assumption
- // that is more useful especially under dynamic scope setup.
- // An alternative is to check for dynamic scope flag
- // and use ScriptableObject.getTopLevelScope(fun) if the flag is not
- // set. But that require access to Context and messy code
- // so for now it is not checked.
- Scriptable scope = ScriptableObject.getTopLevelScope(obj);
- if (cx != null) {
- return fun.call(cx, scope, obj, args);
- } else {
- return Context.call(null, fun, scope, obj, args);
- }
- }
-
- private static Scriptable getBase(Scriptable obj, String name)
- {
- do {
- if (obj.has(name, obj))
- break;
- obj = obj.getPrototype();
- } while(obj != null);
- return obj;
- }
-
- private static Scriptable getBase(Scriptable obj, int index)
- {
- do {
- if (obj.has(index, obj))
- break;
- obj = obj.getPrototype();
- } while(obj != null);
- return obj;
- }
-
- /**
- * Get arbitrary application-specific value associated with this object.
- * @param key key object to select particular value.
- * @see #associateValue(Object key, Object value)
- */
- public final Object getAssociatedValue(Object key)
- {
- Hashtable h = associatedValues;
- if (h == null)
- return null;
- return h.get(key);
- }
-
- /**
- * Get arbitrary application-specific value associated with the top scope
- * of the given scope.
- * The method first calls {@link #getTopLevelScope(Scriptable scope)}
- * and then searches the prototype chain of the top scope for the first
- * object containing the associated value with the given key.
- *
- * @param scope the starting scope.
- * @param key key object to select particular value.
- * @see #getAssociatedValue(Object key)
- */
- public static Object getTopScopeValue(Scriptable scope, Object key)
- {
- scope = ScriptableObject.getTopLevelScope(scope);
- for (;;) {
- if (scope instanceof ScriptableObject) {
- ScriptableObject so = (ScriptableObject)scope;
- Object value = so.getAssociatedValue(key);
- if (value != null) {
- return value;
- }
- }
- scope = scope.getPrototype();
- if (scope == null) {
- return null;
- }
- }
- }
-
- /**
- * Associate arbitrary application-specific value with this object.
- * Value can only be associated with the given object and key only once.
- * The method ignores any subsequent attempts to change the already
- * associated value.
- * <p> The associated values are not serialized.
- * @param key key object to select particular value.
- * @param value the value to associate
- * @return the passed value if the method is called first time for the
- * given key or old value for any subsequent calls.
- * @see #getAssociatedValue(Object key)
- */
- public final Object associateValue(Object key, Object value)
- {
- if (value == null) throw new IllegalArgumentException();
- Hashtable h = associatedValues;
- if (h == null) {
- synchronized (this) {
- h = associatedValues;
- if (h == null) {
- h = new Hashtable();
- associatedValues = h;
- }
- }
- }
- return Kit.initHash(h, key, value);
- }
-
- private Object getImpl(String name, int index, Scriptable start)
- {
- Slot slot = getSlot(name, index, SLOT_QUERY);
- if (slot == null) {
- return Scriptable.NOT_FOUND;
- }
- if (!(slot instanceof GetterSlot)) {
- return slot.value;
- }
- Object getterObj = ((GetterSlot)slot).getter;
- if (getterObj != null) {
- if (getterObj instanceof MemberBox) {
- MemberBox nativeGetter = (MemberBox)getterObj;
- Object getterThis;
- Object[] args;
- if (nativeGetter.delegateTo == null) {
- getterThis = start;
- args = ScriptRuntime.emptyArgs;
- } else {
- getterThis = nativeGetter.delegateTo;
- args = new Object[] { start };
- }
- return nativeGetter.invoke(getterThis, args);
- } else {
- Function f = (Function)getterObj;
- Context cx = Context.getContext();
- return f.call(cx, f.getParentScope(), start,
- ScriptRuntime.emptyArgs);
- }
- }
- Object value = slot.value;
- if (value instanceof LazilyLoadedCtor) {
- LazilyLoadedCtor initializer = (LazilyLoadedCtor)value;
- try {
- initializer.init();
- } finally {
- value = initializer.getValue();
- slot.value = value;
- }
- }
- return value;
- }
-
- /**
- *
- * @param name
- * @param index
- * @param start
- * @param value
- * @param constFlag EMPTY means normal put. UNINITIALIZED_CONST means
- * defineConstProperty. READONLY means const initialization expression.
- * @return false if this != start and no slot was found. true if this == start
- * or this != start and a READONLY slot was found.
- */
- private boolean putImpl(String name, int index, Scriptable start,
- Object value, int constFlag)
- {
- Slot slot;
- if (this != start) {
- slot = getSlot(name, index, SLOT_QUERY);
- if (slot == null) {
- return false;
- }
- } else {
- checkNotSealed(name, index);
- // either const hoisted declaration or initialization
- if (constFlag != EMPTY) {
- slot = getSlot(name, index, SLOT_MODIFY_CONST);
- int attr = slot.getAttributes();
- if ((attr & READONLY) == 0)
- throw Context.reportRuntimeError1("msg.var.redecl", name);
- if ((attr & UNINITIALIZED_CONST) != 0) {
- slot.value = value;
- // clear the bit on const initialization
- if (constFlag != UNINITIALIZED_CONST)
- slot.setAttributes(attr & ~UNINITIALIZED_CONST);
- }
- return true;
- }
- slot = getSlot(name, index, SLOT_MODIFY);
- }
- if ((slot.getAttributes() & READONLY) != 0)
- return true;
- if (slot instanceof GetterSlot) {
- Object setterObj = ((GetterSlot)slot).setter;
- if (setterObj != null) {
- Context cx = Context.getContext();
- if (setterObj instanceof MemberBox) {
- MemberBox nativeSetter = (MemberBox)setterObj;
- Class pTypes[] = nativeSetter.argTypes;
- // XXX: cache tag since it is already calculated in
- // defineProperty ?
- Class valueType = pTypes[pTypes.length - 1];
- int tag = FunctionObject.getTypeTag(valueType);
- Object actualArg = FunctionObject.convertArg(cx, start,
- value, tag);
- Object setterThis;
- Object[] args;
- if (nativeSetter.delegateTo == null) {
- setterThis = start;
- args = new Object[] { actualArg };
- } else {
- setterThis = nativeSetter.delegateTo;
- args = new Object[] { start, actualArg };
- }
- nativeSetter.invoke(setterThis, args);
- } else {
- Function f = (Function)setterObj;
- f.call(cx, f.getParentScope(), start,
- new Object[] { value });
- }
- return true;
- }
- }
- if (this == start) {
- slot.value = value;
- return true;
- } else {
- return false;
- }
- }
-
- private Slot findAttributeSlot(String name, int index, int accessType)
- {
- Slot slot = getSlot(name, index, accessType);
- if (slot == null) {
- String str = (name != null ? name : Integer.toString(index));
- throw Context.reportRuntimeError1("msg.prop.not.found", str);
- }
- return slot;
- }
-
- /**
- * Locate the slot with given name or index.
- *
- * @param name property name or null if slot holds spare array index.
- * @param index index or 0 if slot holds property name.
- */
- private Slot getSlot(String name, int index, int accessType)
- {
- Slot slot;
-
- // Query last access cache and check that it was not deleted.
- lastAccessCheck:
- {
- slot = lastAccess;
- if (name != null) {
- if (name != slot.name)
- break lastAccessCheck;
- // No String.equals here as successful slot search update
- // name object with fresh reference of the same string.
- } else {
- if (slot.name != null || index != slot.indexOrHash)
- break lastAccessCheck;
- }
-
- if (slot.wasDeleted != 0)
- break lastAccessCheck;
-
- if (accessType == SLOT_MODIFY_GETTER_SETTER &&
- !(slot instanceof GetterSlot))
- break lastAccessCheck;
-
- return slot;
- }
-
- slot = accessSlot(name, index, accessType);
- if (slot != null) {
- // Update the cache
- lastAccess = slot;
- }
- return slot;
- }
-
- private Slot accessSlot(String name, int index, int accessType)
- {
- int indexOrHash = (name != null ? name.hashCode() : index);
-
- if (accessType == SLOT_QUERY ||
- accessType == SLOT_MODIFY ||
- accessType == SLOT_MODIFY_CONST ||
- accessType == SLOT_MODIFY_GETTER_SETTER)
- {
- // Check the hashtable without using synchronization
-
- Slot[] slotsLocalRef = slots; // Get stable local reference
- if (slotsLocalRef == null) {
- if (accessType == SLOT_QUERY)
- return null;
- } else {
- int tableSize = slotsLocalRef.length;
- int slotIndex = getSlotIndex(tableSize, indexOrHash);
- Slot slot = slotsLocalRef[slotIndex];
- while (slot != null) {
- String sname = slot.name;
- if (sname != null) {
- if (sname == name)
- break;
- if (name != null && indexOrHash == slot.indexOrHash) {
- if (name.equals(sname)) {
- // This will avoid calling String.equals when
- // slot is accessed with same string object
- // next time.
- slot.name = name;
- break;
- }
- }
- } else if (name == null &&
- indexOrHash == slot.indexOrHash) {
- break;
- }
- slot = slot.next;
- }
- if (accessType == SLOT_QUERY) {
- return slot;
- } else if (accessType == SLOT_MODIFY) {
- if (slot != null)
- return slot;
- } else if (accessType == SLOT_MODIFY_GETTER_SETTER) {
- if (slot instanceof GetterSlot)
- return slot;
- } else if (accessType == SLOT_MODIFY_CONST) {
- if (slot != null)
- return slot;
- }
- }
-
- // A new slot has to be inserted or the old has to be replaced
- // by GetterSlot. Time to synchronize.
-
- synchronized (this) {
- // Refresh local ref if another thread triggered grow
- slotsLocalRef = slots;
- int insertPos;
- if (count == 0) {
- // Always throw away old slots if any on empty insert
- slotsLocalRef = new Slot[5];
- slots = slotsLocalRef;
- insertPos = getSlotIndex(slotsLocalRef.length, indexOrHash);
- } else {
- int tableSize = slotsLocalRef.length;
- insertPos = getSlotIndex(tableSize, indexOrHash);
- Slot prev = slotsLocalRef[insertPos];
- Slot slot = prev;
- while (slot != null) {
- if (slot.indexOrHash == indexOrHash &&
- (slot.name == name ||
- (name != null && name.equals(slot.name))))
- {
- break;
- }
- prev = slot;
- slot = slot.next;
- }
-
- if (slot != null) {
- // Another thread just added a slot with same
- // name/index before this one entered synchronized
- // block. This is a race in application code and
- // probably indicates bug there. But for the hashtable
- // implementation it is harmless with the only
- // complication is the need to replace the added slot
- // if we need GetterSlot and the old one is not.
- if (accessType == SLOT_MODIFY_GETTER_SETTER &&
- !(slot instanceof GetterSlot))
- {
- GetterSlot newSlot = new GetterSlot(name, indexOrHash,
- slot.getAttributes());
- newSlot.value = slot.value;
- newSlot.next = slot.next;
- if (prev == slot) {
- slotsLocalRef[insertPos] = newSlot;
- } else {
- prev.next = newSlot;
- }
- slot.wasDeleted = (byte)1;
- if (slot == lastAccess) {
- lastAccess = REMOVED;
- }
- slot = newSlot;
- } else if (accessType == SLOT_MODIFY_CONST) {
- return null;
- }
- return slot;
- }
-
- // Check if the table is not too full before inserting.
- if (4 * (count + 1) > 3 * slotsLocalRef.length) {
- slotsLocalRef = new Slot[slotsLocalRef.length * 2 + 1];
- copyTable(slots, slotsLocalRef, count);
- slots = slotsLocalRef;
- insertPos = getSlotIndex(slotsLocalRef.length,
- indexOrHash);
- }
- }
-
- Slot newSlot = (accessType == SLOT_MODIFY_GETTER_SETTER
- ? new GetterSlot(name, indexOrHash, 0)
- : new Slot(name, indexOrHash, 0));
- if (accessType == SLOT_MODIFY_CONST)
- newSlot.setAttributes(CONST);
- ++count;
- addKnownAbsentSlot(slotsLocalRef, newSlot, insertPos);
- return newSlot;
- }
-
- } else if (accessType == SLOT_REMOVE) {
- synchronized (this) {
- Slot[] slotsLocalRef = slots;
- if (count != 0) {
- int tableSize = slots.length;
- int slotIndex = getSlotIndex(tableSize, indexOrHash);
- Slot prev = slotsLocalRef[slotIndex];
- Slot slot = prev;
- while (slot != null) {
- if (slot.indexOrHash == indexOrHash &&
- (slot.name == name ||
- (name != null && name.equals(slot.name))))
- {
- break;
- }
- prev = slot;
- slot = slot.next;
- }
- if (slot != null && (slot.getAttributes() & PERMANENT) == 0) {
- count--;
- if (prev == slot) {
- slotsLocalRef[slotIndex] = slot.next;
- } else {
- prev.next = slot.next;
- }
- // Mark the slot as removed to handle a case when
- // another thread manages to put just removed slot
- // into lastAccess cache.
- slot.wasDeleted = (byte)1;
- if (slot == lastAccess) {
- lastAccess = REMOVED;
- }
- }
- }
- }
- return null;
-
- } else {
- throw Kit.codeBug();
- }
- }
-
- private static int getSlotIndex(int tableSize, int indexOrHash)
- {
- return (indexOrHash & 0x7fffffff) % tableSize;
- }
-
- // Must be inside synchronized (this)
- private static void copyTable(Slot[] slots, Slot[] newSlots, int count)
- {
- if (count == 0) throw Kit.codeBug();
-
- int tableSize = newSlots.length;
- int i = slots.length;
- for (;;) {
- --i;
- Slot slot = slots[i];
- while (slot != null) {
- int insertPos = getSlotIndex(tableSize, slot.indexOrHash);
- Slot next = slot.next;
- addKnownAbsentSlot(newSlots, slot, insertPos);
- slot.next = null;
- slot = next;
- if (--count == 0)
- return;
- }
- }
- }
-
- /**
- * Add slot with keys that are known to absent from the table.
- * This is an optimization to use when inserting into empty table,
- * after table growth or during deserialization.
- */
- private static void addKnownAbsentSlot(Slot[] slots, Slot slot, int insertPos)
- {
- if (slots[insertPos] == null) {
- slots[insertPos] = slot;
- } else {
- Slot prev = slots[insertPos];
- while (prev.next != null) {
- prev = prev.next;
- }
- prev.next = slot;
- }
- }
-
- Object[] getIds(boolean getAll) {
- Slot[] s = slots;
- Object[] a = ScriptRuntime.emptyArgs;
- if (s == null)
- return a;
- int c = 0;
- for (int i=0; i < s.length; i++) {
- Slot slot = s[i];
- while (slot != null) {
- if (getAll || (slot.getAttributes() & DONTENUM) == 0) {
- if (c == 0)
- a = new Object[s.length];
- a[c++] = (slot.name != null ? (Object) slot.name
- : new Integer(slot.indexOrHash));
- }
- slot = slot.next;
- }
- }
- if (c == a.length)
- return a;
- Object[] result = new Object[c];
- System.arraycopy(a, 0, result, 0, c);
- return result;
- }
-
- private synchronized void writeObject(ObjectOutputStream out)
- throws IOException
- {
- out.defaultWriteObject();
- int objectsCount = count;
- if (objectsCount < 0) {
- // "this" was sealed
- objectsCount = ~objectsCount;
- }
- if (objectsCount == 0) {
- out.writeInt(0);
- } else {
- out.writeInt(slots.length);
- for (int i = 0; i < slots.length; ++i) {
- Slot slot = slots[i];
- while (slot != null) {
- out.writeObject(slot);
- slot = slot.next;
- if (--objectsCount == 0)
- return;
- }
- }
- }
- }
-
- private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- in.defaultReadObject();
- lastAccess = REMOVED;
-
- int tableSize = in.readInt();
- if (tableSize != 0) {
- slots = new Slot[tableSize];
- int objectsCount = count;
- if (objectsCount < 0) {
- // "this" was sealed
- objectsCount = ~objectsCount;
- }
- for (int i = 0; i != objectsCount; ++i) {
- Slot slot = (Slot)in.readObject();
- int slotIndex = getSlotIndex(tableSize, slot.indexOrHash);
- addKnownAbsentSlot(slots, slot, slotIndex);
- }
- }
- }
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecureCaller.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecureCaller.java
deleted file mode 100644
index bc8ed86..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecureCaller.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/* ***** 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):
- *
- * 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;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.UndeclaredThrowableException;
-import java.net.URL;
-import java.security.AccessController;
-import java.security.CodeSource;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.security.SecureClassLoader;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-/**
- * @author Attila Szegedi
- */
-public abstract class SecureCaller
-{
- private static final byte[] secureCallerImplBytecode = loadBytecode();
-
- // We're storing a CodeSource -> (ClassLoader -> SecureRenderer), since we
- // need to have one renderer per class loader. We're using weak hash maps
- // and soft references all the way, since we don't want to interfere with
- // cleanup of either CodeSource or ClassLoader objects.
- private static final Map callers = new WeakHashMap();
-
- public abstract Object call(Callable callable, Context cx,
- Scriptable scope, Scriptable thisObj, Object[] args);
-
- /**
- * Call the specified callable using a protection domain belonging to the
- * specified code source.
- */
- static Object callSecurely(final CodeSource codeSource, Callable callable,
- Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
- {
- final Thread thread = Thread.currentThread();
- // Run in doPrivileged as we might be checked for "getClassLoader"
- // runtime permission
- final ClassLoader classLoader = (ClassLoader)AccessController.doPrivileged(
- new PrivilegedAction() {
- public Object run() {
- return thread.getContextClassLoader();
- }
- });
- Map classLoaderMap;
- synchronized(callers)
- {
- classLoaderMap = (Map)callers.get(codeSource);
- if(classLoaderMap == null)
- {
- classLoaderMap = new WeakHashMap();
- callers.put(codeSource, classLoaderMap);
- }
- }
- SecureCaller caller;
- synchronized(classLoaderMap)
- {
- SoftReference ref = (SoftReference)classLoaderMap.get(classLoader);
- if(ref != null)
- {
- caller = (SecureCaller)ref.get();
- }
- else
- {
- caller = null;
- }
- if(caller == null)
- {
- try
- {
- // Run in doPrivileged as we'll be checked for
- // "createClassLoader" runtime permission
- caller = (SecureCaller)AccessController.doPrivileged(
- new PrivilegedExceptionAction()
- {
- public Object run() throws Exception
- {
- ClassLoader effectiveClassLoader;
- Class thisClass = getClass();
- if(classLoader.loadClass(thisClass.getName()) != thisClass) {
- effectiveClassLoader = thisClass.getClassLoader();
- } else {
- effectiveClassLoader = classLoader;
- }
- SecureClassLoaderImpl secCl =
- new SecureClassLoaderImpl(effectiveClassLoader);
- Class c = secCl.defineAndLinkClass(
- SecureCaller.class.getName() + "Impl",
- secureCallerImplBytecode, codeSource);
- return c.newInstance();
- }
- });
- classLoaderMap.put(classLoader, new SoftReference(caller));
- }
- catch(PrivilegedActionException ex)
- {
- throw new UndeclaredThrowableException(ex.getCause());
- }
- }
- }
- return caller.call(callable, cx, scope, thisObj, args);
- }
-
- private static class SecureClassLoaderImpl extends SecureClassLoader
- {
- SecureClassLoaderImpl(ClassLoader parent)
- {
- super(parent);
- }
-
- Class defineAndLinkClass(String name, byte[] bytes, CodeSource cs)
- {
- Class cl = defineClass(name, bytes, 0, bytes.length, cs);
- resolveClass(cl);
- return cl;
- }
- }
-
- private static byte[] loadBytecode()
- {
- return (byte[])AccessController.doPrivileged(new PrivilegedAction()
- {
- public Object run()
- {
- return loadBytecodePrivileged();
- }
- });
- }
-
- private static byte[] loadBytecodePrivileged()
- {
- URL url = SecureCaller.class.getResource("SecureCallerImpl.clazz");
- try
- {
- InputStream in = url.openStream();
- try
- {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- for(;;)
- {
- int r = in.read();
- if(r == -1)
- {
- return bout.toByteArray();
- }
- bout.write(r);
- }
- }
- finally
- {
- in.close();
- }
- }
- catch(IOException e)
- {
- throw new UndeclaredThrowableException(e);
- }
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityController.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityController.java
deleted file mode 100644
index ed85dbf..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityController.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/* -*- 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * This class describes the support needed to implement security.
- * <p>
- * Three main pieces of functionality are required to implement
- * security for JavaScript. First, it must be possible to define
- * classes with an associated security domain. (This security
- * domain may be any object incorporating notion of access
- * restrictions that has meaning to an embedding; for a client-side
- * JavaScript embedding this would typically be
- * java.security.ProtectionDomain or similar object depending on an
- * origin URL and/or a digital certificate.)
- * Next it must be possible to get a security domain object that
- * allows a particular action only if all security domains
- * associated with code on the current Java stack allows it. And
- * finally, it must be possible to execute script code with
- * associated security domain injected into Java stack.
- * <p>
- * These three pieces of functionality are encapsulated in the
- * SecurityController class.
- *
- * @see org.mozilla.javascript.Context#setSecurityController(SecurityController)
- * @see java.lang.ClassLoader
- * @since 1.5 Release 4
- */
-public abstract class SecurityController
-{
- private static SecurityController global;
-
-// The method must NOT be public or protected
- static SecurityController global()
- {
- return global;
- }
-
- /**
- * Check if global {@link SecurityController} was already installed.
- * @see #initGlobal(SecurityController controller)
- */
- public static boolean hasGlobal()
- {
- return global != null;
- }
-
- /**
- * Initialize global controller that will be used for all
- * security-related operations. The global controller takes precedence
- * over already installed {@link Context}-specific controllers and cause
- * any subsequent call to
- * {@link Context#setSecurityController(SecurityController)}
- * to throw an exception.
- * <p>
- * The method can only be called once.
- *
- * @see #hasGlobal()
- */
- public static void initGlobal(SecurityController controller)
- {
- if (controller == null) throw new IllegalArgumentException();
- if (global != null) {
- throw new SecurityException("Cannot overwrite already installed global SecurityController");
- }
- global = controller;
- }
-
- /**
- * Get class loader-like object that can be used
- * to define classes with the given security context.
- * @param parentLoader parent class loader to delegate search for classes
- * not defined by the class loader itself
- * @param securityDomain some object specifying the security
- * context of the code that is defined by the returned class loader.
- */
- public abstract GeneratedClassLoader createClassLoader(
- ClassLoader parentLoader, Object securityDomain);
-
- /**
- * Create {@link GeneratedClassLoader} with restrictions imposed by
- * staticDomain and all current stack frames.
- * The method uses the SecurityController instance associated with the
- * current {@link Context} to construct proper dynamic domain and create
- * corresponding class loader.
- * <par>
- * If no SecurityController is associated with the current {@link Context} ,
- * the method calls {@link Context#createClassLoader(ClassLoader parent)}.
- *
- * @param parent parent class loader. If null,
- * {@link Context#getApplicationClassLoader()} will be used.
- * @param staticDomain static security domain.
- */
- public static GeneratedClassLoader createLoader(
- ClassLoader parent, Object staticDomain)
- {
- Context cx = Context.getContext();
- if (parent == null) {
- parent = cx.getApplicationClassLoader();
- }
- SecurityController sc = cx.getSecurityController();
- GeneratedClassLoader loader;
- if (sc == null) {
- loader = cx.createClassLoader(parent);
- } else {
- Object dynamicDomain = sc.getDynamicSecurityDomain(staticDomain);
- loader = sc.createClassLoader(parent, dynamicDomain);
- }
- return loader;
- }
-
- public static Class getStaticSecurityDomainClass() {
- SecurityController sc = Context.getContext().getSecurityController();
- return sc == null ? null : sc.getStaticSecurityDomainClassInternal();
- }
-
- public Class getStaticSecurityDomainClassInternal()
- {
- return null;
- }
-
- /**
- * Get dynamic security domain that allows an action only if it is allowed
- * by the current Java stack and <i>securityDomain</i>. If
- * <i>securityDomain</i> is null, return domain representing permissions
- * allowed by the current stack.
- */
- public abstract Object getDynamicSecurityDomain(Object securityDomain);
-
- /**
- * Call {@link
- * Callable#call(Context cx, Scriptable scope, Scriptable thisObj,
- * Object[] args)}
- * of <i>callable</i> under restricted security domain where an action is
- * allowed only if it is allowed according to the Java stack on the
- * moment of the <i>execWithDomain</i> call and <i>securityDomain</i>.
- * Any call to {@link #getDynamicSecurityDomain(Object)} during
- * execution of <tt>callable.call(cx, scope, thisObj, args)</tt>
- * should return a domain incorporate restrictions imposed by
- * <i>securityDomain</i> and Java stack on the moment of callWithDomain
- * invocation.
- * <p>
- * The method should always be overridden, it is not declared abstract
- * for compatibility reasons.
- */
- public Object callWithDomain(Object securityDomain, Context cx,
- final Callable callable, Scriptable scope,
- final Scriptable thisObj, final Object[] args)
- {
- return execWithDomain(cx, scope, new Script()
- {
- public Object exec(Context cx, Scriptable scope)
- {
- return callable.call(cx, scope, thisObj, args);
- }
-
- }, securityDomain);
- }
-
- /**
- * @deprecated The application should not override this method and instead
- * override
- * {@link #callWithDomain(Object securityDomain, Context cx, Callable callable, Scriptable scope, Scriptable thisObj, Object[] args)}.
- */
- public Object execWithDomain(Context cx, Scriptable scope,
- Script script, Object securityDomain)
- {
- throw new IllegalStateException("callWithDomain should be overridden");
- }
-
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityUtilities.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityUtilities.java
deleted file mode 100644
index 275ad92..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityUtilities.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- 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;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.ProtectionDomain;
-
-/**
- * @author Attila Szegedi
- */
-public class SecurityUtilities
-{
- /**
- * Retrieves a system property within a privileged block. Use it only when
- * the property is used from within Rhino code and is not passed out of it.
- * @param name the name of the system property
- * @return the value of the system property
- */
- public static String getSystemProperty(final String name)
- {
- return (String)AccessController.doPrivileged(
- new PrivilegedAction()
- {
- public Object run()
- {
- return System.getProperty(name);
- }
- });
- }
-
- public static ProtectionDomain getProtectionDomain(final Class clazz)
- {
- return (ProtectionDomain)AccessController.doPrivileged(
- new PrivilegedAction()
- {
- public Object run()
- {
- return clazz.getProtectionDomain();
- }
- });
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SpecialRef.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SpecialRef.java
deleted file mode 100644
index b037eaf..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SpecialRef.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/* -*- 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):
- * Igor Bukanov, igor@fastmail.fm
- *
- * 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;
-
-class SpecialRef extends Ref
-{
- static final long serialVersionUID = -7521596632456797847L;
-
- private static final int SPECIAL_NONE = 0;
- private static final int SPECIAL_PROTO = 1;
- private static final int SPECIAL_PARENT = 2;
-
- private Scriptable target;
- private int type;
- private String name;
-
- private SpecialRef(Scriptable target, int type, String name)
- {
- this.target = target;
- this.type = type;
- this.name = name;
- }
-
- static Ref createSpecial(Context cx, Object object, String name)
- {
- Scriptable target = ScriptRuntime.toObjectOrNull(cx, object);
- if (target == null) {
- throw ScriptRuntime.undefReadError(object, name);
- }
-
- int type;
- if (name.equals("__proto__")) {
- type = SPECIAL_PROTO;
- } else if (name.equals("__parent__")) {
- type = SPECIAL_PARENT;
- } else {
- throw new IllegalArgumentException(name);
- }
-
- if (!cx.hasFeature(Context.FEATURE_PARENT_PROTO_PROPERTIES)) {
- // Clear special after checking for valid name!
- type = SPECIAL_NONE;
- }
-
- return new SpecialRef(target, type, name);
- }
-
- public Object get(Context cx)
- {
- switch (type) {
- case SPECIAL_NONE:
- return ScriptRuntime.getObjectProp(target, name, cx);
- case SPECIAL_PROTO:
- return target.getPrototype();
- case SPECIAL_PARENT:
- return target.getParentScope();
- default:
- throw Kit.codeBug();
- }
- }
-
- public Object set(Context cx, Object value)
- {
- switch (type) {
- case SPECIAL_NONE:
- return ScriptRuntime.setObjectProp(target, name, value, cx);
- case SPECIAL_PROTO:
- case SPECIAL_PARENT:
- {
- Scriptable obj = ScriptRuntime.toObjectOrNull(cx, value);
- if (obj != null) {
- // Check that obj does not contain on its prototype/scope
- // chain to prevent cycles
- Scriptable search = obj;
- do {
- if (search == target) {
- throw Context.reportRuntimeError1(
- "msg.cyclic.value", name);
- }
- if (type == SPECIAL_PROTO) {
- search = search.getPrototype();
- } else {
- search = search.getParentScope();
- }
- } while (search != null);
- }
- if (type == SPECIAL_PROTO) {
- target.setPrototype(obj);
- } else {
- target.setParentScope(obj);
- }
- return obj;
- }
- default:
- throw Kit.codeBug();
- }
- }
-
- public boolean has(Context cx)
- {
- if (type == SPECIAL_NONE) {
- return ScriptRuntime.hasObjectElem(target, name, cx);
- }
- return true;
- }
-
- public boolean delete(Context cx)
- {
- if (type == SPECIAL_NONE) {
- return ScriptRuntime.deleteObjectElem(target, name, cx);
- }
- return false;
- }
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Synchronizer.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Synchronizer.java
deleted file mode 100644
index f2fca52..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Synchronizer.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- 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 Delegator.java, released
- * Sep 27, 2000.
- *
- * The Initial Developer of the Original Code is
- * Matthias Radestock. <matthias@sorted.org>.
- * Portions created by the Initial Developer are Copyright (C) 2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * This class provides support for implementing Java-style synchronized
- * methods in Javascript.
- *
- * Synchronized functions are created from ordinary Javascript
- * functions by the <code>Synchronizer</code> constructor, e.g.
- * <code>new Packages.org.mozilla.javascript.Synchronizer(fun)</code>.
- * The resulting object is a function that establishes an exclusive
- * lock on the <code>this</code> object of its invocation.
- *
- * The Rhino shell provides a short-cut for the creation of
- * synchronized methods: <code>sync(fun)</code> has the same effect as
- * calling the above constructor.
- *
- * @see org.mozilla.javascript.Delegator
- * @author Matthias Radestock
- */
-
-public class Synchronizer extends Delegator {
-
- /**
- * Create a new synchronized function from an existing one.
- *
- * @param obj the existing function
- */
- public Synchronizer(Scriptable obj) {
- super(obj);
- }
-
- /**
- * @see org.mozilla.javascript.Function#call
- */
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- synchronized(thisObj instanceof Wrapper ? ((Wrapper)thisObj).unwrap() : thisObj) {
- return ((Function)obj).call(cx,scope,thisObj,args);
- }
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Token.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Token.java
deleted file mode 100644
index be96487..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Token.java
+++ /dev/null
@@ -1,436 +0,0 @@
-/* -*- 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):
- * Roger Lawrence
- * Mike McCabe
- * Igor Bukanov
- * Bob Jervis
- * Milen Nankov
- *
- * 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 JavaScript scanner.
- *
- * It is based on the C source files jsscan.c and jsscan.h
- * in the jsref package.
- *
- * @see org.mozilla.javascript.Parser
- *
- * @author Mike McCabe
- * @author Brendan Eich
- */
-
-public class Token
-{
-
- // debug flags
- public static final boolean printTrees =
- /*APPJET: some info not generated with this off; we disable
- actual printing in Interpreter and CodeGen */true;
- static final boolean printICode = false;
- static final boolean printNames = printTrees || printICode;
-
- /**
- * Token types. These values correspond to JSTokenType values in
- * jsscan.c.
- */
-
- public final static int
- // start enum
- ERROR = -1, // well-known as the only code < EOF
- EOF = 0, // end of file token - (not EOF_CHAR)
- EOL = 1, // end of line
-
- // Interpreter reuses the following as bytecodes
- FIRST_BYTECODE_TOKEN = 2,
-
- ENTERWITH = 2,
- LEAVEWITH = 3,
- RETURN = 4,
- GOTO = 5,
- IFEQ = 6,
- IFNE = 7,
- SETNAME = 8,
- BITOR = 9,
- BITXOR = 10,
- BITAND = 11,
- EQ = 12,
- NE = 13,
- LT = 14,
- LE = 15,
- GT = 16,
- GE = 17,
- LSH = 18,
- RSH = 19,
- URSH = 20,
- ADD = 21,
- SUB = 22,
- MUL = 23,
- DIV = 24,
- MOD = 25,
- NOT = 26,
- BITNOT = 27,
- POS = 28,
- NEG = 29,
- NEW = 30,
- DELPROP = 31,
- TYPEOF = 32,
- GETPROP = 33,
- GETPROPNOWARN = 34,
- SETPROP = 35,
- GETELEM = 36,
- SETELEM = 37,
- CALL = 38,
- NAME = 39,
- NUMBER = 40,
- STRING = 41,
- NULL = 42,
- THIS = 43,
- FALSE = 44,
- TRUE = 45,
- SHEQ = 46, // shallow equality (===)
- SHNE = 47, // shallow inequality (!==)
- REGEXP = 48,
- BINDNAME = 49,
- THROW = 50,
- RETHROW = 51, // rethrow caught exception: catch (e if ) use it
- IN = 52,
- INSTANCEOF = 53,
- LOCAL_LOAD = 54,
- GETVAR = 55,
- SETVAR = 56,
- CATCH_SCOPE = 57,
- ENUM_INIT_KEYS = 58,
- ENUM_INIT_VALUES = 59,
- ENUM_INIT_ARRAY= 60,
- ENUM_NEXT = 61,
- ENUM_ID = 62,
- THISFN = 63,
- RETURN_RESULT = 64, // to return previously stored return result
- ARRAYLIT = 65, // array literal
- OBJECTLIT = 66, // object literal
- GET_REF = 67, // *reference
- SET_REF = 68, // *reference = something
- DEL_REF = 69, // delete reference
- REF_CALL = 70, // f(args) = something or f(args)++
- REF_SPECIAL = 71, // reference for special properties like __proto
- YIELD = 72, // JS 1.7 yield pseudo keyword
-
- // For XML support:
- DEFAULTNAMESPACE = 73, // default xml namespace =
- ESCXMLATTR = 74,
- ESCXMLTEXT = 75,
- REF_MEMBER = 76, // Reference for x.@y, x..y etc.
- REF_NS_MEMBER = 77, // Reference for x.ns::y, x..ns::y etc.
- REF_NAME = 78, // Reference for @y, @[y] etc.
- REF_NS_NAME = 79; // Reference for ns::y, @ns::y@[y] etc.
-
- // End of interpreter bytecodes
- public final static int
- LAST_BYTECODE_TOKEN = REF_NS_NAME,
-
- TRY = 80,
- SEMI = 81, // semicolon
- LB = 82, // left and right brackets
- RB = 83,
- LC = 84, // left and right curlies (braces)
- RC = 85,
- LP = 86, // left and right parentheses
- RP = 87,
- COMMA = 88, // comma operator
-
- ASSIGN = 89, // simple assignment (=)
- ASSIGN_BITOR = 90, // |=
- ASSIGN_BITXOR = 91, // ^=
- ASSIGN_BITAND = 92, // |=
- ASSIGN_LSH = 93, // <<=
- ASSIGN_RSH = 94, // >>=
- ASSIGN_URSH = 95, // >>>=
- ASSIGN_ADD = 96, // +=
- ASSIGN_SUB = 97, // -=
- ASSIGN_MUL = 98, // *=
- ASSIGN_DIV = 99, // /=
- ASSIGN_MOD = 100; // %=
-
- public final static int
- FIRST_ASSIGN = ASSIGN,
- LAST_ASSIGN = ASSIGN_MOD,
-
- HOOK = 101, // conditional (?:)
- COLON = 102,
- OR = 103, // logical or (||)
- AND = 104, // logical and (&&)
- INC = 105, // increment/decrement (++ --)
- DEC = 106,
- DOT = 107, // member operator (.)
- FUNCTION = 108, // function keyword
- EXPORT = 109, // export keyword
- IMPORT = 110, // import keyword
- IF = 111, // if keyword
- ELSE = 112, // else keyword
- SWITCH = 113, // switch keyword
- CASE = 114, // case keyword
- DEFAULT = 115, // default keyword
- WHILE = 116, // while keyword
- DO = 117, // do keyword
- FOR = 118, // for keyword
- BREAK = 119, // break keyword
- CONTINUE = 120, // continue keyword
- VAR = 121, // var keyword
- WITH = 122, // with keyword
- CATCH = 123, // catch keyword
- FINALLY = 124, // finally keyword
- VOID = 125, // void keyword
- RESERVED = 126, // reserved keywords
-
- EMPTY = 127,
-
- /* types used for the parse tree - these never get returned
- * by the scanner.
- */
-
- BLOCK = 128, // statement block
- LABEL = 129, // label
- TARGET = 130,
- LOOP = 131,
- EXPR_VOID = 132, // expression statement in functions
- EXPR_RESULT = 133, // expression statement in scripts
- JSR = 134,
- SCRIPT = 135, // top-level node for entire script
- TYPEOFNAME = 136, // for typeof(simple-name)
- USE_STACK = 137,
- SETPROP_OP = 138, // x.y op= something
- SETELEM_OP = 139, // x[y] op= something
- LOCAL_BLOCK = 140,
- SET_REF_OP = 141, // *reference op= something
-
- // For XML support:
- DOTDOT = 142, // member operator (..)
- COLONCOLON = 143, // namespace::name
- XML = 144, // XML type
- DOTQUERY = 145, // .() -- e.g., x.emps.emp.(name == "terry")
- XMLATTR = 146, // @
- XMLEND = 147,
-
- // Optimizer-only-tokens
- TO_OBJECT = 148,
- TO_DOUBLE = 149,
-
- GET = 150, // JS 1.5 get pseudo keyword
- SET = 151, // JS 1.5 set pseudo keyword
- LET = 152, // JS 1.7 let pseudo keyword
- CONST = 153,
- SETCONST = 154,
- SETCONSTVAR = 155,
- ARRAYCOMP = 156, // array comprehension
- LETEXPR = 157,
- WITHEXPR = 158,
- DEBUGGER = 159,
- LAST_TOKEN = 159;
-
- public static String name(int token)
- {
- if (!printNames) {
- return String.valueOf(token);
- }
- switch (token) {
- case ERROR: return "ERROR";
- case EOF: return "EOF";
- case EOL: return "EOL";
- case ENTERWITH: return "ENTERWITH";
- case LEAVEWITH: return "LEAVEWITH";
- case RETURN: return "RETURN";
- case GOTO: return "GOTO";
- case IFEQ: return "IFEQ";
- case IFNE: return "IFNE";
- case SETNAME: return "SETNAME";
- case BITOR: return "BITOR";
- case BITXOR: return "BITXOR";
- case BITAND: return "BITAND";
- case EQ: return "EQ";
- case NE: return "NE";
- case LT: return "LT";
- case LE: return "LE";
- case GT: return "GT";
- case GE: return "GE";
- case LSH: return "LSH";
- case RSH: return "RSH";
- case URSH: return "URSH";
- case ADD: return "ADD";
- case SUB: return "SUB";
- case MUL: return "MUL";
- case DIV: return "DIV";
- case MOD: return "MOD";
- case NOT: return "NOT";
- case BITNOT: return "BITNOT";
- case POS: return "POS";
- case NEG: return "NEG";
- case NEW: return "NEW";
- case DELPROP: return "DELPROP";
- case TYPEOF: return "TYPEOF";
- case GETPROP: return "GETPROP";
- case GETPROPNOWARN: return "GETPROPNOWARN";
- case SETPROP: return "SETPROP";
- case GETELEM: return "GETELEM";
- case SETELEM: return "SETELEM";
- case CALL: return "CALL";
- case NAME: return "NAME";
- case NUMBER: return "NUMBER";
- case STRING: return "STRING";
- case NULL: return "NULL";
- case THIS: return "THIS";
- case FALSE: return "FALSE";
- case TRUE: return "TRUE";
- case SHEQ: return "SHEQ";
- case SHNE: return "SHNE";
- case REGEXP: return "OBJECT";
- case BINDNAME: return "BINDNAME";
- case THROW: return "THROW";
- case RETHROW: return "RETHROW";
- case IN: return "IN";
- case INSTANCEOF: return "INSTANCEOF";
- case LOCAL_LOAD: return "LOCAL_LOAD";
- case GETVAR: return "GETVAR";
- case SETVAR: return "SETVAR";
- case CATCH_SCOPE: return "CATCH_SCOPE";
- case ENUM_INIT_KEYS: return "ENUM_INIT_KEYS";
- case ENUM_INIT_VALUES:return "ENUM_INIT_VALUES";
- case ENUM_INIT_ARRAY: return "ENUM_INIT_ARRAY";
- case ENUM_NEXT: return "ENUM_NEXT";
- case ENUM_ID: return "ENUM_ID";
- case THISFN: return "THISFN";
- case RETURN_RESULT: return "RETURN_RESULT";
- case ARRAYLIT: return "ARRAYLIT";
- case OBJECTLIT: return "OBJECTLIT";
- case GET_REF: return "GET_REF";
- case SET_REF: return "SET_REF";
- case DEL_REF: return "DEL_REF";
- case REF_CALL: return "REF_CALL";
- case REF_SPECIAL: return "REF_SPECIAL";
- case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
- case ESCXMLTEXT: return "ESCXMLTEXT";
- case ESCXMLATTR: return "ESCXMLATTR";
- case REF_MEMBER: return "REF_MEMBER";
- case REF_NS_MEMBER: return "REF_NS_MEMBER";
- case REF_NAME: return "REF_NAME";
- case REF_NS_NAME: return "REF_NS_NAME";
- case TRY: return "TRY";
- case SEMI: return "SEMI";
- case LB: return "LB";
- case RB: return "RB";
- case LC: return "LC";
- case RC: return "RC";
- case LP: return "LP";
- case RP: return "RP";
- case COMMA: return "COMMA";
- case ASSIGN: return "ASSIGN";
- case ASSIGN_BITOR: return "ASSIGN_BITOR";
- case ASSIGN_BITXOR: return "ASSIGN_BITXOR";
- case ASSIGN_BITAND: return "ASSIGN_BITAND";
- case ASSIGN_LSH: return "ASSIGN_LSH";
- case ASSIGN_RSH: return "ASSIGN_RSH";
- case ASSIGN_URSH: return "ASSIGN_URSH";
- case ASSIGN_ADD: return "ASSIGN_ADD";
- case ASSIGN_SUB: return "ASSIGN_SUB";
- case ASSIGN_MUL: return "ASSIGN_MUL";
- case ASSIGN_DIV: return "ASSIGN_DIV";
- case ASSIGN_MOD: return "ASSIGN_MOD";
- case HOOK: return "HOOK";
- case COLON: return "COLON";
- case OR: return "OR";
- case AND: return "AND";
- case INC: return "INC";
- case DEC: return "DEC";
- case DOT: return "DOT";
- case FUNCTION: return "FUNCTION";
- case EXPORT: return "EXPORT";
- case IMPORT: return "IMPORT";
- case IF: return "IF";
- case ELSE: return "ELSE";
- case SWITCH: return "SWITCH";
- case CASE: return "CASE";
- case DEFAULT: return "DEFAULT";
- case WHILE: return "WHILE";
- case DO: return "DO";
- case FOR: return "FOR";
- case BREAK: return "BREAK";
- case CONTINUE: return "CONTINUE";
- case VAR: return "VAR";
- case WITH: return "WITH";
- case CATCH: return "CATCH";
- case FINALLY: return "FINALLY";
- case VOID: return "VOID";
- case RESERVED: return "RESERVED";
- case EMPTY: return "EMPTY";
- case BLOCK: return "BLOCK";
- case LABEL: return "LABEL";
- case TARGET: return "TARGET";
- case LOOP: return "LOOP";
- case EXPR_VOID: return "EXPR_VOID";
- case EXPR_RESULT: return "EXPR_RESULT";
- case JSR: return "JSR";
- case SCRIPT: return "SCRIPT";
- case TYPEOFNAME: return "TYPEOFNAME";
- case USE_STACK: return "USE_STACK";
- case SETPROP_OP: return "SETPROP_OP";
- case SETELEM_OP: return "SETELEM_OP";
- case LOCAL_BLOCK: return "LOCAL_BLOCK";
- case SET_REF_OP: return "SET_REF_OP";
- case DOTDOT: return "DOTDOT";
- case COLONCOLON: return "COLONCOLON";
- case XML: return "XML";
- case DOTQUERY: return "DOTQUERY";
- case XMLATTR: return "XMLATTR";
- case XMLEND: return "XMLEND";
- case TO_OBJECT: return "TO_OBJECT";
- case TO_DOUBLE: return "TO_DOUBLE";
- case GET: return "GET";
- case SET: return "SET";
- case LET: return "LET";
- case YIELD: return "YIELD";
- case CONST: return "CONST";
- case SETCONST: return "SETCONST";
- case ARRAYCOMP: return "ARRAYCOMP";
- case WITHEXPR: return "WITHEXPR";
- case LETEXPR: return "LETEXPR";
- case DEBUGGER: return "DEBUGGER";
- }
-
- // Token without name
- throw new IllegalStateException(String.valueOf(token));
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/TokenStream.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/TokenStream.java
deleted file mode 100644
index c8c3045..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/TokenStream.java
+++ /dev/null
@@ -1,1500 +0,0 @@
-/* -*- 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):
- * Roger Lawrence
- * Mike McCabe
- * Igor Bukanov
- * Ethan Hugg
- * Bob Jervis
- * Terry Lucas
- * Milen Nankov
- *
- * 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;
-
-import java.io.*;
-
-/**
- * This class implements the JavaScript scanner.
- *
- * It is based on the C source files jsscan.c and jsscan.h
- * in the jsref package.
- *
- * @see org.mozilla.javascript.Parser
- *
- * @author Mike McCabe
- * @author Brendan Eich
- */
-
-class TokenStream
-{
- /*
- * For chars - because we need something out-of-range
- * to check. (And checking EOF by exception is annoying.)
- * Note distinction from EOF token type!
- */
- private final static int
- EOF_CHAR = -1;
-
- TokenStream(Parser parser, Reader sourceReader, String sourceString,
- int lineno)
- {
- this.parser = parser;
- this.lineno = lineno;
- if (sourceReader != null) {
- if (sourceString != null) Kit.codeBug();
- this.sourceReader = sourceReader;
- this.sourceBuffer = new char[512];
- this.sourceEnd = 0;
- } else {
- if (sourceString == null) Kit.codeBug();
- this.sourceString = sourceString;
- this.sourceEnd = sourceString.length();
- }
- this.sourceCursor = 0;
- }
-
- /* This function uses the cached op, string and number fields in
- * TokenStream; if getToken has been called since the passed token
- * was scanned, the op or string printed may be incorrect.
- */
- String tokenToString(int token)
- {
- if (Token.printTrees) {
- String name = Token.name(token);
-
- switch (token) {
- case Token.STRING:
- case Token.REGEXP:
- case Token.NAME:
- return name + " `" + this.string + "'";
-
- case Token.NUMBER:
- return "NUMBER " + this.number;
- }
-
- return name;
- }
- return "";
- }
-
- static boolean isKeyword(String s)
- {
- return Token.EOF != stringToKeyword(s);
- }
-
- private static int stringToKeyword(String name)
- {
-// #string_id_map#
-// The following assumes that Token.EOF == 0
- final int
- Id_break = Token.BREAK,
- Id_case = Token.CASE,
- Id_continue = Token.CONTINUE,
- Id_default = Token.DEFAULT,
- Id_delete = Token.DELPROP,
- Id_do = Token.DO,
- Id_else = Token.ELSE,
- Id_export = Token.EXPORT,
- Id_false = Token.FALSE,
- Id_for = Token.FOR,
- Id_function = Token.FUNCTION,
- Id_if = Token.IF,
- Id_in = Token.IN,
- Id_let = Token.LET,
- Id_new = Token.NEW,
- Id_null = Token.NULL,
- Id_return = Token.RETURN,
- Id_switch = Token.SWITCH,
- Id_this = Token.THIS,
- Id_true = Token.TRUE,
- Id_typeof = Token.TYPEOF,
- Id_var = Token.VAR,
- Id_void = Token.VOID,
- Id_while = Token.WHILE,
- Id_with = Token.WITH,
- Id_yield = Token.YIELD,
-
- // the following are #ifdef RESERVE_JAVA_KEYWORDS in jsscan.c
- Id_abstract = Token.RESERVED,
- Id_boolean = Token.RESERVED,
- Id_byte = Token.RESERVED,
- Id_catch = Token.CATCH,
- Id_char = Token.RESERVED,
- Id_class = Token.RESERVED,
- Id_const = Token.CONST,
- Id_debugger = Token.DEBUGGER,
- Id_double = Token.RESERVED,
- Id_enum = Token.RESERVED,
- Id_extends = Token.RESERVED,
- Id_final = Token.RESERVED,
- Id_finally = Token.FINALLY,
- Id_float = Token.RESERVED,
- Id_goto = Token.RESERVED,
- Id_implements = Token.RESERVED,
- Id_import = Token.IMPORT,
- Id_instanceof = Token.INSTANCEOF,
- Id_int = Token.RESERVED,
- Id_interface = Token.RESERVED,
- Id_long = Token.RESERVED,
- Id_native = Token.RESERVED,
- Id_package = Token.RESERVED,
- Id_private = Token.RESERVED,
- Id_protected = Token.RESERVED,
- Id_public = Token.RESERVED,
- Id_short = Token.RESERVED,
- Id_static = Token.RESERVED,
- Id_super = Token.RESERVED,
- Id_synchronized = Token.RESERVED,
- Id_throw = Token.THROW,
- Id_throws = Token.RESERVED,
- Id_transient = Token.RESERVED,
- Id_try = Token.TRY,
- Id_volatile = Token.RESERVED;
-
- int id;
- String s = name;
-// #generated# Last update: 2007-04-18 13:53:30 PDT
- L0: { id = 0; String X = null; int c;
- L: switch (s.length()) {
- case 2: c=s.charAt(1);
- if (c=='f') { if (s.charAt(0)=='i') {id=Id_if; break L0;} }
- else if (c=='n') { if (s.charAt(0)=='i') {id=Id_in; break L0;} }
- else if (c=='o') { if (s.charAt(0)=='d') {id=Id_do; break L0;} }
- break L;
- case 3: switch (s.charAt(0)) {
- case 'f': if (s.charAt(2)=='r' && s.charAt(1)=='o') {id=Id_for; break L0;} break L;
- case 'i': if (s.charAt(2)=='t' && s.charAt(1)=='n') {id=Id_int; break L0;} break L;
- case 'l': if (s.charAt(2)=='t' && s.charAt(1)=='e') {id=Id_let; break L0;} break L;
- case 'n': if (s.charAt(2)=='w' && s.charAt(1)=='e') {id=Id_new; break L0;} break L;
- case 't': if (s.charAt(2)=='y' && s.charAt(1)=='r') {id=Id_try; break L0;} break L;
- case 'v': if (s.charAt(2)=='r' && s.charAt(1)=='a') {id=Id_var; break L0;} break L;
- } break L;
- case 4: switch (s.charAt(0)) {
- case 'b': X="byte";id=Id_byte; break L;
- case 'c': c=s.charAt(3);
- if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='a') {id=Id_case; break L0;} }
- else if (c=='r') { if (s.charAt(2)=='a' && s.charAt(1)=='h') {id=Id_char; break L0;} }
- break L;
- case 'e': c=s.charAt(3);
- if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='l') {id=Id_else; break L0;} }
- else if (c=='m') { if (s.charAt(2)=='u' && s.charAt(1)=='n') {id=Id_enum; break L0;} }
- break L;
- case 'g': X="goto";id=Id_goto; break L;
- case 'l': X="long";id=Id_long; break L;
- case 'n': X="null";id=Id_null; break L;
- case 't': c=s.charAt(3);
- if (c=='e') { if (s.charAt(2)=='u' && s.charAt(1)=='r') {id=Id_true; break L0;} }
- else if (c=='s') { if (s.charAt(2)=='i' && s.charAt(1)=='h') {id=Id_this; break L0;} }
- break L;
- case 'v': X="void";id=Id_void; break L;
- case 'w': X="with";id=Id_with; break L;
- } break L;
- case 5: switch (s.charAt(2)) {
- case 'a': X="class";id=Id_class; break L;
- case 'e': c=s.charAt(0);
- if (c=='b') { X="break";id=Id_break; }
- else if (c=='y') { X="yield";id=Id_yield; }
- break L;
- case 'i': X="while";id=Id_while; break L;
- case 'l': X="false";id=Id_false; break L;
- case 'n': c=s.charAt(0);
- if (c=='c') { X="const";id=Id_const; }
- else if (c=='f') { X="final";id=Id_final; }
- break L;
- case 'o': c=s.charAt(0);
- if (c=='f') { X="float";id=Id_float; }
- else if (c=='s') { X="short";id=Id_short; }
- break L;
- case 'p': X="super";id=Id_super; break L;
- case 'r': X="throw";id=Id_throw; break L;
- case 't': X="catch";id=Id_catch; break L;
- } break L;
- case 6: switch (s.charAt(1)) {
- case 'a': X="native";id=Id_native; break L;
- case 'e': c=s.charAt(0);
- if (c=='d') { X="delete";id=Id_delete; }
- else if (c=='r') { X="return";id=Id_return; }
- break L;
- case 'h': X="throws";id=Id_throws; break L;
- /*APPJET*//* case 'm': X="import";id=Id_import; break L;*/
- case 'o': X="double";id=Id_double; break L;
- case 't': X="static";id=Id_static; break L;
- case 'u': X="public";id=Id_public; break L;
- case 'w': X="switch";id=Id_switch; break L;
- case 'x': X="export";id=Id_export; break L;
- case 'y': X="typeof";id=Id_typeof; break L;
- } break L;
- case 7: switch (s.charAt(1)) {
- case 'a': X="package";id=Id_package; break L;
- case 'e': X="default";id=Id_default; break L;
- case 'i': X="finally";id=Id_finally; break L;
- case 'o': X="boolean";id=Id_boolean; break L;
- case 'r': X="private";id=Id_private; break L;
- case 'x': X="extends";id=Id_extends; break L;
- } break L;
- case 8: switch (s.charAt(0)) {
- case 'a': X="abstract";id=Id_abstract; break L;
- case 'c': X="continue";id=Id_continue; break L;
- case 'd': X="debugger";id=Id_debugger; break L;
- case 'f': X="function";id=Id_function; break L;
- case 'v': X="volatile";id=Id_volatile; break L;
- } break L;
- case 9: c=s.charAt(0);
- if (c=='i') { X="interface";id=Id_interface; }
- else if (c=='p') { X="protected";id=Id_protected; }
- else if (c=='t') { X="transient";id=Id_transient; }
- break L;
- case 10: c=s.charAt(1);
- if (c=='m') { X="implements";id=Id_implements; }
- else if (c=='n') { X="instanceof";id=Id_instanceof; }
- break L;
- case 12: X="synchronized";id=Id_synchronized; break L;
- }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- }
-// #/generated#
-// #/string_id_map#
- if (id == 0) { return Token.EOF; }
- return id & 0xff;
- }
-
- final int getLineno() { return lineno; }
-
- final String getString() { return string; }
-
- final double getNumber() { return number; }
-
- final boolean eof() { return hitEOF; }
-
- final int getToken() throws IOException
- {
- int c;
-
- retry:
- for (;;) {
- // Eat whitespace, possibly sensitive to newlines.
- for (;;) {
- c = getChar();
- if (c == EOF_CHAR) {
- return Token.EOF;
- } else if (c == '\n') {
- dirtyLine = false;
- return Token.EOL;
- } else if (!isJSSpace(c)) {
- if (c != '-') {
- dirtyLine = true;
- }
- break;
- }
- }
-
- if (c == '@') return Token.XMLATTR;
-
- // identifier/keyword/instanceof?
- // watch out for starting with a <backslash>
- boolean identifierStart;
- boolean isUnicodeEscapeStart = false;
- if (c == '\\') {
- c = getChar();
- if (c == 'u') {
- identifierStart = true;
- isUnicodeEscapeStart = true;
- stringBufferTop = 0;
- } else {
- identifierStart = false;
- ungetChar(c);
- c = '\\';
- }
- } else {
- identifierStart = Character.isJavaIdentifierStart((char)c);
- if (identifierStart) {
- stringBufferTop = 0;
- addToString(c);
- }
- }
-
- if (identifierStart) {
- boolean containsEscape = isUnicodeEscapeStart;
- for (;;) {
- if (isUnicodeEscapeStart) {
- // strictly speaking we should probably push-back
- // all the bad characters if the <backslash>uXXXX
- // sequence is malformed. But since there isn't a
- // correct context(is there?) for a bad Unicode
- // escape sequence in an identifier, we can report
- // an error here.
- int escapeVal = 0;
- for (int i = 0; i != 4; ++i) {
- c = getChar();
- escapeVal = Kit.xDigitToInt(c, escapeVal);
- // Next check takes care about c < 0 and bad escape
- if (escapeVal < 0) { break; }
- }
- if (escapeVal < 0) {
- parser.addError("msg.invalid.escape");
- return Token.ERROR;
- }
- addToString(escapeVal);
- isUnicodeEscapeStart = false;
- } else {
- c = getChar();
- if (c == '\\') {
- c = getChar();
- if (c == 'u') {
- isUnicodeEscapeStart = true;
- containsEscape = true;
- } else {
- /*APPJET*/
- parser.addError("msg.illegal.character.appjet",
- "\\"+Character.toString((char)c));
- return Token.ERROR;
- }
- } else {
- if (c == EOF_CHAR
- || !Character.isJavaIdentifierPart((char)c))
- {
- break;
- }
- addToString(c);
- }
- }
- }
- ungetChar(c);
-
- String str = getStringFromBuffer();
- /*APPJET*//*MOVED*/this.string = (String)allStrings.intern(str);
- /*APPJET this move lets the names of RESERVED tokens and other
- tokens be determined, and also fixes broken yield/let parsing
- under pre-1.7 JS */
- if (!containsEscape) {
- // OPT we shouldn't have to make a string (object!) to
- // check if it's a keyword.
-
- // Return the corresponding token if it's a keyword
- int result = stringToKeyword(str);
- if (result != Token.EOF) {
- if ((result == Token.LET || result == Token.YIELD) &&
- parser.compilerEnv.getLanguageVersion()
- < Context.VERSION_1_7)
- {
- // LET and YIELD are tokens only in 1.7 and later
- result = Token.NAME;
- }
- if (result != Token.RESERVED) {
- return result;
- } else if (!parser.compilerEnv.
- isReservedKeywordAsIdentifier())
- {
- return result;
- } else {
- // If implementation permits to use future reserved
- // keywords in violation with the EcmaScript,
- // treat it as name but issue warning
- parser.addWarning("msg.reserved.keyword", str);
- }
- }
- }
- return Token.NAME;
- }
-
- // is it a number?
- if (isDigit(c) || (c == '.' && isDigit(peekChar()))) {
-
- stringBufferTop = 0;
- int base = 10;
-
- if (c == '0') {
- c = getChar();
- if (c == 'x' || c == 'X') {
- base = 16;
- c = getChar();
- } else if (isDigit(c)) {
- base = 8;
- } else {
- addToString('0');
- }
- }
-
- if (base == 16) {
- while (0 <= Kit.xDigitToInt(c, 0)) {
- addToString(c);
- c = getChar();
- }
- } else {
- while ('0' <= c && c <= '9') {
- /*
- * We permit 08 and 09 as decimal numbers, which
- * makes our behavior a superset of the ECMA
- * numeric grammar. We might not always be so
- * permissive, so we warn about it.
- */
- if (base == 8 && c >= '8') {
- parser.addWarning("msg.bad.octal.literal",
- c == '8' ? "8" : "9");
- base = 10;
- }
- addToString(c);
- c = getChar();
- }
- }
-
- boolean isInteger = true;
-
- if (base == 10 && (c == '.' || c == 'e' || c == 'E')) {
- isInteger = false;
- if (c == '.') {
- do {
- addToString(c);
- c = getChar();
- } while (isDigit(c));
- }
- if (c == 'e' || c == 'E') {
- addToString(c);
- c = getChar();
- if (c == '+' || c == '-') {
- addToString(c);
- c = getChar();
- }
- if (!isDigit(c)) {
- parser.addError("msg.missing.exponent");
- return Token.ERROR;
- }
- do {
- addToString(c);
- c = getChar();
- } while (isDigit(c));
- }
- }
- ungetChar(c);
- String numString = getStringFromBuffer();
-
- double dval;
- if (base == 10 && !isInteger) {
- try {
- // Use Java conversion to number from string...
- dval = Double.valueOf(numString).doubleValue();
- }
- catch (NumberFormatException ex) {
- parser.addError("msg.caught.nfe");
- return Token.ERROR;
- }
- } else {
- dval = ScriptRuntime.stringToNumber(numString, 0, base);
- }
-
- this.number = dval;
- return Token.NUMBER;
- }
-
- // is it a string?
- if (c == '"' || c == '\'') {
- // We attempt to accumulate a string the fast way, by
- // building it directly out of the reader. But if there
- // are any escaped characters in the string, we revert to
- // building it out of a StringBuffer.
-
- /*APPJET*/
- if (c == '"' && tryReadTripleQuotedString()) {
- return Token.STRING;
- }
-
- int quoteChar = c;
- stringBufferTop = 0;
-
- c = getChar();
- strLoop: while (c != quoteChar) {
- if (c == '\n' || c == EOF_CHAR) {
- ungetChar(c);
- /*APPJET*/
- parser.addError("msg.unterminated.string.lit",
- Character.toString((char)quoteChar));
- return Token.ERROR;
- }
-
- if (c == '\\') {
- // We've hit an escaped character
- int escapeVal;
-
- c = getChar();
- switch (c) {
- case 'b': c = '\b'; break;
- case 'f': c = '\f'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
-
- // \v a late addition to the ECMA spec,
- // it is not in Java, so use 0xb
- case 'v': c = 0xb; break;
-
- case 'u':
- // Get 4 hex digits; if the u escape is not
- // followed by 4 hex digits, use 'u' + the
- // literal character sequence that follows.
- int escapeStart = stringBufferTop;
- addToString('u');
- escapeVal = 0;
- for (int i = 0; i != 4; ++i) {
- c = getChar();
- escapeVal = Kit.xDigitToInt(c, escapeVal);
- if (escapeVal < 0) {
- continue strLoop;
- }
- addToString(c);
- }
- // prepare for replace of stored 'u' sequence
- // by escape value
- stringBufferTop = escapeStart;
- c = escapeVal;
- break;
- case 'x':
- // Get 2 hex digits, defaulting to 'x'+literal
- // sequence, as above.
- c = getChar();
- escapeVal = Kit.xDigitToInt(c, 0);
- if (escapeVal < 0) {
- addToString('x');
- continue strLoop;
- } else {
- int c1 = c;
- c = getChar();
- escapeVal = Kit.xDigitToInt(c, escapeVal);
- if (escapeVal < 0) {
- addToString('x');
- addToString(c1);
- continue strLoop;
- } else {
- // got 2 hex digits
- c = escapeVal;
- }
- }
- break;
-
- case '\n':
- // Remove line terminator after escape to follow
- // SpiderMonkey and C/C++
- c = getChar();
- continue strLoop;
-
- default:
- if ('0' <= c && c < '8') {
- int val = c - '0';
- c = getChar();
- if ('0' <= c && c < '8') {
- val = 8 * val + c - '0';
- c = getChar();
- if ('0' <= c && c < '8' && val <= 037) {
- // c is 3rd char of octal sequence only
- // if the resulting val <= 0377
- val = 8 * val + c - '0';
- c = getChar();
- }
- }
- ungetChar(c);
- c = val;
- }
- }
- }
- addToString(c);
- c = getChar();
- }
-
- String str = getStringFromBuffer();
- this.string = (String)allStrings.intern(str);
- return Token.STRING;
- }
-
- switch (c) {
- case ';': return Token.SEMI;
- case '[': return Token.LB;
- case ']': return Token.RB;
- case '{': return Token.LC;
- case '}': return Token.RC;
- case '(': return Token.LP;
- case ')': return Token.RP;
- case ',': return Token.COMMA;
- case '?': return Token.HOOK;
- case ':':
- if (matchChar(':')) {
- return Token.COLONCOLON;
- } else {
- return Token.COLON;
- }
- case '.':
- if (matchChar('.')) {
- return Token.DOTDOT;
- } else if (matchChar('(')) {
- return Token.DOTQUERY;
- } else {
- return Token.DOT;
- }
-
- case '|':
- if (matchChar('|')) {
- return Token.OR;
- } else if (matchChar('=')) {
- return Token.ASSIGN_BITOR;
- } else {
- return Token.BITOR;
- }
-
- case '^':
- if (matchChar('=')) {
- return Token.ASSIGN_BITXOR;
- } else {
- return Token.BITXOR;
- }
-
- case '&':
- if (matchChar('&')) {
- return Token.AND;
- } else if (matchChar('=')) {
- return Token.ASSIGN_BITAND;
- } else {
- return Token.BITAND;
- }
-
- case '=':
- if (matchChar('=')) {
- if (matchChar('='))
- return Token.SHEQ;
- else
- return Token.EQ;
- } else {
- return Token.ASSIGN;
- }
-
- case '!':
- if (matchChar('=')) {
- if (matchChar('='))
- return Token.SHNE;
- else
- return Token.NE;
- } else {
- return Token.NOT;
- }
-
- case '<':
- /* NB:treat HTML begin-comment as comment-till-eol */
- if (matchChar('!')) {
- if (matchChar('-')) {
- if (matchChar('-')) {
- skipLine();
- continue retry;
- }
- ungetChar('-');
- }
- ungetChar('!');
- }
- if (matchChar('<')) {
- if (matchChar('=')) {
- return Token.ASSIGN_LSH;
- } else {
- return Token.LSH;
- }
- } else {
- if (matchChar('=')) {
- return Token.LE;
- } else {
- return Token.LT;
- }
- }
-
- case '>':
- if (matchChar('>')) {
- if (matchChar('>')) {
- if (matchChar('=')) {
- return Token.ASSIGN_URSH;
- } else {
- return Token.URSH;
- }
- } else {
- if (matchChar('=')) {
- return Token.ASSIGN_RSH;
- } else {
- return Token.RSH;
- }
- }
- } else {
- if (matchChar('=')) {
- return Token.GE;
- } else {
- return Token.GT;
- }
- }
-
- case '*':
- if (matchChar('=')) {
- return Token.ASSIGN_MUL;
- } else {
- return Token.MUL;
- }
-
- case '/':
- // is it a // comment?
- if (matchChar('/')) {
- skipLine();
- continue retry;
- }
- if (matchChar('*')) {
- boolean lookForSlash = false;
- for (;;) {
- c = getChar();
- if (c == EOF_CHAR) {
- parser.addError("msg.unterminated.comment");
- return Token.ERROR;
- } else if (c == '*') {
- lookForSlash = true;
- } else if (c == '/') {
- if (lookForSlash) {
- continue retry;
- }
- } else {
- lookForSlash = false;
- }
- }
- }
-
- if (matchChar('=')) {
- return Token.ASSIGN_DIV;
- } else {
- return Token.DIV;
- }
-
- case '%':
- if (matchChar('=')) {
- return Token.ASSIGN_MOD;
- } else {
- return Token.MOD;
- }
-
- case '~':
- return Token.BITNOT;
-
- case '+':
- if (matchChar('=')) {
- return Token.ASSIGN_ADD;
- } else if (matchChar('+')) {
- return Token.INC;
- } else {
- return Token.ADD;
- }
-
- case '-':
- if (matchChar('=')) {
- c = Token.ASSIGN_SUB;
- } else if (matchChar('-')) {
- if (!dirtyLine) {
- // treat HTML end-comment after possible whitespace
- // after line start as comment-utill-eol
- if (matchChar('>')) {
- skipLine();
- continue retry;
- }
- }
- c = Token.DEC;
- } else {
- c = Token.SUB;
- }
- dirtyLine = true;
- return c;
-
- default:
- /*APPJET*/
- parser.addError("msg.illegal.character.appjet",
- Character.toString((char)c));
- return Token.ERROR;
- }
- }
- }
-
- private static boolean isAlpha(int c)
- {
- // Use 'Z' < 'a'
- if (c <= 'Z') {
- return 'A' <= c;
- } else {
- return 'a' <= c && c <= 'z';
- }
- }
-
- static boolean isDigit(int c)
- {
- return '0' <= c && c <= '9';
- }
-
- /* As defined in ECMA. jsscan.c uses C isspace() (which allows
- * \v, I think.) note that code in getChar() implicitly accepts
- * '\r' == \u000D as well.
- */
- static boolean isJSSpace(int c)
- {
- if (c <= 127) {
- return c == 0x20 || c == 0x9 || c == 0xC || c == 0xB;
- } else {
- return c == 0xA0
- || Character.getType((char)c) == Character.SPACE_SEPARATOR;
- }
- }
-
- private static boolean isJSFormatChar(int c)
- {
- return c > 127 && Character.getType((char)c) == Character.FORMAT;
- }
-
- /**
- * Parser calls the method when it gets / or /= in literal context.
- */
- void readRegExp(int startToken)
- throws IOException
- {
- stringBufferTop = 0;
- if (startToken == Token.ASSIGN_DIV) {
- // Miss-scanned /=
- addToString('=');
- } else {
- if (startToken != Token.DIV) Kit.codeBug();
- }
-
- int c;
- while ((c = getChar()) != '/') {
- if (c == '\n' || c == EOF_CHAR) {
- ungetChar(c);
- throw parser.reportError("msg.unterminated.re.lit");
- }
- if (c == '\\') {
- addToString(c);
- c = getChar();
- }
-
- addToString(c);
- }
- int reEnd = stringBufferTop;
-
- while (true) {
- if (matchChar('g'))
- addToString('g');
- else if (matchChar('i'))
- addToString('i');
- else if (matchChar('m'))
- addToString('m');
- else
- break;
- }
-
- if (isAlpha(peekChar())) {
- throw parser.reportError("msg.invalid.re.flag");
- }
-
- this.string = new String(stringBuffer, 0, reEnd);
- this.regExpFlags = new String(stringBuffer, reEnd,
- stringBufferTop - reEnd);
- }
-
- boolean isXMLAttribute()
- {
- return xmlIsAttribute;
- }
-
- int getFirstXMLToken() throws IOException
- {
- xmlOpenTagsCount = 0;
- xmlIsAttribute = false;
- xmlIsTagContent = false;
- ungetChar('<');
- return getNextXMLToken();
- }
-
- int getNextXMLToken() throws IOException
- {
- stringBufferTop = 0; // remember the XML
-
- for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
- if (xmlIsTagContent) {
- switch (c) {
- case '>':
- addToString(c);
- xmlIsTagContent = false;
- xmlIsAttribute = false;
- break;
- case '/':
- addToString(c);
- if (peekChar() == '>') {
- c = getChar();
- addToString(c);
- xmlIsTagContent = false;
- xmlOpenTagsCount--;
- }
- break;
- case '{':
- ungetChar(c);
- this.string = getStringFromBuffer();
- return Token.XML;
- case '\'':
- case '"':
- addToString(c);
- if (!readQuotedString(c)) return Token.ERROR;
- break;
- case '=':
- addToString(c);
- xmlIsAttribute = true;
- break;
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- addToString(c);
- break;
- default:
- addToString(c);
- xmlIsAttribute = false;
- break;
- }
-
- if (!xmlIsTagContent && xmlOpenTagsCount == 0) {
- this.string = getStringFromBuffer();
- return Token.XMLEND;
- }
- } else {
- switch (c) {
- case '<':
- addToString(c);
- c = peekChar();
- switch (c) {
- case '!':
- c = getChar(); // Skip !
- addToString(c);
- c = peekChar();
- switch (c) {
- case '-':
- c = getChar(); // Skip -
- addToString(c);
- c = getChar();
- if (c == '-') {
- addToString(c);
- if(!readXmlComment()) return Token.ERROR;
- } else {
- // throw away the string in progress
- stringBufferTop = 0;
- this.string = null;
- parser.addError("msg.XML.bad.form");
- return Token.ERROR;
- }
- break;
- case '[':
- c = getChar(); // Skip [
- addToString(c);
- if (getChar() == 'C' &&
- getChar() == 'D' &&
- getChar() == 'A' &&
- getChar() == 'T' &&
- getChar() == 'A' &&
- getChar() == '[')
- {
- addToString('C');
- addToString('D');
- addToString('A');
- addToString('T');
- addToString('A');
- addToString('[');
- if (!readCDATA()) return Token.ERROR;
-
- } else {
- // throw away the string in progress
- stringBufferTop = 0;
- this.string = null;
- parser.addError("msg.XML.bad.form");
- return Token.ERROR;
- }
- break;
- default:
- if(!readEntity()) return Token.ERROR;
- break;
- }
- break;
- case '?':
- c = getChar(); // Skip ?
- addToString(c);
- if (!readPI()) return Token.ERROR;
- break;
- case '/':
- // End tag
- c = getChar(); // Skip /
- addToString(c);
- if (xmlOpenTagsCount == 0) {
- // throw away the string in progress
- stringBufferTop = 0;
- this.string = null;
- parser.addError("msg.XML.bad.form");
- return Token.ERROR;
- }
- xmlIsTagContent = true;
- xmlOpenTagsCount--;
- break;
- default:
- // Start tag
- xmlIsTagContent = true;
- xmlOpenTagsCount++;
- break;
- }
- break;
- case '{':
- ungetChar(c);
- this.string = getStringFromBuffer();
- return Token.XML;
- default:
- addToString(c);
- break;
- }
- }
- }
-
- stringBufferTop = 0; // throw away the string in progress
- this.string = null;
- parser.addError("msg.XML.bad.form");
- return Token.ERROR;
- }
-
- /**
- *
- */
- private boolean readQuotedString(int quote) throws IOException
- {
- for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
- addToString(c);
- if (c == quote) return true;
- }
-
- stringBufferTop = 0; // throw away the string in progress
- this.string = null;
- parser.addError("msg.XML.bad.form");
- return false;
- }
-
- /**
- *
- */
- private boolean readXmlComment() throws IOException
- {
- for (int c = getChar(); c != EOF_CHAR;) {
- addToString(c);
- if (c == '-' && peekChar() == '-') {
- c = getChar();
- addToString(c);
- if (peekChar() == '>') {
- c = getChar(); // Skip >
- addToString(c);
- return true;
- } else {
- continue;
- }
- }
- c = getChar();
- }
-
- stringBufferTop = 0; // throw away the string in progress
- this.string = null;
- parser.addError("msg.XML.bad.form");
- return false;
- }
-
- /**
- *
- */
- private boolean readCDATA() throws IOException
- {
- for (int c = getChar(); c != EOF_CHAR;) {
- addToString(c);
- if (c == ']' && peekChar() == ']') {
- c = getChar();
- addToString(c);
- if (peekChar() == '>') {
- c = getChar(); // Skip >
- addToString(c);
- return true;
- } else {
- continue;
- }
- }
- c = getChar();
- }
-
- stringBufferTop = 0; // throw away the string in progress
- this.string = null;
- parser.addError("msg.XML.bad.form");
- return false;
- }
-
- /**
- *
- */
- private boolean readEntity() throws IOException
- {
- int declTags = 1;
- for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
- addToString(c);
- switch (c) {
- case '<':
- declTags++;
- break;
- case '>':
- declTags--;
- if (declTags == 0) return true;
- break;
- }
- }
-
- stringBufferTop = 0; // throw away the string in progress
- this.string = null;
- parser.addError("msg.XML.bad.form");
- return false;
- }
-
- /**
- *
- */
- private boolean readPI() throws IOException
- {
- for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
- addToString(c);
- if (c == '?' && peekChar() == '>') {
- c = getChar(); // Skip >
- addToString(c);
- return true;
- }
- }
-
- stringBufferTop = 0; // throw away the string in progress
- this.string = null;
- parser.addError("msg.XML.bad.form");
- return false;
- }
-
- private String getStringFromBuffer()
- {
- return new String(stringBuffer, 0, stringBufferTop);
- }
-
- private void addToString(int c)
- {
- int N = stringBufferTop;
- if (N == stringBuffer.length) {
- char[] tmp = new char[stringBuffer.length * 2];
- System.arraycopy(stringBuffer, 0, tmp, 0, N);
- stringBuffer = tmp;
- }
- stringBuffer[N] = (char)c;
- stringBufferTop = N + 1;
- }
-
- private void ungetChar(int c)
- {
- // can not unread past across line boundary
- if (ungetCursor != 0 && ungetBuffer[ungetCursor - 1] == '\n')
- Kit.codeBug();
- ungetBuffer[ungetCursor++] = c;
- }
-
- private boolean matchChar(int test) throws IOException
- {
- int c = getChar();
- if (c == test) {
- return true;
- } else {
- ungetChar(c);
- return false;
- }
- }
-
- private int peekChar() throws IOException
- {
- int c = getChar();
- ungetChar(c);
- return c;
- }
-
- private int getChar() throws IOException
- {
- if (ungetCursor != 0) {
- return ungetBuffer[--ungetCursor];
- }
-
- for(;;) {
- int c;
- if (sourceString != null) {
- if (sourceCursor == sourceEnd) {
- hitEOF = true;
- return EOF_CHAR;
- }
- c = sourceString.charAt(sourceCursor++);
- } else {
- if (sourceCursor == sourceEnd) {
- if (!fillSourceBuffer()) {
- hitEOF = true;
- return EOF_CHAR;
- }
- }
- c = sourceBuffer[sourceCursor++];
- }
-
- if (lineEndChar >= 0) {
- if (lineEndChar == '\r' && c == '\n') {
- lineEndChar = '\n';
- continue;
- }
- lineEndChar = -1;
- lineStart = sourceCursor - 1;
- lineno++;
- }
-
- if (c <= 127) {
- if (c == '\n' || c == '\r') {
- lineEndChar = c;
- c = '\n';
- }
- } else {
- if (isJSFormatChar(c)) {
- continue;
- }
- if (ScriptRuntime.isJSLineTerminator(c)) {
- lineEndChar = c;
- c = '\n';
- }
- }
- return c;
- }
- }
-
- private void skipLine() throws IOException
- {
- // skip to end of line
- int c;
- while ((c = getChar()) != EOF_CHAR && c != '\n') { }
- ungetChar(c);
- }
-
- final int getOffset()
- {
- int n = sourceCursor - lineStart;
- if (lineEndChar >= 0) { --n; }
- return n;
- }
-
- final String getLine()
- {
- if (sourceString != null) {
- // String case
- int lineEnd = sourceCursor;
- if (lineEndChar >= 0) {
- --lineEnd;
- } else {
- for (; lineEnd != sourceEnd; ++lineEnd) {
- int c = sourceString.charAt(lineEnd);
- if (ScriptRuntime.isJSLineTerminator(c)) {
- break;
- }
- }
- }
- return sourceString.substring(lineStart, lineEnd);
- } else {
- // Reader case
- int lineLength = sourceCursor - lineStart;
- if (lineEndChar >= 0) {
- --lineLength;
- } else {
- // Read until the end of line
- for (;; ++lineLength) {
- int i = lineStart + lineLength;
- if (i == sourceEnd) {
- try {
- if (!fillSourceBuffer()) { break; }
- } catch (IOException ioe) {
- // ignore it, we're already displaying an error...
- break;
- }
- // i recalculuation as fillSourceBuffer can move saved
- // line buffer and change lineStart
- i = lineStart + lineLength;
- }
- int c = sourceBuffer[i];
- if (ScriptRuntime.isJSLineTerminator(c)) {
- break;
- }
- }
- }
- return new String(sourceBuffer, lineStart, lineLength);
- }
- }
-
- private boolean fillSourceBuffer() throws IOException
- {
- if (sourceString != null) Kit.codeBug();
- if (sourceEnd == sourceBuffer.length) {
- if (lineStart != 0) {
- System.arraycopy(sourceBuffer, lineStart, sourceBuffer, 0,
- sourceEnd - lineStart);
- sourceEnd -= lineStart;
- sourceCursor -= lineStart;
- lineStart = 0;
- } else {
- char[] tmp = new char[sourceBuffer.length * 2];
- System.arraycopy(sourceBuffer, 0, tmp, 0, sourceEnd);
- sourceBuffer = tmp;
- }
- }
- int n = sourceReader.read(sourceBuffer, sourceEnd,
- sourceBuffer.length - sourceEnd);
- if (n < 0) {
- return false;
- }
- sourceEnd += n;
- return true;
- }
-
- // stuff other than whitespace since start of line
- private boolean dirtyLine;
-
- String regExpFlags;
-
- // Set this to an inital non-null value so that the Parser has
- // something to retrieve even if an error has occured and no
- // string is found. Fosters one class of error, but saves lots of
- // code.
- private String string = "";
- private double number;
-
- private char[] stringBuffer = new char[128];
- private int stringBufferTop;
- private ObjToIntMap allStrings = new ObjToIntMap(50);
-
- // Room to backtrace from to < on failed match of the last - in <!--
- private final int[] ungetBuffer = new int[3];
- private int ungetCursor;
-
- private boolean hitEOF = false;
-
- private int lineStart = 0;
- private int lineno;
- private int lineEndChar = -1;
-
- private String sourceString;
- private Reader sourceReader;
- private char[] sourceBuffer;
- private int sourceEnd;
- private int sourceCursor;
-
- // for xml tokenizer
- private boolean xmlIsAttribute;
- private boolean xmlIsTagContent;
- private int xmlOpenTagsCount;
-
- private Parser parser;
-
- /*APPJET*//* added method */
- private boolean tryReadTripleQuotedString() throws IOException {
- // have to be kind of clever, because we don't want to
- // add to the overhead of tokenizing, but there are constraints
- // like "once you've gotten a newline and put it back (ungotten it),
- // you can't put anything else back"
-
- // have seen one quote
- int c = getChar();
- if (c != '"') { ungetChar(c); return false; }
- // have seen two quotes
- c = getChar();
- if (c != '"') {
- ungetChar(c);
- this.string = (String)allStrings.intern("");
- return true;
- }
- // have seen three quotes
-
- final boolean newPolicy = false;
-
- stringBufferTop = 0;
-
- boolean afterBackslash = false;
- boolean done = false;
- while (! done) {
- c = getChar();
- if (c == EOF_CHAR) {
- ungetChar(c);
- throw parser.reportError("msg.unterminated.mstring.appjet");
- }
- if (c == '"') {
- int quoteCount = 0;
- int quoteLimit = 3;
- if (newPolicy && ! afterBackslash)
- quoteLimit = 5;
- while (c == '"' && quoteCount < quoteLimit) {
- quoteCount++;
- c = getChar();
- }
- ungetChar(c);
-
- if (afterBackslash) {
- if (quoteCount < 3) addToString('\\');
- }
- else if (quoteCount >= 3) {
- quoteCount -= 3;
- done = true;
- }
-
- while (quoteCount > 0) {
- addToString('"'); quoteCount--;
- }
- afterBackslash = false;
- }
- else {
- if (afterBackslash) {
- addToString('\\');
- afterBackslash = false;
- }
- if (c == '\\') {
- afterBackslash = true;
- }
- else {
- addToString(c);
- }
- }
- }
-
- String str = getStringFromBuffer();
- this.string = (String)allStrings.intern(str);
-
- return true;
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UintMap.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UintMap.java
deleted file mode 100644
index 0027819..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UintMap.java
+++ /dev/null
@@ -1,659 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * 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;
-
-import java.io.Serializable;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-/**
- * Map to associate non-negative integers to objects or integers.
- * The map does not synchronize any of its operation, so either use
- * it from a single thread or do own synchronization or perform all mutation
- * operations on one thread before passing the map to others.
- *
- * @author Igor Bukanov
- *
- */
-
-public class UintMap implements Serializable
-{
- static final long serialVersionUID = 4242698212885848444L;
-
-// Map implementation via hashtable,
-// follows "The Art of Computer Programming" by Donald E. Knuth
-
- public UintMap() {
- this(4);
- }
-
- public UintMap(int initialCapacity) {
- if (initialCapacity < 0) Kit.codeBug();
- // Table grow when number of stored keys >= 3/4 of max capacity
- int minimalCapacity = initialCapacity * 4 / 3;
- int i;
- for (i = 2; (1 << i) < minimalCapacity; ++i) { }
- power = i;
- if (check && power < 2) Kit.codeBug();
- }
-
- public boolean isEmpty() {
- return keyCount == 0;
- }
-
- public int size() {
- return keyCount;
- }
-
- public boolean has(int key) {
- if (key < 0) Kit.codeBug();
- return 0 <= findIndex(key);
- }
-
- /**
- * Get object value assigned with key.
- * @return key object value or null if key is absent
- */
- public Object getObject(int key) {
- if (key < 0) Kit.codeBug();
- if (values != null) {
- int index = findIndex(key);
- if (0 <= index) {
- return values[index];
- }
- }
- return null;
- }
-
- /**
- * Get integer value assigned with key.
- * @return key integer value or defaultValue if key is absent
- */
- public int getInt(int key, int defaultValue) {
- if (key < 0) Kit.codeBug();
- int index = findIndex(key);
- if (0 <= index) {
- if (ivaluesShift != 0) {
- return keys[ivaluesShift + index];
- }
- return 0;
- }
- return defaultValue;
- }
-
- /**
- * Get integer value assigned with key.
- * @return key integer value or defaultValue if key does not exist or does
- * not have int value
- * @throws RuntimeException if key does not exist
- */
- public int getExistingInt(int key) {
- if (key < 0) Kit.codeBug();
- int index = findIndex(key);
- if (0 <= index) {
- if (ivaluesShift != 0) {
- return keys[ivaluesShift + index];
- }
- return 0;
- }
- // Key must exist
- Kit.codeBug();
- return 0;
- }
-
- /**
- * Set object value of the key.
- * If key does not exist, also set its int value to 0.
- */
- public void put(int key, Object value) {
- if (key < 0) Kit.codeBug();
- int index = ensureIndex(key, false);
- if (values == null) {
- values = new Object[1 << power];
- }
- values[index] = value;
- }
-
- /**
- * Set int value of the key.
- * If key does not exist, also set its object value to null.
- */
- public void put(int key, int value) {
- if (key < 0) Kit.codeBug();
- int index = ensureIndex(key, true);
- if (ivaluesShift == 0) {
- int N = 1 << power;
- // keys.length can be N * 2 after clear which set ivaluesShift to 0
- if (keys.length != N * 2) {
- int[] tmp = new int[N * 2];
- System.arraycopy(keys, 0, tmp, 0, N);
- keys = tmp;
- }
- ivaluesShift = N;
- }
- keys[ivaluesShift + index] = value;
- }
-
- public void remove(int key) {
- if (key < 0) Kit.codeBug();
- int index = findIndex(key);
- if (0 <= index) {
- keys[index] = DELETED;
- --keyCount;
- // Allow to GC value and make sure that new key with the deleted
- // slot shall get proper default values
- if (values != null) { values[index] = null; }
- if (ivaluesShift != 0) { keys[ivaluesShift + index] = 0; }
- }
- }
-
- public void clear() {
- int N = 1 << power;
- if (keys != null) {
- for (int i = 0; i != N; ++i) {
- keys[i] = EMPTY;
- }
- if (values != null) {
- for (int i = 0; i != N; ++i) {
- values[i] = null;
- }
- }
- }
- ivaluesShift = 0;
- keyCount = 0;
- occupiedCount = 0;
- }
-
- /** Return array of present keys */
- public int[] getKeys() {
- int[] keys = this.keys;
- int n = keyCount;
- int[] result = new int[n];
- for (int i = 0; n != 0; ++i) {
- int entry = keys[i];
- if (entry != EMPTY && entry != DELETED) {
- result[--n] = entry;
- }
- }
- return result;
- }
-
- private static int tableLookupStep(int fraction, int mask, int power) {
- int shift = 32 - 2 * power;
- if (shift >= 0) {
- return ((fraction >>> shift) & mask) | 1;
- }
- else {
- return (fraction & (mask >>> -shift)) | 1;
- }
- }
-
- private int findIndex(int key) {
- int[] keys = this.keys;
- if (keys != null) {
- int fraction = key * A;
- int index = fraction >>> (32 - power);
- int entry = keys[index];
- if (entry == key) { return index; }
- if (entry != EMPTY) {
- // Search in table after first failed attempt
- int mask = (1 << power) - 1;
- int step = tableLookupStep(fraction, mask, power);
- int n = 0;
- do {
- if (check) {
- if (n >= occupiedCount) Kit.codeBug();
- ++n;
- }
- index = (index + step) & mask;
- entry = keys[index];
- if (entry == key) { return index; }
- } while (entry != EMPTY);
- }
- }
- return -1;
- }
-
-// Insert key that is not present to table without deleted entries
-// and enough free space
- private int insertNewKey(int key) {
- if (check && occupiedCount != keyCount) Kit.codeBug();
- if (check && keyCount == 1 << power) Kit.codeBug();
- int[] keys = this.keys;
- int fraction = key * A;
- int index = fraction >>> (32 - power);
- if (keys[index] != EMPTY) {
- int mask = (1 << power) - 1;
- int step = tableLookupStep(fraction, mask, power);
- int firstIndex = index;
- do {
- if (check && keys[index] == DELETED) Kit.codeBug();
- index = (index + step) & mask;
- if (check && firstIndex == index) Kit.codeBug();
- } while (keys[index] != EMPTY);
- }
- keys[index] = key;
- ++occupiedCount;
- ++keyCount;
- return index;
- }
-
- private void rehashTable(boolean ensureIntSpace) {
- if (keys != null) {
- // Check if removing deleted entries would free enough space
- if (keyCount * 2 >= occupiedCount) {
- // Need to grow: less then half of deleted entries
- ++power;
- }
- }
- int N = 1 << power;
- int[] old = keys;
- int oldShift = ivaluesShift;
- if (oldShift == 0 && !ensureIntSpace) {
- keys = new int[N];
- }
- else {
- ivaluesShift = N; keys = new int[N * 2];
- }
- for (int i = 0; i != N; ++i) { keys[i] = EMPTY; }
-
- Object[] oldValues = values;
- if (oldValues != null) { values = new Object[N]; }
-
- int oldCount = keyCount;
- occupiedCount = 0;
- if (oldCount != 0) {
- keyCount = 0;
- for (int i = 0, remaining = oldCount; remaining != 0; ++i) {
- int key = old[i];
- if (key != EMPTY && key != DELETED) {
- int index = insertNewKey(key);
- if (oldValues != null) {
- values[index] = oldValues[i];
- }
- if (oldShift != 0) {
- keys[ivaluesShift + index] = old[oldShift + i];
- }
- --remaining;
- }
- }
- }
- }
-
-// Ensure key index creating one if necessary
- private int ensureIndex(int key, boolean intType) {
- int index = -1;
- int firstDeleted = -1;
- int[] keys = this.keys;
- if (keys != null) {
- int fraction = key * A;
- index = fraction >>> (32 - power);
- int entry = keys[index];
- if (entry == key) { return index; }
- if (entry != EMPTY) {
- if (entry == DELETED) { firstDeleted = index; }
- // Search in table after first failed attempt
- int mask = (1 << power) - 1;
- int step = tableLookupStep(fraction, mask, power);
- int n = 0;
- do {
- if (check) {
- if (n >= occupiedCount) Kit.codeBug();
- ++n;
- }
- index = (index + step) & mask;
- entry = keys[index];
- if (entry == key) { return index; }
- if (entry == DELETED && firstDeleted < 0) {
- firstDeleted = index;
- }
- } while (entry != EMPTY);
- }
- }
- // Inserting of new key
- if (check && keys != null && keys[index] != EMPTY)
- Kit.codeBug();
- if (firstDeleted >= 0) {
- index = firstDeleted;
- }
- else {
- // Need to consume empty entry: check occupation level
- if (keys == null || occupiedCount * 4 >= (1 << power) * 3) {
- // Too litle unused entries: rehash
- rehashTable(intType);
- keys = this.keys;
- return insertNewKey(key);
- }
- ++occupiedCount;
- }
- keys[index] = key;
- ++keyCount;
- return index;
- }
-
- private void writeObject(ObjectOutputStream out)
- throws IOException
- {
- out.defaultWriteObject();
-
- int count = keyCount;
- if (count != 0) {
- boolean hasIntValues = (ivaluesShift != 0);
- boolean hasObjectValues = (values != null);
- out.writeBoolean(hasIntValues);
- out.writeBoolean(hasObjectValues);
-
- for (int i = 0; count != 0; ++i) {
- int key = keys[i];
- if (key != EMPTY && key != DELETED) {
- --count;
- out.writeInt(key);
- if (hasIntValues) {
- out.writeInt(keys[ivaluesShift + i]);
- }
- if (hasObjectValues) {
- out.writeObject(values[i]);
- }
- }
- }
- }
- }
-
- private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- in.defaultReadObject();
-
- int writtenKeyCount = keyCount;
- if (writtenKeyCount != 0) {
- keyCount = 0;
- boolean hasIntValues = in.readBoolean();
- boolean hasObjectValues = in.readBoolean();
-
- int N = 1 << power;
- if (hasIntValues) {
- keys = new int[2 * N];
- ivaluesShift = N;
- }else {
- keys = new int[N];
- }
- for (int i = 0; i != N; ++i) {
- keys[i] = EMPTY;
- }
- if (hasObjectValues) {
- values = new Object[N];
- }
- for (int i = 0; i != writtenKeyCount; ++i) {
- int key = in.readInt();
- int index = insertNewKey(key);
- if (hasIntValues) {
- int ivalue = in.readInt();
- keys[ivaluesShift + index] = ivalue;
- }
- if (hasObjectValues) {
- values[index] = in.readObject();
- }
- }
- }
- }
-
-// A == golden_ratio * (1 << 32) = ((sqrt(5) - 1) / 2) * (1 << 32)
-// See Knuth etc.
- private static final int A = 0x9e3779b9;
-
- private static final int EMPTY = -1;
- private static final int DELETED = -2;
-
-// Structure of kyes and values arrays (N == 1 << power):
-// keys[0 <= i < N]: key value or EMPTY or DELETED mark
-// values[0 <= i < N]: value of key at keys[i]
-// keys[N <= i < 2N]: int values of keys at keys[i - N]
-
- private transient int[] keys;
- private transient Object[] values;
-
- private int power;
- private int keyCount;
- private transient int occupiedCount; // == keyCount + deleted_count
-
- // If ivaluesShift != 0, keys[ivaluesShift + index] contains integer
- // values associated with keys
- private transient int ivaluesShift;
-
-// If true, enables consitency checks
- private static final boolean check = false;
-
-/* TEST START
-
- public static void main(String[] args) {
- if (!check) {
- System.err.println("Set check to true and re-run");
- throw new RuntimeException("Set check to true and re-run");
- }
-
- UintMap map;
- map = new UintMap();
- testHash(map, 2);
- map = new UintMap();
- testHash(map, 10 * 1000);
- map = new UintMap(30 * 1000);
- testHash(map, 10 * 100);
- map.clear();
- testHash(map, 4);
- map = new UintMap(0);
- testHash(map, 10 * 100);
- }
-
- private static void testHash(UintMap map, int N) {
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- map.put(i, i);
- check(i == map.getInt(i, -1));
- }
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- map.put(i, i);
- check(i == map.getInt(i, -1));
- }
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- map.put(i, new Integer(i));
- check(-1 == map.getInt(i, -1));
- Integer obj = (Integer)map.getObject(i);
- check(obj != null && i == obj.intValue());
- }
-
- check(map.size() == N);
-
- System.out.print("."); System.out.flush();
- int[] keys = map.getKeys();
- check(keys.length == N);
- for (int i = 0; i != N; ++i) {
- int key = keys[i];
- check(map.has(key));
- check(!map.isIntType(key));
- check(map.isObjectType(key));
- Integer obj = (Integer) map.getObject(key);
- check(obj != null && key == obj.intValue());
- }
-
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- check(-1 == map.getInt(i, -1));
- }
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- map.put(i * i, i);
- check(i == map.getInt(i * i, -1));
- }
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- check(i == map.getInt(i * i, -1));
- }
-
- System.out.print("."); System.out.flush();
- for (int i = 0; i != N; ++i) {
- map.put(i * i, new Integer(i));
- check(-1 == map.getInt(i * i, -1));
- map.remove(i * i);
- check(!map.has(i * i));
- map.put(i * i, i);
- check(map.isIntType(i * i));
- check(null == map.getObject(i * i));
- map.remove(i * i);
- check(!map.isObjectType(i * i));
- check(!map.isIntType(i * i));
- }
-
- int old_size = map.size();
- for (int i = 0; i != N; ++i) {
- map.remove(i * i);
- check(map.size() == old_size);
- }
-
- System.out.print("."); System.out.flush();
- map.clear();
- check(map.size() == 0);
- for (int i = 0; i != N; ++i) {
- map.put(i * i, i);
- map.put(i * i + 1, new Double(i+0.5));
- }
- checkSameMaps(map, (UintMap)writeAndRead(map));
-
- System.out.print("."); System.out.flush();
- map = new UintMap(0);
- checkSameMaps(map, (UintMap)writeAndRead(map));
- map = new UintMap(1);
- checkSameMaps(map, (UintMap)writeAndRead(map));
- map = new UintMap(1000);
- checkSameMaps(map, (UintMap)writeAndRead(map));
-
- System.out.print("."); System.out.flush();
- map = new UintMap(N / 10);
- for (int i = 0; i != N; ++i) {
- map.put(2*i+1, i);
- }
- checkSameMaps(map, (UintMap)writeAndRead(map));
-
- System.out.print("."); System.out.flush();
- map = new UintMap(N / 10);
- for (int i = 0; i != N; ++i) {
- map.put(2*i+1, i);
- }
- for (int i = 0; i != N / 2; ++i) {
- map.remove(2*i+1);
- }
- checkSameMaps(map, (UintMap)writeAndRead(map));
-
- System.out.print("."); System.out.flush();
- map = new UintMap();
- for (int i = 0; i != N; ++i) {
- map.put(2*i+1, new Double(i + 10));
- }
- for (int i = 0; i != N / 2; ++i) {
- map.remove(2*i+1);
- }
- checkSameMaps(map, (UintMap)writeAndRead(map));
-
- System.out.println(); System.out.flush();
-
- }
-
- private static void checkSameMaps(UintMap map1, UintMap map2) {
- check(map1.size() == map2.size());
- int[] keys = map1.getKeys();
- check(keys.length == map1.size());
- for (int i = 0; i != keys.length; ++i) {
- int key = keys[i];
- check(map2.has(key));
- check(map1.isObjectType(key) == map2.isObjectType(key));
- check(map1.isIntType(key) == map2.isIntType(key));
- Object o1 = map1.getObject(key);
- Object o2 = map2.getObject(key);
- if (map1.isObjectType(key)) {
- check(o1.equals(o2));
- }else {
- check(map1.getObject(key) == null);
- check(map2.getObject(key) == null);
- }
- if (map1.isIntType(key)) {
- check(map1.getExistingInt(key) == map2.getExistingInt(key));
- }else {
- check(map1.getInt(key, -10) == -10);
- check(map1.getInt(key, -11) == -11);
- check(map2.getInt(key, -10) == -10);
- check(map2.getInt(key, -11) == -11);
- }
- }
- }
-
- private static void check(boolean condition) {
- if (!condition) Kit.codeBug();
- }
-
- private static Object writeAndRead(Object obj) {
- try {
- java.io.ByteArrayOutputStream
- bos = new java.io.ByteArrayOutputStream();
- java.io.ObjectOutputStream
- out = new java.io.ObjectOutputStream(bos);
- out.writeObject(obj);
- out.close();
- byte[] data = bos.toByteArray();
- java.io.ByteArrayInputStream
- bis = new java.io.ByteArrayInputStream(data);
- java.io.ObjectInputStream
- in = new java.io.ObjectInputStream(bis);
- Object result = in.readObject();
- in.close();
- return result;
- }catch (Exception ex) {
- ex.printStackTrace();
- throw new RuntimeException("Unexpected");
- }
- }
-
-// TEST END */
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Undefined.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Undefined.java
deleted file mode 100644
index 472f26c..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Undefined.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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
- *
- * 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;
-
-import java.io.Serializable;
-
-/**
- * This class implements the Undefined value in JavaScript.
- */
-public class Undefined implements Serializable
-{
- static final long serialVersionUID = 9195680630202616767L;
-
- public static final Object instance = new Undefined();
-
- private Undefined()
- {
- }
-
- public Object readResolve()
- {
- return instance;
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UniqueTag.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UniqueTag.java
deleted file mode 100644
index 33f96eb..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UniqueTag.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/* -*- 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):
- * 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;
-
-import java.io.Serializable;
-
-/**
- * Class instances represent serializable tags to mark special Object values.
- * <p>
- * Compatibility note: under jdk 1.1 use
- * org.mozilla.javascript.serialize.ScriptableInputStream to read serialized
- * instances of UniqueTag as under this JDK version the default
- * ObjectInputStream would not restore them correctly as it lacks support
- * for readResolve method
- */
-public final class UniqueTag implements Serializable
-{
- static final long serialVersionUID = -4320556826714577259L;
-
- private static final int ID_NOT_FOUND = 1;
- private static final int ID_NULL_VALUE = 2;
- private static final int ID_DOUBLE_MARK = 3;
-
- /**
- * Tag to mark non-existing values.
- */
- public static final UniqueTag
- NOT_FOUND = new UniqueTag(ID_NOT_FOUND);
-
- /**
- * Tag to distinguish between uninitialized and null values.
- */
- public static final UniqueTag
- NULL_VALUE = new UniqueTag(ID_NULL_VALUE);
-
- /**
- * Tag to indicate that a object represents "double" with the real value
- * stored somewhere else.
- */
- public static final UniqueTag
- DOUBLE_MARK = new UniqueTag(ID_DOUBLE_MARK);
-
- private final int tagId;
-
- private UniqueTag(int tagId)
- {
- this.tagId = tagId;
- }
-
- public Object readResolve()
- {
- switch (tagId) {
- case ID_NOT_FOUND:
- return NOT_FOUND;
- case ID_NULL_VALUE:
- return NULL_VALUE;
- case ID_DOUBLE_MARK:
- return DOUBLE_MARK;
- }
- throw new IllegalStateException(String.valueOf(tagId));
- }
-
-// Overridden for better debug printouts
- public String toString()
- {
- String name;
- switch (tagId) {
- case ID_NOT_FOUND:
- name = "NOT_FOUND";
- break;
- case ID_NULL_VALUE:
- name = "NULL_VALUE";
- break;
- case ID_DOUBLE_MARK:
- name = "DOUBLE_MARK";
- break;
- default:
- throw Kit.codeBug();
- }
- return super.toString()+": "+name;
- }
-
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/VMBridge.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/VMBridge.java
deleted file mode 100644
index 5fba4a5..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/VMBridge.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Member;
-import java.util.Iterator;
-
-public abstract class VMBridge
-{
-
- static final VMBridge instance = makeInstance();
-
- private static VMBridge makeInstance()
- {
- String[] classNames = {
- "org.mozilla.javascript.VMBridge_custom",
- "org.mozilla.javascript.jdk15.VMBridge_jdk15",
- "org.mozilla.javascript.jdk13.VMBridge_jdk13",
- "org.mozilla.javascript.jdk11.VMBridge_jdk11",
- };
- for (int i = 0; i != classNames.length; ++i) {
- String className = classNames[i];
- Class cl = Kit.classOrNull(className);
- if (cl != null) {
- VMBridge bridge = (VMBridge)Kit.newInstanceOrNull(cl);
- if (bridge != null) {
- return bridge;
- }
- }
- }
- throw new IllegalStateException("Failed to create VMBridge instance");
- }
-
- /**
- * Return a helper object to optimize {@link Context} access.
- * <p>
- * The runtime will pass the resulting helper object to the subsequent
- * calls to {@link #getContext(Object contextHelper)} and
- * {@link #setContext(Object contextHelper, Context cx)} methods.
- * In this way the implementation can use the helper to cache
- * information about current thread to make {@link Context} access faster.
- */
- protected abstract Object getThreadContextHelper();
-
- /**
- * Get {@link Context} instance associated with the current thread
- * or null if none.
- *
- * @param contextHelper The result of {@link #getThreadContextHelper()}
- * called from the current thread.
- */
- protected abstract Context getContext(Object contextHelper);
-
- /**
- * Associate {@link Context} instance with the current thread or remove
- * the current association if <tt>cx</tt> is null.
- *
- * @param contextHelper The result of {@link #getThreadContextHelper()}
- * called from the current thread.
- */
- protected abstract void setContext(Object contextHelper, Context cx);
-
- /**
- * Return the ClassLoader instance associated with the current thread.
- */
- protected abstract ClassLoader getCurrentThreadClassLoader();
-
- /**
- * In many JVMSs, public methods in private
- * classes are not accessible by default (Sun Bug #4071593).
- * VMBridge instance should try to workaround that via, for example,
- * calling method.setAccessible(true) when it is available.
- * The implementation is responsible to catch all possible exceptions
- * like SecurityException if the workaround is not available.
- *
- * @return true if it was possible to make method accessible
- * or false otherwise.
- */
- protected abstract boolean tryToMakeAccessible(Object accessibleObject);
-
- /**
- * Create helper object to create later proxies implementing the specified
- * interfaces later. Under JDK 1.3 the implementation can look like:
- * <pre>
- * return java.lang.reflect.Proxy.getProxyClass(..., interfaces).
- * getConstructor(new Class[] {
- * java.lang.reflect.InvocationHandler.class });
- * </pre>
- *
- * @param interfaces Array with one or more interface class objects.
- */
- protected Object getInterfaceProxyHelper(ContextFactory cf,
- Class[] interfaces)
- {
- throw Context.reportRuntimeError(
- "VMBridge.getInterfaceProxyHelper is not supported");
- }
-
- /**
- * Create proxy object for {@link InterfaceAdapter}. The proxy should call
- * {@link InterfaceAdapter#invoke(ContextFactory cf,
- * Object target,
- * Scriptable topScope,
- * Method method,
- * Object[] args)}
- * as implementation of interface methods associated with
- * <tt>proxyHelper</tt>.
- *
- * @param proxyHelper The result of the previous call to
- * {@link #getInterfaceProxyHelper(ContextFactory, Class[])}.
- */
- protected Object newInterfaceProxy(Object proxyHelper,
- ContextFactory cf,
- InterfaceAdapter adapter,
- Object target,
- Scriptable topScope)
- {
- throw Context.reportRuntimeError(
- "VMBridge.newInterfaceProxy is not supported");
- }
-
- /**
- * Returns whether or not a given member (method or constructor)
- * has variable arguments.
- * Variable argument methods have only been supported in Java since
- * JDK 1.5.
- */
- protected abstract boolean isVarArgs(Member member);
-
- /**
- * If "obj" is a java.util.Iterator or a java.lang.Iterable, return a
- * wrapping as a JavaScript Iterator. Otherwise, return null.
- * This method is in VMBridge since Iterable is a JDK 1.5 addition.
- */
- public Iterator getJavaIterator(Context cx, Scriptable scope, Object obj) {
- if (obj instanceof Wrapper) {
- Object unwrapped = ((Wrapper) obj).unwrap();
- Iterator iterator = null;
- if (unwrapped instanceof Iterator)
- iterator = (Iterator) unwrapped;
- return iterator;
- }
- return null;
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrapFactory.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrapFactory.java
deleted file mode 100644
index 3edc203..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrapFactory.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/* -*- 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-2000
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * Embeddings that wish to provide their own custom wrappings for Java
- * objects may extend this class and call
- * {@link Context#setWrapFactory(WrapFactory)}
- * Once an instance of this class or an extension of this class is enabled
- * for a given context (by calling setWrapFactory on that context), Rhino
- * will call the methods of this class whenever it needs to wrap a value
- * resulting from a call to a Java method or an access to a Java field.
- *
- * @see org.mozilla.javascript.Context#setWrapFactory(WrapFactory)
- * @since 1.5 Release 4
- */
-public class WrapFactory
-{
- /**
- * Wrap the object.
- * <p>
- * The value returned must be one of
- * <UL>
- * <LI>java.lang.Boolean</LI>
- * <LI>java.lang.String</LI>
- * <LI>java.lang.Number</LI>
- * <LI>org.mozilla.javascript.Scriptable objects</LI>
- * <LI>The value returned by Context.getUndefinedValue()</LI>
- * <LI>null</LI>
- * </UL>
- * @param cx the current Context for this thread
- * @param scope the scope of the executing script
- * @param obj the object to be wrapped. Note it can be null.
- * @param staticType type hint. If security restrictions prevent to wrap
- object based on its class, staticType will be used instead.
- * @return the wrapped value.
- */
- public Object wrap(Context cx, Scriptable scope,
- Object obj, Class staticType)
- {
- if (obj == null || obj == Undefined.instance
- || obj instanceof Scriptable)
- {
- return obj;
- }
- if (staticType != null && staticType.isPrimitive()) {
- if (staticType == Void.TYPE)
- return Undefined.instance;
- if (staticType == Character.TYPE)
- return new Integer(((Character) obj).charValue());
- return obj;
- }
- if (!isJavaPrimitiveWrap()) {
- if (obj instanceof String || obj instanceof Number
- || obj instanceof Boolean)
- {
- return obj;
- } else if (obj instanceof Character) {
- return String.valueOf(((Character)obj).charValue());
- }
- }
- Class cls = obj.getClass();
- if (cls.isArray()) {
- return NativeJavaArray.wrap(scope, obj);
- }
- return wrapAsJavaObject(cx, scope, obj, staticType);
- }
-
- /**
- * Wrap an object newly created by a constructor call.
- * @param cx the current Context for this thread
- * @param scope the scope of the executing script
- * @param obj the object to be wrapped
- * @return the wrapped value.
- */
- public Scriptable wrapNewObject(Context cx, Scriptable scope, Object obj)
- {
- if (obj instanceof Scriptable) {
- return (Scriptable)obj;
- }
- Class cls = obj.getClass();
- if (cls.isArray()) {
- return NativeJavaArray.wrap(scope, obj);
- }
- return wrapAsJavaObject(cx, scope, obj, null);
- }
-
- /**
- * Wrap Java object as Scriptable instance to allow full access to its
- * methods and fields from JavaScript.
- * <p>
- * {@link #wrap(Context, Scriptable, Object, Class)} and
- * {@link #wrapNewObject(Context, Scriptable, Object)} call this method
- * when they can not convert <tt>javaObject</tt> to JavaScript primitive
- * value or JavaScript array.
- * <p>
- * Subclasses can override the method to provide custom wrappers
- * for Java objects.
- * @param cx the current Context for this thread
- * @param scope the scope of the executing script
- * @param javaObject the object to be wrapped
- * @param staticType type hint. If security restrictions prevent to wrap
- object based on its class, staticType will be used instead.
- * @return the wrapped value which shall not be null
- */
- public Scriptable wrapAsJavaObject(Context cx, Scriptable scope,
- Object javaObject, Class staticType)
- {
- Scriptable wrap;
- wrap = new NativeJavaObject(scope, javaObject, staticType);
- return wrap;
- }
-
- /**
- * Return <code>false</code> if result of Java method, which is instance of
- * <code>String</code>, <code>Number</code>, <code>Boolean</code> and
- * <code>Character</code>, should be used directly as JavaScript primitive
- * type.
- * By default the method returns true to indicate that instances of
- * <code>String</code>, <code>Number</code>, <code>Boolean</code> and
- * <code>Character</code> should be wrapped as any other Java object and
- * scripts can access any Java method available in these objects.
- * Use {@link #setJavaPrimitiveWrap(boolean)} to change this.
- */
- public final boolean isJavaPrimitiveWrap()
- {
- return javaPrimitiveWrap;
- }
-
- /**
- * @see #isJavaPrimitiveWrap()
- */
- public final void setJavaPrimitiveWrap(boolean value)
- {
- Context cx = Context.getCurrentContext();
- if (cx != null && cx.isSealed()) {
- Context.onSealedMutation();
- }
- javaPrimitiveWrap = value;
- }
-
- private boolean javaPrimitiveWrap = true;
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrappedException.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrappedException.java
deleted file mode 100644
index c749f74..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrappedException.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- 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
- *
- * 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;
-
-/**
- * A wrapper for runtime exceptions.
- *
- * Used by the JavaScript runtime to wrap and propagate exceptions that occur
- * during runtime.
- *
- * @author Norris Boyd
- */
-public class WrappedException extends EvaluatorException
-{
- static final long serialVersionUID = -1551979216966520648L;
-
- /**
- * @see Context#throwAsScriptRuntimeEx(Throwable e)
- */
- public WrappedException(Throwable exception)
- {
- super("Wrapped "+exception.toString());
- this.exception = exception;
- Kit.initCause(this, exception);
-
- int[] linep = { 0 };
- String sourceName = Context.getSourcePositionFromStack(linep);
- int lineNumber = linep[0];
- if (sourceName != null) {
- initSourceName(sourceName);
- }
- if (lineNumber != 0) {
- initLineNumber(lineNumber);
- }
- }
-
- /**
- * Get the wrapped exception.
- *
- * @return the exception that was presented as a argument to the
- * constructor when this object was created
- */
- public Throwable getWrappedException()
- {
- return exception;
- }
-
- /**
- * @deprecated Use {@link #getWrappedException()} instead.
- */
- public Object unwrap()
- {
- return getWrappedException();
- }
-
- private Throwable exception;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Wrapper.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Wrapper.java
deleted file mode 100644
index cb2d2f5..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Wrapper.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript;
-
-/**
- * Objects that can wrap other values for reflection in the JS environment
- * will implement Wrapper.
- *
- * Wrapper defines a single method that can be called to unwrap the object.
- */
-
-public interface Wrapper {
-
- /**
- * Unwrap the object by returning the wrapped value.
- *
- * @return a wrapped value
- */
- public Object unwrap();
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/continuations/Continuation.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/continuations/Continuation.java
deleted file mode 100644
index c6d3966..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/continuations/Continuation.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- 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):
- * 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.continuations;
-
-import org.mozilla.javascript.*;
-
-public final class Continuation extends IdScriptableObject implements Function
-{
- static final long serialVersionUID = 1794167133757605367L;
-
- private static final Object FTAG = new Object();
-
- private Object implementation;
-
- public static void init(Context cx, Scriptable scope, boolean sealed)
- {
- Continuation obj = new Continuation();
- obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
- }
-
- public Object getImplementation()
- {
- return implementation;
- }
-
- public void initImplementation(Object implementation)
- {
- this.implementation = implementation;
- }
-
- public String getClassName()
- {
- return "Continuation";
- }
-
- public Scriptable construct(Context cx, Scriptable scope, Object[] args)
- {
- throw Context.reportRuntimeError("Direct call is not supported");
- }
-
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- return Interpreter.restartContinuation(this, cx, scope, args);
- }
-
- public static boolean isContinuationConstructor(IdFunctionObject f)
- {
- if (f.hasTag(FTAG) && f.methodId() == Id_constructor) {
- return true;
- }
- return false;
- }
-
- protected void initPrototypeId(int id)
- {
- String s;
- int arity;
- switch (id) {
- case Id_constructor: arity=0; s="constructor"; break;
- default: throw new IllegalArgumentException(String.valueOf(id));
- }
- initPrototypeMethod(FTAG, id, s, arity);
- }
-
- public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(FTAG)) {
- return super.execIdCall(f, cx, scope, thisObj, args);
- }
- int id = f.methodId();
- switch (id) {
- case Id_constructor:
- throw Context.reportRuntimeError("Direct call is not supported");
- }
- throw new IllegalArgumentException(String.valueOf(id));
- }
-
-// #string_id_map#
-
- protected int findPrototypeId(String s)
- {
- int id;
-// #generated# Last update: 2007-05-09 08:16:40 EDT
- L0: { id = 0; String X = null;
- if (s.length()==11) { X="constructor";id=Id_constructor; }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- Id_constructor = 1,
- MAX_PROTOTYPE_ID = 1;
-
-// #/string_id_map#
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebugFrame.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebugFrame.java
deleted file mode 100644
index ef15710..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebugFrame.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript.debug;
-
-import org.mozilla.javascript.Context;
-import org.mozilla.javascript.Scriptable;
-
-/**
-Interface to implement if the application is interested in receiving debug
-information during execution of a particular script or function.
-*/
-public interface DebugFrame {
-
-/**
-Called when execution is ready to start bytecode interpretation for entered a particular function or script.
-
-@param cx current Context for this thread
-@param activation the activation scope for the function or script.
-@param thisObj value of the JavaScript <code>this</code> object
-@param args the array of arguments
-*/
- public void onEnter(Context cx, Scriptable activation,
- Scriptable thisObj, Object[] args);
-/**
-Called when executed code reaches new line in the source.
-@param cx current Context for this thread
-@param lineNumber current line number in the script source
-*/
- public void onLineChange(Context cx, int lineNumber);
-
-/**
-Called when thrown exception is handled by the function or script.
-@param cx current Context for this thread
-@param ex exception object
-*/
- public void onExceptionThrown(Context cx, Throwable ex);
-
-/**
-Called when the function or script for this frame is about to return.
-@param cx current Context for this thread
-@param byThrow if true function will leave by throwing exception, otherwise it
- will execute normal return
-@param resultOrException function result in case of normal return or
- exception object if about to throw exception
-*/
- public void onExit(Context cx, boolean byThrow, Object resultOrException);
-
-/**
-Called when the function or script executes a 'debugger' statement.
-@param cx current Context for this thread
-*/
- public void onDebuggerStatement(Context cx);
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableObject.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableObject.java
deleted file mode 100644
index 23e7421..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableObject.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript.debug;
-
-/**
- * This interface exposes debugging information from objects.
- */
-public interface DebuggableObject {
-
- /**
- * Returns an array of ids for the properties of the object.
- *
- * <p>All properties, even those with attribute {DontEnum}, are listed.
- * This allows the debugger to display all properties of the object.<p>
- *
- * @return an array of java.lang.Objects with an entry for every
- * listed property. Properties accessed via an integer index will
- * have a corresponding
- * Integer entry in the returned array. Properties accessed by
- * a String will have a String entry in the returned array.
- */
- public Object[] getAllIds();
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableScript.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableScript.java
deleted file mode 100644
index 705e442..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableScript.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/* -*- 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-2000
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript.debug;
-
-/**
- * This interface exposes debugging information from executable
- * code (either functions or top-level scripts).
- */
-public interface DebuggableScript
-{
- public boolean isTopLevel();
-
- /**
- * Returns true if this is a function, false if it is a script.
- */
- public boolean isFunction();
-
- /**
- * Get name of the function described by this script.
- * Return null or an empty string if this script is not a function.
- */
- public String getFunctionName();
-
- /**
- * Get number of declared parameters in the function.
- * Return 0 if this script is not a function.
- *
- * @see #getParamAndVarCount()
- * @see #getParamOrVarName(int index)
- */
- public int getParamCount();
-
- /**
- * Get number of declared parameters and local variables.
- * Return number of declared global variables if this script is not a
- * function.
- *
- * @see #getParamCount()
- * @see #getParamOrVarName(int index)
- */
- public int getParamAndVarCount();
-
- /**
- * Get name of a declared parameter or local variable.
- * <tt>index</tt> should be less then {@link #getParamAndVarCount()}.
- * If <tt>index&nbsp;&lt;&nbsp;{@link #getParamCount()}</tt>, return
- * the name of the corresponding parameter, otherwise return the name
- * of variable.
- * If this script is not function, return the name of the declared
- * global variable.
- */
- public String getParamOrVarName(int index);
-
- /**
- * Get the name of the source (usually filename or URL)
- * of the script.
- */
- public String getSourceName();
-
- /**
- * Returns true if this script or function were runtime-generated
- * from JavaScript using <tt>eval</tt> function or <tt>Function</tt>
- * or <tt>Script</tt> constructors.
- */
- public boolean isGeneratedScript();
-
- /**
- * Get array containing the line numbers that
- * that can be passed to <code>DebugFrame.onLineChange()<code>.
- * Note that line order in the resulting array is arbitrary
- */
- public int[] getLineNumbers();
-
- public int getFunctionCount();
-
- public DebuggableScript getFunction(int index);
-
- public DebuggableScript getParent();
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/Debugger.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/Debugger.java
deleted file mode 100644
index bfac153..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/Debugger.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript.debug;
-
-import org.mozilla.javascript.Context;
-
-/**
-Interface to implement if the application is interested in receiving debug
-information.
-*/
-public interface Debugger {
-
-/**
-Called when compilation of a particular function or script into internal
-bytecode is done.
-
-@param cx current Context for this thread
-@param fnOrScript object describing the function or script
-@param source the function or script source
-*/
- void handleCompilationDone(Context cx, DebuggableScript fnOrScript,
- String source);
-
-/**
-Called when execution entered a particular function or script.
-
-@return implementation of DebugFrame which receives debug information during
- the function or script execution or null otherwise
-*/
- DebugFrame getFrame(Context cx, DebuggableScript fnOrScript);
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk11/VMBridge_jdk11.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk11/VMBridge_jdk11.java
deleted file mode 100644
index f5d1522..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk11/VMBridge_jdk11.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * 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.jdk11;
-
-import java.lang.reflect.Member;
-import java.util.Hashtable;
-
-import org.mozilla.javascript.*;
-
-public class VMBridge_jdk11 extends VMBridge
-{
- private Hashtable threadsWithContext = new Hashtable();
-
- protected Object getThreadContextHelper()
- {
- return Thread.currentThread();
- }
-
- protected Context getContext(Object contextHelper)
- {
- Thread t = (Thread)contextHelper;
- return (Context)threadsWithContext.get(t);
- }
-
- protected void setContext(Object contextHelper, Context cx)
- {
- Thread t = (Thread)contextHelper;
- if (cx == null) {
- // Allow to garbage collect thread reference
- threadsWithContext.remove(t);
- } else {
- threadsWithContext.put(t, cx);
- }
- }
-
- protected ClassLoader getCurrentThreadClassLoader()
- {
- return null;
- }
-
- protected boolean tryToMakeAccessible(Object accessibleObject)
- {
- return false;
- }
-
- protected boolean isVarArgs(Member member) {
- return false;
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk13/VMBridge_jdk13.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk13/VMBridge_jdk13.java
deleted file mode 100644
index c33e9b4..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk13/VMBridge_jdk13.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * 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.jdk13;
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Member;
-import java.lang.reflect.Proxy;
-
-import org.mozilla.javascript.*;
-
-public class VMBridge_jdk13 extends VMBridge
-{
- private ThreadLocal contextLocal = new ThreadLocal();
-
- protected Object getThreadContextHelper()
- {
- // To make subsequent batch calls to getContext/setContext faster
- // associate permanently one element array with contextLocal
- // so getContext/setContext would need just to read/write the first
- // array element.
- // Note that it is necessary to use Object[], not Context[] to allow
- // garbage collection of Rhino classes. For details see comments
- // by Attila Szegedi in
- // https://bugzilla.mozilla.org/show_bug.cgi?id=281067#c5
-
- Object[] storage = (Object[])contextLocal.get();
- if (storage == null) {
- storage = new Object[1];
- contextLocal.set(storage);
- }
- return storage;
- }
-
- protected Context getContext(Object contextHelper)
- {
- Object[] storage = (Object[])contextHelper;
- return (Context)storage[0];
- }
-
- protected void setContext(Object contextHelper, Context cx)
- {
- Object[] storage = (Object[])contextHelper;
- storage[0] = cx;
- }
-
- protected ClassLoader getCurrentThreadClassLoader()
- {
- return Thread.currentThread().getContextClassLoader();
- }
-
- protected boolean tryToMakeAccessible(Object accessibleObject)
- {
- if (!(accessibleObject instanceof AccessibleObject)) {
- return false;
- }
- AccessibleObject accessible = (AccessibleObject)accessibleObject;
- if (accessible.isAccessible()) {
- return true;
- }
- try {
- accessible.setAccessible(true);
- } catch (Exception ex) { }
-
- return accessible.isAccessible();
- }
-
- protected Object getInterfaceProxyHelper(ContextFactory cf,
- Class[] interfaces)
- {
- // XXX: How to handle interfaces array withclasses from different
- // class loaders? Using cf.getApplicationClassLoader() ?
- ClassLoader loader = interfaces[0].getClassLoader();
- Class cl = Proxy.getProxyClass(loader, interfaces);
- Constructor c;
- try {
- c = cl.getConstructor(new Class[] { InvocationHandler.class });
- } catch (NoSuchMethodException ex) {
- // Should not happen
- throw Kit.initCause(new IllegalStateException(), ex);
- }
- return c;
- }
-
- protected Object newInterfaceProxy(Object proxyHelper,
- final ContextFactory cf,
- final InterfaceAdapter adapter,
- final Object target,
- final Scriptable topScope)
- {
- Constructor c = (Constructor)proxyHelper;
-
- InvocationHandler handler = new InvocationHandler() {
- public Object invoke(Object proxy,
- Method method,
- Object[] args)
- {
- return adapter.invoke(cf, target, topScope, method, args);
- }
- };
- Object proxy;
- try {
- proxy = c.newInstance(new Object[] { handler });
- } catch (InvocationTargetException ex) {
- throw Context.throwAsScriptRuntimeEx(ex);
- } catch (IllegalAccessException ex) {
- // Shouls not happen
- throw Kit.initCause(new IllegalStateException(), ex);
- } catch (InstantiationException ex) {
- // Shouls not happen
- throw Kit.initCause(new IllegalStateException(), ex);
- }
- return proxy;
- }
-
- protected boolean isVarArgs(Member member) {
- return false;
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk15/VMBridge_jdk15.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk15/VMBridge_jdk15.java
deleted file mode 100644
index 0ffaf9d..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk15/VMBridge_jdk15.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * 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.jdk15;
-
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Constructor;
-import java.util.Iterator;
-import org.mozilla.javascript.*;
-
-public class VMBridge_jdk15 extends org.mozilla.javascript.jdk13.VMBridge_jdk13
-{
- public VMBridge_jdk15() throws SecurityException, InstantiationException {
- try {
- // Just try and see if we can access the isVarArgs method.
- // We want to fail loading if the method does not exist
- // so that we can load a bridge to an older JDK instead.
- Method.class.getMethod("isVarArgs", (Class[]) null);
- } catch (NoSuchMethodException e) {
- // Throw a fitting exception that is handled by
- // org.mozilla.javascript.Kit.newInstanceOrNull:
- throw new InstantiationException(e.getMessage());
- }
- }
-
- public boolean isVarArgs(Member member) {
- if (member instanceof Method)
- return ((Method) member).isVarArgs();
- else if (member instanceof Constructor)
- return ((Constructor) member).isVarArgs();
- else
- return false;
- }
-
- /**
- * If "obj" is a java.util.Iterator or a java.lang.Iterable, return a
- * wrapping as a JavaScript Iterator. Otherwise, return null.
- * This method is in VMBridge since Iterable is a JDK 1.5 addition.
- */
- public Iterator getJavaIterator(Context cx, Scriptable scope, Object obj) {
- if (obj instanceof Wrapper) {
- Object unwrapped = ((Wrapper) obj).unwrap();
- Iterator iterator = null;
- if (unwrapped instanceof Iterator)
- iterator = (Iterator) unwrapped;
- if (unwrapped instanceof Iterable)
- iterator = ((Iterable)unwrapped).iterator();
- return iterator;
- }
- return null;
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Block.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Block.java
deleted file mode 100644
index bd56714..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Block.java
+++ /dev/null
@@ -1,615 +0,0 @@
-/* ***** 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
- * Roger Lawrence
- *
- * 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.optimizer;
-
-import org.mozilla.javascript.*;
-
-import java.util.Hashtable;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-class Block
-{
-
- private static class FatBlock
- {
-
- private static Block[] reduceToArray(ObjToIntMap map)
- {
- Block[] result = null;
- if (!map.isEmpty()) {
- result = new Block[map.size()];
- int i = 0;
- ObjToIntMap.Iterator iter = map.newIterator();
- for (iter.start(); !iter.done(); iter.next()) {
- FatBlock fb = (FatBlock)(iter.getKey());
- result[i++] = fb.realBlock;
- }
- }
- return result;
- }
-
- void addSuccessor(FatBlock b) { successors.put(b, 0); }
- void addPredecessor(FatBlock b) { predecessors.put(b, 0); }
-
- Block[] getSuccessors() { return reduceToArray(successors); }
- Block[] getPredecessors() { return reduceToArray(predecessors); }
-
- // all the Blocks that come immediately after this
- private ObjToIntMap successors = new ObjToIntMap();
- // all the Blocks that come immediately before this
- private ObjToIntMap predecessors = new ObjToIntMap();
-
- Block realBlock;
- }
-
- Block(int startNodeIndex, int endNodeIndex)
- {
- itsStartNodeIndex = startNodeIndex;
- itsEndNodeIndex = endNodeIndex;
- }
-
- static void runFlowAnalyzes(OptFunctionNode fn, Node[] statementNodes)
- {
- int paramCount = fn.fnode.getParamCount();
- int varCount = fn.fnode.getParamAndVarCount();
- int[] varTypes = new int[varCount];
- // If the variable is a parameter, it could have any type.
- for (int i = 0; i != paramCount; ++i) {
- varTypes[i] = Optimizer.AnyType;
- }
- // If the variable is from a "var" statement, its typeEvent will be set
- // when we see the setVar node.
- for (int i = paramCount; i != varCount; ++i) {
- varTypes[i] = Optimizer.NoType;
- }
-
- Block[] theBlocks = buildBlocks(statementNodes);
-
- if (DEBUG) {
- ++debug_blockCount;
- System.out.println("-------------------"+fn.fnode.getFunctionName()+" "+debug_blockCount+"--------");
- System.out.println(toString(theBlocks, statementNodes));
- }
-
- reachingDefDataFlow(fn, statementNodes, theBlocks, varTypes);
- typeFlow(fn, statementNodes, theBlocks, varTypes);
-
- if (DEBUG) {
- for (int i = 0; i < theBlocks.length; i++) {
- System.out.println("For block " + theBlocks[i].itsBlockID);
- theBlocks[i].printLiveOnEntrySet(fn);
- }
- System.out.println("Variable Table, size = " + varCount);
- for (int i = 0; i != varCount; i++) {
- System.out.println("["+i+"] type: "+varTypes[i]);
- }
- }
-
- for (int i = paramCount; i != varCount; i++) {
- if (varTypes[i] == Optimizer.NumberType) {
- fn.setIsNumberVar(i);
- }
- }
-
- }
-
- private static Block[] buildBlocks(Node[] statementNodes)
- {
- // a mapping from each target node to the block it begins
- Hashtable theTargetBlocks = new Hashtable();
- ObjArray theBlocks = new ObjArray();
-
- // there's a block that starts at index 0
- int beginNodeIndex = 0;
-
- for (int i = 0; i < statementNodes.length; i++) {
- switch (statementNodes[i].getType()) {
- case Token.TARGET :
- {
- if (i != beginNodeIndex) {
- FatBlock fb = newFatBlock(beginNodeIndex, i - 1);
- if (statementNodes[beginNodeIndex].getType()
- == Token.TARGET)
- theTargetBlocks.put(statementNodes[beginNodeIndex], fb);
- theBlocks.add(fb);
- // start the next block at this node
- beginNodeIndex = i;
- }
- }
- break;
- case Token.IFNE :
- case Token.IFEQ :
- case Token.GOTO :
- {
- FatBlock fb = newFatBlock(beginNodeIndex, i);
- if (statementNodes[beginNodeIndex].getType()
- == Token.TARGET)
- theTargetBlocks.put(statementNodes[beginNodeIndex], fb);
- theBlocks.add(fb);
- // start the next block at the next node
- beginNodeIndex = i + 1;
- }
- break;
- }
- }
-
- if (beginNodeIndex != statementNodes.length) {
- FatBlock fb = newFatBlock(beginNodeIndex, statementNodes.length - 1);
- if (statementNodes[beginNodeIndex].getType() == Token.TARGET)
- theTargetBlocks.put(statementNodes[beginNodeIndex], fb);
- theBlocks.add(fb);
- }
-
- // build successor and predecessor links
-
- for (int i = 0; i < theBlocks.size(); i++) {
- FatBlock fb = (FatBlock)(theBlocks.get(i));
-
- Node blockEndNode = statementNodes[fb.realBlock.itsEndNodeIndex];
- int blockEndNodeType = blockEndNode.getType();
-
- if ((blockEndNodeType != Token.GOTO)
- && (i < (theBlocks.size() - 1))) {
- FatBlock fallThruTarget = (FatBlock)(theBlocks.get(i + 1));
- fb.addSuccessor(fallThruTarget);
- fallThruTarget.addPredecessor(fb);
- }
-
-
- if ( (blockEndNodeType == Token.IFNE)
- || (blockEndNodeType == Token.IFEQ)
- || (blockEndNodeType == Token.GOTO) ) {
- Node target = ((Node.Jump)blockEndNode).target;
- FatBlock branchTargetBlock
- = (FatBlock)(theTargetBlocks.get(target));
- target.putProp(Node.TARGETBLOCK_PROP,
- branchTargetBlock.realBlock);
- fb.addSuccessor(branchTargetBlock);
- branchTargetBlock.addPredecessor(fb);
- }
- }
-
- Block[] result = new Block[theBlocks.size()];
-
- for (int i = 0; i < theBlocks.size(); i++) {
- FatBlock fb = (FatBlock)(theBlocks.get(i));
- Block b = fb.realBlock;
- b.itsSuccessors = fb.getSuccessors();
- b.itsPredecessors = fb.getPredecessors();
- b.itsBlockID = i;
- result[i] = b;
- }
-
- return result;
- }
-
- private static FatBlock newFatBlock(int startNodeIndex, int endNodeIndex)
- {
- FatBlock fb = new FatBlock();
- fb.realBlock = new Block(startNodeIndex, endNodeIndex);
- return fb;
- }
-
- private static String toString(Block[] blockList, Node[] statementNodes)
- {
- if (!DEBUG) return null;
-
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
-
- pw.println(blockList.length + " Blocks");
- for (int i = 0; i < blockList.length; i++) {
- Block b = blockList[i];
- pw.println("#" + b.itsBlockID);
- pw.println("from " + b.itsStartNodeIndex
- + " "
- + statementNodes[b.itsStartNodeIndex].toString());
- pw.println("thru " + b.itsEndNodeIndex
- + " "
- + statementNodes[b.itsEndNodeIndex].toString());
- pw.print("Predecessors ");
- if (b.itsPredecessors != null) {
- for (int j = 0; j < b.itsPredecessors.length; j++)
- pw.print(b.itsPredecessors[j].itsBlockID + " ");
- pw.println();
- }
- else
- pw.println("none");
- pw.print("Successors ");
- if (b.itsSuccessors != null) {
- for (int j = 0; j < b.itsSuccessors.length; j++)
- pw.print(b.itsSuccessors[j].itsBlockID + " ");
- pw.println();
- }
- else
- pw.println("none");
- }
- return sw.toString();
- }
-
- private static void reachingDefDataFlow(OptFunctionNode fn, Node[] statementNodes, Block theBlocks[], int[] varTypes)
- {
-/*
- initialize the liveOnEntry and liveOnExit sets, then discover the variables
- that are def'd by each function, and those that are used before being def'd
- (hence liveOnEntry)
-*/
- for (int i = 0; i < theBlocks.length; i++) {
- theBlocks[i].initLiveOnEntrySets(fn, statementNodes);
- }
-/*
- this visits every block starting at the last, re-adding the predecessors of
- any block whose inputs change as a result of the dataflow.
- REMIND, better would be to visit in CFG postorder
-*/
- boolean visit[] = new boolean[theBlocks.length];
- boolean doneOnce[] = new boolean[theBlocks.length];
- int vIndex = theBlocks.length - 1;
- boolean needRescan = false;
- visit[vIndex] = true;
- while (true) {
- if (visit[vIndex] || !doneOnce[vIndex]) {
- doneOnce[vIndex] = true;
- visit[vIndex] = false;
- if (theBlocks[vIndex].doReachedUseDataFlow()) {
- Block pred[] = theBlocks[vIndex].itsPredecessors;
- if (pred != null) {
- for (int i = 0; i < pred.length; i++) {
- int index = pred[i].itsBlockID;
- visit[index] = true;
- needRescan |= (index > vIndex);
- }
- }
- }
- }
- if (vIndex == 0) {
- if (needRescan) {
- vIndex = theBlocks.length - 1;
- needRescan = false;
- }
- else
- break;
- }
- else
- vIndex--;
- }
-/*
- if any variable is live on entry to block 0, we have to mark it as
- not jRegable - since it means that someone is trying to access the
- 'undefined'-ness of that variable.
-*/
-
- theBlocks[0].markAnyTypeVariables(varTypes);
- }
-
- private static void typeFlow(OptFunctionNode fn, Node[] statementNodes, Block theBlocks[], int[] varTypes)
- {
- boolean visit[] = new boolean[theBlocks.length];
- boolean doneOnce[] = new boolean[theBlocks.length];
- int vIndex = 0;
- boolean needRescan = false;
- visit[vIndex] = true;
- while (true) {
- if (visit[vIndex] || !doneOnce[vIndex]) {
- doneOnce[vIndex] = true;
- visit[vIndex] = false;
- if (theBlocks[vIndex].doTypeFlow(fn, statementNodes, varTypes))
- {
- Block succ[] = theBlocks[vIndex].itsSuccessors;
- if (succ != null) {
- for (int i = 0; i < succ.length; i++) {
- int index = succ[i].itsBlockID;
- visit[index] = true;
- needRescan |= (index < vIndex);
- }
- }
- }
- }
- if (vIndex == (theBlocks.length - 1)) {
- if (needRescan) {
- vIndex = 0;
- needRescan = false;
- }
- else
- break;
- }
- else
- vIndex++;
- }
- }
-
- private static boolean assignType(int[] varTypes, int index, int type)
- {
- return type != (varTypes[index] |= type);
- }
-
- private void markAnyTypeVariables(int[] varTypes)
- {
- for (int i = 0; i != varTypes.length; i++) {
- if (itsLiveOnEntrySet.test(i)) {
- assignType(varTypes, i, Optimizer.AnyType);
- }
- }
-
- }
-
- /*
- We're tracking uses and defs - in order to
- build the def set and to identify the last use
- nodes.
-
- The itsNotDefSet is built reversed then flipped later.
-
- */
- private void lookForVariableAccess(OptFunctionNode fn, Node n)
- {
- switch (n.getType()) {
- case Token.DEC :
- case Token.INC :
- {
- Node child = n.getFirstChild();
- if (child.getType() == Token.GETVAR) {
- int varIndex = fn.getVarIndex(child);
- if (!itsNotDefSet.test(varIndex))
- itsUseBeforeDefSet.set(varIndex);
- itsNotDefSet.set(varIndex);
- }
- }
- break;
- case Token.SETVAR :
- {
- Node lhs = n.getFirstChild();
- Node rhs = lhs.getNext();
- lookForVariableAccess(fn, rhs);
- itsNotDefSet.set(fn.getVarIndex(n));
- }
- break;
- case Token.GETVAR :
- {
- int varIndex = fn.getVarIndex(n);
- if (!itsNotDefSet.test(varIndex))
- itsUseBeforeDefSet.set(varIndex);
- }
- break;
- default :
- Node child = n.getFirstChild();
- while (child != null) {
- lookForVariableAccess(fn, child);
- child = child.getNext();
- }
- break;
- }
- }
-
- /*
- build the live on entry/exit sets.
- Then walk the trees looking for defs/uses of variables
- and build the def and useBeforeDef sets.
- */
- private void initLiveOnEntrySets(OptFunctionNode fn, Node[] statementNodes)
- {
- int listLength = fn.getVarCount();
- itsUseBeforeDefSet = new DataFlowBitSet(listLength);
- itsNotDefSet = new DataFlowBitSet(listLength);
- itsLiveOnEntrySet = new DataFlowBitSet(listLength);
- itsLiveOnExitSet = new DataFlowBitSet(listLength);
- for (int i = itsStartNodeIndex; i <= itsEndNodeIndex; i++) {
- Node n = statementNodes[i];
- lookForVariableAccess(fn, n);
- }
- itsNotDefSet.not(); // truth in advertising
- }
-
- /*
- the liveOnEntry of each successor is the liveOnExit for this block.
- The liveOnEntry for this block is -
- liveOnEntry = liveOnExit - defsInThisBlock + useBeforeDefsInThisBlock
-
- */
- private boolean doReachedUseDataFlow()
- {
- itsLiveOnExitSet.clear();
- if (itsSuccessors != null)
- for (int i = 0; i < itsSuccessors.length; i++)
- itsLiveOnExitSet.or(itsSuccessors[i].itsLiveOnEntrySet);
- return itsLiveOnEntrySet.df2(itsLiveOnExitSet,
- itsUseBeforeDefSet, itsNotDefSet);
- }
-
- /*
- the type of an expression is relatively unknown. Cases we can be sure
- about are -
- Literals,
- Arithmetic operations - always return a Number
- */
- private static int findExpressionType(OptFunctionNode fn, Node n,
- int[] varTypes)
- {
- switch (n.getType()) {
- case Token.NUMBER :
- return Optimizer.NumberType;
-
- case Token.CALL :
- case Token.NEW :
- case Token.REF_CALL :
- return Optimizer.AnyType;
-
- case Token.GETELEM :
- return Optimizer.AnyType;
-
- case Token.GETVAR :
- return varTypes[fn.getVarIndex(n)];
-
- case Token.INC :
- case Token.DEC :
- case Token.DIV:
- case Token.MOD:
- case Token.BITOR:
- case Token.BITXOR:
- case Token.BITAND:
- case Token.LSH:
- case Token.RSH:
- case Token.URSH:
- case Token.SUB :
- return Optimizer.NumberType;
-
- case Token.ARRAYLIT:
- case Token.OBJECTLIT:
- return Optimizer.AnyType; // XXX: actually, we know it's not
- // number, but no type yet for that
-
- case Token.ADD : {
- // if the lhs & rhs are known to be numbers, we can be sure that's
- // the result, otherwise it could be a string.
- Node child = n.getFirstChild();
- int lType = findExpressionType(fn, child, varTypes);
- int rType = findExpressionType(fn, child.getNext(), varTypes);
- return lType | rType; // we're not distinguishing strings yet
- }
- }
-
- Node child = n.getFirstChild();
- if (child == null) {
- return Optimizer.AnyType;
- } else {
- int result = Optimizer.NoType;
- while (child != null) {
- result |= findExpressionType(fn, child, varTypes);
- child = child.getNext();
- }
- return result;
- }
- }
-
- private static boolean findDefPoints(OptFunctionNode fn, Node n,
- int[] varTypes)
- {
- boolean result = false;
- Node child = n.getFirstChild();
- switch (n.getType()) {
- default :
- while (child != null) {
- result |= findDefPoints(fn, child, varTypes);
- child = child.getNext();
- }
- break;
- case Token.DEC :
- case Token.INC :
- if (child.getType() == Token.GETVAR) {
- // theVar is a Number now
- int i = fn.getVarIndex(child);
- result |= assignType(varTypes, i, Optimizer.NumberType);
- }
- break;
- case Token.SETPROP :
- case Token.SETPROP_OP :
- if (child.getType() == Token.GETVAR) {
- int i = fn.getVarIndex(child);
- assignType(varTypes, i, Optimizer.AnyType);
- }
- while (child != null) {
- result |= findDefPoints(fn, child, varTypes);
- child = child.getNext();
- }
- break;
- case Token.SETVAR : {
- Node rValue = child.getNext();
- int theType = findExpressionType(fn, rValue, varTypes);
- int i = fn.getVarIndex(n);
- result |= assignType(varTypes, i, theType);
- break;
- }
- }
- return result;
- }
-
- private boolean doTypeFlow(OptFunctionNode fn, Node[] statementNodes,
- int[] varTypes)
- {
- boolean changed = false;
-
- for (int i = itsStartNodeIndex; i <= itsEndNodeIndex; i++) {
- Node n = statementNodes[i];
- if (n != null)
- changed |= findDefPoints(fn, n, varTypes);
- }
-
- return changed;
- }
-
- private void printLiveOnEntrySet(OptFunctionNode fn)
- {
- if (DEBUG) {
- for (int i = 0; i < fn.getVarCount(); i++) {
- String name = fn.fnode.getParamOrVarName(i);
- if (itsUseBeforeDefSet.test(i))
- System.out.println(name + " is used before def'd");
- if (itsNotDefSet.test(i))
- System.out.println(name + " is not def'd");
- if (itsLiveOnEntrySet.test(i))
- System.out.println(name + " is live on entry");
- if (itsLiveOnExitSet.test(i))
- System.out.println(name + " is live on exit");
- }
- }
- }
-
- // all the Blocks that come immediately after this
- private Block[] itsSuccessors;
- // all the Blocks that come immediately before this
- private Block[] itsPredecessors;
-
- private int itsStartNodeIndex; // the Node at the start of the block
- private int itsEndNodeIndex; // the Node at the end of the block
-
- private int itsBlockID; // a unique index for each block
-
-// reaching def bit sets -
- private DataFlowBitSet itsLiveOnEntrySet;
- private DataFlowBitSet itsLiveOnExitSet;
- private DataFlowBitSet itsUseBeforeDefSet;
- private DataFlowBitSet itsNotDefSet;
-
- static final boolean DEBUG = false;
- private static int debug_blockCount;
-
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/ClassCompiler.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/ClassCompiler.java
deleted file mode 100644
index 4a69c6a..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/ClassCompiler.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/* ***** 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * 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.optimizer;
-
-import org.mozilla.javascript.*;
-
-/**
- * Generates class files from script sources.
- *
- * since 1.5 Release 5
- * @author Igor Bukanov
- */
-
-public class ClassCompiler
-{
- /**
- * Construct ClassCompiler that uses the specified compiler environment
- * when generating classes.
- */
- public ClassCompiler(CompilerEnvirons compilerEnv)
- {
- if (compilerEnv == null) throw new IllegalArgumentException();
- this.compilerEnv = compilerEnv;
- this.mainMethodClassName = Codegen.DEFAULT_MAIN_METHOD_CLASS;
- }
-
- /**
- * Set the class name to use for main method implementation.
- * The class must have a method matching
- * <tt>public static void main(Script sc, String[] args)</tt>, it will be
- * called when <tt>main(String[] args)</tt> is called in the generated
- * class. The class name should be fully qulified name and include the
- * package name like in <tt>org.foo.Bar<tt>.
- */
- public void setMainMethodClass(String className)
- {
- // XXX Should this check for a valid class name?
- mainMethodClassName = className;
- }
-
- /**
- * Get the name of the class for main method implementation.
- * @see #setMainMethodClass(String)
- */
- public String getMainMethodClass()
- {
- return mainMethodClassName;
- }
-
- /**
- * Get the compiler environment the compiler uses.
- */
- public CompilerEnvirons getCompilerEnv()
- {
- return compilerEnv;
- }
-
- /**
- * Get the class that the generated target will extend.
- */
- public Class getTargetExtends()
- {
- return targetExtends;
- }
-
- /**
- * Set the class that the generated target will extend.
- *
- * @param extendsClass the class it extends
- */
- public void setTargetExtends(Class extendsClass)
- {
- targetExtends = extendsClass;
- }
-
- /**
- * Get the interfaces that the generated target will implement.
- */
- public Class[] getTargetImplements()
- {
- return targetImplements == null ? null : (Class[])targetImplements.clone();
- }
-
- /**
- * Set the interfaces that the generated target will implement.
- *
- * @param implementsClasses an array of Class objects, one for each
- * interface the target will extend
- */
- public void setTargetImplements(Class[] implementsClasses)
- {
- targetImplements = implementsClasses == null ? null : (Class[])implementsClasses.clone();
- }
-
- /**
- * Build class name for a auxiliary class generated by compiler.
- * If the compiler needs to generate extra classes beyond the main class,
- * it will call this function to build the auxiliary class name.
- * The default implementation simply appends auxMarker to mainClassName
- * but this can be overridden.
- */
- protected String makeAuxiliaryClassName(String mainClassName,
- String auxMarker)
- {
- return mainClassName+auxMarker;
- }
-
- /**
- * Compile JavaScript source into one or more Java class files.
- * The first compiled class will have name mainClassName.
- * If the results of {@link #getTargetExtends()} or
- * {@link #getTargetImplements()} are not null, then the first compiled
- * class will extend the specified super class and implement
- * specified interfaces.
- *
- * @return array where elements with even indexes specifies class name
- * and the following odd index gives class file body as byte[]
- * array. The initial element of the array always holds
- * mainClassName and array[1] holds its byte code.
- */
- public Object[] compileToClassFiles(String source,
- String sourceLocation,
- int lineno,
- String mainClassName)
- {
- /*APPJET*/
- Parser p =
- InformativeParser.makeParser(compilerEnv,
- compilerEnv.getErrorReporter());
- ScriptOrFnNode tree = p.parse(source, sourceLocation, lineno);
- String encodedSource = p.getEncodedSource();
-
- Class superClass = getTargetExtends();
- Class[] interfaces = getTargetImplements();
- String scriptClassName;
- boolean isPrimary = (interfaces == null && superClass == null);
- if (isPrimary) {
- scriptClassName = mainClassName;
- } else {
- scriptClassName = makeAuxiliaryClassName(mainClassName, "1");
- }
-
- Codegen codegen = new Codegen();
- codegen.setMainMethodClass(mainMethodClassName);
- byte[] scriptClassBytes
- = codegen.compileToClassFile(compilerEnv, scriptClassName,
- tree, encodedSource,
- false);
-
- if (isPrimary) {
- return new Object[] { scriptClassName, scriptClassBytes };
- }
- int functionCount = tree.getFunctionCount();
- ObjToIntMap functionNames = new ObjToIntMap(functionCount);
- for (int i = 0; i != functionCount; ++i) {
- FunctionNode ofn = tree.getFunctionNode(i);
- String name = ofn.getFunctionName();
- if (name != null && name.length() != 0) {
- functionNames.put(name, ofn.getParamCount());
- }
- }
- if (superClass == null) {
- superClass = ScriptRuntime.ObjectClass;
- }
- byte[] mainClassBytes
- = JavaAdapter.createAdapterCode(
- functionNames, mainClassName,
- superClass, interfaces, scriptClassName);
-
- return new Object[] { mainClassName, mainClassBytes,
- scriptClassName, scriptClassBytes };
- }
-
- private String mainMethodClassName;
- private CompilerEnvirons compilerEnv;
- private Class targetExtends;
- private Class[] targetImplements;
-
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Codegen.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Codegen.java
deleted file mode 100644
index 64952bf..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Codegen.java
+++ /dev/null
@@ -1,5031 +0,0 @@
-/* ***** 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- * Kemal Bayram
- * Igor Bukanov
- * Bob Jervis
- * Roger Lawrence
- * Andi Vajda
- * Hannes Wallnoefer
- *
- * 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.optimizer;
-
-import org.mozilla.javascript.*;
-import org.mozilla.classfile.*;
-import java.util.*;
-import java.lang.reflect.Constructor;
-import java.util.Hashtable;
-
-/**
- * This class generates code for a given IR tree.
- *
- * @author Norris Boyd
- * @author Roger Lawrence
- */
-
-public class Codegen implements Evaluator
-{
- public void captureStackInfo(RhinoException ex) {
- throw new UnsupportedOperationException();
- }
-
- public String getSourcePositionFromStack(Context cx, int[] linep) {
- throw new UnsupportedOperationException();
- }
-
- public String getPatchedStack(RhinoException ex, String nativeStackTrace) {
- throw new UnsupportedOperationException();
- }
-
- public List getScriptStack(RhinoException ex) {
- throw new UnsupportedOperationException();
- }
-
- public void setEvalScriptFlag(Script script) {
- throw new UnsupportedOperationException();
- }
-
- public Object compile(CompilerEnvirons compilerEnv,
- ScriptOrFnNode tree,
- String encodedSource,
- boolean returnFunction)
- {
- int serial;
- synchronized (globalLock) {
- serial = ++globalSerialClassCounter;
- }
- String mainClassName = "org.mozilla.javascript.gen.c"+serial;
-
- byte[] mainClassBytes = compileToClassFile(compilerEnv, mainClassName,
- tree, encodedSource,
- returnFunction);
-
- return new Object[] { mainClassName, mainClassBytes };
- }
-
- public Script createScriptObject(Object bytecode,
- Object staticSecurityDomain)
- {
- Class cl = defineClass(bytecode, staticSecurityDomain);
-
- Script script;
- try {
- script = (Script)cl.newInstance();
- } catch (Exception ex) {
- throw new RuntimeException
- ("Unable to instantiate compiled class:"+ex.toString());
- }
- return script;
- }
-
- public Function createFunctionObject(Context cx, Scriptable scope,
- Object bytecode,
- Object staticSecurityDomain)
- {
- Class cl = defineClass(bytecode, staticSecurityDomain);
-
- NativeFunction f;
- try {
- Constructor ctor = cl.getConstructors()[0];
- Object[] initArgs = { scope, cx, new Integer(0) };
- f = (NativeFunction)ctor.newInstance(initArgs);
- } catch (Exception ex) {
- throw new RuntimeException
- ("Unable to instantiate compiled class:"+ex.toString());
- }
- return f;
- }
-
- private Class defineClass(Object bytecode,
- Object staticSecurityDomain)
- {
- Object[] nameBytesPair = (Object[])bytecode;
- String className = (String)nameBytesPair[0];
- byte[] classBytes = (byte[])nameBytesPair[1];
-
- // The generated classes in this case refer only to Rhino classes
- // which must be accessible through this class loader
- ClassLoader rhinoLoader = getClass().getClassLoader();
- GeneratedClassLoader loader;
- loader = SecurityController.createLoader(rhinoLoader,
- staticSecurityDomain);
- Exception e;
- try {
- Class cl = loader.defineClass(className, classBytes);
- loader.linkClass(cl);
- return cl;
- } catch (SecurityException x) {
- e = x;
- } catch (IllegalArgumentException x) {
- e = x;
- }
- throw new RuntimeException("Malformed optimizer package " + e);
- }
-
- byte[] compileToClassFile(CompilerEnvirons compilerEnv,
- String mainClassName,
- ScriptOrFnNode scriptOrFn,
- String encodedSource,
- boolean returnFunction)
- {
- this.compilerEnv = compilerEnv;
-
- transform(scriptOrFn);
-
- if (Token.printTrees) {
- /*APPJET*///System.out.println(scriptOrFn.toStringTree(scriptOrFn));
- }
-
- if (returnFunction) {
- scriptOrFn = scriptOrFn.getFunctionNode(0);
- }
-
- initScriptOrFnNodesData(scriptOrFn);
-
- this.mainClassName = mainClassName;
- this.mainClassSignature
- = ClassFileWriter.classNameToSignature(mainClassName);
-
- try {
- return generateCode(encodedSource);
- } catch (ClassFileWriter.ClassFileFormatException e) {
- throw reportClassFileFormatException(scriptOrFn, e.getMessage());
- }
- }
-
- private RuntimeException reportClassFileFormatException(
- ScriptOrFnNode scriptOrFn,
- String message)
- {
- String msg = scriptOrFn instanceof FunctionNode
- ? ScriptRuntime.getMessage2("msg.while.compiling.fn",
- ((FunctionNode)scriptOrFn).getFunctionName(), message)
- : ScriptRuntime.getMessage1("msg.while.compiling.script", message);
- return Context.reportRuntimeError(msg, scriptOrFn.getSourceName(),
- scriptOrFn.getLineno(), null, 0);
- }
-
- private void transform(ScriptOrFnNode tree)
- {
- initOptFunctions_r(tree);
-
- int optLevel = compilerEnv.getOptimizationLevel();
-
- Hashtable possibleDirectCalls = null;
- if (optLevel > 0) {
- /*
- * Collect all of the contained functions into a hashtable
- * so that the call optimizer can access the class name & parameter
- * count for any call it encounters
- */
- if (tree.getType() == Token.SCRIPT) {
- int functionCount = tree.getFunctionCount();
- for (int i = 0; i != functionCount; ++i) {
- OptFunctionNode ofn = OptFunctionNode.get(tree, i);
- if (ofn.fnode.getFunctionType()
- == FunctionNode.FUNCTION_STATEMENT)
- {
- String name = ofn.fnode.getFunctionName();
- if (name.length() != 0) {
- if (possibleDirectCalls == null) {
- possibleDirectCalls = new Hashtable();
- }
- possibleDirectCalls.put(name, ofn);
- }
- }
- }
- }
- }
-
- if (possibleDirectCalls != null) {
- directCallTargets = new ObjArray();
- }
-
- OptTransformer ot = new OptTransformer(possibleDirectCalls,
- directCallTargets);
- ot.transform(tree);
-
- if (optLevel > 0) {
- (new Optimizer()).optimize(tree);
- }
- }
-
- private static void initOptFunctions_r(ScriptOrFnNode scriptOrFn)
- {
- for (int i = 0, N = scriptOrFn.getFunctionCount(); i != N; ++i) {
- FunctionNode fn = scriptOrFn.getFunctionNode(i);
- new OptFunctionNode(fn);
- initOptFunctions_r(fn);
- }
- }
-
- private void initScriptOrFnNodesData(ScriptOrFnNode scriptOrFn)
- {
- ObjArray x = new ObjArray();
- collectScriptOrFnNodes_r(scriptOrFn, x);
-
- int count = x.size();
- scriptOrFnNodes = new ScriptOrFnNode[count];
- x.toArray(scriptOrFnNodes);
-
- scriptOrFnIndexes = new ObjToIntMap(count);
- for (int i = 0; i != count; ++i) {
- scriptOrFnIndexes.put(scriptOrFnNodes[i], i);
- }
- }
-
- private static void collectScriptOrFnNodes_r(ScriptOrFnNode n,
- ObjArray x)
- {
- x.add(n);
- int nestedCount = n.getFunctionCount();
- for (int i = 0; i != nestedCount; ++i) {
- collectScriptOrFnNodes_r(n.getFunctionNode(i), x);
- }
- }
-
- private byte[] generateCode(String encodedSource)
- {
- boolean hasScript = (scriptOrFnNodes[0].getType() == Token.SCRIPT);
- boolean hasFunctions = (scriptOrFnNodes.length > 1 || !hasScript);
-
- String sourceFile = null;
- if (compilerEnv.isGenerateDebugInfo()) {
- sourceFile = scriptOrFnNodes[0].getSourceName();
- }
-
- ClassFileWriter cfw = new ClassFileWriter(mainClassName,
- SUPER_CLASS_NAME,
- sourceFile);
- cfw.addField(ID_FIELD_NAME, "I",
- ClassFileWriter.ACC_PRIVATE);
- cfw.addField(DIRECT_CALL_PARENT_FIELD, mainClassSignature,
- ClassFileWriter.ACC_PRIVATE);
- cfw.addField(REGEXP_ARRAY_FIELD_NAME, REGEXP_ARRAY_FIELD_TYPE,
- ClassFileWriter.ACC_PRIVATE);
-
- if (hasFunctions) {
- generateFunctionConstructor(cfw);
- }
-
- if (hasScript) {
- cfw.addInterface("org/mozilla/javascript/Script");
- generateScriptCtor(cfw);
- generateMain(cfw);
- generateExecute(cfw);
- }
-
- generateCallMethod(cfw);
- generateResumeGenerator(cfw);
-
- generateNativeFunctionOverrides(cfw, encodedSource);
-
- int count = scriptOrFnNodes.length;
- for (int i = 0; i != count; ++i) {
- ScriptOrFnNode n = scriptOrFnNodes[i];
-
- BodyCodegen bodygen = new BodyCodegen();
- bodygen.cfw = cfw;
- bodygen.codegen = this;
- bodygen.compilerEnv = compilerEnv;
- bodygen.scriptOrFn = n;
- bodygen.scriptOrFnIndex = i;
-
- try {
- bodygen.generateBodyCode();
- } catch (ClassFileWriter.ClassFileFormatException e) {
- throw reportClassFileFormatException(n, e.getMessage());
- }
-
- if (n.getType() == Token.FUNCTION) {
- OptFunctionNode ofn = OptFunctionNode.get(n);
- generateFunctionInit(cfw, ofn);
- if (ofn.isTargetOfDirectCall()) {
- emitDirectConstructor(cfw, ofn);
- }
- }
- }
-
- if (directCallTargets != null) {
- int N = directCallTargets.size();
- for (int j = 0; j != N; ++j) {
- cfw.addField(getDirectTargetFieldName(j),
- mainClassSignature,
- ClassFileWriter.ACC_PRIVATE);
- }
- }
-
- emitRegExpInit(cfw);
- emitConstantDudeInitializers(cfw);
-
- return cfw.toByteArray();
- }
-
- private void emitDirectConstructor(ClassFileWriter cfw,
- OptFunctionNode ofn)
- {
-/*
- we generate ..
- Scriptable directConstruct(<directCallArgs>) {
- Scriptable newInstance = createObject(cx, scope);
- Object val = <body-name>(cx, scope, newInstance, <directCallArgs>);
- if (val instanceof Scriptable) {
- return (Scriptable) val;
- }
- return newInstance;
- }
-*/
- cfw.startMethod(getDirectCtorName(ofn.fnode),
- getBodyMethodSignature(ofn.fnode),
- (short)(ClassFileWriter.ACC_STATIC
- | ClassFileWriter.ACC_PRIVATE));
-
- int argCount = ofn.fnode.getParamCount();
- int firstLocal = (4 + argCount * 3) + 1;
-
- cfw.addALoad(0); // this
- cfw.addALoad(1); // cx
- cfw.addALoad(2); // scope
- cfw.addInvoke(ByteCode.INVOKEVIRTUAL,
- "org/mozilla/javascript/BaseFunction",
- "createObject",
- "(Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Lorg/mozilla/javascript/Scriptable;");
- cfw.addAStore(firstLocal);
-
- cfw.addALoad(0);
- cfw.addALoad(1);
- cfw.addALoad(2);
- cfw.addALoad(firstLocal);
- for (int i = 0; i < argCount; i++) {
- cfw.addALoad(4 + (i * 3));
- cfw.addDLoad(5 + (i * 3));
- }
- cfw.addALoad(4 + argCount * 3);
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- mainClassName,
- getBodyMethodName(ofn.fnode),
- getBodyMethodSignature(ofn.fnode));
- int exitLabel = cfw.acquireLabel();
- cfw.add(ByteCode.DUP); // make a copy of direct call result
- cfw.add(ByteCode.INSTANCEOF, "org/mozilla/javascript/Scriptable");
- cfw.add(ByteCode.IFEQ, exitLabel);
- // cast direct call result
- cfw.add(ByteCode.CHECKCAST, "org/mozilla/javascript/Scriptable");
- cfw.add(ByteCode.ARETURN);
- cfw.markLabel(exitLabel);
-
- cfw.addALoad(firstLocal);
- cfw.add(ByteCode.ARETURN);
-
- cfw.stopMethod((short)(firstLocal + 1));
- }
-
- static boolean isGenerator(ScriptOrFnNode node)
- {
- return (node.getType() == Token.FUNCTION ) &&
- ((FunctionNode)node).isGenerator();
- }
-
- // How dispatch to generators works:
- // Two methods are generated corresponding to a user-written generator.
- // One of these creates a generator object (NativeGenerator), which is
- // returned to the user. The other method contains all of the body code
- // of the generator.
- // When a user calls a generator, the call() method dispatches control to
- // to the method that creates the NativeGenerator object. Subsequently when
- // the user invokes .next(), .send() or any such method on the generator
- // object, the resumeGenerator() below dispatches the call to the
- // method corresponding to the generator body. As a matter of convention
- // the generator body is given the name of the generator activation function
- // appended by "_gen".
- private void generateResumeGenerator(ClassFileWriter cfw)
- {
- boolean hasGenerators = false;
- for (int i=0; i < scriptOrFnNodes.length; i++) {
- if (isGenerator(scriptOrFnNodes[i]))
- hasGenerators = true;
- }
-
- // if there are no generators defined, we don't implement a
- // resumeGenerator(). The base class provides a default implementation.
- if (!hasGenerators)
- return;
-
- cfw.startMethod("resumeGenerator",
- "(Lorg/mozilla/javascript/Context;" +
- "Lorg/mozilla/javascript/Scriptable;" +
- "ILjava/lang/Object;" +
- "Ljava/lang/Object;)Ljava/lang/Object;",
- (short)(ClassFileWriter.ACC_PUBLIC
- | ClassFileWriter.ACC_FINAL));
-
- // load arguments for dispatch to the corresponding *_gen method
- cfw.addALoad(0);
- cfw.addALoad(1);
- cfw.addALoad(2);
- cfw.addALoad(4);
- cfw.addALoad(5);
- cfw.addILoad(3);
-
- cfw.addLoadThis();
- cfw.add(ByteCode.GETFIELD, cfw.getClassName(), ID_FIELD_NAME, "I");
-
- int startSwitch = cfw.addTableSwitch(0, scriptOrFnNodes.length - 1);
- cfw.markTableSwitchDefault(startSwitch);
- int endlabel = cfw.acquireLabel();
-
- for (int i = 0; i < scriptOrFnNodes.length; i++) {
- ScriptOrFnNode n = scriptOrFnNodes[i];
- cfw.markTableSwitchCase(startSwitch, i, (short)6);
- if (isGenerator(n)) {
- String type = "(" +
- mainClassSignature +
- "Lorg/mozilla/javascript/Context;" +
- "Lorg/mozilla/javascript/Scriptable;" +
- "Ljava/lang/Object;" +
- "Ljava/lang/Object;I)Ljava/lang/Object;";
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- mainClassName,
- getBodyMethodName(n) + "_gen",
- type);
- cfw.add(ByteCode.ARETURN);
- } else {
- cfw.add(ByteCode.GOTO, endlabel);
- }
- }
-
- cfw.markLabel(endlabel);
- pushUndefined(cfw);
- cfw.add(ByteCode.ARETURN);
-
-
- // this method uses as many locals as there are arguments (hence 6)
- cfw.stopMethod((short)6);
- }
-
- private void generateCallMethod(ClassFileWriter cfw)
- {
- cfw.startMethod("call",
- "(Lorg/mozilla/javascript/Context;" +
- "Lorg/mozilla/javascript/Scriptable;" +
- "Lorg/mozilla/javascript/Scriptable;" +
- "[Ljava/lang/Object;)Ljava/lang/Object;",
- (short)(ClassFileWriter.ACC_PUBLIC
- | ClassFileWriter.ACC_FINAL));
-
- // Generate code for:
- // if (!ScriptRuntime.hasTopCall(cx)) {
- // return ScriptRuntime.doTopCall(this, cx, scope, thisObj, args);
- // }
-
- int nonTopCallLabel = cfw.acquireLabel();
- cfw.addALoad(1); //cx
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/ScriptRuntime",
- "hasTopCall",
- "(Lorg/mozilla/javascript/Context;"
- +")Z");
- cfw.add(ByteCode.IFNE, nonTopCallLabel);
- cfw.addALoad(0);
- cfw.addALoad(1);
- cfw.addALoad(2);
- cfw.addALoad(3);
- cfw.addALoad(4);
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/ScriptRuntime",
- "doTopCall",
- "(Lorg/mozilla/javascript/Callable;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"[Ljava/lang/Object;"
- +")Ljava/lang/Object;");
- cfw.add(ByteCode.ARETURN);
- cfw.markLabel(nonTopCallLabel);
-
- // Now generate switch to call the real methods
- cfw.addALoad(0);
- cfw.addALoad(1);
- cfw.addALoad(2);
- cfw.addALoad(3);
- cfw.addALoad(4);
-
- int end = scriptOrFnNodes.length;
- boolean generateSwitch = (2 <= end);
-
- int switchStart = 0;
- int switchStackTop = 0;
- if (generateSwitch) {
- cfw.addLoadThis();
- cfw.add(ByteCode.GETFIELD, cfw.getClassName(), ID_FIELD_NAME, "I");
- // do switch from (1, end - 1) mapping 0 to
- // the default case
- switchStart = cfw.addTableSwitch(1, end - 1);
- }
-
- for (int i = 0; i != end; ++i) {
- ScriptOrFnNode n = scriptOrFnNodes[i];
- if (generateSwitch) {
- if (i == 0) {
- cfw.markTableSwitchDefault(switchStart);
- switchStackTop = cfw.getStackTop();
- } else {
- cfw.markTableSwitchCase(switchStart, i - 1,
- switchStackTop);
- }
- }
- if (n.getType() == Token.FUNCTION) {
- OptFunctionNode ofn = OptFunctionNode.get(n);
- if (ofn.isTargetOfDirectCall()) {
- int pcount = ofn.fnode.getParamCount();
- if (pcount != 0) {
- // loop invariant:
- // stack top == arguments array from addALoad4()
- for (int p = 0; p != pcount; ++p) {
- cfw.add(ByteCode.ARRAYLENGTH);
- cfw.addPush(p);
- int undefArg = cfw.acquireLabel();
- int beyond = cfw.acquireLabel();
- cfw.add(ByteCode.IF_ICMPLE, undefArg);
- // get array[p]
- cfw.addALoad(4);
- cfw.addPush(p);
- cfw.add(ByteCode.AALOAD);
- cfw.add(ByteCode.GOTO, beyond);
- cfw.markLabel(undefArg);
- pushUndefined(cfw);
- cfw.markLabel(beyond);
- // Only one push
- cfw.adjustStackTop(-1);
- cfw.addPush(0.0);
- // restore invariant
- cfw.addALoad(4);
- }
- }
- }
- }
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- mainClassName,
- getBodyMethodName(n),
- getBodyMethodSignature(n));
- cfw.add(ByteCode.ARETURN);
- }
- cfw.stopMethod((short)5);
- // 5: this, cx, scope, js this, args[]
- }
-
- private void generateMain(ClassFileWriter cfw)
- {
- cfw.startMethod("main", "([Ljava/lang/String;)V",
- (short)(ClassFileWriter.ACC_PUBLIC
- | ClassFileWriter.ACC_STATIC));
-
- // load new ScriptImpl()
- cfw.add(ByteCode.NEW, cfw.getClassName());
- cfw.add(ByteCode.DUP);
- cfw.addInvoke(ByteCode.INVOKESPECIAL, cfw.getClassName(),
- "<init>", "()V");
- // load 'args'
- cfw.add(ByteCode.ALOAD_0);
- // Call mainMethodClass.main(Script script, String[] args)
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- mainMethodClass,
- "main",
- "(Lorg/mozilla/javascript/Script;[Ljava/lang/String;)V");
- cfw.add(ByteCode.RETURN);
- // 1 = String[] args
- cfw.stopMethod((short)1);
- }
-
- private void generateExecute(ClassFileWriter cfw)
- {
- cfw.startMethod("exec",
- "(Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Ljava/lang/Object;",
- (short)(ClassFileWriter.ACC_PUBLIC
- | ClassFileWriter.ACC_FINAL));
-
- final int CONTEXT_ARG = 1;
- final int SCOPE_ARG = 2;
-
- cfw.addLoadThis();
- cfw.addALoad(CONTEXT_ARG);
- cfw.addALoad(SCOPE_ARG);
- cfw.add(ByteCode.DUP);
- cfw.add(ByteCode.ACONST_NULL);
- cfw.addInvoke(ByteCode.INVOKEVIRTUAL,
- cfw.getClassName(),
- "call",
- "(Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"[Ljava/lang/Object;"
- +")Ljava/lang/Object;");
-
- cfw.add(ByteCode.ARETURN);
- // 3 = this + context + scope
- cfw.stopMethod((short)3);
- }
-
- private void generateScriptCtor(ClassFileWriter cfw)
- {
- cfw.startMethod("<init>", "()V", ClassFileWriter.ACC_PUBLIC);
-
- cfw.addLoadThis();
- cfw.addInvoke(ByteCode.INVOKESPECIAL, SUPER_CLASS_NAME,
- "<init>", "()V");
- // set id to 0
- cfw.addLoadThis();
- cfw.addPush(0);
- cfw.add(ByteCode.PUTFIELD, cfw.getClassName(), ID_FIELD_NAME, "I");
-
- cfw.add(ByteCode.RETURN);
- // 1 parameter = this
- cfw.stopMethod((short)1);
- }
-
- private void generateFunctionConstructor(ClassFileWriter cfw)
- {
- final int SCOPE_ARG = 1;
- final int CONTEXT_ARG = 2;
- final int ID_ARG = 3;
-
- cfw.startMethod("<init>", FUNCTION_CONSTRUCTOR_SIGNATURE,
- ClassFileWriter.ACC_PUBLIC);
- cfw.addALoad(0);
- cfw.addInvoke(ByteCode.INVOKESPECIAL, SUPER_CLASS_NAME,
- "<init>", "()V");
-
- cfw.addLoadThis();
- cfw.addILoad(ID_ARG);
- cfw.add(ByteCode.PUTFIELD, cfw.getClassName(), ID_FIELD_NAME, "I");
-
- cfw.addLoadThis();
- cfw.addALoad(CONTEXT_ARG);
- cfw.addALoad(SCOPE_ARG);
-
- int start = (scriptOrFnNodes[0].getType() == Token.SCRIPT) ? 1 : 0;
- int end = scriptOrFnNodes.length;
- if (start == end) throw badTree();
- boolean generateSwitch = (2 <= end - start);
-
- int switchStart = 0;
- int switchStackTop = 0;
- if (generateSwitch) {
- cfw.addILoad(ID_ARG);
- // do switch from (start + 1, end - 1) mapping start to
- // the default case
- switchStart = cfw.addTableSwitch(start + 1, end - 1);
- }
-
- for (int i = start; i != end; ++i) {
- if (generateSwitch) {
- if (i == start) {
- cfw.markTableSwitchDefault(switchStart);
- switchStackTop = cfw.getStackTop();
- } else {
- cfw.markTableSwitchCase(switchStart, i - 1 - start,
- switchStackTop);
- }
- }
- OptFunctionNode ofn = OptFunctionNode.get(scriptOrFnNodes[i]);
- cfw.addInvoke(ByteCode.INVOKEVIRTUAL,
- mainClassName,
- getFunctionInitMethodName(ofn),
- FUNCTION_INIT_SIGNATURE);
- cfw.add(ByteCode.RETURN);
- }
-
- // 4 = this + scope + context + id
- cfw.stopMethod((short)4);
- }
-
- private void generateFunctionInit(ClassFileWriter cfw,
- OptFunctionNode ofn)
- {
- final int CONTEXT_ARG = 1;
- final int SCOPE_ARG = 2;
- cfw.startMethod(getFunctionInitMethodName(ofn),
- FUNCTION_INIT_SIGNATURE,
- (short)(ClassFileWriter.ACC_PRIVATE
- | ClassFileWriter.ACC_FINAL));
-
- // Call NativeFunction.initScriptFunction
- cfw.addLoadThis();
- cfw.addALoad(CONTEXT_ARG);
- cfw.addALoad(SCOPE_ARG);
- cfw.addInvoke(ByteCode.INVOKEVIRTUAL,
- "org/mozilla/javascript/NativeFunction",
- "initScriptFunction",
- "(Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")V");
-
- // precompile all regexp literals
- int regexpCount = ofn.fnode.getRegexpCount();
- if (regexpCount != 0) {
- cfw.addLoadThis();
- pushRegExpArray(cfw, ofn.fnode, CONTEXT_ARG, SCOPE_ARG);
- cfw.add(ByteCode.PUTFIELD, mainClassName,
- REGEXP_ARRAY_FIELD_NAME, REGEXP_ARRAY_FIELD_TYPE);
- }
-
- cfw.add(ByteCode.RETURN);
- // 3 = (scriptThis/functionRef) + scope + context
- cfw.stopMethod((short)3);
- }
-
- private void generateNativeFunctionOverrides(ClassFileWriter cfw,
- String encodedSource)
- {
- // Override NativeFunction.getLanguageVersion() with
- // public int getLanguageVersion() { return <version-constant>; }
-
- cfw.startMethod("getLanguageVersion", "()I",
- ClassFileWriter.ACC_PUBLIC);
-
- cfw.addPush(compilerEnv.getLanguageVersion());
- cfw.add(ByteCode.IRETURN);
-
- // 1: this and no argument or locals
- cfw.stopMethod((short)1);
-
- // The rest of NativeFunction overrides require specific code for each
- // script/function id
-
- final int Do_getFunctionName = 0;
- final int Do_getParamCount = 1;
- final int Do_getParamAndVarCount = 2;
- final int Do_getParamOrVarName = 3;
- final int Do_getEncodedSource = 4;
- final int Do_getParamOrVarConst = 5;
- final int SWITCH_COUNT = 6;
-
- for (int methodIndex = 0; methodIndex != SWITCH_COUNT; ++methodIndex) {
- if (methodIndex == Do_getEncodedSource && encodedSource == null) {
- continue;
- }
-
- // Generate:
- // prologue;
- // switch over function id to implement function-specific action
- // epilogue
-
- short methodLocals;
- switch (methodIndex) {
- case Do_getFunctionName:
- methodLocals = 1; // Only this
- cfw.startMethod("getFunctionName", "()Ljava/lang/String;",
- ClassFileWriter.ACC_PUBLIC);
- break;
- case Do_getParamCount:
- methodLocals = 1; // Only this
- cfw.startMethod("getParamCount", "()I",
- ClassFileWriter.ACC_PUBLIC);
- break;
- case Do_getParamAndVarCount:
- methodLocals = 1; // Only this
- cfw.startMethod("getParamAndVarCount", "()I",
- ClassFileWriter.ACC_PUBLIC);
- break;
- case Do_getParamOrVarName:
- methodLocals = 1 + 1; // this + paramOrVarIndex
- cfw.startMethod("getParamOrVarName", "(I)Ljava/lang/String;",
- ClassFileWriter.ACC_PUBLIC);
- break;
- case Do_getParamOrVarConst:
- methodLocals = 1 + 1 + 1; // this + paramOrVarName
- cfw.startMethod("getParamOrVarConst", "(I)Z",
- ClassFileWriter.ACC_PUBLIC);
- break;
- case Do_getEncodedSource:
- methodLocals = 1; // Only this
- cfw.startMethod("getEncodedSource", "()Ljava/lang/String;",
- ClassFileWriter.ACC_PUBLIC);
- cfw.addPush(encodedSource);
- break;
- default:
- throw Kit.codeBug();
- }
-
- int count = scriptOrFnNodes.length;
-
- int switchStart = 0;
- int switchStackTop = 0;
- if (count > 1) {
- // Generate switch but only if there is more then one
- // script/function
- cfw.addLoadThis();
- cfw.add(ByteCode.GETFIELD, cfw.getClassName(),
- ID_FIELD_NAME, "I");
-
- // do switch from 1 .. count - 1 mapping 0 to the default case
- switchStart = cfw.addTableSwitch(1, count - 1);
- }
-
- for (int i = 0; i != count; ++i) {
- ScriptOrFnNode n = scriptOrFnNodes[i];
- if (i == 0) {
- if (count > 1) {
- cfw.markTableSwitchDefault(switchStart);
- switchStackTop = cfw.getStackTop();
- }
- } else {
- cfw.markTableSwitchCase(switchStart, i - 1,
- switchStackTop);
- }
-
- // Impelemnet method-specific switch code
- switch (methodIndex) {
- case Do_getFunctionName:
- // Push function name
- if (n.getType() == Token.SCRIPT) {
- cfw.addPush("");
- } else {
- String name = ((FunctionNode)n).getFunctionName();
- cfw.addPush(name);
- }
- cfw.add(ByteCode.ARETURN);
- break;
-
- case Do_getParamCount:
- // Push number of defined parameters
- cfw.addPush(n.getParamCount());
- cfw.add(ByteCode.IRETURN);
- break;
-
- case Do_getParamAndVarCount:
- // Push number of defined parameters and declared variables
- cfw.addPush(n.getParamAndVarCount());
- cfw.add(ByteCode.IRETURN);
- break;
-
- case Do_getParamOrVarName:
- // Push name of parameter using another switch
- // over paramAndVarCount
- int paramAndVarCount = n.getParamAndVarCount();
- if (paramAndVarCount == 0) {
- // The runtime should never call the method in this
- // case but to make bytecode verifier happy return null
- // as throwing execption takes more code
- cfw.add(ByteCode.ACONST_NULL);
- cfw.add(ByteCode.ARETURN);
- } else if (paramAndVarCount == 1) {
- // As above do not check for valid index but always
- // return the name of the first param
- cfw.addPush(n.getParamOrVarName(0));
- cfw.add(ByteCode.ARETURN);
- } else {
- // Do switch over getParamOrVarName
- cfw.addILoad(1); // param or var index
- // do switch from 1 .. paramAndVarCount - 1 mapping 0
- // to the default case
- int paramSwitchStart = cfw.addTableSwitch(
- 1, paramAndVarCount - 1);
- for (int j = 0; j != paramAndVarCount; ++j) {
- if (cfw.getStackTop() != 0) Kit.codeBug();
- String s = n.getParamOrVarName(j);
- if (j == 0) {
- cfw.markTableSwitchDefault(paramSwitchStart);
- } else {
- cfw.markTableSwitchCase(paramSwitchStart, j - 1,
- 0);
- }
- cfw.addPush(s);
- cfw.add(ByteCode.ARETURN);
- }
- }
- break;
-
- case Do_getParamOrVarConst:
- // Push name of parameter using another switch
- // over paramAndVarCount
- paramAndVarCount = n.getParamAndVarCount();
- boolean [] constness = n.getParamAndVarConst();
- if (paramAndVarCount == 0) {
- // The runtime should never call the method in this
- // case but to make bytecode verifier happy return null
- // as throwing execption takes more code
- cfw.add(ByteCode.ICONST_0);
- cfw.add(ByteCode.IRETURN);
- } else if (paramAndVarCount == 1) {
- // As above do not check for valid index but always
- // return the name of the first param
- cfw.addPush(constness[0]);
- cfw.add(ByteCode.IRETURN);
- } else {
- // Do switch over getParamOrVarName
- cfw.addILoad(1); // param or var index
- // do switch from 1 .. paramAndVarCount - 1 mapping 0
- // to the default case
- int paramSwitchStart = cfw.addTableSwitch(
- 1, paramAndVarCount - 1);
- for (int j = 0; j != paramAndVarCount; ++j) {
- if (cfw.getStackTop() != 0) Kit.codeBug();
- if (j == 0) {
- cfw.markTableSwitchDefault(paramSwitchStart);
- } else {
- cfw.markTableSwitchCase(paramSwitchStart, j - 1,
- 0);
- }
- cfw.addPush(constness[j]);
- cfw.add(ByteCode.IRETURN);
- }
- }
- break;
-
- case Do_getEncodedSource:
- // Push number encoded source start and end
- // to prepare for encodedSource.substring(start, end)
- cfw.addPush(n.getEncodedSourceStart());
- cfw.addPush(n.getEncodedSourceEnd());
- cfw.addInvoke(ByteCode.INVOKEVIRTUAL,
- "java/lang/String",
- "substring",
- "(II)Ljava/lang/String;");
- cfw.add(ByteCode.ARETURN);
- break;
-
- default:
- throw Kit.codeBug();
- }
- }
-
- cfw.stopMethod(methodLocals);
- }
- }
-
- private void emitRegExpInit(ClassFileWriter cfw)
- {
- // precompile all regexp literals
-
- int totalRegCount = 0;
- for (int i = 0; i != scriptOrFnNodes.length; ++i) {
- totalRegCount += scriptOrFnNodes[i].getRegexpCount();
- }
- if (totalRegCount == 0) {
- return;
- }
-
- cfw.startMethod(REGEXP_INIT_METHOD_NAME, REGEXP_INIT_METHOD_SIGNATURE,
- (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_PRIVATE
- | ClassFileWriter.ACC_SYNCHRONIZED));
- cfw.addField("_reInitDone", "Z",
- (short)(ClassFileWriter.ACC_STATIC
- | ClassFileWriter.ACC_PRIVATE));
- cfw.add(ByteCode.GETSTATIC, mainClassName, "_reInitDone", "Z");
- int doInit = cfw.acquireLabel();
- cfw.add(ByteCode.IFEQ, doInit);
- cfw.add(ByteCode.RETURN);
- cfw.markLabel(doInit);
-
- for (int i = 0; i != scriptOrFnNodes.length; ++i) {
- ScriptOrFnNode n = scriptOrFnNodes[i];
- int regCount = n.getRegexpCount();
- for (int j = 0; j != regCount; ++j) {
- String reFieldName = getCompiledRegexpName(n, j);
- String reFieldType = "Ljava/lang/Object;";
- String reString = n.getRegexpString(j);
- String reFlags = n.getRegexpFlags(j);
- cfw.addField(reFieldName, reFieldType,
- (short)(ClassFileWriter.ACC_STATIC
- | ClassFileWriter.ACC_PRIVATE));
- cfw.addALoad(0); // proxy
- cfw.addALoad(1); // context
- cfw.addPush(reString);
- if (reFlags == null) {
- cfw.add(ByteCode.ACONST_NULL);
- } else {
- cfw.addPush(reFlags);
- }
- /*APPJET*/cfw.addLineNumberEntry((short)n.getRegexpLineno(j));
- cfw.addInvoke(ByteCode.INVOKEINTERFACE,
- "org/mozilla/javascript/RegExpProxy",
- "compileRegExp",
- "(Lorg/mozilla/javascript/Context;"
- +"Ljava/lang/String;Ljava/lang/String;"
- +")Ljava/lang/Object;");
- cfw.add(ByteCode.PUTSTATIC, mainClassName,
- reFieldName, reFieldType);
- }
- }
-
- cfw.addPush(1);
- cfw.add(ByteCode.PUTSTATIC, mainClassName, "_reInitDone", "Z");
- cfw.add(ByteCode.RETURN);
- cfw.stopMethod((short)2);
- }
-
- private void emitConstantDudeInitializers(ClassFileWriter cfw)
- {
- int N = itsConstantListSize;
- if (N == 0)
- return;
-
- cfw.startMethod("<clinit>", "()V",
- (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_FINAL));
-
- double[] array = itsConstantList;
- for (int i = 0; i != N; ++i) {
- double num = array[i];
- String constantName = "_k" + i;
- String constantType = getStaticConstantWrapperType(num);
- cfw.addField(constantName, constantType,
- (short)(ClassFileWriter.ACC_STATIC
- | ClassFileWriter.ACC_PRIVATE));
- int inum = (int)num;
- if (inum == num) {
- cfw.add(ByteCode.NEW, "java/lang/Integer");
- cfw.add(ByteCode.DUP);
- cfw.addPush(inum);
- cfw.addInvoke(ByteCode.INVOKESPECIAL, "java/lang/Integer",
- "<init>", "(I)V");
- } else {
- cfw.addPush(num);
- addDoubleWrap(cfw);
- }
- cfw.add(ByteCode.PUTSTATIC, mainClassName,
- constantName, constantType);
- }
-
- cfw.add(ByteCode.RETURN);
- cfw.stopMethod((short)0);
- }
-
- void pushRegExpArray(ClassFileWriter cfw, ScriptOrFnNode n,
- int contextArg, int scopeArg)
- {
- int regexpCount = n.getRegexpCount();
- if (regexpCount == 0) throw badTree();
-
- cfw.addPush(regexpCount);
- cfw.add(ByteCode.ANEWARRAY, "java/lang/Object");
-
- cfw.addALoad(contextArg);
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/ScriptRuntime",
- "checkRegExpProxy",
- "(Lorg/mozilla/javascript/Context;"
- +")Lorg/mozilla/javascript/RegExpProxy;");
- // Stack: proxy, array
- cfw.add(ByteCode.DUP);
- cfw.addALoad(contextArg);
- cfw.addInvoke(ByteCode.INVOKESTATIC, mainClassName,
- REGEXP_INIT_METHOD_NAME, REGEXP_INIT_METHOD_SIGNATURE);
- for (int i = 0; i != regexpCount; ++i) {
- // Stack: proxy, array
- cfw.add(ByteCode.DUP2);
- cfw.addALoad(contextArg);
- cfw.addALoad(scopeArg);
- cfw.add(ByteCode.GETSTATIC, mainClassName,
- getCompiledRegexpName(n, i), "Ljava/lang/Object;");
- // Stack: compiledRegExp, scope, cx, proxy, array, proxy, array
- cfw.addInvoke(ByteCode.INVOKEINTERFACE,
- "org/mozilla/javascript/RegExpProxy",
- "wrapRegExp",
- "(Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/Object;"
- +")Lorg/mozilla/javascript/Scriptable;");
- // Stack: wrappedRegExp, array, proxy, array
- cfw.addPush(i);
- cfw.add(ByteCode.SWAP);
- cfw.add(ByteCode.AASTORE);
- // Stack: proxy, array
- }
- // remove proxy
- cfw.add(ByteCode.POP);
- }
-
- void pushNumberAsObject(ClassFileWriter cfw, double num)
- {
- if (num == 0.0) {
- if (1 / num > 0) {
- // +0.0
- cfw.add(ByteCode.GETSTATIC,
- "org/mozilla/javascript/optimizer/OptRuntime",
- "zeroObj", "Ljava/lang/Double;");
- } else {
- cfw.addPush(num);
- addDoubleWrap(cfw);
- }
-
- } else if (num == 1.0) {
- cfw.add(ByteCode.GETSTATIC,
- "org/mozilla/javascript/optimizer/OptRuntime",
- "oneObj", "Ljava/lang/Double;");
- return;
-
- } else if (num == -1.0) {
- cfw.add(ByteCode.GETSTATIC,
- "org/mozilla/javascript/optimizer/OptRuntime",
- "minusOneObj", "Ljava/lang/Double;");
-
- } else if (num != num) {
- cfw.add(ByteCode.GETSTATIC,
- "org/mozilla/javascript/ScriptRuntime",
- "NaNobj", "Ljava/lang/Double;");
-
- } else if (itsConstantListSize >= 2000) {
- // There appears to be a limit in the JVM on either the number
- // of static fields in a class or the size of the class
- // initializer. Either way, we can't have any more than 2000
- // statically init'd constants.
- cfw.addPush(num);
- addDoubleWrap(cfw);
-
- } else {
- int N = itsConstantListSize;
- int index = 0;
- if (N == 0) {
- itsConstantList = new double[64];
- } else {
- double[] array = itsConstantList;
- while (index != N && array[index] != num) {
- ++index;
- }
- if (N == array.length) {
- array = new double[N * 2];
- System.arraycopy(itsConstantList, 0, array, 0, N);
- itsConstantList = array;
- }
- }
- if (index == N) {
- itsConstantList[N] = num;
- itsConstantListSize = N + 1;
- }
- String constantName = "_k" + index;
- String constantType = getStaticConstantWrapperType(num);
- cfw.add(ByteCode.GETSTATIC, mainClassName,
- constantName, constantType);
- }
- }
-
- private static void addDoubleWrap(ClassFileWriter cfw)
- {
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/optimizer/OptRuntime",
- "wrapDouble", "(D)Ljava/lang/Double;");
- }
-
- private static String getStaticConstantWrapperType(double num)
- {
- int inum = (int)num;
- if (inum == num) {
- return "Ljava/lang/Integer;";
- } else {
- return "Ljava/lang/Double;";
- }
- }
- static void pushUndefined(ClassFileWriter cfw)
- {
- cfw.add(ByteCode.GETSTATIC, "org/mozilla/javascript/Undefined",
- "instance", "Ljava/lang/Object;");
- }
-
- int getIndex(ScriptOrFnNode n)
- {
- return scriptOrFnIndexes.getExisting(n);
- }
-
- static String getDirectTargetFieldName(int i)
- {
- return "_dt" + i;
- }
-
- String getDirectCtorName(ScriptOrFnNode n)
- {
- return "_n"+getIndex(n);
- }
-
- String getBodyMethodName(ScriptOrFnNode n)
- {
- return "_c"+getIndex(n);
- }
-
- String getBodyMethodSignature(ScriptOrFnNode n)
- {
- StringBuffer sb = new StringBuffer();
- sb.append('(');
- sb.append(mainClassSignature);
- sb.append("Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Scriptable;");
- if (n.getType() == Token.FUNCTION) {
- OptFunctionNode ofn = OptFunctionNode.get(n);
- if (ofn.isTargetOfDirectCall()) {
- int pCount = ofn.fnode.getParamCount();
- for (int i = 0; i != pCount; i++) {
- sb.append("Ljava/lang/Object;D");
- }
- }
- }
- sb.append("[Ljava/lang/Object;)Ljava/lang/Object;");
- return sb.toString();
- }
-
- String getFunctionInitMethodName(OptFunctionNode ofn)
- {
- return "_i"+getIndex(ofn.fnode);
- }
-
- String getCompiledRegexpName(ScriptOrFnNode n, int regexpIndex)
- {
- return "_re"+getIndex(n)+"_"+regexpIndex;
- }
-
- static RuntimeException badTree()
- {
- throw new RuntimeException("Bad tree in codegen");
- }
-
- void setMainMethodClass(String className)
- {
- mainMethodClass = className;
- }
-
- static final String DEFAULT_MAIN_METHOD_CLASS
- = "org.mozilla.javascript.optimizer.OptRuntime";
-
- private static final String SUPER_CLASS_NAME
- = "org.mozilla.javascript.NativeFunction";
-
- static final String DIRECT_CALL_PARENT_FIELD = "_dcp";
- private static final String ID_FIELD_NAME = "_id";
-
- private static final String REGEXP_INIT_METHOD_NAME = "_reInit";
- private static final String REGEXP_INIT_METHOD_SIGNATURE
- = "(Lorg/mozilla/javascript/RegExpProxy;"
- +"Lorg/mozilla/javascript/Context;"
- +")V";
- static final String REGEXP_ARRAY_FIELD_NAME = "_re";
- static final String REGEXP_ARRAY_FIELD_TYPE = "[Ljava/lang/Object;";
-
- static final String FUNCTION_INIT_SIGNATURE
- = "(Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")V";
-
- static final String FUNCTION_CONSTRUCTOR_SIGNATURE
- = "(Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Context;I)V";
-
- private static final Object globalLock = new Object();
- private static int globalSerialClassCounter;
-
- private CompilerEnvirons compilerEnv;
-
- private ObjArray directCallTargets;
- ScriptOrFnNode[] scriptOrFnNodes;
- private ObjToIntMap scriptOrFnIndexes;
-
- private String mainMethodClass = DEFAULT_MAIN_METHOD_CLASS;
-
- String mainClassName;
- String mainClassSignature;
-
- private double[] itsConstantList;
- private int itsConstantListSize;
-}
-
-
-class BodyCodegen
-{
- void generateBodyCode()
- {
- isGenerator = Codegen.isGenerator(scriptOrFn);
-
- // generate the body of the current function or script object
- initBodyGeneration();
-
- if (isGenerator) {
-
- // All functions in the generated bytecode have a unique name. Every
- // generator has a unique prefix followed by _gen
- String type = "(" +
- codegen.mainClassSignature +
- "Lorg/mozilla/javascript/Context;" +
- "Lorg/mozilla/javascript/Scriptable;" +
- "Ljava/lang/Object;" +
- "Ljava/lang/Object;I)Ljava/lang/Object;";
- cfw.startMethod(codegen.getBodyMethodName(scriptOrFn) + "_gen",
- type,
- (short)(ClassFileWriter.ACC_STATIC
- | ClassFileWriter.ACC_PRIVATE));
- } else {
- cfw.startMethod(codegen.getBodyMethodName(scriptOrFn),
- codegen.getBodyMethodSignature(scriptOrFn),
- (short)(ClassFileWriter.ACC_STATIC
- | ClassFileWriter.ACC_PRIVATE));
- }
-
- generatePrologue();
- Node treeTop;
- if (fnCurrent != null) {
- treeTop = scriptOrFn.getLastChild();
- } else {
- treeTop = scriptOrFn;
- }
- generateStatement(treeTop);
- generateEpilogue();
-
- cfw.stopMethod((short)(localsMax + 1));
-
- if (isGenerator) {
- // generate the user visible method which when invoked will
- // return a generator object
- generateGenerator();
- }
- }
-
- // This creates a the user-facing function that returns a NativeGenerator
- // object.
- private void generateGenerator()
- {
- cfw.startMethod(codegen.getBodyMethodName(scriptOrFn),
- codegen.getBodyMethodSignature(scriptOrFn),
- (short)(ClassFileWriter.ACC_STATIC
- | ClassFileWriter.ACC_PRIVATE));
-
- initBodyGeneration();
- argsLocal = firstFreeLocal++;
- localsMax = firstFreeLocal;
-
- // get top level scope
- if (fnCurrent != null && !inDirectCallFunction
- && (!compilerEnv.isUseDynamicScope()
- || fnCurrent.fnode.getIgnoreDynamicScope()))
- {
- // Unless we're either in a direct call or using dynamic scope,
- // use the enclosing scope of the function as our variable object.
- cfw.addALoad(funObjLocal);
- cfw.addInvoke(ByteCode.INVOKEINTERFACE,
- "org/mozilla/javascript/Scriptable",
- "getParentScope",
- "()Lorg/mozilla/javascript/Scriptable;");
- cfw.addAStore(variableObjectLocal);
- }
-
- // generators are forced to have an activation record
- cfw.addALoad(funObjLocal);
- cfw.addALoad(variableObjectLocal);
- cfw.addALoad(argsLocal);
- addScriptRuntimeInvoke("createFunctionActivation",
- "(Lorg/mozilla/javascript/NativeFunction;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"[Ljava/lang/Object;"
- +")Lorg/mozilla/javascript/Scriptable;");
- cfw.addAStore(variableObjectLocal);
-
- // create a function object
- cfw.add(ByteCode.NEW, codegen.mainClassName);
- // Call function constructor
- cfw.add(ByteCode.DUP);
- cfw.addALoad(variableObjectLocal);
- cfw.addALoad(contextLocal); // load 'cx'
- cfw.addPush(scriptOrFnIndex);
- cfw.addInvoke(ByteCode.INVOKESPECIAL, codegen.mainClassName,
- "<init>", Codegen.FUNCTION_CONSTRUCTOR_SIGNATURE);
-
- // Init mainScript field
- cfw.add(ByteCode.DUP);
- if (isTopLevel) Kit.codeBug(); // Only functions can be generators
- cfw.add(ByteCode.ALOAD_0);
- cfw.add(ByteCode.GETFIELD,
- codegen.mainClassName,
- Codegen.DIRECT_CALL_PARENT_FIELD,
- codegen.mainClassSignature);
- cfw.add(ByteCode.PUTFIELD,
- codegen.mainClassName,
- Codegen.DIRECT_CALL_PARENT_FIELD,
- codegen.mainClassSignature);
-
- generateNestedFunctionInits();
-
- // create the NativeGenerator object that we return
- cfw.addALoad(variableObjectLocal);
- cfw.addALoad(thisObjLocal);
- cfw.addLoadConstant(maxLocals);
- cfw.addLoadConstant(maxStack);
- addOptRuntimeInvoke("createNativeGenerator",
- "(Lorg/mozilla/javascript/NativeFunction;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Scriptable;II"
- +")Lorg/mozilla/javascript/Scriptable;");
-
- cfw.add(ByteCode.ARETURN);
- cfw.stopMethod((short)(localsMax + 1));
- }
-
- private void generateNestedFunctionInits()
- {
- int functionCount = scriptOrFn.getFunctionCount();
- for (int i = 0; i != functionCount; i++) {
- OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn, i);
- if (ofn.fnode.getFunctionType()
- == FunctionNode.FUNCTION_STATEMENT)
- {
- visitFunction(ofn, FunctionNode.FUNCTION_STATEMENT);
- }
- }
- }
-
- private void initBodyGeneration()
- {
- isTopLevel = (scriptOrFn == codegen.scriptOrFnNodes[0]);
-
- varRegisters = null;
- if (scriptOrFn.getType() == Token.FUNCTION) {
- fnCurrent = OptFunctionNode.get(scriptOrFn);
- hasVarsInRegs = !fnCurrent.fnode.requiresActivation();
- if (hasVarsInRegs) {
- int n = fnCurrent.fnode.getParamAndVarCount();
- if (n != 0) {
- varRegisters = new short[n];
- }
- }
- inDirectCallFunction = fnCurrent.isTargetOfDirectCall();
- if (inDirectCallFunction && !hasVarsInRegs) Codegen.badTree();
- } else {
- fnCurrent = null;
- hasVarsInRegs = false;
- inDirectCallFunction = false;
- }
-
- locals = new int[MAX_LOCALS];
-
- funObjLocal = 0;
- contextLocal = 1;
- variableObjectLocal = 2;
- thisObjLocal = 3;
- localsMax = (short) 4; // number of parms + "this"
- firstFreeLocal = 4;
-
- popvLocal = -1;
- argsLocal = -1;
- itsZeroArgArray = -1;
- itsOneArgArray = -1;
- scriptRegexpLocal = -1;
- epilogueLabel = -1;
- enterAreaStartLabel = -1;
- generatorStateLocal = -1;
- }
-
- /**
- * Generate the prologue for a function or script.
- */
- private void generatePrologue()
- {
- if (inDirectCallFunction) {
- int directParameterCount = scriptOrFn.getParamCount();
- // 0 is reserved for function Object 'this'
- // 1 is reserved for context
- // 2 is reserved for parentScope
- // 3 is reserved for script 'this'
- if (firstFreeLocal != 4) Kit.codeBug();
- for (int i = 0; i != directParameterCount; ++i) {
- varRegisters[i] = firstFreeLocal;
- // 3 is 1 for Object parm and 2 for double parm
- firstFreeLocal += 3;
- }
- if (!fnCurrent.getParameterNumberContext()) {
- // make sure that all parameters are objects
- itsForcedObjectParameters = true;
- for (int i = 0; i != directParameterCount; ++i) {
- short reg = varRegisters[i];
- cfw.addALoad(reg);
- cfw.add(ByteCode.GETSTATIC,
- "java/lang/Void",
- "TYPE",
- "Ljava/lang/Class;");
- int isObjectLabel = cfw.acquireLabel();
- cfw.add(ByteCode.IF_ACMPNE, isObjectLabel);
- cfw.addDLoad(reg + 1);
- addDoubleWrap();
- cfw.addAStore(reg);
- cfw.markLabel(isObjectLabel);
- }
- }
- }
-
- if (fnCurrent != null && !inDirectCallFunction
- && (!compilerEnv.isUseDynamicScope()
- || fnCurrent.fnode.getIgnoreDynamicScope()))
- {
- // Unless we're either in a direct call or using dynamic scope,
- // use the enclosing scope of the function as our variable object.
- cfw.addALoad(funObjLocal);
- cfw.addInvoke(ByteCode.INVOKEINTERFACE,
- "org/mozilla/javascript/Scriptable",
- "getParentScope",
- "()Lorg/mozilla/javascript/Scriptable;");
- cfw.addAStore(variableObjectLocal);
- }
-
- // reserve 'args[]'
- argsLocal = firstFreeLocal++;
- localsMax = firstFreeLocal;
-
- // Generate Generator specific prelude
- if (isGenerator) {
-
- // reserve 'args[]'
- operationLocal = firstFreeLocal++;
- localsMax = firstFreeLocal;
-
- // Local 3 is a reference to a GeneratorState object. The rest
- // of codegen expects local 3 to be a reference to the thisObj.
- // So move the value in local 3 to generatorStateLocal, and load
- // the saved thisObj from the GeneratorState object.
- cfw.addALoad(thisObjLocal);
- generatorStateLocal = firstFreeLocal++;
- localsMax = firstFreeLocal;
- cfw.add(ByteCode.CHECKCAST, OptRuntime.GeneratorState.CLASS_NAME);
- cfw.add(ByteCode.DUP);
- cfw.addAStore(generatorStateLocal);
- cfw.add(ByteCode.GETFIELD,
- OptRuntime.GeneratorState.CLASS_NAME,
- OptRuntime.GeneratorState.thisObj_NAME,
- OptRuntime.GeneratorState.thisObj_TYPE);
- cfw.addAStore(thisObjLocal);
-
- if (epilogueLabel == -1) {
- epilogueLabel = cfw.acquireLabel();
- }
-
- ArrayList targets = ((FunctionNode)scriptOrFn).getResumptionPoints();
- if (targets != null) {
- // get resumption point
- generateGetGeneratorResumptionPoint();
-
- // generate dispatch table
- generatorSwitch = cfw.addTableSwitch(0,
- targets.size() + GENERATOR_START);
- generateCheckForThrowOrClose(-1, false, GENERATOR_START);
- }
- }
-
- if (fnCurrent == null) {
- // See comments in case Token.REGEXP
- if (scriptOrFn.getRegexpCount() != 0) {
- scriptRegexpLocal = getNewWordLocal();
- codegen.pushRegExpArray(cfw, scriptOrFn, contextLocal,
- variableObjectLocal);
- cfw.addAStore(scriptRegexpLocal);
- }
- }
-
- if (compilerEnv.isGenerateObserverCount())
- saveCurrentCodeOffset();
-
- if (hasVarsInRegs) {
- // No need to create activation. Pad arguments if need be.
- int parmCount = scriptOrFn.getParamCount();
- if (parmCount > 0 && !inDirectCallFunction) {
- // Set up args array
- // check length of arguments, pad if need be
- cfw.addALoad(argsLocal);
- cfw.add(ByteCode.ARRAYLENGTH);
- cfw.addPush(parmCount);
- int label = cfw.acquireLabel();
- cfw.add(ByteCode.IF_ICMPGE, label);
- cfw.addALoad(argsLocal);
- cfw.addPush(parmCount);
- addScriptRuntimeInvoke("padArguments",
- "([Ljava/lang/Object;I"
- +")[Ljava/lang/Object;");
- cfw.addAStore(argsLocal);
- cfw.markLabel(label);
- }
-
- int paramCount = fnCurrent.fnode.getParamCount();
- int varCount = fnCurrent.fnode.getParamAndVarCount();
- boolean [] constDeclarations = fnCurrent.fnode.getParamAndVarConst();
-
- // REMIND - only need to initialize the vars that don't get a value
- // before the next call and are used in the function
- short firstUndefVar = -1;
- for (int i = 0; i != varCount; ++i) {
- short reg = -1;
- if (i < paramCount) {
- if (!inDirectCallFunction) {
- reg = getNewWordLocal();
- cfw.addALoad(argsLocal);
- cfw.addPush(i);
- cfw.add(ByteCode.AALOAD);
- cfw.addAStore(reg);
- }
- } else if (fnCurrent.isNumberVar(i)) {
- reg = getNewWordPairLocal(constDeclarations[i]);
- cfw.addPush(0.0);
- cfw.addDStore(reg);
- } else {
- reg = getNewWordLocal(constDeclarations[i]);
- if (firstUndefVar == -1) {
- Codegen.pushUndefined(cfw);
- firstUndefVar = reg;
- } else {
- cfw.addALoad(firstUndefVar);
- }
- cfw.addAStore(reg);
- }
- if (reg >= 0) {
- if (constDeclarations[i]) {
- cfw.addPush(0);
- cfw.addIStore(reg + (fnCurrent.isNumberVar(i) ? 2 : 1));
- }
- varRegisters[i] = reg;
- }
-
- // Add debug table entry if we're generating debug info
- if (compilerEnv.isGenerateDebugInfo()) {
- String name = fnCurrent.fnode.getParamOrVarName(i);
- String type = fnCurrent.isNumberVar(i)
- ? "D" : "Ljava/lang/Object;";
- int startPC = cfw.getCurrentCodeOffset();
- if (reg < 0) {
- reg = varRegisters[i];
- }
- cfw.addVariableDescriptor(name, type, startPC, reg);
- }
- }
-
- // Skip creating activation object.
- return;
- }
-
- // skip creating activation object for the body of a generator. The
- // activation record required by a generator has already been created
- // in generateGenerator().
- if (isGenerator)
- return;
-
-
- String debugVariableName;
- if (fnCurrent != null) {
- debugVariableName = "activation";
- cfw.addALoad(funObjLocal);
- cfw.addALoad(variableObjectLocal);
- cfw.addALoad(argsLocal);
- addScriptRuntimeInvoke("createFunctionActivation",
- "(Lorg/mozilla/javascript/NativeFunction;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"[Ljava/lang/Object;"
- +")Lorg/mozilla/javascript/Scriptable;");
- cfw.addAStore(variableObjectLocal);
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- addScriptRuntimeInvoke("enterActivationFunction",
- "(Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")V");
- } else {
- debugVariableName = "global";
- cfw.addALoad(funObjLocal);
- cfw.addALoad(thisObjLocal);
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- cfw.addPush(0); // false to indicate it is not eval script
- addScriptRuntimeInvoke("initScript",
- "(Lorg/mozilla/javascript/NativeFunction;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Z"
- +")V");
- }
-
- enterAreaStartLabel = cfw.acquireLabel();
- epilogueLabel = cfw.acquireLabel();
- cfw.markLabel(enterAreaStartLabel);
-
- generateNestedFunctionInits();
-
- // default is to generate debug info
- if (compilerEnv.isGenerateDebugInfo()) {
- cfw.addVariableDescriptor(debugVariableName,
- "Lorg/mozilla/javascript/Scriptable;",
- cfw.getCurrentCodeOffset(), variableObjectLocal);
- }
-
- if (fnCurrent == null) {
- // OPT: use dataflow to prove that this assignment is dead
- popvLocal = getNewWordLocal();
- Codegen.pushUndefined(cfw);
- cfw.addAStore(popvLocal);
-
- int linenum = scriptOrFn.getEndLineno();
- if (linenum != -1)
- cfw.addLineNumberEntry((short)linenum);
-
- } else {
- if (fnCurrent.itsContainsCalls0) {
- itsZeroArgArray = getNewWordLocal();
- cfw.add(ByteCode.GETSTATIC,
- "org/mozilla/javascript/ScriptRuntime",
- "emptyArgs", "[Ljava/lang/Object;");
- cfw.addAStore(itsZeroArgArray);
- }
- if (fnCurrent.itsContainsCalls1) {
- itsOneArgArray = getNewWordLocal();
- cfw.addPush(1);
- cfw.add(ByteCode.ANEWARRAY, "java/lang/Object");
- cfw.addAStore(itsOneArgArray);
- }
- }
- }
-
- private void generateGetGeneratorResumptionPoint()
- {
- cfw.addALoad(generatorStateLocal);
- cfw.add(ByteCode.GETFIELD,
- OptRuntime.GeneratorState.CLASS_NAME,
- OptRuntime.GeneratorState.resumptionPoint_NAME,
- OptRuntime.GeneratorState.resumptionPoint_TYPE);
- }
-
- private void generateSetGeneratorResumptionPoint(int nextState)
- {
- cfw.addALoad(generatorStateLocal);
- cfw.addLoadConstant(nextState);
- cfw.add(ByteCode.PUTFIELD,
- OptRuntime.GeneratorState.CLASS_NAME,
- OptRuntime.GeneratorState.resumptionPoint_NAME,
- OptRuntime.GeneratorState.resumptionPoint_TYPE);
- }
-
- private void generateGetGeneratorStackState()
- {
- cfw.addALoad(generatorStateLocal);
- addOptRuntimeInvoke("getGeneratorStackState",
- "(Ljava/lang/Object;)[Ljava/lang/Object;");
- }
-
- private void generateEpilogue()
- {
- if (compilerEnv.isGenerateObserverCount())
- addInstructionCount();
- if (isGenerator) {
- // generate locals initialization
- HashMap liveLocals = ((FunctionNode)scriptOrFn).getLiveLocals();
- if (liveLocals != null) {
- ArrayList nodes = ((FunctionNode)scriptOrFn).getResumptionPoints();
- for (int i = 0; i < nodes.size(); i++) {
- Node node = (Node) nodes.get(i);
- int[] live = (int [])liveLocals.get(node);
- if (live != null) {
- cfw.markTableSwitchCase(generatorSwitch,
- getNextGeneratorState(node));
- generateGetGeneratorLocalsState();
- for (int j = 0; j < live.length; j++) {
- cfw.add(ByteCode.DUP);
- cfw.addLoadConstant(j);
- cfw.add(ByteCode.AALOAD);
- cfw.addAStore(live[j]);
- }
- cfw.add(ByteCode.POP);
- cfw.add(ByteCode.GOTO, getTargetLabel(node));
- }
- }
- }
-
- // generate dispatch tables for finally
- if (finallys != null) {
- Enumeration en = finallys.keys();
- while(en.hasMoreElements()) {
- Node n = (Node) en.nextElement();
- if (n.getType() == Token.FINALLY) {
- FinallyReturnPoint ret =
- (FinallyReturnPoint)finallys.get(n);
- // the finally will jump here
- cfw.markLabel(ret.tableLabel, (short)1);
-
- // start generating a dispatch table
- int startSwitch = cfw.addTableSwitch(0,
- ret.jsrPoints.size() - 1);
- int c = 0;
- cfw.markTableSwitchDefault(startSwitch);
- for (int i = 0; i < ret.jsrPoints.size(); i++) {
- // generate gotos back to the JSR location
- cfw.markTableSwitchCase(startSwitch, c);
- cfw.add(ByteCode.GOTO,
- ((Integer)ret.jsrPoints.get(i)).intValue());
- c++;
- }
- }
- }
- }
- }
-
- if (epilogueLabel != -1) {
- cfw.markLabel(epilogueLabel);
- }
-
- if (hasVarsInRegs) {
- cfw.add(ByteCode.ARETURN);
- return;
- } else if (isGenerator) {
- if (((FunctionNode)scriptOrFn).getResumptionPoints() != null) {
- cfw.markTableSwitchDefault(generatorSwitch);
- }
-
- // change state for re-entry
- generateSetGeneratorResumptionPoint(GENERATOR_TERMINATE);
-
- // throw StopIteration
- cfw.addALoad(variableObjectLocal);
- addOptRuntimeInvoke("throwStopIteration",
- "(Ljava/lang/Object;)V");
-
- Codegen.pushUndefined(cfw);
- cfw.add(ByteCode.ARETURN);
-
- } else if (fnCurrent == null) {
- cfw.addALoad(popvLocal);
- cfw.add(ByteCode.ARETURN);
- } else {
- generateActivationExit();
- cfw.add(ByteCode.ARETURN);
-
- // Generate catch block to catch all and rethrow to call exit code
- // under exception propagation as well.
-
- int finallyHandler = cfw.acquireLabel();
- cfw.markHandler(finallyHandler);
- short exceptionObject = getNewWordLocal();
- cfw.addAStore(exceptionObject);
-
- // Duplicate generateActivationExit() in the catch block since it
- // takes less space then full-featured ByteCode.JSR/ByteCode.RET
- generateActivationExit();
-
- cfw.addALoad(exceptionObject);
- releaseWordLocal(exceptionObject);
- // rethrow
- cfw.add(ByteCode.ATHROW);
-
- // mark the handler
- cfw.addExceptionHandler(enterAreaStartLabel, epilogueLabel,
- finallyHandler, null); // catch any
- }
- }
-
- private void generateGetGeneratorLocalsState() {
- cfw.addALoad(generatorStateLocal);
- addOptRuntimeInvoke("getGeneratorLocalsState",
- "(Ljava/lang/Object;)[Ljava/lang/Object;");
- }
-
- private void generateActivationExit()
- {
- if (fnCurrent == null || hasVarsInRegs) throw Kit.codeBug();
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke("exitActivationFunction",
- "(Lorg/mozilla/javascript/Context;)V");
- }
-
- private void generateStatement(Node node)
- {
- updateLineNumber(node);
- int type = node.getType();
- Node child = node.getFirstChild();
- switch (type) {
- case Token.LOOP:
- case Token.LABEL:
- case Token.WITH:
- case Token.SCRIPT:
- case Token.BLOCK:
- case Token.EMPTY:
- // no-ops.
- while (child != null) {
- generateStatement(child);
- child = child.getNext();
- }
- break;
-
- case Token.LOCAL_BLOCK: {
- int local = getNewWordLocal();
- if (isGenerator) {
- cfw.add(ByteCode.ACONST_NULL);
- cfw.addAStore(local);
- }
- node.putIntProp(Node.LOCAL_PROP, local);
- while (child != null) {
- generateStatement(child);
- child = child.getNext();
- }
- releaseWordLocal((short)local);
- node.removeProp(Node.LOCAL_PROP);
- break;
- }
-
- case Token.FUNCTION: {
- int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP);
- OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn, fnIndex);
- int t = ofn.fnode.getFunctionType();
- if (t == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) {
- visitFunction(ofn, t);
- } else {
- if (t != FunctionNode.FUNCTION_STATEMENT) {
- throw Codegen.badTree();
- }
- }
- break;
- }
-
- case Token.TRY:
- visitTryCatchFinally((Node.Jump)node, child);
- break;
-
- case Token.CATCH_SCOPE:
- {
- // nothing stays on the stack on entry into a catch scope
- cfw.setStackTop((short) 0);
-
- int local = getLocalBlockRegister(node);
- int scopeIndex
- = node.getExistingIntProp(Node.CATCH_SCOPE_PROP);
-
- String name = child.getString(); // name of exception
- child = child.getNext();
- generateExpression(child, node); // load expression object
- if (scopeIndex == 0) {
- cfw.add(ByteCode.ACONST_NULL);
- } else {
- // Load previous catch scope object
- cfw.addALoad(local);
- }
- cfw.addPush(name);
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
-
- addScriptRuntimeInvoke(
- "newCatchScope",
- "(Ljava/lang/Throwable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Lorg/mozilla/javascript/Scriptable;");
- cfw.addAStore(local);
- }
- break;
-
- case Token.THROW:
- generateExpression(child, node);
- if (compilerEnv.isGenerateObserverCount())
- addInstructionCount();
- generateThrowJavaScriptException();
- break;
-
- case Token.RETHROW:
- if (compilerEnv.isGenerateObserverCount())
- addInstructionCount();
- cfw.addALoad(getLocalBlockRegister(node));
- cfw.add(ByteCode.ATHROW);
- break;
-
- case Token.RETURN_RESULT:
- case Token.RETURN:
- if (!isGenerator) {
- if (child != null) {
- generateExpression(child, node);
- } else if (type == Token.RETURN) {
- Codegen.pushUndefined(cfw);
- } else {
- if (popvLocal < 0) throw Codegen.badTree();
- cfw.addALoad(popvLocal);
- }
- }
- if (compilerEnv.isGenerateObserverCount())
- addInstructionCount();
- if (epilogueLabel == -1) {
- if (!hasVarsInRegs) throw Codegen.badTree();
- epilogueLabel = cfw.acquireLabel();
- }
- cfw.add(ByteCode.GOTO, epilogueLabel);
- break;
-
- case Token.SWITCH:
- if (compilerEnv.isGenerateObserverCount())
- addInstructionCount();
- visitSwitch((Node.Jump)node, child);
- break;
-
- case Token.ENTERWITH:
- generateExpression(child, node);
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- addScriptRuntimeInvoke(
- "enterWith",
- "(Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Lorg/mozilla/javascript/Scriptable;");
- cfw.addAStore(variableObjectLocal);
- incReferenceWordLocal(variableObjectLocal);
- break;
-
- case Token.LEAVEWITH:
- cfw.addALoad(variableObjectLocal);
- addScriptRuntimeInvoke(
- "leaveWith",
- "(Lorg/mozilla/javascript/Scriptable;"
- +")Lorg/mozilla/javascript/Scriptable;");
- cfw.addAStore(variableObjectLocal);
- decReferenceWordLocal(variableObjectLocal);
- break;
-
- case Token.ENUM_INIT_KEYS:
- case Token.ENUM_INIT_VALUES:
- case Token.ENUM_INIT_ARRAY:
- generateExpression(child, node);
- cfw.addALoad(contextLocal);
- int enumType = type == Token.ENUM_INIT_KEYS
- ? ScriptRuntime.ENUMERATE_KEYS :
- type == Token.ENUM_INIT_VALUES
- ? ScriptRuntime.ENUMERATE_VALUES :
- ScriptRuntime.ENUMERATE_ARRAY;
- cfw.addPush(enumType);
- addScriptRuntimeInvoke("enumInit",
- "(Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"I"
- +")Ljava/lang/Object;");
- cfw.addAStore(getLocalBlockRegister(node));
- break;
-
- case Token.EXPR_VOID:
- if (child.getType() == Token.SETVAR) {
- /* special case this so as to avoid unnecessary
- load's & pop's */
- visitSetVar(child, child.getFirstChild(), false);
- }
- else if (child.getType() == Token.SETCONSTVAR) {
- /* special case this so as to avoid unnecessary
- load's & pop's */
- visitSetConstVar(child, child.getFirstChild(), false);
- }
- else if (child.getType() == Token.YIELD) {
- generateYieldPoint(child, false);
- }
- else {
- generateExpression(child, node);
- if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1)
- cfw.add(ByteCode.POP2);
- else
- cfw.add(ByteCode.POP);
- }
- break;
-
- case Token.EXPR_RESULT:
- generateExpression(child, node);
- if (popvLocal < 0) {
- popvLocal = getNewWordLocal();
- }
- cfw.addAStore(popvLocal);
- break;
-
- case Token.TARGET:
- {
- if (compilerEnv.isGenerateObserverCount())
- addInstructionCount();
- int label = getTargetLabel(node);
- cfw.markLabel(label);
- if (compilerEnv.isGenerateObserverCount())
- saveCurrentCodeOffset();
- }
- break;
-
- case Token.JSR:
- case Token.GOTO:
- case Token.IFEQ:
- case Token.IFNE:
- if (compilerEnv.isGenerateObserverCount())
- addInstructionCount();
- visitGoto((Node.Jump)node, type, child);
- break;
-
- case Token.FINALLY:
- {
- if (compilerEnv.isGenerateObserverCount())
- saveCurrentCodeOffset();
- // there is exactly one value on the stack when enterring
- // finally blocks: the return address (or its int encoding)
- cfw.setStackTop((short)1);
-
- // Save return address in a new local
- int finallyRegister = getNewWordLocal();
- if (isGenerator)
- generateIntegerWrap();
- cfw.addAStore(finallyRegister);
-
- while (child != null) {
- generateStatement(child);
- child = child.getNext();
- }
- if (isGenerator) {
- cfw.addALoad(finallyRegister);
- cfw.add(ByteCode.CHECKCAST, "java/lang/Integer");
- generateIntegerUnwrap();
- FinallyReturnPoint ret =
- (FinallyReturnPoint)finallys.get(node);
- ret.tableLabel = cfw.acquireLabel();
- cfw.add(ByteCode.GOTO, ret.tableLabel);
- } else {
- cfw.add(ByteCode.RET, finallyRegister);
- }
- releaseWordLocal((short)finallyRegister);
- }
- break;
-
- case Token.DEBUGGER:
- break;
-
- default:
- throw Codegen.badTree();
- }
-
- }
-
- private void generateIntegerWrap()
- {
- cfw.addInvoke(ByteCode.INVOKESTATIC, "java/lang/Integer", "valueOf",
- "(I)Ljava/lang/Integer;");
- }
-
-
- private void generateIntegerUnwrap()
- {
- cfw.addInvoke(ByteCode.INVOKEVIRTUAL, "java/lang/Integer",
- "intValue", "()I");
- }
-
-
- private void generateThrowJavaScriptException()
- {
- cfw.add(ByteCode.NEW,
- "org/mozilla/javascript/JavaScriptException");
- cfw.add(ByteCode.DUP_X1);
- cfw.add(ByteCode.SWAP);
- cfw.addPush(scriptOrFn.getSourceName());
- cfw.addPush(itsLineNumber);
- cfw.addInvoke(
- ByteCode.INVOKESPECIAL,
- "org/mozilla/javascript/JavaScriptException",
- "<init>",
- "(Ljava/lang/Object;Ljava/lang/String;I)V");
- cfw.add(ByteCode.ATHROW);
- }
-
- private int getNextGeneratorState(Node node)
- {
- int nodeIndex = ((FunctionNode)scriptOrFn).getResumptionPoints()
- .indexOf(node);
- return nodeIndex + GENERATOR_YIELD_START;
- }
-
- private void generateExpression(Node node, Node parent)
- {
- int type = node.getType();
- Node child = node.getFirstChild();
- switch (type) {
- case Token.USE_STACK:
- break;
-
- case Token.FUNCTION:
- if (fnCurrent != null || parent.getType() != Token.SCRIPT) {
- int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP);
- OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn,
- fnIndex);
- int t = ofn.fnode.getFunctionType();
- if (t != FunctionNode.FUNCTION_EXPRESSION) {
- throw Codegen.badTree();
- }
- visitFunction(ofn, t);
- }
- break;
-
- case Token.NAME:
- {
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- cfw.addPush(node.getString());
- addScriptRuntimeInvoke(
- "name",
- "(Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/String;"
- +")Ljava/lang/Object;");
- }
- break;
-
- case Token.CALL:
- case Token.NEW:
- {
- int specialType = node.getIntProp(Node.SPECIALCALL_PROP,
- Node.NON_SPECIALCALL);
- if (specialType == Node.NON_SPECIALCALL) {
- OptFunctionNode target;
- target = (OptFunctionNode)node.getProp(
- Node.DIRECTCALL_PROP);
-
- if (target != null) {
- visitOptimizedCall(node, target, type, child);
- } else if (type == Token.CALL) {
- visitStandardCall(node, child);
- } else {
- visitStandardNew(node, child);
- }
- } else {
- visitSpecialCall(node, type, specialType, child);
- }
- }
- break;
-
- case Token.REF_CALL:
- generateFunctionAndThisObj(child, node);
- // stack: ... functionObj thisObj
- child = child.getNext();
- generateCallArgArray(node, child, false);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "callRef",
- "(Lorg/mozilla/javascript/Callable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"[Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Lorg/mozilla/javascript/Ref;");
- break;
-
- case Token.NUMBER:
- {
- double num = node.getDouble();
- if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
- cfw.addPush(num);
- } else {
- codegen.pushNumberAsObject(cfw, num);
- }
- }
- break;
-
- case Token.STRING:
- cfw.addPush(node.getString());
- break;
-
- case Token.THIS:
- cfw.addALoad(thisObjLocal);
- break;
-
- case Token.THISFN:
- cfw.add(ByteCode.ALOAD_0);
- break;
-
- case Token.NULL:
- cfw.add(ByteCode.ACONST_NULL);
- break;
-
- case Token.TRUE:
- cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean",
- "TRUE", "Ljava/lang/Boolean;");
- break;
-
- case Token.FALSE:
- cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean",
- "FALSE", "Ljava/lang/Boolean;");
- break;
-
- case Token.REGEXP:
- {
- int i = node.getExistingIntProp(Node.REGEXP_PROP);
- // Scripts can not use REGEXP_ARRAY_FIELD_NAME since
- // it it will make script.exec non-reentrant so they
- // store regexp array in a local variable while
- // functions always access precomputed
- // REGEXP_ARRAY_FIELD_NAME not to consume locals
- if (fnCurrent == null) {
- cfw.addALoad(scriptRegexpLocal);
- } else {
- cfw.addALoad(funObjLocal);
- cfw.add(ByteCode.GETFIELD, codegen.mainClassName,
- Codegen.REGEXP_ARRAY_FIELD_NAME,
- Codegen.REGEXP_ARRAY_FIELD_TYPE);
- }
- cfw.addPush(i);
- cfw.add(ByteCode.AALOAD);
- }
- break;
-
- case Token.COMMA: {
- Node next = child.getNext();
- while (next != null) {
- generateExpression(child, node);
- cfw.add(ByteCode.POP);
- child = next;
- next = next.getNext();
- }
- generateExpression(child, node);
- break;
- }
-
- case Token.ENUM_NEXT:
- case Token.ENUM_ID: {
- int local = getLocalBlockRegister(node);
- cfw.addALoad(local);
- if (type == Token.ENUM_NEXT) {
- addScriptRuntimeInvoke(
- "enumNext", "(Ljava/lang/Object;)Ljava/lang/Boolean;");
- } else {
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke("enumId",
- "(Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- }
- break;
- }
-
- case Token.ARRAYLIT:
- visitArrayLiteral(node, child);
- break;
-
- case Token.OBJECTLIT:
- visitObjectLiteral(node, child);
- break;
-
- case Token.NOT: {
- int trueTarget = cfw.acquireLabel();
- int falseTarget = cfw.acquireLabel();
- int beyond = cfw.acquireLabel();
- generateIfJump(child, node, trueTarget, falseTarget);
-
- cfw.markLabel(trueTarget);
- cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean",
- "FALSE", "Ljava/lang/Boolean;");
- cfw.add(ByteCode.GOTO, beyond);
- cfw.markLabel(falseTarget);
- cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean",
- "TRUE", "Ljava/lang/Boolean;");
- cfw.markLabel(beyond);
- cfw.adjustStackTop(-1);
- break;
- }
-
- case Token.BITNOT:
- generateExpression(child, node);
- addScriptRuntimeInvoke("toInt32", "(Ljava/lang/Object;)I");
- cfw.addPush(-1); // implement ~a as (a ^ -1)
- cfw.add(ByteCode.IXOR);
- cfw.add(ByteCode.I2D);
- addDoubleWrap();
- break;
-
- case Token.VOID:
- generateExpression(child, node);
- cfw.add(ByteCode.POP);
- Codegen.pushUndefined(cfw);
- break;
-
- case Token.TYPEOF:
- generateExpression(child, node);
- addScriptRuntimeInvoke("typeof",
- "(Ljava/lang/Object;"
- +")Ljava/lang/String;");
- break;
-
- case Token.TYPEOFNAME:
- visitTypeofname(node);
- break;
-
- case Token.INC:
- case Token.DEC:
- visitIncDec(node);
- break;
-
- case Token.OR:
- case Token.AND: {
- generateExpression(child, node);
- cfw.add(ByteCode.DUP);
- addScriptRuntimeInvoke("toBoolean",
- "(Ljava/lang/Object;)Z");
- int falseTarget = cfw.acquireLabel();
- if (type == Token.AND)
- cfw.add(ByteCode.IFEQ, falseTarget);
- else
- cfw.add(ByteCode.IFNE, falseTarget);
- cfw.add(ByteCode.POP);
- generateExpression(child.getNext(), node);
- cfw.markLabel(falseTarget);
- }
- break;
-
- case Token.HOOK : {
- Node ifThen = child.getNext();
- Node ifElse = ifThen.getNext();
- generateExpression(child, node);
- addScriptRuntimeInvoke("toBoolean",
- "(Ljava/lang/Object;)Z");
- int elseTarget = cfw.acquireLabel();
- cfw.add(ByteCode.IFEQ, elseTarget);
- short stack = cfw.getStackTop();
- generateExpression(ifThen, node);
- int afterHook = cfw.acquireLabel();
- cfw.add(ByteCode.GOTO, afterHook);
- cfw.markLabel(elseTarget, stack);
- generateExpression(ifElse, node);
- cfw.markLabel(afterHook);
- }
- break;
-
- case Token.ADD: {
- generateExpression(child, node);
- generateExpression(child.getNext(), node);
- switch (node.getIntProp(Node.ISNUMBER_PROP, -1)) {
- case Node.BOTH:
- cfw.add(ByteCode.DADD);
- break;
- case Node.LEFT:
- addOptRuntimeInvoke("add",
- "(DLjava/lang/Object;)Ljava/lang/Object;");
- break;
- case Node.RIGHT:
- addOptRuntimeInvoke("add",
- "(Ljava/lang/Object;D)Ljava/lang/Object;");
- break;
- default:
- if (child.getType() == Token.STRING) {
- addScriptRuntimeInvoke("add",
- "(Ljava/lang/String;"
- +"Ljava/lang/Object;"
- +")Ljava/lang/String;");
- } else if (child.getNext().getType() == Token.STRING) {
- addScriptRuntimeInvoke("add",
- "(Ljava/lang/Object;"
- +"Ljava/lang/String;"
- +")Ljava/lang/String;");
- } else {
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke("add",
- "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- }
- }
- }
- break;
-
- case Token.MUL:
- visitArithmetic(node, ByteCode.DMUL, child, parent);
- break;
-
- case Token.SUB:
- visitArithmetic(node, ByteCode.DSUB, child, parent);
- break;
-
- case Token.DIV:
- case Token.MOD:
- visitArithmetic(node, type == Token.DIV
- ? ByteCode.DDIV
- : ByteCode.DREM, child, parent);
- break;
-
- case Token.BITOR:
- case Token.BITXOR:
- case Token.BITAND:
- case Token.LSH:
- case Token.RSH:
- case Token.URSH:
- visitBitOp(node, type, child);
- break;
-
- case Token.POS:
- case Token.NEG:
- generateExpression(child, node);
- addObjectToDouble();
- if (type == Token.NEG) {
- cfw.add(ByteCode.DNEG);
- }
- addDoubleWrap();
- break;
-
- case Token.TO_DOUBLE:
- // cnvt to double (not Double)
- generateExpression(child, node);
- addObjectToDouble();
- break;
-
- case Token.TO_OBJECT: {
- // convert from double
- int prop = -1;
- if (child.getType() == Token.NUMBER) {
- prop = child.getIntProp(Node.ISNUMBER_PROP, -1);
- }
- if (prop != -1) {
- child.removeProp(Node.ISNUMBER_PROP);
- generateExpression(child, node);
- child.putIntProp(Node.ISNUMBER_PROP, prop);
- } else {
- generateExpression(child, node);
- addDoubleWrap();
- }
- break;
- }
-
- case Token.IN:
- case Token.INSTANCEOF:
- case Token.LE:
- case Token.LT:
- case Token.GE:
- case Token.GT: {
- int trueGOTO = cfw.acquireLabel();
- int falseGOTO = cfw.acquireLabel();
- visitIfJumpRelOp(node, child, trueGOTO, falseGOTO);
- addJumpedBooleanWrap(trueGOTO, falseGOTO);
- break;
- }
-
- case Token.EQ:
- case Token.NE:
- case Token.SHEQ:
- case Token.SHNE: {
- int trueGOTO = cfw.acquireLabel();
- int falseGOTO = cfw.acquireLabel();
- visitIfJumpEqOp(node, child, trueGOTO, falseGOTO);
- addJumpedBooleanWrap(trueGOTO, falseGOTO);
- break;
- }
-
- case Token.GETPROP:
- case Token.GETPROPNOWARN:
- visitGetProp(node, child);
- break;
-
- case Token.GETELEM:
- generateExpression(child, node); // object
- generateExpression(child.getNext(), node); // id
- cfw.addALoad(contextLocal);
- if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
- addScriptRuntimeInvoke(
- "getObjectIndex",
- "(Ljava/lang/Object;D"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- }
- else {
- addScriptRuntimeInvoke(
- "getObjectElem",
- "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- }
- break;
-
- case Token.GET_REF:
- generateExpression(child, node); // reference
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "refGet",
- "(Lorg/mozilla/javascript/Ref;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- break;
-
- case Token.GETVAR:
- visitGetVar(node);
- break;
-
- case Token.SETVAR:
- visitSetVar(node, child, true);
- break;
-
- case Token.SETNAME:
- visitSetName(node, child);
- break;
-
- case Token.SETCONST:
- visitSetConst(node, child);
- break;
-
- case Token.SETCONSTVAR:
- visitSetConstVar(node, child, true);
- break;
-
- case Token.SETPROP:
- case Token.SETPROP_OP:
- visitSetProp(type, node, child);
- break;
-
- case Token.SETELEM:
- case Token.SETELEM_OP:
- visitSetElem(type, node, child);
- break;
-
- case Token.SET_REF:
- case Token.SET_REF_OP:
- {
- generateExpression(child, node);
- child = child.getNext();
- if (type == Token.SET_REF_OP) {
- cfw.add(ByteCode.DUP);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "refGet",
- "(Lorg/mozilla/javascript/Ref;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- }
- generateExpression(child, node);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "refSet",
- "(Lorg/mozilla/javascript/Ref;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- }
- break;
-
- case Token.DEL_REF:
- generateExpression(child, node);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke("refDel",
- "(Lorg/mozilla/javascript/Ref;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- break;
-
- case Token.DELPROP:
- generateExpression(child, node);
- child = child.getNext();
- generateExpression(child, node);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke("delete",
- "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- break;
-
- case Token.BINDNAME:
- {
- while (child != null) {
- generateExpression(child, node);
- child = child.getNext();
- }
- // Generate code for "ScriptRuntime.bind(varObj, "s")"
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- cfw.addPush(node.getString());
- addScriptRuntimeInvoke(
- "bind",
- "(Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/String;"
- +")Lorg/mozilla/javascript/Scriptable;");
- }
- break;
-
- case Token.LOCAL_LOAD:
- cfw.addALoad(getLocalBlockRegister(node));
- break;
-
- case Token.REF_SPECIAL:
- {
- String special = (String)node.getProp(Node.NAME_PROP);
- generateExpression(child, node);
- cfw.addPush(special);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "specialRef",
- "(Ljava/lang/Object;"
- +"Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +")Lorg/mozilla/javascript/Ref;");
- }
- break;
-
- case Token.REF_MEMBER:
- case Token.REF_NS_MEMBER:
- case Token.REF_NAME:
- case Token.REF_NS_NAME:
- {
- int memberTypeFlags
- = node.getIntProp(Node.MEMBER_TYPE_PROP, 0);
- // generate possible target, possible namespace and member
- do {
- generateExpression(child, node);
- child = child.getNext();
- } while (child != null);
- cfw.addALoad(contextLocal);
- String methodName, signature;
- switch (type) {
- case Token.REF_MEMBER:
- methodName = "memberRef";
- signature = "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"I"
- +")Lorg/mozilla/javascript/Ref;";
- break;
- case Token.REF_NS_MEMBER:
- methodName = "memberRef";
- signature = "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"I"
- +")Lorg/mozilla/javascript/Ref;";
- break;
- case Token.REF_NAME:
- methodName = "nameRef";
- signature = "(Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"I"
- +")Lorg/mozilla/javascript/Ref;";
- cfw.addALoad(variableObjectLocal);
- break;
- case Token.REF_NS_NAME:
- methodName = "nameRef";
- signature = "(Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"I"
- +")Lorg/mozilla/javascript/Ref;";
- cfw.addALoad(variableObjectLocal);
- break;
- default:
- throw Kit.codeBug();
- }
- cfw.addPush(memberTypeFlags);
- addScriptRuntimeInvoke(methodName, signature);
- }
- break;
-
- case Token.DOTQUERY:
- visitDotQuery(node, child);
- break;
-
- case Token.ESCXMLATTR:
- generateExpression(child, node);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke("escapeAttributeValue",
- "(Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/String;");
- break;
-
- case Token.ESCXMLTEXT:
- generateExpression(child, node);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke("escapeTextValue",
- "(Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/String;");
- break;
-
- case Token.DEFAULTNAMESPACE:
- generateExpression(child, node);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke("setDefaultNamespace",
- "(Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- break;
-
- case Token.YIELD:
- generateYieldPoint(node, true);
- break;
-
- case Token.WITHEXPR: {
- Node enterWith = child;
- Node with = enterWith.getNext();
- Node leaveWith = with.getNext();
- generateStatement(enterWith);
- generateExpression(with.getFirstChild(), with);
- generateStatement(leaveWith);
- break;
- }
-
- case Token.ARRAYCOMP: {
- Node initStmt = child;
- Node expr = child.getNext();
- generateStatement(initStmt);
- generateExpression(expr, node);
- break;
- }
-
- default:
- throw new RuntimeException("Unexpected node type "+type);
- }
-
- }
-
- private void generateYieldPoint(Node node, boolean exprContext) {
- // save stack state
- int top = cfw.getStackTop();
- maxStack = maxStack > top ? maxStack : top;
- if (cfw.getStackTop() != 0) {
- generateGetGeneratorStackState();
- for (int i = 0; i < top; i++) {
- cfw.add(ByteCode.DUP_X1);
- cfw.add(ByteCode.SWAP);
- cfw.addLoadConstant(i);
- cfw.add(ByteCode.SWAP);
- cfw.add(ByteCode.AASTORE);
- }
- // pop the array object
- cfw.add(ByteCode.POP);
- }
-
- // generate the yield argument
- Node child = node.getFirstChild();
- if (child != null)
- generateExpression(child, node);
- else
- Codegen.pushUndefined(cfw);
-
- // change the resumption state
- int nextState = getNextGeneratorState(node);
- generateSetGeneratorResumptionPoint(nextState);
-
- boolean hasLocals = generateSaveLocals(node);
-
- cfw.add(ByteCode.ARETURN);
-
- generateCheckForThrowOrClose(getTargetLabel(node),
- hasLocals, nextState);
-
- // reconstruct the stack
- if (top != 0) {
- generateGetGeneratorStackState();
- for (int i = 0; i < top; i++) {
- cfw.add(ByteCode.DUP);
- cfw.addLoadConstant(top - i - 1);
- cfw.add(ByteCode.AALOAD);
- cfw.add(ByteCode.SWAP);
- }
- cfw.add(ByteCode.POP);
- }
-
- // load return value from yield
- if (exprContext) {
- cfw.addALoad(argsLocal);
- }
- }
-
- private void generateCheckForThrowOrClose(int label,
- boolean hasLocals,
- int nextState) {
- int throwLabel = cfw.acquireLabel();
- int closeLabel = cfw.acquireLabel();
-
- // throw the user provided object, if the operation is .throw()
- cfw.markLabel(throwLabel);
- cfw.addALoad(argsLocal);
- generateThrowJavaScriptException();
-
- // throw our special internal exception if the generator is being closed
- cfw.markLabel(closeLabel);
- cfw.addALoad(argsLocal);
- cfw.add(ByteCode.CHECKCAST, "java/lang/Throwable");
- cfw.add(ByteCode.ATHROW);
-
- // mark the re-entry point
- // jump here after initializing the locals
- if (label != -1)
- cfw.markLabel(label);
- if (!hasLocals) {
- // jump here directly if there are no locals
- cfw.markTableSwitchCase(generatorSwitch, nextState);
- }
-
- // see if we need to dispatch for .close() or .throw()
- cfw.addILoad(operationLocal);
- cfw.addLoadConstant(NativeGenerator.GENERATOR_CLOSE);
- cfw.add(ByteCode.IF_ICMPEQ, closeLabel);
- cfw.addILoad(operationLocal);
- cfw.addLoadConstant(NativeGenerator.GENERATOR_THROW);
- cfw.add(ByteCode.IF_ICMPEQ, throwLabel);
- }
-
- private void generateIfJump(Node node, Node parent,
- int trueLabel, int falseLabel)
- {
- // System.out.println("gen code for " + node.toString());
-
- int type = node.getType();
- Node child = node.getFirstChild();
-
- switch (type) {
- case Token.NOT:
- generateIfJump(child, node, falseLabel, trueLabel);
- break;
-
- case Token.OR:
- case Token.AND: {
- int interLabel = cfw.acquireLabel();
- if (type == Token.AND) {
- generateIfJump(child, node, interLabel, falseLabel);
- }
- else {
- generateIfJump(child, node, trueLabel, interLabel);
- }
- cfw.markLabel(interLabel);
- child = child.getNext();
- generateIfJump(child, node, trueLabel, falseLabel);
- break;
- }
-
- case Token.IN:
- case Token.INSTANCEOF:
- case Token.LE:
- case Token.LT:
- case Token.GE:
- case Token.GT:
- visitIfJumpRelOp(node, child, trueLabel, falseLabel);
- break;
-
- case Token.EQ:
- case Token.NE:
- case Token.SHEQ:
- case Token.SHNE:
- visitIfJumpEqOp(node, child, trueLabel, falseLabel);
- break;
-
- default:
- // Generate generic code for non-optimized jump
- generateExpression(node, parent);
- addScriptRuntimeInvoke("toBoolean", "(Ljava/lang/Object;)Z");
- cfw.add(ByteCode.IFNE, trueLabel);
- cfw.add(ByteCode.GOTO, falseLabel);
- }
- }
-
- private void visitFunction(OptFunctionNode ofn, int functionType)
- {
- int fnIndex = codegen.getIndex(ofn.fnode);
- cfw.add(ByteCode.NEW, codegen.mainClassName);
- // Call function constructor
- cfw.add(ByteCode.DUP);
- cfw.addALoad(variableObjectLocal);
- cfw.addALoad(contextLocal); // load 'cx'
- cfw.addPush(fnIndex);
- cfw.addInvoke(ByteCode.INVOKESPECIAL, codegen.mainClassName,
- "<init>", Codegen.FUNCTION_CONSTRUCTOR_SIGNATURE);
-
- // Init mainScript field;
- cfw.add(ByteCode.DUP);
- if (isTopLevel) {
- cfw.add(ByteCode.ALOAD_0);
- } else {
- cfw.add(ByteCode.ALOAD_0);
- cfw.add(ByteCode.GETFIELD,
- codegen.mainClassName,
- Codegen.DIRECT_CALL_PARENT_FIELD,
- codegen.mainClassSignature);
- }
- cfw.add(ByteCode.PUTFIELD,
- codegen.mainClassName,
- Codegen.DIRECT_CALL_PARENT_FIELD,
- codegen.mainClassSignature);
-
- int directTargetIndex = ofn.getDirectTargetIndex();
- if (directTargetIndex >= 0) {
- cfw.add(ByteCode.DUP);
- if (isTopLevel) {
- cfw.add(ByteCode.ALOAD_0);
- } else {
- cfw.add(ByteCode.ALOAD_0);
- cfw.add(ByteCode.GETFIELD,
- codegen.mainClassName,
- Codegen.DIRECT_CALL_PARENT_FIELD,
- codegen.mainClassSignature);
- }
- cfw.add(ByteCode.SWAP);
- cfw.add(ByteCode.PUTFIELD,
- codegen.mainClassName,
- Codegen.getDirectTargetFieldName(directTargetIndex),
- codegen.mainClassSignature);
- }
-
- if (functionType == FunctionNode.FUNCTION_EXPRESSION) {
- // Leave closure object on stack and do not pass it to
- // initFunction which suppose to connect statements to scope
- return;
- }
- cfw.addPush(functionType);
- cfw.addALoad(variableObjectLocal);
- cfw.addALoad(contextLocal); // load 'cx'
- addOptRuntimeInvoke("initFunction",
- "(Lorg/mozilla/javascript/NativeFunction;"
- +"I"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Context;"
- +")V");
- }
-
- private int getTargetLabel(Node target)
- {
- int labelId = target.labelId();
- if (labelId == -1) {
- labelId = cfw.acquireLabel();
- target.labelId(labelId);
- }
- return labelId;
- }
-
- private void visitGoto(Node.Jump node, int type, Node child)
- {
- Node target = node.target;
- if (type == Token.IFEQ || type == Token.IFNE) {
- if (child == null) throw Codegen.badTree();
- int targetLabel = getTargetLabel(target);
- int fallThruLabel = cfw.acquireLabel();
- if (type == Token.IFEQ)
- generateIfJump(child, node, targetLabel, fallThruLabel);
- else
- generateIfJump(child, node, fallThruLabel, targetLabel);
- cfw.markLabel(fallThruLabel);
- } else {
- if (type == Token.JSR) {
- if (isGenerator) {
- addGotoWithReturn(target);
- } else {
- addGoto(target, ByteCode.JSR);
- }
- } else {
- addGoto(target, ByteCode.GOTO);
- }
- }
- }
-
- private void addGotoWithReturn(Node target) {
- FinallyReturnPoint ret =
- (FinallyReturnPoint)finallys.get(target);
- cfw.addLoadConstant(ret.jsrPoints.size());
- addGoto(target, ByteCode.GOTO);
- int retLabel = cfw.acquireLabel();
- cfw.markLabel(retLabel);
- ret.jsrPoints.add(Integer.valueOf(retLabel));
- }
-
- private void visitArrayLiteral(Node node, Node child)
- {
- int count = 0;
- for (Node cursor = child; cursor != null; cursor = cursor.getNext()) {
- ++count;
- }
- // load array to store array literal objects
- addNewObjectArray(count);
- for (int i = 0; i != count; ++i) {
- cfw.add(ByteCode.DUP);
- cfw.addPush(i);
- generateExpression(child, node);
- cfw.add(ByteCode.AASTORE);
- child = child.getNext();
- }
- int[] skipIndexes = (int[])node.getProp(Node.SKIP_INDEXES_PROP);
- if (skipIndexes == null) {
- cfw.add(ByteCode.ACONST_NULL);
- cfw.add(ByteCode.ICONST_0);
- } else {
- cfw.addPush(OptRuntime.encodeIntArray(skipIndexes));
- cfw.addPush(skipIndexes.length);
- }
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- addOptRuntimeInvoke("newArrayLiteral",
- "([Ljava/lang/Object;"
- +"Ljava/lang/String;"
- +"I"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Lorg/mozilla/javascript/Scriptable;");
- }
-
- private void visitObjectLiteral(Node node, Node child)
- {
- Object[] properties = (Object[])node.getProp(Node.OBJECT_IDS_PROP);
- int count = properties.length;
-
- // load array with property ids
- addNewObjectArray(count);
- for (int i = 0; i != count; ++i) {
- cfw.add(ByteCode.DUP);
- cfw.addPush(i);
- Object id = properties[i];
- if (id instanceof String) {
- cfw.addPush((String)id);
- } else {
- cfw.addPush(((Integer)id).intValue());
- addScriptRuntimeInvoke("wrapInt", "(I)Ljava/lang/Integer;");
- }
- cfw.add(ByteCode.AASTORE);
- }
- // load array with property values
- addNewObjectArray(count);
- Node child2 = child;
- for (int i = 0; i != count; ++i) {
- cfw.add(ByteCode.DUP);
- cfw.addPush(i);
- int childType = child.getType();
- if (childType == Token.GET) {
- generateExpression(child.getFirstChild(), node);
- } else if (childType == Token.SET) {
- generateExpression(child.getFirstChild(), node);
- } else {
- generateExpression(child, node);
- }
- cfw.add(ByteCode.AASTORE);
- child = child.getNext();
- }
- // load array with getterSetter values
- cfw.addPush(count);
- cfw.add(ByteCode.NEWARRAY, ByteCode.T_INT);
- for (int i = 0; i != count; ++i) {
- cfw.add(ByteCode.DUP);
- cfw.addPush(i);
- int childType = child2.getType();
- if (childType == Token.GET) {
- cfw.add(ByteCode.ICONST_M1);
- } else if (childType == Token.SET) {
- cfw.add(ByteCode.ICONST_1);
- } else {
- cfw.add(ByteCode.ICONST_0);
- }
- cfw.add(ByteCode.IASTORE);
- child2 = child2.getNext();
- }
-
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- addScriptRuntimeInvoke("newObjectLiteral",
- "([Ljava/lang/Object;"
- +"[Ljava/lang/Object;"
- +"[I"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Lorg/mozilla/javascript/Scriptable;");
- }
-
- private void visitSpecialCall(Node node, int type, int specialType,
- Node child)
- {
- cfw.addALoad(contextLocal);
-
- if (type == Token.NEW) {
- generateExpression(child, node);
- // stack: ... cx functionObj
- } else {
- generateFunctionAndThisObj(child, node);
- // stack: ... cx functionObj thisObj
- }
- child = child.getNext();
-
- generateCallArgArray(node, child, false);
-
- String methodName;
- String callSignature;
-
- if (type == Token.NEW) {
- methodName = "newObjectSpecial";
- callSignature = "(Lorg/mozilla/javascript/Context;"
- +"Ljava/lang/Object;"
- +"[Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"I" // call type
- +")Ljava/lang/Object;";
- cfw.addALoad(variableObjectLocal);
- cfw.addALoad(thisObjLocal);
- cfw.addPush(specialType);
- } else {
- methodName = "callSpecial";
- callSignature = "(Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Callable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"[Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"I" // call type
- +"Ljava/lang/String;I" // filename, linenumber
- +")Ljava/lang/Object;";
- cfw.addALoad(variableObjectLocal);
- cfw.addALoad(thisObjLocal);
- cfw.addPush(specialType);
- String sourceName = scriptOrFn.getSourceName();
- cfw.addPush(sourceName == null ? "" : sourceName);
- cfw.addPush(itsLineNumber);
- }
-
- addOptRuntimeInvoke(methodName, callSignature);
- }
-
- private void visitStandardCall(Node node, Node child)
- {
- if (node.getType() != Token.CALL) throw Codegen.badTree();
-
- Node firstArgChild = child.getNext();
- int childType = child.getType();
-
- String methodName;
- String signature;
-
- if (firstArgChild == null) {
- if (childType == Token.NAME) {
- // name() call
- String name = child.getString();
- cfw.addPush(name);
- methodName = "callName0";
- signature = "(Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Ljava/lang/Object;";
- } else if (childType == Token.GETPROP) {
- // x.name() call
- Node propTarget = child.getFirstChild();
- generateExpression(propTarget, node);
- Node id = propTarget.getNext();
- String property = id.getString();
- cfw.addPush(property);
- methodName = "callProp0";
- signature = "(Ljava/lang/Object;"
- +"Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Ljava/lang/Object;";
- } else if (childType == Token.GETPROPNOWARN) {
- throw Kit.codeBug();
- } else {
- generateFunctionAndThisObj(child, node);
- methodName = "call0";
- signature = "(Lorg/mozilla/javascript/Callable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Ljava/lang/Object;";
- }
-
- } else if (childType == Token.NAME) {
- // XXX: this optimization is only possible if name
- // resolution
- // is not affected by arguments evaluation and currently
- // there are no checks for it
- String name = child.getString();
- generateCallArgArray(node, firstArgChild, false);
- cfw.addPush(name);
- methodName = "callName";
- signature = "([Ljava/lang/Object;"
- +"Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Ljava/lang/Object;";
- } else {
- int argCount = 0;
- for (Node arg = firstArgChild; arg != null; arg = arg.getNext()) {
- ++argCount;
- }
- generateFunctionAndThisObj(child, node);
- // stack: ... functionObj thisObj
- if (argCount == 1) {
- generateExpression(firstArgChild, node);
- methodName = "call1";
- signature = "(Lorg/mozilla/javascript/Callable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Ljava/lang/Object;";
- } else if (argCount == 2) {
- generateExpression(firstArgChild, node);
- generateExpression(firstArgChild.getNext(), node);
- methodName = "call2";
- signature = "(Lorg/mozilla/javascript/Callable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Ljava/lang/Object;";
- } else {
- generateCallArgArray(node, firstArgChild, false);
- methodName = "callN";
- signature = "(Lorg/mozilla/javascript/Callable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"[Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Ljava/lang/Object;";
- }
- }
-
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- addOptRuntimeInvoke(methodName, signature);
- }
-
- private void visitStandardNew(Node node, Node child)
- {
- if (node.getType() != Token.NEW) throw Codegen.badTree();
-
- Node firstArgChild = child.getNext();
-
- generateExpression(child, node);
- // stack: ... functionObj
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- // stack: ... functionObj cx scope
- generateCallArgArray(node, firstArgChild, false);
- addScriptRuntimeInvoke(
- "newObject",
- "(Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"[Ljava/lang/Object;"
- +")Lorg/mozilla/javascript/Scriptable;");
- }
-
- private void visitOptimizedCall(Node node, OptFunctionNode target,
- int type, Node child)
- {
- Node firstArgChild = child.getNext();
-
- short thisObjLocal = 0;
- if (type == Token.NEW) {
- generateExpression(child, node);
- } else {
- generateFunctionAndThisObj(child, node);
- thisObjLocal = getNewWordLocal();
- cfw.addAStore(thisObjLocal);
- }
- // stack: ... functionObj
-
- int beyond = cfw.acquireLabel();
-
- int directTargetIndex = target.getDirectTargetIndex();
- if (isTopLevel) {
- cfw.add(ByteCode.ALOAD_0);
- } else {
- cfw.add(ByteCode.ALOAD_0);
- cfw.add(ByteCode.GETFIELD, codegen.mainClassName,
- Codegen.DIRECT_CALL_PARENT_FIELD,
- codegen.mainClassSignature);
- }
- cfw.add(ByteCode.GETFIELD, codegen.mainClassName,
- Codegen.getDirectTargetFieldName(directTargetIndex),
- codegen.mainClassSignature);
-
- cfw.add(ByteCode.DUP2);
- // stack: ... functionObj directFunct functionObj directFunct
-
- int regularCall = cfw.acquireLabel();
- cfw.add(ByteCode.IF_ACMPNE, regularCall);
-
- // stack: ... functionObj directFunct
- short stackHeight = cfw.getStackTop();
- cfw.add(ByteCode.SWAP);
- cfw.add(ByteCode.POP);
- // stack: ... directFunct
- if (compilerEnv.isUseDynamicScope()) {
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- } else {
- cfw.add(ByteCode.DUP);
- // stack: ... directFunct directFunct
- cfw.addInvoke(ByteCode.INVOKEINTERFACE,
- "org/mozilla/javascript/Scriptable",
- "getParentScope",
- "()Lorg/mozilla/javascript/Scriptable;");
- // stack: ... directFunct scope
- cfw.addALoad(contextLocal);
- // stack: ... directFunct scope cx
- cfw.add(ByteCode.SWAP);
- }
- // stack: ... directFunc cx scope
-
- if (type == Token.NEW) {
- cfw.add(ByteCode.ACONST_NULL);
- } else {
- cfw.addALoad(thisObjLocal);
- }
- // stack: ... directFunc cx scope thisObj
-/*
-Remember that directCall parameters are paired in 1 aReg and 1 dReg
-If the argument is an incoming arg, just pass the orginal pair thru.
-Else, if the argument is known to be typed 'Number', pass Void.TYPE
-in the aReg and the number is the dReg
-Else pass the JS object in the aReg and 0.0 in the dReg.
-*/
- Node argChild = firstArgChild;
- while (argChild != null) {
- int dcp_register = nodeIsDirectCallParameter(argChild);
- if (dcp_register >= 0) {
- cfw.addALoad(dcp_register);
- cfw.addDLoad(dcp_register + 1);
- } else if (argChild.getIntProp(Node.ISNUMBER_PROP, -1)
- == Node.BOTH)
- {
- cfw.add(ByteCode.GETSTATIC,
- "java/lang/Void",
- "TYPE",
- "Ljava/lang/Class;");
- generateExpression(argChild, node);
- } else {
- generateExpression(argChild, node);
- cfw.addPush(0.0);
- }
- argChild = argChild.getNext();
- }
-
- cfw.add(ByteCode.GETSTATIC,
- "org/mozilla/javascript/ScriptRuntime",
- "emptyArgs", "[Ljava/lang/Object;");
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- codegen.mainClassName,
- (type == Token.NEW)
- ? codegen.getDirectCtorName(target.fnode)
- : codegen.getBodyMethodName(target.fnode),
- codegen.getBodyMethodSignature(target.fnode));
-
- cfw.add(ByteCode.GOTO, beyond);
-
- cfw.markLabel(regularCall, stackHeight);
- // stack: ... functionObj directFunct
- cfw.add(ByteCode.POP);
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- // stack: ... functionObj cx scope
- if (type != Token.NEW) {
- cfw.addALoad(thisObjLocal);
- releaseWordLocal(thisObjLocal);
- // stack: ... functionObj cx scope thisObj
- }
- // XXX: this will generate code for the child array the second time,
- // so expression code generation better not to alter tree structure...
- generateCallArgArray(node, firstArgChild, true);
-
- if (type == Token.NEW) {
- addScriptRuntimeInvoke(
- "newObject",
- "(Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"[Ljava/lang/Object;"
- +")Lorg/mozilla/javascript/Scriptable;");
- } else {
- cfw.addInvoke(ByteCode.INVOKEINTERFACE,
- "org/mozilla/javascript/Callable",
- "call",
- "(Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"[Ljava/lang/Object;"
- +")Ljava/lang/Object;");
- }
-
- cfw.markLabel(beyond);
- }
-
- private void generateCallArgArray(Node node, Node argChild, boolean directCall)
- {
- int argCount = 0;
- for (Node child = argChild; child != null; child = child.getNext()) {
- ++argCount;
- }
- // load array object to set arguments
- if (argCount == 1 && itsOneArgArray >= 0) {
- cfw.addALoad(itsOneArgArray);
- } else {
- addNewObjectArray(argCount);
- }
- // Copy arguments into it
- for (int i = 0; i != argCount; ++i) {
- // If we are compiling a generator an argument could be the result
- // of a yield. In that case we will have an immediate on the stack
- // which we need to avoid
- if (!isGenerator) {
- cfw.add(ByteCode.DUP);
- cfw.addPush(i);
- }
-
- if (!directCall) {
- generateExpression(argChild, node);
- } else {
- // If this has also been a directCall sequence, the Number
- // flag will have remained set for any parameter so that
- // the values could be copied directly into the outgoing
- // args. Here we want to force it to be treated as not in
- // a Number context, so we set the flag off.
- int dcp_register = nodeIsDirectCallParameter(argChild);
- if (dcp_register >= 0) {
- dcpLoadAsObject(dcp_register);
- } else {
- generateExpression(argChild, node);
- int childNumberFlag
- = argChild.getIntProp(Node.ISNUMBER_PROP, -1);
- if (childNumberFlag == Node.BOTH) {
- addDoubleWrap();
- }
- }
- }
-
- // When compiling generators, any argument to a method may be a
- // yield expression. Hence we compile the argument first and then
- // load the argument index and assign the value to the args array.
- if (isGenerator) {
- short tempLocal = getNewWordLocal();
- cfw.addAStore(tempLocal);
- cfw.add(ByteCode.CHECKCAST, "[Ljava/lang/Object;");
- cfw.add(ByteCode.DUP);
- cfw.addPush(i);
- cfw.addALoad(tempLocal);
- releaseWordLocal(tempLocal);
- }
-
- cfw.add(ByteCode.AASTORE);
-
- argChild = argChild.getNext();
- }
- }
-
- private void generateFunctionAndThisObj(Node node, Node parent)
- {
- // Place on stack (function object, function this) pair
- int type = node.getType();
- switch (node.getType()) {
- case Token.GETPROPNOWARN:
- throw Kit.codeBug();
-
- case Token.GETPROP:
- case Token.GETELEM: {
- Node target = node.getFirstChild();
- generateExpression(target, node);
- Node id = target.getNext();
- if (type == Token.GETPROP) {
- String property = id.getString();
- cfw.addPush(property);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "getPropFunctionAndThis",
- "(Ljava/lang/Object;"
- +"Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +")Lorg/mozilla/javascript/Callable;");
- } else {
- // Optimizer do not optimize this case for now
- if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1)
- throw Codegen.badTree();
- generateExpression(id, node); // id
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "getElemFunctionAndThis",
- "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Lorg/mozilla/javascript/Callable;");
- }
- break;
- }
-
- case Token.NAME: {
- String name = node.getString();
- cfw.addPush(name);
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- addScriptRuntimeInvoke(
- "getNameFunctionAndThis",
- "(Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Lorg/mozilla/javascript/Callable;");
- break;
- }
-
- default: // including GETVAR
- generateExpression(node, parent);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "getValueFunctionAndThis",
- "(Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Lorg/mozilla/javascript/Callable;");
- break;
- }
- // Get thisObj prepared by get(Name|Prop|Elem|Value)FunctionAndThis
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "lastStoredScriptable",
- "(Lorg/mozilla/javascript/Context;"
- +")Lorg/mozilla/javascript/Scriptable;");
- }
-
- private void updateLineNumber(Node node)
- {
- itsLineNumber = node.getLineno();
- if (itsLineNumber == -1)
- return;
- cfw.addLineNumberEntry((short)itsLineNumber);
- }
-
- private void visitTryCatchFinally(Node.Jump node, Node child)
- {
- /* Save the variable object, in case there are with statements
- * enclosed by the try block and we catch some exception.
- * We'll restore it for the catch block so that catch block
- * statements get the right scope.
- */
-
- // OPT we only need to do this if there are enclosed WITH
- // statements; could statically check and omit this if there aren't any.
-
- // XXX OPT Maybe instead do syntactic transforms to associate
- // each 'with' with a try/finally block that does the exitwith.
-
- short savedVariableObject = getNewWordLocal();
- cfw.addALoad(variableObjectLocal);
- cfw.addAStore(savedVariableObject);
-
- /*
- * Generate the code for the tree; most of the work is done in IRFactory
- * and NodeTransformer; Codegen just adds the java handlers for the
- * javascript catch and finally clauses. */
-
- int startLabel = cfw.acquireLabel();
- cfw.markLabel(startLabel, (short)0);
-
- Node catchTarget = node.target;
- Node finallyTarget = node.getFinally();
-
- // create a table for the equivalent of JSR returns
- if (isGenerator && finallyTarget != null) {
- FinallyReturnPoint ret = new FinallyReturnPoint();
- if (finallys == null) {
- finallys = new Hashtable();
- }
- // add the finally target to hashtable
- finallys.put(finallyTarget, ret);
- // add the finally node as well to the hash table
- finallys.put(finallyTarget.getNext(), ret);
- }
-
- while (child != null) {
- generateStatement(child);
- child = child.getNext();
- }
-
- // control flow skips the handlers
- int realEnd = cfw.acquireLabel();
- cfw.add(ByteCode.GOTO, realEnd);
-
- int exceptionLocal = getLocalBlockRegister(node);
- // javascript handler; unwrap exception and GOTO to javascript
- // catch area.
- if (catchTarget != null) {
- // get the label to goto
- int catchLabel = catchTarget.labelId();
-
- generateCatchBlock(JAVASCRIPT_EXCEPTION, savedVariableObject,
- catchLabel, startLabel, exceptionLocal);
- /*
- * catch WrappedExceptions, see if they are wrapped
- * JavaScriptExceptions. Otherwise, rethrow.
- */
- generateCatchBlock(EVALUATOR_EXCEPTION, savedVariableObject,
- catchLabel, startLabel, exceptionLocal);
-
- /*
- we also need to catch EcmaErrors and feed the
- associated error object to the handler
- */
- generateCatchBlock(ECMAERROR_EXCEPTION, savedVariableObject,
- catchLabel, startLabel, exceptionLocal);
-
- Context cx = Context.getCurrentContext();
- if (cx != null &&
- cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS))
- {
- generateCatchBlock(THROWABLE_EXCEPTION, savedVariableObject,
- catchLabel, startLabel, exceptionLocal);
- }
- }
-
- // finally handler; catch all exceptions, store to a local; JSR to
- // the finally, then re-throw.
- if (finallyTarget != null) {
- int finallyHandler = cfw.acquireLabel();
- cfw.markHandler(finallyHandler);
- cfw.addAStore(exceptionLocal);
-
- // reset the variable object local
- cfw.addALoad(savedVariableObject);
- cfw.addAStore(variableObjectLocal);
-
- // get the label to JSR to
- int finallyLabel = finallyTarget.labelId();
- if (isGenerator)
- addGotoWithReturn(finallyTarget);
- else
- cfw.add(ByteCode.JSR, finallyLabel);
-
- // rethrow
- cfw.addALoad(exceptionLocal);
- if (isGenerator)
- cfw.add(ByteCode.CHECKCAST, "java/lang/Throwable");
- cfw.add(ByteCode.ATHROW);
-
- // mark the handler
- cfw.addExceptionHandler(startLabel, finallyLabel,
- finallyHandler, null); // catch any
- }
- releaseWordLocal(savedVariableObject);
- cfw.markLabel(realEnd);
- }
-
- private static final int JAVASCRIPT_EXCEPTION = 0;
- private static final int EVALUATOR_EXCEPTION = 1;
- private static final int ECMAERROR_EXCEPTION = 2;
- private static final int THROWABLE_EXCEPTION = 3;
-
- private void generateCatchBlock(int exceptionType,
- short savedVariableObject,
- int catchLabel, int startLabel,
- int exceptionLocal)
- {
- int handler = cfw.acquireLabel();
- cfw.markHandler(handler);
-
- // MS JVM gets cranky if the exception object is left on the stack
- cfw.addAStore(exceptionLocal);
-
- // reset the variable object local
- cfw.addALoad(savedVariableObject);
- cfw.addAStore(variableObjectLocal);
-
- String exceptionName;
- if (exceptionType == JAVASCRIPT_EXCEPTION) {
- exceptionName = "org/mozilla/javascript/JavaScriptException";
- } else if (exceptionType == EVALUATOR_EXCEPTION) {
- exceptionName = "org/mozilla/javascript/EvaluatorException";
- } else if (exceptionType == ECMAERROR_EXCEPTION) {
- exceptionName = "org/mozilla/javascript/EcmaError";
- } else if (exceptionType == THROWABLE_EXCEPTION) {
- exceptionName = "java/lang/Throwable";
- } else {
- throw Kit.codeBug();
- }
-
- // mark the handler
- cfw.addExceptionHandler(startLabel, catchLabel, handler,
- exceptionName);
-
- cfw.add(ByteCode.GOTO, catchLabel);
- }
-
-
- private boolean generateSaveLocals(Node node)
- {
- int count = 0;
- for (int i = 0; i < firstFreeLocal; i++) {
- if (locals[i] != 0)
- count++;
- }
-
- if (count == 0) {
- ((FunctionNode)scriptOrFn).addLiveLocals(node, null);
- return false;
- }
-
- // calculate the max locals
- maxLocals = maxLocals > count ? maxLocals : count;
-
- // create a locals list
- int[] ls = new int[count];
- int s = 0;
- for (int i = 0; i < firstFreeLocal; i++) {
- if (locals[i] != 0) {
- ls[s] = i;
- s++;
- }
- }
-
- // save the locals
- ((FunctionNode)scriptOrFn).addLiveLocals(node, ls);
-
- // save locals
- generateGetGeneratorLocalsState();
- for (int i = 0; i < count; i++) {
- cfw.add(ByteCode.DUP);
- cfw.addLoadConstant(i);
- cfw.addALoad(ls[i]);
- cfw.add(ByteCode.AASTORE);
- }
- // pop the array off the stack
- cfw.add(ByteCode.POP);
-
- return true;
- }
-
- private void visitSwitch(Node.Jump switchNode, Node child)
- {
- // See comments in IRFactory.createSwitch() for description
- // of SWITCH node
-
- generateExpression(child, switchNode);
- // save selector value
- short selector = getNewWordLocal();
- cfw.addAStore(selector);
-
- for (Node.Jump caseNode = (Node.Jump)child.getNext();
- caseNode != null;
- caseNode = (Node.Jump)caseNode.getNext())
- {
- if (caseNode.getType() != Token.CASE)
- throw Codegen.badTree();
- Node test = caseNode.getFirstChild();
- generateExpression(test, caseNode);
- cfw.addALoad(selector);
- addScriptRuntimeInvoke("shallowEq",
- "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +")Z");
- addGoto(caseNode.target, ByteCode.IFNE);
- }
- releaseWordLocal(selector);
- }
-
- private void visitTypeofname(Node node)
- {
- if (hasVarsInRegs) {
- int varIndex = fnCurrent.fnode.getIndexForNameNode(node);
- if (varIndex >= 0) {
- if (fnCurrent.isNumberVar(varIndex)) {
- cfw.addPush("number");
- } else if (varIsDirectCallParameter(varIndex)) {
- int dcp_register = varRegisters[varIndex];
- cfw.addALoad(dcp_register);
- cfw.add(ByteCode.GETSTATIC, "java/lang/Void", "TYPE",
- "Ljava/lang/Class;");
- int isNumberLabel = cfw.acquireLabel();
- cfw.add(ByteCode.IF_ACMPEQ, isNumberLabel);
- short stack = cfw.getStackTop();
- cfw.addALoad(dcp_register);
- addScriptRuntimeInvoke("typeof",
- "(Ljava/lang/Object;"
- +")Ljava/lang/String;");
- int beyond = cfw.acquireLabel();
- cfw.add(ByteCode.GOTO, beyond);
- cfw.markLabel(isNumberLabel, stack);
- cfw.addPush("number");
- cfw.markLabel(beyond);
- } else {
- cfw.addALoad(varRegisters[varIndex]);
- addScriptRuntimeInvoke("typeof",
- "(Ljava/lang/Object;"
- +")Ljava/lang/String;");
- }
- return;
- }
- }
- cfw.addALoad(variableObjectLocal);
- cfw.addPush(node.getString());
- addScriptRuntimeInvoke("typeofName",
- "(Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/String;"
- +")Ljava/lang/String;");
- }
-
- /**
- * Save the current code offset. This saved code offset is used to
- * compute instruction counts in subsequent calls to
- * {@link #addInstructionCount}.
- */
- private void saveCurrentCodeOffset() {
- savedCodeOffset = cfw.getCurrentCodeOffset();
- }
-
- /**
- * Generate calls to ScriptRuntime.addInstructionCount to keep track of
- * executed instructions and call <code>observeInstructionCount()</code>
- * if a threshold is exceeded.
- */
- private void addInstructionCount() {
- int count = cfw.getCurrentCodeOffset() - savedCodeOffset;
- if (count == 0)
- return;
- cfw.addALoad(contextLocal);
- cfw.addPush(count);
- addScriptRuntimeInvoke("addInstructionCount",
- "(Lorg/mozilla/javascript/Context;"
- +"I)V");
- }
-
- private void visitIncDec(Node node)
- {
- int incrDecrMask = node.getExistingIntProp(Node.INCRDECR_PROP);
- Node child = node.getFirstChild();
- switch (child.getType()) {
- case Token.GETVAR:
- if (!hasVarsInRegs) Kit.codeBug();
- if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
- boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
- int varIndex = fnCurrent.getVarIndex(child);
- short reg = varRegisters[varIndex];
- int offset = varIsDirectCallParameter(varIndex) ? 1 : 0;
- cfw.addDLoad(reg + offset);
- if (post) {
- cfw.add(ByteCode.DUP2);
- }
- cfw.addPush(1.0);
- if ((incrDecrMask & Node.DECR_FLAG) == 0) {
- cfw.add(ByteCode.DADD);
- } else {
- cfw.add(ByteCode.DSUB);
- }
- if (!post) {
- cfw.add(ByteCode.DUP2);
- }
- cfw.addDStore(reg + offset);
- } else {
- boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
- int varIndex = fnCurrent.getVarIndex(child);
- short reg = varRegisters[varIndex];
- cfw.addALoad(reg);
- if (post) {
- cfw.add(ByteCode.DUP);
- }
- addObjectToDouble();
- cfw.addPush(1.0);
- if ((incrDecrMask & Node.DECR_FLAG) == 0) {
- cfw.add(ByteCode.DADD);
- } else {
- cfw.add(ByteCode.DSUB);
- }
- addDoubleWrap();
- if (!post) {
- cfw.add(ByteCode.DUP);
- }
- cfw.addAStore(reg);
- break;
- }
- break;
- case Token.NAME:
- cfw.addALoad(variableObjectLocal);
- cfw.addPush(child.getString()); // push name
- cfw.addALoad(contextLocal);
- cfw.addPush(incrDecrMask);
- addScriptRuntimeInvoke("nameIncrDecr",
- "(Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +"I)Ljava/lang/Object;");
- break;
- case Token.GETPROPNOWARN:
- throw Kit.codeBug();
- case Token.GETPROP: {
- Node getPropChild = child.getFirstChild();
- generateExpression(getPropChild, node);
- generateExpression(getPropChild.getNext(), node);
- cfw.addALoad(contextLocal);
- cfw.addPush(incrDecrMask);
- addScriptRuntimeInvoke("propIncrDecr",
- "(Ljava/lang/Object;"
- +"Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +"I)Ljava/lang/Object;");
- break;
- }
- case Token.GETELEM: {
- Node elemChild = child.getFirstChild();
- generateExpression(elemChild, node);
- generateExpression(elemChild.getNext(), node);
- cfw.addALoad(contextLocal);
- cfw.addPush(incrDecrMask);
- if (elemChild.getNext().getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
- addOptRuntimeInvoke("elemIncrDecr",
- "(Ljava/lang/Object;"
- +"D"
- +"Lorg/mozilla/javascript/Context;"
- +"I"
- +")Ljava/lang/Object;");
- } else {
- addScriptRuntimeInvoke("elemIncrDecr",
- "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"I"
- +")Ljava/lang/Object;");
- }
- break;
- }
- case Token.GET_REF: {
- Node refChild = child.getFirstChild();
- generateExpression(refChild, node);
- cfw.addALoad(contextLocal);
- cfw.addPush(incrDecrMask);
- addScriptRuntimeInvoke(
- "refIncrDecr",
- "(Lorg/mozilla/javascript/Ref;"
- +"Lorg/mozilla/javascript/Context;"
- +"I)Ljava/lang/Object;");
- break;
- }
- default:
- Codegen.badTree();
- }
- }
-
- private static boolean isArithmeticNode(Node node)
- {
- int type = node.getType();
- return (type == Token.SUB)
- || (type == Token.MOD)
- || (type == Token.DIV)
- || (type == Token.MUL);
- }
-
- private void visitArithmetic(Node node, int opCode, Node child,
- Node parent)
- {
- int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1);
- if (childNumberFlag != -1) {
- generateExpression(child, node);
- generateExpression(child.getNext(), node);
- cfw.add(opCode);
- }
- else {
- boolean childOfArithmetic = isArithmeticNode(parent);
- generateExpression(child, node);
- if (!isArithmeticNode(child))
- addObjectToDouble();
- generateExpression(child.getNext(), node);
- if (!isArithmeticNode(child.getNext()))
- addObjectToDouble();
- cfw.add(opCode);
- if (!childOfArithmetic) {
- addDoubleWrap();
- }
- }
- }
-
- private void visitBitOp(Node node, int type, Node child)
- {
- int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1);
- generateExpression(child, node);
-
- // special-case URSH; work with the target arg as a long, so
- // that we can return a 32-bit unsigned value, and call
- // toUint32 instead of toInt32.
- if (type == Token.URSH) {
- addScriptRuntimeInvoke("toUint32", "(Ljava/lang/Object;)J");
- generateExpression(child.getNext(), node);
- addScriptRuntimeInvoke("toInt32", "(Ljava/lang/Object;)I");
- // Looks like we need to explicitly mask the shift to 5 bits -
- // LUSHR takes 6 bits.
- cfw.addPush(31);
- cfw.add(ByteCode.IAND);
- cfw.add(ByteCode.LUSHR);
- cfw.add(ByteCode.L2D);
- addDoubleWrap();
- return;
- }
- if (childNumberFlag == -1) {
- addScriptRuntimeInvoke("toInt32", "(Ljava/lang/Object;)I");
- generateExpression(child.getNext(), node);
- addScriptRuntimeInvoke("toInt32", "(Ljava/lang/Object;)I");
- }
- else {
- addScriptRuntimeInvoke("toInt32", "(D)I");
- generateExpression(child.getNext(), node);
- addScriptRuntimeInvoke("toInt32", "(D)I");
- }
- switch (type) {
- case Token.BITOR:
- cfw.add(ByteCode.IOR);
- break;
- case Token.BITXOR:
- cfw.add(ByteCode.IXOR);
- break;
- case Token.BITAND:
- cfw.add(ByteCode.IAND);
- break;
- case Token.RSH:
- cfw.add(ByteCode.ISHR);
- break;
- case Token.LSH:
- cfw.add(ByteCode.ISHL);
- break;
- default:
- throw Codegen.badTree();
- }
- cfw.add(ByteCode.I2D);
- if (childNumberFlag == -1) {
- addDoubleWrap();
- }
- }
-
- private int nodeIsDirectCallParameter(Node node)
- {
- if (node.getType() == Token.GETVAR
- && inDirectCallFunction && !itsForcedObjectParameters)
- {
- int varIndex = fnCurrent.getVarIndex(node);
- if (fnCurrent.isParameter(varIndex)) {
- return varRegisters[varIndex];
- }
- }
- return -1;
- }
-
- private boolean varIsDirectCallParameter(int varIndex)
- {
- return fnCurrent.isParameter(varIndex)
- && inDirectCallFunction && !itsForcedObjectParameters;
- }
-
- private void genSimpleCompare(int type, int trueGOTO, int falseGOTO)
- {
- if (trueGOTO == -1) throw Codegen.badTree();
- switch (type) {
- case Token.LE :
- cfw.add(ByteCode.DCMPG);
- cfw.add(ByteCode.IFLE, trueGOTO);
- break;
- case Token.GE :
- cfw.add(ByteCode.DCMPL);
- cfw.add(ByteCode.IFGE, trueGOTO);
- break;
- case Token.LT :
- cfw.add(ByteCode.DCMPG);
- cfw.add(ByteCode.IFLT, trueGOTO);
- break;
- case Token.GT :
- cfw.add(ByteCode.DCMPL);
- cfw.add(ByteCode.IFGT, trueGOTO);
- break;
- default :
- throw Codegen.badTree();
-
- }
- if (falseGOTO != -1)
- cfw.add(ByteCode.GOTO, falseGOTO);
- }
-
- private void visitIfJumpRelOp(Node node, Node child,
- int trueGOTO, int falseGOTO)
- {
- if (trueGOTO == -1 || falseGOTO == -1) throw Codegen.badTree();
- int type = node.getType();
- Node rChild = child.getNext();
- if (type == Token.INSTANCEOF || type == Token.IN) {
- generateExpression(child, node);
- generateExpression(rChild, node);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- (type == Token.INSTANCEOF) ? "instanceOf" : "in",
- "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Z");
- cfw.add(ByteCode.IFNE, trueGOTO);
- cfw.add(ByteCode.GOTO, falseGOTO);
- return;
- }
- int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1);
- int left_dcp_register = nodeIsDirectCallParameter(child);
- int right_dcp_register = nodeIsDirectCallParameter(rChild);
- if (childNumberFlag != -1) {
- // Force numeric context on both parameters and optimize
- // direct call case as Optimizer currently does not handle it
-
- if (childNumberFlag != Node.RIGHT) {
- // Left already has number content
- generateExpression(child, node);
- } else if (left_dcp_register != -1) {
- dcpLoadAsNumber(left_dcp_register);
- } else {
- generateExpression(child, node);
- addObjectToDouble();
- }
-
- if (childNumberFlag != Node.LEFT) {
- // Right already has number content
- generateExpression(rChild, node);
- } else if (right_dcp_register != -1) {
- dcpLoadAsNumber(right_dcp_register);
- } else {
- generateExpression(rChild, node);
- addObjectToDouble();
- }
-
- genSimpleCompare(type, trueGOTO, falseGOTO);
-
- } else {
- if (left_dcp_register != -1 && right_dcp_register != -1) {
- // Generate code to dynamically check for number content
- // if both operands are dcp
- short stack = cfw.getStackTop();
- int leftIsNotNumber = cfw.acquireLabel();
- cfw.addALoad(left_dcp_register);
- cfw.add(ByteCode.GETSTATIC,
- "java/lang/Void",
- "TYPE",
- "Ljava/lang/Class;");
- cfw.add(ByteCode.IF_ACMPNE, leftIsNotNumber);
- cfw.addDLoad(left_dcp_register + 1);
- dcpLoadAsNumber(right_dcp_register);
- genSimpleCompare(type, trueGOTO, falseGOTO);
- if (stack != cfw.getStackTop()) throw Codegen.badTree();
-
- cfw.markLabel(leftIsNotNumber);
- int rightIsNotNumber = cfw.acquireLabel();
- cfw.addALoad(right_dcp_register);
- cfw.add(ByteCode.GETSTATIC,
- "java/lang/Void",
- "TYPE",
- "Ljava/lang/Class;");
- cfw.add(ByteCode.IF_ACMPNE, rightIsNotNumber);
- cfw.addALoad(left_dcp_register);
- addObjectToDouble();
- cfw.addDLoad(right_dcp_register + 1);
- genSimpleCompare(type, trueGOTO, falseGOTO);
- if (stack != cfw.getStackTop()) throw Codegen.badTree();
-
- cfw.markLabel(rightIsNotNumber);
- // Load both register as objects to call generic cmp_*
- cfw.addALoad(left_dcp_register);
- cfw.addALoad(right_dcp_register);
-
- } else {
- generateExpression(child, node);
- generateExpression(rChild, node);
- }
-
- if (type == Token.GE || type == Token.GT) {
- cfw.add(ByteCode.SWAP);
- }
- String routine = ((type == Token.LT)
- || (type == Token.GT)) ? "cmp_LT" : "cmp_LE";
- addScriptRuntimeInvoke(routine,
- "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +")Z");
- cfw.add(ByteCode.IFNE, trueGOTO);
- cfw.add(ByteCode.GOTO, falseGOTO);
- }
- }
-
- private void visitIfJumpEqOp(Node node, Node child,
- int trueGOTO, int falseGOTO)
- {
- if (trueGOTO == -1 || falseGOTO == -1) throw Codegen.badTree();
-
- short stackInitial = cfw.getStackTop();
- int type = node.getType();
- Node rChild = child.getNext();
-
- // Optimize if one of operands is null
- if (child.getType() == Token.NULL || rChild.getType() == Token.NULL) {
- // eq is symmetric in this case
- if (child.getType() == Token.NULL) {
- child = rChild;
- }
- generateExpression(child, node);
- if (type == Token.SHEQ || type == Token.SHNE) {
- int testCode = (type == Token.SHEQ)
- ? ByteCode.IFNULL : ByteCode.IFNONNULL;
- cfw.add(testCode, trueGOTO);
- } else {
- if (type != Token.EQ) {
- // swap false/true targets for !=
- if (type != Token.NE) throw Codegen.badTree();
- int tmp = trueGOTO;
- trueGOTO = falseGOTO;
- falseGOTO = tmp;
- }
- cfw.add(ByteCode.DUP);
- int undefCheckLabel = cfw.acquireLabel();
- cfw.add(ByteCode.IFNONNULL, undefCheckLabel);
- short stack = cfw.getStackTop();
- cfw.add(ByteCode.POP);
- cfw.add(ByteCode.GOTO, trueGOTO);
- cfw.markLabel(undefCheckLabel, stack);
- Codegen.pushUndefined(cfw);
- cfw.add(ByteCode.IF_ACMPEQ, trueGOTO);
- }
- cfw.add(ByteCode.GOTO, falseGOTO);
- } else {
- int child_dcp_register = nodeIsDirectCallParameter(child);
- if (child_dcp_register != -1
- && rChild.getType() == Token.TO_OBJECT)
- {
- Node convertChild = rChild.getFirstChild();
- if (convertChild.getType() == Token.NUMBER) {
- cfw.addALoad(child_dcp_register);
- cfw.add(ByteCode.GETSTATIC,
- "java/lang/Void",
- "TYPE",
- "Ljava/lang/Class;");
- int notNumbersLabel = cfw.acquireLabel();
- cfw.add(ByteCode.IF_ACMPNE, notNumbersLabel);
- cfw.addDLoad(child_dcp_register + 1);
- cfw.addPush(convertChild.getDouble());
- cfw.add(ByteCode.DCMPL);
- if (type == Token.EQ)
- cfw.add(ByteCode.IFEQ, trueGOTO);
- else
- cfw.add(ByteCode.IFNE, trueGOTO);
- cfw.add(ByteCode.GOTO, falseGOTO);
- cfw.markLabel(notNumbersLabel);
- // fall thru into generic handling
- }
- }
-
- generateExpression(child, node);
- generateExpression(rChild, node);
-
- String name;
- int testCode;
- switch (type) {
- case Token.EQ:
- name = "eq";
- testCode = ByteCode.IFNE;
- break;
- case Token.NE:
- name = "eq";
- testCode = ByteCode.IFEQ;
- break;
- case Token.SHEQ:
- name = "shallowEq";
- testCode = ByteCode.IFNE;
- break;
- case Token.SHNE:
- name = "shallowEq";
- testCode = ByteCode.IFEQ;
- break;
- default:
- throw Codegen.badTree();
- }
- addScriptRuntimeInvoke(name,
- "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +")Z");
- cfw.add(testCode, trueGOTO);
- cfw.add(ByteCode.GOTO, falseGOTO);
- }
- if (stackInitial != cfw.getStackTop()) throw Codegen.badTree();
- }
-
- private void visitSetName(Node node, Node child)
- {
- String name = node.getFirstChild().getString();
- while (child != null) {
- generateExpression(child, node);
- child = child.getNext();
- }
- cfw.addALoad(contextLocal);
- cfw.addALoad(variableObjectLocal);
- cfw.addPush(name);
- addScriptRuntimeInvoke(
- "setName",
- "(Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/String;"
- +")Ljava/lang/Object;");
- }
-
- private void visitSetConst(Node node, Node child)
- {
- String name = node.getFirstChild().getString();
- while (child != null) {
- generateExpression(child, node);
- child = child.getNext();
- }
- cfw.addALoad(contextLocal);
- cfw.addPush(name);
- addScriptRuntimeInvoke(
- "setConst",
- "(Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +"Ljava/lang/String;"
- +")Ljava/lang/Object;");
- }
-
- private void visitGetVar(Node node)
- {
- if (!hasVarsInRegs) Kit.codeBug();
- int varIndex = fnCurrent.getVarIndex(node);
- short reg = varRegisters[varIndex];
- if (varIsDirectCallParameter(varIndex)) {
- // Remember that here the isNumber flag means that we
- // want to use the incoming parameter in a Number
- // context, so test the object type and convert the
- // value as necessary.
- if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
- dcpLoadAsNumber(reg);
- } else {
- dcpLoadAsObject(reg);
- }
- } else if (fnCurrent.isNumberVar(varIndex)) {
- cfw.addDLoad(reg);
- } else {
- cfw.addALoad(reg);
- }
- }
-
- private void visitSetVar(Node node, Node child, boolean needValue)
- {
- if (!hasVarsInRegs) Kit.codeBug();
- int varIndex = fnCurrent.getVarIndex(node);
- generateExpression(child.getNext(), node);
- boolean isNumber = (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1);
- short reg = varRegisters[varIndex];
- boolean [] constDeclarations = fnCurrent.fnode.getParamAndVarConst();
- if (constDeclarations[varIndex]) {
- if (!needValue) {
- if (isNumber)
- cfw.add(ByteCode.POP2);
- else
- cfw.add(ByteCode.POP);
- }
- }
- else if (varIsDirectCallParameter(varIndex)) {
- if (isNumber) {
- if (needValue) cfw.add(ByteCode.DUP2);
- cfw.addALoad(reg);
- cfw.add(ByteCode.GETSTATIC,
- "java/lang/Void",
- "TYPE",
- "Ljava/lang/Class;");
- int isNumberLabel = cfw.acquireLabel();
- int beyond = cfw.acquireLabel();
- cfw.add(ByteCode.IF_ACMPEQ, isNumberLabel);
- short stack = cfw.getStackTop();
- addDoubleWrap();
- cfw.addAStore(reg);
- cfw.add(ByteCode.GOTO, beyond);
- cfw.markLabel(isNumberLabel, stack);
- cfw.addDStore(reg + 1);
- cfw.markLabel(beyond);
- }
- else {
- if (needValue) cfw.add(ByteCode.DUP);
- cfw.addAStore(reg);
- }
- } else {
- boolean isNumberVar = fnCurrent.isNumberVar(varIndex);
- if (isNumber) {
- if (isNumberVar) {
- cfw.addDStore(reg);
- if (needValue) cfw.addDLoad(reg);
- } else {
- if (needValue) cfw.add(ByteCode.DUP2);
- // Cannot save number in variable since !isNumberVar,
- // so convert to object
- addDoubleWrap();
- cfw.addAStore(reg);
- }
- } else {
- if (isNumberVar) Kit.codeBug();
- cfw.addAStore(reg);
- if (needValue) cfw.addALoad(reg);
- }
- }
- }
-
- private void visitSetConstVar(Node node, Node child, boolean needValue)
- {
- if (!hasVarsInRegs) Kit.codeBug();
- int varIndex = fnCurrent.getVarIndex(node);
- generateExpression(child.getNext(), node);
- boolean isNumber = (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1);
- short reg = varRegisters[varIndex];
- int beyond = cfw.acquireLabel();
- int noAssign = cfw.acquireLabel();
- if (isNumber) {
- cfw.addILoad(reg + 2);
- cfw.add(ByteCode.IFNE, noAssign);
- short stack = cfw.getStackTop();
- cfw.addPush(1);
- cfw.addIStore(reg + 2);
- cfw.addDStore(reg);
- if (needValue) {
- cfw.addDLoad(reg);
- cfw.markLabel(noAssign, stack);
- } else {
- cfw.add(ByteCode.GOTO, beyond);
- cfw.markLabel(noAssign, stack);
- cfw.add(ByteCode.POP2);
- }
- }
- else {
- cfw.addILoad(reg + 1);
- cfw.add(ByteCode.IFNE, noAssign);
- short stack = cfw.getStackTop();
- cfw.addPush(1);
- cfw.addIStore(reg + 1);
- cfw.addAStore(reg);
- if (needValue) {
- cfw.addALoad(reg);
- cfw.markLabel(noAssign, stack);
- } else {
- cfw.add(ByteCode.GOTO, beyond);
- cfw.markLabel(noAssign, stack);
- cfw.add(ByteCode.POP);
- }
- }
- cfw.markLabel(beyond);
- }
-
- private void visitGetProp(Node node, Node child)
- {
- generateExpression(child, node); // object
- Node nameChild = child.getNext();
- generateExpression(nameChild, node); // the name
- if (node.getType() == Token.GETPROPNOWARN) {
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "getObjectPropNoWarn",
- "(Ljava/lang/Object;"
- +"Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- return;
- }
- /*
- for 'this.foo' we call getObjectProp(Scriptable...) which can
- skip some casting overhead.
- */
- int childType = child.getType();
- if (childType == Token.THIS && nameChild.getType() == Token.STRING) {
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "getObjectProp",
- "(Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- } else {
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "getObjectProp",
- "(Ljava/lang/Object;"
- +"Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- }
- }
-
- private void visitSetProp(int type, Node node, Node child)
- {
- Node objectChild = child;
- generateExpression(child, node);
- child = child.getNext();
- if (type == Token.SETPROP_OP) {
- cfw.add(ByteCode.DUP);
- }
- Node nameChild = child;
- generateExpression(child, node);
- child = child.getNext();
- if (type == Token.SETPROP_OP) {
- // stack: ... object object name -> ... object name object name
- cfw.add(ByteCode.DUP_X1);
- //for 'this.foo += ...' we call thisGet which can skip some
- //casting overhead.
- if (objectChild.getType() == Token.THIS
- && nameChild.getType() == Token.STRING)
- {
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "getObjectProp",
- "(Lorg/mozilla/javascript/Scriptable;"
- +"Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- } else {
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "getObjectProp",
- "(Ljava/lang/Object;"
- +"Ljava/lang/String;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- }
- }
- generateExpression(child, node);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "setObjectProp",
- "(Ljava/lang/Object;"
- +"Ljava/lang/String;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- }
-
- private void visitSetElem(int type, Node node, Node child)
- {
- generateExpression(child, node);
- child = child.getNext();
- if (type == Token.SETELEM_OP) {
- cfw.add(ByteCode.DUP);
- }
- generateExpression(child, node);
- child = child.getNext();
- boolean indexIsNumber = (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1);
- if (type == Token.SETELEM_OP) {
- if (indexIsNumber) {
- // stack: ... object object number
- // -> ... object number object number
- cfw.add(ByteCode.DUP2_X1);
- cfw.addALoad(contextLocal);
- addOptRuntimeInvoke(
- "getObjectIndex",
- "(Ljava/lang/Object;D"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- } else {
- // stack: ... object object indexObject
- // -> ... object indexObject object indexObject
- cfw.add(ByteCode.DUP_X1);
- cfw.addALoad(contextLocal);
- addScriptRuntimeInvoke(
- "getObjectElem",
- "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- }
- }
- generateExpression(child, node);
- cfw.addALoad(contextLocal);
- if (indexIsNumber) {
- addScriptRuntimeInvoke(
- "setObjectIndex",
- "(Ljava/lang/Object;"
- +"D"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- } else {
- addScriptRuntimeInvoke(
- "setObjectElem",
- "(Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Context;"
- +")Ljava/lang/Object;");
- }
- }
-
- private void visitDotQuery(Node node, Node child)
- {
- updateLineNumber(node);
- generateExpression(child, node);
- cfw.addALoad(variableObjectLocal);
- addScriptRuntimeInvoke("enterDotQuery",
- "(Ljava/lang/Object;"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Lorg/mozilla/javascript/Scriptable;");
- cfw.addAStore(variableObjectLocal);
-
- // add push null/pop with label in between to simplify code for loop
- // continue when it is necessary to pop the null result from
- // updateDotQuery
- cfw.add(ByteCode.ACONST_NULL);
- int queryLoopStart = cfw.acquireLabel();
- cfw.markLabel(queryLoopStart); // loop continue jumps here
- cfw.add(ByteCode.POP);
-
- generateExpression(child.getNext(), node);
- addScriptRuntimeInvoke("toBoolean", "(Ljava/lang/Object;)Z");
- cfw.addALoad(variableObjectLocal);
- addScriptRuntimeInvoke("updateDotQuery",
- "(Z"
- +"Lorg/mozilla/javascript/Scriptable;"
- +")Ljava/lang/Object;");
- cfw.add(ByteCode.DUP);
- cfw.add(ByteCode.IFNULL, queryLoopStart);
- // stack: ... non_null_result_of_updateDotQuery
- cfw.addALoad(variableObjectLocal);
- addScriptRuntimeInvoke("leaveDotQuery",
- "(Lorg/mozilla/javascript/Scriptable;"
- +")Lorg/mozilla/javascript/Scriptable;");
- cfw.addAStore(variableObjectLocal);
- }
-
- private int getLocalBlockRegister(Node node)
- {
- Node localBlock = (Node)node.getProp(Node.LOCAL_BLOCK_PROP);
- int localSlot = localBlock.getExistingIntProp(Node.LOCAL_PROP);
- return localSlot;
- }
-
- private void dcpLoadAsNumber(int dcp_register)
- {
- cfw.addALoad(dcp_register);
- cfw.add(ByteCode.GETSTATIC,
- "java/lang/Void",
- "TYPE",
- "Ljava/lang/Class;");
- int isNumberLabel = cfw.acquireLabel();
- cfw.add(ByteCode.IF_ACMPEQ, isNumberLabel);
- short stack = cfw.getStackTop();
- cfw.addALoad(dcp_register);
- addObjectToDouble();
- int beyond = cfw.acquireLabel();
- cfw.add(ByteCode.GOTO, beyond);
- cfw.markLabel(isNumberLabel, stack);
- cfw.addDLoad(dcp_register + 1);
- cfw.markLabel(beyond);
- }
-
- private void dcpLoadAsObject(int dcp_register)
- {
- cfw.addALoad(dcp_register);
- cfw.add(ByteCode.GETSTATIC,
- "java/lang/Void",
- "TYPE",
- "Ljava/lang/Class;");
- int isNumberLabel = cfw.acquireLabel();
- cfw.add(ByteCode.IF_ACMPEQ, isNumberLabel);
- short stack = cfw.getStackTop();
- cfw.addALoad(dcp_register);
- int beyond = cfw.acquireLabel();
- cfw.add(ByteCode.GOTO, beyond);
- cfw.markLabel(isNumberLabel, stack);
- cfw.addDLoad(dcp_register + 1);
- addDoubleWrap();
- cfw.markLabel(beyond);
- }
-
- private void addGoto(Node target, int jumpcode)
- {
- int targetLabel = getTargetLabel(target);
- cfw.add(jumpcode, targetLabel);
- }
-
- private void addObjectToDouble()
- {
- addScriptRuntimeInvoke("toNumber", "(Ljava/lang/Object;)D");
- }
-
- private void addNewObjectArray(int size)
- {
- if (size == 0) {
- if (itsZeroArgArray >= 0) {
- cfw.addALoad(itsZeroArgArray);
- } else {
- cfw.add(ByteCode.GETSTATIC,
- "org/mozilla/javascript/ScriptRuntime",
- "emptyArgs", "[Ljava/lang/Object;");
- }
- } else {
- cfw.addPush(size);
- cfw.add(ByteCode.ANEWARRAY, "java/lang/Object");
- }
- }
-
- private void addScriptRuntimeInvoke(String methodName,
- String methodSignature)
- {
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org.mozilla.javascript.ScriptRuntime",
- methodName,
- methodSignature);
- }
-
- private void addOptRuntimeInvoke(String methodName,
- String methodSignature)
- {
- cfw.addInvoke(ByteCode.INVOKESTATIC,
- "org/mozilla/javascript/optimizer/OptRuntime",
- methodName,
- methodSignature);
- }
-
- private void addJumpedBooleanWrap(int trueLabel, int falseLabel)
- {
- cfw.markLabel(falseLabel);
- int skip = cfw.acquireLabel();
- cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean",
- "FALSE", "Ljava/lang/Boolean;");
- cfw.add(ByteCode.GOTO, skip);
- cfw.markLabel(trueLabel);
- cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean",
- "TRUE", "Ljava/lang/Boolean;");
- cfw.markLabel(skip);
- cfw.adjustStackTop(-1); // only have 1 of true/false
- }
-
- private void addDoubleWrap()
- {
- addOptRuntimeInvoke("wrapDouble", "(D)Ljava/lang/Double;");
- }
-
- /**
- * Const locals use an extra slot to hold the has-been-assigned-once flag at
- * runtime.
- * @param isConst true iff the variable is const
- * @return the register for the word pair (double/long)
- */
- private short getNewWordPairLocal(boolean isConst)
- {
- short result = getConsecutiveSlots(2, isConst);
- if (result < (MAX_LOCALS - 1)) {
- locals[result] = 1;
- locals[result + 1] = 1;
- if (isConst)
- locals[result + 2] = 1;
- if (result == firstFreeLocal) {
- for (int i = firstFreeLocal + 2; i < MAX_LOCALS; i++) {
- if (locals[i] == 0) {
- firstFreeLocal = (short) i;
- if (localsMax < firstFreeLocal)
- localsMax = firstFreeLocal;
- return result;
- }
- }
- }
- else {
- return result;
- }
- }
- throw Context.reportRuntimeError("Program too complex " +
- "(out of locals)");
- }
-
- private short getNewWordLocal(boolean isConst)
- {
- short result = getConsecutiveSlots(1, isConst);
- if (result < (MAX_LOCALS - 1)) {
- locals[result] = 1;
- if (isConst)
- locals[result + 1] = 1;
- if (result == firstFreeLocal) {
- for (int i = firstFreeLocal + 2; i < MAX_LOCALS; i++) {
- if (locals[i] == 0) {
- firstFreeLocal = (short) i;
- if (localsMax < firstFreeLocal)
- localsMax = firstFreeLocal;
- return result;
- }
- }
- }
- else {
- return result;
- }
- }
- throw Context.reportRuntimeError("Program too complex " +
- "(out of locals)");
- }
-
- private short getNewWordLocal()
- {
- short result = firstFreeLocal;
- locals[result] = 1;
- for (int i = firstFreeLocal + 1; i < MAX_LOCALS; i++) {
- if (locals[i] == 0) {
- firstFreeLocal = (short) i;
- if (localsMax < firstFreeLocal)
- localsMax = firstFreeLocal;
- return result;
- }
- }
- throw Context.reportRuntimeError("Program too complex " +
- "(out of locals)");
- }
-
- private short getConsecutiveSlots(int count, boolean isConst) {
- if (isConst)
- count++;
- short result = firstFreeLocal;
- while (true) {
- if (result >= (MAX_LOCALS - 1))
- break;
- int i;
- for (i = 0; i < count; i++)
- if (locals[result + i] != 0)
- break;
- if (i >= count)
- break;
- result++;
- }
- return result;
- }
-
- // This is a valid call only for a local that is allocated by default.
- private void incReferenceWordLocal(short local)
- {
- locals[local]++;
- }
-
- // This is a valid call only for a local that is allocated by default.
- private void decReferenceWordLocal(short local)
- {
- locals[local]--;
- }
-
- private void releaseWordLocal(short local)
- {
- if (local < firstFreeLocal)
- firstFreeLocal = local;
- locals[local] = 0;
- }
-
-
- static final int GENERATOR_TERMINATE = -1;
- static final int GENERATOR_START = 0;
- static final int GENERATOR_YIELD_START = 1;
-
- ClassFileWriter cfw;
- Codegen codegen;
- CompilerEnvirons compilerEnv;
- ScriptOrFnNode scriptOrFn;
- public int scriptOrFnIndex;
- private int savedCodeOffset;
-
- private OptFunctionNode fnCurrent;
- private boolean isTopLevel;
-
- private static final int MAX_LOCALS = 256;
- private int[] locals;
- private short firstFreeLocal;
- private short localsMax;
-
- private int itsLineNumber;
-
- private boolean hasVarsInRegs;
- private short[] varRegisters;
- private boolean inDirectCallFunction;
- private boolean itsForcedObjectParameters;
- private int enterAreaStartLabel;
- private int epilogueLabel;
-
- // special known locals. If you add a new local here, be sure
- // to initialize it to -1 in initBodyGeneration
- private short variableObjectLocal;
- private short popvLocal;
- private short contextLocal;
- private short argsLocal;
- private short operationLocal;
- private short thisObjLocal;
- private short funObjLocal;
- private short itsZeroArgArray;
- private short itsOneArgArray;
- private short scriptRegexpLocal;
- private short generatorStateLocal;
-
- private boolean isGenerator;
- private int generatorSwitch;
- private int maxLocals = 0;
- private int maxStack = 0;
-
- private Hashtable finallys;
-
- class FinallyReturnPoint {
- public ArrayList jsrPoints = new ArrayList();
- public int tableLabel = 0;
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/DataFlowBitSet.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/DataFlowBitSet.java
deleted file mode 100644
index 607e649..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/DataFlowBitSet.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/* ***** 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
- * Roger Lawrence
- *
- * 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.optimizer;
-
-class DataFlowBitSet {
-
- private int itsBits[];
- private int itsSize;
-
- DataFlowBitSet(int size)
- {
- itsSize = size;
- itsBits = new int[(size + 31) >> 5];
- }
-
- void set(int n)
- {
- if (!(0 <= n && n < itsSize)) badIndex(n);
- itsBits[n >> 5] |= 1 << (n & 31);
- }
-
- boolean test(int n)
- {
- if (!(0 <= n && n < itsSize)) badIndex(n);
- return ((itsBits[n >> 5] & (1 << (n & 31))) != 0);
- }
-
- void not()
- {
- int bitsLength = itsBits.length;
- for (int i = 0; i < bitsLength; i++)
- itsBits[i] = ~itsBits[i];
- }
-
- void clear(int n)
- {
- if (!(0 <= n && n < itsSize)) badIndex(n);
- itsBits[n >> 5] &= ~(1 << (n & 31));
- }
-
- void clear()
- {
- int bitsLength = itsBits.length;
- for (int i = 0; i < bitsLength; i++)
- itsBits[i] = 0;
- }
-
- void or(DataFlowBitSet b)
- {
- int bitsLength = itsBits.length;
- for (int i = 0; i < bitsLength; i++)
- itsBits[i] |= b.itsBits[i];
- }
-
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
- sb.append("DataFlowBitSet, size = ");
- sb.append(itsSize);
- sb.append('\n');
- int bitsLength = itsBits.length;
- for (int i = 0; i < bitsLength; i++) {
- sb.append(Integer.toHexString(itsBits[i]));
- sb.append(' ');
- }
- return sb.toString();
- }
-
- boolean df(DataFlowBitSet in, DataFlowBitSet gen, DataFlowBitSet notKill)
- {
- int bitsLength = itsBits.length;
- boolean changed = false;
- for (int i = 0; i < bitsLength; i++) {
- int oldBits = itsBits[i];
- itsBits[i] = (in.itsBits[i] | gen.itsBits[i]) & notKill.itsBits[i];
- changed |= (oldBits != itsBits[i]);
- }
- return changed;
- }
-
- boolean df2(DataFlowBitSet in, DataFlowBitSet gen, DataFlowBitSet notKill)
- {
- int bitsLength = itsBits.length;
- boolean changed = false;
- for (int i = 0; i < bitsLength; i++) {
- int oldBits = itsBits[i];
- itsBits[i] = (in.itsBits[i] & notKill.itsBits[i]) | gen.itsBits[i];
- changed |= (oldBits != itsBits[i]);
- }
- return changed;
- }
-
- private void badIndex(int n)
- {
- throw new RuntimeException("DataFlowBitSet bad index " + n);
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptFunctionNode.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptFunctionNode.java
deleted file mode 100644
index e043165..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptFunctionNode.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/* ***** 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
- * Bob Jervis
- * Roger Lawrence
- *
- * 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.optimizer;
-
-import org.mozilla.javascript.*;
-
-final class OptFunctionNode
-{
- OptFunctionNode(FunctionNode fnode)
- {
- this.fnode = fnode;
- fnode.setCompilerData(this);
- }
-
- static OptFunctionNode get(ScriptOrFnNode scriptOrFn, int i)
- {
- FunctionNode fnode = scriptOrFn.getFunctionNode(i);
- return (OptFunctionNode)fnode.getCompilerData();
- }
-
- static OptFunctionNode get(ScriptOrFnNode scriptOrFn)
- {
- return (OptFunctionNode)scriptOrFn.getCompilerData();
- }
-
- boolean isTargetOfDirectCall()
- {
- return directTargetIndex >= 0;
- }
-
- int getDirectTargetIndex()
- {
- return directTargetIndex;
- }
-
- void setDirectTargetIndex(int directTargetIndex)
- {
- // One time action
- if (directTargetIndex < 0 || this.directTargetIndex >= 0)
- Kit.codeBug();
- this.directTargetIndex = directTargetIndex;
- }
-
- void setParameterNumberContext(boolean b)
- {
- itsParameterNumberContext = b;
- }
-
- boolean getParameterNumberContext()
- {
- return itsParameterNumberContext;
- }
-
- int getVarCount()
- {
- return fnode.getParamAndVarCount();
- }
-
- boolean isParameter(int varIndex)
- {
- return varIndex < fnode.getParamCount();
- }
-
- boolean isNumberVar(int varIndex)
- {
- varIndex -= fnode.getParamCount();
- if (varIndex >= 0 && numberVarFlags != null) {
- return numberVarFlags[varIndex];
- }
- return false;
- }
-
- void setIsNumberVar(int varIndex)
- {
- varIndex -= fnode.getParamCount();
- // Can only be used with non-parameters
- if (varIndex < 0) Kit.codeBug();
- if (numberVarFlags == null) {
- int size = fnode.getParamAndVarCount() - fnode.getParamCount();
- numberVarFlags = new boolean[size];
- }
- numberVarFlags[varIndex] = true;
- }
-
- int getVarIndex(Node n)
- {
- int index = n.getIntProp(Node.VARIABLE_PROP, -1);
- if (index == -1) {
- Node node;
- int type = n.getType();
- if (type == Token.GETVAR) {
- node = n;
- } else if (type == Token.SETVAR ||
- type == Token.SETCONSTVAR) {
- node = n.getFirstChild();
- } else {
- throw Kit.codeBug();
- }
- index = fnode.getIndexForNameNode(node);
- if (index < 0) throw Kit.codeBug();
- n.putIntProp(Node.VARIABLE_PROP, index);
- }
- return index;
- }
-
- FunctionNode fnode;
- private boolean[] numberVarFlags;
- private int directTargetIndex = -1;
- private boolean itsParameterNumberContext;
- boolean itsContainsCalls0;
- boolean itsContainsCalls1;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptRuntime.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptRuntime.java
deleted file mode 100644
index ba8ca03..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptRuntime.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/* ***** 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- * Roger Lawrence
- * Hannes Wallnoefer
- *
- * 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.optimizer;
-
-import org.mozilla.javascript.*;
-
-public final class OptRuntime extends ScriptRuntime
-{
-
- public static final Double zeroObj = new Double(0.0);
- public static final Double oneObj = new Double(1.0);
- public static final Double minusOneObj = new Double(-1.0);
-
- /**
- * Implement ....() call shrinking optimizer code.
- */
- public static Object call0(Callable fun, Scriptable thisObj,
- Context cx, Scriptable scope)
- {
- return fun.call(cx, scope, thisObj, ScriptRuntime.emptyArgs);
- }
-
- /**
- * Implement ....(arg) call shrinking optimizer code.
- */
- public static Object call1(Callable fun, Scriptable thisObj, Object arg0,
- Context cx, Scriptable scope)
- {
- return fun.call(cx, scope, thisObj, new Object[] { arg0 } );
- }
-
- /**
- * Implement ....(arg0, arg1) call shrinking optimizer code.
- */
- public static Object call2(Callable fun, Scriptable thisObj,
- Object arg0, Object arg1,
- Context cx, Scriptable scope)
- {
- return fun.call(cx, scope, thisObj, new Object[] { arg0, arg1 });
- }
-
- /**
- * Implement ....(arg0, arg1, ...) call shrinking optimizer code.
- */
- public static Object callN(Callable fun, Scriptable thisObj,
- Object[] args,
- Context cx, Scriptable scope)
- {
- return fun.call(cx, scope, thisObj, args);
- }
-
- /**
- * Implement name(args) call shrinking optimizer code.
- */
- public static Object callName(Object[] args, String name,
- Context cx, Scriptable scope)
- {
- Callable f = getNameFunctionAndThis(name, cx, scope);
- Scriptable thisObj = lastStoredScriptable(cx);
- return f.call(cx, scope, thisObj, args);
- }
-
- /**
- * Implement name() call shrinking optimizer code.
- */
- public static Object callName0(String name,
- Context cx, Scriptable scope)
- {
- Callable f = getNameFunctionAndThis(name, cx, scope);
- Scriptable thisObj = lastStoredScriptable(cx);
- return f.call(cx, scope, thisObj, ScriptRuntime.emptyArgs);
- }
-
- /**
- * Implement x.property() call shrinking optimizer code.
- */
- public static Object callProp0(Object value, String property,
- Context cx, Scriptable scope)
- {
- Callable f = getPropFunctionAndThis(value, property, cx);
- Scriptable thisObj = lastStoredScriptable(cx);
- return f.call(cx, scope, thisObj, ScriptRuntime.emptyArgs);
- }
-
- public static Object add(Object val1, double val2)
- {
- if (val1 instanceof Scriptable)
- val1 = ((Scriptable) val1).getDefaultValue(null);
- if (!(val1 instanceof String))
- return wrapDouble(toNumber(val1) + val2);
- return ((String)val1).concat(toString(val2));
- }
-
- public static Object add(double val1, Object val2)
- {
- if (val2 instanceof Scriptable)
- val2 = ((Scriptable) val2).getDefaultValue(null);
- if (!(val2 instanceof String))
- return wrapDouble(toNumber(val2) + val1);
- return toString(val1).concat((String)val2);
- }
-
- public static Object elemIncrDecr(Object obj, double index,
- Context cx, int incrDecrMask)
- {
- return ScriptRuntime.elemIncrDecr(obj, new Double(index), cx,
- incrDecrMask);
- }
-
- public static Object[] padStart(Object[] currentArgs, int count) {
- Object[] result = new Object[currentArgs.length + count];
- System.arraycopy(currentArgs, 0, result, count, currentArgs.length);
- return result;
- }
-
- public static void initFunction(NativeFunction fn, int functionType,
- Scriptable scope, Context cx)
- {
- ScriptRuntime.initFunction(cx, scope, fn, functionType, false);
- }
-
- public static Object callSpecial(Context cx, Callable fun,
- Scriptable thisObj, Object[] args,
- Scriptable scope,
- Scriptable callerThis, int callType,
- String fileName, int lineNumber)
- {
- return ScriptRuntime.callSpecial(cx, fun, thisObj, args, scope,
- callerThis, callType,
- fileName, lineNumber);
- }
-
- public static Object newObjectSpecial(Context cx, Object fun,
- Object[] args, Scriptable scope,
- Scriptable callerThis, int callType)
- {
- return ScriptRuntime.newSpecial(cx, fun, args, scope, callType);
- }
-
- public static Double wrapDouble(double num)
- {
- if (num == 0.0) {
- if (1 / num > 0) {
- // +0.0
- return zeroObj;
- }
- } else if (num == 1.0) {
- return oneObj;
- } else if (num == -1.0) {
- return minusOneObj;
- } else if (num != num) {
- return NaNobj;
- }
- return new Double(num);
- }
-
- static String encodeIntArray(int[] array)
- {
- // XXX: this extremely inefficient for small integers
- if (array == null) { return null; }
- int n = array.length;
- char[] buffer = new char[1 + n * 2];
- buffer[0] = 1;
- for (int i = 0; i != n; ++i) {
- int value = array[i];
- int shift = 1 + i * 2;
- buffer[shift] = (char)(value >>> 16);
- buffer[shift + 1] = (char)value;
- }
- return new String(buffer);
- }
-
- private static int[] decodeIntArray(String str, int arraySize)
- {
- // XXX: this extremely inefficient for small integers
- if (arraySize == 0) {
- if (str != null) throw new IllegalArgumentException();
- return null;
- }
- if (str.length() != 1 + arraySize * 2 && str.charAt(0) != 1) {
- throw new IllegalArgumentException();
- }
- int[] array = new int[arraySize];
- for (int i = 0; i != arraySize; ++i) {
- int shift = 1 + i * 2;
- array[i] = (str.charAt(shift) << 16) | str.charAt(shift + 1);
- }
- return array;
- }
-
- public static Scriptable newArrayLiteral(Object[] objects,
- String encodedInts,
- int skipCount,
- Context cx,
- Scriptable scope)
- {
- int[] skipIndexces = decodeIntArray(encodedInts, skipCount);
- return newArrayLiteral(objects, skipIndexces, cx, scope);
- }
-
- public static void main(final Script script, final String[] args)
- {
- Context.call(new ContextAction() {
- public Object run(Context cx)
- {
- ScriptableObject global = getGlobal(cx);
-
- // get the command line arguments and define "arguments"
- // array in the top-level object
- Object[] argsCopy = new Object[args.length];
- System.arraycopy(args, 0, argsCopy, 0, args.length);
- Scriptable argsObj = cx.newArray(global, argsCopy);
- global.defineProperty("arguments", argsObj,
- ScriptableObject.DONTENUM);
- script.exec(cx, global);
- return null;
- }
- });
- }
-
- public static void throwStopIteration(Object obj) {
- throw new JavaScriptException(
- NativeIterator.getStopIterationObject((Scriptable)obj), "", 0);
- }
-
- public static Scriptable createNativeGenerator(NativeFunction funObj,
- Scriptable scope,
- Scriptable thisObj,
- int maxLocals,
- int maxStack)
- {
- return new NativeGenerator(scope, funObj,
- new GeneratorState(thisObj, maxLocals, maxStack));
- }
-
- public static Object[] getGeneratorStackState(Object obj) {
- GeneratorState rgs = (GeneratorState) obj;
- if (rgs.stackState == null)
- rgs.stackState = new Object[rgs.maxStack];
- return rgs.stackState;
- }
-
- public static Object[] getGeneratorLocalsState(Object obj) {
- GeneratorState rgs = (GeneratorState) obj;
- if (rgs.localsState == null)
- rgs.localsState = new Object[rgs.maxLocals];
- return rgs.localsState;
- }
-
- public static class GeneratorState {
- static final String CLASS_NAME =
- "org/mozilla/javascript/optimizer/OptRuntime$GeneratorState";
-
- public int resumptionPoint;
- static final String resumptionPoint_NAME = "resumptionPoint";
- static final String resumptionPoint_TYPE = "I";
-
- public Scriptable thisObj;
- static final String thisObj_NAME = "thisObj";
- static final String thisObj_TYPE =
- "Lorg/mozilla/javascript/Scriptable;";
-
- Object[] stackState;
- Object[] localsState;
- int maxLocals;
- int maxStack;
-
- GeneratorState(Scriptable thisObj, int maxLocals, int maxStack) {
- this.thisObj = thisObj;
- this.maxLocals = maxLocals;
- this.maxStack = maxStack;
- }
- }
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptTransformer.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptTransformer.java
deleted file mode 100644
index 7cf679f..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptTransformer.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/* ***** 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
- * Roger Lawrence
- *
- * 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.optimizer;
-
-import org.mozilla.javascript.*;
-import java.util.Hashtable;
-
-/**
- * This class performs node transforms to prepare for optimization.
- *
- * @see NodeTransformer
- * @author Norris Boyd
- */
-
-class OptTransformer extends NodeTransformer {
-
- OptTransformer(Hashtable possibleDirectCalls, ObjArray directCallTargets)
- {
- this.possibleDirectCalls = possibleDirectCalls;
- this.directCallTargets = directCallTargets;
- }
-
- protected void visitNew(Node node, ScriptOrFnNode tree) {
- detectDirectCall(node, tree);
- super.visitNew(node, tree);
- }
-
- protected void visitCall(Node node, ScriptOrFnNode tree) {
- detectDirectCall(node, tree);
- super.visitCall(node, tree);
- }
-
- private void detectDirectCall(Node node, ScriptOrFnNode tree)
- {
- if (tree.getType() == Token.FUNCTION) {
- Node left = node.getFirstChild();
-
- // count the arguments
- int argCount = 0;
- Node arg = left.getNext();
- while (arg != null) {
- arg = arg.getNext();
- argCount++;
- }
-
- if (argCount == 0) {
- OptFunctionNode.get(tree).itsContainsCalls0 = true;
- }
-
- /*
- * Optimize a call site by converting call("a", b, c) into :
- *
- * FunctionObjectFor"a" <-- instance variable init'd by constructor
- *
- * // this is a DIRECTCALL node
- * fn = GetProp(tmp = GetBase("a"), "a");
- * if (fn == FunctionObjectFor"a")
- * fn.call(tmp, b, c)
- * else
- * ScriptRuntime.Call(fn, tmp, b, c)
- */
- if (possibleDirectCalls != null) {
- String targetName = null;
- if (left.getType() == Token.NAME) {
- targetName = left.getString();
- } else if (left.getType() == Token.GETPROP) {
- targetName = left.getFirstChild().getNext().getString();
- } else if (left.getType() == Token.GETPROPNOWARN) {
- throw Kit.codeBug();
- }
- if (targetName != null) {
- OptFunctionNode ofn;
- ofn = (OptFunctionNode)possibleDirectCalls.get(targetName);
- if (ofn != null
- && argCount == ofn.fnode.getParamCount()
- && !ofn.fnode.requiresActivation())
- {
- // Refuse to directCall any function with more
- // than 32 parameters - prevent code explosion
- // for wacky test cases
- if (argCount <= 32) {
- node.putProp(Node.DIRECTCALL_PROP, ofn);
- if (!ofn.isTargetOfDirectCall()) {
- int index = directCallTargets.size();
- directCallTargets.add(ofn);
- ofn.setDirectTargetIndex(index);
- }
- }
- }
- }
- }
- }
- }
-
- private Hashtable possibleDirectCalls;
- private ObjArray directCallTargets;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Optimizer.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Optimizer.java
deleted file mode 100644
index 575c7e7..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Optimizer.java
+++ /dev/null
@@ -1,510 +0,0 @@
-/* ***** 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
- * Roger Lawrence
- *
- * 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.optimizer;
-
-import org.mozilla.javascript.*;
-
-class Optimizer
-{
-
- static final int NoType = 0;
- static final int NumberType = 1;
- static final int AnyType = 3;
-
- // It is assumed that (NumberType | AnyType) == AnyType
-
- void optimize(ScriptOrFnNode scriptOrFn)
- {
- // run on one function at a time for now
- int functionCount = scriptOrFn.getFunctionCount();
- for (int i = 0; i != functionCount; ++i) {
- OptFunctionNode f = OptFunctionNode.get(scriptOrFn, i);
- optimizeFunction(f);
- }
- }
-
- private void optimizeFunction(OptFunctionNode theFunction)
- {
- if (theFunction.fnode.requiresActivation()) return;
-
- inDirectCallFunction = theFunction.isTargetOfDirectCall();
- this.theFunction = theFunction;
-
- ObjArray statementsArray = new ObjArray();
- buildStatementList_r(theFunction.fnode, statementsArray);
- Node[] theStatementNodes = new Node[statementsArray.size()];
- statementsArray.toArray(theStatementNodes);
-
- Block.runFlowAnalyzes(theFunction, theStatementNodes);
-
- if (!theFunction.fnode.requiresActivation()) {
- /*
- * Now that we know which local vars are in fact always
- * Numbers, we re-write the tree to take advantage of
- * that. Any arithmetic or assignment op involving just
- * Number typed vars is marked so that the codegen will
- * generate non-object code.
- */
- parameterUsedInNumberContext = false;
- for (int i = 0; i < theStatementNodes.length; i++) {
- rewriteForNumberVariables(theStatementNodes[i]);
- }
- theFunction.setParameterNumberContext(parameterUsedInNumberContext);
- }
-
- }
-
-
-/*
- Each directCall parameter is passed as a pair of values - an object
- and a double. The value passed depends on the type of value available at
- the call site. If a double is available, the object in java/lang/Void.TYPE
- is passed as the object value, and if an object value is available, then
- 0.0 is passed as the double value.
-
- The receiving routine always tests the object value before proceeding.
- If the parameter is being accessed in a 'Number Context' then the code
- sequence is :
- if ("parameter_objectValue" == java/lang/Void.TYPE)
- ...fine..., use the parameter_doubleValue
- else
- toNumber(parameter_objectValue)
-
- and if the parameter is being referenced in an Object context, the code is
- if ("parameter_objectValue" == java/lang/Void.TYPE)
- new Double(parameter_doubleValue)
- else
- ...fine..., use the parameter_objectValue
-
- If the receiving code never uses the doubleValue, it is converted on
- entry to a Double instead.
-*/
-
-
-/*
- We're referencing a node in a Number context (i.e. we'd prefer it
- was a double value). If the node is a parameter in a directCall
- function, mark it as being referenced in this context.
-*/
- private void markDCPNumberContext(Node n)
- {
- if (inDirectCallFunction && n.getType() == Token.GETVAR) {
- int varIndex = theFunction.getVarIndex(n);
- if (theFunction.isParameter(varIndex)) {
- parameterUsedInNumberContext = true;
- }
- }
- }
-
- private boolean convertParameter(Node n)
- {
- if (inDirectCallFunction && n.getType() == Token.GETVAR) {
- int varIndex = theFunction.getVarIndex(n);
- if (theFunction.isParameter(varIndex)) {
- n.removeProp(Node.ISNUMBER_PROP);
- return true;
- }
- }
- return false;
- }
-
- private int rewriteForNumberVariables(Node n)
- {
- switch (n.getType()) {
- case Token.EXPR_VOID : {
- Node child = n.getFirstChild();
- int type = rewriteForNumberVariables(child);
- if (type == NumberType)
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- return NoType;
- }
- case Token.NUMBER :
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- return NumberType;
-
- case Token.GETVAR :
- {
- int varIndex = theFunction.getVarIndex(n);
- if (inDirectCallFunction
- && theFunction.isParameter(varIndex))
- {
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- return NumberType;
- }
- else if (theFunction.isNumberVar(varIndex)) {
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- return NumberType;
- }
- return NoType;
- }
-
- case Token.INC :
- case Token.DEC : {
- Node child = n.getFirstChild();
- // "child" will be GETVAR or GETPROP or GETELEM
- if (child.getType() == Token.GETVAR) {
- if (rewriteForNumberVariables(child) == NumberType) {
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- markDCPNumberContext(child);
- return NumberType;
- }
- return NoType;
- }
- else if (child.getType() == Token.GETELEM) {
- return rewriteForNumberVariables(child);
- }
- return NoType;
- }
- case Token.SETVAR : {
- Node lChild = n.getFirstChild();
- Node rChild = lChild.getNext();
- int rType = rewriteForNumberVariables(rChild);
- int varIndex = theFunction.getVarIndex(n);
- if (inDirectCallFunction
- && theFunction.isParameter(varIndex))
- {
- if (rType == NumberType) {
- if (!convertParameter(rChild)) {
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- return NumberType;
- }
- markDCPNumberContext(rChild);
- return NoType;
- }
- else
- return rType;
- }
- else if (theFunction.isNumberVar(varIndex)) {
- if (rType != NumberType) {
- n.removeChild(rChild);
- n.addChildToBack(
- new Node(Token.TO_DOUBLE, rChild));
- }
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- markDCPNumberContext(rChild);
- return NumberType;
- }
- else {
- if (rType == NumberType) {
- if (!convertParameter(rChild)) {
- n.removeChild(rChild);
- n.addChildToBack(
- new Node(Token.TO_OBJECT, rChild));
- }
- }
- return NoType;
- }
- }
- case Token.LE :
- case Token.LT :
- case Token.GE :
- case Token.GT : {
- Node lChild = n.getFirstChild();
- Node rChild = lChild.getNext();
- int lType = rewriteForNumberVariables(lChild);
- int rType = rewriteForNumberVariables(rChild);
- markDCPNumberContext(lChild);
- markDCPNumberContext(rChild);
-
- if (convertParameter(lChild)) {
- if (convertParameter(rChild)) {
- return NoType;
- } else if (rType == NumberType) {
- n.putIntProp(Node.ISNUMBER_PROP, Node.RIGHT);
- }
- }
- else if (convertParameter(rChild)) {
- if (lType == NumberType) {
- n.putIntProp(Node.ISNUMBER_PROP, Node.LEFT);
- }
- }
- else {
- if (lType == NumberType) {
- if (rType == NumberType) {
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- }
- else {
- n.putIntProp(Node.ISNUMBER_PROP, Node.LEFT);
- }
- }
- else {
- if (rType == NumberType) {
- n.putIntProp(Node.ISNUMBER_PROP, Node.RIGHT);
- }
- }
- }
- // we actually build a boolean value
- return NoType;
- }
-
- case Token.ADD : {
- Node lChild = n.getFirstChild();
- Node rChild = lChild.getNext();
- int lType = rewriteForNumberVariables(lChild);
- int rType = rewriteForNumberVariables(rChild);
-
-
- if (convertParameter(lChild)) {
- if (convertParameter(rChild)) {
- return NoType;
- }
- else {
- if (rType == NumberType) {
- n.putIntProp(Node.ISNUMBER_PROP, Node.RIGHT);
- }
- }
- }
- else {
- if (convertParameter(rChild)) {
- if (lType == NumberType) {
- n.putIntProp(Node.ISNUMBER_PROP, Node.LEFT);
- }
- }
- else {
- if (lType == NumberType) {
- if (rType == NumberType) {
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- return NumberType;
- }
- else {
- n.putIntProp(Node.ISNUMBER_PROP, Node.LEFT);
- }
- }
- else {
- if (rType == NumberType) {
- n.putIntProp(Node.ISNUMBER_PROP,
- Node.RIGHT);
- }
- }
- }
- }
- return NoType;
- }
-
- case Token.BITXOR :
- case Token.BITOR :
- case Token.BITAND :
- case Token.RSH :
- case Token.LSH :
- case Token.SUB :
- case Token.MUL :
- case Token.DIV :
- case Token.MOD : {
- Node lChild = n.getFirstChild();
- Node rChild = lChild.getNext();
- int lType = rewriteForNumberVariables(lChild);
- int rType = rewriteForNumberVariables(rChild);
- markDCPNumberContext(lChild);
- markDCPNumberContext(rChild);
- if (lType == NumberType) {
- if (rType == NumberType) {
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- return NumberType;
- }
- else {
- if (!convertParameter(rChild)) {
- n.removeChild(rChild);
- n.addChildToBack(
- new Node(Token.TO_DOUBLE, rChild));
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- }
- return NumberType;
- }
- }
- else {
- if (rType == NumberType) {
- if (!convertParameter(lChild)) {
- n.removeChild(lChild);
- n.addChildToFront(
- new Node(Token.TO_DOUBLE, lChild));
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- }
- return NumberType;
- }
- else {
- if (!convertParameter(lChild)) {
- n.removeChild(lChild);
- n.addChildToFront(
- new Node(Token.TO_DOUBLE, lChild));
- }
- if (!convertParameter(rChild)) {
- n.removeChild(rChild);
- n.addChildToBack(
- new Node(Token.TO_DOUBLE, rChild));
- }
- n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
- return NumberType;
- }
- }
- }
- case Token.SETELEM :
- case Token.SETELEM_OP : {
- Node arrayBase = n.getFirstChild();
- Node arrayIndex = arrayBase.getNext();
- Node rValue = arrayIndex.getNext();
- int baseType = rewriteForNumberVariables(arrayBase);
- if (baseType == NumberType) {// can never happen ???
- if (!convertParameter(arrayBase)) {
- n.removeChild(arrayBase);
- n.addChildToFront(
- new Node(Token.TO_OBJECT, arrayBase));
- }
- }
- int indexType = rewriteForNumberVariables(arrayIndex);
- if (indexType == NumberType) {
- // setting the ISNUMBER_PROP signals the codegen
- // to use the OptRuntime.setObjectIndex that takes
- // a double index
- n.putIntProp(Node.ISNUMBER_PROP, Node.LEFT);
- markDCPNumberContext(arrayIndex);
- }
- int rValueType = rewriteForNumberVariables(rValue);
- if (rValueType == NumberType) {
- if (!convertParameter(rValue)) {
- n.removeChild(rValue);
- n.addChildToBack(
- new Node(Token.TO_OBJECT, rValue));
- }
- }
- return NoType;
- }
- case Token.GETELEM : {
- Node arrayBase = n.getFirstChild();
- Node arrayIndex = arrayBase.getNext();
- int baseType = rewriteForNumberVariables(arrayBase);
- if (baseType == NumberType) {// can never happen ???
- if (!convertParameter(arrayBase)) {
- n.removeChild(arrayBase);
- n.addChildToFront(
- new Node(Token.TO_OBJECT, arrayBase));
- }
- }
- int indexType = rewriteForNumberVariables(arrayIndex);
- if (indexType == NumberType) {
- if (!convertParameter(arrayIndex)) {
- // setting the ISNUMBER_PROP signals the codegen
- // to use the OptRuntime.getObjectIndex that takes
- // a double index
- n.putIntProp(Node.ISNUMBER_PROP, Node.RIGHT);
- }
- }
- return NoType;
- }
- case Token.CALL :
- {
- Node child = n.getFirstChild(); // the function node
- if (child.getType() == Token.GETELEM) {
- // Optimization of x[0]() is not supported
- // so bypass GETELEM optimization that
- // rewriteForNumberVariables would trigger
- rewriteAsObjectChildren(child, child.getFirstChild());
- } else {
- rewriteForNumberVariables(child);
- }
- child = child.getNext(); // the first arg
-
- OptFunctionNode target
- = (OptFunctionNode)n.getProp(Node.DIRECTCALL_PROP);
- if (target != null) {
-/*
- we leave each child as a Number if it can be. The codegen will
- handle moving the pairs of parameters.
-*/
- while (child != null) {
- int type = rewriteForNumberVariables(child);
- if (type == NumberType) {
- markDCPNumberContext(child);
- }
- child = child.getNext();
- }
- } else {
- rewriteAsObjectChildren(n, child);
- }
- return NoType;
- }
- default : {
- rewriteAsObjectChildren(n, n.getFirstChild());
- return NoType;
- }
- }
- }
-
- private void rewriteAsObjectChildren(Node n, Node child)
- {
- // Force optimized children to be objects
- while (child != null) {
- Node nextChild = child.getNext();
- int type = rewriteForNumberVariables(child);
- if (type == NumberType) {
- if (!convertParameter(child)) {
- n.removeChild(child);
- Node nuChild = new Node(Token.TO_OBJECT, child);
- if (nextChild == null)
- n.addChildToBack(nuChild);
- else
- n.addChildBefore(nuChild, nextChild);
- }
- }
- child = nextChild;
- }
- }
-
- private static void buildStatementList_r(Node node, ObjArray statements)
- {
- int type = node.getType();
- if (type == Token.BLOCK
- || type == Token.LOCAL_BLOCK
- || type == Token.LOOP
- || type == Token.FUNCTION)
- {
- Node child = node.getFirstChild();
- while (child != null) {
- buildStatementList_r(child, statements);
- child = child.getNext();
- }
- } else {
- statements.add(node);
- }
- }
-
- private boolean inDirectCallFunction;
- OptFunctionNode theFunction;
- private boolean parameterUsedInNumberContext;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExp.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExp.java
deleted file mode 100644
index a893841..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExp.java
+++ /dev/null
@@ -1,2782 +0,0 @@
-/* -*- 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, 1998.
- *
- * 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
- * Brendan Eich
- * Matthias Radestock
- *
- * 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.regexp;
-
-import java.io.Serializable;
-
-import org.mozilla.javascript.Context;
-import org.mozilla.javascript.Function;
-import org.mozilla.javascript.IdFunctionObject;
-import org.mozilla.javascript.IdScriptableObject;
-import org.mozilla.javascript.Kit;
-import org.mozilla.javascript.ScriptRuntime;
-import org.mozilla.javascript.Scriptable;
-import org.mozilla.javascript.ScriptableObject;
-import org.mozilla.javascript.Undefined;
-
-/**
- * This class implements the RegExp native object.
- *
- * Revision History:
- * Implementation in C by Brendan Eich
- * Initial port to Java by Norris Boyd from jsregexp.c version 1.36
- * Merged up to version 1.38, which included Unicode support.
- * Merged bug fixes in version 1.39.
- * Merged JSFUN13_BRANCH changes up to 1.32.2.13
- *
- * @author Brendan Eich
- * @author Norris Boyd
- */
-
-
-
-public class NativeRegExp extends IdScriptableObject implements Function
-{
- static final long serialVersionUID = 4965263491464903264L;
-
- 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
- public static final int JSREG_MULTILINE = 0x4; // 'm' flag: multiline
-
- //type of match to perform
- public static final int TEST = 0;
- public static final int MATCH = 1;
- public static final int PREFIX = 2;
-
- private static final boolean debug = false;
-
- private static final byte REOP_EMPTY = 0; /* match rest of input against rest of r.e. */
- private static final byte REOP_ALT = 1; /* alternative subexpressions in kid and next */
- private static final byte REOP_BOL = 2; /* beginning of input (or line if multiline) */
- private static final byte REOP_EOL = 3; /* end of input (or line if multiline) */
- private static final byte REOP_WBDRY = 4; /* match "" at word boundary */
- private static final byte REOP_WNONBDRY = 5; /* match "" at word non-boundary */
- private static final byte REOP_QUANT = 6; /* quantified atom: atom{1,2} */
- private static final byte REOP_STAR = 7; /* zero or more occurrences of kid */
- private static final byte REOP_PLUS = 8; /* one or more occurrences of kid */
- private static final byte REOP_OPT = 9; /* optional subexpression in kid */
- private static final byte REOP_LPAREN = 10; /* left paren bytecode: kid is u.num'th sub-regexp */
- private static final byte REOP_RPAREN = 11; /* right paren bytecode */
- private static final byte REOP_DOT = 12; /* stands for any character */
-// private static final byte REOP_CCLASS = 13; /* character class: [a-f] */
- private static final byte REOP_DIGIT = 14; /* match a digit char: [0-9] */
- private static final byte REOP_NONDIGIT = 15; /* match a non-digit char: [^0-9] */
- private static final byte REOP_ALNUM = 16; /* match an alphanumeric char: [0-9a-z_A-Z] */
- private static final byte REOP_NONALNUM = 17; /* match a non-alphanumeric char: [^0-9a-z_A-Z] */
- private static final byte REOP_SPACE = 18; /* match a whitespace char */
- private static final byte REOP_NONSPACE = 19; /* match a non-whitespace char */
- private static final byte REOP_BACKREF = 20; /* back-reference (e.g., \1) to a parenthetical */
- private static final byte REOP_FLAT = 21; /* match a flat string */
- private static final byte REOP_FLAT1 = 22; /* match a single char */
- private static final byte REOP_JUMP = 23; /* for deoptimized closure loops */
-// private static final byte REOP_DOTSTAR = 24; /* optimize .* to use a single opcode */
-// private static final byte REOP_ANCHOR = 25; /* like .* but skips left context to unanchored r.e. */
-// private static final byte REOP_EOLONLY = 26; /* $ not preceded by any pattern */
-// private static final byte REOP_UCFLAT = 27; /* flat Unicode string; len immediate counts chars */
- private static final byte REOP_UCFLAT1 = 28; /* single Unicode char */
-// private static final byte REOP_UCCLASS = 29; /* Unicode character class, vector of chars to match */
-// private static final byte REOP_NUCCLASS = 30; /* negated Unicode character class */
-// private static final byte REOP_BACKREFi = 31; /* case-independent REOP_BACKREF */
- private static final byte REOP_FLATi = 32; /* case-independent REOP_FLAT */
- private static final byte REOP_FLAT1i = 33; /* case-independent REOP_FLAT1 */
-// private static final byte REOP_UCFLATi = 34; /* case-independent REOP_UCFLAT */
- private static final byte REOP_UCFLAT1i = 35; /* case-independent REOP_UCFLAT1 */
-// private static final byte REOP_ANCHOR1 = 36; /* first-char discriminating REOP_ANCHOR */
-// private static final byte REOP_NCCLASS = 37; /* negated 8-bit character class */
-// private static final byte REOP_DOTSTARMIN = 38; /* ungreedy version of REOP_DOTSTAR */
-// private static final byte REOP_LPARENNON = 39; /* non-capturing version of REOP_LPAREN */
-// private static final byte REOP_RPARENNON = 40; /* non-capturing version of REOP_RPAREN */
- private static final byte REOP_ASSERT = 41; /* zero width positive lookahead assertion */
- private static final byte REOP_ASSERT_NOT = 42; /* zero width negative lookahead assertion */
- private static final byte REOP_ASSERTTEST = 43; /* sentinel at end of assertion child */
- private static final byte REOP_ASSERTNOTTEST = 44; /* sentinel at end of !assertion child */
- private static final byte REOP_MINIMALSTAR = 45; /* non-greedy version of * */
- private static final byte REOP_MINIMALPLUS = 46; /* non-greedy version of + */
- private static final byte REOP_MINIMALOPT = 47; /* non-greedy version of ? */
- private static final byte REOP_MINIMALQUANT = 48; /* non-greedy version of {} */
- private static final byte REOP_ENDCHILD = 49; /* sentinel at end of quantifier child */
- private static final byte REOP_CLASS = 50; /* character class with index */
- private static final byte REOP_REPEAT = 51; /* directs execution of greedy quantifier */
- private static final byte REOP_MINIMALREPEAT = 52; /* directs execution of non-greedy quantifier */
- private static final byte REOP_END = 53;
-
-
-
- public static void init(Context cx, Scriptable scope, boolean sealed)
- {
-
- NativeRegExp proto = new NativeRegExp();
- proto.re = (RECompiled)compileRE(cx, "", null, false);
- proto.activatePrototypeMap(MAX_PROTOTYPE_ID);
- proto.setParentScope(scope);
- proto.setPrototype(getObjectPrototype(scope));
-
- NativeRegExpCtor ctor = new NativeRegExpCtor();
- // Bug #324006: ECMA-262 15.10.6.1 says "The initial value of
- // RegExp.prototype.constructor is the builtin RegExp constructor."
- proto.put("constructor", proto, ctor);
-
- ScriptRuntime.setFunctionProtoAndParent(ctor, scope);
-
- ctor.setImmunePrototypeProperty(proto);
-
- if (sealed) {
- proto.sealObject();
- ctor.sealObject();
- }
-
- defineProperty(scope, "RegExp", ctor, ScriptableObject.DONTENUM);
- }
-
- NativeRegExp(Scriptable scope, Object regexpCompiled)
- {
- this.re = (RECompiled)regexpCompiled;
- this.lastIndex = 0;
- ScriptRuntime.setObjectProtoAndParent(this, scope);
- }
-
- public String getClassName()
- {
- return "RegExp";
- }
-
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- return execSub(cx, scope, args, MATCH);
- }
-
- public Scriptable construct(Context cx, Scriptable scope, Object[] args)
- {
- return (Scriptable)execSub(cx, scope, args, MATCH);
- }
-
- Scriptable compile(Context cx, Scriptable scope, Object[] args)
- {
- if (args.length > 0 && args[0] instanceof NativeRegExp) {
- if (args.length > 1 && args[1] != Undefined.instance) {
- // report error
- throw ScriptRuntime.typeError0("msg.bad.regexp.compile");
- }
- NativeRegExp thatObj = (NativeRegExp) args[0];
- this.re = thatObj.re;
- this.lastIndex = thatObj.lastIndex;
- return this;
- }
- String s = args.length == 0 ? "" : ScriptRuntime.toString(args[0]);
- String global = args.length > 1 && args[1] != Undefined.instance
- ? ScriptRuntime.toString(args[1])
- : null;
- this.re = (RECompiled)compileRE(cx, s, global, false);
- this.lastIndex = 0;
- return this;
- }
-
- public String toString()
- {
- StringBuffer buf = new StringBuffer();
- buf.append('/');
- if (re.source.length != 0) {
- buf.append(re.source);
- } else {
- // See bugzilla 226045
- buf.append("(?:)");
- }
- buf.append('/');
- if ((re.flags & JSREG_GLOB) != 0)
- buf.append('g');
- if ((re.flags & JSREG_FOLD) != 0)
- buf.append('i');
- if ((re.flags & JSREG_MULTILINE) != 0)
- buf.append('m');
- return buf.toString();
- }
-
- NativeRegExp() { }
-
- private static RegExpImpl getImpl(Context cx)
- {
- return (RegExpImpl) ScriptRuntime.getRegExpProxy(cx);
- }
-
- private Object execSub(Context cx, Scriptable scopeObj,
- Object[] args, int matchType)
- {
- RegExpImpl reImpl = getImpl(cx);
- String str;
- if (args.length == 0) {
- str = reImpl.input;
- if (str == null) {
- reportError("msg.no.re.input.for", toString());
- }
- } else {
- str = ScriptRuntime.toString(args[0]);
- }
- double d = ((re.flags & JSREG_GLOB) != 0) ? lastIndex : 0;
-
- Object rval;
- if (d < 0 || str.length() < d) {
- lastIndex = 0;
- rval = null;
- }
- else {
- int indexp[] = { (int)d };
- rval = executeRegExp(cx, scopeObj, reImpl, str, indexp, matchType);
- if ((re.flags & JSREG_GLOB) != 0) {
- lastIndex = (rval == null || rval == Undefined.instance)
- ? 0 : indexp[0];
- }
- }
- return rval;
- }
-
- static Object compileRE(Context cx, String str, String global, boolean flat)
- {
- RECompiled regexp = new RECompiled();
- regexp.source = str.toCharArray();
- int length = str.length();
-
- int flags = 0;
- if (global != null) {
- for (int i = 0; i < global.length(); i++) {
- char c = global.charAt(i);
- if (c == 'g') {
- flags |= JSREG_GLOB;
- } else if (c == 'i') {
- flags |= JSREG_FOLD;
- } else if (c == 'm') {
- flags |= JSREG_MULTILINE;
- } else {
- reportError("msg.invalid.re.flag", String.valueOf(c));
- }
- }
- }
- regexp.flags = flags;
-
- CompilerState state = new CompilerState(cx, regexp.source, length, flags);
- if (flat && length > 0) {
-if (debug) {
-System.out.println("flat = \"" + str + "\"");
-}
- state.result = new RENode(REOP_FLAT);
- state.result.chr = state.cpbegin[0];
- state.result.length = length;
- state.result.flatIndex = 0;
- state.progLength += 5;
- }
- else
- if (!parseDisjunction(state))
- return null;
-
- regexp.program = new byte[state.progLength + 1];
- if (state.classCount != 0) {
- regexp.classList = new RECharSet[state.classCount];
- regexp.classCount = state.classCount;
- }
- int endPC = emitREBytecode(state, regexp, 0, state.result);
- regexp.program[endPC++] = REOP_END;
-
-if (debug) {
-System.out.println("Prog. length = " + endPC);
-for (int i = 0; i < endPC; i++) {
- System.out.print(regexp.program[i]);
- if (i < (endPC - 1)) System.out.print(", ");
-}
-System.out.println();
-}
- regexp.parenCount = state.parenCount;
-
- // If re starts with literal, init anchorCh accordingly
- switch (regexp.program[0]) {
- case REOP_UCFLAT1:
- case REOP_UCFLAT1i:
- regexp.anchorCh = (char)getIndex(regexp.program, 1);
- break;
- case REOP_FLAT1:
- case REOP_FLAT1i:
- regexp.anchorCh = (char)(regexp.program[1] & 0xFF);
- break;
- case REOP_FLAT:
- case REOP_FLATi:
- int k = getIndex(regexp.program, 1);
- regexp.anchorCh = regexp.source[k];
- break;
- }
-
-if (debug) {
-if (regexp.anchorCh >= 0) {
- System.out.println("Anchor ch = '" + (char)regexp.anchorCh + "'");
-}
-}
- return regexp;
- }
-
- static boolean isDigit(char c)
- {
- return '0' <= c && c <= '9';
- }
-
- private static boolean isWord(char c)
- {
- return Character.isLetter(c) || isDigit(c) || c == '_';
- }
-
- private static boolean isLineTerm(char c)
- {
- return ScriptRuntime.isJSLineTerminator(c);
- }
-
- private static boolean isREWhiteSpace(int c)
- {
- return (c == '\u0020' || c == '\u0009'
- || c == '\n' || c == '\r'
- || c == 0x2028 || c == 0x2029
- || c == '\u000C' || c == '\u000B'
- || c == '\u00A0'
- || Character.getType((char)c) == Character.SPACE_SEPARATOR);
- }
-
- /*
- *
- * 1. If IgnoreCase is false, return ch.
- * 2. Let u be ch converted to upper case as if by calling
- * String.prototype.toUpperCase on the one-character string ch.
- * 3. If u does not consist of a single character, return ch.
- * 4. Let cu be u's character.
- * 5. If ch's code point value is greater than or equal to decimal 128 and cu's
- * code point value is less than decimal 128, then return ch.
- * 6. Return cu.
- */
- private static char upcase(char ch)
- {
- if (ch < 128) {
- if ('a' <= ch && ch <= 'z') {
- return (char)(ch + ('A' - 'a'));
- }
- return ch;
- }
- char cu = Character.toUpperCase(ch);
- if ((ch >= 128) && (cu < 128)) return ch;
- return cu;
- }
-
- private static char downcase(char ch)
- {
- if (ch < 128) {
- if ('A' <= ch && ch <= 'Z') {
- return (char)(ch + ('a' - 'A'));
- }
- return ch;
- }
- char cl = Character.toLowerCase(ch);
- if ((ch >= 128) && (cl < 128)) return ch;
- return cl;
- }
-
-/*
- * Validates and converts hex ascii value.
- */
- private static int toASCIIHexDigit(int c)
- {
- if (c < '0')
- return -1;
- if (c <= '9') {
- return c - '0';
- }
- c |= 0x20;
- if ('a' <= c && c <= 'f') {
- return c - 'a' + 10;
- }
- return -1;
- }
-
-/*
- * Top-down regular expression grammar, based closely on Perl4.
- *
- * regexp: altern A regular expression is one or more
- * altern '|' regexp alternatives separated by vertical bar.
- */
- private static boolean parseDisjunction(CompilerState state)
- {
- if (!parseAlternative(state))
- return false;
- char[] source = state.cpbegin;
- int index = state.cp;
- if (index != source.length && source[index] == '|') {
- RENode altResult;
- ++state.cp;
- altResult = new RENode(REOP_ALT);
- altResult.kid = state.result;
- if (!parseDisjunction(state))
- return false;
- altResult.kid2 = state.result;
- state.result = altResult;
- /* ALT, <next>, ..., JUMP, <end> ... JUMP <end> */
- state.progLength += 9;
- }
- return true;
- }
-
-/*
- * altern: item An alternative is one or more items,
- * item altern concatenated together.
- */
- private static boolean parseAlternative(CompilerState state)
- {
- RENode headTerm = null;
- RENode tailTerm = null;
- char[] source = state.cpbegin;
- while (true) {
- if (state.cp == state.cpend || source[state.cp] == '|'
- || (state.parenNesting != 0 && source[state.cp] == ')'))
- {
- if (headTerm == null) {
- state.result = new RENode(REOP_EMPTY);
- }
- else
- state.result = headTerm;
- return true;
- }
- if (!parseTerm(state))
- return false;
- if (headTerm == null)
- headTerm = state.result;
- else {
- if (tailTerm == null) {
- headTerm.next = state.result;
- tailTerm = state.result;
- while (tailTerm.next != null) tailTerm = tailTerm.next;
- }
- else {
- tailTerm.next = state.result;
- tailTerm = tailTerm.next;
- while (tailTerm.next != null) tailTerm = tailTerm.next;
- }
- }
- }
- }
-
- /* calculate the total size of the bitmap required for a class expression */
- private static boolean
- calculateBitmapSize(CompilerState state, RENode target, char[] src,
- int index, int end)
- {
- char rangeStart = 0;
- char c;
- int n;
- int nDigits;
- int i;
- int max = 0;
- boolean inRange = false;
-
- target.bmsize = 0;
-
- if (index == end)
- return true;
-
- if (src[index] == '^')
- ++index;
-
- while (index != end) {
- int localMax = 0;
- nDigits = 2;
- switch (src[index]) {
- case '\\':
- ++index;
- c = src[index++];
- switch (c) {
- case 'b':
- localMax = 0x8;
- break;
- case 'f':
- localMax = 0xC;
- break;
- case 'n':
- localMax = 0xA;
- break;
- case 'r':
- localMax = 0xD;
- break;
- case 't':
- localMax = 0x9;
- break;
- case 'v':
- localMax = 0xB;
- break;
- case 'c':
- if (((index + 1) < end) && Character.isLetter(src[index + 1]))
- localMax = (char)(src[index++] & 0x1F);
- else
- localMax = '\\';
- break;
- case 'u':
- nDigits += 2;
- // fall thru...
- case 'x':
- n = 0;
- for (i = 0; (i < nDigits) && (index < end); i++) {
- c = src[index++];
- n = Kit.xDigitToInt(c, n);
- if (n < 0) {
- // Back off to accepting the original
- // '\' as a literal
- index -= (i + 1);
- n = '\\';
- break;
- }
- }
- localMax = n;
- break;
- case 'd':
- if (inRange) {
- reportError("msg.bad.range", "");
- return false;
- }
- localMax = '9';
- break;
- case 'D':
- case 's':
- case 'S':
- case 'w':
- case 'W':
- if (inRange) {
- reportError("msg.bad.range", "");
- return false;
- }
- target.bmsize = 65535;
- return true;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- /*
- * This is a non-ECMA extension - decimal escapes (in this
- * case, octal!) are supposed to be an error inside class
- * ranges, but supported here for backwards compatibility.
- *
- */
- n = (c - '0');
- c = src[index];
- if ('0' <= c && c <= '7') {
- index++;
- n = 8 * n + (c - '0');
- c = src[index];
- if ('0' <= c && c <= '7') {
- index++;
- i = 8 * n + (c - '0');
- if (i <= 0377)
- n = i;
- else
- index--;
- }
- }
- localMax = n;
- break;
-
- default:
- localMax = c;
- break;
- }
- break;
- default:
- localMax = src[index++];
- break;
- }
- if (inRange) {
- if (rangeStart > localMax) {
- reportError("msg.bad.range", "");
- return false;
- }
- inRange = false;
- }
- else {
- if (index < (end - 1)) {
- if (src[index] == '-') {
- ++index;
- inRange = true;
- rangeStart = (char)localMax;
- continue;
- }
- }
- }
- if ((state.flags & JSREG_FOLD) != 0){
- char cu = upcase((char)localMax);
- char cd = downcase((char)localMax);
- localMax = (cu >= cd) ? cu : cd;
- }
- if (localMax > max)
- max = localMax;
- }
- target.bmsize = max;
- return true;
- }
-
- /*
- * item: assertion An item is either an assertion or
- * quantatom a quantified atom.
- *
- * assertion: '^' Assertions match beginning of string
- * (or line if the class static property
- * RegExp.multiline is true).
- * '$' End of string (or line if the class
- * static property RegExp.multiline is
- * true).
- * '\b' Word boundary (between \w and \W).
- * '\B' Word non-boundary.
- *
- * quantatom: atom An unquantified atom.
- * quantatom '{' n ',' m '}'
- * Atom must occur between n and m times.
- * quantatom '{' n ',' '}' Atom must occur at least n times.
- * quantatom '{' n '}' Atom must occur exactly n times.
- * quantatom '*' Zero or more times (same as {0,}).
- * quantatom '+' One or more times (same as {1,}).
- * quantatom '?' Zero or one time (same as {0,1}).
- *
- * any of which can be optionally followed by '?' for ungreedy
- *
- * atom: '(' regexp ')' A parenthesized regexp (what matched
- * can be addressed using a backreference,
- * see '\' n below).
- * '.' Matches any char except '\n'.
- * '[' classlist ']' A character class.
- * '[' '^' classlist ']' A negated character class.
- * '\f' Form Feed.
- * '\n' Newline (Line Feed).
- * '\r' Carriage Return.
- * '\t' Horizontal Tab.
- * '\v' Vertical Tab.
- * '\d' A digit (same as [0-9]).
- * '\D' A non-digit.
- * '\w' A word character, [0-9a-z_A-Z].
- * '\W' A non-word character.
- * '\s' A whitespace character, [ \b\f\n\r\t\v].
- * '\S' A non-whitespace character.
- * '\' n A backreference to the nth (n decimal
- * and positive) parenthesized expression.
- * '\' octal An octal escape sequence (octal must be
- * two or three digits long, unless it is
- * 0 for the null character).
- * '\x' hex A hex escape (hex must be two digits).
- * '\c' ctrl A control character, ctrl is a letter.
- * '\' literalatomchar Any character except one of the above
- * that follow '\' in an atom.
- * otheratomchar Any character not first among the other
- * atom right-hand sides.
- */
-
- private static void doFlat(CompilerState state, char c)
- {
- state.result = new RENode(REOP_FLAT);
- state.result.chr = c;
- state.result.length = 1;
- state.result.flatIndex = -1;
- state.progLength += 3;
- }
-
- private static int
- getDecimalValue(char c, CompilerState state, int maxValue,
- String overflowMessageId)
- {
- boolean overflow = false;
- int start = state.cp;
- char[] src = state.cpbegin;
- int value = c - '0';
- for (; state.cp != state.cpend; ++state.cp) {
- c = src[state.cp];
- if (!isDigit(c)) {
- break;
- }
- if (!overflow) {
- int digit = c - '0';
- if (value < (maxValue - digit) / 10) {
- value = value * 10 + digit;
- } else {
- overflow = true;
- value = maxValue;
- }
- }
- }
- if (overflow) {
- reportError(overflowMessageId,
- String.valueOf(src, start, state.cp - start));
- }
- return value;
- }
-
- private static boolean
- parseTerm(CompilerState state)
- {
- char[] src = state.cpbegin;
- char c = src[state.cp++];
- int nDigits = 2;
- int parenBaseCount = state.parenCount;
- int num, tmp;
- RENode term;
- int termStart;
-
- switch (c) {
- /* assertions and atoms */
- case '^':
- state.result = new RENode(REOP_BOL);
- state.progLength++;
- return true;
- case '$':
- state.result = new RENode(REOP_EOL);
- state.progLength++;
- return true;
- case '\\':
- if (state.cp < state.cpend) {
- c = src[state.cp++];
- switch (c) {
- /* assertion escapes */
- case 'b' :
- state.result = new RENode(REOP_WBDRY);
- state.progLength++;
- return true;
- case 'B':
- state.result = new RENode(REOP_WNONBDRY);
- state.progLength++;
- return true;
- /* Decimal escape */
- case '0':
-/*
- * Under 'strict' ECMA 3, we interpret \0 as NUL and don't accept octal.
- * However, (XXX and since Rhino doesn't have a 'strict' mode) we'll just
- * behave the old way for compatibility reasons.
- * (see http://bugzilla.mozilla.org/show_bug.cgi?id=141078)
- *
- */
- reportWarning(state.cx, "msg.bad.backref", "");
- /* octal escape */
- num = 0;
- while (state.cp < state.cpend) {
- c = src[state.cp];
- if ((c >= '0') && (c <= '7')) {
- state.cp++;
- tmp = 8 * num + (c - '0');
- if (tmp > 0377)
- break;
- num = tmp;
- }
- else
- break;
- }
- c = (char)(num);
- doFlat(state, c);
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- termStart = state.cp - 1;
- num = getDecimalValue(c, state, 0xFFFF,
- "msg.overlarge.backref");
- if (num > state.parenCount)
- reportWarning(state.cx, "msg.bad.backref", "");
- /*
- * n > 9 or > count of parentheses,
- * then treat as octal instead.
- */
- if ((num > 9) && (num > state.parenCount)) {
- state.cp = termStart;
- num = 0;
- while (state.cp < state.cpend) {
- c = src[state.cp];
- if ((c >= '0') && (c <= '7')) {
- state.cp++;
- tmp = 8 * num + (c - '0');
- if (tmp > 0377)
- break;
- num = tmp;
- }
- else
- break;
- }
- c = (char)(num);
- doFlat(state, c);
- break;
- }
- /* otherwise, it's a back-reference */
- state.result = new RENode(REOP_BACKREF);
- state.result.parenIndex = num - 1;
- state.progLength += 3;
- break;
- /* Control escape */
- case 'f':
- c = 0xC;
- doFlat(state, c);
- break;
- case 'n':
- c = 0xA;
- doFlat(state, c);
- break;
- case 'r':
- c = 0xD;
- doFlat(state, c);
- break;
- case 't':
- c = 0x9;
- doFlat(state, c);
- break;
- case 'v':
- c = 0xB;
- doFlat(state, c);
- break;
- /* Control letter */
- case 'c':
- if (((state.cp + 1) < state.cpend) &&
- Character.isLetter(src[state.cp + 1]))
- c = (char)(src[state.cp++] & 0x1F);
- else {
- /* back off to accepting the original '\' as a literal */
- --state.cp;
- c = '\\';
- }
- doFlat(state, c);
- break;
- /* UnicodeEscapeSequence */
- case 'u':
- nDigits += 2;
- // fall thru...
- /* HexEscapeSequence */
- case 'x':
- {
- int n = 0;
- int i;
- for (i = 0; (i < nDigits)
- && (state.cp < state.cpend); i++) {
- c = src[state.cp++];
- n = Kit.xDigitToInt(c, n);
- if (n < 0) {
- // Back off to accepting the original
- // 'u' or 'x' as a literal
- state.cp -= (i + 2);
- n = src[state.cp++];
- break;
- }
- }
- c = (char)(n);
- }
- doFlat(state, c);
- break;
- /* Character class escapes */
- case 'd':
- state.result = new RENode(REOP_DIGIT);
- state.progLength++;
- break;
- case 'D':
- state.result = new RENode(REOP_NONDIGIT);
- state.progLength++;
- break;
- case 's':
- state.result = new RENode(REOP_SPACE);
- state.progLength++;
- break;
- case 'S':
- state.result = new RENode(REOP_NONSPACE);
- state.progLength++;
- break;
- case 'w':
- state.result = new RENode(REOP_ALNUM);
- state.progLength++;
- break;
- case 'W':
- state.result = new RENode(REOP_NONALNUM);
- state.progLength++;
- break;
- /* IdentityEscape */
- default:
- state.result = new RENode(REOP_FLAT);
- state.result.chr = c;
- state.result.length = 1;
- state.result.flatIndex = state.cp - 1;
- state.progLength += 3;
- break;
- }
- break;
- }
- else {
- /* a trailing '\' is an error */
- reportError("msg.trail.backslash", "");
- return false;
- }
- case '(': {
- RENode result = null;
- termStart = state.cp;
- if (state.cp + 1 < state.cpend && src[state.cp] == '?'
- && ((c = src[state.cp + 1]) == '=' || c == '!' || c == ':'))
- {
- state.cp += 2;
- if (c == '=') {
- result = new RENode(REOP_ASSERT);
- /* ASSERT, <next>, ... ASSERTTEST */
- state.progLength += 4;
- } else if (c == '!') {
- result = new RENode(REOP_ASSERT_NOT);
- /* ASSERTNOT, <next>, ... ASSERTNOTTEST */
- state.progLength += 4;
- }
- } else {
- result = new RENode(REOP_LPAREN);
- /* LPAREN, <index>, ... RPAREN, <index> */
- state.progLength += 6;
- result.parenIndex = state.parenCount++;
- }
- ++state.parenNesting;
- if (!parseDisjunction(state))
- return false;
- if (state.cp == state.cpend || src[state.cp] != ')') {
- reportError("msg.unterm.paren", "in regular expression"/*APPJET*/);
- return false;
- }
- ++state.cp;
- --state.parenNesting;
- if (result != null) {
- result.kid = state.result;
- state.result = result;
- }
- break;
- }
- case ')':
- reportError("msg.re.unmatched.right.paren", "");
- return false;
- case '[':
- state.result = new RENode(REOP_CLASS);
- termStart = state.cp;
- state.result.startIndex = termStart;
- while (true) {
- if (state.cp == state.cpend) {
- reportError("msg.unterm.class", "");
- return false;
- }
- if (src[state.cp] == '\\')
- state.cp++;
- else {
- if (src[state.cp] == ']') {
- state.result.kidlen = state.cp - termStart;
- break;
- }
- }
- state.cp++;
- }
- state.result.index = state.classCount++;
- /*
- * Call calculateBitmapSize now as we want any errors it finds
- * to be reported during the parse phase, not at execution.
- */
- if (!calculateBitmapSize(state, state.result, src, termStart, state.cp++))
- return false;
- state.progLength += 3; /* CLASS, <index> */
- break;
-
- case '.':
- state.result = new RENode(REOP_DOT);
- state.progLength++;
- break;
- case '*':
- case '+':
- case '?':
- reportError("msg.bad.quant", String.valueOf(src[state.cp - 1]));
- return false;
- default:
- state.result = new RENode(REOP_FLAT);
- state.result.chr = c;
- state.result.length = 1;
- state.result.flatIndex = state.cp - 1;
- state.progLength += 3;
- break;
- }
-
- term = state.result;
- if (state.cp == state.cpend) {
- return true;
- }
- boolean hasQ = false;
- switch (src[state.cp]) {
- case '+':
- state.result = new RENode(REOP_QUANT);
- state.result.min = 1;
- state.result.max = -1;
- /* <PLUS>, <parencount>, <parenindex>, <next> ... <ENDCHILD> */
- state.progLength += 8;
- hasQ = true;
- break;
- case '*':
- state.result = new RENode(REOP_QUANT);
- state.result.min = 0;
- state.result.max = -1;
- /* <STAR>, <parencount>, <parenindex>, <next> ... <ENDCHILD> */
- state.progLength += 8;
- hasQ = true;
- break;
- case '?':
- state.result = new RENode(REOP_QUANT);
- state.result.min = 0;
- state.result.max = 1;
- /* <OPT>, <parencount>, <parenindex>, <next> ... <ENDCHILD> */
- state.progLength += 8;
- hasQ = true;
- break;
- case '{': /* balance '}' */
- {
- int min = 0;
- int max = -1;
- int leftCurl = state.cp;
-
- /* For Perl etc. compatibility, if quntifier does not match
- * \{\d+(,\d*)?\} exactly back off from it
- * being a quantifier, and chew it up as a literal
- * atom next time instead.
- */
-
- c = src[++state.cp];
- if (isDigit(c)) {
- ++state.cp;
- min = getDecimalValue(c, state, 0xFFFF,
- "msg.overlarge.min");
- c = src[state.cp];
- if (c == ',') {
- c = src[++state.cp];
- if (isDigit(c)) {
- ++state.cp;
- max = getDecimalValue(c, state, 0xFFFF,
- "msg.overlarge.max");
- c = src[state.cp];
- if (min > max) {
- reportError("msg.max.lt.min",
- String.valueOf(src[state.cp]));
- return false;
- }
- }
- } else {
- max = min;
- }
- /* balance '{' */
- if (c == '}') {
- state.result = new RENode(REOP_QUANT);
- state.result.min = min;
- state.result.max = max;
- // QUANT, <min>, <max>, <parencount>,
- // <parenindex>, <next> ... <ENDCHILD>
- state.progLength += 12;
- hasQ = true;
- }
- }
- if (!hasQ) {
- state.cp = leftCurl;
- }
- break;
- }
- }
- if (!hasQ)
- return true;
-
- ++state.cp;
- state.result.kid = term;
- state.result.parenIndex = parenBaseCount;
- state.result.parenCount = state.parenCount - parenBaseCount;
- if ((state.cp < state.cpend) && (src[state.cp] == '?')) {
- ++state.cp;
- state.result.greedy = false;
- }
- else
- state.result.greedy = true;
- return true;
- }
-
- private static void resolveForwardJump(byte[] array, int from, int pc)
- {
- if (from > pc) throw Kit.codeBug();
- addIndex(array, from, pc - from);
- }
-
- private static int getOffset(byte[] array, int pc)
- {
- return getIndex(array, pc);
- }
-
- private static int addIndex(byte[] array, int pc, int index)
- {
- if (index < 0) throw Kit.codeBug();
- if (index > 0xFFFF)
- throw Context.reportRuntimeError("Too complex regexp");
- array[pc] = (byte)(index >> 8);
- array[pc + 1] = (byte)(index);
- return pc + 2;
- }
-
- private static int getIndex(byte[] array, int pc)
- {
- return ((array[pc] & 0xFF) << 8) | (array[pc + 1] & 0xFF);
- }
-
- private static final int OFFSET_LEN = 2;
- private static final int INDEX_LEN = 2;
-
- private static int
- emitREBytecode(CompilerState state, RECompiled re, int pc, RENode t)
- {
- RENode nextAlt;
- int nextAltFixup, nextTermFixup;
- byte[] program = re.program;
-
- while (t != null) {
- program[pc++] = t.op;
- switch (t.op) {
- case REOP_EMPTY:
- --pc;
- break;
- case REOP_ALT:
- nextAlt = t.kid2;
- nextAltFixup = pc; /* address of next alternate */
- pc += OFFSET_LEN;
- pc = emitREBytecode(state, re, pc, t.kid);
- program[pc++] = REOP_JUMP;
- nextTermFixup = pc; /* address of following term */
- pc += OFFSET_LEN;
- resolveForwardJump(program, nextAltFixup, pc);
- pc = emitREBytecode(state, re, pc, nextAlt);
-
- program[pc++] = REOP_JUMP;
- nextAltFixup = pc;
- pc += OFFSET_LEN;
-
- resolveForwardJump(program, nextTermFixup, pc);
- resolveForwardJump(program, nextAltFixup, pc);
- break;
- case REOP_FLAT:
- /*
- * Consecutize FLAT's if possible.
- */
- if (t.flatIndex != -1) {
- while ((t.next != null) && (t.next.op == REOP_FLAT)
- && ((t.flatIndex + t.length)
- == t.next.flatIndex)) {
- t.length += t.next.length;
- t.next = t.next.next;
- }
- }
- if ((t.flatIndex != -1) && (t.length > 1)) {
- if ((state.flags & JSREG_FOLD) != 0)
- program[pc - 1] = REOP_FLATi;
- else
- program[pc - 1] = REOP_FLAT;
- pc = addIndex(program, pc, t.flatIndex);
- pc = addIndex(program, pc, t.length);
- }
- else {
- if (t.chr < 256) {
- if ((state.flags & JSREG_FOLD) != 0)
- program[pc - 1] = REOP_FLAT1i;
- else
- program[pc - 1] = REOP_FLAT1;
- program[pc++] = (byte)(t.chr);
- }
- else {
- if ((state.flags & JSREG_FOLD) != 0)
- program[pc - 1] = REOP_UCFLAT1i;
- else
- program[pc - 1] = REOP_UCFLAT1;
- pc = addIndex(program, pc, t.chr);
- }
- }
- break;
- case REOP_LPAREN:
- pc = addIndex(program, pc, t.parenIndex);
- pc = emitREBytecode(state, re, pc, t.kid);
- program[pc++] = REOP_RPAREN;
- pc = addIndex(program, pc, t.parenIndex);
- break;
- case REOP_BACKREF:
- pc = addIndex(program, pc, t.parenIndex);
- break;
- case REOP_ASSERT:
- nextTermFixup = pc;
- pc += OFFSET_LEN;
- pc = emitREBytecode(state, re, pc, t.kid);
- program[pc++] = REOP_ASSERTTEST;
- resolveForwardJump(program, nextTermFixup, pc);
- break;
- case REOP_ASSERT_NOT:
- nextTermFixup = pc;
- pc += OFFSET_LEN;
- pc = emitREBytecode(state, re, pc, t.kid);
- program[pc++] = REOP_ASSERTNOTTEST;
- resolveForwardJump(program, nextTermFixup, pc);
- break;
- case REOP_QUANT:
- if ((t.min == 0) && (t.max == -1))
- program[pc - 1] = (t.greedy) ? REOP_STAR : REOP_MINIMALSTAR;
- else
- if ((t.min == 0) && (t.max == 1))
- program[pc - 1] = (t.greedy) ? REOP_OPT : REOP_MINIMALOPT;
- else
- if ((t.min == 1) && (t.max == -1))
- program[pc - 1] = (t.greedy) ? REOP_PLUS : REOP_MINIMALPLUS;
- else {
- if (!t.greedy) program[pc - 1] = REOP_MINIMALQUANT;
- pc = addIndex(program, pc, t.min);
- // max can be -1 which addIndex does not accept
- pc = addIndex(program, pc, t.max + 1);
- }
- pc = addIndex(program, pc, t.parenCount);
- pc = addIndex(program, pc, t.parenIndex);
- nextTermFixup = pc;
- pc += OFFSET_LEN;
- pc = emitREBytecode(state, re, pc, t.kid);
- program[pc++] = REOP_ENDCHILD;
- resolveForwardJump(program, nextTermFixup, pc);
- break;
- case REOP_CLASS:
- pc = addIndex(program, pc, t.index);
- re.classList[t.index] = new RECharSet(t.bmsize, t.startIndex,
- t.kidlen);
- break;
- default:
- break;
- }
- t = t.next;
- }
- return pc;
- }
-
- private static void
- pushProgState(REGlobalData gData, int min, int max,
- REBackTrackData backTrackLastToSave,
- int continuation_pc, int continuation_op)
- {
- gData.stateStackTop = new REProgState(gData.stateStackTop, min, max,
- gData.cp, backTrackLastToSave,
- continuation_pc,
- continuation_op);
- }
-
- private static REProgState
- popProgState(REGlobalData gData)
- {
- REProgState state = gData.stateStackTop;
- gData.stateStackTop = state.previous;
- return state;
- }
-
- private static void
- pushBackTrackState(REGlobalData gData, byte op, int target)
- {
- gData.backTrackStackTop = new REBackTrackData(gData, op, target);
- }
-
- /*
- * Consecutive literal characters.
- */
- private static boolean
- flatNMatcher(REGlobalData gData, int matchChars,
- int length, char[] chars, int end)
- {
- if ((gData.cp + length) > end)
- return false;
- for (int i = 0; i < length; i++) {
- if (gData.regexp.source[matchChars + i] != chars[gData.cp + i]) {
- return false;
- }
- }
- gData.cp += length;
- return true;
- }
-
- private static boolean
- flatNIMatcher(REGlobalData gData, int matchChars,
- int length, char[] chars, int end)
- {
- if ((gData.cp + length) > end)
- return false;
- for (int i = 0; i < length; i++) {
- if (upcase(gData.regexp.source[matchChars + i])
- != upcase(chars[gData.cp + i]))
- {
- return false;
- }
- }
- gData.cp += length;
- return true;
- }
-
- /*
- 1. Evaluate DecimalEscape to obtain an EscapeValue E.
- 2. If E is not a character then go to step 6.
- 3. Let ch be E's character.
- 4. Let A be a one-element RECharSet containing the character ch.
- 5. Call CharacterSetMatcher(A, false) and return its Matcher result.
- 6. E must be an integer. Let n be that integer.
- 7. If n=0 or n>NCapturingParens then throw a SyntaxError exception.
- 8. Return an internal Matcher closure that takes two arguments, a State x
- and a Continuation c, and performs the following:
- 1. Let cap be x's captures internal array.
- 2. Let s be cap[n].
- 3. If s is undefined, then call c(x) and return its result.
- 4. Let e be x's endIndex.
- 5. Let len be s's length.
- 6. Let f be e+len.
- 7. If f>InputLength, return failure.
- 8. If there exists an integer i between 0 (inclusive) and len (exclusive)
- such that Canonicalize(s[i]) is not the same character as
- Canonicalize(Input [e+i]), then return failure.
- 9. Let y be the State (f, cap).
- 10. Call c(y) and return its result.
- */
- private static boolean
- backrefMatcher(REGlobalData gData, int parenIndex,
- char[] chars, int end)
- {
- int len;
- int i;
- int parenContent = gData.parens_index(parenIndex);
- if (parenContent == -1)
- return true;
-
- len = gData.parens_length(parenIndex);
- if ((gData.cp + len) > end)
- return false;
-
- if ((gData.regexp.flags & JSREG_FOLD) != 0) {
- for (i = 0; i < len; i++) {
- if (upcase(chars[parenContent + i]) != upcase(chars[gData.cp + i]))
- return false;
- }
- }
- else {
- for (i = 0; i < len; i++) {
- if (chars[parenContent + i] != chars[gData.cp + i])
- return false;
- }
- }
- gData.cp += len;
- return true;
- }
-
-
- /* Add a single character to the RECharSet */
- private static void
- addCharacterToCharSet(RECharSet cs, char c)
- {
- int byteIndex = (c / 8);
- if (c > cs.length)
- throw new RuntimeException();
- cs.bits[byteIndex] |= 1 << (c & 0x7);
- }
-
-
- /* Add a character range, c1 to c2 (inclusive) to the RECharSet */
- private static void
- addCharacterRangeToCharSet(RECharSet cs, char c1, char c2)
- {
- int i;
-
- int byteIndex1 = (c1 / 8);
- int byteIndex2 = (c2 / 8);
-
- if ((c2 > cs.length) || (c1 > c2))
- throw new RuntimeException();
-
- c1 &= 0x7;
- c2 &= 0x7;
-
- if (byteIndex1 == byteIndex2) {
- cs.bits[byteIndex1] |= ((0xFF) >> (7 - (c2 - c1))) << c1;
- }
- else {
- cs.bits[byteIndex1] |= 0xFF << c1;
- for (i = byteIndex1 + 1; i < byteIndex2; i++)
- cs.bits[i] = (byte)0xFF;
- cs.bits[byteIndex2] |= (0xFF) >> (7 - c2);
- }
- }
-
- /* Compile the source of the class into a RECharSet */
- private static void
- processCharSet(REGlobalData gData, RECharSet charSet)
- {
- synchronized (charSet) {
- if (!charSet.converted) {
- processCharSetImpl(gData, charSet);
- charSet.converted = true;
- }
- }
- }
-
-
- private static void
- processCharSetImpl(REGlobalData gData, RECharSet charSet)
- {
- int src = charSet.startIndex;
- int end = src + charSet.strlength;
-
- char rangeStart = 0, thisCh;
- int byteLength;
- char c;
- int n;
- int nDigits;
- int i;
- boolean inRange = false;
-
- charSet.sense = true;
- byteLength = (charSet.length / 8) + 1;
- charSet.bits = new byte[byteLength];
-
- if (src == end)
- return;
-
- if (gData.regexp.source[src] == '^') {
- charSet.sense = false;
- ++src;
- }
-
- while (src != end) {
- nDigits = 2;
- switch (gData.regexp.source[src]) {
- case '\\':
- ++src;
- c = gData.regexp.source[src++];
- switch (c) {
- case 'b':
- thisCh = 0x8;
- break;
- case 'f':
- thisCh = 0xC;
- break;
- case 'n':
- thisCh = 0xA;
- break;
- case 'r':
- thisCh = 0xD;
- break;
- case 't':
- thisCh = 0x9;
- break;
- case 'v':
- thisCh = 0xB;
- break;
- case 'c':
- if (((src + 1) < end) && isWord(gData.regexp.source[src + 1]))
- thisCh = (char)(gData.regexp.source[src++] & 0x1F);
- else {
- --src;
- thisCh = '\\';
- }
- break;
- case 'u':
- nDigits += 2;
- // fall thru
- case 'x':
- n = 0;
- for (i = 0; (i < nDigits) && (src < end); i++) {
- c = gData.regexp.source[src++];
- int digit = toASCIIHexDigit(c);
- if (digit < 0) {
- /* back off to accepting the original '\'
- * as a literal
- */
- src -= (i + 1);
- n = '\\';
- break;
- }
- n = (n << 4) | digit;
- }
- thisCh = (char)(n);
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- /*
- * This is a non-ECMA extension - decimal escapes (in this
- * case, octal!) are supposed to be an error inside class
- * ranges, but supported here for backwards compatibility.
- *
- */
- n = (c - '0');
- c = gData.regexp.source[src];
- if ('0' <= c && c <= '7') {
- src++;
- n = 8 * n + (c - '0');
- c = gData.regexp.source[src];
- if ('0' <= c && c <= '7') {
- src++;
- i = 8 * n + (c - '0');
- if (i <= 0377)
- n = i;
- else
- src--;
- }
- }
- thisCh = (char)(n);
- break;
-
- case 'd':
- addCharacterRangeToCharSet(charSet, '0', '9');
- continue; /* don't need range processing */
- case 'D':
- addCharacterRangeToCharSet(charSet, (char)0, (char)('0' - 1));
- addCharacterRangeToCharSet(charSet, (char)('9' + 1),
- (char)(charSet.length));
- continue;
- case 's':
- for (i = charSet.length; i >= 0; i--)
- if (isREWhiteSpace(i))
- addCharacterToCharSet(charSet, (char)(i));
- continue;
- case 'S':
- for (i = charSet.length; i >= 0; i--)
- if (!isREWhiteSpace(i))
- addCharacterToCharSet(charSet, (char)(i));
- continue;
- case 'w':
- for (i = charSet.length; i >= 0; i--)
- if (isWord((char)i))
- addCharacterToCharSet(charSet, (char)(i));
- continue;
- case 'W':
- for (i = charSet.length; i >= 0; i--)
- if (!isWord((char)i))
- addCharacterToCharSet(charSet, (char)(i));
- continue;
- default:
- thisCh = c;
- break;
-
- }
- break;
-
- default:
- thisCh = gData.regexp.source[src++];
- break;
-
- }
- if (inRange) {
- if ((gData.regexp.flags & JSREG_FOLD) != 0) {
- addCharacterRangeToCharSet(charSet,
- upcase(rangeStart),
- upcase(thisCh));
- addCharacterRangeToCharSet(charSet,
- downcase(rangeStart),
- downcase(thisCh));
- } else {
- addCharacterRangeToCharSet(charSet, rangeStart, thisCh);
- }
- inRange = false;
- }
- else {
- if ((gData.regexp.flags & JSREG_FOLD) != 0) {
- addCharacterToCharSet(charSet, upcase(thisCh));
- addCharacterToCharSet(charSet, downcase(thisCh));
- } else {
- addCharacterToCharSet(charSet, thisCh);
- }
- if (src < (end - 1)) {
- if (gData.regexp.source[src] == '-') {
- ++src;
- inRange = true;
- rangeStart = thisCh;
- }
- }
- }
- }
- }
-
-
- /*
- * Initialize the character set if it this is the first call.
- * Test the bit - if the ^ flag was specified, non-inclusion is a success
- */
- private static boolean
- classMatcher(REGlobalData gData, RECharSet charSet, char ch)
- {
- if (!charSet.converted) {
- processCharSet(gData, charSet);
- }
-
- int byteIndex = ch / 8;
- if (charSet.sense) {
- if ((charSet.length == 0) ||
- ( (ch > charSet.length)
- || ((charSet.bits[byteIndex] & (1 << (ch & 0x7))) == 0) ))
- return false;
- } else {
- if (! ((charSet.length == 0) ||
- ( (ch > charSet.length)
- || ((charSet.bits[byteIndex] & (1 << (ch & 0x7))) == 0) )))
- return false;
- }
- return true;
- }
-
- private static boolean
- executeREBytecode(REGlobalData gData, char[] chars, int end)
- {
- int pc = 0;
- byte program[] = gData.regexp.program;
- int currentContinuation_op;
- int currentContinuation_pc;
- boolean result = false;
-
- currentContinuation_pc = 0;
- currentContinuation_op = REOP_END;
-if (debug) {
-System.out.println("Input = \"" + new String(chars) + "\", start at " + gData.cp);
-}
- int op = program[pc++];
- for (;;) {
-if (debug) {
-System.out.println("Testing at " + gData.cp + ", op = " + op);
-}
- switch (op) {
- case REOP_EMPTY:
- result = true;
- break;
- case REOP_BOL:
- if (gData.cp != 0) {
- if (gData.multiline ||
- ((gData.regexp.flags & JSREG_MULTILINE) != 0)) {
- if (!isLineTerm(chars[gData.cp - 1])) {
- result = false;
- break;
- }
- }
- else {
- result = false;
- break;
- }
- }
- result = true;
- break;
- case REOP_EOL:
- if (gData.cp != end) {
- if (gData.multiline ||
- ((gData.regexp.flags & JSREG_MULTILINE) != 0)) {
- if (!isLineTerm(chars[gData.cp])) {
- result = false;
- break;
- }
- }
- else {
- result = false;
- break;
- }
- }
- result = true;
- break;
- case REOP_WBDRY:
- result = ((gData.cp == 0 || !isWord(chars[gData.cp - 1]))
- ^ !((gData.cp < end) && isWord(chars[gData.cp])));
- break;
- case REOP_WNONBDRY:
- result = ((gData.cp == 0 || !isWord(chars[gData.cp - 1]))
- ^ ((gData.cp < end) && isWord(chars[gData.cp])));
- break;
- case REOP_DOT:
- result = (gData.cp != end && !isLineTerm(chars[gData.cp]));
- if (result) {
- gData.cp++;
- }
- break;
- case REOP_DIGIT:
- result = (gData.cp != end && isDigit(chars[gData.cp]));
- if (result) {
- gData.cp++;
- }
- break;
- case REOP_NONDIGIT:
- result = (gData.cp != end && !isDigit(chars[gData.cp]));
- if (result) {
- gData.cp++;
- }
- break;
- case REOP_SPACE:
- result = (gData.cp != end && isREWhiteSpace(chars[gData.cp]));
- if (result) {
- gData.cp++;
- }
- break;
- case REOP_NONSPACE:
- result = (gData.cp != end && !isREWhiteSpace(chars[gData.cp]));
- if (result) {
- gData.cp++;
- }
- break;
- case REOP_ALNUM:
- result = (gData.cp != end && isWord(chars[gData.cp]));
- if (result) {
- gData.cp++;
- }
- break;
- case REOP_NONALNUM:
- result = (gData.cp != end && !isWord(chars[gData.cp]));
- if (result) {
- gData.cp++;
- }
- break;
- case REOP_FLAT:
- {
- int offset = getIndex(program, pc);
- pc += INDEX_LEN;
- int length = getIndex(program, pc);
- pc += INDEX_LEN;
- result = flatNMatcher(gData, offset, length, chars, end);
- }
- break;
- case REOP_FLATi:
- {
- int offset = getIndex(program, pc);
- pc += INDEX_LEN;
- int length = getIndex(program, pc);
- pc += INDEX_LEN;
- result = flatNIMatcher(gData, offset, length, chars, end);
- }
- break;
- case REOP_FLAT1:
- {
- char matchCh = (char)(program[pc++] & 0xFF);
- result = (gData.cp != end && chars[gData.cp] == matchCh);
- if (result) {
- gData.cp++;
- }
- }
- break;
- case REOP_FLAT1i:
- {
- char matchCh = (char)(program[pc++] & 0xFF);
- result = (gData.cp != end
- && upcase(chars[gData.cp]) == upcase(matchCh));
- if (result) {
- gData.cp++;
- }
- }
- break;
- case REOP_UCFLAT1:
- {
- char matchCh = (char)getIndex(program, pc);
- pc += INDEX_LEN;
- result = (gData.cp != end && chars[gData.cp] == matchCh);
- if (result) {
- gData.cp++;
- }
- }
- break;
- case REOP_UCFLAT1i:
- {
- char matchCh = (char)getIndex(program, pc);
- pc += INDEX_LEN;
- result = (gData.cp != end
- && upcase(chars[gData.cp]) == upcase(matchCh));
- if (result) {
- gData.cp++;
- }
- }
- break;
- case REOP_ALT:
- {
- int nextpc;
- byte nextop;
- pushProgState(gData, 0, 0, null,
- currentContinuation_pc,
- currentContinuation_op);
- nextpc = pc + getOffset(program, pc);
- nextop = program[nextpc++];
- pushBackTrackState(gData, nextop, nextpc);
- pc += INDEX_LEN;
- op = program[pc++];
- }
- continue;
-
- case REOP_JUMP:
- {
- int offset;
- REProgState state = popProgState(gData);
- currentContinuation_pc = state.continuation_pc;
- currentContinuation_op = state.continuation_op;
- offset = getOffset(program, pc);
- pc += offset;
- op = program[pc++];
- }
- continue;
-
-
- case REOP_LPAREN:
- {
- int parenIndex = getIndex(program, pc);
- pc += INDEX_LEN;
- gData.set_parens(parenIndex, gData.cp, 0);
- op = program[pc++];
- }
- continue;
- case REOP_RPAREN:
- {
- int cap_index;
- int parenIndex = getIndex(program, pc);
- pc += INDEX_LEN;
- cap_index = gData.parens_index(parenIndex);
- gData.set_parens(parenIndex, cap_index,
- gData.cp - cap_index);
- if (parenIndex > gData.lastParen)
- gData.lastParen = parenIndex;
- op = program[pc++];
- }
- continue;
- case REOP_BACKREF:
- {
- int parenIndex = getIndex(program, pc);
- pc += INDEX_LEN;
- result = backrefMatcher(gData, parenIndex, chars, end);
- }
- break;
-
- case REOP_CLASS:
- {
- int index = getIndex(program, pc);
- pc += INDEX_LEN;
- if (gData.cp != end) {
- if (classMatcher(gData, gData.regexp.classList[index],
- chars[gData.cp]))
- {
- gData.cp++;
- result = true;
- break;
- }
- }
- result = false;
- }
- break;
-
- case REOP_ASSERT:
- case REOP_ASSERT_NOT:
- {
- byte testOp;
- pushProgState(gData, 0, 0, gData.backTrackStackTop,
- currentContinuation_pc,
- currentContinuation_op);
- if (op == REOP_ASSERT) {
- testOp = REOP_ASSERTTEST;
- } else {
- testOp = REOP_ASSERTNOTTEST;
- }
- pushBackTrackState(gData, testOp,
- pc + getOffset(program, pc));
- pc += INDEX_LEN;
- op = program[pc++];
- }
- continue;
-
- case REOP_ASSERTTEST:
- case REOP_ASSERTNOTTEST:
- {
- REProgState state = popProgState(gData);
- gData.cp = state.index;
- gData.backTrackStackTop = state.backTrack;
- currentContinuation_pc = state.continuation_pc;
- currentContinuation_op = state.continuation_op;
- if (result) {
- if (op == REOP_ASSERTTEST) {
- result = true;
- } else {
- result = false;
- }
- } else {
- if (op == REOP_ASSERTTEST) {
- // Do nothing
- } else {
- result = true;
- }
- }
- }
- break;
-
- case REOP_STAR:
- case REOP_PLUS:
- case REOP_OPT:
- case REOP_QUANT:
- case REOP_MINIMALSTAR:
- case REOP_MINIMALPLUS:
- case REOP_MINIMALOPT:
- case REOP_MINIMALQUANT:
- {
- int min, max;
- boolean greedy = false;
- switch (op) {
- case REOP_STAR:
- greedy = true;
- // fallthrough
- case REOP_MINIMALSTAR:
- min = 0;
- max = -1;
- break;
- case REOP_PLUS:
- greedy = true;
- // fallthrough
- case REOP_MINIMALPLUS:
- min = 1;
- max = -1;
- break;
- case REOP_OPT:
- greedy = true;
- // fallthrough
- case REOP_MINIMALOPT:
- min = 0;
- max = 1;
- break;
- case REOP_QUANT:
- greedy = true;
- // fallthrough
- case REOP_MINIMALQUANT:
- min = getOffset(program, pc);
- pc += INDEX_LEN;
- // See comments in emitREBytecode for " - 1" reason
- max = getOffset(program, pc) - 1;
- pc += INDEX_LEN;
- break;
- default:
- throw Kit.codeBug();
- }
- pushProgState(gData, min, max, null,
- currentContinuation_pc,
- currentContinuation_op);
- if (greedy) {
- currentContinuation_op = REOP_REPEAT;
- currentContinuation_pc = pc;
- pushBackTrackState(gData, REOP_REPEAT, pc);
- /* Step over <parencount>, <parenindex> & <next> */
- pc += 3 * INDEX_LEN;
- op = program[pc++];
- } else {
- if (min != 0) {
- currentContinuation_op = REOP_MINIMALREPEAT;
- currentContinuation_pc = pc;
- /* <parencount> <parenindex> & <next> */
- pc += 3 * INDEX_LEN;
- op = program[pc++];
- } else {
- pushBackTrackState(gData, REOP_MINIMALREPEAT, pc);
- popProgState(gData);
- pc += 2 * INDEX_LEN; // <parencount> & <parenindex>
- pc = pc + getOffset(program, pc);
- op = program[pc++];
- }
- }
- }
- continue;
-
- case REOP_ENDCHILD:
- // Use the current continuation.
- pc = currentContinuation_pc;
- op = currentContinuation_op;
- continue;
-
- case REOP_REPEAT:
- {
- REProgState state = popProgState(gData);
- if (!result) {
- //
- // There's been a failure, see if we have enough
- // children.
- //
- if (state.min == 0)
- result = true;
- currentContinuation_pc = state.continuation_pc;
- currentContinuation_op = state.continuation_op;
- pc += 2 * INDEX_LEN; /* <parencount> & <parenindex> */
- pc = pc + getOffset(program, pc);
- break;
- }
- else {
- if (state.min == 0 && gData.cp == state.index) {
- // matched an empty string, that'll get us nowhere
- result = false;
- currentContinuation_pc = state.continuation_pc;
- currentContinuation_op = state.continuation_op;
- pc += 2 * INDEX_LEN;
- pc = pc + getOffset(program, pc);
- break;
- }
- int new_min = state.min, new_max = state.max;
- if (new_min != 0) new_min--;
- if (new_max != -1) new_max--;
- if (new_max == 0) {
- result = true;
- currentContinuation_pc = state.continuation_pc;
- currentContinuation_op = state.continuation_op;
- pc += 2 * INDEX_LEN;
- pc = pc + getOffset(program, pc);
- break;
- }
- pushProgState(gData, new_min, new_max, null,
- state.continuation_pc,
- state.continuation_op);
- currentContinuation_op = REOP_REPEAT;
- currentContinuation_pc = pc;
- pushBackTrackState(gData, REOP_REPEAT, pc);
- int parenCount = getIndex(program, pc);
- pc += INDEX_LEN;
- int parenIndex = getIndex(program, pc);
- pc += 2 * INDEX_LEN;
- op = program[pc++];
- for (int k = 0; k < parenCount; k++) {
- gData.set_parens(parenIndex + k, -1, 0);
- }
- }
- }
- continue;
-
- case REOP_MINIMALREPEAT:
- {
- REProgState state = popProgState(gData);
- if (!result) {
- //
- // Non-greedy failure - try to consume another child.
- //
- if (state.max == -1 || state.max > 0) {
- pushProgState(gData, state.min, state.max, null,
- state.continuation_pc,
- state.continuation_op);
- currentContinuation_op = REOP_MINIMALREPEAT;
- currentContinuation_pc = pc;
- int parenCount = getIndex(program, pc);
- pc += INDEX_LEN;
- int parenIndex = getIndex(program, pc);
- pc += 2 * INDEX_LEN;
- for (int k = 0; k < parenCount; k++) {
- gData.set_parens(parenIndex + k, -1, 0);
- }
- op = program[pc++];
- continue;
- } else {
- // Don't need to adjust pc since we're going to pop.
- currentContinuation_pc = state.continuation_pc;
- currentContinuation_op = state.continuation_op;
- break;
- }
- } else {
- if (state.min == 0 && gData.cp == state.index) {
- // Matched an empty string, that'll get us nowhere.
- result = false;
- currentContinuation_pc = state.continuation_pc;
- currentContinuation_op = state.continuation_op;
- break;
- }
- int new_min = state.min, new_max = state.max;
- if (new_min != 0) new_min--;
- if (new_max != -1) new_max--;
- pushProgState(gData, new_min, new_max, null,
- state.continuation_pc,
- state.continuation_op);
- if (new_min != 0) {
- currentContinuation_op = REOP_MINIMALREPEAT;
- currentContinuation_pc = pc;
- int parenCount = getIndex(program, pc);
- pc += INDEX_LEN;
- int parenIndex = getIndex(program, pc);
- pc += 2 * INDEX_LEN;
- for (int k = 0; k < parenCount; k++) {
- gData.set_parens(parenIndex + k, -1, 0);
- }
- op = program[pc++];
- } else {
- currentContinuation_pc = state.continuation_pc;
- currentContinuation_op = state.continuation_op;
- pushBackTrackState(gData, REOP_MINIMALREPEAT, pc);
- popProgState(gData);
- pc += 2 * INDEX_LEN;
- pc = pc + getOffset(program, pc);
- op = program[pc++];
- }
- continue;
- }
- }
-
- case REOP_END:
- return true;
-
- default:
- throw Kit.codeBug();
-
- }
- /*
- * If the match failed and there's a backtrack option, take it.
- * Otherwise this is a complete and utter failure.
- */
- if (!result) {
- REBackTrackData backTrackData = gData.backTrackStackTop;
- if (backTrackData != null) {
- gData.backTrackStackTop = backTrackData.previous;
-
- gData.lastParen = backTrackData.lastParen;
-
- // XXX: If backTrackData will no longer be used, then
- // there is no need to clone backTrackData.parens
- if (backTrackData.parens != null) {
- gData.parens = backTrackData.parens.clone();
- }
-
- gData.cp = backTrackData.cp;
-
- gData.stateStackTop = backTrackData.stateStackTop;
-
- currentContinuation_op
- = gData.stateStackTop.continuation_op;
- currentContinuation_pc
- = gData.stateStackTop.continuation_pc;
- pc = backTrackData.continuation_pc;
- op = backTrackData.continuation_op;
- continue;
- }
- else
- return false;
- }
-
- op = program[pc++];
- }
-
- }
-
- private static boolean
- matchRegExp(REGlobalData gData, RECompiled re,
- char[] chars, int start, int end, boolean multiline)
- {
- if (re.parenCount != 0) {
- gData.parens = new long[re.parenCount];
- } else {
- gData.parens = null;
- }
-
- gData.backTrackStackTop = null;
-
- gData.stateStackTop = null;
-
- gData.multiline = multiline;
- gData.regexp = re;
- gData.lastParen = 0;
-
- int anchorCh = gData.regexp.anchorCh;
- //
- // have to include the position beyond the last character
- // in order to detect end-of-input/line condition
- //
- for (int i = start; i <= end; ++i) {
- //
- // If the first node is a literal match, step the index into
- // the string until that match is made, or fail if it can't be
- // found at all.
- //
- if (anchorCh >= 0) {
- for (;;) {
- if (i == end) {
- return false;
- }
- char matchCh = chars[i];
- if (matchCh == anchorCh ||
- ((gData.regexp.flags & JSREG_FOLD) != 0
- && upcase(matchCh) == upcase((char)anchorCh)))
- {
- break;
- }
- ++i;
- }
- }
- gData.cp = i;
- for (int j = 0; j < re.parenCount; j++) {
- gData.set_parens(j, -1, 0);
- }
- boolean result = executeREBytecode(gData, chars, end);
-
- gData.backTrackStackTop = null;
- gData.stateStackTop = null;
- if (result) {
- gData.skipped = i - start;
- return true;
- }
- }
- return false;
- }
-
- /*
- * indexp is assumed to be an array of length 1
- */
- Object executeRegExp(Context cx, Scriptable scopeObj, RegExpImpl res,
- String str, int indexp[], int matchType)
- {
- REGlobalData gData = new REGlobalData();
-
- int start = indexp[0];
- char[] charArray = str.toCharArray();
- int end = charArray.length;
- if (start > end)
- start = end;
- //
- // Call the recursive matcher to do the real work.
- //
- boolean matches = matchRegExp(gData, re, charArray, start, end,
- res.multiline);
- if (!matches) {
- if (matchType != PREFIX) return null;
- return Undefined.instance;
- }
- int index = gData.cp;
- int i = index;
- indexp[0] = i;
- int matchlen = i - (start + gData.skipped);
- int ep = index;
- index -= matchlen;
- Object result;
- Scriptable obj;
-
- if (matchType == TEST) {
- /*
- * Testing for a match and updating cx.regExpImpl: don't allocate
- * an array object, do return true.
- */
- result = Boolean.TRUE;
- obj = null;
- }
- else {
- /*
- * The array returned on match has element 0 bound to the matched
- * string, elements 1 through re.parenCount bound to the paren
- * matches, an index property telling the length of the left context,
- * and an input property referring to the input string.
- */
- Scriptable scope = getTopLevelScope(scopeObj);
- result = ScriptRuntime.newObject(cx, scope, "Array", null);
- obj = (Scriptable) result;
-
- String matchstr = new String(charArray, index, matchlen);
- obj.put(0, obj, matchstr);
- }
-
- if (re.parenCount == 0) {
- res.parens = null;
- res.lastParen = SubString.emptySubString;
- } else {
- SubString parsub = null;
- int num;
- res.parens = new SubString[re.parenCount];
- for (num = 0; num < re.parenCount; num++) {
- int cap_index = gData.parens_index(num);
- String parstr;
- if (cap_index != -1) {
- int cap_length = gData.parens_length(num);
- parsub = new SubString(charArray, cap_index, cap_length);
- res.parens[num] = parsub;
- if (matchType == TEST) continue;
- parstr = parsub.toString();
- obj.put(num+1, obj, parstr);
- }
- else {
- if (matchType != TEST)
- obj.put(num+1, obj, Undefined.instance);
- }
- }
- res.lastParen = parsub;
- }
-
- if (! (matchType == TEST)) {
- /*
- * Define the index and input properties last for better for/in loop
- * order (so they come after the elements).
- */
- obj.put("index", obj, new Integer(start + gData.skipped));
- obj.put("input", obj, str);
- }
-
- if (res.lastMatch == null) {
- res.lastMatch = new SubString();
- res.leftContext = new SubString();
- res.rightContext = new SubString();
- }
- res.lastMatch.charArray = charArray;
- res.lastMatch.index = index;
- res.lastMatch.length = matchlen;
-
- res.leftContext.charArray = charArray;
- if (cx.getLanguageVersion() == Context.VERSION_1_2) {
- /*
- * JS1.2 emulated Perl4.0.1.8 (patch level 36) for global regexps used
- * in scalar contexts, and unintentionally for the string.match "list"
- * psuedo-context. On "hi there bye", the following would result:
- *
- * Language while(/ /g){print("$`");} s/ /$`/g
- * perl4.036 "hi", "there" "hihitherehi therebye"
- * perl5 "hi", "hi there" "hihitherehi therebye"
- * js1.2 "hi", "there" "hihitheretherebye"
- *
- * Insofar as JS1.2 always defined $` as "left context from the last
- * match" for global regexps, it was more consistent than perl4.
- */
- res.leftContext.index = start;
- res.leftContext.length = gData.skipped;
- } else {
- /*
- * For JS1.3 and ECMAv2, emulate Perl5 exactly:
- *
- * js1.3 "hi", "hi there" "hihitherehi therebye"
- */
- res.leftContext.index = 0;
- res.leftContext.length = start + gData.skipped;
- }
-
- res.rightContext.charArray = charArray;
- res.rightContext.index = ep;
- res.rightContext.length = end - ep;
-
- return result;
- }
-
- int getFlags()
- {
- return re.flags;
- }
-
- private static void reportWarning(Context cx, String messageId, String arg)
- {
- if (cx.hasFeature(Context.FEATURE_STRICT_MODE)) {
- String msg = ScriptRuntime.getMessage1(messageId, arg);
- Context.reportWarning(msg);
- }
- }
-
- private static void reportError(String messageId, String arg)
- {
- String msg = ScriptRuntime.getMessage1(messageId, arg);
- throw ScriptRuntime.constructError("SyntaxError", msg);
- }
-
-// #string_id_map#
-
- private static final int
- Id_lastIndex = 1,
- Id_source = 2,
- Id_global = 3,
- Id_ignoreCase = 4,
- Id_multiline = 5,
-
- MAX_INSTANCE_ID = 5;
-
- protected int getMaxInstanceId()
- {
- return MAX_INSTANCE_ID;
- }
-
- protected int findInstanceIdInfo(String s)
- {
- int id;
-// #generated# Last update: 2007-05-09 08:16:24 EDT
- L0: { id = 0; String X = null; int c;
- int s_length = s.length();
- if (s_length==6) {
- c=s.charAt(0);
- if (c=='g') { X="global";id=Id_global; }
- else if (c=='s') { X="source";id=Id_source; }
- }
- else if (s_length==9) {
- c=s.charAt(0);
- if (c=='l') { X="lastIndex";id=Id_lastIndex; }
- else if (c=='m') { X="multiline";id=Id_multiline; }
- }
- else if (s_length==10) { X="ignoreCase";id=Id_ignoreCase; }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
-// #/string_id_map#
-
- 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 ScriptRuntime.wrapNumber(lastIndex);
- case Id_source:
- return new String(re.source);
- case Id_global:
- return ScriptRuntime.wrapBoolean((re.flags & JSREG_GLOB) != 0);
- case Id_ignoreCase:
- return ScriptRuntime.wrapBoolean((re.flags & JSREG_FOLD) != 0);
- case Id_multiline:
- return ScriptRuntime.wrapBoolean((re.flags & JSREG_MULTILINE) != 0);
- }
- return super.getInstanceIdValue(id);
- }
-
- protected void setInstanceIdValue(int id, Object value)
- {
- if (id == Id_lastIndex) {
- lastIndex = ScriptRuntime.toNumber(value);
- return;
- }
- super.setInstanceIdValue(id, 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 execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args)
- {
- if (!f.hasTag(REGEXP_TAG)) {
- return super.execIdCall(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, IdFunctionObject f)
- {
- if (!(thisObj instanceof NativeRegExp))
- throw incompatibleCallError(f);
- return (NativeRegExp)thisObj;
- }
-
-// #string_id_map#
- protected int findPrototypeId(String s)
- {
- int id;
-// #generated# Last update: 2007-05-09 08:16:24 EDT
- L0: { id = 0; String X = null; int c;
- L: switch (s.length()) {
- case 4: c=s.charAt(0);
- if (c=='e') { X="exec";id=Id_exec; }
- else if (c=='t') { X="test";id=Id_test; }
- break L;
- case 6: X="prefix";id=Id_prefix; break L;
- case 7: X="compile";id=Id_compile; break L;
- case 8: c=s.charAt(3);
- if (c=='o') { X="toSource";id=Id_toSource; }
- else if (c=='t') { X="toString";id=Id_toString; }
- break L;
- }
- if (X!=null && X!=s && !X.equals(s)) id = 0;
- break L0;
- }
-// #/generated#
- return id;
- }
-
- private static final int
- Id_compile = 1,
- Id_toString = 2,
- Id_toSource = 3,
- Id_exec = 4,
- Id_test = 5,
- Id_prefix = 6,
-
- MAX_PROTOTYPE_ID = 6;
-
-// #/string_id_map#
-
- private RECompiled re;
- double lastIndex; /* index after last match, for //g iterator */
-
-} // class NativeRegExp
-
-class RECompiled implements Serializable
-{
- static final long serialVersionUID = -6144956577595844213L;
-
- char []source; /* locked source string, sans // */
- int parenCount; /* number of parenthesized submatches */
- int flags; /* flags */
- byte[] program; /* regular expression bytecode */
- int classCount; /* count [...] bitmaps */
- RECharSet[] classList; /* list of [...] bitmaps */
- int anchorCh = -1; /* if >= 0, then re starts with this literal char */
-}
-
-class RENode {
-
- RENode(byte op)
- {
- this.op = op;
- }
-
- byte op; /* r.e. op bytecode */
- RENode next; /* next in concatenation order */
- RENode kid; /* first operand */
-
- RENode kid2; /* second operand */
- int num; /* could be a number */
- int parenIndex; /* or a parenthesis index */
-
- /* or a range */
- int min;
- int max;
- int parenCount;
- boolean greedy;
-
- /* or a character class */
- int startIndex;
- int kidlen; /* length of string at kid, in chars */
- int bmsize; /* bitmap size, based on max char code */
- int index; /* index into class list */
-
- /* or a literal sequence */
- char chr; /* of one character */
- int length; /* or many (via the index) */
- int flatIndex; /* which is -1 if not sourced */
-
-}
-
-class CompilerState {
-
- CompilerState(Context cx, char[] source, int length, int flags)
- {
- this.cx = cx;
- this.cpbegin = source;
- this.cp = 0;
- this.cpend = length;
- this.flags = flags;
- this.parenCount = 0;
- this.classCount = 0;
- this.progLength = 0;
- }
-
- Context cx;
- char cpbegin[];
- int cpend;
- int cp;
- int flags;
- int parenCount;
- int parenNesting;
- int classCount; /* number of [] encountered */
- int progLength; /* estimated bytecode length */
- RENode result;
-}
-
-class REProgState
-{
- REProgState(REProgState previous, int min, int max, int index,
- REBackTrackData backTrack,
- int continuation_pc, int continuation_op)
- {
- this.previous = previous;
- this.min = min;
- this.max = max;
- this.index = index;
- this.continuation_op = continuation_op;
- this.continuation_pc = continuation_pc;
- this.backTrack = backTrack;
- }
-
- REProgState previous; // previous state in stack
-
- int min; /* current quantifier min */
- int max; /* current quantifier max */
- int index; /* progress in text */
- int continuation_op;
- int continuation_pc;
- REBackTrackData backTrack; // used by ASSERT_ to recover state
-}
-
-class REBackTrackData {
-
- REBackTrackData(REGlobalData gData, int op, int pc)
- {
- previous = gData.backTrackStackTop;
- continuation_op = op;
- continuation_pc = pc;
- lastParen = gData.lastParen;
- if (gData.parens != null) {
- parens = gData.parens.clone();
- }
- cp = gData.cp;
- stateStackTop = gData.stateStackTop;
- }
-
- REBackTrackData previous;
-
- int continuation_op; /* where to backtrack to */
- int continuation_pc;
- int lastParen;
- long[] parens; /* parenthesis captures */
- int cp; /* char buffer index */
- REProgState stateStackTop; /* state of op that backtracked */
-}
-
-class REGlobalData {
- boolean multiline;
- RECompiled regexp; /* the RE in execution */
- int lastParen; /* highest paren set so far */
- int skipped; /* chars skipped anchoring this r.e. */
-
- int cp; /* char buffer index */
- long[] parens; /* parens captures */
-
- REProgState stateStackTop; /* stack of state of current ancestors */
-
- REBackTrackData backTrackStackTop; /* last matched-so-far position */
-
-
- /**
- * Get start of parenthesis capture contents, -1 for empty.
- */
- int parens_index(int i)
- {
- return (int)(parens[i]);
- }
-
- /**
- * Get length of parenthesis capture contents.
- */
- int parens_length(int i)
- {
- return (int)(parens[i] >>> 32);
- }
-
- void set_parens(int i, int index, int length)
- {
- parens[i] = (index & 0xffffffffL) | ((long)length << 32);
- }
-
-}
-
-/*
- * This struct holds a bitmap representation of a class from a regexp.
- * There's a list of these referenced by the classList field in the NativeRegExp
- * struct below. The initial state has startIndex set to the offset in the
- * original regexp source of the beginning of the class contents. The first
- * use of the class converts the source representation into a bitmap.
- *
- */
-final class RECharSet implements Serializable
-{
- static final long serialVersionUID = 7931787979395898394L;
-
- RECharSet(int length, int startIndex, int strlength)
- {
- this.length = length;
- this.startIndex = startIndex;
- this.strlength = strlength;
- }
-
- int length;
- int startIndex;
- int strlength;
-
- volatile transient boolean converted;
- volatile transient boolean sense;
- volatile transient byte[] bits;
-}
-
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExpCtor.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExpCtor.java
deleted file mode 100644
index 808d62d..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExpCtor.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/* -*- 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, 1998.
- *
- * 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
- * Brendan Eich
- *
- * 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.regexp;
-
-import org.mozilla.javascript.*;
-
-/**
- * This class implements the RegExp constructor native object.
- *
- * Revision History:
- * Implementation in C by Brendan Eich
- * Initial port to Java by Norris Boyd from jsregexp.c version 1.36
- * Merged up to version 1.38, which included Unicode support.
- * Merged bug fixes in version 1.39.
- * Merged JSFUN13_BRANCH changes up to 1.32.2.11
- *
- * @author Brendan Eich
- * @author Norris Boyd
- */
-class NativeRegExpCtor extends BaseFunction
-{
- static final long serialVersionUID = -5733330028285400526L;
-
- NativeRegExpCtor()
- {
- }
-
- public String getFunctionName()
- {
- return "RegExp";
- }
-
- public Object call(Context cx, Scriptable scope, Scriptable thisObj,
- Object[] args)
- {
- if (args.length > 0 && args[0] instanceof NativeRegExp &&
- (args.length == 1 || args[1] == Undefined.instance))
- {
- return args[0];
- }
- return construct(cx, scope, args);
- }
-
- public Scriptable construct(Context cx, Scriptable scope, Object[] args)
- {
- NativeRegExp re = new NativeRegExp();
- re.compile(cx, scope, args);
- ScriptRuntime.setObjectProtoAndParent(re, scope);
- return re;
- }
-
- private static RegExpImpl getImpl()
- {
- Context cx = Context.getCurrentContext();
- return (RegExpImpl) ScriptRuntime.getRegExpProxy(cx);
- }
-
-// #string_id_map#
-
- private static final int
- Id_multiline = 1,
- Id_STAR = 2, // #string=$*#
-
- Id_input = 3,
- Id_UNDERSCORE = 4, // #string=$_#
-
- Id_lastMatch = 5,
- Id_AMPERSAND = 6, // #string=$&#
-
- Id_lastParen = 7,
- Id_PLUS = 8, // #string=$+#
-
- Id_leftContext = 9,
- Id_BACK_QUOTE = 10, // #string=$`#
-
- Id_rightContext = 11,
- Id_QUOTE = 12, // #string=$'#
-
- DOLLAR_ID_BASE = 12;
-
- private static final int
- Id_DOLLAR_1 = DOLLAR_ID_BASE + 1, // #string=$1#
- Id_DOLLAR_2 = DOLLAR_ID_BASE + 2, // #string=$2#
- Id_DOLLAR_3 = DOLLAR_ID_BASE + 3, // #string=$3#
- Id_DOLLAR_4 = DOLLAR_ID_BASE + 4, // #string=$4#
- Id_DOLLAR_5 = DOLLAR_ID_BASE + 5, // #string=$5#
- Id_DOLLAR_6 = DOLLAR_ID_BASE + 6, // #string=$6#
- Id_DOLLAR_7 = DOLLAR_ID_BASE + 7, // #string=$7#
- Id_DOLLAR_8 = DOLLAR_ID_BASE + 8, // #string=$8#
- Id_DOLLAR_9 = DOLLAR_ID_BASE + 9, // #string=$9#
-
- MAX_INSTANCE_ID = DOLLAR_ID_BASE + 9;
-
- protected int getMaxInstanceId()
- {
- return super.getMaxInstanceId() + MAX_INSTANCE_ID;
- }
-
- 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;
- L: switch (s.length()) {
- case 2: switch (s.charAt(1)) {
- case '&': if (s.charAt(0)=='$') {id=Id_AMPERSAND; break L0;} break L;
- case '\'': if (s.charAt(0)=='$') {id=Id_QUOTE; break L0;} break L;
- case '*': if (s.charAt(0)=='$') {id=Id_STAR; break L0;} break L;
- case '+': if (s.charAt(0)=='$') {id=Id_PLUS; break L0;} break L;
- case '1': if (s.charAt(0)=='$') {id=Id_DOLLAR_1; break L0;} break L;
- case '2': if (s.charAt(0)=='$') {id=Id_DOLLAR_2; break L0;} break L;
- case '3': if (s.charAt(0)=='$') {id=Id_DOLLAR_3; break L0;} break L;
- case '4': if (s.charAt(0)=='$') {id=Id_DOLLAR_4; break L0;} break L;
- case '5': if (s.charAt(0)=='$') {id=Id_DOLLAR_5; break L0;} break L;
- case '6': if (s.charAt(0)=='$') {id=Id_DOLLAR_6; break L0;} break L;
- case '7': if (s.charAt(0)=='$') {id=Id_DOLLAR_7; break L0;} break L;
- case '8': if (s.charAt(0)=='$') {id=Id_DOLLAR_8; break L0;} break L;
- case '9': if (s.charAt(0)=='$') {id=Id_DOLLAR_9; break L0;} break L;
- case '_': if (s.charAt(0)=='$') {id=Id_UNDERSCORE; break L0;} break L;
- case '`': if (s.charAt(0)=='$') {id=Id_BACK_QUOTE; break L0;} break L;
- } break L;
- case 5: X="input";id=Id_input; break L;
- case 9: c=s.charAt(4);
- if (c=='M') { X="lastMatch";id=Id_lastMatch; }
- else if (c=='P') { X="lastParen";id=Id_lastParen; }
- else if (c=='i') { X="multiline";id=Id_multiline; }
- break L;
- case 11: X="leftContext";id=Id_leftContext; break L;
- case 12: X="rightContext";id=Id_rightContext; break L;
- }
- 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, super.getMaxInstanceId() + id);
- }
-
-// #/string_id_map#
-
- protected String getInstanceIdName(int id)
- {
- int shifted = id - super.getMaxInstanceId();
- 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 - super.getMaxInstanceId();
- if (1 <= shifted && shifted <= MAX_INSTANCE_ID) {
- RegExpImpl impl = getImpl();
- Object stringResult;
- switch (shifted) {
- case Id_multiline:
- case Id_STAR:
- return ScriptRuntime.wrapBoolean(impl.multiline);
-
- case Id_input:
- case Id_UNDERSCORE:
- stringResult = impl.input;
- break;
-
- case Id_lastMatch:
- case Id_AMPERSAND:
- stringResult = impl.lastMatch;
- break;
-
- case Id_lastParen:
- case Id_PLUS:
- stringResult = impl.lastParen;
- break;
-
- case Id_leftContext:
- case Id_BACK_QUOTE:
- stringResult = impl.leftContext;
- break;
-
- case Id_rightContext:
- case Id_QUOTE:
- stringResult = impl.rightContext;
- break;
-
- default:
- {
- // Must be one of $1..$9, convert to 0..8
- int substring_number = shifted - DOLLAR_ID_BASE - 1;
- stringResult = impl.getParenSubString(substring_number);
- break;
- }
- }
- return (stringResult == null) ? "" : stringResult.toString();
- }
- return super.getInstanceIdValue(id);
- }
-
- protected void setInstanceIdValue(int id, Object value)
- {
- int shifted = id - super.getMaxInstanceId();
- switch (shifted) {
- 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);
- }
-
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/RegExpImpl.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/RegExpImpl.java
deleted file mode 100644
index 4b0a303..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/RegExpImpl.java
+++ /dev/null
@@ -1,541 +0,0 @@
-/* -*- 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, 1998.
- *
- * 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):
- *
- * 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.regexp;
-
-import org.mozilla.javascript.*;
-
-/**
- *
- */
-public class RegExpImpl implements RegExpProxy {
-
- public boolean isRegExp(Scriptable obj) {
- return obj instanceof NativeRegExp;
- }
-
- public Object compileRegExp(Context cx, String source, String flags)
- {
- return NativeRegExp.compileRE(cx, source, flags, false);
- }
-
- public Scriptable wrapRegExp(Context cx, Scriptable scope,
- Object compiled)
- {
- return new NativeRegExp(scope, compiled);
- }
-
- public Object action(Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args,
- int actionType)
- {
- GlobData data = new GlobData();
- data.mode = actionType;
-
- switch (actionType) {
- case RA_MATCH:
- {
- Object rval;
- data.optarg = 1;
- rval = matchOrReplace(cx, scope, thisObj, args,
- this, data, false);
- return data.arrayobj == null ? rval : data.arrayobj;
- }
-
- case RA_SEARCH:
- data.optarg = 1;
- return matchOrReplace(cx, scope, thisObj, args,
- this, data, false);
-
- case RA_REPLACE:
- {
- Object arg1 = args.length < 2 ? Undefined.instance : args[1];
- String repstr = null;
- Function lambda = null;
- if (arg1 instanceof Function) {
- lambda = (Function) arg1;
- } else {
- repstr = ScriptRuntime.toString(arg1);
- }
-
- data.optarg = 2;
- data.lambda = lambda;
- data.repstr = repstr;
- data.dollar = repstr == null ? -1 : repstr.indexOf('$');
- data.charBuf = null;
- data.leftIndex = 0;
- Object val = matchOrReplace(cx, scope, thisObj, args,
- this, data, true);
- SubString rc = this.rightContext;
-
- if (data.charBuf == null) {
- if (data.global || val == null
- || !val.equals(Boolean.TRUE))
- {
- /* Didn't match even once. */
- return data.str;
- }
- SubString lc = this.leftContext;
- replace_glob(data, cx, scope, this, lc.index, lc.length);
- }
- data.charBuf.append(rc.charArray, rc.index, rc.length);
- return data.charBuf.toString();
- }
-
- default:
- throw Kit.codeBug();
- }
- }
-
- /**
- * Analog of C match_or_replace.
- */
- private static Object matchOrReplace(Context cx, Scriptable scope,
- Scriptable thisObj, Object[] args,
- RegExpImpl reImpl,
- GlobData data, boolean forceFlat)
- {
- NativeRegExp re;
-
- String str = ScriptRuntime.toString(thisObj);
- data.str = str;
- Scriptable topScope = ScriptableObject.getTopLevelScope(scope);
-
- if (args.length == 0) {
- Object compiled = NativeRegExp.compileRE(cx, "", "", false);
- re = new NativeRegExp(topScope, compiled);
- } else if (args[0] instanceof NativeRegExp) {
- re = (NativeRegExp) args[0];
- } else {
- String src = ScriptRuntime.toString(args[0]);
- String opt;
- if (data.optarg < args.length) {
- args[0] = src;
- opt = ScriptRuntime.toString(args[data.optarg]);
- } else {
- opt = null;
- }
- Object compiled = NativeRegExp.compileRE(cx, src, opt, forceFlat);
- re = new NativeRegExp(topScope, compiled);
- }
- data.regexp = re;
-
- data.global = (re.getFlags() & NativeRegExp.JSREG_GLOB) != 0;
- int[] indexp = { 0 };
- Object result = null;
- if (data.mode == RA_SEARCH) {
- result = re.executeRegExp(cx, scope, reImpl,
- str, indexp, NativeRegExp.TEST);
- if (result != null && result.equals(Boolean.TRUE))
- result = new Integer(reImpl.leftContext.length);
- else
- result = new Integer(-1);
- } else if (data.global) {
- re.lastIndex = 0;
- for (int count = 0; indexp[0] <= str.length(); count++) {
- result = re.executeRegExp(cx, scope, reImpl,
- str, indexp, NativeRegExp.TEST);
- if (result == null || !result.equals(Boolean.TRUE))
- break;
- if (data.mode == RA_MATCH) {
- match_glob(data, cx, scope, count, reImpl);
- } else {
- if (data.mode != RA_REPLACE) Kit.codeBug();
- SubString lastMatch = reImpl.lastMatch;
- int leftIndex = data.leftIndex;
- int leftlen = lastMatch.index - leftIndex;
- data.leftIndex = lastMatch.index + lastMatch.length;
- replace_glob(data, cx, scope, reImpl, leftIndex, leftlen);
- }
- if (reImpl.lastMatch.length == 0) {
- if (indexp[0] == str.length())
- break;
- indexp[0]++;
- }
- }
- } else {
- result = re.executeRegExp(cx, scope, reImpl, str, indexp,
- ((data.mode == RA_REPLACE)
- ? NativeRegExp.TEST
- : NativeRegExp.MATCH));
- }
-
- return result;
- }
-
-
-
- public int find_split(Context cx, Scriptable scope, String target,
- String separator, Scriptable reObj,
- int[] ip, int[] matchlen,
- boolean[] matched, String[][] parensp)
- {
- int i = ip[0];
- int length = target.length();
- int result;
-
- int version = cx.getLanguageVersion();
- NativeRegExp re = (NativeRegExp) reObj;
- again:
- while (true) { // imitating C label
- /* JS1.2 deviated from Perl by never matching at end of string. */
- int ipsave = ip[0]; // reuse ip to save object creation
- ip[0] = i;
- Object ret = re.executeRegExp(cx, scope, this, target, ip,
- NativeRegExp.TEST);
- if (ret != Boolean.TRUE) {
- // Mismatch: ensure our caller advances i past end of string.
- ip[0] = ipsave;
- matchlen[0] = 1;
- matched[0] = false;
- return length;
- }
- i = ip[0];
- ip[0] = ipsave;
- matched[0] = true;
-
- SubString sep = this.lastMatch;
- matchlen[0] = sep.length;
- if (matchlen[0] == 0) {
- /*
- * Empty string match: never split on an empty
- * match at the start of a find_split cycle. Same
- * rule as for an empty global match in
- * match_or_replace.
- */
- if (i == ip[0]) {
- /*
- * "Bump-along" to avoid sticking at an empty
- * match, but don't bump past end of string --
- * our caller must do that by adding
- * sep->length to our return value.
- */
- if (i == length) {
- if (version == Context.VERSION_1_2) {
- matchlen[0] = 1;
- result = i;
- }
- else
- result = -1;
- break;
- }
- i++;
- continue again; // imitating C goto
- }
- }
- // PR_ASSERT((size_t)i >= sep->length);
- result = i - matchlen[0];
- break;
- }
- int size = (parens == null) ? 0 : parens.length;
- parensp[0] = new String[size];
- for (int num = 0; num < size; num++) {
- SubString parsub = getParenSubString(num);
- parensp[0][num] = parsub.toString();
- }
- return result;
- }
-
- /**
- * Analog of REGEXP_PAREN_SUBSTRING in C jsregexp.h.
- * Assumes zero-based; i.e., for $3, i==2
- */
- SubString getParenSubString(int i)
- {
- if (parens != null && i < parens.length) {
- SubString parsub = parens[i];
- if (parsub != null) {
- return parsub;
- }
- }
- return SubString.emptySubString;
- }
-
- /*
- * Analog of match_glob() in jsstr.c
- */
- private static void match_glob(GlobData mdata, Context cx,
- Scriptable scope, int count,
- RegExpImpl reImpl)
- {
- if (mdata.arrayobj == null) {
- Scriptable s = ScriptableObject.getTopLevelScope(scope);
- mdata.arrayobj = ScriptRuntime.newObject(cx, s, "Array", null);
- }
- SubString matchsub = reImpl.lastMatch;
- String matchstr = matchsub.toString();
- mdata.arrayobj.put(count, mdata.arrayobj, matchstr);
- }
-
- /*
- * Analog of replace_glob() in jsstr.c
- */
- private static void replace_glob(GlobData rdata, Context cx,
- Scriptable scope, RegExpImpl reImpl,
- int leftIndex, int leftlen)
- {
- int replen;
- String lambdaStr;
- if (rdata.lambda != null) {
- // invoke lambda function with args lastMatch, $1, $2, ... $n,
- // leftContext.length, whole string.
- SubString[] parens = reImpl.parens;
- int parenCount = (parens == null) ? 0 : parens.length;
- Object[] args = new Object[parenCount + 3];
- args[0] = reImpl.lastMatch.toString();
- for (int i=0; i < parenCount; i++) {
- SubString sub = parens[i];
- if (sub != null) {
- args[i+1] = sub.toString();
- } else {
- args[i+1] = Undefined.instance;
- }
- }
- args[parenCount+1] = new Integer(reImpl.leftContext.length);
- args[parenCount+2] = rdata.str;
- // This is a hack to prevent expose of reImpl data to
- // JS function which can run new regexps modifing
- // regexp that are used later by the engine.
- // TODO: redesign is necessary
- if (reImpl != ScriptRuntime.getRegExpProxy(cx)) Kit.codeBug();
- RegExpImpl re2 = new RegExpImpl();
- re2.multiline = reImpl.multiline;
- re2.input = reImpl.input;
- ScriptRuntime.setRegExpProxy(cx, re2);
- try {
- Scriptable parent = ScriptableObject.getTopLevelScope(scope);
- Object result = rdata.lambda.call(cx, parent, parent, args);
- lambdaStr = ScriptRuntime.toString(result);
- } finally {
- ScriptRuntime.setRegExpProxy(cx, reImpl);
- }
- replen = lambdaStr.length();
- } else {
- lambdaStr = null;
- replen = rdata.repstr.length();
- if (rdata.dollar >= 0) {
- int[] skip = new int[1];
- int dp = rdata.dollar;
- do {
- SubString sub = interpretDollar(cx, reImpl, rdata.repstr,
- dp, skip);
- if (sub != null) {
- replen += sub.length - skip[0];
- dp += skip[0];
- } else {
- ++dp;
- }
- dp = rdata.repstr.indexOf('$', dp);
- } while (dp >= 0);
- }
- }
-
- int growth = leftlen + replen + reImpl.rightContext.length;
- StringBuffer charBuf = rdata.charBuf;
- if (charBuf == null) {
- charBuf = new StringBuffer(growth);
- rdata.charBuf = charBuf;
- } else {
- charBuf.ensureCapacity(rdata.charBuf.length() + growth);
- }
-
- charBuf.append(reImpl.leftContext.charArray, leftIndex, leftlen);
- if (rdata.lambda != null) {
- charBuf.append(lambdaStr);
- } else {
- do_replace(rdata, cx, reImpl);
- }
- }
-
- private static SubString interpretDollar(Context cx, RegExpImpl res,
- String da, int dp, int[] skip)
- {
- char dc;
- int num, tmp;
-
- if (da.charAt(dp) != '$') Kit.codeBug();
-
- /* Allow a real backslash (literal "\\") to escape "$1" etc. */
- int version = cx.getLanguageVersion();
- if (version != Context.VERSION_DEFAULT
- && version <= Context.VERSION_1_4)
- {
- if (dp > 0 && da.charAt(dp - 1) == '\\')
- return null;
- }
- int daL = da.length();
- if (dp + 1 >= daL)
- return null;
- /* Interpret all Perl match-induced dollar variables. */
- dc = da.charAt(dp + 1);
- if (NativeRegExp.isDigit(dc)) {
- int cp;
- if (version != Context.VERSION_DEFAULT
- && version <= Context.VERSION_1_4)
- {
- if (dc == '0')
- return null;
- /* Check for overflow to avoid gobbling arbitrary decimal digits. */
- num = 0;
- cp = dp;
- while (++cp < daL && NativeRegExp.isDigit(dc = da.charAt(cp)))
- {
- tmp = 10 * num + (dc - '0');
- if (tmp < num)
- break;
- num = tmp;
- }
- }
- else { /* ECMA 3, 1-9 or 01-99 */
- int parenCount = (res.parens == null) ? 0 : res.parens.length;
- num = dc - '0';
- if (num > parenCount)
- return null;
- cp = dp + 2;
- if ((dp + 2) < daL) {
- dc = da.charAt(dp + 2);
- if (NativeRegExp.isDigit(dc)) {
- tmp = 10 * num + (dc - '0');
- if (tmp <= parenCount) {
- cp++;
- num = tmp;
- }
- }
- }
- if (num == 0) return null; /* $0 or $00 is not valid */
- }
- /* Adjust num from 1 $n-origin to 0 array-index-origin. */
- num--;
- skip[0] = cp - dp;
- return res.getParenSubString(num);
- }
-
- skip[0] = 2;
- switch (dc) {
- case '$':
- return new SubString("$");
- case '&':
- return res.lastMatch;
- case '+':
- return res.lastParen;
- case '`':
- if (version == Context.VERSION_1_2) {
- /*
- * JS1.2 imitated the Perl4 bug where left context at each step
- * in an iterative use of a global regexp started from last match,
- * not from the start of the target string. But Perl4 does start
- * $` at the beginning of the target string when it is used in a
- * substitution, so we emulate that special case here.
- */
- res.leftContext.index = 0;
- res.leftContext.length = res.lastMatch.index;
- }
- return res.leftContext;
- case '\'':
- return res.rightContext;
- }
- return null;
- }
-
- /**
- * Analog of do_replace in jsstr.c
- */
- private static void do_replace(GlobData rdata, Context cx,
- RegExpImpl regExpImpl)
- {
- StringBuffer charBuf = rdata.charBuf;
- int cp = 0;
- String da = rdata.repstr;
- int dp = rdata.dollar;
- if (dp != -1) {
- int[] skip = new int[1];
- do {
- int len = dp - cp;
- charBuf.append(da.substring(cp, dp));
- cp = dp;
- SubString sub = interpretDollar(cx, regExpImpl, da,
- dp, skip);
- if (sub != null) {
- len = sub.length;
- if (len > 0) {
- charBuf.append(sub.charArray, sub.index, len);
- }
- cp += skip[0];
- dp += skip[0];
- } else {
- ++dp;
- }
- dp = da.indexOf('$', dp);
- } while (dp >= 0);
- }
- int daL = da.length();
- if (daL > cp) {
- charBuf.append(da.substring(cp, daL));
- }
- }
-
- String input; /* input string to match (perl $_, GC root) */
- boolean multiline; /* whether input contains newlines (perl $*) */
- SubString[] parens; /* Vector of SubString; last set of parens
- matched (perl $1, $2) */
- SubString lastMatch; /* last string matched (perl $&) */
- SubString lastParen; /* last paren matched (perl $+) */
- SubString leftContext; /* input to left of last match (perl $`) */
- SubString rightContext; /* input to right of last match (perl $') */
-}
-
-
-final class GlobData
-{
- int mode; /* input: return index, match object, or void */
- int optarg; /* input: index of optional flags argument */
- boolean global; /* output: whether regexp was global */
- String str; /* output: 'this' parameter object as string */
- NativeRegExp regexp;/* output: regexp parameter object private data */
-
- // match-specific data
-
- Scriptable arrayobj;
-
- // replace-specific data
-
- Function lambda; /* replacement function object or null */
- String repstr; /* replacement string */
- int dollar = -1; /* -1 or index of first $ in repstr */
- StringBuffer charBuf; /* result characters, null initially */
- int leftIndex; /* leftContext index, always 0 for JS1.2 */
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/SubString.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/SubString.java
deleted file mode 100644
index 00905ca..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/SubString.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- 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, 1998.
- *
- * 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):
- *
- * 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.regexp;
-
-class SubString {
-
- public SubString()
- {
- }
-
- public SubString(String str)
- {
- index = 0;
- charArray = str.toCharArray();
- length = str.length();
- }
-
- public SubString(char[] source, int start, int len)
- {
- // there must be a better way of doing this??
- index = 0;
- length = len;
- charArray = new char[len];
- for (int j = 0; j < len; j++)
- charArray[j] = source[start + j];
- }
-
- public String toString() {
- return charArray == null
- ? ""
- : new String(charArray, index, length);
- }
-
- static final SubString emptySubString = new SubString();
-
- char[] charArray;
- int index;
- int length;
-}
-
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages.properties b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages.properties
deleted file mode 100644
index fd869c1..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages.properties
+++ /dev/null
@@ -1,778 +0,0 @@
-#
-# Default JavaScript messages file.
-#
-# ***** 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
-# Bob Jervis
-#
-# 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 *****
-
-# This is replaced during jar assembly from property string
-# and should not be translated
-implementation.version = @IMPLEMENTATION.VERSION@
-
-#
-# To add JavaScript error messages for a particular locale, create a
-# new Messages_[locale].properties file, where [locale] is the Java
-# string abbreviation for that locale. For example, JavaScript
-# messages for the Polish locale should be located in
-# Messages_pl.properties, and messages for the Italian Swiss locale
-# should be located in Messages_it_CH.properties. Message properties
-# files should be accessible through the classpath under
-# org.mozilla.javascript.resources
-#
-# See:
-# java.util.ResourceBundle
-# java.text.MessageFormat
-#
-
-# SomeJavaClassWhereUsed
-
-# Codegen
-msg.dup.parms =\
- Duplicate parameter name "{0}".
-
-msg.too.big.jump =\
- Program too complex: too big jump offset.
-
-msg.too.big.index =\
- Program too complex: internal index exceeds 64K limit.
-
-msg.while.compiling.fn =\
- Encountered code generation error while compiling function "{0}": {1}
-
-msg.while.compiling.script =\
- Encountered code generation error while compiling script: {0}
-
-# Context
-msg.ctor.not.found =\
- Constructor for "{0}" not found.
-
-msg.not.ctor =\
- "{0}" is not a constructor.
-
-# FunctionObject
-msg.varargs.ctor =\
- Method or constructor "{0}" must be static with the signature \
- "(Context cx, Object[] args, Function ctorObj, boolean inNewExpr)" \
- to define a variable arguments constructor.
-
-msg.varargs.fun =\
- Method "{0}" must be static with the signature \
- "(Context cx, Scriptable thisObj, Object[] args, Function funObj)" \
- to define a variable arguments function.
-
-msg.incompat.call =\
- Method "{0}" called on incompatible object.
-
-msg.bad.parms =\
- Unsupported parameter type "{0}" in method "{1}".
-
-msg.bad.method.return =\
- Unsupported return type "{0}" in method "{1}".
-
-msg.bad.ctor.return =\
- Construction of objects of type "{0}" is not supported.
-
-msg.no.overload =\
- Method "{0}" occurs multiple times in class "{1}".
-
-msg.method.not.found =\
- Method "{0}" not found in "{1}".
-
-# IRFactory
-
-msg.bad.for.in.lhs =\
- Invalid left-hand side of for..in loop.
-
-msg.mult.index =\
- Only one variable allowed in for..in loop.
-
-msg.bad.for.in.destruct =\
- Left hand side of for..in loop must be an array of length 2 to accept \
- key/value pair.
-
-msg.cant.convert =\
- Can''t convert to type "{0}".
-
-msg.bad.assign.left =\
- Invalid assignment left-hand side.
-
-msg.bad.decr =\
- Invalid decerement operand.
-
-msg.bad.incr =\
- Invalid increment operand.
-
-msg.bad.yield =\
- yield must be in a function.
-
-msg.yield.parenthesized =\
- yield expression must be parenthesized.
-
-# NativeGlobal
-msg.cant.call.indirect =\
- Function "{0}" must be called directly, and not by way of a \
- function of another name.
-
-msg.eval.nonstring =\
- Calling eval() with anything other than a primitive string value will \
- simply return the value. Is this what you intended?
-
-msg.eval.nonstring.strict =\
- Calling eval() with anything other than a primitive string value is not \
- allowed in strict mode.
-
-msg.bad.destruct.op =\
- Invalid destructuring assignment operator
-
-# NativeCall
-msg.only.from.new =\
- "{0}" may only be invoked from a "new" expression.
-
-msg.deprec.ctor =\
- The "{0}" constructor is deprecated.
-
-# NativeFunction
-msg.no.function.ref.found =\
- no source found to decompile function reference {0}
-
-msg.arg.isnt.array =\
- second argument to Function.prototype.apply must be an array
-
-# NativeGlobal
-msg.bad.esc.mask =\
- invalid string escape mask
-
-# NativeJavaClass
-msg.cant.instantiate =\
- error instantiating ({0}): class {1} is interface or abstract
-
-msg.bad.ctor.sig =\
- Found constructor with wrong signature: \
- {0} calling {1} with signature {2}
-
-msg.not.java.obj =\
- Expected argument to getClass() to be a Java object.
-
-msg.no.java.ctor =\
- Java constructor for "{0}" with arguments "{1}" not found.
-
-# NativeJavaMethod
-msg.method.ambiguous =\
- The choice of Java method {0}.{1} matching JavaScript argument types ({2}) is ambiguous; \
- candidate methods are: {3}
-
-msg.constructor.ambiguous =\
- The choice of Java constructor {0} matching JavaScript argument types ({1}) is ambiguous; \
- candidate constructors are: {2}
-
-# NativeJavaObject
-msg.conversion.not.allowed =\
- Cannot convert {0} to {1}
-
-msg.no.empty.interface.conversion =\
- Cannot convert {0} to interface {1} with no methods
-
-msg.no.function.interface.conversion =\
- Cannot convert function {0} to interface since it contains methods with \
- different signatures
-
-# NativeJavaPackage
-msg.not.classloader =\
- Constructor for "Packages" expects argument of type java.lang.Classloader
-
-# NativeRegExp
-msg.bad.quant =\
- Invalid quantifier {0}
-
-msg.overlarge.backref =\
- Overly large back reference {0}
-
-msg.overlarge.min =\
- Overly large minimum {0}
-
-msg.overlarge.max =\
- Overly large maximum {0}
-
-msg.zero.quant =\
- Zero quantifier {0}
-
-msg.max.lt.min =\
- Maximum {0} less than minimum
-
-msg.unterm.quant =\
- Unterminated quantifier {0}
-
-msg.unterm.paren =\
- Unterminated parenthetical {0}
-
-msg.unterm.class =\
- Unterminated character class {0}
-
-msg.bad.range =\
- Invalid range in character class.
-
-msg.trail.backslash =\
- Trailing \\ in regular expression.
-
-msg.re.unmatched.right.paren =\
- unmatched ) in regular expression.
-
-msg.no.regexp =\
- Regular expressions are not available.
-
-msg.bad.backref =\
- back-reference exceeds number of capturing parentheses.
-
-msg.bad.regexp.compile =\
- Only one argument may be specified if the first argument to \
- RegExp.prototype.compile is a RegExp object.
-
-# Parser
-msg.got.syntax.errors = \
- Compilation produced {0} syntax errors.
-
-msg.var.redecl =\
- TypeError: redeclaration of var {0}.
-
-msg.const.redecl =\
- TypeError: redeclaration of const {0}.
-
-msg.let.redecl =\
- TypeError: redeclaration of variable {0}.
-
-msg.parm.redecl =\
- TypeError: redeclaration of formal parameter {0}.
-
-msg.fn.redecl =\
- TypeError: redeclaration of function {0}.
-
-# NodeTransformer
-msg.dup.label =\
- duplicated label
-
-msg.undef.label =\
- undefined label
-
-msg.bad.break =\
- unlabelled break must be inside loop or switch
-
-msg.continue.outside =\
- continue must be inside loop
-
-msg.continue.nonloop =\
- continue can only use labeles of iteration statements
-
-msg.bad.throw.eol =\
- Line terminator is not allowed between the throw keyword and throw \
- expression.
-
-msg.no.paren.parms =\
- missing ( before function parameters.
-
-msg.no.parm =\
- missing formal parameter
-
-msg.no.paren.after.parms =\
- missing ) after formal parameters
-
-msg.no.brace.body =\
- missing '{' before function body
-
-msg.no.brace.after.body =\
- missing } after function body
-
-msg.no.paren.cond =\
- missing ( before condition
-
-msg.no.paren.after.cond =\
- missing ) after condition
-
-msg.no.semi.stmt =\
- missing ; before statement
-
-msg.no.name.after.dot =\
- missing name after . operator
-
-msg.no.name.after.coloncolon =\
- missing name after :: operator
-
-msg.no.name.after.dotdot =\
- missing name after .. operator
-
-msg.no.name.after.xmlAttr =\
- missing name after .@
-
-msg.no.bracket.index =\
- missing ] in index expression
-
-msg.no.paren.switch =\
- missing ( before switch expression
-
-msg.no.paren.after.switch =\
- missing ) after switch expression
-
-msg.no.brace.switch =\
- missing '{' before switch body
-
-msg.bad.switch =\
- invalid switch statement
-
-msg.no.colon.case =\
- missing : after case expression
-
-msg.double.switch.default =\
- double default label in the switch statement
-
-msg.no.while.do =\
- missing while after do-loop body
-
-msg.no.paren.for =\
- missing ( after for
-
-msg.no.semi.for =\
- missing ; after for-loop initializer
-
-msg.no.semi.for.cond =\
- missing ; after for-loop condition
-
-msg.in.after.for.name =\
- missing in after for
-
-msg.no.paren.for.ctrl =\
- missing ) after for-loop control
-
-msg.no.paren.with =\
- missing ( before with-statement object
-
-msg.no.paren.after.with =\
- missing ) after with-statement object
-
-msg.no.paren.after.let =\
- missing ( after let
-
-msg.no.paren.let =\
- missing ) after variable list
-
-msg.no.curly.let =\
- missing } after let statement
-
-msg.bad.return =\
- invalid return
-
-msg.no.brace.block =\
- missing } in compound statement
-
-msg.bad.label =\
- invalid label
-
-msg.bad.var =\
- missing variable name
-
-msg.bad.var.init =\
- invalid variable initialization
-
-msg.no.colon.cond =\
- missing : in conditional expression
-
-msg.no.paren.arg =\
- missing ) after argument list
-
-msg.no.bracket.arg =\
- missing ] after element list
-
-msg.bad.prop =\
- invalid property id
-
-msg.no.colon.prop =\
- missing : after property id
-
-msg.no.brace.prop =\
- missing } after property list
-
-msg.no.paren =\
- missing ) in parenthetical
-
-msg.reserved.id =\
- identifier is a reserved word
-
-msg.no.paren.catch =\
- missing ( before catch-block condition
-
-msg.bad.catchcond =\
- invalid catch block condition
-
-msg.catch.unreachable =\
- any catch clauses following an unqualified catch are unreachable
-
-msg.no.brace.try =\
- missing '{' before try block
-
-msg.no.brace.catchblock =\
- missing '{' before catch-block body
-
-msg.try.no.catchfinally =\
- ''try'' without ''catch'' or ''finally''
-
-msg.no.return.value =\
- function {0} does not always return a value
-
-msg.anon.no.return.value =\
- anonymous function does not always return a value
-
-msg.return.inconsistent =\
- return statement is inconsistent with previous usage
-
-msg.generator.returns =\
- TypeError: generator function {0} returns a value
-
-msg.anon.generator.returns =\
- TypeError: anonymous generator function returns a value
-
-msg.syntax =\
- syntax error
-
-msg.unexpected.eof =\
- Unexpected end of file
-
-msg.XML.bad.form =\
- illegally formed XML syntax
-
-msg.XML.not.available =\
- XML runtime not available
-
-msg.too.deep.parser.recursion =\
- Too deep recursion while parsing
-
-msg.no.side.effects =\
- Code has no side effects
-
-msg.extra.trailing.comma =\
- Trailing comma is not legal in an ECMA-262 object initializer
-
-msg.equal.as.assign =\
- Test for equality (==) mistyped as assignment (=)?
-
-msg.var.hides.arg =\
- Variable {0} hides argument
-
-msg.destruct.assign.no.init =\
- Missing = in destructuring declaration
-
-# ScriptRuntime
-msg.no.properties =\
- {0} has no properties.
-
-msg.invalid.iterator =\
- Invalid iterator value
-
-msg.iterator.primitive =\
- __iterator__ returned a primitive value
-
-msg.assn.create.strict =\
- Assignment to undeclared variable {0}
-
-msg.ref.undefined.prop =\
- Reference to undefined property "{0}"
-
-msg.prop.not.found =\
- Property {0} not found.
-
-msg.invalid.type =\
- Invalid JavaScript value of type {0}
-
-msg.primitive.expected =\
- Primitive type expected (had {0} instead)
-
-msg.namespace.expected =\
- Namespace object expected to left of :: (found {0} instead)
-
-msg.null.to.object =\
- Cannot convert null to an object.
-
-msg.undef.to.object =\
- Cannot convert undefined to an object.
-
-msg.cyclic.value =\
- Cyclic {0} value not allowed.
-
-msg.is.not.defined =\
- "{0}" is not defined.
-
-msg.undef.prop.read =\
- Cannot read property "{1}" from {0}
-
-msg.undef.prop.write =\
- Cannot set property "{1}" of {0} to "{2}"
-
-msg.undef.prop.delete =\
- Cannot delete property "{1}" of {0}
-
-msg.undef.method.call =\
- Cannot call method "{1}" of {0}
-
-msg.undef.with =\
- Cannot apply "with" to {0}
-
-msg.isnt.function =\
- {0} is not a function, it is {1}.
-
-msg.isnt.function.in =\
- Cannot call property {0} in object {1}. It is not a function, it is "{2}".
-
-msg.function.not.found =\
- Cannot find function {0}.
-
-msg.function.not.found.in =\
- Cannot find function {0} in object {1}.
-
-msg.isnt.xml.object =\
- {0} is not an xml object.
-
-msg.no.ref.to.get =\
- {0} is not a reference to read reference value.
-
-msg.no.ref.to.set =\
- {0} is not a reference to set reference value to {1}.
-
-msg.no.ref.from.function =\
- Function {0} can not be used as the left-hand side of assignment \
- or as an operand of ++ or -- operator.
-
-msg.bad.default.value =\
- Object''s getDefaultValue() method returned an object.
-
-msg.instanceof.not.object = \
- Can''t use instanceof on a non-object.
-
-msg.instanceof.bad.prototype = \
- ''prototype'' property of {0} is not an object.
-
-msg.bad.radix = \
- illegal radix {0}.
-
-# ScriptableObject
-msg.default.value =\
- Cannot find default value for object.
-
-msg.zero.arg.ctor =\
- Cannot load class "{0}" which has no zero-parameter constructor.
-
-msg.ctor.multiple.parms =\
- Can''t define constructor or class {0} since more than one \
- constructor has multiple parameters.
-
-msg.extend.scriptable =\
- {0} must extend ScriptableObject in order to define property {1}.
-
-msg.bad.getter.parms =\
- In order to define a property, getter {0} must have zero parameters \
- or a single ScriptableObject parameter.
-
-msg.obj.getter.parms =\
- Expected static or delegated getter {0} to take a ScriptableObject parameter.
-
-msg.getter.static =\
- Getter and setter must both be static or neither be static.
-
-msg.setter.return =\
- Setter must have void return type: {0}
-
-msg.setter2.parms =\
- Two-parameter setter must take a ScriptableObject as its first parameter.
-
-msg.setter1.parms =\
- Expected single parameter setter for {0}
-
-msg.setter2.expected =\
- Expected static or delegated setter {0} to take two parameters.
-
-msg.setter.parms =\
- Expected either one or two parameters for setter.
-
-msg.setter.bad.type =\
- Unsupported parameter type "{0}" in setter "{1}".
-
-msg.add.sealed =\
- Cannot add a property to a sealed object: {0}.
-
-msg.remove.sealed =\
- Cannot remove a property from a sealed object: {0}.
-
-msg.modify.sealed =\
- Cannot modify a property of a sealed object: {0}.
-
-msg.modify.readonly =\
- Cannot modify readonly property: {0}.
-
-# TokenStream
-msg.missing.exponent =\
- missing exponent
-
-msg.caught.nfe =\
- number format error
-
-msg.unterminated.string.lit =\
- unterminated string literal
-
-msg.unterminated.mstring.appjet =\
- unterminated multi-line string literal
-
-msg.unterminated.comment =\
- unterminated comment
-
-msg.unterminated.re.lit =\
- unterminated regular expression literal
-
-msg.invalid.re.flag =\
- invalid flag after regular expression
-
-msg.no.re.input.for =\
- no input for {0}
-
-msg.illegal.character =\
- illegal character
-
-msg.illegal.character.appjet =\
- illegal character: {0}
-
-msg.invalid.escape =\
- invalid Unicode escape sequence
-
-msg.bad.namespace =\
- not a valid default namespace statement. \
- Syntax is: default xml namespace = EXPRESSION;
-
-# TokensStream warnings
-msg.bad.octal.literal =\
- illegal octal literal digit {0}; interpreting it as a decimal digit
-
-msg.reserved.keyword =\
- illegal usage of future reserved keyword {0}; interpreting it as ordinary identifier
-
-# LiveConnect errors
-msg.java.internal.field.type =\
- Internal error: type conversion of {0} to assign to {1} on {2} failed.
-
-msg.java.conversion.implicit_method =\
- Can''t find converter method "{0}" on class {1}.
-
-msg.java.method.assign =\
- Java method "{0}" cannot be assigned to.
-
-msg.java.internal.private =\
- Internal error: attempt to access private/protected field "{0}".
-
-msg.java.no_such_method =\
- Can''t find method {0}.
-
-msg.script.is.not.constructor =\
- Script objects are not constructors.
-
-msg.nonjava.method =\
- Java method "{0}" was invoked with {1} as "this" value that can not be converted to Java type {2}.
-
-msg.java.member.not.found =\
- Java class "{0}" has no public instance field or method named "{1}".
-
-msg.java.array.index.out.of.bounds =\
- Array index {0} is out of bounds [0..{1}].
-
-msg.java.array.member.not.found =\
- Java arrays have no public instance fields or methods named "{0}".
-
-msg.pkg.int =\
- Java package names may not be numbers.
-
-msg.access.prohibited =\
- Access to Java class "{0}" is prohibited.
-
-# ImporterTopLevel
-msg.ambig.import =\
- Ambiguous import: "{0}" and and "{1}".
-
-msg.not.pkg =\
- Function importPackage must be called with a package; had "{0}" instead.
-
-msg.not.class =\
- Function importClass must be called with a class; had "{0}" instead.
-
-msg.not.class.not.pkg =\
- "{0}" is neither a class nor a package.
-
-msg.prop.defined =\
- Cannot import "{0}" since a property by that name is already defined.
-
-#JavaAdapter
-msg.adapter.zero.args =\
- JavaAdapter requires at least one argument.
-
-msg.not.java.class.arg = \
-Argument {0} is not Java class: {1}.
-
-#JavaAdapter
-msg.only.one.super = \
-Only one class may be extended by a JavaAdapter. Had {0} and {1}.
-
-
-# Arrays
-msg.arraylength.bad =\
- Inappropriate array length.
-
-# Arrays
-msg.arraylength.too.big =\
- Array length {0} exceeds supported capacity limit.
-
-# URI
-msg.bad.uri =\
- Malformed URI sequence.
-
-# Number
-msg.bad.precision =\
- Precision {0} out of range.
-
-# NativeGenerator
-msg.send.newborn =\
- Attempt to send value to newborn generator
-
-msg.already.exec.gen =\
- Already executing generator
-
-msg.StopIteration.invalid =\
- StopIteration may not be changed to an arbitrary object.
-
-# Interpreter
-msg.yield.closing =\
- Yield from closing generator
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages_fr.properties b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages_fr.properties
deleted file mode 100644
index fc87c97..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages_fr.properties
+++ /dev/null
@@ -1,329 +0,0 @@
-#
-# French JavaScript messages file.
-#
-# ***** 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 Aviva Inc. code, released
-# March 5, 2004.
-#
-# The Initial Developer of the Original Code is
-# Aviva Inc.
-# Portions created by the Initial Developer are Copyright (C) 2004
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Eugene Aresteanu
-#
-# 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 *****
-
-msg.dup.parms =\
- Le nom de param\u00E8tre "{0}" existe d\u00E9j\u00E0.
-msg.too.big.jump =\
- Programme trop complexe : d\u00E9calage de saut trop important
-msg.too.big.index =\
- Programme trop complexe : l''indice interne d\u00E9passe la limite de 64 ko
-msg.ctor.not.found =\
- Le constructeur de "{0}" est introuvable
-msg.not.ctor =\
- {0} n''est pas un constructeur
-msg.varargs.ctor =\
- La m\u00E9thode ou le constructeur "{0}" doit \u00EAtre statique avec la signature "(Context cx, arguments Object[], Function ctorObj, boolean inNewExpr)" pour d\u00E9finir un constructeur d''arguments de variable.
-msg.varargs.fun =\
- La m\u00E9thode "{0}" doit \u00EAtre statique avec la signature "(Context cx, Scriptable thisObj, arguments Object[], Function funObj)" pour d\u00E9finir une fonction d''arguments de variable
-msg.incompat.call =\
- La m\u00E9thode "{0}" a \u00E9t\u00E9 appel\u00E9e dans un objet non compatible
-msg.bad.parms =\
- Les param\u00E8tres de la m\u00E9thode sont incorrects pour "{0}"
-msg.no.overload =\
- La m\u00E9thode "{0}" appara\u00EEt plusieurs fois dans la classe "{1}"
-msg.method.not.found =\
- La m\u00E9thode "{0}" est introuvable dans "{1}"
-msg.bad.for.in.lhs =\
- La partie gauche de la boucle for..in est incorrecte
-msg.bad.lhs.assign =\
- La partie gauche de l''affectation est incorrecte
-msg.mult.index =\
- Une seule variable est autoris\u00E9e dans la boucle for..in
-msg.cant.convert =\
- La conversion en type "{0}" est impossible
-msg.cant.call.indirect =\
- La fonction "{0}" doit \u00EAtre appel\u00E9e directement et non par l''interm\u00E9diaire d''une fonction portant un autre nom
-msg.eval.nonstring =\
- Si vous appelez la fonction eval() avec une valeur qui n''appartient pas \u00E0 une cha\u00EEne primitive, c''est la valeur en question qui est renvoy\u00E9e. \u00E9tait-ce votre intention ?
-msg.only.from.new =\
- {0} ne peut \u00EAtre appel\u00E9e qu''\u00E0 partir d''une "nouvelle" expression.
-msg.deprec.ctor =\
- Le constructeur "{0}" est d\u00E9conseill\u00E9
-msg.no.function.ref.found =\
- aucune source n''a \u00E9t\u00E9 trouv\u00E9e pour d\u00E9compiler la r\u00E9f\u00E9rence de fonction {0}
-msg.arg.isnt.array =\
- le second argument de la m\u00E9thode Function.prototype.apply doit \u00EAtre un tableau
-msg.bad.esc.mask =\
- le masque d''\u00E9chappement de cha\u00EEne est incorrect
-msg.cant.instantiate =\
- erreur lors de l''instanciation ({0}) : la classe {1} est une classe interface ou abstract
-msg.bad.ctor.sig =\
- Un constructeur avec une signature incorrecte a \u00E9t\u00E9 d\u00E9tect\u00E9 : {0} qui appelle {1} avec la signature {2}
-msg.not.java.obj =\
- L''argument attendu pour la fonction getClass() doit \u00EAtre un objet Java
-msg.no.java.ctor =\
- Le constructeur Java de "{0}" avec les arguments "{1}" est introuvable
-msg.method.ambiguous =\
- Le choix de la m\u00E9thode Java {0}.{1} correspondant aux types d''argument JavaScript ({2}) est ambigu. Les m\u00E9thodes propos\u00E9es sont les suivantes : {3}
-msg.constructor.ambiguous =\
- Le choix du constructeur Java {0} correspondant aux types d''argument JavaScript ({1}) est ambigu. Les constructeurs propos\u00E9s sont les suivants : {2}
-msg.conversion.not.allowed =\
- Impossible de convertir {0} en {1}
-msg.not.classloader =\
- Le constructeur de "Packages" attend un argument de type java.lang.Classloader
-msg.bad.quant =\
- Le quantificateur {0} est incorrect
-msg.overlarge.max =\
- Le maximum {0} est trop important
-msg.zero.quant =\
- Le quantificateur {0} est nul
-msg.max.lt.min =\
- Le maximum {0} est inf\u00E9rieur au minimum
-msg.unterm.quant =\
- Le quantificateur {0} n''a pas de limite
-msg.unterm.paren =\
- Les parenth\u00E8ses {0} n''ont pas de limite
-msg.unterm.class =\
- La classe de caract\u00E8res {0} n''a pas de limite
-msg.bad.range =\
- La classe de caract\u00E8res contient une plage de valeurs incorrecte
-msg.trail.backslash =\
- \\ au d\u00E9but d''une expression r\u00E9guli\u00E8re
-msg.no.regexp =\
- Les expressions r\u00E9guli\u00E8res ne sont pas disponibles
-msg.bad.backref =\
- la r\u00E9f\u00E9rence ant\u00E9rieure d\u00E9passe le nombre de parenth\u00E8ses de capture
-msg.dup.label =\
- Le libell\u00E9 {0} existe d\u00E9j\u00E0
-msg.undef.label =\
- Le libell\u00E9 {0} n''est pas d\u00E9fini
-msg.bad.break =\
- Le saut non libell\u00E9 doit se trouver dans la boucle ou dans l''aiguillage
-msg.continue.outside =\
- continue doit se trouver dans la boucle
-msg.continue.nonloop =\
- Il n''est possible de continuer que dans l''instruction d''it\u00E9ration libell\u00E9e
-msg.fn.redecl =\
- La fonction "{0}" a \u00E9t\u00E9 de nouveau d\u00E9clar\u00E9e. La d\u00E9finition pr\u00E9c\u00E9dente sera ignor\u00E9e
-msg.no.paren.parms =\
- il manque ''('' avant les param\u00E8tres de la fonction
-msg.no.parm =\
- il manque un param\u00E8tre de forme
-msg.no.paren.after.parms =\
- il manque '')'' apr\u00E8s les param\u00E8tres de forme
-msg.no.brace.body =\
- il manque '{' avant le corps d''une fonction
-msg.no.brace.after.body =\
- il manque ''}'' apr\u00E8s le corps d''une fonction
-msg.no.paren.cond =\
- il manque ''('' avant une condition
-msg.no.paren.after.cond =\
- il manque '')'' apr\u00E8s une condition
-msg.no.semi.stmt =\
- il manque '';'' avant une instruction
-msg.no.name.after.dot =\
- il manque un nom apr\u00E8s un op\u00E9rateur ''.''
-msg.no.bracket.index =\
- il manque '']'' dans l''expression de l''indice
-msg.no.paren.switch =\
- il manque ''('' avant l''expression d''un aiguillage
-msg.no.paren.after.switch =\
- il manque '')'' apr\u00E8s l''expression d''un aiguillage
-msg.no.brace.switch =\
- il manque '{' avant le corps d''un aiguillage
-msg.bad.switch =\
- l''instruction d''aiguillage est incorrecte
-msg.no.colon.case =\
- il manque '':'' apr\u00E8s l''expression d''un cas
-msg.no.while.do =\
- il manque ''while'' apr\u00E8s le corps d''une boucle do-loop
-msg.no.paren.for =\
- il manque ''('' apr\u00E8s for
-msg.no.semi.for =\
- Il manque '';'' apr\u00E8s l''initialiseur for-loop
-msg.no.semi.for.cond =\
- il manque '';'' apr\u00E8s la condition for-loop
-msg.no.paren.for.ctrl =\
- il manque '')'' apr\u00E8s le contrôle for-loop
-msg.no.paren.with =\
- il manque ''('' avant un objet with-statement
-msg.no.paren.after.with =\
- il manque '')'' apr\u00E8s un objet with-statement
-msg.bad.return =\
- la valeur renvoy\u00E9e est incorrecte
-msg.no.brace.block =\
- il manque ''}'' dans une instruction compos\u00E9e
-msg.bad.label =\
- le libell\u00E9 est incorrect
-msg.bad.var =\
- il manque un nom de variable
-msg.bad.var.init =\
- l''initialisation de la variable est incorrecte
-msg.no.colon.cond =\
- il manque '':'' dans une expression conditionnelle
-msg.no.paren.arg =\
- il manque '')'' apr\u00E8s une liste d''arguments
-msg.no.bracket.arg =\
- il manque '']'' apr\u00E8s une liste d''\u00E9l\u00E9ments
-msg.bad.prop =\
- l''identifiant de propri\u00E9t\u00E9 est incorrect
-msg.no.colon.prop =\
- il manque '':'' apr\u00E8s un identifiant de propri\u00E9t\u00E9
-msg.no.brace.prop =\
- il manque ''}'' apr\u00E8s une liste de propri\u00E9t\u00E9s
-msg.no.paren =\
- il manque '')'' dans des parenth\u00E8ses
-msg.reserved.id =\
- l''identifiant est un mot r\u00E9serv\u00E9
-msg.no.paren.catch =\
- il manque ''('' avant une condition catch-block
-msg.bad.catchcond =\
- la condition catch-block est incorrecte
-msg.catch.unreachable =\
- aucune clause catch suivant une interception non qualifi\u00E9e ne peut \u00EAtre atteinte
-msg.no.brace.catchblock =\
- il manque '{' avant le corps catch-block
-msg.try.no.catchfinally =\
- ''try'' a \u00E9t\u00E9 d\u00E9tect\u00E9 sans ''catch'' ni ''finally''
-msg.syntax =\
- erreur de syntaxe
-msg.assn.create =\
- Une variable va \u00EAtre cr\u00E9\u00E9e en raison de l''affectation \u00E0 un ''{0}'' non d\u00E9fini. Ajoutez une instruction de variable \u00E0 la port\u00E9e sup\u00E9rieure pour que cet avertissement ne soit plus affich\u00E9
-msg.prop.not.found =\
- La propri\u00E9t\u00E9 est introuvable
-msg.invalid.type =\
- Valeur JavaScript de type {0} incorrecte
-msg.primitive.expected =\
- Un type primitif \u00E9tait attendu (et non {0})
-msg.null.to.object =\
- Il est impossible de convertir la valeur null en objet
-msg.undef.to.object =\
- Il est impossible de convertir une valeur non d\u00E9finie en objet
-msg.cyclic.value =\
- La valeur cyclique {0} n''est pas autoris\u00E9e
-msg.is.not.defined =\
- "{0}" n''est pas d\u00E9fini
-msg.isnt.function =\
- {0} n''est pas une fonction, est un {1}
-msg.bad.default.value =\
- La m\u00E9thode getDefaultValue() de l''objet a renvoy\u00E9 un objet
-msg.instanceof.not.object =\
- Il est impossible d''utiliser une instance d''un \u00E9l\u00E9ment autre qu''un objet
-msg.instanceof.bad.prototype =\
- La propri\u00E9t\u00E9 ''prototype'' de {0} n''est pas un objet
-msg.bad.radix =\
- la base {0} n''est pas autoris\u00E9e
-msg.default.value =\
- La valeur par d\u00E9faut de l''objet est introuvable
-msg.zero.arg.ctor =\
- Il est impossible de charger la classe "{0}", qui ne poss\u00E8de pas de constructeur de param\u00E8tre z\u00E9ro
-msg.multiple.ctors =\
- Les m\u00E9thodes {0} et {1} ont \u00E9t\u00E9 d\u00E9tect\u00E9es alors qu''il est impossible d''utiliser plusieurs m\u00E9thodes constructor
-msg.ctor.multiple.parms =\
- Il est impossible de d\u00E9finir le constructeur ou la classe {0} car plusieurs constructeurs poss\u00E8dent plusieurs param\u00E8tres
-msg.extend.scriptable =\
- {0} doit \u00E9tendre ScriptableObject afin de d\u00E9finir la propri\u00E9t\u00E9 {1}
-msg.bad.getter.parms =\
- Pour d\u00E9finir une propri\u00E9t\u00E9, la m\u00E9thode d''obtention {0} doit avoir des param\u00E8tres z\u00E9ro ou un seul param\u00E8tre ScriptableObject
-msg.obj.getter.parms =\
- La m\u00E9thode d''obtention statique ou d\u00E9l\u00E9gu\u00E9e {0} doit utiliser un param\u00E8tre ScriptableObject
-msg.getter.static =\
- La m\u00E9thode d''obtention et la m\u00E9thode de d\u00E9finition doivent toutes deux avoir le m\u00EAme \u00E9tat (statique ou non)
-msg.setter2.parms =\
- La m\u00E9thode de d\u00E9finition \u00E0 deux param\u00E8tres doit utiliser un param\u00E8tre ScriptableObject comme premier param\u00E8tre
-msg.setter1.parms =\
- Une m\u00E9thode d''obtention \u00E0 param\u00E8tre unique est attendue pour {0}
-msg.setter2.expected =\
- La m\u00E9thode de d\u00E9finition statique ou d\u00E9l\u00E9gu\u00E9e {0} doit utiliser deux param\u00E8tres
-msg.setter.parms =\
- Un ou deux param\u00E8tres sont attendus pour la m\u00E9thode de d\u00E9finition
-msg.add.sealed =\
- Il est impossible d''ajouter une propri\u00E9t\u00E9 \u00E0 un objet ferm\u00E9
-msg.remove.sealed =\
- Il est impossible de supprimer une propri\u00E9t\u00E9 d''un objet ferm\u00E9
-msg.token.replaces.pushback =\
- le jeton de non-obtention {0} remplace le jeton de renvoi {1}
-msg.missing.exponent =\
- il manque un exposant
-msg.caught.nfe =\
- erreur de format de nombre : {0}
-msg.unterminated.string.lit =\
- le litt\u00E9ral de la cha\u00EEne n''a pas de limite
-msg.unterminated.comment =\
- le commentaire n''a pas de limite
-msg.unterminated.re.lit =\
- le litt\u00E9ral de l''expression r\u00E9guli\u00E8re n''a pas de limite
-msg.invalid.re.flag =\
- une expression r\u00E9guli\u00E8re est suivie d''un indicateur incorrect
-msg.no.re.input.for =\
- il n''y a pas d''entr\u00E9e pour {0}
-msg.illegal.character =\
- caract\u00E8re non autoris\u00E9
-msg.invalid.escape =\
- la s\u00E9quence d''\u00E9chappement Unicode est incorrecte
-msg.bad.octal.literal =\
- le chiffre octal du litt\u00E9ral, {0}, n''est pas autoris\u00E9 et sera interpr\u00E9t\u00E9 comme un chiffre d\u00E9cimal
-msg.reserved.keyword =\
- l''utilisation du futur mot-cl\u00E9 r\u00E9serv\u00E9 {0} n''est pas autoris\u00E9e et celui-ci sera interpr\u00E9t\u00E9 comme un identifiant ordinaire
-msg.undefined =\
- La valeur non d\u00E9finie ne poss\u00E8de pas de propri\u00E9t\u00E9
-msg.java.internal.field.type =\
- Erreur interne : la conversion de type de {0} afin d''affecter {1} \u00E0 {2} a \u00E9chou\u00E9
-msg.java.conversion.implicit_method =\
- La m\u00E9thode de conversion "{0}" est introuvable dans la classe {1}
-sg.java.method.assign =\
- La m\u00E9thode Java "{0}" ne peut pas \u00EAtre affect\u00E9e \u00E0
-msg.java.internal.private =\
- Erreur interne : une tentative d''acc\u00E9der \u00E0 un champ "{0}" priv\u00E9/prot\u00E9g\u00E9 a \u00E9t\u00E9 d\u00E9tect\u00E9e
-msg.java.no_such_method =\
- La m\u00E9thode ''{0}'' est introuvable
-msg.script.is.not.constructor =\
- Les objets Script ne sont pas des constructeurs
-msg.nonjava.method =\
- La m\u00E9thode Java "{0}" a \u00E9t\u00E9 appel\u00E9e avec une valeur ''this'' qui n''est pas un objet Java
-msg.java.member.not.found =\
- La classe Java "{0}" ne poss\u00E8de aucun champ ou aucune m\u00E9thode d''instance publique appel\u00E9 "{1}"
-msg.java.array.index.out.of.bounds =\
- Array index {0} is out of bounds [0..{1}].
-msg.pkg.int =\
- Les noms de package Java ne peuvent pas \u00EAtre des nombres
-msg.ambig.import =\
- Importation ambigu\u00EB : "{0}" et "{1}"
-msg.not.pkg =\
- La fonction importPackage doit \u00EAtre appel\u00E9e avec un package et non avec "{0}"
-msg.not.class =\
- La fonction importClass doit \u00EAtre appel\u00E9e avec une classe et non avec "{0}"
-msg.prop.defined =\
- Il est impossible d''importer "{0}" car une propri\u00E9t\u00E9 portant le m\u00EAme nom a d\u00E9j\u00E0 \u00E9t\u00E9 d\u00E9finie
-sg.arraylength.bad =\
- La longueur du tableau n''est pas appropri\u00E9e
-msg.bad.uri =\
- La s\u00E9quence URI n''est pas form\u00E9e correctement
-msg.bad.precision =\
- La pr\u00E9cision {0} ne se trouve pas dans la plage de valeurs
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableInputStream.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableInputStream.java
deleted file mode 100644
index 476ff69..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableInputStream.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- 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 serialization code, released
- * Sept. 25, 2001.
- *
- * The Initial Developer of the Original Code is
- * Norris Boyd.
- * Portions created by the Initial Developer are Copyright (C) 2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- * Igor Bukanov
- * Attila Szegedi
- *
- * 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 ***** */
-
-// API class
-
-package org.mozilla.javascript.serialize;
-
-import java.io.*;
-
-import org.mozilla.javascript.*;
-
-/**
- * Class ScriptableInputStream is used to read in a JavaScript
- * object or function previously serialized with a ScriptableOutputStream.
- * References to names in the exclusion list
- * replaced with references to the top-level scope specified during
- * creation of the ScriptableInputStream.
- *
- * @author Norris Boyd
- */
-
-public class ScriptableInputStream extends ObjectInputStream {
-
- /**
- * Create a ScriptableInputStream.
- * @param in the InputStream to read from.
- * @param scope the top-level scope to create the object in.
- */
- public ScriptableInputStream(InputStream in, Scriptable scope)
- throws IOException
- {
- super(in);
- this.scope = scope;
- enableResolveObject(true);
- Context cx = Context.getCurrentContext();
- if (cx != null) {
- this.classLoader = cx.getApplicationClassLoader();
- }
- }
-
- protected Class resolveClass(ObjectStreamClass desc)
- throws IOException, ClassNotFoundException
- {
- String name = desc.getName();
- if (classLoader != null) {
- try {
- return classLoader.loadClass(name);
- } catch (ClassNotFoundException ex) {
- // fall through to default loading
- }
- }
- return super.resolveClass(desc);
- }
-
- protected Object resolveObject(Object obj)
- throws IOException
- {
- if (obj instanceof ScriptableOutputStream.PendingLookup) {
- String name = ((ScriptableOutputStream.PendingLookup)obj).getName();
- obj = ScriptableOutputStream.lookupQualifiedName(scope, name);
- if (obj == Scriptable.NOT_FOUND) {
- throw new IOException("Object " + name + " not found upon " +
- "deserialization.");
- }
- }else if (obj instanceof UniqueTag) {
- obj = ((UniqueTag)obj).readResolve();
- }else if (obj instanceof Undefined) {
- obj = ((Undefined)obj).readResolve();
- }
- return obj;
- }
-
- private Scriptable scope;
- private ClassLoader classLoader;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableOutputStream.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableOutputStream.java
deleted file mode 100644
index 5ba0d74..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableOutputStream.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/* -*- 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 serialization code, released
- * Sept. 25, 2001.
- *
- * The Initial Developer of the Original Code is
- * Norris Boyd.
- * Portions created by the Initial Developer are Copyright (C) 2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- * Attila Szegedi
- *
- * 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.serialize;
-
-import java.util.Hashtable;
-import java.util.StringTokenizer;
-import java.io.*;
-
-import org.mozilla.javascript.*;
-
-/**
- * Class ScriptableOutputStream is an ObjectOutputStream used
- * to serialize JavaScript objects and functions. Note that
- * compiled functions currently cannot be serialized, only
- * interpreted functions. The top-level scope containing the
- * object is not written out, but is instead replaced with
- * another top-level object when the ScriptableInputStream
- * reads in this object. Also, object corresponding to names
- * added to the exclude list are not written out but instead
- * are looked up during deserialization. This approach avoids
- * the creation of duplicate copies of standard objects
- * during deserialization.
- *
- * @author Norris Boyd
- */
-
-// API class
-
-public class ScriptableOutputStream extends ObjectOutputStream {
-
- /**
- * ScriptableOutputStream constructor.
- * Creates a ScriptableOutputStream for use in serializing
- * JavaScript objects. Calls excludeStandardObjectNames.
- *
- * @param out the OutputStream to write to.
- * @param scope the scope containing the object.
- */
- public ScriptableOutputStream(OutputStream out, Scriptable scope)
- throws IOException
- {
- super(out);
- this.scope = scope;
- table = new Hashtable(31);
- table.put(scope, "");
- enableReplaceObject(true);
- excludeStandardObjectNames();
- }
-
- /**
- * Adds a qualified name to the list of object to be excluded from
- * serialization. Names excluded from serialization are looked up
- * in the new scope and replaced upon deserialization.
- * @param name a fully qualified name (of the form "a.b.c", where
- * "a" must be a property of the top-level object). The object
- * need not exist, in which case the name is ignored.
- * @throws IllegalArgumentException if the object is not a
- * {@link Scriptable}.
- */
- public void addOptionalExcludedName(String name) {
- Object obj = lookupQualifiedName(scope, name);
- if(obj != null && obj != UniqueTag.NOT_FOUND) {
- if (!(obj instanceof Scriptable)) {
- throw new IllegalArgumentException(
- "Object for excluded name " + name +
- " is not a Scriptable, it is " +
- obj.getClass().getName());
- }
- table.put(obj, name);
- }
- }
-
- /**
- * Adds a qualified name to the list of object to be excluded from
- * serialization. Names excluded from serialization are looked up
- * in the new scope and replaced upon deserialization.
- * @param name a fully qualified name (of the form "a.b.c", where
- * "a" must be a property of the top-level object)
- * @throws IllegalArgumentException if the object is not found or is not
- * a {@link Scriptable}.
- */
- public void addExcludedName(String name) {
- Object obj = lookupQualifiedName(scope, name);
- if (!(obj instanceof Scriptable)) {
- throw new IllegalArgumentException("Object for excluded name " +
- name + " not found.");
- }
- table.put(obj, name);
- }
-
- /**
- * Returns true if the name is excluded from serialization.
- */
- public boolean hasExcludedName(String name) {
- return table.get(name) != null;
- }
-
- /**
- * Removes a name from the list of names to exclude.
- */
- public void removeExcludedName(String name) {
- table.remove(name);
- }
-
- /**
- * Adds the names of the standard objects and their
- * prototypes to the list of excluded names.
- */
- public void excludeStandardObjectNames() {
- String[] names = { "Object", "Object.prototype",
- "Function", "Function.prototype",
- "String", "String.prototype",
- "Math", // no Math.prototype
- "Array", "Array.prototype",
- "Error", "Error.prototype",
- "Number", "Number.prototype",
- "Date", "Date.prototype",
- "RegExp", "RegExp.prototype",
- "Script", "Script.prototype",
- "Continuation", "Continuation.prototype",
- };
- for (int i=0; i < names.length; i++) {
- addExcludedName(names[i]);
- }
-
- String[] optionalNames = {
- "XML", "XML.prototype",
- "XMLList", "XMLList.prototype",
- };
- for (int i=0; i < optionalNames.length; i++) {
- addOptionalExcludedName(optionalNames[i]);
- }
- }
-
- static Object lookupQualifiedName(Scriptable scope,
- String qualifiedName)
- {
- StringTokenizer st = new StringTokenizer(qualifiedName, ".");
- Object result = scope;
- while (st.hasMoreTokens()) {
- String s = st.nextToken();
- result = ScriptableObject.getProperty((Scriptable)result, s);
- if (result == null || !(result instanceof Scriptable))
- break;
- }
- return result;
- }
-
- static class PendingLookup implements Serializable
- {
- static final long serialVersionUID = -2692990309789917727L;
-
- PendingLookup(String name) { this.name = name; }
-
- String getName() { return name; }
-
- private String name;
- }
-
- protected Object replaceObject(Object obj) throws IOException
- {
- String name = (String) table.get(obj);
- if (name == null)
- return obj;
- return new PendingLookup(name);
- }
-
- private Scriptable scope;
- private Hashtable table;
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLLib.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLLib.java
deleted file mode 100644
index da57ddf..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLLib.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * 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.xml;
-
-import org.mozilla.javascript.*;
-
-public abstract class XMLLib
-{
- private static final Object XML_LIB_KEY = new Object();
-
- /**
- An object which specifies an XMLLib implementation to be used at runtime.
-
- This interface should be considered experimental. It may be better
- (and certainly more flexible) to write an interface that returns an
- XMLLib object rather than a class name, for example. But that would
- cause many more ripple effects in the code, all the way back to
- {@link ScriptRuntime}.
- */
- public static abstract class Factory {
- public static Factory create(final String className) {
- return new Factory() {
- public String getImplementationClassName() {
- return className;
- }
- };
- }
-
- public abstract String getImplementationClassName();
- }
-
- public static XMLLib extractFromScopeOrNull(Scriptable scope)
- {
- ScriptableObject so = ScriptRuntime.getLibraryScopeOrNull(scope);
- if (so == null) {
- // If library is not yet initialized, return null
- return null;
- }
-
- // Ensure lazily initialization of real XML library instance
- // which is done on first access to XML property
- ScriptableObject.getProperty(so, "XML");
-
- return (XMLLib)so.getAssociatedValue(XML_LIB_KEY);
- }
-
- public static XMLLib extractFromScope(Scriptable scope)
- {
- XMLLib lib = extractFromScopeOrNull(scope);
- if (lib != null) {
- return lib;
- }
- String msg = ScriptRuntime.getMessage0("msg.XML.not.available");
- throw Context.reportRuntimeError(msg);
- }
-
- protected final XMLLib bindToScope(Scriptable scope)
- {
- ScriptableObject so = ScriptRuntime.getLibraryScopeOrNull(scope);
- if (so == null) {
- // standard library should be initialized at this point
- throw new IllegalStateException();
- }
- return (XMLLib)so.associateValue(XML_LIB_KEY, this);
- }
-
- public abstract boolean isXMLName(Context cx, Object name);
-
- public abstract Ref nameRef(Context cx, Object name,
- Scriptable scope, int memberTypeFlags);
-
- public abstract Ref nameRef(Context cx, Object namespace, Object name,
- Scriptable scope, int memberTypeFlags);
-
- /**
- * Escapes the reserved characters in a value of an attribute.
- *
- * @param value Unescaped text
- * @return The escaped text
- */
- public abstract String escapeAttributeValue(Object value);
-
- /**
- * Escapes the reserved characters in a value of a text node.
- *
- * @param value Unescaped text
- * @return The escaped text
- */
- public abstract String escapeTextValue(Object value);
-
-
- /**
- * Construct namespace for default xml statement.
- */
- public abstract Object toDefaultXmlNamespace(Context cx, Object uriValue);
-}
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLObject.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLObject.java
deleted file mode 100644
index 5033564..0000000
--- a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLObject.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- 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-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Igor Bukanov
- * Ethan Hugg
- * Terry Lucas
- * Milen Nankov
- *
- * 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.xml;
-
-import org.mozilla.javascript.*;
-
-/**
- * This Interface describes what all XML objects (XML, XMLList) should have in common.
- *
- */
-public abstract class XMLObject extends IdScriptableObject
-{
- public XMLObject()
- {
- }
-
- public XMLObject(Scriptable scope, Scriptable prototype)
- {
- super(scope, prototype);
- }
-
- /**
- * Implementation of ECMAScript [[Has]].
- */
- public abstract boolean ecmaHas(Context cx, Object id);
-
- /**
- * Implementation of ECMAScript [[Get]].
- */
- public abstract Object ecmaGet(Context cx, Object id);
-
- /**
- * Implementation of ECMAScript [[Put]].
- */
- public abstract void ecmaPut(Context cx, Object id, Object value);
-
- /**
- * Implementation of ECMAScript [[Delete]].
- */
- public abstract boolean ecmaDelete(Context cx, Object id);
-
- /**
- * Return an additional object to look for methods that runtime should
- * consider during method search. Return null if no such object available.
- */
- public abstract Scriptable getExtraMethodSource(Context cx);
-
- /**
- * Generic reference to implement x.@y, x..y etc.
- */
- public abstract Ref memberRef(Context cx, Object elem,
- int memberTypeFlags);
-
- /**
- * Generic reference to implement x::ns, x.@ns::y, x..@ns::y etc.
- */
- public abstract Ref memberRef(Context cx, Object namespace, Object elem,
- int memberTypeFlags);
-
- /**
- * Wrap this object into NativeWith to implement the with statement.
- */
- public abstract NativeWith enterWith(Scriptable scope);
-
- /**
- * Wrap this object into NativeWith to implement the .() query.
- */
- public abstract NativeWith enterDotQuery(Scriptable scope);
-
- /**
- * Custom <tt>+</tt> operator.
- * Should return {@link Scriptable#NOT_FOUND} if this object does not have
- * custom addition operator for the given value,
- * or the result of the addition operation.
- * <p>
- * The default implementation returns {@link Scriptable#NOT_FOUND}
- * to indicate no custom addition operation.
- *
- * @param cx the Context object associated with the current thread.
- * @param thisIsLeft if true, the object should calculate this + value
- * if false, the object should calculate value + this.
- * @param value the second argument for addition operation.
- */
- public Object addValues(Context cx, boolean thisIsLeft, Object value)
- {
- return Scriptable.NOT_FOUND;
- }
-
-}