diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/BaseFunction.java b/mozilla/js/rhino/src/org/mozilla/javascript/BaseFunction.java index 4b317114605..8d094be9932 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/BaseFunction.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/BaseFunction.java @@ -487,26 +487,18 @@ public class BaseFunction extends IdScriptableObject implements Function linep[0] = 1; } - String sourceName = ScriptRuntime. + String sourceURI = ScriptRuntime. makeUrlForGeneratedScript(false, filename, linep[0]); Scriptable global = ScriptableObject.getTopLevelScope(scope); - // Compile the function with opt level of -1 to force interpreter + ErrorReporter reporter; + reporter = DefaultErrorReporter.forEval(cx.getErrorReporter()); + + // Compile with explicit interpreter instance to force interpreter // mode. - int savedLevel = cx.optimizationLevel; - cx.optimizationLevel = -1; - NativeFunction fn; - try { - fn = (NativeFunction) cx.compileFunction(global, source, - sourceName, 1, - null); - } - finally { cx.optimizationLevel = savedLevel; } - - ScriptRuntime.setFunctionProtoAndParent(global, fn); - - return fn; + return cx.compileFunction(global, source, new Interpreter(), reporter, + sourceURI, 1, null); } protected int findPrototypeId(String s) diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Context.java b/mozilla/js/rhino/src/org/mozilla/javascript/Context.java index ec6a0dd8f51..66b7e1daea6 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Context.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Context.java @@ -1253,8 +1253,8 @@ public class Context throw new IllegalArgumentException( "Line number can not be negative:"+lineno); } - return (Script) compile(null, in, null, sourceName, lineno, - securityDomain, false, null); + return (Script) compileImpl(null, in, null, sourceName, lineno, + securityDomain, false, null, null); } /** @@ -1280,18 +1280,20 @@ public class Context throw new IllegalArgumentException( "Line number can not be negative:"+lineno); } - return compileString(source, null, sourceName, lineno, securityDomain); + return compileString(source, null, null, sourceName, lineno, + securityDomain); } final Script compileString(String source, + Interpreter compiler, ErrorReporter compilationErrorReporter, String sourceName, int lineno, Object securityDomain) { try { - return (Script) compile(null, null, source, sourceName, lineno, - securityDomain, false, - compilationErrorReporter); + return (Script) compileImpl(null, null, source, sourceName, lineno, + securityDomain, false, + compiler, compilationErrorReporter); } catch (IOException ex) { // Should not happen when dealing with source as string throw new RuntimeException(); @@ -1318,10 +1320,21 @@ public class Context public final Function compileFunction(Scriptable scope, String source, String sourceName, int lineno, Object securityDomain) + { + return compileFunction(scope, source, null, null, sourceName, lineno, + securityDomain); + } + + final Function compileFunction(Scriptable scope, String source, + Interpreter compiler, + ErrorReporter compilationErrorReporter, + String sourceName, int lineno, + Object securityDomain) { try { - return (Function) compile(scope, null, source, sourceName, lineno, - securityDomain, true, null); + return (Function) compileImpl(scope, null, source, sourceName, + lineno, securityDomain, true, + compiler, compilationErrorReporter); } catch (IOException ioe) { // Should never happen because we just made the reader @@ -2287,11 +2300,12 @@ public class Context return formatter.format(arguments); } - private Object compile(Scriptable scope, - Reader sourceReader, String sourceString, - String sourceName, int lineno, - Object securityDomain, boolean returnFunction, - ErrorReporter compilationErrorReporter) + private Object compileImpl(Scriptable scope, + Reader sourceReader, String sourceString, + String sourceName, int lineno, + Object securityDomain, boolean returnFunction, + Interpreter compiler, + ErrorReporter compilationErrorReporter) throws IOException { if (securityDomain != null && securityController == null) { @@ -2337,22 +2351,46 @@ public class Context } } - Interpreter compiler = createCompiler(); + if (compiler == null) { + compiler = createCompiler(); + } String encodedSource = p.getEncodedSource(); - Object result = compiler.compile(scope, compilerEnv, - tree, encodedSource, - returnFunction, - securityDomain); + Object bytecode = compiler.compile(compilerEnv, + tree, encodedSource, + returnFunction); + if (debugger != null) { if (sourceString == null) Kit.codeBug(); - compiler.notifyDebuggerCompilationDone(this, result, - sourceString); + if (bytecode instanceof DebuggableScript) { + DebuggableScript dscript = (DebuggableScript)bytecode; + notifyDebugger_r(this, dscript, sourceString); + } else { + throw new RuntimeException("NOT SUPPORTED"); + } } + + Object result; + if (returnFunction) { + result = compiler.createFunctionObject(this, scope, bytecode, + securityDomain); + } else { + result = compiler.createScriptObject(bytecode, securityDomain); + } + return result; } + private static void notifyDebugger_r(Context cx, DebuggableScript dscript, + String debugSource) + { + cx.debugger.handleCompilationDone(cx, dscript, debugSource); + for (int i = 0; i != dscript.getFunctionCount(); ++i) { + notifyDebugger_r(cx, dscript.getFunction(i), debugSource); + } + } + private static Class codegenClass = Kit.classOrNull( "org.mozilla.javascript.optimizer.Codegen"); @@ -2562,7 +2600,7 @@ public class Context private boolean generatingDebugChanged; private boolean generatingSource=true; private boolean compileFunctionsWithDynamicScopeFlag; - int optimizationLevel; + private int optimizationLevel; private WrapFactory wrapFactory; Debugger debugger; private Object debuggerData; diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/InterpretedFunction.java b/mozilla/js/rhino/src/org/mozilla/javascript/InterpretedFunction.java index eedbdc7dbba..1528201c7ce 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/InterpretedFunction.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/InterpretedFunction.java @@ -19,6 +19,7 @@ * Rights Reserved. * * Contributor(s): + * Igor Bukanov * Roger Lawrence * * Alternatively, the contents of this file may be used under the @@ -35,40 +36,126 @@ package org.mozilla.javascript; -import java.io.Serializable; - -final class InterpretedFunction extends NativeFunction - implements Serializable +final class InterpretedFunction extends NativeFunction implements Script { + InterpreterData idata; + SecurityController securityController; + Object securityDomain; + Scriptable[] functionRegExps; + boolean evalScriptFlag; // true if script corresponds to eval() code - static final long serialVersionUID = -6235150451107527319L; - - InterpretedFunction(InterpreterData theData) + private InterpretedFunction(InterpreterData idata, + Object staticSecurityDomain) { - itsData = theData; - initScriptFunction(itsData.languageVersion, itsData.itsName, - itsData.argNames, itsData.argCount); + this.idata = idata; + + // Always get Context from the current thread to + // avoid security breaches via passing mangled Context instances + // with bogus SecurityController + Context cx = Context.getContext(); + SecurityController sc = cx.getSecurityController(); + Object dynamicDomain; + if (sc != null) { + dynamicDomain = sc.getDynamicSecurityDomain(staticSecurityDomain); + } else { + if (staticSecurityDomain != null) { + throw new IllegalArgumentException(); + } + dynamicDomain = null; + } + + this.securityController = sc; + this.securityDomain = dynamicDomain; + } + + private InterpretedFunction(InterpretedFunction parent, int index) + { + this.idata = parent.idata.itsNestedFunctions[index]; + this.securityController = parent.securityController; + this.securityDomain = parent.securityDomain; + } + + /** + * Create script from compiled bytecode. + */ + static InterpretedFunction createScript(InterpreterData idata, + Object staticSecurityDomain) + { + InterpretedFunction f; + f = new InterpretedFunction(idata, staticSecurityDomain); + f.initScriptObject(idata.languageVersion, idata.argNames); + return f; + } + + /** + * Create function compiled from Function(...) constructor. + */ + static InterpretedFunction createFunction(Context cx,Scriptable scope, + InterpreterData idata, + Object staticSecurityDomain) + { + InterpretedFunction f; + f = new InterpretedFunction(idata, staticSecurityDomain); + f.initInterpretedFunction(cx, scope); + return f; + } + + /** + * Create function embedded in script or another function. + */ + static InterpretedFunction createFunction(Context cx, Scriptable scope, + InterpretedFunction parent, + int index) + { + InterpretedFunction f = new InterpretedFunction(parent, index); + f.initInterpretedFunction(cx, scope); + return f; + } + + Scriptable[] createRegExpWraps(Context cx, Scriptable scope) + { + if (idata.itsRegExpLiterals == null) Kit.codeBug(); + + RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx); + int N = idata.itsRegExpLiterals.length; + Scriptable[] array = new Scriptable[N]; + for (int i = 0; i != N; ++i) { + array[i] = rep.wrapRegExp(cx, scope, idata.itsRegExpLiterals[i]); + } + return array; + } + + private void initInterpretedFunction(Context cx, Scriptable scope) + { + initScriptFunction(cx, scope, idata.languageVersion, idata.itsName, + idata.argNames, idata.argCount); + if (idata.itsRegExpLiterals != null) { + functionRegExps = createRegExpWraps(cx, scope); + } } public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) - throws JavaScriptException { if (!ScriptRuntime.hasTopCall(cx)) { return ScriptRuntime.doTopCall(this, cx, scope, thisObj, args); } - return Interpreter.interpret(cx, scope, thisObj, - args, null, 0, args.length, - this, itsData); + return Interpreter.interpret(cx, scope, thisObj, args, null, + 0, args.length, this); + } + + public Object exec(Context cx, Scriptable scope) + { + if (idata.itsFunctionType != 0) { + // Can only be applied to scripts + throw new IllegalStateException(); + } + return call(cx, scope, scope, ScriptRuntime.emptyArgs); } public String getEncodedSource() { - return Interpreter.getEncodedSource(itsData); + return Interpreter.getEncodedSource(idata); } - - InterpreterData itsData; - boolean itsUseDynamicScope; - Scriptable[] itsRegExps; } diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/InterpretedScript.java b/mozilla/js/rhino/src/org/mozilla/javascript/InterpretedScript.java deleted file mode 100644 index 07be31f8b7a..00000000000 --- a/mozilla/js/rhino/src/org/mozilla/javascript/InterpretedScript.java +++ /dev/null @@ -1,75 +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 - { - if (!ScriptRuntime.hasTopCall(cx)) { - return ScriptRuntime.doTopCall(this, cx, scope, thisObj, args); - } - return Interpreter.interpret(cx, scope, thisObj, - args, null, 0, args.length, - this, itsData); - } - - public String getEncodedSource() - { - return Interpreter.getEncodedSource(itsData); - } - - InterpreterData itsData; -} - diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java b/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java index c4b8575346b..b3e2aecb41d 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java @@ -257,12 +257,10 @@ public class Interpreter return validIcode(bytecode) || validTokenCode(bytecode); } - public Object compile(Scriptable scope, - CompilerEnvirons compilerEnv, + public Object compile(CompilerEnvirons compilerEnv, ScriptOrFnNode tree, String encodedSource, - boolean returnFunction, - Object staticSecurityDomain) + boolean returnFunction) { this.compilerEnv = compilerEnv; new NodeTransformer().transform(tree); @@ -275,56 +273,36 @@ public class Interpreter tree = tree.getFunctionNode(0); } - Context cx = Context.getContext(); - SecurityController sc = cx.getSecurityController(); - Object dynamicDomain; - if (sc != null) { - dynamicDomain = sc.getDynamicSecurityDomain(staticSecurityDomain); - } else { - if (staticSecurityDomain != null) { - throw new IllegalArgumentException(); - } - dynamicDomain = null; - } - scriptOrFn = tree; - itsData = new InterpreterData(sc, dynamicDomain, - compilerEnv.getLanguageVersion(), + itsData = new InterpreterData(compilerEnv.getLanguageVersion(), scriptOrFn.getSourceName(), encodedSource); itsData.topLevel = true; if (returnFunction) { generateFunctionICode(); - return createFunction(cx, scope, itsData, false); } else { generateICodeFromTree(scriptOrFn); - return new InterpretedScript(itsData); } + + return itsData; } - public void notifyDebuggerCompilationDone(Context cx, - Object scriptOrFunction, - String debugSource) + public Script createScriptObject(Object bytecode, + Object staticSecurityDomain) { - InterpreterData idata; - if (scriptOrFunction instanceof InterpretedScript) { - idata = ((InterpretedScript)scriptOrFunction).itsData; - } else { - idata = ((InterpretedFunction)scriptOrFunction).itsData; - } - notifyDebugger_r(cx, idata, debugSource); + InterpreterData idata = (InterpreterData)bytecode; + return InterpretedFunction.createScript(itsData, + staticSecurityDomain); } - private static void notifyDebugger_r(Context cx, InterpreterData idata, - String debugSource) + public Function createFunctionObject(Context cx, Scriptable scope, + Object bytecode, + Object staticSecurityDomain) { - cx.debugger.handleCompilationDone(cx, idata, debugSource); - if (idata.itsNestedFunctions != null) { - for (int i = 0; i != idata.itsNestedFunctions.length; ++i) { - notifyDebugger_r(cx, idata.itsNestedFunctions[i], debugSource); - } - } + InterpreterData idata = (InterpreterData)bytecode; + return InterpretedFunction.createFunction(cx, scope, itsData, + staticSecurityDomain); } private void generateFunctionICode() @@ -1953,56 +1931,38 @@ public class Interpreter idata.encodedSourceEnd); } - private static Scriptable[] wrapRegExps(Context cx, Scriptable scope, - InterpreterData idata) + private static void initFunction(Context cx, Scriptable scope, + InterpretedFunction parent, int index) { - if (idata.itsRegExpLiterals == null) Kit.codeBug(); - - RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx); - int N = idata.itsRegExpLiterals.length; - Scriptable[] array = new Scriptable[N]; - for (int i = 0; i != N; ++i) { - array[i] = rep.wrapRegExp(cx, scope, idata.itsRegExpLiterals[i]); - } - return array; - } - - private static InterpretedFunction createFunction(Context cx, - Scriptable scope, - InterpreterData idata, - boolean fromEvalCode) - { - InterpretedFunction fn = new InterpretedFunction(idata); - if (idata.itsRegExpLiterals != null) { - fn.itsRegExps = wrapRegExps(cx, scope, idata); - } - ScriptRuntime.initFunction(cx, scope, fn, idata.itsFunctionType, - fromEvalCode); - return fn; + InterpretedFunction fn; + fn = InterpretedFunction.createFunction(cx, scope, parent, index); + ScriptRuntime.initFunction(cx, scope, fn, fn.idata.itsFunctionType, + parent.evalScriptFlag); } static Object interpret(Context cx, Scriptable scope, Scriptable thisObj, Object[] args, double[] argsDbl, int argShift, int argCount, - NativeFunction fnOrScript, - InterpreterData idata) - throws JavaScriptException + InterpretedFunction fnOrScript) { - if (cx.interpreterSecurityDomain != idata.securityDomain) { + if (cx.interpreterSecurityDomain != fnOrScript.securityDomain) { if (argsDbl != null) { args = getArgsArray(args, argsDbl, argShift, argCount); } - SecurityController sc = idata.securityController; + SecurityController sc = fnOrScript.securityController; Object savedDomain = cx.interpreterSecurityDomain; - cx.interpreterSecurityDomain = idata.securityDomain; + cx.interpreterSecurityDomain = fnOrScript.securityDomain; try { - return sc.callWithDomain(idata.securityDomain, cx, fnOrScript, - scope, thisObj, args); + return fnOrScript.securityController.callWithDomain( + fnOrScript.securityDomain, cx, fnOrScript, scope, + thisObj, args); } finally { cx.interpreterSecurityDomain = savedDomain; } } + InterpreterData idata = fnOrScript.idata; + final Object DBL_MRK = Interpreter.DBL_MRK; final Scriptable undefined = Undefined.instance; @@ -2055,7 +2015,6 @@ public class Interpreter } if (idata.itsFunctionType != 0) { - InterpretedFunction f = (InterpretedFunction)fnOrScript; if (!idata.useDynamicScope) { scope = fnOrScript.getParentScope(); } @@ -2071,7 +2030,7 @@ public class Interpreter } } else { ScriptRuntime.initScript(fnOrScript, thisObj, cx, scope, - idata.itsFromEvalCode); + fnOrScript.evalScriptFlag); } if (idata.itsNestedFunctions != null) { @@ -2080,21 +2039,29 @@ public class Interpreter for (int i = 0; i < idata.itsNestedFunctions.length; i++) { InterpreterData fdata = idata.itsNestedFunctions[i]; if (fdata.itsFunctionType == FunctionNode.FUNCTION_STATEMENT) { - createFunction(cx, scope, fdata, idata.itsFromEvalCode); + initFunction(cx, scope, fnOrScript, i); } } } - // Wrapped regexps for functions are stored in InterpretedFunction - // but for script which should not contain references to scope - // the regexps re-wrapped during each script execution Scriptable[] scriptRegExps = null; + if (idata.itsRegExpLiterals != null) { + // Wrapped regexps for functions are stored in InterpretedFunction + // but for script which should not contain references to scope + // the regexps re-wrapped during each script execution + if (idata.itsFunctionType != 0) { + scriptRegExps = fnOrScript.functionRegExps; + } else { + scriptRegExps = fnOrScript.createRegExpWraps(cx, scope); + } + } if (debuggerFrame != null) { debuggerFrame.onEnter(cx, scope, thisObj, args); } InterpreterData savedData = cx.interpreterData; + int savedLineIndex = cx.interpreterLineIndex; cx.interpreterData = idata; cx.interpreterLineIndex = idata.firstLinePC; @@ -2638,9 +2605,8 @@ switch (op) { // Inlining of InterpretedFunction.call not to create // argument array InterpretedFunction ifun = (InterpretedFunction)fun; - stack[stackTop] = interpret(cx, funScope, funThisObj, - stack, sDbl, calleeArgShft, indexReg, - ifun, ifun.itsData); + stack[stackTop] = interpret(cx, funScope, funThisObj, stack, sDbl, + calleeArgShft, indexReg, ifun); } else { Object[] outArgs = getArgsArray(stack, sDbl, calleeArgShft, indexReg); @@ -2685,9 +2651,8 @@ switch (op) { // argument array InterpretedFunction f = (InterpretedFunction)lhs; Scriptable newInstance = f.createObject(cx, scope); - Object callResult = interpret(cx, scope, newInstance, - stack, sDbl, calleeArgShft, indexReg, - f, f.itsData); + Object callResult = interpret(cx, scope, newInstance, stack, sDbl, + calleeArgShft, indexReg, f); if (callResult instanceof Scriptable && callResult != undefined) { stack[stackTop] = callResult; } else { @@ -2883,30 +2848,17 @@ switch (op) { case Icode_SCOPE : stack[++stackTop] = scope; continue Loop; - case Icode_CLOSURE_EXPR : { - InterpreterData closureData = idata.itsNestedFunctions[indexReg]; - stack[++stackTop] = createFunction(cx, scope, closureData, - idata.itsFromEvalCode); + case Icode_CLOSURE_EXPR : + stack[++stackTop] = InterpretedFunction.createFunction(cx, scope, + fnOrScript, + indexReg); continue Loop; - } - case Icode_CLOSURE_STMT : { - InterpreterData closureData = idata.itsNestedFunctions[indexReg]; - createFunction(cx, scope, closureData, idata.itsFromEvalCode); + case Icode_CLOSURE_STMT : + initFunction(cx, scope, fnOrScript, indexReg); continue Loop; - } - case Token.REGEXP : { - Scriptable regexp; - if (idata.itsFunctionType != 0) { - regexp = ((InterpretedFunction)fnOrScript).itsRegExps[indexReg]; - } else { - if (scriptRegExps == null) { - scriptRegExps = wrapRegExps(cx, scope, idata); - } - regexp = scriptRegExps[indexReg]; - } - stack[++stackTop] = regexp; + case Token.REGEXP : + stack[++stackTop] = scriptRegExps[indexReg]; continue Loop; - } case Icode_LITERAL_NEW : // indexReg: number of values in the literal ++stackTop; @@ -3101,6 +3053,7 @@ switch (op) { } // end of interpreter loop cx.interpreterData = savedData; + cx.interpreterLineIndex = savedLineIndex; if (debuggerFrame != null) { if (javaException != null) { diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/InterpreterData.java b/mozilla/js/rhino/src/org/mozilla/javascript/InterpreterData.java index ba502fdbb8c..2d09d8f4f6f 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/InterpreterData.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/InterpreterData.java @@ -49,13 +49,9 @@ final class InterpreterData implements Serializable, DebuggableScript static final int INITIAL_STRINGTABLE_SIZE = 64; static final int INITIAL_NUMBERTABLE_SIZE = 64; - InterpreterData(SecurityController securityController, - Object securityDomain, - int languageVersion, + InterpreterData(int languageVersion, String sourceFile, String encodedSource) { - this.securityController = securityController; - this.securityDomain = securityDomain; this.languageVersion = languageVersion; this.itsSourceFile = sourceFile; this.encodedSource = encodedSource; @@ -66,8 +62,6 @@ final class InterpreterData implements Serializable, DebuggableScript InterpreterData(InterpreterData parent) { this.parentData = parent; - this.securityController = parent.securityController; - this.securityDomain = parent.securityDomain; this.languageVersion = parent.languageVersion; this.itsSourceFile = parent.itsSourceFile; this.encodedSource = parent.encodedSource; @@ -81,13 +75,9 @@ final class InterpreterData implements Serializable, DebuggableScript itsStringTable = new String[INITIAL_STRINGTABLE_SIZE]; } - SecurityController securityController; - Object securityDomain; - String itsName; String itsSourceFile; boolean itsNeedsActivation; - boolean itsFromEvalCode; boolean itsCheckThis; int itsFunctionType; diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/NativeFunction.java b/mozilla/js/rhino/src/org/mozilla/javascript/NativeFunction.java index 541e48d93dd..d1882e7e6a7 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/NativeFunction.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/NativeFunction.java @@ -46,7 +46,8 @@ package org.mozilla.javascript; public class NativeFunction extends BaseFunction { - public final void initScriptFunction(int version, String functionName, + public final void initScriptFunction(Context cx, Scriptable scope, + int version, String functionName, String[] argNames, int argCount) { if (!(argNames != null @@ -64,6 +65,25 @@ public class NativeFunction extends BaseFunction this.argNames = argNames; this.argCount = argCount; this.version = version; + + ScriptRuntime.setFunctionProtoAndParent(scope, this); + } + + public final void initScriptObject(int version, String[] varNames) + { + if (varNames == null) { + throw new IllegalArgumentException(); + } + + if (!(this.argNames == null)) { + // Initialization can only be done once + throw new IllegalStateException(); + } + + this.functionName = ""; + this.argNames = varNames; + this.argCount = 0; + this.version = version; } /** diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/NativeScript.java b/mozilla/js/rhino/src/org/mozilla/javascript/NativeScript.java index 5b7b1ea3ae2..6efe10c92e5 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/NativeScript.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/NativeScript.java @@ -198,7 +198,8 @@ class NativeScript extends NativeFunction implements Script } ErrorReporter reporter; reporter = DefaultErrorReporter.forEval(cx.getErrorReporter()); - return cx.compileString(source, reporter, filename, linep[0], null); + return cx.compileString(source, null, reporter, filename, + linep[0], null); } // #string_id_map# diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java b/mozilla/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java index fa6b0a0c776..fc9230b0aa4 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java @@ -2203,17 +2203,11 @@ public class ScriptRuntime { ErrorReporter reporter; reporter = DefaultErrorReporter.forEval(cx.getErrorReporter()); - // Compile the reader with opt level of -1 to force interpreter + // Compile with explicit interpreter instance to force interpreter // mode. - int savedLevel = cx.optimizationLevel; - cx.optimizationLevel = -1; - Script script; - try { - script = cx.compileString((String)x, reporter, sourceName, 1, null); - } finally { - cx.optimizationLevel = savedLevel; - } - ((InterpretedScript)script).itsData.itsFromEvalCode = true; + Script script = cx.compileString((String)x, new Interpreter(), + reporter, sourceName, 1, null); + ((InterpretedFunction)script).evalScriptFlag = true; // if the compile fails, an error has been reported by the // compiler, but we need to stop execution to avoid @@ -2910,7 +2904,7 @@ public class ScriptRuntime { } public static void setFunctionProtoAndParent(Scriptable scope, - Function fn) + BaseFunction fn) { fn.setPrototype(ScriptableObject.getFunctionPrototype(scope)); fn.setParentScope(scope); @@ -2920,7 +2914,6 @@ public class ScriptRuntime { NativeFunction function, int type, boolean fromEvalCode) { - setFunctionProtoAndParent(scope, function); if (type == FunctionNode.FUNCTION_STATEMENT) { String name = function.functionName; if (name != null && name.length() != 0) { @@ -2944,6 +2937,8 @@ public class ScriptRuntime { } scope.put(name, scope, function); } + } else { + throw Kit.codeBug(); } } diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java b/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java index 4a40ff8299d..e1ee3b38bfa 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java @@ -54,12 +54,10 @@ import java.lang.reflect.Constructor; public class Codegen extends Interpreter { - public Object compile(Scriptable scope, - CompilerEnvirons compilerEnv, - ScriptOrFnNode scriptOrFn, + public Object compile(CompilerEnvirons compilerEnv, + ScriptOrFnNode tree, String encodedSource, - boolean returnFunction, - Object securityDomain) + boolean returnFunction) { int serial; synchronized (globalLock) { @@ -68,56 +66,66 @@ public class Codegen extends Interpreter String mainClassName = "org.mozilla.javascript.gen.c"+serial; byte[] mainClassBytes = compileToClassFile(compilerEnv, mainClassName, - scriptOrFn, encodedSource, + tree, encodedSource, returnFunction); - Exception e = null; - Class result = null; - GeneratedClassLoader - loader = SecurityController.createLoader(null, securityDomain); + return new Object[] { mainClassName, mainClassBytes }; + } + public Script createScriptObject(Object bytecode, + Object staticSecurityDomain) + { + Class cl = defineClass(bytecode, staticSecurityDomain); + + Script script; try { - result = loader.defineClass(mainClassName, mainClassBytes); - loader.linkClass(result); + script = (Script)cl.newInstance(); + } catch (Exception ex) { + throw new RuntimeException + ("Unable to instantiate compiled class:"+ex.toString()); + } + return script; + } + + public Function createFunctionObject(Context cx, Scriptable scope, + Object bytecode, + Object staticSecurityDomain) + { + Class cl = defineClass(bytecode, staticSecurityDomain); + + NativeFunction f; + try { + Constructor ctor = cl.getConstructors()[0]; + Object[] initArgs = { scope, cx, new Integer(0) }; + f = (NativeFunction)ctor.newInstance(initArgs); + } catch (Exception ex) { + throw new RuntimeException + ("Unable to instantiate compiled class:"+ex.toString()); + } + return f; + } + + private static Class defineClass(Object bytecode, + Object staticSecurityDomain) + { + Object[] nameBytesPair = (Object[])bytecode; + String className = (String)nameBytesPair[0]; + byte[] classBytes = (byte[])nameBytesPair[1]; + + GeneratedClassLoader loader; + loader = SecurityController.createLoader(null, staticSecurityDomain); + + Exception e; + try { + Class cl = loader.defineClass(className, classBytes); + loader.linkClass(cl); + return cl; } catch (SecurityException x) { e = x; } catch (IllegalArgumentException x) { e = x; } - if (e != null) - throw new RuntimeException("Malformed optimizer package " + e); - - if (returnFunction) { - Context cx = Context.getCurrentContext(); - NativeFunction f; - try { - Constructor ctor = result.getConstructors()[0]; - Object[] initArgs = { scope, cx, new Integer(0) }; - f = (NativeFunction)ctor.newInstance(initArgs); - } catch (Exception ex) { - throw new RuntimeException - ("Unable to instantiate compiled class:"+ex.toString()); - } - OptRuntime.initFunction( - f, FunctionNode.FUNCTION_STATEMENT, scope, cx); - return f; - } else { - Script script; - try { - script = (Script) result.newInstance(); - } catch (Exception ex) { - throw new RuntimeException - ("Unable to instantiate compiled class:"+ex.toString()); - } - return script; - } - } - - public void notifyDebuggerCompilationDone(Context cx, - ScriptOrFnNode scriptOrFn, - String debugSource) - { - throw new RuntimeException("NOT SUPPORTED"); + throw new RuntimeException("Malformed optimizer package " + e); } byte[] compileToClassFile(CompilerEnvirons compilerEnv, @@ -543,17 +551,13 @@ public class Codegen extends Interpreter cfw.add(ByteCode.PUTFIELD, cfw.getClassName(), ID_FIELD_NAME, "I"); // Call - // NativeFunction.initScriptFunction(version, "", varNamesArray, 0) - + // NativeFunction.initScriptObject(version, varNamesArray) cfw.addLoadThis(); cfw.addPush(compilerEnv.getLanguageVersion()); - cfw.addPush(""); // Function name pushParamNamesArray(cfw, script); - cfw.addPush(0); // No parameters, only varnames cfw.addInvoke(ByteCode.INVOKEVIRTUAL, - "org/mozilla/javascript/NativeFunction", - "initScriptFunction", - "(ILjava/lang/String;[Ljava/lang/String;I)V"); + "org/mozilla/javascript/NativeFunction", + "initScriptObject", "(I[Ljava/lang/String;)V"); cfw.add(ByteCode.RETURN); // 1 parameter = this @@ -628,6 +632,8 @@ public class Codegen extends Interpreter // Call NativeFunction.initScriptFunction cfw.addLoadThis(); + cfw.addALoad(CONTEXT_ARG); + cfw.addALoad(SCOPE_ARG); cfw.addPush(compilerEnv.getLanguageVersion()); cfw.addPush(ofn.fnode.getFunctionName()); pushParamNamesArray(cfw, ofn.fnode); @@ -635,14 +641,13 @@ public class Codegen extends Interpreter cfw.addInvoke(ByteCode.INVOKEVIRTUAL, "org/mozilla/javascript/NativeFunction", "initScriptFunction", - "(ILjava/lang/String;[Ljava/lang/String;I)V"); - - cfw.addLoadThis(); - cfw.addALoad(SCOPE_ARG); - cfw.addInvoke(ByteCode.INVOKEVIRTUAL, - "org/mozilla/javascript/ScriptableObject", - "setParentScope", - "(Lorg/mozilla/javascript/Scriptable;)V"); + "(Lorg/mozilla/javascript/Context;" + +"Lorg/mozilla/javascript/Scriptable;" + +"I" + +"Ljava/lang/String;" + +"[Ljava/lang/String;" + +"I" + +")V"); // precompile all regexp literals int regexpCount = ofn.fnode.getRegexpCount(); @@ -2123,10 +2128,10 @@ class BodyCodegen codegen.mainClassSignature); } - // Dup function reference for function expressions to have it - // on top of the stack when initFunction returns if (functionType == FunctionNode.FUNCTION_EXPRESSION) { - cfw.add(ByteCode.DUP); + // Leave closure object on stack and do not pass it to + // initFunction which suppose to connect statements to scope + return; } cfw.addPush(functionType); cfw.addALoad(variableObjectLocal);