зеркало из https://github.com/mozilla/pjs.git
Top call scope tracking changes:
Since E4X implementation needs to know the activation scope for tracking of default namespaces, previously an elaborated schema was added to set/restore the activation scope which relied on the fact that scrip and function with activation record should always call special entry/exit functions. But that does not work for functions without activation records since they never call any special entry/exit pairs. So if application call such function directly, the function would not store its top scope anywhere and the E4X subsystem would not be able to get E4X library object. The patch fixes with introduction of 2 functions, hasTopCall and doTopCall to ScriptRuntime and adding the following code prefix to each implementation of Callable.call that can start execution of script code: public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) throws JavaScriptException { // Prefix start if (!ScriptRuntime.hasTopCall(cx)) { return ScriptRuntime.doTopCall(this, cx, scope, thisObj, args); } // Prefix end ... In this way there is always registered top scope during script execution and the previous elaborated schema became unnecessary so I reverted that part to almost pre-E4x state.
This commit is contained in:
Родитель
033645c483
Коммит
caf00e67ee
|
@ -226,10 +226,10 @@ final class Arguments extends IdScriptableObject
|
||||||
if (value == UniqueTag.NULL_VALUE) { value = null; }
|
if (value == UniqueTag.NULL_VALUE) { value = null; }
|
||||||
else if (value == null) {
|
else if (value == null) {
|
||||||
NativeCall caller = activation.parentActivationCall;
|
NativeCall caller = activation.parentActivationCall;
|
||||||
if (caller == null) {
|
if (caller != null) {
|
||||||
value = null;
|
|
||||||
} else {
|
|
||||||
value = caller.get("arguments", caller);
|
value = caller.get("arguments", caller);
|
||||||
|
} else {
|
||||||
|
value = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
|
|
@ -2547,11 +2547,8 @@ public class Context
|
||||||
private boolean sealed;
|
private boolean sealed;
|
||||||
private Object sealKey;
|
private Object sealKey;
|
||||||
|
|
||||||
Scriptable topActivationScope;
|
Scriptable topCallScope;
|
||||||
NativeCall currentActivationCall;
|
NativeCall currentActivationCall;
|
||||||
Scriptable currentActivationScope;
|
|
||||||
int currentActivationDepth;
|
|
||||||
|
|
||||||
XMLLib cachedXMLLib;
|
XMLLib cachedXMLLib;
|
||||||
|
|
||||||
// for Objects, Arrays to tag themselves as being printed out,
|
// for Objects, Arrays to tag themselves as being printed out,
|
||||||
|
|
|
@ -54,6 +54,9 @@ final class InterpretedFunction extends NativeFunction
|
||||||
Object[] args)
|
Object[] args)
|
||||||
throws JavaScriptException
|
throws JavaScriptException
|
||||||
{
|
{
|
||||||
|
if (!ScriptRuntime.hasTopCall(cx)) {
|
||||||
|
return ScriptRuntime.doTopCall(this, cx, scope, thisObj, args);
|
||||||
|
}
|
||||||
return Interpreter.interpret(cx, scope, thisObj,
|
return Interpreter.interpret(cx, scope, thisObj,
|
||||||
args, null, 0, args.length,
|
args, null, 0, args.length,
|
||||||
this, itsData);
|
this, itsData);
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the Netscape Public
|
|
||||||
* License Version 1.1 (the "License"); you may not use this file
|
|
||||||
* except in compliance with the License. You may obtain a copy of
|
|
||||||
* the License at http://www.mozilla.org/NPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS
|
|
||||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
||||||
* implied. See the License for the specific language governing
|
|
||||||
* rights and limitations under the License.
|
|
||||||
*
|
|
||||||
* The Original Code is Rhino code, released
|
|
||||||
* May 6, 1999.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is Netscape
|
|
||||||
* Communications Corporation. Portions created by Netscape are
|
|
||||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
|
||||||
* Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
* Roger Lawrence
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
final class InterpretedScript extends NativeFunction implements Script
|
|
||||||
{
|
|
||||||
|
|
||||||
InterpretedScript(InterpreterData theData)
|
|
||||||
{
|
|
||||||
itsData = theData;
|
|
||||||
initScriptFunction(itsData.languageVersion, "",
|
|
||||||
itsData.argNames, itsData.argCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object exec(Context cx, Scriptable scope)
|
|
||||||
throws JavaScriptException
|
|
||||||
{
|
|
||||||
return call(cx, scope, scope, ScriptRuntime.emptyArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object call(Context cx, Scriptable scope,
|
|
||||||
Scriptable thisObj, Object[] args)
|
|
||||||
throws JavaScriptException
|
|
||||||
{
|
|
||||||
return Interpreter.interpret(cx, scope, thisObj,
|
|
||||||
args, null, 0, args.length,
|
|
||||||
this, itsData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEncodedSource()
|
|
||||||
{
|
|
||||||
return Interpreter.getEncodedSource(itsData);
|
|
||||||
}
|
|
||||||
|
|
||||||
InterpreterData itsData;
|
|
||||||
}
|
|
||||||
|
|
|
@ -2041,8 +2041,18 @@ public class Interpreter
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugFrame debuggerFrame = null;
|
DebugFrame debuggerFrame = null;
|
||||||
|
boolean useActivationVars = false;
|
||||||
if (cx.debugger != null) {
|
if (cx.debugger != null) {
|
||||||
debuggerFrame = cx.debugger.getFrame(cx, idata);
|
debuggerFrame = cx.debugger.getFrame(cx, idata);
|
||||||
|
useActivationVars = (debuggerFrame != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idata.itsNeedsActivation || useActivationVars) {
|
||||||
|
if (argsDbl != null) {
|
||||||
|
args = getArgsArray(args, argsDbl, argShift, argCount);
|
||||||
|
argShift = 0;
|
||||||
|
argsDbl = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idata.itsFunctionType != 0) {
|
if (idata.itsFunctionType != 0) {
|
||||||
|
@ -2055,19 +2065,14 @@ public class Interpreter
|
||||||
thisObj = ScriptRuntime.getThis(thisObj);
|
thisObj = ScriptRuntime.getThis(thisObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idata.itsNeedsActivation) {
|
if (idata.itsNeedsActivation || useActivationVars) {
|
||||||
if (argsDbl != null) {
|
|
||||||
args = getArgsArray(args, argsDbl, argShift, argCount);
|
|
||||||
argShift = 0;
|
|
||||||
argsDbl = null;
|
|
||||||
}
|
|
||||||
scope = ScriptRuntime.enterActivationFunction(cx, scope,
|
scope = ScriptRuntime.enterActivationFunction(cx, scope,
|
||||||
fnOrScript,
|
fnOrScript,
|
||||||
thisObj, args);
|
thisObj, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
scope = ScriptRuntime.enterScript(cx, scope, fnOrScript, thisObj);
|
ScriptRuntime.initScript(fnOrScript, thisObj, cx, scope,
|
||||||
|
idata.itsFromEvalCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idata.itsNestedFunctions != null) {
|
if (idata.itsNestedFunctions != null) {
|
||||||
|
@ -2086,19 +2091,7 @@ public class Interpreter
|
||||||
// the regexps re-wrapped during each script execution
|
// the regexps re-wrapped during each script execution
|
||||||
Scriptable[] scriptRegExps = null;
|
Scriptable[] scriptRegExps = null;
|
||||||
|
|
||||||
boolean useActivationVars = false;
|
|
||||||
if (debuggerFrame != null) {
|
if (debuggerFrame != null) {
|
||||||
if (argsDbl != null) {
|
|
||||||
args = getArgsArray(args, argsDbl, argShift, argCount);
|
|
||||||
argShift = 0;
|
|
||||||
argsDbl = null;
|
|
||||||
}
|
|
||||||
if (idata.itsFunctionType != 0 && !idata.itsNeedsActivation) {
|
|
||||||
useActivationVars = true;
|
|
||||||
scope = ScriptRuntime.enterActivationFunction(cx, scope,
|
|
||||||
fnOrScript,
|
|
||||||
thisObj, args);
|
|
||||||
}
|
|
||||||
debuggerFrame.onEnter(cx, scope, thisObj, args);
|
debuggerFrame.onEnter(cx, scope, thisObj, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3119,11 +3112,9 @@ switch (op) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idata.itsFunctionType != 0) {
|
if (idata.itsFunctionType != 0) {
|
||||||
if (idata.itsNeedsActivation || debuggerFrame != null) {
|
if (idata.itsNeedsActivation || useActivationVars) {
|
||||||
ScriptRuntime.exitActivationFunction(cx);
|
ScriptRuntime.exitActivationFunction(cx);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ScriptRuntime.exitScript(cx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (javaException != null) {
|
if (javaException != null) {
|
||||||
|
|
|
@ -157,6 +157,5 @@ public final class NativeCall extends IdScriptableObject
|
||||||
private Object[] originalArgs;
|
private Object[] originalArgs;
|
||||||
|
|
||||||
NativeCall parentActivationCall;
|
NativeCall parentActivationCall;
|
||||||
Scriptable parentActivationScope;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1085,9 +1085,12 @@ public class ScriptRuntime {
|
||||||
|
|
||||||
public static Object setDefaultNamespace(Object namespace, Context cx)
|
public static Object setDefaultNamespace(Object namespace, Context cx)
|
||||||
{
|
{
|
||||||
Scriptable scope = cx.currentActivationScope;
|
Scriptable scope = cx.currentActivationCall;
|
||||||
|
if (scope == null) {
|
||||||
|
scope = cx.topCallScope;
|
||||||
if (scope == null)
|
if (scope == null)
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
XMLLib xmlLib = currentXMLLib(cx);
|
XMLLib xmlLib = currentXMLLib(cx);
|
||||||
Object ns = xmlLib.toDefaultXmlNamespace(cx, namespace);
|
Object ns = xmlLib.toDefaultXmlNamespace(cx, namespace);
|
||||||
|
@ -1107,9 +1110,11 @@ public class ScriptRuntime {
|
||||||
|
|
||||||
public static Object searchDefaultNamespace(Context cx)
|
public static Object searchDefaultNamespace(Context cx)
|
||||||
{
|
{
|
||||||
Scriptable scope = cx.currentActivationScope;
|
Scriptable scope = cx.currentActivationCall;
|
||||||
if (scope == null) {
|
if (scope == null) {
|
||||||
return null;
|
scope = cx.topCallScope;
|
||||||
|
if (scope == null)
|
||||||
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
Object nsObject;
|
Object nsObject;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -1751,8 +1756,7 @@ public class ScriptRuntime {
|
||||||
// been defined, creates a new property in the
|
// been defined, creates a new property in the
|
||||||
// global object. Find the global object by
|
// global object. Find the global object by
|
||||||
// walking up the scope chain.
|
// walking up the scope chain.
|
||||||
Scriptable scope = cx.currentActivationScope;
|
bound = cx.topCallScope;
|
||||||
bound = ScriptableObject.getTopLevelScope(scope);
|
|
||||||
bound.put(id, bound, value);
|
bound.put(id, bound, value);
|
||||||
/*
|
/*
|
||||||
This code is causing immense performance problems in
|
This code is causing immense performance problems in
|
||||||
|
@ -2749,27 +2753,64 @@ public class ScriptRuntime {
|
||||||
return new ImporterTopLevel(cx);
|
return new ImporterTopLevel(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Scriptable enterScript(Context cx, Scriptable scope,
|
public static boolean hasTopCall(Context cx)
|
||||||
NativeFunction funObj,
|
|
||||||
Scriptable thisObj)
|
|
||||||
{
|
{
|
||||||
boolean topLevel = (cx.currentActivationDepth == 0);
|
return (cx.topCallScope != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object doTopCall(Callable callable,
|
||||||
|
Context cx, Scriptable scope,
|
||||||
|
Scriptable thisObj, Object[] args)
|
||||||
|
{
|
||||||
|
if (cx.topCallScope != null)
|
||||||
|
throw new IllegalStateException();
|
||||||
|
|
||||||
|
Object result;
|
||||||
|
cx.topCallScope = ScriptableObject.getTopLevelScope(scope);
|
||||||
|
try {
|
||||||
|
result = callable.call(cx, scope, thisObj, args);
|
||||||
|
} finally {
|
||||||
|
releaseTopCall(cx);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void releaseTopCall(Context cx)
|
||||||
|
{
|
||||||
|
cx.topCallScope = null;
|
||||||
|
// Cleanup cached references
|
||||||
|
cx.cachedXMLLib = null;
|
||||||
|
|
||||||
|
if (cx.currentActivationCall != null) {
|
||||||
|
// Function should always call exitActivationFunction
|
||||||
|
// if it creates activation record
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initScript(NativeFunction funObj, Scriptable thisObj,
|
||||||
|
Context cx, Scriptable scope,
|
||||||
|
boolean evalScript)
|
||||||
|
{
|
||||||
|
if (cx.topCallScope == null)
|
||||||
|
throw new IllegalStateException();
|
||||||
|
|
||||||
|
String[] argNames = funObj.argNames;
|
||||||
|
if (argNames != null) {
|
||||||
|
|
||||||
Scriptable varScope = scope;
|
Scriptable varScope = scope;
|
||||||
// Never define any variables from var statements inside with object.
|
// Never define any variables from var statements inside with
|
||||||
// See bug 38590.
|
// object. See bug 38590.
|
||||||
while (varScope instanceof NativeWith) {
|
while (varScope instanceof NativeWith) {
|
||||||
varScope = varScope.getParentScope();
|
varScope = varScope.getParentScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] argNames = funObj.argNames;
|
|
||||||
if (argNames != null) {
|
|
||||||
for (int i = argNames.length; i-- != 0;) {
|
for (int i = argNames.length; i-- != 0;) {
|
||||||
String name = argNames[i];
|
String name = argNames[i];
|
||||||
// Don't overwrite existing def if already defined in object
|
// Don't overwrite existing def if already defined in object
|
||||||
// or prototypes of object.
|
// or prototypes of object.
|
||||||
if (!hasProp(scope, name)) {
|
if (!hasProp(scope, name)) {
|
||||||
if (topLevel) {
|
if (!evalScript) {
|
||||||
// Global var definitions are supposed to be DONTDELETE
|
// Global var definitions are supposed to be DONTDELETE
|
||||||
ScriptableObject.defineProperty(
|
ScriptableObject.defineProperty(
|
||||||
varScope, name, Undefined.instance,
|
varScope, name, Undefined.instance,
|
||||||
|
@ -2780,29 +2821,6 @@ public class ScriptRuntime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topLevel) {
|
|
||||||
if (cx.currentActivationScope != null)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
cx.currentActivationScope = varScope;
|
|
||||||
}
|
|
||||||
|
|
||||||
increaseActivationDepth(cx);
|
|
||||||
|
|
||||||
return scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void exitScript(Context cx)
|
|
||||||
{
|
|
||||||
if (cx.currentActivationDepth == 0)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
if (cx.currentActivationScope == null)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
|
|
||||||
if (cx.currentActivationDepth == 1) {
|
|
||||||
cx.currentActivationScope = null;
|
|
||||||
}
|
|
||||||
decreaseActivationDepth(cx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Scriptable enterActivationFunction(Context cx,
|
public static Scriptable enterActivationFunction(Context cx,
|
||||||
|
@ -2811,64 +2829,21 @@ public class ScriptRuntime {
|
||||||
Scriptable thisObj,
|
Scriptable thisObj,
|
||||||
Object[] args)
|
Object[] args)
|
||||||
{
|
{
|
||||||
|
if (cx.topCallScope == null)
|
||||||
|
throw new IllegalStateException();
|
||||||
|
|
||||||
NativeCall call = new NativeCall(scope, funObj, thisObj, args);
|
NativeCall call = new NativeCall(scope, funObj, thisObj, args);
|
||||||
call.parentActivationCall = cx.currentActivationCall;
|
call.parentActivationCall = cx.currentActivationCall;
|
||||||
call.parentActivationScope = cx.currentActivationScope;
|
|
||||||
|
|
||||||
cx.currentActivationCall = call;
|
cx.currentActivationCall = call;
|
||||||
cx.currentActivationScope = call;
|
|
||||||
|
|
||||||
increaseActivationDepth(cx);
|
|
||||||
|
|
||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void exitActivationFunction(Context cx)
|
public static void exitActivationFunction(Context cx)
|
||||||
{
|
{
|
||||||
if (cx.currentActivationDepth == 0)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
if (cx.currentActivationScope == null)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
if (cx.currentActivationCall != cx.currentActivationScope)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
|
|
||||||
NativeCall call = cx.currentActivationCall;
|
NativeCall call = cx.currentActivationCall;
|
||||||
cx.currentActivationCall = call.parentActivationCall;
|
cx.currentActivationCall = call.parentActivationCall;
|
||||||
cx.currentActivationScope = call.parentActivationScope;
|
|
||||||
|
|
||||||
call.parentActivationCall = null;
|
call.parentActivationCall = null;
|
||||||
call.parentActivationScope = null;
|
|
||||||
|
|
||||||
decreaseActivationDepth(cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void increaseActivationDepth(Context cx)
|
|
||||||
{
|
|
||||||
// The caller should initialize this already
|
|
||||||
if (cx.currentActivationScope == null)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
|
|
||||||
if (cx.currentActivationDepth == 0) {
|
|
||||||
cx.topActivationScope = cx.currentActivationScope;
|
|
||||||
}
|
|
||||||
++cx.currentActivationDepth;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void decreaseActivationDepth(Context cx)
|
|
||||||
{
|
|
||||||
--cx.currentActivationDepth;
|
|
||||||
|
|
||||||
if (cx.currentActivationDepth == 0) {
|
|
||||||
// The caller should do proper cleanup
|
|
||||||
if (cx.currentActivationScope != null)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
if (cx.currentActivationCall != null)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
cx.topActivationScope = null;
|
|
||||||
|
|
||||||
// Cleanup references
|
|
||||||
cx.cachedXMLLib = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static NativeCall findFunctionActivation(Context cx, Function f)
|
static NativeCall findFunctionActivation(Context cx, Function f)
|
||||||
|
@ -3185,12 +3160,12 @@ public class ScriptRuntime {
|
||||||
private static XMLLib currentXMLLib(Context cx)
|
private static XMLLib currentXMLLib(Context cx)
|
||||||
{
|
{
|
||||||
// Scripts should be running to access this
|
// Scripts should be running to access this
|
||||||
if (cx.topActivationScope == null)
|
if (cx.topCallScope == null)
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
|
|
||||||
XMLLib xmlLib = cx.cachedXMLLib;
|
XMLLib xmlLib = cx.cachedXMLLib;
|
||||||
if (xmlLib == null) {
|
if (xmlLib == null) {
|
||||||
xmlLib = XMLLib.extractFromScope(cx.topActivationScope);
|
xmlLib = XMLLib.extractFromScope(cx.topCallScope);
|
||||||
if (xmlLib == null)
|
if (xmlLib == null)
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
cx.cachedXMLLib = xmlLib;
|
cx.cachedXMLLib = xmlLib;
|
||||||
|
|
|
@ -374,6 +374,38 @@ public class Codegen extends Interpreter
|
||||||
(short)(ClassFileWriter.ACC_PUBLIC
|
(short)(ClassFileWriter.ACC_PUBLIC
|
||||||
| ClassFileWriter.ACC_FINAL));
|
| ClassFileWriter.ACC_FINAL));
|
||||||
|
|
||||||
|
// Generate code for:
|
||||||
|
// if (!ScriptRuntime.hasTopCall(cx)) {
|
||||||
|
// return ScriptRuntime.doTopCall(this, cx, scope, thisObj, args);
|
||||||
|
// }
|
||||||
|
|
||||||
|
int nonTopCallLabel = cfw.acquireLabel();
|
||||||
|
cfw.addALoad(1); //cx
|
||||||
|
cfw.addInvoke(ByteCode.INVOKESTATIC,
|
||||||
|
"org/mozilla/javascript/ScriptRuntime",
|
||||||
|
"hasTopCall",
|
||||||
|
"(Lorg/mozilla/javascript/Context;"
|
||||||
|
+")Z");
|
||||||
|
cfw.add(ByteCode.IFNE, nonTopCallLabel);
|
||||||
|
cfw.addALoad(0);
|
||||||
|
cfw.addALoad(1);
|
||||||
|
cfw.addALoad(2);
|
||||||
|
cfw.addALoad(3);
|
||||||
|
cfw.addALoad(4);
|
||||||
|
cfw.addInvoke(ByteCode.INVOKESTATIC,
|
||||||
|
"org/mozilla/javascript/ScriptRuntime",
|
||||||
|
"doTopCall",
|
||||||
|
"(Lorg/mozilla/javascript/Callable;"
|
||||||
|
+"Lorg/mozilla/javascript/Context;"
|
||||||
|
+"Lorg/mozilla/javascript/Scriptable;"
|
||||||
|
+"Lorg/mozilla/javascript/Scriptable;"
|
||||||
|
+"[Ljava/lang/Object;"
|
||||||
|
+")Ljava/lang/Object;");
|
||||||
|
cfw.add(ByteCode.ARETURN);
|
||||||
|
cfw.markLabel(nonTopCallLabel);
|
||||||
|
|
||||||
|
// No generate switch to call the real methods
|
||||||
|
|
||||||
cfw.addALoad(0);
|
cfw.addALoad(0);
|
||||||
cfw.addALoad(1);
|
cfw.addALoad(1);
|
||||||
cfw.addALoad(2);
|
cfw.addALoad(2);
|
||||||
|
@ -1261,20 +1293,22 @@ class BodyCodegen
|
||||||
+"Lorg/mozilla/javascript/Scriptable;"
|
+"Lorg/mozilla/javascript/Scriptable;"
|
||||||
+"[Ljava/lang/Object;"
|
+"[Ljava/lang/Object;"
|
||||||
+")Lorg/mozilla/javascript/Scriptable;");
|
+")Lorg/mozilla/javascript/Scriptable;");
|
||||||
|
cfw.addAStore(variableObjectLocal);
|
||||||
} else {
|
} else {
|
||||||
debugVariableName = "global";
|
debugVariableName = "global";
|
||||||
cfw.addALoad(contextLocal);
|
|
||||||
cfw.addALoad(variableObjectLocal);
|
|
||||||
cfw.addALoad(funObjLocal);
|
cfw.addALoad(funObjLocal);
|
||||||
cfw.addALoad(thisObjLocal);
|
cfw.addALoad(thisObjLocal);
|
||||||
addScriptRuntimeInvoke("enterScript",
|
cfw.addALoad(contextLocal);
|
||||||
"(Lorg/mozilla/javascript/Context;"
|
cfw.addALoad(variableObjectLocal);
|
||||||
|
cfw.addPush(0); // false to indicate it is not eval script
|
||||||
|
addScriptRuntimeInvoke("initScript",
|
||||||
|
"(Lorg/mozilla/javascript/NativeFunction;"
|
||||||
+"Lorg/mozilla/javascript/Scriptable;"
|
+"Lorg/mozilla/javascript/Scriptable;"
|
||||||
+"Lorg/mozilla/javascript/NativeFunction;"
|
+"Lorg/mozilla/javascript/Context;"
|
||||||
+"Lorg/mozilla/javascript/Scriptable;"
|
+"Lorg/mozilla/javascript/Scriptable;"
|
||||||
+")Lorg/mozilla/javascript/Scriptable;");
|
+"Z"
|
||||||
|
+")V");
|
||||||
}
|
}
|
||||||
cfw.addAStore(variableObjectLocal);
|
|
||||||
|
|
||||||
enterAreaStartLabel = cfw.acquireLabel();
|
enterAreaStartLabel = cfw.acquireLabel();
|
||||||
epilogueLabel = cfw.acquireLabel();
|
epilogueLabel = cfw.acquireLabel();
|
||||||
|
@ -1334,10 +1368,11 @@ class BodyCodegen
|
||||||
}
|
}
|
||||||
|
|
||||||
cfw.markLabel(epilogueLabel);
|
cfw.markLabel(epilogueLabel);
|
||||||
generateExitCode();
|
|
||||||
if (fnCurrent == null) {
|
if (fnCurrent == null) {
|
||||||
cfw.addALoad(popvLocal);
|
cfw.addALoad(popvLocal);
|
||||||
}
|
cfw.add(ByteCode.ARETURN);
|
||||||
|
} else {
|
||||||
|
generateActivationExit();
|
||||||
cfw.add(ByteCode.ARETURN);
|
cfw.add(ByteCode.ARETURN);
|
||||||
|
|
||||||
// Generate catch block to catch all and rethrow to call exit code
|
// Generate catch block to catch all and rethrow to call exit code
|
||||||
|
@ -1348,9 +1383,9 @@ class BodyCodegen
|
||||||
short exceptionObject = getNewWordLocal();
|
short exceptionObject = getNewWordLocal();
|
||||||
cfw.addAStore(exceptionObject);
|
cfw.addAStore(exceptionObject);
|
||||||
|
|
||||||
// Duplicate generateExitCode() in the catch block since it takes
|
// Duplicate generateActivationExit() in the catch block since it
|
||||||
// less space then full-fetured ByteCode.JSR/ByteCode.RET
|
// takes less space then full-fetured ByteCode.JSR/ByteCode.RET
|
||||||
generateExitCode();
|
generateActivationExit();
|
||||||
|
|
||||||
cfw.addALoad(exceptionObject);
|
cfw.addALoad(exceptionObject);
|
||||||
releaseWordLocal(exceptionObject);
|
releaseWordLocal(exceptionObject);
|
||||||
|
@ -1361,17 +1396,14 @@ class BodyCodegen
|
||||||
cfw.addExceptionHandler(enterAreaStartLabel, epilogueLabel,
|
cfw.addExceptionHandler(enterAreaStartLabel, epilogueLabel,
|
||||||
finallyHandler, null); // catch any
|
finallyHandler, null); // catch any
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void generateExitCode()
|
private void generateActivationExit()
|
||||||
{
|
{
|
||||||
|
if (fnCurrent == null || hasVarsInRegs) throw Kit.codeBug();
|
||||||
cfw.addALoad(contextLocal);
|
cfw.addALoad(contextLocal);
|
||||||
if (fnCurrent != null) {
|
|
||||||
addScriptRuntimeInvoke("exitActivationFunction",
|
addScriptRuntimeInvoke("exitActivationFunction",
|
||||||
"(Lorg/mozilla/javascript/Context;)V");
|
"(Lorg/mozilla/javascript/Context;)V");
|
||||||
} else {
|
|
||||||
addScriptRuntimeInvoke("exitScript",
|
|
||||||
"(Lorg/mozilla/javascript/Context;)V");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateStatement(Node node, Node parent)
|
private void generateStatement(Node node, Node parent)
|
||||||
|
|
|
@ -532,7 +532,8 @@ msg.invalid.escape =\
|
||||||
invalid Unicode escape sequence
|
invalid Unicode escape sequence
|
||||||
|
|
||||||
msg.bad.namespace =\
|
msg.bad.namespace =\
|
||||||
not a valid namespace. Syntax is: namespace variableName as "URI";
|
not a valid default namespace statement. \
|
||||||
|
Syntax is: default xml namespace = EXPRESSION;
|
||||||
|
|
||||||
# TokensStream warnings
|
# TokensStream warnings
|
||||||
msg.bad.octal.literal =\
|
msg.bad.octal.literal =\
|
||||||
|
|
Загрузка…
Ссылка в новой задаче