diff options
author | Alexander Sulfrian <alexander@sulfrian.net> | 2010-06-08 08:22:05 +0200 |
---|---|---|
committer | Alexander Sulfrian <alexander@sulfrian.net> | 2010-06-08 08:22:05 +0200 |
commit | d7c5ad7d6263fd1baf9bfdbaa4c50b70ef2fbdb2 (patch) | |
tree | ae0b65da6432f4c26c8d5a7319efbda5d172846c /infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java | |
parent | fa61221dcd89fcd72cba2c97971626f456c86e5d (diff) | |
download | etherpad-d7c5ad7d6263fd1baf9bfdbaa4c50b70ef2fbdb2.tar.gz etherpad-d7c5ad7d6263fd1baf9bfdbaa4c50b70ef2fbdb2.tar.xz etherpad-d7c5ad7d6263fd1baf9bfdbaa4c50b70ef2fbdb2.zip |
reverted folder structure change for better mergeing with upstream
Diffstat (limited to 'infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java')
-rw-r--r-- | infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java | 2526 |
1 files changed, 0 insertions, 2526 deletions
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java deleted file mode 100644 index 0833883..0000000 --- a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java +++ /dev/null @@ -1,2526 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0 - * - * The contents of this file are subject to the Mozilla 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/MPL/ - * - * 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 the Initial Developer are Copyright (C) 1997-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Bob Jervis - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License Version 2 or later (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 - * MPL, indicate your decision by deleting the provisions above and replacing - * 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 MPL or the GPL. - * - * ***** END LICENSE BLOCK ***** */ - -// API class - -package org.mozilla.javascript; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.CharArrayWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Hashtable; -import java.util.Locale; - -import org.mozilla.javascript.debug.DebuggableScript; -import org.mozilla.javascript.debug.Debugger; -import org.mozilla.javascript.xml.XMLLib; - -/** - * This class represents the runtime context of an executing script. - * - * Before executing a script, an instance of Context must be created - * and associated with the thread that will be executing the script. - * The Context will be used to store information about the executing - * of the script such as the call stack. Contexts are associated with - * the current thread using the {@link #call(ContextAction)} - * or {@link #enter()} methods.<p> - * - * Different forms of script execution are supported. Scripts may be - * evaluated from the source directly, or first compiled and then later - * executed. Interactive execution is also supported.<p> - * - * Some aspects of script execution, such as type conversions and - * object creation, may be accessed directly through methods of - * Context. - * - * @see Scriptable - * @author Norris Boyd - * @author Brendan Eich - */ - -public class Context -{ - /** - * Language versions. - * - * All integral values are reserved for future version numbers. - */ - - /** - * The unknown version. - */ - public static final int VERSION_UNKNOWN = -1; - - /** - * The default version. - */ - public static final int VERSION_DEFAULT = 0; - - /** - * JavaScript 1.0 - */ - public static final int VERSION_1_0 = 100; - - /** - * JavaScript 1.1 - */ - public static final int VERSION_1_1 = 110; - - /** - * JavaScript 1.2 - */ - public static final int VERSION_1_2 = 120; - - /** - * JavaScript 1.3 - */ - public static final int VERSION_1_3 = 130; - - /** - * JavaScript 1.4 - */ - public static final int VERSION_1_4 = 140; - - /** - * JavaScript 1.5 - */ - public static final int VERSION_1_5 = 150; - - /** - * JavaScript 1.6 - */ - public static final int VERSION_1_6 = 160; - - /** - * JavaScript 1.7 - */ - public static final int VERSION_1_7 = 170; - - /** - * Controls behaviour of <tt>Date.prototype.getYear()</tt>. - * If <tt>hasFeature(FEATURE_NON_ECMA_GET_YEAR)</tt> returns true, - * Date.prototype.getYear subtructs 1900 only if 1900 <= date < 2000. - * The default behavior of {@link #hasFeature(int)} is always to subtruct - * 1900 as rquired by ECMAScript B.2.4. - */ - public static final int FEATURE_NON_ECMA_GET_YEAR = 1; - - /** - * Control if member expression as function name extension is available. - * If <tt>hasFeature(FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME)</tt> returns - * true, allow <tt>function memberExpression(args) { body }</tt> to be - * syntax sugar for <tt>memberExpression = function(args) { body }</tt>, - * when memberExpression is not a simple identifier. - * See ECMAScript-262, section 11.2 for definition of memberExpression. - * By default {@link #hasFeature(int)} returns false. - */ - public static final int FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME = 2; - - /** - * Control if reserved keywords are treated as identifiers. - * If <tt>hasFeature(RESERVED_KEYWORD_AS_IDENTIFIER)</tt> returns true, - * treat future reserved keyword (see Ecma-262, section 7.5.3) as ordinary - * identifiers but warn about this usage. - * - * By default {@link #hasFeature(int)} returns false. - */ - public static final int FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER = 3; - - /** - * Control if <tt>toString()</tt> should returns the same result - * as <tt>toSource()</tt> when applied to objects and arrays. - * If <tt>hasFeature(FEATURE_TO_STRING_AS_SOURCE)</tt> returns true, - * calling <tt>toString()</tt> on JS objects gives the same result as - * calling <tt>toSource()</tt>. That is it returns JS source with code - * 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}. - */ - public static final int FEATURE_TO_STRING_AS_SOURCE = 4; - - /** - * Control if properties <tt>__proto__</tt> and <tt>__parent__</tt> - * are treated specially. - * If <tt>hasFeature(FEATURE_PARENT_PROTO_PROPERTIES)</tt> returns true, - * treat <tt>__parent__</tt> and <tt>__proto__</tt> as special properties. - * <p> - * The properties allow to query and set scope and prototype chains for the - * objects. The special meaning of the properties is available - * only when they are used as the right hand side of the dot operator. - * For example, while <tt>x.__proto__ = y</tt> changes the prototype - * chain of the object <tt>x</tt> to point to <tt>y</tt>, - * <tt>x["__proto__"] = y</tt> simply assigns a new value to the property - * <tt>__proto__</tt> in <tt>x</tt> even when the feature is on. - * - * By default {@link #hasFeature(int)} returns true. - */ - public static final int FEATURE_PARENT_PROTO_PROPERTIES = 5; - - /** - * @deprecated In previous releases, this name was given to - * FEATURE_PARENT_PROTO_PROPERTIES. - */ - 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 at least {@link #VERSION_1_6}. - * @since 1.6 Release 1 - */ - public static final int FEATURE_E4X = 6; - - /** - * Control if dynamic scope should be used for name access. - * If hasFeature(FEATURE_DYNAMIC_SCOPE) returns true, then the name lookup - * during name resolution will use the top scope of the script or function - * which is at the top of JS execution stack instead of the top scope of the - * script or function from the current stack frame if the top scope of - * the top stack frame contains the top scope of the current stack frame - * on its prototype chain. - * <p> - * This is useful to define shared scope containing functions that can - * be called from scripts and functions using private scopes. - * <p> - * By default {@link #hasFeature(int)} returns false. - * @since 1.6 Release 1 - */ - public static final int FEATURE_DYNAMIC_SCOPE = 7; - - /** - * Control if strict variable mode is enabled. - * When the feature is on Rhino reports runtime errors if assignment - * to a global variable that does not exist is executed. When the feature - * is off such assignments creates new variable in the global scope as - * required by ECMA 262. - * <p> - * By default {@link #hasFeature(int)} returns false. - * @since 1.6 Release 1 - */ - public static final int FEATURE_STRICT_VARS = 8; - - /** - * Control if strict eval mode is enabled. - * When the feature is on Rhino reports runtime errors if non-string - * argument is passed to the eval function. When the feature is off - * eval simply return non-string argument as is without performing any - * evaluation as required by ECMA 262. - * <p> - * By default {@link #hasFeature(int)} returns false. - * @since 1.6 Release 1 - */ - public static final int FEATURE_STRICT_EVAL = 9; - - /** - * When the feature is on Rhino will add a "fileName" and "lineNumber" - * properties to Error objects automatically. When the feature is off, you - * have to explicitly pass them as the second and third argument to the - * Error constructor. Note that neither behaviour is fully ECMA 262 - * compliant (as 262 doesn't specify a three-arg constructor), but keeping - * the feature off results in Error objects that don't have - * additional non-ECMA properties when constructed using the ECMA-defined - * single-arg constructor and is thus desirable if a stricter ECMA - * compliance is desired, specifically adherence to the point 15.11.5. of - * the standard. - * <p> - * By default {@link #hasFeature(int)} returns false. - * @since 1.6 Release 6 - */ - public static final int FEATURE_LOCATION_INFORMATION_IN_ERROR = 10; - - /** - * Controls whether JS 1.5 'strict mode' is enabled. - * When the feature is on, Rhino reports more than a dozen different - * warnings. When the feature is off, these warnings are not generated. - * FEATURE_STRICT_MODE implies FEATURE_STRICT_VARS and FEATURE_STRICT_EVAL. - * <p> - * By default {@link #hasFeature(int)} returns false. - * @since 1.6 Release 6 - */ - public static final int FEATURE_STRICT_MODE = 11; - - /** - * Controls whether a warning should be treated as an error. - * @since 1.6 Release 6 - */ - public static final int FEATURE_WARNING_AS_ERROR = 12; - - /** - * Enables enhanced access to Java. - * Specifically, controls whether private and protected members can be - * accessed, and whether scripts can catch all Java exceptions. - * <p> - * Note that this feature should only be enabled for trusted scripts. - * <p> - * By default {@link #hasFeature(int)} returns false. - * @since 1.7 Release 1 - */ - public static final int FEATURE_ENHANCED_JAVA_ACCESS = 13; - - - public static final String languageVersionProperty = "language version"; - public static final String errorReporterProperty = "error reporter"; - - /** - * Convenient value to use as zero-length array of objects. - */ - public static final Object[] emptyArgs = ScriptRuntime.emptyArgs; - - /** - * Create a new Context. - * - * Note that the Context must be associated with a thread before - * it can be used to execute a script. - * @deprecated use {@link ContextFactory#enter()} or - * {@link ContextFactory#call(ContextAction)} instead. - */ - public Context() - { - this(ContextFactory.getGlobal()); - } - - Context(ContextFactory factory) - { - assert factory != null; - this.factory = factory; - setLanguageVersion(VERSION_DEFAULT); - optimizationLevel = codegenClass != null ? 0 : -1; - maximumInterpreterStackDepth = Integer.MAX_VALUE; - } - - /** - * Get the current Context. - * - * The current Context is per-thread; this method looks up - * the Context associated with the current thread. <p> - * - * @return the Context associated with the current thread, or - * null if no context is associated with the current - * thread. - * @see ContextFactory#enterContext() - * @see ContextFactory#call(ContextAction) - */ - public static Context getCurrentContext() - { - Object helper = VMBridge.instance.getThreadContextHelper(); - return VMBridge.instance.getContext(helper); - } - - /** - * Same as calling {@link ContextFactory#enterContext()} on the global - * ContextFactory instance. - * @deprecated use {@link ContextFactory#enter()} or - * {@link ContextFactory#call(ContextAction)} instead as this method relies - * on usage of a static singleton "global" ContextFactory. - * @return a Context associated with the current thread - * @see #getCurrentContext() - * @see #exit() - * @see #call(ContextAction) - */ - public static Context enter() - { - return enter(null); - } - - /** - * Get a Context associated with the current thread, using - * the given Context if need be. - * <p> - * The same as <code>enter()</code> except that <code>cx</code> - * is associated with the current thread and returned if - * the current thread has no associated context and <code>cx</code> - * is not associated with any other thread. - * @param cx a Context to associate with the thread if possible - * @return a Context associated with the current thread - * @deprecated use {@link ContextFactory#enterContext(Context)} instead as - * this method relies on usage of a static singleton "global" ContextFactory. - * @see ContextFactory#enterContext(Context) - * @see ContextFactory#call(ContextAction) - */ - public static Context enter(Context cx) - { - return enter(cx, ContextFactory.getGlobal()); - } - - static final Context enter(Context cx, ContextFactory factory) - { - Object helper = VMBridge.instance.getThreadContextHelper(); - Context old = VMBridge.instance.getContext(helper); - if (old != null) { - cx = old; - } else { - if (cx == null) { - cx = factory.makeContext(); - if (cx.enterCount != 0) { - throw new IllegalStateException("factory.makeContext() returned Context instance already associated with some thread"); - } - factory.onContextCreated(cx); - if (factory.isSealed() && !cx.isSealed()) { - cx.seal(null); - } - } else { - if (cx.enterCount != 0) { - throw new IllegalStateException("can not use Context instance already associated with some thread"); - } - } - VMBridge.instance.setContext(helper, cx); - } - ++cx.enterCount; - return cx; - } - - /** - * Exit a block of code requiring a Context. - * - * Calling <code>exit()</code> will remove the association between - * the current thread and a Context if the prior call to - * {@link ContextFactory#enterContext()} on this thread newly associated a - * Context with this thread. Once the current thread no longer has an - * associated Context, it cannot be used to execute JavaScript until it is - * again associated with a Context. - * @see ContextFactory#enterContext() - */ - public static void exit() - { - Object helper = VMBridge.instance.getThreadContextHelper(); - Context cx = VMBridge.instance.getContext(helper); - if (cx == null) { - throw new IllegalStateException( - "Calling Context.exit without previous Context.enter"); - } - if (cx.enterCount < 1) Kit.codeBug(); - if (--cx.enterCount == 0) { - VMBridge.instance.setContext(helper, null); - cx.factory.onContextReleased(cx); - } - } - - /** - * Call {@link ContextAction#run(Context cx)} - * using the Context instance associated with the current thread. - * If no Context is associated with the thread, then - * <tt>ContextFactory.getGlobal().makeContext()</tt> will be called to - * construct new Context instance. The instance will be temporary - * associated with the thread during call to - * {@link ContextAction#run(Context)}. - * @deprecated use {@link ContextFactory#call(ContextAction)} instead as - * this method relies on usage of a static singleton "global" - * ContextFactory. - * @return The result of {@link ContextAction#run(Context)}. - */ - public static Object call(ContextAction action) - { - return call(ContextFactory.getGlobal(), action); - } - - /** - * Call {@link - * Callable#call(Context cx, Scriptable scope, Scriptable thisObj, - * Object[] args)} - * using the Context instance associated with the current thread. - * If no Context is associated with the thread, then - * {@link ContextFactory#makeContext()} will be called to construct - * new Context instance. The instance will be temporary associated - * with the thread during call to {@link ContextAction#run(Context)}. - * <p> - * It is allowed but not advisable to use null for <tt>factory</tt> - * argument in which case the global static singleton ContextFactory - * instance will be used to create new context instances. - * @see ContextFactory#call(ContextAction) - */ - public static Object call(ContextFactory factory, final Callable callable, - final Scriptable scope, final Scriptable thisObj, - final Object[] args) - { - if(factory == null) { - factory = ContextFactory.getGlobal(); - } - return call(factory, new ContextAction() { - public Object run(Context cx) { - return callable.call(cx, scope, thisObj, args); - } - }); - } - - /** - * The method implements {@links ContextFactory#call(ContextAction)} logic. - */ - static Object call(ContextFactory factory, ContextAction action) { - Context cx = enter(null, factory); - try { - return action.run(cx); - } - finally { - exit(); - } - } - - /** - * @deprecated - * @see ContextFactory#addListener(ContextFactory.Listener) - * @see ContextFactory#getGlobal() - */ - public static void addContextListener(ContextListener listener) - { - // Special workaround for the debugger - String DBG = "org.mozilla.javascript.tools.debugger.Main"; - if (DBG.equals(listener.getClass().getName())) { - Class cl = listener.getClass(); - Class factoryClass = Kit.classOrNull( - "org.mozilla.javascript.ContextFactory"); - Class[] sig = { factoryClass }; - Object[] args = { ContextFactory.getGlobal() }; - try { - Method m = cl.getMethod("attachTo", sig); - m.invoke(listener, args); - } catch (Exception ex) { - RuntimeException rex = new RuntimeException(); - Kit.initCause(rex, ex); - throw rex; - } - return; - } - - ContextFactory.getGlobal().addListener(listener); - } - - /** - * @deprecated - * @see ContextFactory#removeListener(ContextFactory.Listener) - * @see ContextFactory#getGlobal() - */ - public static void removeContextListener(ContextListener listener) - { - ContextFactory.getGlobal().addListener(listener); - } - - /** - * Return {@link ContextFactory} instance used to create this Context. - */ - public final ContextFactory getFactory() - { - return factory; - } - - /** - * Checks if this is a sealed Context. A sealed Context instance does not - * allow to modify any of its properties and will throw an exception - * on any such attempt. - * @see #seal(Object sealKey) - */ - public final boolean isSealed() - { - return sealed; - } - - /** - * Seal this Context object so any attempt to modify any of its properties - * including calling {@link #enter()} and {@link #exit()} methods will - * throw an exception. - * <p> - * If <tt>sealKey</tt> is not null, calling - * {@link #unseal(Object sealKey)} with the same key unseals - * the object. If <tt>sealKey</tt> is null, unsealing is no longer possible. - * - * @see #isSealed() - * @see #unseal(Object) - */ - public final void seal(Object sealKey) - { - if (sealed) onSealedMutation(); - sealed = true; - this.sealKey = sealKey; - } - - /** - * Unseal previously sealed Context object. - * The <tt>sealKey</tt> argument should not be null and should match - * <tt>sealKey</tt> suplied with the last call to - * {@link #seal(Object)} or an exception will be thrown. - * - * @see #isSealed() - * @see #seal(Object sealKey) - */ - public final void unseal(Object sealKey) - { - if (sealKey == null) throw new IllegalArgumentException(); - if (this.sealKey != sealKey) throw new IllegalArgumentException(); - if (!sealed) throw new IllegalStateException(); - sealed = false; - this.sealKey = null; - } - - static void onSealedMutation() - { - throw new IllegalStateException(); - } - - /** - * Get the current language version. - * <p> - * The language version number affects JavaScript semantics as detailed - * in the overview documentation. - * - * @return an integer that is one of VERSION_1_0, VERSION_1_1, etc. - */ - public final int getLanguageVersion() - { - return version; - } - - /** - * Set the language version. - * - * <p> - * Setting the language version will affect functions and scripts compiled - * subsequently. See the overview documentation for version-specific - * behavior. - * - * @param version the version as specified by VERSION_1_0, VERSION_1_1, etc. - */ - public void setLanguageVersion(int version) - { - if (sealed) onSealedMutation(); - checkLanguageVersion(version); - Object listeners = propertyListeners; - if (listeners != null && version != this.version) { - firePropertyChangeImpl(listeners, languageVersionProperty, - new Integer(this.version), - new Integer(version)); - } - this.version = version; - } - - public static boolean isValidLanguageVersion(int version) - { - switch (version) { - case VERSION_DEFAULT: - case VERSION_1_0: - case VERSION_1_1: - case VERSION_1_2: - case VERSION_1_3: - case VERSION_1_4: - case VERSION_1_5: - case VERSION_1_6: - case VERSION_1_7: - return true; - } - return false; - } - - public static void checkLanguageVersion(int version) - { - if (isValidLanguageVersion(version)) { - return; - } - throw new IllegalArgumentException("Bad language version: "+version); - } - - /** - * Get the implementation version. - * - * <p> - * The implementation version is of the form - * <pre> - * "<i>name langVer</i> <code>release</code> <i>relNum date</i>" - * </pre> - * where <i>name</i> is the name of the product, <i>langVer</i> is - * the language version, <i>relNum</i> is the release number, and - * <i>date</i> is the release date for that specific - * release in the form "yyyy mm dd". - * - * @return a string that encodes the product, language version, release - * number, and date. - */ - public final String getImplementationVersion() - { - // XXX Probably it would be better to embed this directly into source - // with special build preprocessing but that would require some ant - // tweaking and then replacing token in resource files was simpler - if (implementationVersion == null) { - implementationVersion - = ScriptRuntime.getMessage0("implementation.version"); - } - return implementationVersion; - } - - /** - * Get the current error reporter. - * - * @see org.mozilla.javascript.ErrorReporter - */ - public final ErrorReporter getErrorReporter() - { - if (errorReporter == null) { - return DefaultErrorReporter.instance; - } - return errorReporter; - } - - /** - * Change the current error reporter. - * - * @return the previous error reporter - * @see org.mozilla.javascript.ErrorReporter - */ - public final ErrorReporter setErrorReporter(ErrorReporter reporter) - { - if (sealed) onSealedMutation(); - if (reporter == null) throw new IllegalArgumentException(); - ErrorReporter old = getErrorReporter(); - if (reporter == old) { - return old; - } - Object listeners = propertyListeners; - if (listeners != null) { - firePropertyChangeImpl(listeners, errorReporterProperty, - old, reporter); - } - this.errorReporter = reporter; - return old; - } - - /** - * Get the current locale. Returns the default locale if none has - * been set. - * - * @see java.util.Locale - */ - - public final Locale getLocale() - { - if (locale == null) - locale = Locale.getDefault(); - return locale; - } - - /** - * Set the current locale. - * - * @see java.util.Locale - */ - public final Locale setLocale(Locale loc) - { - if (sealed) onSealedMutation(); - Locale result = locale; - locale = loc; - return result; - } - - /** - * Register an object to receive notifications when a bound property - * has changed - * @see java.beans.PropertyChangeEvent - * @see #removePropertyChangeListener(java.beans.PropertyChangeListener) - * @param l the listener - */ - public final void addPropertyChangeListener(PropertyChangeListener l) - { - if (sealed) onSealedMutation(); - propertyListeners = Kit.addListener(propertyListeners, l); - } - - /** - * Remove an object from the list of objects registered to receive - * notification of changes to a bounded property - * @see java.beans.PropertyChangeEvent - * @see #addPropertyChangeListener(java.beans.PropertyChangeListener) - * @param l the listener - */ - public final void removePropertyChangeListener(PropertyChangeListener l) - { - if (sealed) onSealedMutation(); - propertyListeners = Kit.removeListener(propertyListeners, l); - } - - /** - * Notify any registered listeners that a bounded property has changed - * @see #addPropertyChangeListener(java.beans.PropertyChangeListener) - * @see #removePropertyChangeListener(java.beans.PropertyChangeListener) - * @see java.beans.PropertyChangeListener - * @see java.beans.PropertyChangeEvent - * @param property the bound property - * @param oldValue the old value - * @param newValue the new value - */ - final void firePropertyChange(String property, Object oldValue, - Object newValue) - { - Object listeners = propertyListeners; - if (listeners != null) { - firePropertyChangeImpl(listeners, property, oldValue, newValue); - } - } - - private void firePropertyChangeImpl(Object listeners, String property, - Object oldValue, Object newValue) - { - for (int i = 0; ; ++i) { - Object l = Kit.getListener(listeners, i); - if (l == null) - break; - if (l instanceof PropertyChangeListener) { - PropertyChangeListener pcl = (PropertyChangeListener)l; - pcl.propertyChange(new PropertyChangeEvent( - this, property, oldValue, newValue)); - } - } - } - - /** - * Report a warning using the error reporter for the current thread. - * - * @param message the warning message to report - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number - * @param lineSource the text of the line (may be null) - * @param lineOffset the offset into lineSource where problem was detected - * @see org.mozilla.javascript.ErrorReporter - */ - public static void reportWarning(String message, String sourceName, - int lineno, String lineSource, - int lineOffset) - { - Context cx = Context.getContext(); - if (cx.hasFeature(FEATURE_WARNING_AS_ERROR)) - reportError(message, sourceName, lineno, lineSource, lineOffset); - else - cx.getErrorReporter().warning(message, sourceName, lineno, - lineSource, lineOffset); - } - - /** - * Report a warning using the error reporter for the current thread. - * - * @param message the warning message to report - * @see org.mozilla.javascript.ErrorReporter - */ - public static void reportWarning(String message) - { - int[] linep = { 0 }; - String filename = getSourcePositionFromStack(linep); - Context.reportWarning(message, filename, linep[0], null, 0); - } - - public static void reportWarning(String message, Throwable t) - { - int[] linep = { 0 }; - String filename = getSourcePositionFromStack(linep); - Writer sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - pw.println(message); - t.printStackTrace(pw); - pw.flush(); - Context.reportWarning(sw.toString(), filename, linep[0], null, 0); - } - - /** - * Report an error using the error reporter for the current thread. - * - * @param message the error message to report - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number - * @param lineSource the text of the line (may be null) - * @param lineOffset the offset into lineSource where problem was detected - * @see org.mozilla.javascript.ErrorReporter - */ - public static void reportError(String message, String sourceName, - int lineno, String lineSource, - int lineOffset) - { - Context cx = getCurrentContext(); - if (cx != null) { - cx.getErrorReporter().error(message, sourceName, lineno, - lineSource, lineOffset); - } else { - throw new EvaluatorException(message, sourceName, lineno, - lineSource, lineOffset); - } - } - - /** - * Report an error using the error reporter for the current thread. - * - * @param message the error message to report - * @see org.mozilla.javascript.ErrorReporter - */ - public static void reportError(String message) - { - int[] linep = { 0 }; - String filename = getSourcePositionFromStack(linep); - Context.reportError(message, filename, linep[0], null, 0); - } - - /** - * Report a runtime error using the error reporter for the current thread. - * - * @param message the error message to report - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number - * @param lineSource the text of the line (may be null) - * @param lineOffset the offset into lineSource where problem was detected - * @return a runtime exception that will be thrown to terminate the - * execution of the script - * @see org.mozilla.javascript.ErrorReporter - */ - public static EvaluatorException reportRuntimeError(String message, - String sourceName, - int lineno, - String lineSource, - int lineOffset) - { - Context cx = getCurrentContext(); - if (cx != null) { - return cx.getErrorReporter(). - runtimeError(message, sourceName, lineno, - lineSource, lineOffset); - } else { - throw new EvaluatorException(message, sourceName, lineno, - lineSource, lineOffset); - } - } - - static EvaluatorException reportRuntimeError0(String messageId) - { - String msg = ScriptRuntime.getMessage0(messageId); - return reportRuntimeError(msg); - } - - static EvaluatorException reportRuntimeError1(String messageId, - Object arg1) - { - String msg = ScriptRuntime.getMessage1(messageId, arg1); - return reportRuntimeError(msg); - } - - static EvaluatorException reportRuntimeError2(String messageId, - Object arg1, Object arg2) - { - String msg = ScriptRuntime.getMessage2(messageId, arg1, arg2); - return reportRuntimeError(msg); - } - - static EvaluatorException reportRuntimeError3(String messageId, - Object arg1, Object arg2, - Object arg3) - { - String msg = ScriptRuntime.getMessage3(messageId, arg1, arg2, arg3); - return reportRuntimeError(msg); - } - - static EvaluatorException reportRuntimeError4(String messageId, - Object arg1, Object arg2, - Object arg3, Object arg4) - { - String msg - = ScriptRuntime.getMessage4(messageId, arg1, arg2, arg3, arg4); - return reportRuntimeError(msg); - } - - /** - * Report a runtime error using the error reporter for the current thread. - * - * @param message the error message to report - * @see org.mozilla.javascript.ErrorReporter - */ - public static EvaluatorException reportRuntimeError(String message) - { - int[] linep = { 0 }; - String filename = getSourcePositionFromStack(linep); - return Context.reportRuntimeError(message, filename, linep[0], null, 0); - } - - /** - * Initialize the standard objects. - * - * Creates instances of the standard objects and their constructors - * (Object, String, Number, Date, etc.), setting up 'scope' to act - * as a global object as in ECMA 15.1.<p> - * - * This method must be called to initialize a scope before scripts - * can be evaluated in that scope.<p> - * - * This method does not affect the Context it is called upon. - * - * @return the initialized scope - */ - public final ScriptableObject initStandardObjects() - { - return initStandardObjects(null, false); - } - - /** - * Initialize the standard objects. - * - * Creates instances of the standard objects and their constructors - * (Object, String, Number, Date, etc.), setting up 'scope' to act - * as a global object as in ECMA 15.1.<p> - * - * This method must be called to initialize a scope before scripts - * can be evaluated in that scope.<p> - * - * This method does not affect the Context it is called upon. - * - * @param scope the scope to initialize, or null, in which case a new - * object will be created to serve as the scope - * @return the initialized scope. The method returns the value of the scope - * argument if it is not null or newly allocated scope object which - * is an instance {@link ScriptableObject}. - */ - public final Scriptable initStandardObjects(ScriptableObject scope) - { - return initStandardObjects(scope, false); - } - - /** - * Initialize the standard objects. - * - * Creates instances of the standard objects and their constructors - * (Object, String, Number, Date, etc.), setting up 'scope' to act - * as a global object as in ECMA 15.1.<p> - * - * This method must be called to initialize a scope before scripts - * can be evaluated in that scope.<p> - * - * This method does not affect the Context it is called upon.<p> - * - * This form of the method also allows for creating "sealed" standard - * objects. An object that is sealed cannot have properties added, changed, - * or removed. This is useful to create a "superglobal" that can be shared - * among several top-level objects. Note that sealing is not allowed in - * the current ECMA/ISO language specification, but is likely for - * the next version. - * - * @param scope the scope to initialize, or null, in which case a new - * object will be created to serve as the scope - * @param sealed whether or not to create sealed standard objects that - * cannot be modified. - * @return the initialized scope. The method returns the value of the scope - * argument if it is not null or newly allocated scope object. - * @since 1.4R3 - */ - public ScriptableObject initStandardObjects(ScriptableObject scope, - boolean sealed) - { - return ScriptRuntime.initStandardObjects(this, scope, sealed); - } - - /** - * Get the singleton object that represents the JavaScript Undefined value. - */ - public static Object getUndefinedValue() - { - return Undefined.instance; - } - - /** - * Evaluate a JavaScript source string. - * - * The provided source name and line number are used for error messages - * and for producing debug information. - * - * @param scope the scope to execute in - * @param source the JavaScript source - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number - * @param securityDomain an arbitrary object that specifies security - * information about the origin or owner of the script. For - * implementations that don't care about security, this value - * may be null. - * @return the result of evaluating the string - * @see org.mozilla.javascript.SecurityController - */ - public final Object evaluateString(Scriptable scope, String source, - String sourceName, int lineno, - Object securityDomain) - { - Script script = compileString(source, sourceName, lineno, - securityDomain); - if (script != null) { - return script.exec(this, scope); - } else { - return null; - } - } - - /** - * Evaluate a reader as JavaScript source. - * - * All characters of the reader are consumed. - * - * @param scope the scope to execute in - * @param in the Reader to get JavaScript source from - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number - * @param securityDomain an arbitrary object that specifies security - * information about the origin or owner of the script. For - * implementations that don't care about security, this value - * may be null. - * @return the result of evaluating the source - * - * @exception IOException if an IOException was generated by the Reader - */ - public final Object evaluateReader(Scriptable scope, Reader in, - String sourceName, int lineno, - Object securityDomain) - throws IOException - { - Script script = compileReader(scope, in, sourceName, lineno, - securityDomain); - if (script != null) { - return script.exec(this, scope); - } else { - return null; - } - } - - /** - * Check whether a string is ready to be compiled. - * <p> - * stringIsCompilableUnit is intended to support interactive compilation of - * javascript. If compiling the string would result in an error - * that might be fixed by appending more source, this method - * returns false. In every other case, it returns true. - * <p> - * Interactive shells may accumulate source lines, using this - * method after each new line is appended to check whether the - * statement being entered is complete. - * - * @param source the source buffer to check - * @return whether the source is ready for compilation - * @since 1.4 Release 2 - */ - public final boolean stringIsCompilableUnit(String source) - { - boolean errorseen = false; - CompilerEnvirons compilerEnv = new CompilerEnvirons(); - compilerEnv.initFromContext(this); - // no source name or source text manager, because we're just - // going to throw away the result. - compilerEnv.setGeneratingSource(false); - /*APPJET*/ - Parser p = InformativeParser.makeParser(compilerEnv, - DefaultErrorReporter.instance); - try { - p.parse(source, null, 1); - } catch (EvaluatorException ee) { - errorseen = true; - } - // Return false only if an error occurred as a result of reading past - // the end of the file, i.e. if the source could be fixed by - // appending more source. - if (errorseen && p.eof()) - return false; - else - return true; - } - - /** - * @deprecated - * @see #compileReader(Reader in, String sourceName, int lineno, - * Object securityDomain) - */ - public final Script compileReader(Scriptable scope, Reader in, - String sourceName, int lineno, - Object securityDomain) - throws IOException - { - return compileReader(in, sourceName, lineno, securityDomain); - } - - /** - * Compiles the source in the given reader. - * <p> - * Returns a script that may later be executed. - * Will consume all the source in the reader. - * - * @param in the input reader - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number for reporting errors - * @param securityDomain an arbitrary object that specifies security - * information about the origin or owner of the script. For - * implementations that don't care about security, this value - * may be null. - * @return a script that may later be executed - * @exception IOException if an IOException was generated by the Reader - * @see org.mozilla.javascript.Script - */ - public final Script compileReader(Reader in, String sourceName, - int lineno, Object securityDomain) - throws IOException - { - if (lineno < 0) { - // For compatibility IllegalArgumentException can not be thrown here - lineno = 0; - } - return (Script) compileImpl(null, in, null, sourceName, lineno, - securityDomain, false, null, null); - } - - /** - * Compiles the source in the given string. - * <p> - * Returns a script that may later be executed. - * - * @param source the source string - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number for reporting errors - * @param securityDomain an arbitrary object that specifies security - * information about the origin or owner of the script. For - * implementations that don't care about security, this value - * may be null. - * @return a script that may later be executed - * @see org.mozilla.javascript.Script - */ - public final Script compileString(String source, - String sourceName, int lineno, - Object securityDomain) - { - if (lineno < 0) { - // For compatibility IllegalArgumentException can not be thrown here - lineno = 0; - } - return compileString(source, null, null, sourceName, lineno, - securityDomain); - } - - final Script compileString(String source, - Evaluator compiler, - ErrorReporter compilationErrorReporter, - String sourceName, int lineno, - Object securityDomain) - { - try { - 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(); - } - } - - /** - * Compile a JavaScript function. - * <p> - * The function source must be a function definition as defined by - * ECMA (e.g., "function f(a) { return a; }"). - * - * @param scope the scope to compile relative to - * @param source the function definition source - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number - * @param securityDomain an arbitrary object that specifies security - * information about the origin or owner of the script. For - * implementations that don't care about security, this value - * may be null. - * @return a Function that may later be called - * @see org.mozilla.javascript.Function - */ - 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, - Evaluator compiler, - ErrorReporter compilationErrorReporter, - String sourceName, int lineno, - Object securityDomain) - { - try { - return (Function) compileImpl(scope, null, source, sourceName, - lineno, securityDomain, true, - compiler, compilationErrorReporter); - } - catch (IOException ioe) { - // Should never happen because we just made the reader - // from a String - throw new RuntimeException(); - } - } - - /** - * Decompile the script. - * <p> - * The canonical source of the script is returned. - * - * @param script the script to decompile - * @param indent the number of spaces to indent the result - * @return a string representing the script source - */ - public final String decompileScript(Script script, int indent) - { - NativeFunction scriptImpl = (NativeFunction) script; - return scriptImpl.decompile(indent, 0); - } - - /** - * Decompile a JavaScript Function. - * <p> - * Decompiles a previously compiled JavaScript function object to - * canonical source. - * <p> - * Returns function body of '[native code]' if no decompilation - * information is available. - * - * @param fun the JavaScript function to decompile - * @param indent the number of spaces to indent the result - * @return a string representing the function source - */ - public final String decompileFunction(Function fun, int indent) - { - if (fun instanceof BaseFunction) - return ((BaseFunction)fun).decompile(indent, 0); - else - return "function " + fun.getClassName() + - "() {\n\t[native code]\n}\n"; - } - - /** - * Decompile the body of a JavaScript Function. - * <p> - * Decompiles the body a previously compiled JavaScript Function - * object to canonical source, omitting the function header and - * trailing brace. - * - * Returns '[native code]' if no decompilation information is available. - * - * @param fun the JavaScript function to decompile - * @param indent the number of spaces to indent the result - * @return a string representing the function body source. - */ - public final String decompileFunctionBody(Function fun, int indent) - { - if (fun instanceof BaseFunction) { - BaseFunction bf = (BaseFunction)fun; - return bf.decompile(indent, Decompiler.ONLY_BODY_FLAG); - } - // ALERT: not sure what the right response here is. - return "[native code]\n"; - } - - /** - * Create a new JavaScript object. - * - * Equivalent to evaluating "new Object()". - * @param scope the scope to search for the constructor and to evaluate - * against - * @return the new object - */ - public final Scriptable newObject(Scriptable scope) - { - return newObject(scope, "Object", ScriptRuntime.emptyArgs); - } - - /** - * Create a new JavaScript object by executing the named constructor. - * - * The call <code>newObject(scope, "Foo")</code> is equivalent to - * evaluating "new Foo()". - * - * @param scope the scope to search for the constructor and to evaluate against - * @param constructorName the name of the constructor to call - * @return the new object - */ - public final Scriptable newObject(Scriptable scope, String constructorName) - { - return newObject(scope, constructorName, ScriptRuntime.emptyArgs); - } - - /** - * Creates a new JavaScript object by executing the named constructor. - * - * Searches <code>scope</code> for the named constructor, calls it with - * the given arguments, and returns the result.<p> - * - * The code - * <pre> - * Object[] args = { "a", "b" }; - * newObject(scope, "Foo", args)</pre> - * is equivalent to evaluating "new Foo('a', 'b')", assuming that the Foo - * constructor has been defined in <code>scope</code>. - * - * @param scope The scope to search for the constructor and to evaluate - * against - * @param constructorName the name of the constructor to call - * @param args the array of arguments for the constructor - * @return the new object - */ - public final Scriptable newObject(Scriptable scope, String constructorName, - Object[] args) - { - scope = ScriptableObject.getTopLevelScope(scope); - Function ctor = ScriptRuntime.getExistingCtor(this, scope, - constructorName); - if (args == null) { args = ScriptRuntime.emptyArgs; } - return ctor.construct(this, scope, args); - } - - /** - * Create an array with a specified initial length. - * <p> - * @param scope the scope to create the object in - * @param length the initial length (JavaScript arrays may have - * additional properties added dynamically). - * @return the new array object - */ - public final Scriptable newArray(Scriptable scope, int length) - { - NativeArray result = new NativeArray(length); - ScriptRuntime.setObjectProtoAndParent(result, scope); - return result; - } - - /** - * Create an array with a set of initial elements. - * - * @param scope the scope to create the object in. - * @param elements the initial elements. Each object in this array - * must be an acceptable JavaScript type and type - * of array should be exactly Object[], not - * SomeObjectSubclass[]. - * @return the new array object. - */ - public final Scriptable newArray(Scriptable scope, Object[] elements) - { - if (elements.getClass().getComponentType() != ScriptRuntime.ObjectClass) - throw new IllegalArgumentException(); - NativeArray result = new NativeArray(elements); - ScriptRuntime.setObjectProtoAndParent(result, scope); - return result; - } - - /** - * Get the elements of a JavaScript array. - * <p> - * If the object defines a length property convertible to double number, - * then the number is converted Uint32 value as defined in Ecma 9.6 - * and Java array of that size is allocated. - * The array is initialized with the values obtained by - * calling get() on object for each value of i in [0,length-1]. If - * there is not a defined value for a property the Undefined value - * is used to initialize the corresponding element in the array. The - * Java array is then returned. - * If the object doesn't define a length property or it is not a number, - * empty array is returned. - * @param object the JavaScript array or array-like object - * @return a Java array of objects - * @since 1.4 release 2 - */ - public final Object[] getElements(Scriptable object) - { - return ScriptRuntime.getArrayElements(object); - } - - /** - * Convert the value to a JavaScript boolean value. - * <p> - * See ECMA 9.2. - * - * @param value a JavaScript value - * @return the corresponding boolean value converted using - * the ECMA rules - */ - public static boolean toBoolean(Object value) - { - return ScriptRuntime.toBoolean(value); - } - - /** - * Convert the value to a JavaScript Number value. - * <p> - * Returns a Java double for the JavaScript Number. - * <p> - * See ECMA 9.3. - * - * @param value a JavaScript value - * @return the corresponding double value converted using - * the ECMA rules - */ - public static double toNumber(Object value) - { - return ScriptRuntime.toNumber(value); - } - - /** - * Convert the value to a JavaScript String value. - * <p> - * See ECMA 9.8. - * <p> - * @param value a JavaScript value - * @return the corresponding String value converted using - * the ECMA rules - */ - public static String toString(Object value) - { - return ScriptRuntime.toString(value); - } - - /** - * Convert the value to an JavaScript object value. - * <p> - * Note that a scope must be provided to look up the constructors - * for Number, Boolean, and String. - * <p> - * See ECMA 9.9. - * <p> - * Additionally, arbitrary Java objects and classes will be - * wrapped in a Scriptable object with its Java fields and methods - * reflected as JavaScript properties of the object. - * - * @param value any Java object - * @param scope global scope containing constructors for Number, - * Boolean, and String - * @return new JavaScript object - */ - public static Scriptable toObject(Object value, Scriptable scope) - { - return ScriptRuntime.toObject(scope, value); - } - - /** - * @deprecated - * @see #toObject(Object, Scriptable) - */ - public static Scriptable toObject(Object value, Scriptable scope, - Class staticType) - { - return ScriptRuntime.toObject(scope, value); - } - - /** - * Convenient method to convert java value to its closest representation - * in JavaScript. - * <p> - * If value is an instance of String, Number, Boolean, Function or - * Scriptable, it is returned as it and will be treated as the corresponding - * JavaScript type of string, number, boolean, function and object. - * <p> - * Note that for Number instances during any arithmetic operation in - * JavaScript the engine will always use the result of - * <tt>Number.doubleValue()</tt> resulting in a precision loss if - * the number can not fit into double. - * <p> - * If value is an instance of Character, it will be converted to string of - * length 1 and its JavaScript type will be string. - * <p> - * The rest of values will be wrapped as LiveConnect objects - * by calling {@link WrapFactory#wrap(Context cx, Scriptable scope, - * Object obj, Class staticType)} as in: - * <pre> - * Context cx = Context.getCurrentContext(); - * return cx.getWrapFactory().wrap(cx, scope, value, null); - * </pre> - * - * @param value any Java object - * @param scope top scope object - * @return value suitable to pass to any API that takes JavaScript values. - */ - public static Object javaToJS(Object value, Scriptable scope) - { - if (value instanceof String || value instanceof Number - || value instanceof Boolean || value instanceof Scriptable) - { - return value; - } else if (value instanceof Character) { - return String.valueOf(((Character)value).charValue()); - } else { - Context cx = Context.getContext(); - return cx.getWrapFactory().wrap(cx, scope, value, null); - } - } - - /** - * Convert a JavaScript value into the desired type. - * Uses the semantics defined with LiveConnect3 and throws an - * Illegal argument exception if the conversion cannot be performed. - * @param value the JavaScript value to convert - * @param desiredType the Java type to convert to. Primitive Java - * types are represented using the TYPE fields in the corresponding - * wrapper class in java.lang. - * @return the converted value - * @throws EvaluatorException if the conversion cannot be performed - */ - public static Object jsToJava(Object value, Class desiredType) - throws EvaluatorException - { - return NativeJavaObject.coerceTypeImpl(desiredType, value); - } - - /** - * @deprecated - * @see #jsToJava(Object, Class) - * @throws IllegalArgumentException if the conversion cannot be performed. - * Note that {@link #jsToJava(Object, Class)} throws - * {@link EvaluatorException} instead. - */ - public static Object toType(Object value, Class desiredType) - throws IllegalArgumentException - { - try { - return jsToJava(value, desiredType); - } catch (EvaluatorException ex) { - IllegalArgumentException - ex2 = new IllegalArgumentException(ex.getMessage()); - Kit.initCause(ex2, ex); - throw ex2; - } - } - - /** - * Rethrow the exception wrapping it as the script runtime exception. - * Unless the exception is instance of {@link EcmaError} or - * {@link EvaluatorException} it will be wrapped as - * {@link WrappedException}, a subclass of {@link EvaluatorException}. - * The resulting exception object always contains - * source name and line number of script that triggered exception. - * <p> - * This method always throws an exception, its return value is provided - * only for convenience to allow a usage like: - * <pre> - * throw Context.throwAsScriptRuntimeEx(ex); - * </pre> - * to indicate that code after the method is unreachable. - * @throws EvaluatorException - * @throws EcmaError - */ - public static RuntimeException throwAsScriptRuntimeEx(Throwable e) - { - while ((e instanceof InvocationTargetException)) { - e = ((InvocationTargetException) e).getTargetException(); - } - // special handling of Error so scripts would not catch them - if (e instanceof Error) { - Context cx = getContext(); - if (cx == null || - !cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS)) - { - throw (Error)e; - } - } - if (e instanceof RhinoException) { - throw (RhinoException)e; - } - throw new WrappedException(e); - } - - /** - * Tell whether debug information is being generated. - * @since 1.3 - */ - public final boolean isGeneratingDebug() - { - return generatingDebug; - } - - /** - * Specify whether or not debug information should be generated. - * <p> - * Setting the generation of debug information on will set the - * optimization level to zero. - * @since 1.3 - */ - public final void setGeneratingDebug(boolean generatingDebug) - { - if (sealed) onSealedMutation(); - generatingDebugChanged = true; - if (generatingDebug && getOptimizationLevel() > 0) - setOptimizationLevel(0); - this.generatingDebug = generatingDebug; - } - - /** - * Tell whether source information is being generated. - * @since 1.3 - */ - public final boolean isGeneratingSource() - { - return generatingSource; - } - - /** - * Specify whether or not source information should be generated. - * <p> - * Without source information, evaluating the "toString" method - * on JavaScript functions produces only "[native code]" for - * the body of the function. - * Note that code generated without source is not fully ECMA - * conformant. - * @since 1.3 - */ - public final void setGeneratingSource(boolean generatingSource) - { - if (sealed) onSealedMutation(); - this.generatingSource = generatingSource; - } - - /** - * Get the current optimization level. - * <p> - * The optimization level is expressed as an integer between -1 and - * 9. - * @since 1.3 - * - */ - public final int getOptimizationLevel() - { - return optimizationLevel; - } - - /** - * Set the current optimization level. - * <p> - * The optimization level is expected to be an integer between -1 and - * 9. Any negative values will be interpreted as -1, and any values - * greater than 9 will be interpreted as 9. - * An optimization level of -1 indicates that interpretive mode will - * always be used. Levels 0 through 9 indicate that class files may - * be generated. Higher optimization levels trade off compile time - * performance for runtime performance. - * The optimizer level can't be set greater than -1 if the optimizer - * package doesn't exist at run time. - * @param optimizationLevel an integer indicating the level of - * optimization to perform - * @since 1.3 - * - */ - public final void setOptimizationLevel(int optimizationLevel) - { - if (sealed) onSealedMutation(); - if (optimizationLevel == -2) { - // To be compatible with Cocoon fork - optimizationLevel = -1; - } - checkOptimizationLevel(optimizationLevel); - if (codegenClass == null) - optimizationLevel = -1; - this.optimizationLevel = optimizationLevel; - } - - public static boolean isValidOptimizationLevel(int optimizationLevel) - { - return -1 <= optimizationLevel && optimizationLevel <= 9; - } - - public static void checkOptimizationLevel(int optimizationLevel) - { - if (isValidOptimizationLevel(optimizationLevel)) { - return; - } - throw new IllegalArgumentException( - "Optimization level outside [-1..9]: "+optimizationLevel); - } - - /** - * Returns the maximum stack depth (in terms of number of call frames) - * allowed in a single invocation of interpreter. If the set depth would be - * exceeded, the interpreter will throw an EvaluatorException in the script. - * Defaults to Integer.MAX_VALUE. The setting only has effect for - * interpreted functions (those compiled with optimization level set to -1). - * As the interpreter doesn't use the Java stack but rather manages its own - * stack in the heap memory, a runaway recursion in interpreted code would - * eventually consume all available memory and cause OutOfMemoryError - * instead of a StackOverflowError limited to only a single thread. This - * setting helps prevent such situations. - * - * @return The current maximum interpreter stack depth. - */ - public final int getMaximumInterpreterStackDepth() - { - return maximumInterpreterStackDepth; - } - - /** - * Sets the maximum stack depth (in terms of number of call frames) - * allowed in a single invocation of interpreter. If the set depth would be - * exceeded, the interpreter will throw an EvaluatorException in the script. - * Defaults to Integer.MAX_VALUE. The setting only has effect for - * interpreted functions (those compiled with optimization level set to -1). - * As the interpreter doesn't use the Java stack but rather manages its own - * stack in the heap memory, a runaway recursion in interpreted code would - * eventually consume all available memory and cause OutOfMemoryError - * instead of a StackOverflowError limited to only a single thread. This - * setting helps prevent such situations. - * - * @param max the new maximum interpreter stack depth - * @throws IllegalStateException if this context's optimization level is not - * -1 - * @throws IllegalArgumentException if the new depth is not at least 1 - */ - public final void setMaximumInterpreterStackDepth(int max) - { - if(sealed) onSealedMutation(); - if(optimizationLevel != -1) { - throw new IllegalStateException("Cannot set maximumInterpreterStackDepth when optimizationLevel != -1"); - } - if(max < 1) { - throw new IllegalArgumentException("Cannot set maximumInterpreterStackDepth to less than 1"); - } - maximumInterpreterStackDepth = max; - } - - /** - * Set the security controller for this context. - * <p> SecurityController may only be set if it is currently null - * and {@link SecurityController#hasGlobal()} is <tt>false</tt>. - * Otherwise a SecurityException is thrown. - * @param controller a SecurityController object - * @throws SecurityException if there is already a SecurityController - * object for this Context or globally installed. - * @see SecurityController#initGlobal(SecurityController controller) - * @see SecurityController#hasGlobal() - */ - public final void setSecurityController(SecurityController controller) - { - if (sealed) onSealedMutation(); - if (controller == null) throw new IllegalArgumentException(); - if (securityController != null) { - throw new SecurityException("Can not overwrite existing SecurityController object"); - } - if (SecurityController.hasGlobal()) { - throw new SecurityException("Can not overwrite existing global SecurityController object"); - } - securityController = controller; - } - - /** - * Set the LiveConnect access filter for this context. - * <p> {@link ClassShutter} may only be set if it is currently null. - * Otherwise a SecurityException is thrown. - * @param shutter a ClassShutter object - * @throws SecurityException if there is already a ClassShutter - * object for this Context - */ - public final void setClassShutter(ClassShutter shutter) - { - if (sealed) onSealedMutation(); - if (shutter == null) throw new IllegalArgumentException(); - if (classShutter != null) { - throw new SecurityException("Cannot overwrite existing " + - "ClassShutter object"); - } - classShutter = shutter; - } - - final ClassShutter getClassShutter() - { - return classShutter; - } - - /** - * Get a value corresponding to a key. - * <p> - * Since the Context is associated with a thread it can be - * used to maintain values that can be later retrieved using - * the current thread. - * <p> - * Note that the values are maintained with the Context, so - * if the Context is disassociated from the thread the values - * cannot be retrieved. Also, if private data is to be maintained - * in this manner the key should be a java.lang.Object - * whose reference is not divulged to untrusted code. - * @param key the key used to lookup the value - * @return a value previously stored using putThreadLocal. - */ - public final Object getThreadLocal(Object key) - { - if (hashtable == null) - return null; - return hashtable.get(key); - } - - /** - * Put a value that can later be retrieved using a given key. - * <p> - * @param key the key used to index the value - * @param value the value to save - */ - public final void putThreadLocal(Object key, Object value) - { - if (sealed) onSealedMutation(); - if (hashtable == null) - hashtable = new Hashtable(); - hashtable.put(key, value); - } - - /** - * Remove values from thread-local storage. - * @param key the key for the entry to remove. - * @since 1.5 release 2 - */ - public final void removeThreadLocal(Object key) - { - if (sealed) onSealedMutation(); - if (hashtable == null) - return; - hashtable.remove(key); - } - - /** - * @deprecated - * @see #FEATURE_DYNAMIC_SCOPE - * @see #hasFeature(int) - */ - public final boolean hasCompileFunctionsWithDynamicScope() - { - return compileFunctionsWithDynamicScopeFlag; - } - - /** - * @deprecated - * @see #FEATURE_DYNAMIC_SCOPE - * @see #hasFeature(int) - */ - public final void setCompileFunctionsWithDynamicScope(boolean flag) - { - if (sealed) onSealedMutation(); - compileFunctionsWithDynamicScopeFlag = flag; - } - - /** - * @deprecated - * @see ClassCache#get(Scriptable) - * @see ClassCache#setCachingEnabled(boolean) - */ - public static void setCachingEnabled(boolean cachingEnabled) - { - } - - /** - * Set a WrapFactory for this Context. - * <p> - * The WrapFactory allows custom object wrapping behavior for - * Java object manipulated with JavaScript. - * @see WrapFactory - * @since 1.5 Release 4 - */ - public final void setWrapFactory(WrapFactory wrapFactory) - { - if (sealed) onSealedMutation(); - if (wrapFactory == null) throw new IllegalArgumentException(); - this.wrapFactory = wrapFactory; - } - - /** - * Return the current WrapFactory, or null if none is defined. - * @see WrapFactory - * @since 1.5 Release 4 - */ - public final WrapFactory getWrapFactory() - { - if (wrapFactory == null) { - wrapFactory = new WrapFactory(); - } - return wrapFactory; - } - - /** - * Return the current debugger. - * @return the debugger, or null if none is attached. - */ - public final Debugger getDebugger() - { - return debugger; - } - - /** - * Return the debugger context data associated with current context. - * @return the debugger data, or null if debugger is not attached - */ - public final Object getDebuggerContextData() - { - return debuggerData; - } - - /** - * Set the associated debugger. - * @param debugger the debugger to be used on callbacks from - * the engine. - * @param contextData arbitrary object that debugger can use to store - * per Context data. - */ - public final void setDebugger(Debugger debugger, Object contextData) - { - if (sealed) onSealedMutation(); - this.debugger = debugger; - debuggerData = contextData; - } - - /** - * Return DebuggableScript instance if any associated with the script. - * If callable supports DebuggableScript implementation, the method - * returns it. Otherwise null is returned. - */ - public static DebuggableScript getDebuggableView(Script script) - { - if (script instanceof NativeFunction) { - return ((NativeFunction)script).getDebuggableView(); - } - return null; - } - - /** - * Controls certain aspects of script semantics. - * Should be overwritten to alter default behavior. - * <p> - * The default implementation calls - * {@link ContextFactory#hasFeature(Context cx, int featureIndex)} - * that allows to customize Context behavior without introducing - * Context subclasses. {@link ContextFactory} documentation gives - * an example of hasFeature implementation. - * - * @param featureIndex feature index to check - * @return true if the <code>featureIndex</code> feature is turned on - * @see #FEATURE_NON_ECMA_GET_YEAR - * @see #FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME - * @see #FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER - * @see #FEATURE_TO_STRING_AS_SOURCE - * @see #FEATURE_PARENT_PROTO_PROPRTIES - * @see #FEATURE_E4X - * @see #FEATURE_DYNAMIC_SCOPE - * @see #FEATURE_STRICT_VARS - * @see #FEATURE_STRICT_EVAL - * @see #FEATURE_LOCATION_INFORMATION_IN_ERROR - * @see #FEATURE_STRICT_MODE - * @see #FEATURE_WARNING_AS_ERROR - * @see #FEATURE_ENHANCED_JAVA_ACCESS - */ - public boolean hasFeature(int featureIndex) - { - ContextFactory f = getFactory(); - return f.hasFeature(this, featureIndex); - } - - /** - Returns an object which specifies an E4X implementation to use within - this <code>Context</code>. Note - that the XMLLib.Factory interface should be considered experimental. - - The default implementation uses the implementation provided by this - <code>Context</code>'s {@link ContextFactory}. - - @return An XMLLib.Factory. Should not return <code>null</code> if - {@link #FEATURE_E4X} is enabled. See {@link #hasFeature}. - */ - public XMLLib.Factory getE4xImplementationFactory() { - return getFactory().getE4xImplementationFactory(); - } - - /** - * Get threshold of executed instructions counter that triggers call to - * <code>observeInstructionCount()</code>. - * When the threshold is zero, instruction counting is disabled, - * otherwise each time the run-time executes at least the threshold value - * of script instructions, <code>observeInstructionCount()</code> will - * be called. - */ - public final int getInstructionObserverThreshold() - { - return instructionThreshold; - } - - /** - * Set threshold of executed instructions counter that triggers call to - * <code>observeInstructionCount()</code>. - * When the threshold is zero, instruction counting is disabled, - * otherwise each time the run-time executes at least the threshold value - * of script instructions, <code>observeInstructionCount()</code> will - * be called.<p/> - * Note that the meaning of "instruction" is not guaranteed to be - * consistent between compiled and interpretive modes: executing a given - * script or function in the different modes will result in different - * instruction counts against the threshold. - * {@link #setGenerateObserverCount} is called with true if - * <code>threshold</code> is greater than zero, false otherwise. - * @param threshold The instruction threshold - */ - public final void setInstructionObserverThreshold(int threshold) - { - if (sealed) onSealedMutation(); - if (threshold < 0) throw new IllegalArgumentException(); - instructionThreshold = threshold; - setGenerateObserverCount(threshold > 0); - } - - /** - * Turn on or off generation of code with callbacks to - * track the count of executed instructions. - * Currently only affects JVM byte code generation: this slows down the - * generated code, but code generated without the callbacks will not - * be counted toward instruction thresholds. Rhino's interpretive - * mode does instruction counting without inserting callbacks, so - * there is no requirement to compile code differently. - * @param generateObserverCount if true, generated code will contain - * calls to accumulate an estimate of the instructions executed. - */ - public void setGenerateObserverCount(boolean generateObserverCount) { - this.generateObserverCount = generateObserverCount; - } - - /** - * Allow application to monitor counter of executed script instructions - * in Context subclasses. - * Run-time calls this when instruction counting is enabled and the counter - * reaches limit set by <code>setInstructionObserverThreshold()</code>. - * The method is useful to observe long running scripts and if necessary - * to terminate them. - * <p> - * The instruction counting support is available only for interpreted - * scripts generated when the optimization level is set to -1. - * <p> - * The default implementation calls - * {@link ContextFactory#observeInstructionCount(Context cx, - * int instructionCount)} - * that allows to customize Context behavior without introducing - * Context subclasses. - * - * @param instructionCount amount of script instruction executed since - * last call to <code>observeInstructionCount</code> - * @throws Error to terminate the script - * @see #setOptimizationLevel(int) - */ - protected void observeInstructionCount(int instructionCount) - { - ContextFactory f = getFactory(); - f.observeInstructionCount(this, instructionCount); - } - - /** - * Create class loader for generated classes. - * The method calls {@link ContextFactory#createClassLoader(ClassLoader)} - * using the result of {@link #getFactory()}. - */ - public GeneratedClassLoader createClassLoader(ClassLoader parent) - { - ContextFactory f = getFactory(); - return f.createClassLoader(parent); - } - - public final ClassLoader getApplicationClassLoader() - { - if (applicationClassLoader == null) { - ContextFactory f = getFactory(); - ClassLoader loader = f.getApplicationClassLoader(); - if (loader == null) { - ClassLoader threadLoader - = VMBridge.instance.getCurrentThreadClassLoader(); - if (threadLoader != null - && Kit.testIfCanLoadRhinoClasses(threadLoader)) - { - // Thread.getContextClassLoader is not cached since - // its caching prevents it from GC which may lead to - // a memory leak and hides updates to - // Thread.getContextClassLoader - return threadLoader; - } - // Thread.getContextClassLoader can not load Rhino classes, - // try to use the loader of ContextFactory or Context - // subclasses. - Class fClass = f.getClass(); - if (fClass != ScriptRuntime.ContextFactoryClass) { - loader = fClass.getClassLoader(); - } else { - loader = getClass().getClassLoader(); - } - } - applicationClassLoader = loader; - } - return applicationClassLoader; - } - - public final void setApplicationClassLoader(ClassLoader loader) - { - if (sealed) onSealedMutation(); - if (loader == null) { - // restore default behaviour - applicationClassLoader = null; - return; - } - if (!Kit.testIfCanLoadRhinoClasses(loader)) { - throw new IllegalArgumentException( - "Loader can not resolve Rhino classes"); - } - applicationClassLoader = loader; - } - - /********** end of API **********/ - - /** - * Internal method that reports an error for missing calls to - * enter(). - */ - static Context getContext() - { - Context cx = getCurrentContext(); - if (cx == null) { - throw new RuntimeException( - "No Context associated with current Thread"); - } - return cx; - } - - private Object compileImpl(Scriptable scope, - Reader sourceReader, String sourceString, - String sourceName, int lineno, - Object securityDomain, boolean returnFunction, - Evaluator compiler, - ErrorReporter compilationErrorReporter) - throws IOException - { - if(sourceName == null) { - sourceName = "unnamed script"; - } - if (securityDomain != null && getSecurityController() == null) { - throw new IllegalArgumentException( - "securityDomain should be null if setSecurityController() was never called"); - } - - // One of sourceReader or sourceString has to be null - if (!(sourceReader == null ^ sourceString == null)) Kit.codeBug(); - // scope should be given if and only if compiling function - if (!(scope == null ^ returnFunction)) Kit.codeBug(); - - CompilerEnvirons compilerEnv = new CompilerEnvirons(); - compilerEnv.initFromContext(this); - if (compilationErrorReporter == null) { - compilationErrorReporter = compilerEnv.getErrorReporter(); - } - - if (debugger != null) { - if (sourceReader != null) { - sourceString = Kit.readReader(sourceReader); - sourceReader = null; - } - } - - /*APPJET*/ - Parser p = InformativeParser.makeParser(compilerEnv, - compilationErrorReporter); - if (returnFunction) { - p.calledByCompileFunction = true; - } - ScriptOrFnNode tree; - if (sourceString != null) { - tree = p.parse(sourceString, sourceName, lineno); - } else { - tree = p.parse(sourceReader, sourceName, lineno); - } - if (returnFunction) { - if (!(tree.getFunctionCount() == 1 - && tree.getFirstChild() != null - && tree.getFirstChild().getType() == Token.FUNCTION)) - { - // XXX: the check just look for the first child - // and allows for more nodes after it for compatibility - // with sources like function() {};;; - throw new IllegalArgumentException( - "compileFunction only accepts source with single JS function: "+sourceString); - } - } - - if (compiler == null) { - compiler = createCompiler(); - } - - String encodedSource = p.getEncodedSource(); - - Object bytecode = compiler.compile(compilerEnv, - tree, encodedSource, - returnFunction); - - if (debugger != null) { - if (sourceString == null) Kit.codeBug(); - 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"); - private static Class interpreterClass = Kit.classOrNull( - "org.mozilla.javascript.Interpreter"); - - private Evaluator createCompiler() - { - Evaluator result = null; - if (optimizationLevel >= 0 && codegenClass != null) { - result = (Evaluator)Kit.newInstanceOrNull(codegenClass); - } - if (result == null) { - result = createInterpreter(); - } - return result; - } - - static Evaluator createInterpreter() - { - return (Evaluator)Kit.newInstanceOrNull(interpreterClass); - } - - static String getSourcePositionFromStack(int[] linep) - { - Context cx = getCurrentContext(); - if (cx == null) - return null; - if (cx.lastInterpreterFrame != null) { - Evaluator evaluator = createInterpreter(); - if (evaluator != null) - return evaluator.getSourcePositionFromStack(cx, linep); - } - /** - * A bit of a hack, but the only way to get filename and line - * number from an enclosing frame. - */ - CharArrayWriter writer = new CharArrayWriter(); - RuntimeException re = new RuntimeException(); - re.printStackTrace(new PrintWriter(writer)); - String s = writer.toString(); - int open = -1; - int close = -1; - int colon = -1; - for (int i=0; i < s.length(); i++) { - char c = s.charAt(i); - if (c == ':') - colon = i; - else if (c == '(') - open = i; - else if (c == ')') - close = i; - else if (c == '\n' && open != -1 && close != -1 && colon != -1 && - open < colon && colon < close) - { - String fileStr = s.substring(open + 1, colon); - if (!fileStr.endsWith(".java")) { - String lineStr = s.substring(colon + 1, close); - try { - linep[0] = Integer.parseInt(lineStr); - if (linep[0] < 0) { - linep[0] = 0; - } - return fileStr; - } - catch (NumberFormatException e) { - // fall through - } - } - open = close = colon = -1; - } - } - - return null; - } - - RegExpProxy getRegExpProxy() - { - if (regExpProxy == null) { - Class cl = Kit.classOrNull( - "org.mozilla.javascript.regexp.RegExpImpl"); - if (cl != null) { - regExpProxy = (RegExpProxy)Kit.newInstanceOrNull(cl); - } - } - return regExpProxy; - } - - final boolean isVersionECMA1() - { - return version == VERSION_DEFAULT || version >= VERSION_1_3; - } - -// The method must NOT be public or protected - SecurityController getSecurityController() - { - SecurityController global = SecurityController.global(); - if (global != null) { - return global; - } - return securityController; - } - - public final boolean isGeneratingDebugChanged() - { - return generatingDebugChanged; - } - - /** - * Add a name to the list of names forcing the creation of real - * activation objects for functions. - * - * @param name the name of the object to add to the list - */ - public void addActivationName(String name) - { - if (sealed) onSealedMutation(); - if (activationNames == null) - activationNames = new Hashtable(5); - activationNames.put(name, name); - } - - /** - * Check whether the name is in the list of names of objects - * forcing the creation of activation objects. - * - * @param name the name of the object to test - * - * @return true if an function activation object is needed. - */ - public final boolean isActivationNeeded(String name) - { - return activationNames != null && activationNames.containsKey(name); - } - - /** - * Remove a name from the list of names forcing the creation of real - * activation objects for functions. - * - * @param name the name of the object to remove from the list - */ - public void removeActivationName(String name) - { - if (sealed) onSealedMutation(); - if (activationNames != null) - activationNames.remove(name); - } - - private static String implementationVersion; - - private final ContextFactory factory; - private boolean sealed; - private Object sealKey; - - Scriptable topCallScope; - NativeCall currentActivationCall; - XMLLib cachedXMLLib; - - // for Objects, Arrays to tag themselves as being printed out, - // so they don't print themselves out recursively. - // Use ObjToIntMap instead of java.util.HashSet for JDK 1.1 compatibility - ObjToIntMap iterating; - - Object interpreterSecurityDomain; - - int version; - - private SecurityController securityController; - private ClassShutter classShutter; - private ErrorReporter errorReporter; - RegExpProxy regExpProxy; - private Locale locale; - private boolean generatingDebug; - private boolean generatingDebugChanged; - private boolean generatingSource=true; - boolean compileFunctionsWithDynamicScopeFlag; - boolean useDynamicScope; - private int optimizationLevel; - private int maximumInterpreterStackDepth; - private WrapFactory wrapFactory; - Debugger debugger; - private Object debuggerData; - private int enterCount; - private Object propertyListeners; - private Hashtable hashtable; - private ClassLoader applicationClassLoader; - - /** - * This is the list of names of objects forcing the creation of - * function activation records. - */ - Hashtable activationNames; - - // For the interpreter to store the last frame for error reports etc. - Object lastInterpreterFrame; - - // For the interpreter to store information about previous invocations - // interpreter invocations - ObjArray previousInterpreterInvocations; - - // For instruction counting (interpreter only) - int instructionCount; - int instructionThreshold; - - // It can be used to return the second index-like result from function - int scratchIndex; - - // It can be used to return the second uint32 result from function - long scratchUint32; - - // It can be used to return the second Scriptable result from function - Scriptable scratchScriptable; - - // Generate an observer count on compiled code - public boolean generateObserverCount = false; -} |