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:
igor%mir2.org 2004-07-28 21:11:02 +00:00
Родитель 20e64eb7e5
Коммит 0659e0b714
27 изменённых файлов: 2584 добавлений и 695 удалений

62
js/rhino/build.properties Normal file
Просмотреть файл

@ -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>