Add support for dynamic scopes and fix remaining test failures in the tip.
git-svn-id: svn://10.0.0.236/trunk@61135 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
160
mozilla/js/rhino/examples/DynamicScopes.java
Normal file
160
mozilla/js/rhino/examples/DynamicScopes.java
Normal file
@@ -0,0 +1,160 @@
|
||||
/* -*- 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 oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Rhino code, released
|
||||
* May 6, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
|
||||
/**
|
||||
* Example of controlling the JavaScript with multiple scopes and threads.
|
||||
*/
|
||||
public class DynamicScopes {
|
||||
|
||||
/**
|
||||
* Main entry point.
|
||||
*
|
||||
* Set up the shared scope and then spawn new threads that execute
|
||||
* relative to that shared scope. Try compiling functions with and
|
||||
* without dynamic scope to see the effect.
|
||||
*
|
||||
* The expected output is
|
||||
* <pre>
|
||||
* sharedScope
|
||||
* sharedScope
|
||||
* sharedScope
|
||||
* a
|
||||
* b
|
||||
* c
|
||||
* </pre>
|
||||
* The final three lines may be permuted in any order depending on
|
||||
* thread scheduling.
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
throws JavaScriptException
|
||||
{
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
cx.setCompileFunctionsWithDynamicScope(false);
|
||||
runScripts(cx);
|
||||
cx.setCompileFunctionsWithDynamicScope(true);
|
||||
runScripts(cx);
|
||||
} finally {
|
||||
cx.exit();
|
||||
}
|
||||
}
|
||||
|
||||
static void runScripts(Context cx)
|
||||
throws JavaScriptException
|
||||
{
|
||||
// Initialize the standard objects (Object, Function, etc.)
|
||||
// This must be done before scripts can be executed. The call
|
||||
// returns a new scope that we will share.
|
||||
Scriptable scope = cx.initStandardObjects(null);
|
||||
|
||||
// Now we can evaluate a script and functions will be compiled to
|
||||
// use dynamic scope if the Context is so initialized.
|
||||
String source = "var x = 'sharedScope';" +
|
||||
"function f() { return x; }";
|
||||
cx.evaluateString(scope, source, "MySource", 1, null);
|
||||
|
||||
// Now we spawn some threads that execute a script that calls the
|
||||
// function 'f'. The scope chain looks like this:
|
||||
// <pre>
|
||||
// ------------------
|
||||
// | shared scope |
|
||||
// ------------------
|
||||
// ^
|
||||
// |
|
||||
// ------------------
|
||||
// | per-thread scope |
|
||||
// ------------------
|
||||
// ^
|
||||
// |
|
||||
// ------------------
|
||||
// | f's activation |
|
||||
// ------------------
|
||||
// </pre>
|
||||
// Both the shared scope and the per-thread scope have variables 'x'
|
||||
// defined in them. If 'f' is compiled with dynamic scope enabled,
|
||||
// the 'x' from the per-thread scope will be used. Otherwise, the 'x'
|
||||
// from the shared scope will be used. The 'x' defined in 'g' (which
|
||||
// calls 'f') should not be seen by 'f'.
|
||||
String[] s = { "a", "b", "c" };
|
||||
for (int i=0; i < 3; i++) {
|
||||
String script = "function g() { var x = 'local'; return f(); }" +
|
||||
"java.lang.System.out.println(g());";
|
||||
Thread thread = new Thread(new PerThread(scope, script, s[i]));
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
static class PerThread implements Runnable {
|
||||
|
||||
PerThread(Scriptable scope, String script, String x) {
|
||||
this.scope = scope;
|
||||
this.script = script;
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
// We need a new Context for this thread.
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
// We can share the scope.
|
||||
Scriptable threadScope = cx.newObject(scope);
|
||||
threadScope.setPrototype(scope);
|
||||
// Create a JavaScript property of the thread scope named
|
||||
// 'x' and save a value for it.
|
||||
threadScope.put("x", threadScope, x);
|
||||
cx.evaluateString(threadScope, script, "threadScript", 1, null);
|
||||
}
|
||||
catch (NotAFunctionException jse) {
|
||||
// ignore
|
||||
}
|
||||
catch (PropertyException jse) {
|
||||
// ignore
|
||||
}
|
||||
catch (JavaScriptException jse) {
|
||||
// ignore
|
||||
}
|
||||
finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
private Scriptable scope;
|
||||
private String script;
|
||||
private String x;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -1607,6 +1607,30 @@ public final class Context {
|
||||
hashtable = new Hashtable();
|
||||
hashtable.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether functions are compiled by this context using
|
||||
* dynamic scope.
|
||||
* <p>
|
||||
* If functions are compiled with dynamic scope, then they execute
|
||||
* in the scope of their caller, rather than in their parent scope.
|
||||
* This is useful for sharing functions across multiple scopes.
|
||||
* @since 1.5 Release 1
|
||||
*/
|
||||
public boolean hasCompileFunctionsWithDynamicScope() {
|
||||
return compileFunctionsWithDynamicScopeFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether functions compiled by this context should use
|
||||
* dynamic scope.
|
||||
* <p>
|
||||
* @param flag if true, compile functions with dynamic scope
|
||||
* @since 1.5 Release 1
|
||||
*/
|
||||
public void setCompileFunctionsWithDynamicScope(boolean flag) {
|
||||
compileFunctionsWithDynamicScopeFlag = flag;
|
||||
}
|
||||
|
||||
/********** end of API **********/
|
||||
|
||||
@@ -1915,6 +1939,7 @@ public final class Context {
|
||||
private Locale locale;
|
||||
private boolean generatingDebug;
|
||||
private boolean generatingSource=true;
|
||||
private boolean compileFunctionsWithDynamicScopeFlag;
|
||||
private int optimizationLevel;
|
||||
private SourceTextManager debug_stm;
|
||||
private DeepScriptHook debug_scriptHook;
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Ted Neward
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
@@ -207,6 +209,9 @@ public class FunctionObject extends NativeFunction {
|
||||
|
||||
setParentScope(scope);
|
||||
setPrototype(getFunctionPrototype(scope));
|
||||
Context cx = Context.getCurrentContext();
|
||||
useDynamicScope = cx != null &&
|
||||
cx.hasCompileFunctionsWithDynamicScope();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,14 +294,13 @@ public class FunctionObject extends NativeFunction {
|
||||
* @param name the name of the methods to find
|
||||
* @return an array of the found methods, or null if no methods
|
||||
* by that name were found.
|
||||
* @see java.lang.Class#getMethods
|
||||
* @see java.lang.Class#getDeclaredMethods
|
||||
*/
|
||||
public static Method[] findMethods(Class clazz, String name) {
|
||||
Vector v = new Vector(5);
|
||||
Method[] methods = clazz.getMethods();
|
||||
Method[] methods = clazz.getDeclaredMethods();
|
||||
for (int i=0; i < methods.length; i++) {
|
||||
if (methods[i].getDeclaringClass() == clazz &&
|
||||
methods[i].getName().equals(name)){
|
||||
if (methods[i].getName().equals(name)) {
|
||||
v.addElement(methods[i]);
|
||||
}
|
||||
}
|
||||
@@ -401,11 +405,14 @@ public class FunctionObject extends NativeFunction {
|
||||
// OPT: cache "clazz"?
|
||||
Class clazz = method != null ? method.getDeclaringClass()
|
||||
: ctor.getDeclaringClass();
|
||||
if (!clazz.isInstance(thisObj)) {
|
||||
// Couldn't find an object to call this on.
|
||||
Object[] errArgs = { names[0] };
|
||||
String msg = Context.getMessage("msg.incompat.call", errArgs);
|
||||
throw NativeGlobal.constructError(cx, "TypeError", msg, scope);
|
||||
while (!clazz.isInstance(thisObj)) {
|
||||
thisObj = thisObj.getPrototype();
|
||||
if (thisObj == null || !useDynamicScope) {
|
||||
// Couldn't find an object to call this on.
|
||||
Object[] errArgs = { names[0] };
|
||||
String msg = Context.getMessage("msg.incompat.call", errArgs);
|
||||
throw NativeGlobal.constructError(cx, "TypeError", msg, scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
Object[] invokeArgs;
|
||||
@@ -563,4 +570,5 @@ public class FunctionObject extends NativeFunction {
|
||||
private short lengthPropertyValue;
|
||||
private boolean hasVoidReturn;
|
||||
private boolean isStatic;
|
||||
private boolean useDynamicScope;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -74,6 +74,8 @@ class InterpretedFunction extends NativeFunction {
|
||||
itsData.itsCX = cx;
|
||||
if (itsClosure != null)
|
||||
scope = itsClosure;
|
||||
else if (!itsData.itsUseDynamicScope)
|
||||
scope = getParentScope();
|
||||
if (itsData.itsNeedsActivation)
|
||||
scope = ScriptRuntime.initVarObj(cx, scope, this, thisObj, args);
|
||||
itsData.itsScope = scope;
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Patrick Beard
|
||||
* Norris Boyd
|
||||
* Roger Lawrence
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
@@ -61,7 +62,8 @@ public class Interpreter extends LabelTable {
|
||||
throws IOException
|
||||
{
|
||||
version = cx.getLanguageVersion();
|
||||
itsData = new InterpreterData(0, 0, 0, securityDomain);
|
||||
itsData = new InterpreterData(0, 0, 0, securityDomain,
|
||||
cx.hasCompileFunctionsWithDynamicScope());
|
||||
if (tree instanceof FunctionNode) {
|
||||
FunctionNode f = (FunctionNode) tree;
|
||||
InterpretedFunction result =
|
||||
@@ -137,7 +139,8 @@ public class Interpreter extends LabelTable {
|
||||
FunctionNode def = (FunctionNode)itsFunctionList.elementAt(i);
|
||||
Interpreter jsi = new Interpreter();
|
||||
jsi.itsSourceFile = itsSourceFile;
|
||||
jsi.itsData = new InterpreterData(0, 0, 0, securityDomain);
|
||||
jsi.itsData = new InterpreterData(0, 0, 0, securityDomain,
|
||||
cx.hasCompileFunctionsWithDynamicScope());
|
||||
jsi.itsInFunctionFlag = true;
|
||||
itsNestedFunctions[i] = jsi.generateFunctionICode(cx, scope, def,
|
||||
securityDomain);
|
||||
@@ -1414,7 +1417,7 @@ public class Interpreter extends LabelTable {
|
||||
case TokenStream.EQ :
|
||||
rhs = stack[stackTop--];
|
||||
lhs = stack[stackTop];
|
||||
stack[stackTop] = ScriptRuntime.eqB(rhs, lhs);
|
||||
stack[stackTop] = ScriptRuntime.eqB(lhs, rhs);
|
||||
break;
|
||||
case TokenStream.NE :
|
||||
rhs = stack[stackTop--];
|
||||
@@ -1661,8 +1664,13 @@ public class Interpreter extends LabelTable {
|
||||
lhs = getString(theData.itsStringTable, iCode,
|
||||
pc + 1);
|
||||
}
|
||||
Scriptable calleeScope = scope;
|
||||
if (theData.itsNeedsActivation) {
|
||||
calleeScope = ScriptableObject.getTopLevelScope(scope);
|
||||
}
|
||||
stack[stackTop] = ScriptRuntime.call(cx, lhs, rhs,
|
||||
outArgs, scope);
|
||||
outArgs,
|
||||
calleeScope);
|
||||
pc += 4;
|
||||
break;
|
||||
case TokenStream.NEW :
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -44,7 +44,8 @@ class InterpreterData {
|
||||
static final int INITIAL_NUMBERTABLE_SIZE = 64;
|
||||
|
||||
InterpreterData(int lastICodeTop, int lastStringTableIndex,
|
||||
int lastNumberTableIndex, Object securityDomain)
|
||||
int lastNumberTableIndex, Object securityDomain,
|
||||
boolean useDynamicScope)
|
||||
{
|
||||
itsICodeTop = lastICodeTop == 0
|
||||
? INITIAL_MAX_ICODE_LENGTH
|
||||
@@ -59,6 +60,7 @@ class InterpreterData {
|
||||
? INITIAL_NUMBERTABLE_SIZE
|
||||
: lastNumberTableIndex * 2];
|
||||
|
||||
itsUseDynamicScope = useDynamicScope;
|
||||
if (securityDomain == null && Context.isSecurityDomainRequired())
|
||||
throw new SecurityException("Required security context missing");
|
||||
this.securityDomain = securityDomain;
|
||||
@@ -71,6 +73,7 @@ class InterpreterData {
|
||||
String itsSourceFile;
|
||||
boolean itsNeedsActivation;
|
||||
boolean itsFromEvalCode;
|
||||
boolean itsUseDynamicScope;
|
||||
|
||||
String[] itsStringTable;
|
||||
int itsStringTableIndex;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -219,8 +219,8 @@ public class NativeJavaObject implements Scriptable, Wrapper {
|
||||
if (converter == null) {
|
||||
Object[] errArgs = { converterName, javaObject.getClass().getName() };
|
||||
throw Context.reportRuntimeError(
|
||||
Context.getMessage("msg.java.conversion.implicit_method",
|
||||
errArgs));
|
||||
Context.getMessage("msg.java.conversion.implicit_method",
|
||||
errArgs));
|
||||
}
|
||||
return callConverter(converter);
|
||||
}
|
||||
@@ -239,7 +239,7 @@ public class NativeJavaObject implements Scriptable, Wrapper {
|
||||
// fall through to error message
|
||||
}
|
||||
throw Context.reportRuntimeError(
|
||||
Context.getMessage("msg.default.value", null));
|
||||
Context.getMessage("msg.default.value", null));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -1281,12 +1281,12 @@ public class ScriptRuntime {
|
||||
}
|
||||
|
||||
Scriptable thisObj;
|
||||
if (thisArg instanceof Scriptable) {
|
||||
if (thisArg instanceof Scriptable || thisArg == null) {
|
||||
thisObj = (Scriptable) thisArg;
|
||||
} else {
|
||||
thisObj = ScriptRuntime.toObject(scope, thisArg);
|
||||
}
|
||||
return function.call(cx, function.getParentScope(), thisObj, args);
|
||||
return function.call(cx, scope, thisObj, args);
|
||||
}
|
||||
|
||||
private static Object callOrNewSpecial(Context cx, Scriptable scope,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -1469,6 +1469,16 @@ public class Codegen extends Interpreter {
|
||||
variableObjectLocal = reserveWordLocal(2);
|
||||
thisObjLocal = reserveWordLocal(3);
|
||||
|
||||
if (!cx.hasCompileFunctionsWithDynamicScope()) {
|
||||
aload(funObjLocal);
|
||||
classFile.add(ByteCode.INVOKEINTERFACE,
|
||||
"org/mozilla/javascript/Scriptable",
|
||||
"getParentScope",
|
||||
"()",
|
||||
"Lorg/mozilla/javascript/Scriptable;");
|
||||
astore(variableObjectLocal);
|
||||
}
|
||||
|
||||
if (directParameterCount > 0) {
|
||||
for (int i = 0; i < (3 * directParameterCount); i++)
|
||||
reserveWordLocal(i + 4); // reserve 'args'
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -277,7 +277,7 @@ public final class OptRuntime extends ScriptRuntime {
|
||||
getMessage("msg.isnt.function", errorArgs));
|
||||
}
|
||||
|
||||
return function.call(cx, function.getParentScope(), thisArg, args);
|
||||
return function.call(cx, scope, thisArg, args);
|
||||
}
|
||||
|
||||
public static Object thisGet(Scriptable thisObj, String id,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -1607,6 +1607,30 @@ public final class Context {
|
||||
hashtable = new Hashtable();
|
||||
hashtable.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether functions are compiled by this context using
|
||||
* dynamic scope.
|
||||
* <p>
|
||||
* If functions are compiled with dynamic scope, then they execute
|
||||
* in the scope of their caller, rather than in their parent scope.
|
||||
* This is useful for sharing functions across multiple scopes.
|
||||
* @since 1.5 Release 1
|
||||
*/
|
||||
public boolean hasCompileFunctionsWithDynamicScope() {
|
||||
return compileFunctionsWithDynamicScopeFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether functions compiled by this context should use
|
||||
* dynamic scope.
|
||||
* <p>
|
||||
* @param flag if true, compile functions with dynamic scope
|
||||
* @since 1.5 Release 1
|
||||
*/
|
||||
public void setCompileFunctionsWithDynamicScope(boolean flag) {
|
||||
compileFunctionsWithDynamicScopeFlag = flag;
|
||||
}
|
||||
|
||||
/********** end of API **********/
|
||||
|
||||
@@ -1915,6 +1939,7 @@ public final class Context {
|
||||
private Locale locale;
|
||||
private boolean generatingDebug;
|
||||
private boolean generatingSource=true;
|
||||
private boolean compileFunctionsWithDynamicScopeFlag;
|
||||
private int optimizationLevel;
|
||||
private SourceTextManager debug_stm;
|
||||
private DeepScriptHook debug_scriptHook;
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Ted Neward
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
@@ -207,6 +209,9 @@ public class FunctionObject extends NativeFunction {
|
||||
|
||||
setParentScope(scope);
|
||||
setPrototype(getFunctionPrototype(scope));
|
||||
Context cx = Context.getCurrentContext();
|
||||
useDynamicScope = cx != null &&
|
||||
cx.hasCompileFunctionsWithDynamicScope();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,14 +294,13 @@ public class FunctionObject extends NativeFunction {
|
||||
* @param name the name of the methods to find
|
||||
* @return an array of the found methods, or null if no methods
|
||||
* by that name were found.
|
||||
* @see java.lang.Class#getMethods
|
||||
* @see java.lang.Class#getDeclaredMethods
|
||||
*/
|
||||
public static Method[] findMethods(Class clazz, String name) {
|
||||
Vector v = new Vector(5);
|
||||
Method[] methods = clazz.getMethods();
|
||||
Method[] methods = clazz.getDeclaredMethods();
|
||||
for (int i=0; i < methods.length; i++) {
|
||||
if (methods[i].getDeclaringClass() == clazz &&
|
||||
methods[i].getName().equals(name)){
|
||||
if (methods[i].getName().equals(name)) {
|
||||
v.addElement(methods[i]);
|
||||
}
|
||||
}
|
||||
@@ -401,11 +405,14 @@ public class FunctionObject extends NativeFunction {
|
||||
// OPT: cache "clazz"?
|
||||
Class clazz = method != null ? method.getDeclaringClass()
|
||||
: ctor.getDeclaringClass();
|
||||
if (!clazz.isInstance(thisObj)) {
|
||||
// Couldn't find an object to call this on.
|
||||
Object[] errArgs = { names[0] };
|
||||
String msg = Context.getMessage("msg.incompat.call", errArgs);
|
||||
throw NativeGlobal.constructError(cx, "TypeError", msg, scope);
|
||||
while (!clazz.isInstance(thisObj)) {
|
||||
thisObj = thisObj.getPrototype();
|
||||
if (thisObj == null || !useDynamicScope) {
|
||||
// Couldn't find an object to call this on.
|
||||
Object[] errArgs = { names[0] };
|
||||
String msg = Context.getMessage("msg.incompat.call", errArgs);
|
||||
throw NativeGlobal.constructError(cx, "TypeError", msg, scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
Object[] invokeArgs;
|
||||
@@ -563,4 +570,5 @@ public class FunctionObject extends NativeFunction {
|
||||
private short lengthPropertyValue;
|
||||
private boolean hasVoidReturn;
|
||||
private boolean isStatic;
|
||||
private boolean useDynamicScope;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -74,6 +74,8 @@ class InterpretedFunction extends NativeFunction {
|
||||
itsData.itsCX = cx;
|
||||
if (itsClosure != null)
|
||||
scope = itsClosure;
|
||||
else if (!itsData.itsUseDynamicScope)
|
||||
scope = getParentScope();
|
||||
if (itsData.itsNeedsActivation)
|
||||
scope = ScriptRuntime.initVarObj(cx, scope, this, thisObj, args);
|
||||
itsData.itsScope = scope;
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Patrick Beard
|
||||
* Norris Boyd
|
||||
* Roger Lawrence
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
@@ -61,7 +62,8 @@ public class Interpreter extends LabelTable {
|
||||
throws IOException
|
||||
{
|
||||
version = cx.getLanguageVersion();
|
||||
itsData = new InterpreterData(0, 0, 0, securityDomain);
|
||||
itsData = new InterpreterData(0, 0, 0, securityDomain,
|
||||
cx.hasCompileFunctionsWithDynamicScope());
|
||||
if (tree instanceof FunctionNode) {
|
||||
FunctionNode f = (FunctionNode) tree;
|
||||
InterpretedFunction result =
|
||||
@@ -137,7 +139,8 @@ public class Interpreter extends LabelTable {
|
||||
FunctionNode def = (FunctionNode)itsFunctionList.elementAt(i);
|
||||
Interpreter jsi = new Interpreter();
|
||||
jsi.itsSourceFile = itsSourceFile;
|
||||
jsi.itsData = new InterpreterData(0, 0, 0, securityDomain);
|
||||
jsi.itsData = new InterpreterData(0, 0, 0, securityDomain,
|
||||
cx.hasCompileFunctionsWithDynamicScope());
|
||||
jsi.itsInFunctionFlag = true;
|
||||
itsNestedFunctions[i] = jsi.generateFunctionICode(cx, scope, def,
|
||||
securityDomain);
|
||||
@@ -1414,7 +1417,7 @@ public class Interpreter extends LabelTable {
|
||||
case TokenStream.EQ :
|
||||
rhs = stack[stackTop--];
|
||||
lhs = stack[stackTop];
|
||||
stack[stackTop] = ScriptRuntime.eqB(rhs, lhs);
|
||||
stack[stackTop] = ScriptRuntime.eqB(lhs, rhs);
|
||||
break;
|
||||
case TokenStream.NE :
|
||||
rhs = stack[stackTop--];
|
||||
@@ -1661,8 +1664,13 @@ public class Interpreter extends LabelTable {
|
||||
lhs = getString(theData.itsStringTable, iCode,
|
||||
pc + 1);
|
||||
}
|
||||
Scriptable calleeScope = scope;
|
||||
if (theData.itsNeedsActivation) {
|
||||
calleeScope = ScriptableObject.getTopLevelScope(scope);
|
||||
}
|
||||
stack[stackTop] = ScriptRuntime.call(cx, lhs, rhs,
|
||||
outArgs, scope);
|
||||
outArgs,
|
||||
calleeScope);
|
||||
pc += 4;
|
||||
break;
|
||||
case TokenStream.NEW :
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -44,7 +44,8 @@ class InterpreterData {
|
||||
static final int INITIAL_NUMBERTABLE_SIZE = 64;
|
||||
|
||||
InterpreterData(int lastICodeTop, int lastStringTableIndex,
|
||||
int lastNumberTableIndex, Object securityDomain)
|
||||
int lastNumberTableIndex, Object securityDomain,
|
||||
boolean useDynamicScope)
|
||||
{
|
||||
itsICodeTop = lastICodeTop == 0
|
||||
? INITIAL_MAX_ICODE_LENGTH
|
||||
@@ -59,6 +60,7 @@ class InterpreterData {
|
||||
? INITIAL_NUMBERTABLE_SIZE
|
||||
: lastNumberTableIndex * 2];
|
||||
|
||||
itsUseDynamicScope = useDynamicScope;
|
||||
if (securityDomain == null && Context.isSecurityDomainRequired())
|
||||
throw new SecurityException("Required security context missing");
|
||||
this.securityDomain = securityDomain;
|
||||
@@ -71,6 +73,7 @@ class InterpreterData {
|
||||
String itsSourceFile;
|
||||
boolean itsNeedsActivation;
|
||||
boolean itsFromEvalCode;
|
||||
boolean itsUseDynamicScope;
|
||||
|
||||
String[] itsStringTable;
|
||||
int itsStringTableIndex;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -219,8 +219,8 @@ public class NativeJavaObject implements Scriptable, Wrapper {
|
||||
if (converter == null) {
|
||||
Object[] errArgs = { converterName, javaObject.getClass().getName() };
|
||||
throw Context.reportRuntimeError(
|
||||
Context.getMessage("msg.java.conversion.implicit_method",
|
||||
errArgs));
|
||||
Context.getMessage("msg.java.conversion.implicit_method",
|
||||
errArgs));
|
||||
}
|
||||
return callConverter(converter);
|
||||
}
|
||||
@@ -239,7 +239,7 @@ public class NativeJavaObject implements Scriptable, Wrapper {
|
||||
// fall through to error message
|
||||
}
|
||||
throw Context.reportRuntimeError(
|
||||
Context.getMessage("msg.default.value", null));
|
||||
Context.getMessage("msg.default.value", null));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -1281,12 +1281,12 @@ public class ScriptRuntime {
|
||||
}
|
||||
|
||||
Scriptable thisObj;
|
||||
if (thisArg instanceof Scriptable) {
|
||||
if (thisArg instanceof Scriptable || thisArg == null) {
|
||||
thisObj = (Scriptable) thisArg;
|
||||
} else {
|
||||
thisObj = ScriptRuntime.toObject(scope, thisArg);
|
||||
}
|
||||
return function.call(cx, function.getParentScope(), thisObj, args);
|
||||
return function.call(cx, scope, thisObj, args);
|
||||
}
|
||||
|
||||
private static Object callOrNewSpecial(Context cx, Scriptable scope,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -1469,6 +1469,16 @@ public class Codegen extends Interpreter {
|
||||
variableObjectLocal = reserveWordLocal(2);
|
||||
thisObjLocal = reserveWordLocal(3);
|
||||
|
||||
if (!cx.hasCompileFunctionsWithDynamicScope()) {
|
||||
aload(funObjLocal);
|
||||
classFile.add(ByteCode.INVOKEINTERFACE,
|
||||
"org/mozilla/javascript/Scriptable",
|
||||
"getParentScope",
|
||||
"()",
|
||||
"Lorg/mozilla/javascript/Scriptable;");
|
||||
astore(variableObjectLocal);
|
||||
}
|
||||
|
||||
if (directParameterCount > 0) {
|
||||
for (int i = 0; i < (3 * directParameterCount); i++)
|
||||
reserveWordLocal(i + 4); // reserve 'args'
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1997-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@@ -277,7 +277,7 @@ public final class OptRuntime extends ScriptRuntime {
|
||||
getMessage("msg.isnt.function", errorArgs));
|
||||
}
|
||||
|
||||
return function.call(cx, function.getParentScope(), thisArg, args);
|
||||
return function.call(cx, scope, thisArg, args);
|
||||
}
|
||||
|
||||
public static Object thisGet(Scriptable thisObj, String id,
|
||||
|
||||
Reference in New Issue
Block a user