зеркало из https://github.com/mozilla/gecko-dev.git
Committing E4X parser and runtime proxies: see enhancement report 242805.
This is based on code contributed to Rhino by AgileDelta, Inc, www.agiledelta.com and in particular by Ethan Hugg Terry Lucas Milen Nankov John Schneider Thanks!
This commit is contained in:
Родитель
20e64eb7e5
Коммит
0659e0b714
|
@ -0,0 +1,62 @@
|
|||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Rhino code, released
|
||||
# May 6, 1999.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Igor Bukanov
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
|
||||
name: rhino
|
||||
Name: Rhino
|
||||
version: 1_6R1pre
|
||||
|
||||
build.dir: build
|
||||
rhino.jar: js.jar
|
||||
small-rhino.jar: smalljs.jar
|
||||
|
||||
dist.name: rhino${version}
|
||||
dist.dir: ${build.dir}/${dist.name}
|
||||
|
||||
# compilation destionation
|
||||
classes: ${build.dir}/classes
|
||||
|
||||
# compilation settings
|
||||
debug: on
|
||||
target-jvm: 1.1
|
||||
|
||||
# jar generation settings
|
||||
jar-compression: true
|
||||
|
||||
# optional external packages
|
||||
jarlib: jarlib
|
||||
xbean.jar: ${jarlib}/xbean.jar
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -8,54 +8,51 @@ Requires Ant version 1.2 or later
|
|||
<project name="Rhino" default="help" basedir=".">
|
||||
|
||||
<target name="properties">
|
||||
<property name="name" value="rhino"/>
|
||||
<property name="Name" value="Rhino"/>
|
||||
<property name="version" value="1_6R1pre"/>
|
||||
<property name="rhino.jar" value="js.jar"/>
|
||||
<property name="small-rhino.jar" value="smalljs.jar"/>
|
||||
<property file="build.properties"/>
|
||||
|
||||
<property name="jar-compression" value="true"/>
|
||||
<property name="debug" value="on"/>
|
||||
|
||||
<property name="build.dir" value="./build"/>
|
||||
<property name="classes" value="${build.dir}/classes"/>
|
||||
|
||||
<property name="dist.name" value="rhino${version}"/>
|
||||
<property name="dist.dir" value="${build.dir}/${dist.name}"/>
|
||||
<property name="dist.src" value="${dist.dir}/src"/>
|
||||
<property name="dist.toolsrc" value="${dist.dir}/toolsrc"/>
|
||||
<property name="dist.examples" value="${dist.dir}/examples"/>
|
||||
<property name="dist.docs" value="${dist.dir}/docs"/>
|
||||
<property name="dist.apidocs" value="${dist.docs}/apidocs"/>
|
||||
<property name="dist.file" value="rhino${version}.zip"/>
|
||||
<property name="dist.source-only-zip" value="rhino${version}-sources.zip"/>
|
||||
|
||||
<property file="apiClasses.properties"/>
|
||||
<property name="docsrc.dir" value="docs"/>
|
||||
<property name="dist.docsrc.dir" value="src/docs"/>
|
||||
<property name="xmlimplsrc-build-file"
|
||||
location="xmlimplsrc/build.xml"/>
|
||||
|
||||
<available property="xmlimplsrc-present?"
|
||||
file="${xmlimplsrc-build-file}" />
|
||||
|
||||
</target>
|
||||
|
||||
<target name="init" depends="properties">
|
||||
<mkdir dir="${build.dir}"/>
|
||||
<mkdir dir="${classes}"/>
|
||||
<mkdir dir="${dist.dir}"/>
|
||||
<mkdir dir="${dist.src}"/>
|
||||
<mkdir dir="${dist.toolsrc}"/>
|
||||
<mkdir dir="${dist.examples}"/>
|
||||
<mkdir dir="${dist.docs}"/>
|
||||
<mkdir dir="${dist.apidocs}"/>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init">
|
||||
<ant dir="src" target="compile"/>
|
||||
<ant dir="toolsrc" target="compile"/>
|
||||
<ant antfile="src/build.xml" target="compile"/>
|
||||
<ant antfile="toolsrc/build.xml" target="compile"/>
|
||||
<antcall target="xmlimplsrc-compile" />
|
||||
</target>
|
||||
|
||||
<target name="copy-source" depends="init">
|
||||
<ant antfile="src/build.xml" target="copy-source"/>
|
||||
<ant antfile="toolsrc/build.xml" target="copy-source"/>
|
||||
<antcall target="xmlimplsrc-copy-source" />
|
||||
<copy todir="${dist.dir}" file="build.xml"/>
|
||||
<copy todir="${dist.dir}" file="build.properties"/>
|
||||
<copy todir="${dist.dir}" file="apiClasses.properties"/>
|
||||
</target>
|
||||
|
||||
<target name="copy-source" depends="init">
|
||||
<ant dir="src" target="copy-source"/>
|
||||
<ant dir="toolsrc" target="copy-source"/>
|
||||
<copy todir="${dist.dir}" file="build.xml"/>
|
||||
<copy todir="${dist.dir}" file="apiClasses.properties"/>
|
||||
<target name="xmlimplsrc-compile" if="xmlimplsrc-present?">
|
||||
<echo>Calling ${xmlimplsrc-build-file}</echo>
|
||||
<!-- Ignore compilation errors under JDK less then 1.4 -->
|
||||
<property name="xmlimpl.compile.failonerror" value="no"/>
|
||||
<ant antfile="${xmlimplsrc-build-file}" target="compile"/>
|
||||
</target>
|
||||
|
||||
<target name="xmlimplsrc-copy-source" if="xmlimplsrc-present?">
|
||||
<echo>Calling ${xmlimplsrc-build-file}</echo>
|
||||
<ant antfile="${xmlimplsrc-build-file}" target="copy-source"/>
|
||||
</target>
|
||||
|
||||
<target name="jar" depends="compile">
|
||||
|
@ -84,7 +81,8 @@ Requires Ant version 1.2 or later
|
|||
</target>
|
||||
|
||||
<target name="copy-examples" depends="init">
|
||||
<copy todir="${dist.examples}">
|
||||
<mkdir dir="${dist.dir}/examples"/>
|
||||
<copy todir="${dist.dir}/examples">
|
||||
<fileset dir="examples" includes="*.java,*.js,*.html" />
|
||||
</copy>
|
||||
</target>
|
||||
|
@ -105,18 +103,19 @@ Requires Ant version 1.2 or later
|
|||
</target>
|
||||
|
||||
<target name="copy-docs" depends="init">
|
||||
<echo message="copy from ${docsrc.dir}"/>
|
||||
<copy todir="${dist.docs}">
|
||||
<fileset dir="${docsrc.dir}"
|
||||
includes="**/*.html,**/*.jpg,**/*.gif" />
|
||||
<echo message="copy from docs"/>
|
||||
<mkdir dir="${dist.dir}/docs"/>
|
||||
<copy todir="${dist.dir}/docs">
|
||||
<fileset dir="docs" includes="**/*.html,**/*.jpg,**/*.gif" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="javadoc" depends="compile,copy-docs">
|
||||
<mkdir dir="${dist.dir}/docs/apidocs"/>
|
||||
<javadoc sourcefiles="${apiClasses}"
|
||||
sourcepath="src"
|
||||
destdir="${dist.apidocs}"
|
||||
overview="${dist.docs}/api.html"
|
||||
destdir="${dist.dir}/docs/apidocs"
|
||||
overview="${dist.dir}/docs/api.html"
|
||||
version="true"
|
||||
author="true"
|
||||
windowtitle="${Name}" />
|
||||
|
@ -124,16 +123,23 @@ Requires Ant version 1.2 or later
|
|||
|
||||
<target name="dist" depends="deepclean,jar,copy-all,javadoc">
|
||||
<delete file="${dist.file}" />
|
||||
<zip zipfile="${dist.file}"
|
||||
basedir="${build.dir}"
|
||||
includes="**"
|
||||
excludes="classes/**" />
|
||||
<zip destfile="${dist.file}">
|
||||
<fileset dir="${build.dir}" includes="${dist.name}/**"/>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="source-zip" depends="copy-source">
|
||||
<target name="source-zip" depends="copy-source,copy-examples,copy-docs">
|
||||
<delete file="${dist.source-only-zip}" />
|
||||
<zip zipfile="${dist.source-only-zip}" basedir="${build.dir}"
|
||||
includes="${dist.name}/src/**,${dist.name}/toolsrc/**,${dist.name}/build.xml,${dist.name}/apiClasses.properties"/>
|
||||
<zip destfile="${dist.source-only-zip}">
|
||||
<zipfileset prefix="${dist.name}" dir="${dist.dir}">
|
||||
<include name="*src/**"/>
|
||||
<include name="build.xml"/>
|
||||
<include name="*.properties"/>
|
||||
<include name="examples/**"/>
|
||||
<include name="docs/**"/>
|
||||
<exclude name="docs/apidocs/**"/>
|
||||
</zipfileset>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="clean" depends="properties">
|
||||
|
@ -168,11 +174,11 @@ Requires Ant version 1.2 or later
|
|||
minimalist set of Rhino classes. See footprint.html
|
||||
from the doc directory for details.
|
||||
|
||||
javadoc generate generate Rhino API documentation
|
||||
in ${dist.apidocs}
|
||||
javadoc generate Rhino API documentation
|
||||
in ${dist.dir}/docs/apidocs
|
||||
|
||||
source-zip create ${dist.source-only-zip} with all Rhino
|
||||
source files necessary to recreate ${rhino.jar}
|
||||
source files necessary to recreate ${dist.file}
|
||||
</echo>
|
||||
</target>
|
||||
|
||||
|
|
|
@ -4,36 +4,35 @@
|
|||
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=".">
|
||||
<project name="src" default="compile" basedir="..">
|
||||
|
||||
<target name="properties">
|
||||
<property name="nest" value=".."/>
|
||||
<property name="build.dir" value="./build"/>
|
||||
<property name="classes" value="${build.dir}/classes"/>
|
||||
</target>
|
||||
<property file="build.properties"/>
|
||||
|
||||
<target name="compile" depends="properties">
|
||||
<javac srcdir="."
|
||||
destdir="${nest}/${classes}"
|
||||
<target name="compile">
|
||||
<javac srcdir="src"
|
||||
destdir="${classes}"
|
||||
includes="org/**/*.java"
|
||||
deprecation="on"
|
||||
debug="${debug}">
|
||||
debug="${debug}"
|
||||
target="${target-jvm}"
|
||||
>
|
||||
</javac>
|
||||
<copy todir="${nest}/${classes}">
|
||||
<fileset dir="." includes="org/**/*.properties" />
|
||||
<copy todir="${classes}">
|
||||
<fileset dir="src" includes="org/**/*.properties" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="copy-source" depends="properties">
|
||||
<copy todir="${nest}/${dist.src}">
|
||||
<fileset dir="."
|
||||
includes="org/**/*.java,org/**/*.properties,build.xml,manifest"/>
|
||||
<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" depends="properties">
|
||||
<target name="clean">
|
||||
<delete includeEmptyDirs="true">
|
||||
<fileset dir="${nest}/${classes}"
|
||||
<fileset dir="${classes}"
|
||||
excludes="org/mozilla/javascript/tools/**"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
|
|
@ -46,7 +46,8 @@ package org.mozilla.javascript;
|
|||
*/
|
||||
class Arguments extends IdScriptable {
|
||||
|
||||
public Arguments(NativeCall activation) {
|
||||
public Arguments(NativeCall activation)
|
||||
{
|
||||
this.activation = activation;
|
||||
|
||||
Scriptable parent = activation.getParentScope();
|
||||
|
@ -56,23 +57,25 @@ class Arguments extends IdScriptable {
|
|||
args = activation.getOriginalArguments();
|
||||
lengthObj = new Integer(args.length);
|
||||
|
||||
NativeFunction funObj = activation.funObj;
|
||||
calleeObj = funObj;
|
||||
NativeFunction f = activation.getFunctionObject();
|
||||
calleeObj = f;
|
||||
|
||||
if (funObj.version <= Context.VERSION_1_3
|
||||
&& funObj.version != Context.VERSION_DEFAULT)
|
||||
if (f.version <= Context.VERSION_1_3
|
||||
&& f.version != Context.VERSION_DEFAULT)
|
||||
{
|
||||
callerObj = null;
|
||||
}else {
|
||||
} else {
|
||||
callerObj = NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
public String getClassName()
|
||||
{
|
||||
return "Arguments";
|
||||
}
|
||||
|
||||
public boolean has(int index, Scriptable start) {
|
||||
public boolean has(int index, Scriptable start)
|
||||
{
|
||||
if (0 <= index && index < args.length) {
|
||||
if (args[index] != NOT_FOUND) {
|
||||
return true;
|
||||
|
@ -81,12 +84,14 @@ class Arguments extends IdScriptable {
|
|||
return super.has(index, start);
|
||||
}
|
||||
|
||||
public Object get(int index, Scriptable 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)) {
|
||||
String argName = activation.funObj.argNames[index];
|
||||
NativeFunction f = activation.getFunctionObject();
|
||||
String argName = f.argNames[index];
|
||||
value = activation.get(argName, activation);
|
||||
if (value == NOT_FOUND) Kit.codeBug();
|
||||
}
|
||||
|
@ -96,8 +101,9 @@ class Arguments extends IdScriptable {
|
|||
return super.get(index, start);
|
||||
}
|
||||
|
||||
private boolean sharedWithActivation(int index) {
|
||||
NativeFunction f = activation.funObj;
|
||||
private boolean sharedWithActivation(int index)
|
||||
{
|
||||
NativeFunction f = activation.getFunctionObject();
|
||||
int definedCount = f.argCount;
|
||||
if (index < definedCount) {
|
||||
// Check if argument is not hidden by later argument with the same
|
||||
|
@ -115,11 +121,13 @@ class Arguments extends IdScriptable {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void put(int index, Scriptable start, Object value) {
|
||||
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 = activation.funObj.argNames[index];
|
||||
NativeFunction f = activation.getFunctionObject();
|
||||
String argName = f.argNames[index];
|
||||
activation.put(argName, activation, value);
|
||||
return;
|
||||
}
|
||||
|
@ -137,7 +145,8 @@ class Arguments extends IdScriptable {
|
|||
super.put(index, start, value);
|
||||
}
|
||||
|
||||
public void delete(int index) {
|
||||
public void delete(int index)
|
||||
{
|
||||
if (0 <= index && index < args.length) {
|
||||
synchronized (this) {
|
||||
if (args[index] != NOT_FOUND) {
|
||||
|
@ -215,7 +224,7 @@ class Arguments extends IdScriptable {
|
|||
Object value = callerObj;
|
||||
if (value == UniqueTag.NULL_VALUE) { value = null; }
|
||||
else if (value == null) {
|
||||
NativeCall caller = activation.caller;
|
||||
NativeCall caller = activation.parentActivationCall;
|
||||
if (caller == null) {
|
||||
value = null;
|
||||
} else {
|
||||
|
|
|
@ -428,23 +428,13 @@ public class BaseFunction extends IdScriptable implements Function {
|
|||
// means assigned or delete arguments
|
||||
return (value == UniqueTag.NULL_VALUE) ? null : value;
|
||||
}
|
||||
NativeCall activation = getActivation(Context.getContext());
|
||||
Context cx = Context.getContext();
|
||||
NativeCall activation = ScriptRuntime.findFunctionActivation(cx, this);
|
||||
return (activation == null)
|
||||
? null
|
||||
: activation.get("arguments", activation);
|
||||
}
|
||||
|
||||
NativeCall getActivation(Context cx)
|
||||
{
|
||||
NativeCall activation = cx.currentActivation;
|
||||
while (activation != null) {
|
||||
if (activation.getFunctionObject() == this)
|
||||
return activation;
|
||||
activation = activation.caller;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Object jsConstructor(Context cx, Scriptable scope,
|
||||
Object[] args)
|
||||
{
|
||||
|
|
|
@ -185,6 +185,10 @@ public class CompilerEnvirons
|
|||
this.generatingSource = generatingSource;
|
||||
}
|
||||
|
||||
final boolean isXmlAvailable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private ErrorReporter errorReporter;
|
||||
private int syntaxErrorCount;
|
||||
|
|
|
@ -20,16 +20,19 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Kemal Bayram
|
||||
* Patrick Beard
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
* Brendan Eich
|
||||
* Ethan Hugg
|
||||
* Roger Lawrence
|
||||
* Terry Lucas
|
||||
* Mike McCabe
|
||||
* Milen Nankov
|
||||
* Ian D. Stewart
|
||||
* Andi Vajda
|
||||
* Andrew Wason
|
||||
* Kemal Bayram
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
|
@ -56,6 +59,8 @@ import java.text.MessageFormat;
|
|||
import java.lang.reflect.*;
|
||||
import org.mozilla.javascript.debug.*;
|
||||
|
||||
import org.mozilla.javascript.xml.XMLLib;
|
||||
|
||||
/**
|
||||
* This class represents the runtime context of an executing script.
|
||||
*
|
||||
|
@ -175,7 +180,7 @@ public class Context
|
|||
* 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}.
|
||||
*/
|
||||
|
@ -199,6 +204,16 @@ public class Context
|
|||
*/
|
||||
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 greater then {@link #VERSION_1_6}.
|
||||
*/
|
||||
public static final int FEATURE_E4X = 6;
|
||||
|
||||
public static final String languageVersionProperty = "language version";
|
||||
public static final String errorReporterProperty = "error reporter";
|
||||
|
||||
|
@ -1117,15 +1132,23 @@ public class Context
|
|||
NativeCall.init(this, scope, sealed);
|
||||
NativeScript.init(this, scope, sealed);
|
||||
|
||||
boolean withXml = hasFeature(FEATURE_E4X);
|
||||
|
||||
for (int i = 0; i != lazilyNames.length; i += 2) {
|
||||
String topProperty = lazilyNames[i];
|
||||
String className = lazilyNames[i + 1];
|
||||
if (!withXml && className == XML_INIT_CLASS) {
|
||||
continue;
|
||||
}
|
||||
new LazilyLoadedCtor(scope, topProperty, className, sealed);
|
||||
}
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
private static final String
|
||||
XML_INIT_CLASS = "org.mozilla.javascript.xmlimpl.XMLLibImpl";
|
||||
|
||||
private static final String[] lazilyNames = {
|
||||
"RegExp", "org.mozilla.javascript.regexp.NativeRegExp",
|
||||
"Packages", "org.mozilla.javascript.NativeJavaTopPackage",
|
||||
|
@ -1133,6 +1156,10 @@ public class Context
|
|||
"getClass", "org.mozilla.javascript.NativeJavaTopPackage",
|
||||
"JavaAdapter", "org.mozilla.javascript.JavaAdapter",
|
||||
"JavaImporter", "org.mozilla.javascript.ImporterTopLevel",
|
||||
"XML", XML_INIT_CLASS,
|
||||
"XMLList", XML_INIT_CLASS,
|
||||
"Namespace", XML_INIT_CLASS,
|
||||
"QName", XML_INIT_CLASS,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1949,11 +1976,17 @@ public class Context
|
|||
{
|
||||
}
|
||||
|
||||
// Proxy to allow to use deprecated WrapHandler in place of WrapFactory
|
||||
/**
|
||||
* @deprecated Proxy to allow to use deprecated WrapHandler in place
|
||||
* of WrapFactory.
|
||||
*/
|
||||
private static class WrapHandlerProxy extends WrapFactory
|
||||
{
|
||||
WrapHandler _handler;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
WrapHandlerProxy(WrapHandler handler)
|
||||
{
|
||||
_handler = handler;
|
||||
|
@ -2080,6 +2113,7 @@ public class Context
|
|||
* @see #FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER
|
||||
* @see #FEATURE_TO_STRING_AS_SOURCE
|
||||
* @see #FEATURE_PARENT_PROTO_PROPRTIES
|
||||
* @see #FEATURE_E4X
|
||||
*/
|
||||
public boolean hasFeature(int featureIndex)
|
||||
{
|
||||
|
@ -2096,9 +2130,9 @@ public class Context
|
|||
* we try to protect existing scripts that have specified a
|
||||
* version...
|
||||
*/
|
||||
return (version == Context.VERSION_1_0
|
||||
|| version == Context.VERSION_1_1
|
||||
|| version == Context.VERSION_1_2);
|
||||
return (version == VERSION_1_0
|
||||
|| version == VERSION_1_1
|
||||
|| version == VERSION_1_2);
|
||||
|
||||
case FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME:
|
||||
return false;
|
||||
|
@ -2111,6 +2145,9 @@ public class Context
|
|||
|
||||
case FEATURE_PARENT_PROTO_PROPRTIES:
|
||||
return true;
|
||||
|
||||
case FEATURE_E4X:
|
||||
return version == VERSION_DEFAULT || version >= VERSION_1_6;
|
||||
}
|
||||
// It is a bug to call the method with unknown featureIndex
|
||||
throw new IllegalArgumentException(String.valueOf(featureIndex));
|
||||
|
@ -2572,10 +2609,12 @@ public class Context
|
|||
private boolean sealed;
|
||||
private Object sealKey;
|
||||
|
||||
/**
|
||||
* The activation of the currently executing function or script.
|
||||
*/
|
||||
NativeCall currentActivation;
|
||||
Scriptable topActivationScope;
|
||||
NativeCall currentActivationCall;
|
||||
Scriptable currentActivationScope;
|
||||
int currentActivationDepth;
|
||||
|
||||
XMLLib cachedXMLLib;
|
||||
|
||||
// for Objects, Arrays to tag themselves as being printed out,
|
||||
// so they don't print themselves out recursively.
|
||||
|
@ -2618,4 +2657,7 @@ public class Context
|
|||
// For instruction counting (interpreter only)
|
||||
int instructionCount;
|
||||
int instructionThreshold;
|
||||
|
||||
// It can be used to return the second long or uint32 result from function
|
||||
long scratchLong;
|
||||
}
|
||||
|
|
|
@ -789,6 +789,18 @@ public class Decompiler
|
|||
result.append(" % ");
|
||||
break;
|
||||
|
||||
case Token.COLONCOLON:
|
||||
result.append("::");
|
||||
break;
|
||||
|
||||
case Token.DOTDOT:
|
||||
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();
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
* Ethan Hugg
|
||||
* Terry Lucas
|
||||
* Milen Nankov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
|
@ -107,6 +110,15 @@ final class IRFactory
|
|||
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
|
||||
*/
|
||||
|
@ -132,6 +144,55 @@ final class IRFactory
|
|||
return Node.newNumber(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* PropertySelector :: PropertySelector
|
||||
*/
|
||||
Node createQualifiedName(String namespace, String name)
|
||||
{
|
||||
Node namespaceNode = createString(namespace);
|
||||
Node nameNode = createString(name);
|
||||
return new Node(Token.COLONCOLON, namespaceNode, nameNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* PropertySelector :: [Expression]
|
||||
*/
|
||||
Node createQualifiedExpr(String namespace, Node expr)
|
||||
{
|
||||
Node namespaceNode = createString(namespace);
|
||||
return new Node(Token.COLONCOLON, namespaceNode, expr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @PropertySelector or @QualifiedIdentifier
|
||||
*/
|
||||
Node createAttributeName(Node nameNode)
|
||||
{
|
||||
int type = nameNode.getType();
|
||||
if (type == Token.NAME) {
|
||||
nameNode.setType(Token.STRING);
|
||||
} else {
|
||||
// If not name, then it should come from createQualifiedExpr
|
||||
if (type != Token.COLONCOLON)
|
||||
throw new IllegalArgumentException(String.valueOf(type));
|
||||
}
|
||||
return new Node(Token.TOATTRNAME, nameNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @::[Expression]
|
||||
*/
|
||||
Node createAttributeExpr(Node expr)
|
||||
{
|
||||
return new Node(Token.TOATTRNAME, expr);
|
||||
}
|
||||
|
||||
Node createXMLPrimary(Node xmlName)
|
||||
{
|
||||
Node xmlRef = new Node(Token.XML_REF, xmlName);
|
||||
return new Node(Token.GET_REF, xmlRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Catch clause of try/catch/finally
|
||||
* @param varName the name of the variable to bind to the exception
|
||||
|
@ -362,7 +423,8 @@ final class IRFactory
|
|||
* For .. In
|
||||
*
|
||||
*/
|
||||
Node createForIn(Node lhs, Node obj, Node body, int lineno)
|
||||
Node createForIn(Node lhs, Node obj, Node body, boolean isForEach,
|
||||
int lineno)
|
||||
{
|
||||
String name;
|
||||
int type = lhs.getType();
|
||||
|
@ -397,7 +459,9 @@ final class IRFactory
|
|||
|
||||
Node localBlock = new Node(Token.LOCAL_BLOCK);
|
||||
|
||||
Node init = new Node(Token.ENUM_INIT, obj);
|
||||
int initType = (isForEach) ? Token.ENUM_INIT_VALUES
|
||||
: 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);
|
||||
|
@ -593,7 +657,7 @@ final class IRFactory
|
|||
*/
|
||||
Node createWith(Node obj, Node body, int lineno)
|
||||
{
|
||||
parser.setRequiresActivation();
|
||||
setRequiresActivation();
|
||||
Node result = new Node(Token.BLOCK, lineno);
|
||||
result.addChildToBack(new Node(Token.ENTERWITH, obj));
|
||||
Node bodyNode = new Node(Token.WITH, body, lineno);
|
||||
|
@ -602,6 +666,16 @@ final class IRFactory
|
|||
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 length = elems.size();
|
||||
|
@ -718,25 +792,30 @@ final class IRFactory
|
|||
int childType = child.getType();
|
||||
switch (nodeType) {
|
||||
case Token.DELPROP: {
|
||||
Node left;
|
||||
Node right;
|
||||
Node n;
|
||||
if (childType == Token.NAME) {
|
||||
// Transform Delete(Name "a")
|
||||
// to Delete(Bind("a"), String("a"))
|
||||
child.setType(Token.BINDNAME);
|
||||
left = child;
|
||||
right = Node.newString(child.getString());
|
||||
Node left = child;
|
||||
Node right = Node.newString(child.getString());
|
||||
n = new Node(nodeType, left, right);
|
||||
} else if (childType == Token.GETPROP ||
|
||||
childType == Token.GETELEM)
|
||||
{
|
||||
left = child.getFirstChild();
|
||||
right = child.getLastChild();
|
||||
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.DELPROP, ref);
|
||||
} else {
|
||||
return new Node(Token.TRUE);
|
||||
n = new Node(Token.TRUE);
|
||||
}
|
||||
return new Node(nodeType, left, right);
|
||||
return n;
|
||||
}
|
||||
case Token.TYPEOF:
|
||||
if (childType == Token.NAME) {
|
||||
|
@ -797,7 +876,7 @@ final class IRFactory
|
|||
Node node = new Node(nodeType, child);
|
||||
if (type != Node.NON_SPECIALCALL) {
|
||||
// Calls to these functions require activation objects.
|
||||
parser.setRequiresActivation();
|
||||
setRequiresActivation();
|
||||
node.putIntProp(Node.SPECIALCALL_PROP, type);
|
||||
}
|
||||
return node;
|
||||
|
@ -847,15 +926,28 @@ final class IRFactory
|
|||
switch (nodeType) {
|
||||
|
||||
case Token.DOT:
|
||||
nodeType = Token.GETPROP;
|
||||
right.setType(Token.STRING);
|
||||
String id = right.getString();
|
||||
if (ScriptRuntime.isSpecialProperty(id)) {
|
||||
Node ref = new Node(Token.SPECIAL_REF, left);
|
||||
ref.putProp(Node.SPECIAL_PROP_PROP, id);
|
||||
return new Node(Token.GET_REF, ref);
|
||||
if (right.getType() == Token.NAME) {
|
||||
String id = right.getString();
|
||||
if (ScriptRuntime.isSpecialProperty(id)) {
|
||||
Node ref = new Node(Token.SPECIAL_REF, left);
|
||||
ref.putProp(Node.SPECIAL_PROP_PROP, id);
|
||||
return new Node(Token.GET_REF, ref);
|
||||
}
|
||||
nodeType = Token.GETPROP;
|
||||
right.setType(Token.STRING);
|
||||
checkActivationName(id, Token.GETPROP);
|
||||
} else {
|
||||
// corresponds to name.@... or name.namespace::...
|
||||
nodeType = Token.GETELEM;
|
||||
}
|
||||
checkActivationName(id, Token.GETPROP);
|
||||
break;
|
||||
|
||||
case Token.DOTDOT:
|
||||
if (right.getType() == Token.NAME) {
|
||||
right.setType(Token.STRING);
|
||||
}
|
||||
right = new Node(Token.DESCENDANTS, right);
|
||||
nodeType = Token.GETELEM;
|
||||
break;
|
||||
|
||||
case Token.LB:
|
||||
|
@ -1135,11 +1227,18 @@ final class IRFactory
|
|||
}
|
||||
}
|
||||
if (activation) {
|
||||
parser.setRequiresActivation();
|
||||
setRequiresActivation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setRequiresActivation()
|
||||
{
|
||||
if (parser.insideFunction()) {
|
||||
((FunctionNode)parser.currentScriptOrFn).setRequiresActivation();
|
||||
}
|
||||
}
|
||||
|
||||
// Only needed to call reportCurrentLineError.
|
||||
private Parser parser;
|
||||
|
||||
|
|
|
@ -22,7 +22,10 @@
|
|||
* Patrick Beard
|
||||
* Norris Boyd
|
||||
* Igor Bukanov
|
||||
* Ethan Hugg
|
||||
* Terry Lucas
|
||||
* Roger Lawrence
|
||||
* Milen Nankov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
|
@ -42,6 +45,8 @@ import java.io.*;
|
|||
|
||||
import org.mozilla.javascript.debug.*;
|
||||
|
||||
import org.mozilla.javascript.xml.XMLObject;
|
||||
|
||||
public class Interpreter
|
||||
{
|
||||
|
||||
|
@ -141,8 +146,12 @@ public class Interpreter
|
|||
Icode_ZERO = -49,
|
||||
Icode_ONE = -50,
|
||||
|
||||
// entrance and exit from .()
|
||||
Icode_ENTERDQ = -51,
|
||||
Icode_LEAVEDQ = -52,
|
||||
|
||||
// Last icode
|
||||
MIN_ICODE = -50;
|
||||
MIN_ICODE = -52;
|
||||
|
||||
static {
|
||||
// Checks for byte code consistencies, good compiler can eliminate them
|
||||
|
@ -224,6 +233,8 @@ public class Interpreter
|
|||
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";
|
||||
}
|
||||
|
||||
// icode without name
|
||||
|
@ -700,9 +711,10 @@ public class Interpreter
|
|||
iCodeTop = addToken(Token.RETURN_RESULT, iCodeTop);
|
||||
break;
|
||||
|
||||
case Token.ENUM_INIT:
|
||||
case Token.ENUM_INIT_KEYS:
|
||||
case Token.ENUM_INIT_VALUES :
|
||||
iCodeTop = visitExpression(child, iCodeTop);
|
||||
iCodeTop = addIndexOp(Token.ENUM_INIT, getLocalBlockRef(node), iCodeTop);
|
||||
iCodeTop = addIndexOp(type, getLocalBlockRef(node), iCodeTop);
|
||||
stackChange(-1);
|
||||
break;
|
||||
|
||||
|
@ -891,6 +903,7 @@ public class Interpreter
|
|||
case Token.BITNOT:
|
||||
case Token.TYPEOF:
|
||||
case Token.VOID:
|
||||
case Token.DEL_REF:
|
||||
iCodeTop = visitExpression(child, iCodeTop);
|
||||
if (type == Token.VOID) {
|
||||
iCodeTop = addIcode(Icode_POP, iCodeTop);
|
||||
|
@ -1071,11 +1084,36 @@ public class Interpreter
|
|||
break;
|
||||
}
|
||||
|
||||
case Token.XML_REF:
|
||||
case Token.GENERIC_REF:
|
||||
iCodeTop = visitExpression(child, iCodeTop);
|
||||
iCodeTop = addToken(Token.GENERIC_REF, iCodeTop);
|
||||
iCodeTop = addToken(type, iCodeTop);
|
||||
break;
|
||||
|
||||
case Token.DOTQUERY:
|
||||
iCodeTop = visitDotQery(node, child, iCodeTop);
|
||||
break;
|
||||
|
||||
case Token.DEFAULTNAMESPACE :
|
||||
case Token.ESCXMLATTR :
|
||||
case Token.ESCXMLTEXT :
|
||||
case Token.TOATTRNAME :
|
||||
case Token.DESCENDANTS :
|
||||
iCodeTop = visitExpression(child, iCodeTop);
|
||||
iCodeTop = addToken(type, iCodeTop);
|
||||
break;
|
||||
|
||||
case Token.COLONCOLON : {
|
||||
if (child.getType() != Token.STRING)
|
||||
throw badTree(child);
|
||||
String namespace = child.getString();
|
||||
child = child.getNext();
|
||||
iCodeTop = visitExpression(child, iCodeTop);
|
||||
iCodeTop = addStringOp(Token.COLONCOLON, namespace, iCodeTop);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
throw badTree(node);
|
||||
}
|
||||
|
@ -1294,6 +1332,21 @@ public class Interpreter
|
|||
return iCodeTop;
|
||||
}
|
||||
|
||||
private int visitDotQery(Node node, Node child, int iCodeTop)
|
||||
{
|
||||
iCodeTop = updateLineNumber(node, iCodeTop);
|
||||
iCodeTop = visitExpression(child, iCodeTop);
|
||||
iCodeTop = addIcode(Icode_ENTERDQ, iCodeTop);
|
||||
stackChange(-1);
|
||||
int queryPC = iCodeTop;
|
||||
iCodeTop = visitExpression(child.getNext(), iCodeTop);
|
||||
int leavePC = iCodeTop;
|
||||
iCodeTop = addIcode(Icode_LEAVEDQ, iCodeTop);
|
||||
recordJump(leavePC, queryPC);
|
||||
iCodeTop += 2;
|
||||
return iCodeTop;
|
||||
}
|
||||
|
||||
private int getLocalBlockRef(Node node)
|
||||
{
|
||||
Node localBlock = (Node)node.getProp(Node.LOCAL_BLOCK_PROP);
|
||||
|
@ -1655,7 +1708,8 @@ public class Interpreter
|
|||
case Token.GOTO :
|
||||
case Token.IFEQ :
|
||||
case Token.IFNE :
|
||||
case Icode_IFEQ_POP : {
|
||||
case Icode_IFEQ_POP :
|
||||
case Icode_LEAVEDQ : {
|
||||
int newPC = pc + getShort(iCode, pc) - 1;
|
||||
out.println(tname + " " + newPC);
|
||||
pc += 2;
|
||||
|
@ -1809,6 +1863,7 @@ public class Interpreter
|
|||
case Token.IFEQ :
|
||||
case Token.IFNE :
|
||||
case Icode_IFEQ_POP :
|
||||
case Icode_LEAVEDQ :
|
||||
// target pc offset
|
||||
return 1 + 2;
|
||||
|
||||
|
@ -2024,13 +2079,13 @@ public class Interpreter
|
|||
argShift = 0;
|
||||
argsDbl = null;
|
||||
}
|
||||
scope = ScriptRuntime.initVarObj(cx, scope, fnOrScript,
|
||||
thisObj, args);
|
||||
scope = ScriptRuntime.enterActivationFunction(cx, scope,
|
||||
fnOrScript,
|
||||
thisObj, args);
|
||||
}
|
||||
|
||||
} else {
|
||||
ScriptRuntime.initScript(cx, scope, fnOrScript, thisObj,
|
||||
idata.itsFromEvalCode);
|
||||
scope = ScriptRuntime.enterScript(cx, scope, fnOrScript, thisObj);
|
||||
}
|
||||
|
||||
if (idata.itsNestedFunctions != null) {
|
||||
|
@ -2058,8 +2113,9 @@ public class Interpreter
|
|||
}
|
||||
if (idata.itsFunctionType != 0 && !idata.itsNeedsActivation) {
|
||||
useActivationVars = true;
|
||||
scope = ScriptRuntime.initVarObj(cx, scope, fnOrScript,
|
||||
thisObj, args);
|
||||
scope = ScriptRuntime.enterActivationFunction(cx, scope,
|
||||
fnOrScript,
|
||||
thisObj, args);
|
||||
}
|
||||
debuggerFrame.onEnter(cx, scope, thisObj, args);
|
||||
}
|
||||
|
@ -2205,7 +2261,7 @@ switch (op) {
|
|||
--stackTop;
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
boolean valBln = ScriptRuntime.in(lhs, rhs, scope);
|
||||
boolean valBln = ScriptRuntime.in(lhs, rhs, cx, scope);
|
||||
stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
|
||||
continue Loop;
|
||||
}
|
||||
|
@ -2215,7 +2271,7 @@ switch (op) {
|
|||
--stackTop;
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
boolean valBln = ScriptRuntime.instanceOf(lhs, rhs, scope);
|
||||
boolean valBln = ScriptRuntime.instanceOf(lhs, rhs, cx, scope);
|
||||
stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
|
||||
continue Loop;
|
||||
}
|
||||
|
@ -2379,7 +2435,7 @@ switch (op) {
|
|||
continue Loop;
|
||||
}
|
||||
case Token.ADD :
|
||||
stackTop = do_add(stack, sDbl, stackTop);
|
||||
stackTop = do_add(stack, sDbl, stackTop, cx);
|
||||
continue Loop;
|
||||
case Token.SUB : {
|
||||
double rDbl = stack_double(stack, sDbl, stackTop);
|
||||
|
@ -2419,14 +2475,14 @@ switch (op) {
|
|||
? Boolean.FALSE : Boolean.TRUE;
|
||||
continue Loop;
|
||||
case Token.BINDNAME :
|
||||
stack[++stackTop] = ScriptRuntime.bind(scope, stringReg);
|
||||
stack[++stackTop] = ScriptRuntime.bind(cx, scope, stringReg);
|
||||
continue Loop;
|
||||
case Token.SETNAME : {
|
||||
Object rhs = stack[stackTop];
|
||||
if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
|
||||
--stackTop;
|
||||
Scriptable lhs = (Scriptable)stack[stackTop];
|
||||
stack[stackTop] = ScriptRuntime.setName(lhs, rhs, scope, stringReg);
|
||||
stack[stackTop] = ScriptRuntime.setName(lhs, rhs, cx, stringReg);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.DELPROP : {
|
||||
|
@ -2441,7 +2497,8 @@ switch (op) {
|
|||
case Token.GETPROP : {
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.getProp(lhs, stringReg, scope);
|
||||
stack[stackTop] = ScriptRuntime.getObjectProp(lhs, stringReg,
|
||||
cx, scope);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.SETPROP : {
|
||||
|
@ -2450,7 +2507,8 @@ switch (op) {
|
|||
--stackTop;
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.setProp(lhs, stringReg, rhs, scope);
|
||||
stack[stackTop] = ScriptRuntime.setObjectProp(lhs, stringReg, rhs,
|
||||
cx, scope);
|
||||
continue Loop;
|
||||
}
|
||||
case Icode_PROP_INC_DEC : {
|
||||
|
@ -2473,7 +2531,7 @@ switch (op) {
|
|||
--stackTop;
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.elemIncrDecr(lhs, rhs, scope,
|
||||
stack[stackTop] = ScriptRuntime.elemIncrDecr(lhs, rhs, cx, scope,
|
||||
iCode[pc]);
|
||||
++pc;
|
||||
continue Loop;
|
||||
|
@ -2493,6 +2551,12 @@ switch (op) {
|
|||
stack[stackTop] = ScriptRuntime.setReference(lhs, rhs);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.DEL_REF : {
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.deleteReference(lhs);
|
||||
continue Loop;
|
||||
}
|
||||
case Icode_REF_INC_DEC : {
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
|
@ -2670,7 +2734,7 @@ switch (op) {
|
|||
sDbl[stackTop] = idata.itsDoubleTable[indexReg];
|
||||
continue Loop;
|
||||
case Token.NAME :
|
||||
stack[++stackTop] = ScriptRuntime.name(scope, stringReg);
|
||||
stack[++stackTop] = ScriptRuntime.name(cx, scope, stringReg);
|
||||
continue Loop;
|
||||
case Icode_NAME_INC_DEC :
|
||||
stack[++stackTop] = ScriptRuntime.nameIncrDecr(scope, stringReg,
|
||||
|
@ -2772,13 +2836,20 @@ switch (op) {
|
|||
stack[stackTop] = ScriptRuntime.newCatchScope(stringReg,
|
||||
stack[stackTop]);
|
||||
continue Loop;
|
||||
case Token.ENUM_INIT : {
|
||||
case Token.ENUM_INIT_KEYS : {
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
--stackTop;
|
||||
stack[LOCAL_SHFT + indexReg] = ScriptRuntime.enumInit(lhs, scope);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.ENUM_INIT_VALUES : {
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
--stackTop;
|
||||
stack[LOCAL_SHFT + indexReg] = ScriptRuntime.enumValuesInit(lhs, scope);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.ENUM_NEXT :
|
||||
case Token.ENUM_ID : {
|
||||
Object val = stack[LOCAL_SHFT + indexReg];
|
||||
|
@ -2802,6 +2873,12 @@ switch (op) {
|
|||
cx, scope);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.XML_REF : {
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.xmlReference(lhs, cx, scope);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.GENERIC_REF : {
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
|
@ -2868,6 +2945,68 @@ switch (op) {
|
|||
stack[stackTop] = val;
|
||||
continue Loop;
|
||||
}
|
||||
case Icode_ENTERDQ : {
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
--stackTop;
|
||||
scope = ScriptRuntime.enterDotQuery(lhs, scope);
|
||||
++withDepth;
|
||||
continue Loop;
|
||||
}
|
||||
case Icode_LEAVEDQ : {
|
||||
boolean valBln = stack_boolean(stack, sDbl, stackTop);
|
||||
Object x = ScriptRuntime.updateDotQuery(valBln, scope);
|
||||
if (x == null) {
|
||||
// reset stack and PC to code after ENTERDQ
|
||||
--stackTop;
|
||||
break;
|
||||
}
|
||||
stack[stackTop] = x;
|
||||
scope = ScriptRuntime.leaveDotQuery(scope);
|
||||
--withDepth;
|
||||
pc += 2;
|
||||
continue Loop;
|
||||
}
|
||||
case Token.DEFAULTNAMESPACE : {
|
||||
Object value = stack[stackTop];
|
||||
if (value == DBL_MRK) value = doubleWrap(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 Token.TOATTRNAME : {
|
||||
Object value = stack[stackTop];
|
||||
if (value == DBL_MRK) value = doubleWrap(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.toAttributeName(value, cx);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.DESCENDANTS : {
|
||||
Object value = stack[stackTop];
|
||||
if(value == DBL_MRK) value = doubleWrap(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.toDescendantsName(value, cx);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.COLONCOLON : {
|
||||
Object value = stack[stackTop];
|
||||
if (value == DBL_MRK) value = doubleWrap(sDbl[stackTop]);
|
||||
// stringReg contains namespace
|
||||
stack[stackTop] = ScriptRuntime.toQualifiedName(stringReg, value,
|
||||
cx, scope);
|
||||
continue Loop;
|
||||
}
|
||||
case Icode_LINE :
|
||||
cx.interpreterLineIndex = pc;
|
||||
if (debuggerFrame != null) {
|
||||
|
@ -2973,8 +3112,13 @@ switch (op) {
|
|||
debuggerFrame.onExit(cx, false, result);
|
||||
}
|
||||
}
|
||||
if (idata.itsNeedsActivation || debuggerFrame != null) {
|
||||
ScriptRuntime.popActivation(cx);
|
||||
|
||||
if (idata.itsFunctionType != 0) {
|
||||
if (idata.itsNeedsActivation || debuggerFrame != null) {
|
||||
ScriptRuntime.exitActivationFunction(cx);
|
||||
}
|
||||
} else {
|
||||
ScriptRuntime.exitScript(cx);
|
||||
}
|
||||
|
||||
if (javaException != null) {
|
||||
|
@ -3035,7 +3179,8 @@ switch (op) {
|
|||
}
|
||||
}
|
||||
|
||||
private static int do_add(Object[] stack, double[] sDbl, int stackTop)
|
||||
private static int do_add(Object[] stack, double[] sDbl, int stackTop,
|
||||
Context cx)
|
||||
{
|
||||
--stackTop;
|
||||
Object rhs = stack[stackTop + 1];
|
||||
|
@ -3050,6 +3195,10 @@ switch (op) {
|
|||
} else if (lhs == DBL_MRK) {
|
||||
do_add(rhs, sDbl[stackTop], stack, sDbl, stackTop, false);
|
||||
} else {
|
||||
if (lhs instanceof XMLObject || rhs instanceof XMLObject) {
|
||||
stack[stackTop] = ScriptRuntime.add(lhs, rhs, cx);
|
||||
return stackTop;
|
||||
}
|
||||
if (lhs instanceof Scriptable)
|
||||
lhs = ((Scriptable) lhs).getDefaultValue(null);
|
||||
if (rhs instanceof Scriptable)
|
||||
|
@ -3236,7 +3385,7 @@ switch (op) {
|
|||
Object result;
|
||||
Object id = stack[stackTop];
|
||||
if (id != DBL_MRK) {
|
||||
result = ScriptRuntime.getElem(lhs, id, scope);
|
||||
result = ScriptRuntime.getObjectId(lhs, id, cx, scope);
|
||||
} else {
|
||||
double val = sDbl[stackTop];
|
||||
if (lhs == null || lhs == Undefined.instance) {
|
||||
|
@ -3248,10 +3397,10 @@ switch (op) {
|
|||
: ScriptRuntime.toObject(cx, scope, lhs);
|
||||
int index = (int)val;
|
||||
if (index == val) {
|
||||
result = ScriptRuntime.getElem(obj, index);
|
||||
result = ScriptRuntime.getObjectIndex(obj, index, cx);
|
||||
} else {
|
||||
String s = ScriptRuntime.toString(val);
|
||||
result = ScriptRuntime.getProp(obj, s);
|
||||
result = ScriptRuntime.getObjectProp(obj, s, cx);
|
||||
}
|
||||
}
|
||||
--stackTop;
|
||||
|
@ -3270,7 +3419,7 @@ switch (op) {
|
|||
Object result;
|
||||
Object id = stack[stackTop - 1];
|
||||
if (id != DBL_MRK) {
|
||||
result = ScriptRuntime.setElem(lhs, id, rhs, scope);
|
||||
result = ScriptRuntime.setObjectId(lhs, id, rhs, cx, scope);
|
||||
} else {
|
||||
double val = sDbl[stackTop - 1];
|
||||
if (lhs == null || lhs == Undefined.instance) {
|
||||
|
@ -3282,10 +3431,10 @@ switch (op) {
|
|||
: ScriptRuntime.toObject(cx, scope, lhs);
|
||||
int index = (int)val;
|
||||
if (index == val) {
|
||||
result = ScriptRuntime.setElem(obj, index, rhs);
|
||||
result = ScriptRuntime.setObjectIndex(obj, index, rhs, cx);
|
||||
} else {
|
||||
String s = ScriptRuntime.toString(val);
|
||||
result = ScriptRuntime.setProp(obj, s, rhs);
|
||||
result = ScriptRuntime.setObjectProp(obj, s, rhs, cx);
|
||||
}
|
||||
}
|
||||
stackTop -= 2;
|
||||
|
|
|
@ -426,7 +426,7 @@ public class NativeArray extends IdScriptable {
|
|||
* getLengthProperty returns 0 if obj does not have the length property
|
||||
* or its value is not convertible to a number.
|
||||
*/
|
||||
static long getLengthProperty(Scriptable obj) {
|
||||
static long getLengthProperty(Context cx, Scriptable obj) {
|
||||
// These will both give numeric lengths within Uint32 range.
|
||||
if (obj instanceof NativeString) {
|
||||
return ((NativeString)obj).getLength();
|
||||
|
@ -435,8 +435,15 @@ public class NativeArray extends IdScriptable {
|
|||
} else if (!(obj instanceof Scriptable)) {
|
||||
return 0;
|
||||
}
|
||||
return ScriptRuntime.toUint32(ScriptRuntime
|
||||
.getProp(obj, "length", obj));
|
||||
return ScriptRuntime.toUint32(
|
||||
ScriptRuntime.getObjectProp(obj, "length", cx));
|
||||
}
|
||||
|
||||
private static Object setLengthProperty(Context cx, Scriptable target,
|
||||
long length)
|
||||
{
|
||||
return ScriptRuntime.setObjectProp(target, "length",
|
||||
new Double(length), cx);
|
||||
}
|
||||
|
||||
/* Utility functions to encapsulate index > Integer.MAX_VALUE
|
||||
|
@ -450,21 +457,24 @@ public class NativeArray extends IdScriptable {
|
|||
else { target.delete(Long.toString(index)); }
|
||||
}
|
||||
|
||||
private static Object getElem(Scriptable target, long index) {
|
||||
private static Object getElem(Context cx, Scriptable target, long index)
|
||||
{
|
||||
if (index > Integer.MAX_VALUE) {
|
||||
String id = Long.toString(index);
|
||||
return ScriptRuntime.getProp(target, id);
|
||||
return ScriptRuntime.getObjectProp(target, id, cx);
|
||||
} else {
|
||||
return ScriptRuntime.getElem(target, (int)index);
|
||||
return ScriptRuntime.getObjectIndex(target, (int)index, cx);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setElem(Scriptable target, long index, Object value) {
|
||||
private static void setElem(Context cx, Scriptable target, long index,
|
||||
Object value)
|
||||
{
|
||||
if (index > Integer.MAX_VALUE) {
|
||||
String id = Long.toString(index);
|
||||
ScriptRuntime.setProp(target, id, value);
|
||||
ScriptRuntime.setObjectProp(target, id, value, cx);
|
||||
} else {
|
||||
ScriptRuntime.setElem(target, (int)index, value);
|
||||
ScriptRuntime.setObjectIndex(target, (int)index, value, cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,7 +487,7 @@ public class NativeArray extends IdScriptable {
|
|||
* function; StringBuffers are limited to 2^31 in java.
|
||||
*/
|
||||
|
||||
long length = getLengthProperty(thisObj);
|
||||
long length = getLengthProperty(cx, thisObj);
|
||||
|
||||
StringBuffer result = new StringBuffer(256);
|
||||
|
||||
|
@ -511,7 +521,7 @@ public class NativeArray extends IdScriptable {
|
|||
cx.iterating.put(thisObj, 0); // stop recursion.
|
||||
for (i = 0; i < length; i++) {
|
||||
if (i > 0) result.append(separator);
|
||||
Object elem = getElem(thisObj, i);
|
||||
Object elem = getElem(cx, thisObj, i);
|
||||
if (elem == null || elem == Undefined.instance) {
|
||||
haslast = false;
|
||||
continue;
|
||||
|
@ -538,7 +548,7 @@ public class NativeArray extends IdScriptable {
|
|||
Scriptable obj = ScriptRuntime.
|
||||
toObject(cx, thisObj, elem);
|
||||
Object tls = ScriptRuntime.
|
||||
getProp(obj, "toLocaleString", thisObj);
|
||||
getObjectProp(obj, "toLocaleString", cx);
|
||||
elem = ScriptRuntime.call(cx, tls, elem,
|
||||
ScriptRuntime.emptyArgs);
|
||||
}
|
||||
|
@ -570,7 +580,7 @@ public class NativeArray extends IdScriptable {
|
|||
{
|
||||
String separator;
|
||||
|
||||
long llength = getLengthProperty(thisObj);
|
||||
long llength = getLengthProperty(cx, thisObj);
|
||||
int length = (int)llength;
|
||||
if (llength != length) {
|
||||
throw Context.reportRuntimeError1(
|
||||
|
@ -588,7 +598,7 @@ public class NativeArray extends IdScriptable {
|
|||
String[] buf = new String[length];
|
||||
int total_size = 0;
|
||||
for (int i = 0; i != length; i++) {
|
||||
Object temp = getElem(thisObj, i);
|
||||
Object temp = getElem(cx, thisObj, i);
|
||||
if (temp != null && temp != Undefined.instance) {
|
||||
String str = ScriptRuntime.toString(temp);
|
||||
total_size += str.length();
|
||||
|
@ -616,15 +626,15 @@ public class NativeArray extends IdScriptable {
|
|||
private static Scriptable js_reverse(Context cx, Scriptable thisObj,
|
||||
Object[] args)
|
||||
{
|
||||
long len = getLengthProperty(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(thisObj, i);
|
||||
Object temp2 = getElem(thisObj, j);
|
||||
setElem(thisObj, i, temp2);
|
||||
setElem(thisObj, j, temp1);
|
||||
Object temp1 = getElem(cx, thisObj, i);
|
||||
Object temp2 = getElem(cx, thisObj, j);
|
||||
setElem(cx, thisObj, i, temp2);
|
||||
setElem(cx, thisObj, j, temp1);
|
||||
}
|
||||
return thisObj;
|
||||
}
|
||||
|
@ -636,7 +646,7 @@ public class NativeArray extends IdScriptable {
|
|||
Scriptable thisObj, Object[] args)
|
||||
throws JavaScriptException
|
||||
{
|
||||
long length = getLengthProperty(thisObj);
|
||||
long length = getLengthProperty(cx, thisObj);
|
||||
|
||||
if (length <= 1) { return thisObj; }
|
||||
|
||||
|
@ -663,14 +673,14 @@ public class NativeArray extends IdScriptable {
|
|||
// sorted cheaply.
|
||||
Object[] working = new Object[ilength];
|
||||
for (int i = 0; i != ilength; ++i) {
|
||||
working[i] = getElem(thisObj, 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(thisObj, i, working[i]);
|
||||
setElem(cx, thisObj, i, working[i]);
|
||||
}
|
||||
}
|
||||
return thisObj;
|
||||
|
@ -790,15 +800,15 @@ public class NativeArray extends IdScriptable {
|
|||
// Build heap
|
||||
for (long i = length / 2; i != 0;) {
|
||||
--i;
|
||||
Object pivot = getElem(target, 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(target, i);
|
||||
setElem(target, i, getElem(target, 0));
|
||||
Object pivot = getElem(cx, target, i);
|
||||
setElem(cx, target, i, getElem(cx, target, 0));
|
||||
heapify_extended(cx, scope, pivot, target, 0, i, cmp, cmpBuf);
|
||||
}
|
||||
}
|
||||
|
@ -814,9 +824,9 @@ public class NativeArray extends IdScriptable {
|
|||
if (child >= end) {
|
||||
break;
|
||||
}
|
||||
Object childVal = getElem(target, child);
|
||||
Object childVal = getElem(cx, target, child);
|
||||
if (child + 1 < end) {
|
||||
Object nextVal = getElem(target, child + 1);
|
||||
Object nextVal = getElem(cx, target, child + 1);
|
||||
if (isBigger(cx, scope, nextVal, childVal, cmp, cmpBuf)) {
|
||||
++child; childVal = nextVal;
|
||||
}
|
||||
|
@ -824,10 +834,10 @@ public class NativeArray extends IdScriptable {
|
|||
if (!isBigger(cx, scope, childVal, pivot, cmp, cmpBuf)) {
|
||||
break;
|
||||
}
|
||||
setElem(target, i, childVal);
|
||||
setElem(cx, target, i, childVal);
|
||||
i = child;
|
||||
}
|
||||
setElem(target, i, pivot);
|
||||
setElem(cx, target, i, pivot);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -837,14 +847,13 @@ public class NativeArray extends IdScriptable {
|
|||
private static Object js_push(Context cx, Scriptable thisObj,
|
||||
Object[] args)
|
||||
{
|
||||
long length = getLengthProperty(thisObj);
|
||||
long length = getLengthProperty(cx, thisObj);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
setElem(thisObj, length + i, args[i]);
|
||||
setElem(cx, thisObj, length + i, args[i]);
|
||||
}
|
||||
|
||||
length += args.length;
|
||||
Double lengthObj = new Double(length);
|
||||
ScriptRuntime.setProp(thisObj, "length", lengthObj);
|
||||
Object lengthObj = setLengthProperty(cx, thisObj, length);
|
||||
|
||||
/*
|
||||
* If JS1.2, follow Perl4 by returning the last thing pushed.
|
||||
|
@ -864,12 +873,12 @@ public class NativeArray extends IdScriptable {
|
|||
Object[] args)
|
||||
{
|
||||
Object result;
|
||||
long length = getLengthProperty(thisObj);
|
||||
long length = getLengthProperty(cx, thisObj);
|
||||
if (length > 0) {
|
||||
length--;
|
||||
|
||||
// Get the to-be-deleted property's value.
|
||||
result = getElem(thisObj, length);
|
||||
result = getElem(cx, thisObj, length);
|
||||
|
||||
// We don't need to delete the last property, because
|
||||
// setLength does that for us.
|
||||
|
@ -878,7 +887,7 @@ public class NativeArray extends IdScriptable {
|
|||
}
|
||||
// necessary to match js even when length < 0; js pop will give a
|
||||
// length property to any target it is called on.
|
||||
ScriptRuntime.setProp(thisObj, "length", new Double(length));
|
||||
setLengthProperty(cx, thisObj, length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -887,13 +896,13 @@ public class NativeArray extends IdScriptable {
|
|||
Object[] args)
|
||||
{
|
||||
Object result;
|
||||
long length = getLengthProperty(thisObj);
|
||||
long length = getLengthProperty(cx, thisObj);
|
||||
if (length > 0) {
|
||||
long i = 0;
|
||||
length--;
|
||||
|
||||
// Get the to-be-deleted property's value.
|
||||
result = getElem(thisObj, i);
|
||||
result = getElem(cx, thisObj, i);
|
||||
|
||||
/*
|
||||
* Slide down the array above the first element. Leave i
|
||||
|
@ -901,8 +910,8 @@ public class NativeArray extends IdScriptable {
|
|||
*/
|
||||
if (length > 0) {
|
||||
for (i = 1; i <= length; i++) {
|
||||
Object temp = getElem(thisObj, i);
|
||||
setElem(thisObj, i - 1, temp);
|
||||
Object temp = getElem(cx, thisObj, i);
|
||||
setElem(cx, thisObj, i - 1, temp);
|
||||
}
|
||||
}
|
||||
// We don't need to delete the last property, because
|
||||
|
@ -910,7 +919,7 @@ public class NativeArray extends IdScriptable {
|
|||
} else {
|
||||
result = Context.getUndefinedValue();
|
||||
}
|
||||
ScriptRuntime.setProp(thisObj, "length", new Double(length));
|
||||
setLengthProperty(cx, thisObj, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -918,28 +927,28 @@ public class NativeArray extends IdScriptable {
|
|||
Object[] args)
|
||||
{
|
||||
Object result;
|
||||
double length = (double)getLengthProperty(thisObj);
|
||||
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 = (long)length - 1; last >= 0; last--) {
|
||||
Object temp = getElem(thisObj, last);
|
||||
setElem(thisObj, last + argc, temp);
|
||||
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(thisObj, i, args[i]);
|
||||
setElem(cx, thisObj, i, args[i]);
|
||||
}
|
||||
|
||||
/* Follow Perl by returning the new array length. */
|
||||
length += args.length;
|
||||
ScriptRuntime.setProp(thisObj, "length", new Double(length));
|
||||
return setLengthProperty(cx, thisObj, length);
|
||||
}
|
||||
return new Long((long)length);
|
||||
return new Double(length);
|
||||
}
|
||||
|
||||
private static Object js_splice(Context cx, Scriptable scope,
|
||||
|
@ -951,7 +960,7 @@ public class NativeArray extends IdScriptable {
|
|||
int argc = args.length;
|
||||
if (argc == 0)
|
||||
return result;
|
||||
long length = getLengthProperty(thisObj);
|
||||
long length = getLengthProperty(cx, thisObj);
|
||||
|
||||
/* Convert the first argument into a starting index. */
|
||||
long begin = toSliceIndex(ScriptRuntime.toInteger(args[0]), length);
|
||||
|
@ -991,12 +1000,12 @@ public class NativeArray extends IdScriptable {
|
|||
* wrap in [] if necessary. So JS1.3, default, and other
|
||||
* versions all return an array of length 1 for uniformity.
|
||||
*/
|
||||
result = getElem(thisObj, begin);
|
||||
result = getElem(cx, thisObj, begin);
|
||||
} else {
|
||||
for (long last = begin; last != end; last++) {
|
||||
Scriptable resultArray = (Scriptable)result;
|
||||
Object temp = getElem(thisObj, last);
|
||||
setElem(resultArray, last - begin, temp);
|
||||
Object temp = getElem(cx, thisObj, last);
|
||||
setElem(cx, resultArray, last - begin, temp);
|
||||
}
|
||||
}
|
||||
} else if (count == 0
|
||||
|
@ -1011,25 +1020,24 @@ public class NativeArray extends IdScriptable {
|
|||
|
||||
if (delta > 0) {
|
||||
for (long last = length - 1; last >= end; last--) {
|
||||
Object temp = getElem(thisObj, last);
|
||||
setElem(thisObj, last + delta, temp);
|
||||
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(thisObj, last);
|
||||
setElem(thisObj, last + delta, temp);
|
||||
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(thisObj, begin + i, args[i + argoffset]);
|
||||
setElem(cx, thisObj, begin + i, args[i + argoffset]);
|
||||
}
|
||||
|
||||
/* Update length in case we deleted elements from the end. */
|
||||
ScriptRuntime.setProp(thisObj, "length",
|
||||
new Double(length + delta));
|
||||
setLengthProperty(cx, thisObj, length + delta);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1050,16 +1058,16 @@ public class NativeArray extends IdScriptable {
|
|||
/* Put the target in the result array; only add it as an array
|
||||
* if it looks like one.
|
||||
*/
|
||||
if (ScriptRuntime.instanceOf(thisObj, ctor, scope)) {
|
||||
length = getLengthProperty(thisObj);
|
||||
if (ScriptRuntime.instanceOf(thisObj, ctor, cx, scope)) {
|
||||
length = getLengthProperty(cx, thisObj);
|
||||
|
||||
// Copy from the target object into the result
|
||||
for (slot = 0; slot < length; slot++) {
|
||||
Object temp = getElem(thisObj, slot);
|
||||
setElem(result, slot, temp);
|
||||
Object temp = getElem(cx, thisObj, slot);
|
||||
setElem(cx, result, slot, temp);
|
||||
}
|
||||
} else {
|
||||
setElem(result, slot++, thisObj);
|
||||
setElem(cx, result, slot++, thisObj);
|
||||
}
|
||||
|
||||
/* Copy from the arguments into the result. If any argument
|
||||
|
@ -1067,16 +1075,16 @@ public class NativeArray extends IdScriptable {
|
|||
* elements separately; otherwise, just copy the argument.
|
||||
*/
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (ScriptRuntime.instanceOf(args[i], ctor, scope)) {
|
||||
if (ScriptRuntime.instanceOf(args[i], ctor, cx, scope)) {
|
||||
// ScriptRuntime.instanceOf => instanceof Scriptable
|
||||
Scriptable arg = (Scriptable)args[i];
|
||||
length = getLengthProperty(arg);
|
||||
length = getLengthProperty(cx, arg);
|
||||
for (long j = 0; j < length; j++, slot++) {
|
||||
Object temp = getElem(arg, j);
|
||||
setElem(result, slot, temp);
|
||||
Object temp = getElem(cx, arg, j);
|
||||
setElem(cx, result, slot, temp);
|
||||
}
|
||||
} else {
|
||||
setElem(result, slot++, args[i]);
|
||||
setElem(cx, result, slot++, args[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -1087,7 +1095,7 @@ public class NativeArray extends IdScriptable {
|
|||
{
|
||||
Scriptable scope = getTopLevelScope(this);
|
||||
Scriptable result = ScriptRuntime.newObject(cx, scope, "Array", null);
|
||||
long length = getLengthProperty(thisObj);
|
||||
long length = getLengthProperty(cx, thisObj);
|
||||
|
||||
long begin, end;
|
||||
if (args.length == 0) {
|
||||
|
@ -1103,8 +1111,8 @@ public class NativeArray extends IdScriptable {
|
|||
}
|
||||
|
||||
for (long slot = begin; slot < end; slot++) {
|
||||
Object temp = getElem(thisObj, slot);
|
||||
setElem(result, slot - begin, temp);
|
||||
Object temp = getElem(cx, thisObj, slot);
|
||||
setElem(cx, result, slot - begin, temp);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -55,7 +55,7 @@ public final class NativeCall extends IdScriptable
|
|||
|
||||
NativeCall() { }
|
||||
|
||||
NativeCall(Context cx, Scriptable scope, NativeFunction funObj,
|
||||
NativeCall(Scriptable scope, NativeFunction funObj,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
this.funObj = funObj;
|
||||
|
@ -64,10 +64,6 @@ public final class NativeCall extends IdScriptable
|
|||
setParentScope(scope);
|
||||
// leave prototype null
|
||||
|
||||
// save current activation
|
||||
this.caller = cx.currentActivation;
|
||||
cx.currentActivation = this;
|
||||
|
||||
this.originalArgs = (args == null) ? ScriptRuntime.emptyArgs : args;
|
||||
|
||||
// initialize values of arguments
|
||||
|
@ -101,37 +97,26 @@ public final class NativeCall extends IdScriptable
|
|||
return "Call";
|
||||
}
|
||||
|
||||
NativeCall getActivation(Function f)
|
||||
{
|
||||
NativeCall x = this;
|
||||
do {
|
||||
if (x.funObj == f)
|
||||
return x;
|
||||
x = x.caller;
|
||||
} while (x != null);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Function getFunctionObject()
|
||||
NativeFunction getFunctionObject()
|
||||
{
|
||||
return funObj;
|
||||
}
|
||||
|
||||
public Object[] getOriginalArguments()
|
||||
Object[] getOriginalArguments()
|
||||
{
|
||||
return originalArgs;
|
||||
}
|
||||
|
||||
public NativeCall getCaller()
|
||||
{
|
||||
return caller;
|
||||
}
|
||||
|
||||
public Scriptable getThisObj()
|
||||
Scriptable getThisObj()
|
||||
{
|
||||
return thisObj;
|
||||
}
|
||||
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
return s.equals("constructor") ? Id_constructor : 0;
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
|
@ -139,7 +124,7 @@ public final class NativeCall extends IdScriptable
|
|||
if (id == Id_constructor) {
|
||||
arity=1; s="constructor";
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(CALL_TAG, id, s, arity);
|
||||
}
|
||||
|
@ -163,19 +148,15 @@ public final class NativeCall extends IdScriptable
|
|||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
return s.equals("constructor") ? Id_constructor : 0;
|
||||
}
|
||||
|
||||
private static final int
|
||||
Id_constructor = 1,
|
||||
MAX_PROTOTYPE_ID = 1;
|
||||
|
||||
|
||||
NativeCall caller;
|
||||
NativeFunction funObj;
|
||||
Scriptable thisObj;
|
||||
private NativeFunction funObj;
|
||||
private Scriptable thisObj;
|
||||
private Object[] originalArgs;
|
||||
|
||||
NativeCall parentActivationCall;
|
||||
Scriptable parentActivationScope;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,8 @@ public class NativeFunction extends BaseFunction
|
|||
{
|
||||
if (version != Context.VERSION_1_2)
|
||||
return argCount;
|
||||
NativeCall activation = getActivation(Context.getContext());
|
||||
Context cx = Context.getContext();
|
||||
NativeCall activation = ScriptRuntime.findFunctionActivation(cx, this);
|
||||
if (activation == null)
|
||||
return argCount;
|
||||
return activation.getOriginalArguments().length;
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
package org.mozilla.javascript;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.mozilla.javascript.xml.XMLLib;
|
||||
|
||||
/**
|
||||
* This class implements the global native object (function and value
|
||||
|
@ -83,6 +84,9 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
|
|||
case Id_isNaN:
|
||||
name = "isNaN";
|
||||
break;
|
||||
case Id_isXMLName:
|
||||
name = "isXMLName";
|
||||
break;
|
||||
case Id_parseFloat:
|
||||
name = "parseFloat";
|
||||
break;
|
||||
|
@ -195,6 +199,14 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
|
|||
return (d != d) ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -756,12 +768,13 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
|
|||
Id_eval = 6,
|
||||
Id_isFinite = 7,
|
||||
Id_isNaN = 8,
|
||||
Id_parseFloat = 9,
|
||||
Id_parseInt = 10,
|
||||
Id_unescape = 11,
|
||||
Id_uneval = 12,
|
||||
Id_isXMLName = 9,
|
||||
Id_parseFloat = 10,
|
||||
Id_parseInt = 11,
|
||||
Id_unescape = 12,
|
||||
Id_uneval = 13,
|
||||
|
||||
LAST_SCOPE_FUNCTION_ID = 12,
|
||||
LAST_SCOPE_FUNCTION_ID = 13,
|
||||
|
||||
Id_new_CommonError = 13;
|
||||
Id_new_CommonError = 14;
|
||||
}
|
||||
|
|
|
@ -362,10 +362,10 @@ WrapFactory#wrap(Context cx, Scriptable scope, Object obj, Class)}
|
|||
|
||||
case JSTYPE_OBJECT:
|
||||
// Other objects takes #1-#3 spots
|
||||
if (to == fromObj.getClass()) {
|
||||
// No conversion required
|
||||
return 1;
|
||||
}
|
||||
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
|
||||
|
@ -402,7 +402,6 @@ WrapFactory#wrap(Context cx, Scriptable scope, Object obj, Class)}
|
|||
}
|
||||
|
||||
return CONVERSION_NONE;
|
||||
|
||||
}
|
||||
|
||||
static int getSizeRank(Class aType) {
|
||||
|
|
|
@ -147,6 +147,15 @@ public class NativeWith implements Scriptable, IdFunctionMaster {
|
|||
return prototype.hasInstance(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Must return null to continue looping or the final collection result.
|
||||
*/
|
||||
public Object updateDotQuery(boolean value)
|
||||
{
|
||||
// NativeWith itself does not support it
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
|
|
|
@ -21,7 +21,10 @@
|
|||
* Contributor(s):
|
||||
* Mike Ang
|
||||
* Igor Bukanov
|
||||
* Ethan Hugg
|
||||
* Terry Lucas
|
||||
* Mike McCabe
|
||||
* Milen Nankov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
|
@ -103,13 +106,18 @@ public class Parser
|
|||
return parse();
|
||||
}
|
||||
|
||||
private void mustHaveXML()
|
||||
{
|
||||
if (!compilerEnv.isXmlAvailable()) {
|
||||
reportError("msg.XML.not.available");
|
||||
}
|
||||
}
|
||||
|
||||
private void mustMatchToken(int toMatch, String messageId)
|
||||
throws IOException, ParserException
|
||||
{
|
||||
int tt;
|
||||
if ((tt = ts.getToken()) != toMatch) {
|
||||
if (!ts.matchToken(toMatch)) {
|
||||
reportError(messageId);
|
||||
ts.ungetToken(tt); // In case the parser decides to continue
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,13 +218,6 @@ public class Parser
|
|||
return nestingOfFunction != 0;
|
||||
}
|
||||
|
||||
void setRequiresActivation()
|
||||
{
|
||||
if (insideFunction()) {
|
||||
((FunctionNode)currentScriptOrFn).setRequiresActivation();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The C version of this function takes an argument list,
|
||||
* which doesn't seem to be needed for tree generation...
|
||||
|
@ -601,6 +602,7 @@ public class Parser
|
|||
}
|
||||
|
||||
case Token.FOR: {
|
||||
boolean isForEach = false;
|
||||
skipsemi = true;
|
||||
|
||||
decompiler.addToken(Token.FOR);
|
||||
|
@ -611,6 +613,16 @@ public class Parser
|
|||
Node incr = null; // to kill warning
|
||||
Node body;
|
||||
|
||||
// See if this is a for each () instead of just a for ()
|
||||
if (ts.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 = ts.peekToken();
|
||||
|
@ -658,7 +670,7 @@ public class Parser
|
|||
|
||||
if (incr == null) {
|
||||
// cond could be null if 'in obj' got eaten by the init node.
|
||||
pn = nf.createForIn(init, cond, body, lineno);
|
||||
pn = nf.createForIn(init, cond, body, isForEach, lineno);
|
||||
} else {
|
||||
pn = nf.createFor(init, cond, incr, body, lineno);
|
||||
}
|
||||
|
@ -842,6 +854,33 @@ public class Parser
|
|||
break;
|
||||
}
|
||||
|
||||
case Token.DEFAULT :
|
||||
mustHaveXML();
|
||||
int nsLine = ts.getLineno();
|
||||
|
||||
if (!(ts.matchToken(Token.NAME)
|
||||
&& ts.getString().equals("xml")))
|
||||
{
|
||||
reportError("msg.bad.namespace");
|
||||
}
|
||||
decompiler.addName(ts.getString());
|
||||
|
||||
if (!(ts.matchToken(Token.NAME)
|
||||
&& ts.getString().equals("namespace")))
|
||||
{
|
||||
reportError("msg.bad.namespace");
|
||||
}
|
||||
decompiler.addName(ts.getString());
|
||||
|
||||
if (!ts.matchToken(Token.ASSIGN)) {
|
||||
reportError("msg.bad.namespace");
|
||||
}
|
||||
decompiler.addToken(Token.ASSIGN);
|
||||
|
||||
Node expr = expr(false);
|
||||
pn = nf.createDefaultNamespace(expr, nsLine);
|
||||
break;
|
||||
|
||||
default: {
|
||||
int lastExprType = tt;
|
||||
int tokenno = ts.getTokenno();
|
||||
|
@ -1203,6 +1242,14 @@ public class Parser
|
|||
case Token.ERROR:
|
||||
break;
|
||||
|
||||
// XML stream encountered in expression.
|
||||
case Token.LT:
|
||||
if (compilerEnv.isXmlAvailable()) {
|
||||
Node pn = xmlInitializer();
|
||||
return memberExprTail(true, pn);
|
||||
}
|
||||
// Fall thru to the default handling of RELOP
|
||||
|
||||
default:
|
||||
ts.ungetToken(tt);
|
||||
|
||||
|
@ -1232,6 +1279,74 @@ public class Parser
|
|||
|
||||
}
|
||||
|
||||
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);
|
||||
decompiler.addToken(Token.NEW);
|
||||
decompiler.addToken(Token.DOT);
|
||||
|
||||
String xml = ts.getString();
|
||||
boolean fAnonymous = xml.trim().startsWith("<>");
|
||||
|
||||
decompiler.addName(fAnonymous ? "XMLList" : "XML");
|
||||
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.addString(xml);
|
||||
mustMatchToken(Token.LC, "msg.syntax");
|
||||
decompiler.addToken(Token.LC);
|
||||
expr = (ts.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()) {
|
||||
pn = nf.createBinary(Token.ADD, pn, nf.createString("\""));
|
||||
expr = nf.createUnary(Token.ESCXMLATTR, expr);
|
||||
pn = nf.createBinary(Token.ADD, pn, expr);
|
||||
pn = nf.createBinary(Token.ADD, pn, nf.createString("\""));
|
||||
} else {
|
||||
expr = nf.createUnary(Token.ESCXMLTEXT, expr);
|
||||
pn = nf.createBinary(Token.ADD, pn, expr);
|
||||
}
|
||||
break;
|
||||
case Token.XMLEND:
|
||||
xml = ts.getString();
|
||||
decompiler.addString(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:
|
||||
ts.ungetToken(tt);
|
||||
reportError("msg.syntax");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void argumentList(Node listNode)
|
||||
throws IOException, ParserException
|
||||
{
|
||||
|
@ -1302,35 +1417,193 @@ public class Parser
|
|||
throws IOException, ParserException
|
||||
{
|
||||
int tt;
|
||||
while ((tt = ts.getToken()) > Token.EOF) {
|
||||
if (tt == Token.DOT) {
|
||||
tailLoop:
|
||||
while ((tt = ts.getToken()) != Token.EOF) {
|
||||
switch (tt) {
|
||||
case Token.DOT: {
|
||||
decompiler.addToken(Token.DOT);
|
||||
mustMatchToken(Token.NAME, "msg.no.name.after.dot");
|
||||
String s = ts.getString();
|
||||
decompiler.addName(s);
|
||||
pn = nf.createBinary(Token.DOT, pn, nf.createName(s));
|
||||
} else if (tt == Token.LB) {
|
||||
Node n;
|
||||
if (compilerEnv.isXmlAvailable()) {
|
||||
n = nameOrPropertyIdentifier();
|
||||
} else {
|
||||
mustMatchToken(Token.NAME, "msg.no.name.after.dot");
|
||||
String s = ts.getString();
|
||||
decompiler.addName(s);
|
||||
n = nf.createName(s);
|
||||
}
|
||||
pn = nf.createBinary(Token.DOT, pn, n);
|
||||
break;
|
||||
}
|
||||
|
||||
case Token.DOTDOT: {
|
||||
mustHaveXML();
|
||||
decompiler.addToken(Token.DOTDOT);
|
||||
Node n = nameOrPropertyIdentifier();
|
||||
pn = nf.createBinary(Token.DOTDOT, pn, n);
|
||||
break;
|
||||
}
|
||||
|
||||
case Token.DOTQUERY:
|
||||
mustHaveXML();
|
||||
decompiler.addToken(Token.DOTQUERY);
|
||||
pn = nf.createDotQuery(pn, expr(false), ts.getLineno());
|
||||
mustMatchToken(Token.RP, "msg.no.paren");
|
||||
break;
|
||||
|
||||
case Token.LB:
|
||||
decompiler.addToken(Token.LB);
|
||||
pn = nf.createBinary(Token.LB, pn, expr(false));
|
||||
|
||||
mustMatchToken(Token.RB, "msg.no.bracket.index");
|
||||
decompiler.addToken(Token.RB);
|
||||
} else if (allowCallSyntax && tt == Token.LP) {
|
||||
/* make a call node */
|
||||
break;
|
||||
|
||||
case Token.LP:
|
||||
if (!allowCallSyntax) {
|
||||
ts.ungetToken(tt);
|
||||
break tailLoop;
|
||||
}
|
||||
decompiler.addToken(Token.LP);
|
||||
pn = nf.createCallOrNew(Token.CALL, pn);
|
||||
|
||||
/* Add the arguments to pn, if any are supplied. */
|
||||
argumentList(pn);
|
||||
} else {
|
||||
ts.ungetToken(tt);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ts.ungetToken(tt);
|
||||
break tailLoop;
|
||||
}
|
||||
}
|
||||
return pn;
|
||||
}
|
||||
|
||||
private Node nameOrPropertyIdentifier()
|
||||
throws IOException, ParserException
|
||||
{
|
||||
Node pn;
|
||||
int tt = ts.getToken();
|
||||
|
||||
switch (tt) {
|
||||
// handles: name, ns::name, ns::*, ns::[expr]
|
||||
case Token.NAME: {
|
||||
String s = ts.getString();
|
||||
decompiler.addName(s);
|
||||
pn = nameOrQualifiedName(s, false);
|
||||
break;
|
||||
}
|
||||
|
||||
// handles: *, *::name, *::*, *::[expr]
|
||||
case Token.MUL:
|
||||
decompiler.addName("*");
|
||||
pn = nameOrQualifiedName("*", false);
|
||||
break;
|
||||
|
||||
// handles: '@attr', '@ns::attr', '@ns::*', '@ns::*',
|
||||
// '@::attr', '@::*', '@*', '@*::attr', '@*::*'
|
||||
case Token.XMLATTR:
|
||||
decompiler.addToken(Token.XMLATTR);
|
||||
pn = attributeIdentifier();
|
||||
break;
|
||||
|
||||
default:
|
||||
reportError("msg.no.name.after.dot");
|
||||
pn = nf.createName("?");
|
||||
}
|
||||
|
||||
return pn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Xml attribute expression:
|
||||
* '@attr', '@ns::attr', '@ns::*', '@ns::*', '@*', '@*::attr', '@*::*'
|
||||
*/
|
||||
private Node attributeIdentifier()
|
||||
throws IOException
|
||||
{
|
||||
Node pn;
|
||||
int tt = ts.getToken();
|
||||
|
||||
switch (tt) {
|
||||
// handles: @name, @ns::name, @ns::*, @ns::[expr]
|
||||
case Token.NAME: {
|
||||
String s = ts.getString();
|
||||
decompiler.addName(s);
|
||||
pn = nf.createAttributeName(nameOrQualifiedName(s, false));
|
||||
break;
|
||||
}
|
||||
|
||||
// handles: @*, @*::name, @*::*, @*::[expr]
|
||||
case Token.MUL:
|
||||
decompiler.addName("*");
|
||||
pn = nf.createAttributeName(nameOrQualifiedName("*", false));
|
||||
break;
|
||||
|
||||
// handles @[expr]
|
||||
case Token.LB:
|
||||
decompiler.addToken(Token.LB);
|
||||
pn = nf.createAttributeExpr(expr(false));
|
||||
mustMatchToken(Token.RB, "msg.no.bracket.index");
|
||||
decompiler.addToken(Token.RB);
|
||||
break;
|
||||
|
||||
default:
|
||||
reportError("msg.no.name.after.xmlAttr");
|
||||
pn = nf.createAttributeExpr(nf.createString("?"));
|
||||
break;
|
||||
}
|
||||
|
||||
return pn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if :: follows name in which case it becomes qualified name
|
||||
*/
|
||||
private Node nameOrQualifiedName(String name, boolean primaryContext)
|
||||
throws IOException, ParserException
|
||||
{
|
||||
colonColonCheck:
|
||||
if (ts.matchToken(Token.COLONCOLON)) {
|
||||
decompiler.addToken(Token.COLONCOLON);
|
||||
|
||||
Node pn;
|
||||
int tt = ts.getToken();
|
||||
|
||||
switch (tt) {
|
||||
// handles name::name
|
||||
case Token.NAME: {
|
||||
String s = ts.getString();
|
||||
decompiler.addName(s);
|
||||
pn = nf.createQualifiedName(name, s);
|
||||
break;
|
||||
}
|
||||
|
||||
// handles name::*
|
||||
case Token.MUL:
|
||||
decompiler.addName("*");
|
||||
pn = nf.createQualifiedName(name, "*");
|
||||
break;
|
||||
|
||||
// handles name::[expr]
|
||||
case Token.LB:
|
||||
decompiler.addToken(Token.LB);
|
||||
pn = nf.createQualifiedExpr(name, expr(false));
|
||||
mustMatchToken(Token.RB, "msg.no.bracket.index");
|
||||
decompiler.addToken(Token.RB);
|
||||
break;
|
||||
|
||||
default:
|
||||
reportError("msg.no.name.after.coloncolon");
|
||||
break colonColonCheck;
|
||||
}
|
||||
|
||||
if (primaryContext) {
|
||||
pn = nf.createXMLPrimary(pn);
|
||||
}
|
||||
return pn;
|
||||
}
|
||||
|
||||
return nf.createName(name);
|
||||
}
|
||||
|
||||
private Node primaryExpr()
|
||||
throws IOException, ParserException
|
||||
{
|
||||
|
@ -1452,10 +1725,22 @@ public class Parser
|
|||
mustMatchToken(Token.RP, "msg.no.paren");
|
||||
return pn;
|
||||
|
||||
case Token.NAME:
|
||||
case Token.XMLATTR:
|
||||
mustHaveXML();
|
||||
decompiler.addToken(Token.XMLATTR);
|
||||
pn = attributeIdentifier();
|
||||
return nf.createXMLPrimary(pn);
|
||||
|
||||
case Token.NAME: {
|
||||
String name = ts.getString();
|
||||
decompiler.addName(name);
|
||||
return nf.createName(name);
|
||||
if (compilerEnv.isXmlAvailable()) {
|
||||
pn = nameOrQualifiedName(name, true);
|
||||
} else {
|
||||
pn = nf.createName(name);
|
||||
}
|
||||
return pn;
|
||||
}
|
||||
|
||||
case Token.NUMBER:
|
||||
double n = ts.getNumber();
|
||||
|
@ -1507,7 +1792,7 @@ public class Parser
|
|||
|
||||
private boolean ok; // Did the parse encounter an error?
|
||||
|
||||
private ScriptOrFnNode currentScriptOrFn;
|
||||
ScriptOrFnNode currentScriptOrFn;
|
||||
|
||||
private int nestingOfFunction;
|
||||
private int nestingOfWith;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -22,6 +22,7 @@
|
|||
* Roger Lawrence
|
||||
* Mike McCabe
|
||||
* Igor Bukanov
|
||||
* Milen Nankov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
|
@ -128,82 +129,100 @@ public class Token
|
|||
GETVAR = 54,
|
||||
SETVAR = 55,
|
||||
CATCH_SCOPE = 56,
|
||||
ENUM_INIT = 57,
|
||||
ENUM_NEXT = 58,
|
||||
ENUM_ID = 59,
|
||||
THISFN = 60,
|
||||
RETURN_RESULT = 61, // to return prevoisly stored return result
|
||||
ARRAYLIT = 62, // array literal
|
||||
OBJECTLIT = 63, // object literal
|
||||
GET_REF = 64, // *reference
|
||||
SET_REF = 65, // *reference = something
|
||||
REF_CALL = 66, // f(args) = something or f(args)++
|
||||
SPECIAL_REF = 67, // reference for special properties like __proto
|
||||
GENERIC_REF = 68, // generic reference to generate runtime ref errors
|
||||
ENUM_INIT_KEYS = 57,
|
||||
ENUM_INIT_VALUES = 58,
|
||||
ENUM_NEXT = 59,
|
||||
ENUM_ID = 60,
|
||||
THISFN = 61,
|
||||
RETURN_RESULT = 62, // to return prevoisly stored return result
|
||||
ARRAYLIT = 63, // array literal
|
||||
OBJECTLIT = 64, // object literal
|
||||
GET_REF = 65, // *reference
|
||||
SET_REF = 66, // *reference = something
|
||||
DEL_REF = 67, // delete reference
|
||||
REF_CALL = 68, // f(args) = something or f(args)++
|
||||
SPECIAL_REF = 69, // reference for special properties like __proto
|
||||
GENERIC_REF = 70, // generic reference to generate runtime ref errors
|
||||
|
||||
LAST_BYTECODE_TOKEN = 68,
|
||||
// For XML support:
|
||||
DEFAULTNAMESPACE = 71, // default xml namespace =
|
||||
COLONCOLON = 72, // ::
|
||||
ESCXMLATTR = 73,
|
||||
ESCXMLTEXT = 74,
|
||||
TOATTRNAME = 75,
|
||||
DESCENDANTS = 76,
|
||||
XML_REF = 77,
|
||||
|
||||
LAST_BYTECODE_TOKEN = 77,
|
||||
// End of interpreter bytecodes
|
||||
|
||||
TRY = 69,
|
||||
SEMI = 70, // semicolon
|
||||
LB = 71, // left and right brackets
|
||||
RB = 72,
|
||||
LC = 73, // left and right curlies (braces)
|
||||
RC = 74,
|
||||
LP = 75, // left and right parentheses
|
||||
RP = 76,
|
||||
COMMA = 77, // comma operator
|
||||
ASSIGN = 78, // simple assignment (=)
|
||||
ASSIGNOP = 79, // assignment with operation (+= -= etc.)
|
||||
HOOK = 80, // conditional (?:)
|
||||
COLON = 81,
|
||||
OR = 82, // logical or (||)
|
||||
AND = 83, // logical and (&&)
|
||||
INC = 84, // increment/decrement (++ --)
|
||||
DEC = 85,
|
||||
DOT = 86, // member operator (.)
|
||||
FUNCTION = 87, // function keyword
|
||||
EXPORT = 88, // export keyword
|
||||
IMPORT = 89, // import keyword
|
||||
IF = 90, // if keyword
|
||||
ELSE = 91, // else keyword
|
||||
SWITCH = 92, // switch keyword
|
||||
CASE = 93, // case keyword
|
||||
DEFAULT = 94, // default keyword
|
||||
WHILE = 95, // while keyword
|
||||
DO = 96, // do keyword
|
||||
FOR = 97, // for keyword
|
||||
BREAK = 98, // break keyword
|
||||
CONTINUE = 99, // continue keyword
|
||||
VAR = 100, // var keyword
|
||||
WITH = 101, // with keyword
|
||||
CATCH = 102, // catch keyword
|
||||
FINALLY = 103, // finally keyword
|
||||
VOID = 104, // void keyword
|
||||
RESERVED = 105, // reserved keywords
|
||||
TRY = 78,
|
||||
SEMI = 79, // semicolon
|
||||
LB = 80, // left and right brackets
|
||||
RB = 81,
|
||||
LC = 82, // left and right curlies (braces)
|
||||
RC = 83,
|
||||
LP = 84, // left and right parentheses
|
||||
RP = 85,
|
||||
COMMA = 86, // comma operator
|
||||
ASSIGN = 87, // simple assignment (=)
|
||||
ASSIGNOP = 88, // assignment with operation (+= -= etc.)
|
||||
HOOK = 89, // conditional (?:)
|
||||
COLON = 90,
|
||||
OR = 91, // logical or (||)
|
||||
AND = 92, // logical and (&&)
|
||||
INC = 93, // increment/decrement (++ --)
|
||||
DEC = 94,
|
||||
DOT = 95, // member operator (.)
|
||||
FUNCTION = 96, // function keyword
|
||||
EXPORT = 97, // export keyword
|
||||
IMPORT = 98, // import keyword
|
||||
IF = 99, // if keyword
|
||||
ELSE = 100, // else keyword
|
||||
SWITCH = 101, // switch keyword
|
||||
CASE = 102, // case keyword
|
||||
DEFAULT = 103, // default keyword
|
||||
WHILE = 104, // while keyword
|
||||
DO = 105, // do keyword
|
||||
FOR = 106, // for keyword
|
||||
BREAK = 107, // break keyword
|
||||
CONTINUE = 108, // continue keyword
|
||||
VAR = 109, // var keyword
|
||||
WITH = 110, // with keyword
|
||||
CATCH = 111, // catch keyword
|
||||
FINALLY = 112, // finally keyword
|
||||
VOID = 113, // void keyword
|
||||
RESERVED = 114, // reserved keywords
|
||||
|
||||
EMPTY = 106,
|
||||
EMPTY = 115,
|
||||
|
||||
/* types used for the parse tree - these never get returned
|
||||
* by the scanner.
|
||||
*/
|
||||
|
||||
BLOCK = 107, // statement block
|
||||
LABEL = 108, // label
|
||||
TARGET = 109,
|
||||
LOOP = 110,
|
||||
EXPR_VOID = 111, // expression statement in functions
|
||||
EXPR_RESULT = 112, // expression statement in scripts
|
||||
JSR = 113,
|
||||
SCRIPT = 114, // top-level node for entire script
|
||||
TYPEOFNAME = 115, // for typeof(simple-name)
|
||||
USE_STACK = 116,
|
||||
SETPROP_OP = 117, // x.y op= something
|
||||
SETELEM_OP = 118, // x[y] op= something
|
||||
LOCAL_BLOCK = 119,
|
||||
SET_REF_OP = 120, // *reference op= something
|
||||
BLOCK = 116, // statement block
|
||||
LABEL = 117, // label
|
||||
TARGET = 118,
|
||||
LOOP = 119,
|
||||
EXPR_VOID = 120, // expression statement in functions
|
||||
EXPR_RESULT = 121, // expression statement in scripts
|
||||
JSR = 122,
|
||||
SCRIPT = 123, // top-level node for entire script
|
||||
TYPEOFNAME = 124, // for typeof(simple-name)
|
||||
USE_STACK = 125,
|
||||
SETPROP_OP = 126, // x.y op= something
|
||||
SETELEM_OP = 127, // x[y] op= something
|
||||
LOCAL_BLOCK = 128,
|
||||
SET_REF_OP = 129, // *reference op= something
|
||||
|
||||
LAST_TOKEN = 120;
|
||||
// For XML support:
|
||||
DOTDOT = 130, // member operator (..)
|
||||
XML = 131, // XML type
|
||||
DOTQUERY = 132, // .() -- e.g., x.emps.emp.(name == "terry")
|
||||
XMLATTR = 133, // @
|
||||
XMLEND = 134,
|
||||
|
||||
LAST_TOKEN = 134;
|
||||
|
||||
public static String name(int token)
|
||||
{
|
||||
|
@ -274,7 +293,8 @@ public class Token
|
|||
case GETVAR: return "GETVAR";
|
||||
case SETVAR: return "SETVAR";
|
||||
case CATCH_SCOPE: return "CATCH_SCOPE";
|
||||
case ENUM_INIT: return "ENUM_INIT";
|
||||
case ENUM_INIT_KEYS: return "ENUM_INIT_KEYS";
|
||||
case ENUM_INIT_VALUES: return "ENUM_INIT_VALUES";
|
||||
case ENUM_NEXT: return "ENUM_NEXT";
|
||||
case ENUM_ID: return "ENUM_ID";
|
||||
case THISFN: return "THISFN";
|
||||
|
@ -283,9 +303,17 @@ public class Token
|
|||
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 SPECIAL_REF: return "SPECIAL_REF";
|
||||
case GENERIC_REF: return "GENERIC_REF";
|
||||
case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
|
||||
case COLONCOLON: return "COLONCOLON";
|
||||
case ESCXMLTEXT: return "ESCXMLTEXT";
|
||||
case ESCXMLATTR: return "ESCXMLATTR";
|
||||
case TOATTRNAME: return "TOATTRNAME";
|
||||
case DESCENDANTS: return "DESCENDANTS";
|
||||
case XML_REF: return "XML_REF";
|
||||
case TRY: return "TRY";
|
||||
case SEMI: return "SEMI";
|
||||
case LB: return "LB";
|
||||
|
@ -337,6 +365,11 @@ public class Token
|
|||
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 XML: return "XML";
|
||||
case DOTQUERY: return "DOTQUERY";
|
||||
case XMLATTR: return "XMLATTR";
|
||||
case XMLEND: return "XMLEND";
|
||||
}
|
||||
|
||||
// Token without name
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
* Roger Lawrence
|
||||
* Mike McCabe
|
||||
* Igor Bukanov
|
||||
* Ethan Hugg
|
||||
* Terry Lucas
|
||||
* Milen Nankov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
|
@ -380,6 +383,8 @@ public class TokenStream
|
|||
}
|
||||
}
|
||||
|
||||
if (c == '@') return Token.XMLATTR;
|
||||
|
||||
// identifier/keyword/instanceof?
|
||||
// watch out for starting with a <backslash>
|
||||
boolean identifierStart;
|
||||
|
@ -686,8 +691,20 @@ public class TokenStream
|
|||
case ')': return Token.RP;
|
||||
case ',': return Token.COMMA;
|
||||
case '?': return Token.HOOK;
|
||||
case ':': return Token.COLON;
|
||||
case '.': return Token.DOT;
|
||||
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('|')) {
|
||||
|
@ -969,6 +986,288 @@ public class TokenStream
|
|||
return c > 127 && Character.getType((char)c) == Character.FORMAT;
|
||||
}
|
||||
|
||||
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;
|
||||
reportCurrentLineError(Context.getMessage0(
|
||||
"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;
|
||||
reportCurrentLineError(Context.getMessage0(
|
||||
"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;
|
||||
reportCurrentLineError(Context.getMessage0(
|
||||
"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;
|
||||
reportCurrentLineError(Context.getMessage0("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;
|
||||
reportCurrentLineError(Context.getMessage0("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;
|
||||
reportCurrentLineError(Context.getMessage0("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;
|
||||
reportCurrentLineError(Context.getMessage0("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;
|
||||
reportCurrentLineError(Context.getMessage0("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;
|
||||
reportCurrentLineError(Context.getMessage0("msg.XML.bad.form"));
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getStringFromBuffer() {
|
||||
return new String(stringBuffer, 0, stringBufferTop);
|
||||
}
|
||||
|
@ -1188,5 +1487,10 @@ public class TokenStream
|
|||
private int sourceEnd;
|
||||
private int sourceCursor;
|
||||
|
||||
// for xml tokenizer
|
||||
private boolean xmlIsAttribute;
|
||||
private boolean xmlIsTagContent;
|
||||
private int xmlOpenTagsCount;
|
||||
|
||||
CompilerEnvirons compilerEnv;
|
||||
}
|
||||
|
|
|
@ -1095,6 +1095,7 @@ class BodyCodegen
|
|||
itsOneArgArray = -1;
|
||||
scriptRegexpLocal = -1;
|
||||
epilogueLabel = -1;
|
||||
enterAreaStartLabel = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1248,35 +1249,37 @@ class BodyCodegen
|
|||
|
||||
String debugVariableName;
|
||||
if (fnCurrent != null) {
|
||||
debugVariableName = "activation";
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
cfw.addALoad(funObjLocal);
|
||||
cfw.addALoad(thisObjLocal);
|
||||
cfw.addALoad(argsLocal);
|
||||
addScriptRuntimeInvoke("initVarObj",
|
||||
addScriptRuntimeInvoke("enterActivationFunction",
|
||||
"(Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Lorg/mozilla/javascript/NativeFunction;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"[Ljava/lang/Object;"
|
||||
+")Lorg/mozilla/javascript/Scriptable;");
|
||||
cfw.addAStore(variableObjectLocal);
|
||||
debugVariableName = "activation";
|
||||
} else {
|
||||
debugVariableName = "global";
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
cfw.addALoad(funObjLocal);
|
||||
cfw.addALoad(thisObjLocal);
|
||||
cfw.addPush(0);
|
||||
addScriptRuntimeInvoke("initScript",
|
||||
addScriptRuntimeInvoke("enterScript",
|
||||
"(Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Lorg/mozilla/javascript/NativeFunction;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Z"
|
||||
+")V");
|
||||
debugVariableName = "global";
|
||||
+")Lorg/mozilla/javascript/Scriptable;");
|
||||
}
|
||||
cfw.addAStore(variableObjectLocal);
|
||||
|
||||
enterAreaStartLabel = cfw.acquireLabel();
|
||||
epilogueLabel = cfw.acquireLabel();
|
||||
cfw.markLabel(enterAreaStartLabel);
|
||||
|
||||
int functionCount = scriptOrFn.getFunctionCount();
|
||||
for (int i = 0; i != functionCount; i++) {
|
||||
|
@ -1321,32 +1324,67 @@ class BodyCodegen
|
|||
|
||||
}
|
||||
|
||||
private void generateEpilogue() {
|
||||
if (epilogueLabel != -1) {
|
||||
cfw.markLabel(epilogueLabel);
|
||||
}
|
||||
if (fnCurrent == null || !hasVarsInRegs) {
|
||||
// restore caller's activation
|
||||
cfw.addALoad(contextLocal);
|
||||
addScriptRuntimeInvoke("popActivation",
|
||||
"(Lorg/mozilla/javascript/Context;)V");
|
||||
if (fnCurrent == null) {
|
||||
cfw.addALoad(popvLocal);
|
||||
private void generateEpilogue()
|
||||
{
|
||||
if (hasVarsInRegs) {
|
||||
if (epilogueLabel != -1) {
|
||||
cfw.markLabel(epilogueLabel);
|
||||
}
|
||||
cfw.add(ByteCode.ARETURN);
|
||||
return;
|
||||
}
|
||||
|
||||
cfw.markLabel(epilogueLabel);
|
||||
generateExitCode();
|
||||
if (fnCurrent == null) {
|
||||
cfw.addALoad(popvLocal);
|
||||
}
|
||||
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 generateExitCode() in the catch block since it takes
|
||||
// less space then full-fetured ByteCode.JSR/ByteCode.RET
|
||||
generateExitCode();
|
||||
|
||||
cfw.addALoad(exceptionObject);
|
||||
releaseWordLocal(exceptionObject);
|
||||
// rethrow
|
||||
cfw.add(ByteCode.ATHROW);
|
||||
|
||||
// mark the handler
|
||||
cfw.addExceptionHandler(enterAreaStartLabel, epilogueLabel,
|
||||
finallyHandler, null); // catch any
|
||||
}
|
||||
|
||||
private void generateExitCode()
|
||||
{
|
||||
cfw.addALoad(contextLocal);
|
||||
if (fnCurrent != null) {
|
||||
addScriptRuntimeInvoke("exitActivationFunction",
|
||||
"(Lorg/mozilla/javascript/Context;)V");
|
||||
} else {
|
||||
addScriptRuntimeInvoke("exitScript",
|
||||
"(Lorg/mozilla/javascript/Context;)V");
|
||||
}
|
||||
}
|
||||
|
||||
private void generateStatement(Node node, Node parent)
|
||||
{
|
||||
// System.out.println("gen code for " + node.toString());
|
||||
|
||||
updateLineNumber(node);
|
||||
int type = node.getType();
|
||||
Node child = node.getFirstChild();
|
||||
switch (type) {
|
||||
case Token.LOOP:
|
||||
case Token.LABEL:
|
||||
visitStatement(node);
|
||||
while (child != null) {
|
||||
generateStatement(child, node);
|
||||
child = child.getNext();
|
||||
|
@ -1355,7 +1393,6 @@ class BodyCodegen
|
|||
|
||||
case Token.WITH:
|
||||
++withNesting;
|
||||
visitStatement(node);
|
||||
while (child != null) {
|
||||
generateStatement(child, node);
|
||||
child = child.getNext();
|
||||
|
@ -1371,7 +1408,6 @@ class BodyCodegen
|
|||
case Token.BLOCK:
|
||||
case Token.EMPTY:
|
||||
// no-ops.
|
||||
visitStatement(node);
|
||||
while (child != null) {
|
||||
generateStatement(child, node);
|
||||
child = child.getNext();
|
||||
|
@ -1379,7 +1415,6 @@ class BodyCodegen
|
|||
break;
|
||||
|
||||
case Token.LOCAL_BLOCK: {
|
||||
visitStatement(node);
|
||||
int local = getNewWordLocal();
|
||||
node.putIntProp(Node.LOCAL_PROP, local);
|
||||
while (child != null) {
|
||||
|
@ -1391,9 +1426,6 @@ class BodyCodegen
|
|||
break;
|
||||
}
|
||||
|
||||
case Token.USE_STACK:
|
||||
break;
|
||||
|
||||
case Token.FUNCTION: {
|
||||
int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP);
|
||||
OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn, fnIndex);
|
||||
|
@ -1418,7 +1450,6 @@ class BodyCodegen
|
|||
|
||||
case Token.RETURN_RESULT:
|
||||
case Token.RETURN:
|
||||
visitStatement(node);
|
||||
if (child != null) {
|
||||
generateExpression(child, node);
|
||||
} else if (type == Token.RETURN) {
|
||||
|
@ -1427,8 +1458,10 @@ class BodyCodegen
|
|||
if (popvLocal < 0) throw Codegen.badTree();
|
||||
cfw.addALoad(popvLocal);
|
||||
}
|
||||
if (epilogueLabel == -1)
|
||||
if (epilogueLabel == -1) {
|
||||
if (!hasVarsInRegs) throw Codegen.badTree();
|
||||
epilogueLabel = cfw.acquireLabel();
|
||||
}
|
||||
cfw.add(ByteCode.GOTO, epilogueLabel);
|
||||
break;
|
||||
|
||||
|
@ -1444,20 +1477,19 @@ class BodyCodegen
|
|||
visitLeaveWith(node, child);
|
||||
break;
|
||||
|
||||
case Token.ENUM_INIT: {
|
||||
case Token.ENUM_INIT_KEYS:
|
||||
case Token.ENUM_INIT_VALUES:
|
||||
generateExpression(child, node);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
addScriptRuntimeInvoke("enumInit",
|
||||
addScriptRuntimeInvoke((type == Token.ENUM_INIT_KEYS)
|
||||
? "enumInit" : "enumValuesInit",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
int local = getLocalBlockRegister(node);
|
||||
cfw.addAStore(local);
|
||||
cfw.addAStore(getLocalBlockRegister(node));
|
||||
break;
|
||||
}
|
||||
|
||||
case Token.EXPR_VOID:
|
||||
visitStatement(node);
|
||||
if (child.getType() == Token.SETVAR) {
|
||||
/* special case this so as to avoid unnecessary
|
||||
load's & pop's */
|
||||
|
@ -1473,7 +1505,6 @@ class BodyCodegen
|
|||
break;
|
||||
|
||||
case Token.EXPR_RESULT:
|
||||
visitStatement(node);
|
||||
generateExpression(child, node);
|
||||
if (popvLocal < 0) {
|
||||
popvLocal = getNewWordLocal();
|
||||
|
@ -1599,7 +1630,7 @@ class BodyCodegen
|
|||
"enumNext", "(Ljava/lang/Object;)Ljava/lang/Boolean;");
|
||||
} else {
|
||||
addScriptRuntimeInvoke(
|
||||
"enumId", "(Ljava/lang/Object;)Ljava/lang/String;");
|
||||
"enumId", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1700,22 +1731,24 @@ class BodyCodegen
|
|||
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:
|
||||
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:
|
||||
cfw.addALoad(contextLocal);
|
||||
addScriptRuntimeInvoke("add",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/Object;"
|
||||
+")Ljava/lang/Object;");
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1840,6 +1873,13 @@ class BodyCodegen
|
|||
visitSetRef(type, node, child);
|
||||
break;
|
||||
|
||||
case Token.DEL_REF:
|
||||
generateExpression(child, node);
|
||||
addScriptRuntimeInvoke("deleteReference",
|
||||
"(Ljava/lang/Object;"
|
||||
+")Ljava/lang/Object;");
|
||||
break;
|
||||
|
||||
case Token.DELPROP:
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
|
@ -1866,10 +1906,80 @@ class BodyCodegen
|
|||
visitSpecialRef(node, child);
|
||||
break;
|
||||
|
||||
case Token.XML_REF:
|
||||
visitXMLRef(node, child);
|
||||
break;
|
||||
|
||||
case Token.GENERIC_REF:
|
||||
visitGenericRef(node, child);
|
||||
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.TOATTRNAME:
|
||||
generateExpression(child, node);
|
||||
cfw.addALoad(contextLocal);
|
||||
addScriptRuntimeInvoke("toAttributeName",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+")Ljava/lang/Object;");
|
||||
break;
|
||||
|
||||
case Token.DESCENDANTS:
|
||||
generateExpression(child, node);
|
||||
cfw.addALoad(contextLocal);
|
||||
addScriptRuntimeInvoke("toDescendantsName",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+")Ljava/lang/Object;");
|
||||
break;
|
||||
|
||||
case Token.COLONCOLON : {
|
||||
if (child.getType() != Token.STRING)
|
||||
throw Codegen.badTree();
|
||||
String namespace = child.getString();
|
||||
cfw.addPush(namespace);
|
||||
child = child.getNext();
|
||||
generateExpression(child, node);
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
addScriptRuntimeInvoke("toQualifiedName",
|
||||
"(Ljava/lang/String;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Unexpected node type "+type);
|
||||
}
|
||||
|
@ -2425,18 +2535,22 @@ class BodyCodegen
|
|||
// name()(...)
|
||||
// -> base = getBase("name"), (base.name, getThis(base))(...)
|
||||
String name = node.getString();
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
cfw.addPush(name);
|
||||
addScriptRuntimeInvoke("getBase",
|
||||
"(Lorg/mozilla/javascript/Scriptable;"
|
||||
"(Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Ljava/lang/String;"
|
||||
+")Lorg/mozilla/javascript/Scriptable;");
|
||||
cfw.add(ByteCode.DUP);
|
||||
cfw.addPush(name);
|
||||
addOptRuntimeInvoke(
|
||||
"getPropScriptable",
|
||||
cfw.addALoad(contextLocal);
|
||||
addScriptRuntimeInvoke(
|
||||
"getObjectProp",
|
||||
"(Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Ljava/lang/String;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+")Ljava/lang/Object;");
|
||||
// swap property and base to call getThis(base)
|
||||
cfw.add(ByteCode.SWAP);
|
||||
|
@ -2472,7 +2586,7 @@ class BodyCodegen
|
|||
}
|
||||
}
|
||||
|
||||
private void visitStatement(Node node)
|
||||
private void updateLineNumber(Node node)
|
||||
{
|
||||
itsLineNumber = node.getLineno();
|
||||
if (itsLineNumber == -1)
|
||||
|
@ -2480,7 +2594,6 @@ class BodyCodegen
|
|||
cfw.addLineNumberEntry((short)itsLineNumber);
|
||||
}
|
||||
|
||||
|
||||
private void visitTryCatchFinally(Node.Jump node, Node child)
|
||||
{
|
||||
/* Save the variable object, in case there are with statements
|
||||
|
@ -2510,7 +2623,6 @@ class BodyCodegen
|
|||
int startLabel = cfw.acquireLabel();
|
||||
cfw.markLabel(startLabel, (short)1);
|
||||
|
||||
visitStatement(node);
|
||||
while (child != null) {
|
||||
generateStatement(child, node);
|
||||
child = child.getNext();
|
||||
|
@ -2629,7 +2741,6 @@ class BodyCodegen
|
|||
|
||||
private void visitThrow(Node node, Node child)
|
||||
{
|
||||
visitStatement(node);
|
||||
generateExpression(child, node);
|
||||
cfw.add(ByteCode.NEW,
|
||||
"org/mozilla/javascript/JavaScriptException");
|
||||
|
@ -2647,7 +2758,6 @@ class BodyCodegen
|
|||
|
||||
private void visitSwitch(Node.Jump node, Node child)
|
||||
{
|
||||
visitStatement(node);
|
||||
generateExpression(child, node);
|
||||
// save selector value
|
||||
short selector = getNewWordLocal();
|
||||
|
@ -2798,14 +2908,16 @@ class BodyCodegen
|
|||
break;
|
||||
}
|
||||
case Token.GETELEM: {
|
||||
Node getElemChild = child.getFirstChild();
|
||||
generateExpression(getElemChild, node);
|
||||
generateExpression(getElemChild.getNext(), node);
|
||||
Node elemChild = child.getFirstChild();
|
||||
generateExpression(elemChild, node);
|
||||
generateExpression(elemChild.getNext(), node);
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
cfw.addPush(incrDecrMask);
|
||||
addScriptRuntimeInvoke("elemIncrDecr",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"I)Ljava/lang/Object;");
|
||||
break;
|
||||
|
@ -2968,11 +3080,13 @@ class BodyCodegen
|
|||
if (type == Token.INSTANCEOF || type == Token.IN) {
|
||||
generateExpression(child, node);
|
||||
generateExpression(rChild, node);
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
addScriptRuntimeInvoke(
|
||||
(type == Token.INSTANCEOF) ? "instanceOf" : "in",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Z");
|
||||
cfw.add(ByteCode.IFNE, trueGOTO);
|
||||
|
@ -3196,11 +3310,13 @@ class BodyCodegen
|
|||
|
||||
private void visitName(Node node)
|
||||
{
|
||||
cfw.addALoad(contextLocal); // push cx
|
||||
cfw.addALoad(variableObjectLocal); // get variable object
|
||||
cfw.addPush(node.getString()); // push name
|
||||
addScriptRuntimeInvoke(
|
||||
"name",
|
||||
"(Lorg/mozilla/javascript/Scriptable;"
|
||||
"(Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Ljava/lang/String;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
|
@ -3212,13 +3328,13 @@ class BodyCodegen
|
|||
generateExpression(child, node);
|
||||
child = child.getNext();
|
||||
}
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addPush(name);
|
||||
addScriptRuntimeInvoke(
|
||||
"setName",
|
||||
"(Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Ljava/lang/String;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
|
@ -3249,12 +3365,12 @@ class BodyCodegen
|
|||
} else {
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
cfw.addPush(node.getString());
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
cfw.addALoad(contextLocal);
|
||||
addScriptRuntimeInvoke(
|
||||
"getProp",
|
||||
"(Ljava/lang/Object;"
|
||||
"getObjectProp",
|
||||
"(Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Ljava/lang/String;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
}
|
||||
|
@ -3322,23 +3438,26 @@ class BodyCodegen
|
|||
Node nameChild = child.getNext();
|
||||
generateExpression(nameChild, node); // the name
|
||||
/*
|
||||
for 'this.foo' we call getPropScriptable which can skip some
|
||||
casting overhead.
|
||||
|
||||
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) {
|
||||
addOptRuntimeInvoke(
|
||||
"getPropScriptable",
|
||||
cfw.addALoad(contextLocal);
|
||||
addScriptRuntimeInvoke(
|
||||
"getObjectProp",
|
||||
"(Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Ljava/lang/String;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+")Ljava/lang/Object;");
|
||||
} else {
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
addScriptRuntimeInvoke(
|
||||
"getProp",
|
||||
"getObjectProp",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/String;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
|
@ -3351,19 +3470,22 @@ class BodyCodegen
|
|||
cfw.add(ByteCode.DUP);
|
||||
}
|
||||
generateExpression(child.getNext(), node); // id
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
|
||||
addOptRuntimeInvoke(
|
||||
"getElem",
|
||||
"getObjectIndex",
|
||||
"(Ljava/lang/Object;D"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
else {
|
||||
addScriptRuntimeInvoke(
|
||||
"getElem",
|
||||
"getObjectId",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
|
@ -3390,12 +3512,12 @@ class BodyCodegen
|
|||
if (type == Token.SETPROP_OP) {
|
||||
// stack: ... object object name -> ... object name object name
|
||||
cfw.add(ByteCode.DUP_X1);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
//for 'this.foo += ...' we call thisGet which can skip some
|
||||
//casting overhead.
|
||||
if (objectChild.getType() == Token.THIS
|
||||
&& nameChild.getType() == Token.STRING)
|
||||
{
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
addOptRuntimeInvoke(
|
||||
"thisGet",
|
||||
"(Lorg/mozilla/javascript/Scriptable;"
|
||||
|
@ -3403,21 +3525,26 @@ class BodyCodegen
|
|||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
} else {
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
addScriptRuntimeInvoke(
|
||||
"getProp",
|
||||
"getObjectProp",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/String;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
}
|
||||
generateExpression(child, node);
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
addScriptRuntimeInvoke(
|
||||
"setProp",
|
||||
"setObjectProp",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/String;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
|
@ -3437,41 +3564,48 @@ class BodyCodegen
|
|||
// stack: ... object object number
|
||||
// -> ... object number object number
|
||||
cfw.add(ByteCode.DUP2_X1);
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
addOptRuntimeInvoke(
|
||||
"getElem",
|
||||
"getObjectIndex",
|
||||
"(Ljava/lang/Object;D"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
} else {
|
||||
// stack: ... object object indexObject
|
||||
// -> ... object indexObject object indexObject
|
||||
cfw.add(ByteCode.DUP_X1);
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
addScriptRuntimeInvoke(
|
||||
"getElem",
|
||||
"getObjectId",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
}
|
||||
generateExpression(child, node);
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
if (indexIsNumber) {
|
||||
addOptRuntimeInvoke(
|
||||
"setElem",
|
||||
"setObjectIndex",
|
||||
"(Ljava/lang/Object;"
|
||||
+"D"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
} else {
|
||||
addScriptRuntimeInvoke(
|
||||
"setElem",
|
||||
"setObjectId",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
|
@ -3499,10 +3633,12 @@ class BodyCodegen
|
|||
child = child.getNext();
|
||||
}
|
||||
// Generate code for "ScriptRuntime.bind(varObj, "s")"
|
||||
cfw.addALoad(variableObjectLocal); // get variable object
|
||||
cfw.addALoad(contextLocal); // push cx
|
||||
cfw.addALoad(variableObjectLocal); // push variable object
|
||||
cfw.addPush(node.getString()); // push name
|
||||
addScriptRuntimeInvoke("bind",
|
||||
"(Lorg/mozilla/javascript/Scriptable;"
|
||||
"(Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Ljava/lang/String;"
|
||||
+")Lorg/mozilla/javascript/Scriptable;");
|
||||
}
|
||||
|
@ -3522,6 +3658,18 @@ class BodyCodegen
|
|||
+")Ljava/lang/Object;");
|
||||
}
|
||||
|
||||
private void visitXMLRef(Node node, Node child)
|
||||
{
|
||||
generateExpression(child, node);
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
addScriptRuntimeInvoke("xmlReference",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
|
||||
private void visitGenericRef(Node node, Node child)
|
||||
{
|
||||
generateExpression(child, node);
|
||||
|
@ -3534,6 +3682,42 @@ class BodyCodegen
|
|||
+")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);
|
||||
|
@ -3718,6 +3902,7 @@ class BodyCodegen
|
|||
private boolean hasVarsInRegs;
|
||||
private boolean inDirectCallFunction;
|
||||
private boolean itsForcedObjectParameters;
|
||||
private int enterAreaStartLabel;
|
||||
private int epilogueLabel;
|
||||
|
||||
private int withNesting = 0;
|
||||
|
|
|
@ -46,61 +46,49 @@ public final class OptRuntime extends ScriptRuntime
|
|||
public static final Double oneObj = new Double(1.0);
|
||||
public static final Double minusOneObj = new Double(-1.0);
|
||||
|
||||
public static Object getElem(Object obj, double dblIndex, Scriptable scope)
|
||||
public static Object getObjectIndex(Object obj, double dblIndex,
|
||||
Context cx, Scriptable scope)
|
||||
{
|
||||
int index = (int) dblIndex;
|
||||
Scriptable start = obj instanceof Scriptable
|
||||
? (Scriptable) obj
|
||||
: toObject(scope, obj);
|
||||
Scriptable m = start;
|
||||
if (((double) index) != dblIndex) {
|
||||
String s = toString(dblIndex);
|
||||
while (m != null) {
|
||||
Object result = m.get(s, start);
|
||||
if (result != Scriptable.NOT_FOUND)
|
||||
return result;
|
||||
m = m.getPrototype();
|
||||
}
|
||||
} else {
|
||||
while (m != null) {
|
||||
Object result = m.get(index, start);
|
||||
if (result != Scriptable.NOT_FOUND)
|
||||
return result;
|
||||
m = m.getPrototype();
|
||||
}
|
||||
if (obj == null || obj == Undefined.instance) {
|
||||
throw undefReadError(obj, toString(dblIndex));
|
||||
}
|
||||
Scriptable sobj;
|
||||
if (obj instanceof Scriptable) {
|
||||
sobj = (Scriptable)obj;
|
||||
} else {
|
||||
sobj = toObject(cx, scope, obj);
|
||||
}
|
||||
|
||||
int index = (int)dblIndex;
|
||||
if ((double)index == dblIndex) {
|
||||
return getObjectIndex(sobj, index, cx);
|
||||
} else {
|
||||
String s = toString(dblIndex);
|
||||
return getObjectProp(sobj, s, cx);
|
||||
}
|
||||
return Undefined.instance;
|
||||
}
|
||||
|
||||
public static Object setElem(Object obj, double dblIndex, Object value,
|
||||
Scriptable scope)
|
||||
public static Object setObjectIndex(Object obj, double dblIndex,
|
||||
Object value,
|
||||
Context cx, Scriptable scope)
|
||||
{
|
||||
int index = (int) dblIndex;
|
||||
Scriptable start = obj instanceof Scriptable
|
||||
? (Scriptable) obj
|
||||
: toObject(scope, obj);
|
||||
Scriptable m = start;
|
||||
if (((double) index) != dblIndex) {
|
||||
String s = toString(dblIndex);
|
||||
do {
|
||||
if (m.has(s, start)) {
|
||||
m.put(s, start, value);
|
||||
return value;
|
||||
}
|
||||
m = m.getPrototype();
|
||||
} while (m != null);
|
||||
start.put(s, start, value);
|
||||
} else {
|
||||
do {
|
||||
if (m.has(index, start)) {
|
||||
m.put(index, start, value);
|
||||
return value;
|
||||
}
|
||||
m = m.getPrototype();
|
||||
} while (m != null);
|
||||
start.put(index, start, value);
|
||||
if (obj == null || obj == Undefined.instance) {
|
||||
throw undefWriteError(obj, String.valueOf(dblIndex), value);
|
||||
}
|
||||
Scriptable sobj;
|
||||
if (obj instanceof Scriptable) {
|
||||
sobj = (Scriptable)obj;
|
||||
} else {
|
||||
sobj = toObject(cx, scope, obj);
|
||||
}
|
||||
|
||||
int index = (int)dblIndex;
|
||||
if ((double)index == dblIndex) {
|
||||
return setObjectIndex(sobj, index, value, cx);
|
||||
} else {
|
||||
String s = toString(dblIndex);
|
||||
return setObjectProp(sobj, s, value, cx);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Object add(Object val1, double val2)
|
||||
|
@ -150,17 +138,6 @@ public final class OptRuntime extends ScriptRuntime
|
|||
return function.call(cx, scope, thisArg, args);
|
||||
}
|
||||
|
||||
public static Object getPropScriptable(Scriptable obj, String id)
|
||||
{
|
||||
if (obj == null || obj == Undefined.instance) {
|
||||
throw ScriptRuntime.undefReadError(obj, id);
|
||||
}
|
||||
Object result = ScriptableObject.getProperty(obj, id);
|
||||
if (result != Scriptable.NOT_FOUND)
|
||||
return result;
|
||||
return Undefined.instance;
|
||||
}
|
||||
|
||||
public static Object[] padStart(Object[] currentArgs, int count) {
|
||||
Object[] result = new Object[currentArgs.length + count];
|
||||
System.arraycopy(currentArgs, 0, result, count, currentArgs.length);
|
||||
|
|
|
@ -382,7 +382,7 @@ class Optimizer
|
|||
int indexType = rewriteForNumberVariables(arrayIndex);
|
||||
if (indexType == NumberType) {
|
||||
// setting the ISNUMBER_PROP signals the codegen
|
||||
// to use the scriptRuntime.setElem that takes
|
||||
// to use the OptRuntime.setObjectIndex that takes
|
||||
// a double index
|
||||
n.putIntProp(Node.ISNUMBER_PROP, Node.LEFT);
|
||||
markDCPNumberContext(arrayIndex);
|
||||
|
@ -410,7 +410,7 @@ class Optimizer
|
|||
if (indexType == NumberType) {
|
||||
if (!convertParameter(arrayIndex)) {
|
||||
// setting the ISNUMBER_PROP signals the codegen
|
||||
// to use the scriptRuntime.getElem that takes
|
||||
// to use the OptRuntime.getObjectIndex that takes
|
||||
// a double index
|
||||
n.putIntProp(Node.ISNUMBER_PROP, Node.RIGHT);
|
||||
}
|
||||
|
|
|
@ -264,6 +264,15 @@ msg.no.semi.stmt =\
|
|||
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
|
||||
|
||||
|
@ -360,6 +369,12 @@ msg.try.no.catchfinally =\
|
|||
msg.syntax =\
|
||||
syntax error
|
||||
|
||||
msg.XML.bad.form =\
|
||||
illegally formed XML syntax
|
||||
|
||||
msg.XML.not.available =\
|
||||
XML runtime not available
|
||||
|
||||
mag.too.deep.parser.recursion =\
|
||||
Too deep recursion while parsing
|
||||
|
||||
|
@ -377,6 +392,9 @@ msg.invalid.type =\
|
|||
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.
|
||||
|
||||
|
@ -404,6 +422,9 @@ msg.null.prop.write =\
|
|||
msg.isnt.function =\
|
||||
{0} is not a function.
|
||||
|
||||
msg.isnt.xml.object =\
|
||||
{0} is not an xml object.
|
||||
|
||||
msg.no.ref.to.get =\
|
||||
{0} is not a reference to read reference value.
|
||||
|
||||
|
@ -507,6 +528,9 @@ msg.illegal.character =\
|
|||
msg.invalid.escape =\
|
||||
invalid Unicode escape sequence
|
||||
|
||||
msg.bad.namespace =\
|
||||
not a valid namespace. Syntax is: namespace variableName as "URI";
|
||||
|
||||
# TokensStream warnings
|
||||
msg.bad.octal.literal =\
|
||||
illegal octal literal digit {0}; interpreting it as a decimal digit
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
package org.mozilla.javascript.xml;
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
public abstract class XMLLib
|
||||
{
|
||||
public static XMLLib extractFromScope(Scriptable scope)
|
||||
{
|
||||
scope = ScriptableObject.getTopLevelScope(scope);
|
||||
Object testXML = ScriptableObject.getClassPrototype(scope, "XML");
|
||||
if (testXML instanceof XMLObject) {
|
||||
return ((XMLObject)testXML).lib();
|
||||
}
|
||||
String msg = ScriptRuntime.getMessage0("msg.XML.not.available");
|
||||
throw Context.reportRuntimeError(msg);
|
||||
}
|
||||
|
||||
public abstract boolean isXMLName(Context cx, Object name);
|
||||
|
||||
public abstract Object toQualifiedName(String namespace,
|
||||
Object nameValue,
|
||||
Scriptable scope);
|
||||
|
||||
public abstract Object toAttributeName(Context cx, Object nameValue);
|
||||
|
||||
public abstract Object toDescendantsName(Context cx, Object name);
|
||||
|
||||
public abstract Reference xmlPrimaryReference(Object nameObject,
|
||||
Scriptable scope);
|
||||
|
||||
public abstract Scriptable enterXMLWith(XMLObject object,
|
||||
Scriptable scope);
|
||||
|
||||
public abstract Scriptable enterDotQuery(XMLObject object,
|
||||
Scriptable scope);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
|
||||
/**
|
||||
* Must calculate obj1 + obj2
|
||||
*/
|
||||
public abstract Object addXMLObjects(Context cx,
|
||||
XMLObject obj1,
|
||||
XMLObject obj2);
|
||||
|
||||
/**
|
||||
* Construct namespace for default xml statement.
|
||||
*/
|
||||
public abstract Object toDefaultXmlNamespace(Context cx, Object uriValue);
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1999.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. 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 Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
package org.mozilla.javascript.xml;
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
import org.mozilla.javascript.xml.*;
|
||||
|
||||
/**
|
||||
* This Interface describes what all XML objects (XML, XMLList) should have in common.
|
||||
*
|
||||
* @see XML
|
||||
*/
|
||||
public abstract class XMLObject extends IdScriptable
|
||||
{
|
||||
public abstract XMLLib lib();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
|
@ -4,40 +4,40 @@
|
|||
Build file for Rhino using Ant (see http://jakarta.apache.org/ant/index.html)
|
||||
Requires Ant version 1.2
|
||||
-->
|
||||
<project name="toolsrc" default="compile" basedir=".">
|
||||
<project name="toolsrc" default="compile" basedir="..">
|
||||
|
||||
<target name="properties">
|
||||
<property name="nest" value=".."/>
|
||||
<property name="build.dir" value="./build"/>
|
||||
<property name="classes" value="${build.dir}/classes"/>
|
||||
<property file="build.properties"/>
|
||||
<property name="debugger"
|
||||
value="org/mozilla/javascript/tools/debugger"/>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="properties">
|
||||
<ant dir="${debugger}" target="download"/>
|
||||
<javac srcdir="."
|
||||
destdir="${nest}/${classes}"
|
||||
<ant dir="toolsrc/${debugger}" target="download"/>
|
||||
<javac srcdir="toolsrc"
|
||||
destdir="${classes}"
|
||||
includes="org/**/*.java"
|
||||
deprecation="on"
|
||||
debug="${debug}">
|
||||
debug="${debug}"
|
||||
target="${target-jvm}">
|
||||
</javac>
|
||||
<copy todir="${nest}/${classes}">
|
||||
<fileset dir="." includes="org/**/*.properties" />
|
||||
<copy todir="${classes}">
|
||||
<fileset dir="toolsrc" includes="org/**/*.properties" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="copy-source" depends="properties">
|
||||
<copy todir="${nest}/${dist.toolsrc}">
|
||||
<fileset dir="."
|
||||
includes="org/**/*.java,org/**/*.properties,build.xml"
|
||||
<mkdir dir="${dist.dir}/toolsrc"/>
|
||||
<copy todir="${dist.dir}/toolsrc">
|
||||
<fileset dir="toolsrc"
|
||||
includes="**/*.java,**/*.properties,**/*.xml"
|
||||
excludes="${debugger}/downloaded/**" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="clean" depends="properties">
|
||||
<delete includeEmptyDirs="true">
|
||||
<fileset dir="${nest}/${classes}"
|
||||
<fileset dir="${classes}"
|
||||
includes="org/mozilla/javascript/tools/**"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
|
Загрузка…
Ссылка в новой задаче