001: /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
002: *
003: * ***** BEGIN LICENSE BLOCK *****
004: * Version: MPL 1.1/GPL 2.0
005: *
006: * The contents of this file are subject to the Mozilla Public License Version
007: * 1.1 (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: * http://www.mozilla.org/MPL/
010: *
011: * Software distributed under the License is distributed on an "AS IS" basis,
012: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013: * for the specific language governing rights and limitations under the
014: * License.
015: *
016: * The Original Code is Rhino code, released
017: * May 6, 1999.
018: *
019: * The Initial Developer of the Original Code is
020: * Netscape Communications Corporation.
021: * Portions created by the Initial Developer are Copyright (C) 1997-1999
022: * the Initial Developer. All Rights Reserved.
023: *
024: * Contributor(s):
025: * Norris Boyd
026: * Igor Bukanov
027: * Roger Lawrence
028: * Mike McCabe
029: *
030: * Alternatively, the contents of this file may be used under the terms of
031: * the GNU General Public License Version 2 or later (the "GPL"), in which
032: * case the provisions of the GPL are applicable instead of those above. If
033: * you wish to allow use of your version of this file only under the terms of
034: * the GPL and not to allow others to use your version of this file under the
035: * MPL, indicate your decision by deleting the provisions above and replacing
036: * them with the notice and other provisions required by the GPL. If you do
037: * not delete the provisions above, a recipient may use your version of this
038: * file under either the MPL or the GPL.
039: *
040: * ***** END LICENSE BLOCK ***** */
041:
042: package org.mozilla.javascript;
043:
044: /**
045: * The JavaScript Script object.
046: *
047: * Note that the C version of the engine uses XDR as the format used
048: * by freeze and thaw. Since this depends on the internal format of
049: * structures in the C runtime, we cannot duplicate it.
050: *
051: * Since we cannot replace 'this' as a result of the compile method,
052: * will forward requests to execute to the nonnull 'script' field.
053: *
054: * @since 1.3
055: * @author Norris Boyd
056: */
057:
058: class NativeScript extends BaseFunction {
059: static final long serialVersionUID = -6795101161980121700L;
060:
061: private static final Object SCRIPT_TAG = new Object();
062:
063: static void init(Scriptable scope, boolean sealed) {
064: NativeScript obj = new NativeScript(null);
065: obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
066: }
067:
068: private NativeScript(Script script) {
069: this .script = script;
070: }
071:
072: /**
073: * Returns the name of this JavaScript class, "Script".
074: */
075: public String getClassName() {
076: return "Script";
077: }
078:
079: public Object call(Context cx, Scriptable scope,
080: Scriptable this Obj, Object[] args) {
081: if (script != null) {
082: return script.exec(cx, scope);
083: }
084: return Undefined.instance;
085: }
086:
087: public Scriptable construct(Context cx, Scriptable scope,
088: Object[] args) {
089: throw Context
090: .reportRuntimeError0("msg.script.is.not.constructor");
091: }
092:
093: public int getLength() {
094: return 0;
095: }
096:
097: public int getArity() {
098: return 0;
099: }
100:
101: String decompile(int indent, int flags) {
102: if (script instanceof NativeFunction) {
103: return ((NativeFunction) script).decompile(indent, flags);
104: }
105: return super .decompile(indent, flags);
106: }
107:
108: protected void initPrototypeId(int id) {
109: String s;
110: int arity;
111: switch (id) {
112: case Id_constructor:
113: arity = 1;
114: s = "constructor";
115: break;
116: case Id_toString:
117: arity = 0;
118: s = "toString";
119: break;
120: case Id_exec:
121: arity = 0;
122: s = "exec";
123: break;
124: case Id_compile:
125: arity = 1;
126: s = "compile";
127: break;
128: default:
129: throw new IllegalArgumentException(String.valueOf(id));
130: }
131: initPrototypeMethod(SCRIPT_TAG, id, s, arity);
132: }
133:
134: public Object execIdCall(IdFunctionObject f, Context cx,
135: Scriptable scope, Scriptable this Obj, Object[] args) {
136: if (!f.hasTag(SCRIPT_TAG)) {
137: return super .execIdCall(f, cx, scope, this Obj, args);
138: }
139: int id = f.methodId();
140: switch (id) {
141: case Id_constructor: {
142: String source = (args.length == 0) ? "" : ScriptRuntime
143: .toString(args[0]);
144: Script script = compile(cx, source);
145: NativeScript nscript = new NativeScript(script);
146: ScriptRuntime.setObjectProtoAndParent(nscript, scope);
147: return nscript;
148: }
149:
150: case Id_toString: {
151: NativeScript real = realThis(this Obj, f);
152: Script realScript = real.script;
153: if (realScript == null) {
154: return "";
155: }
156: return cx.decompileScript(realScript, 0);
157: }
158:
159: case Id_exec: {
160: throw Context.reportRuntimeError1("msg.cant.call.indirect",
161: "exec");
162: }
163:
164: case Id_compile: {
165: NativeScript real = realThis(this Obj, f);
166: String source = ScriptRuntime.toString(args, 0);
167: real.script = compile(cx, source);
168: return real;
169: }
170: }
171: throw new IllegalArgumentException(String.valueOf(id));
172: }
173:
174: private static NativeScript realThis(Scriptable this Obj,
175: IdFunctionObject f) {
176: if (!(this Obj instanceof NativeScript))
177: throw incompatibleCallError(f);
178: return (NativeScript) this Obj;
179: }
180:
181: private static Script compile(Context cx, String source) {
182: int[] linep = { 0 };
183: String filename = Context.getSourcePositionFromStack(linep);
184: if (filename == null) {
185: filename = "<Script object>";
186: linep[0] = 1;
187: }
188: ErrorReporter reporter;
189: reporter = DefaultErrorReporter.forEval(cx.getErrorReporter());
190: return cx.compileString(source, null, reporter, filename,
191: linep[0], null);
192: }
193:
194: // #string_id_map#
195:
196: protected int findPrototypeId(String s) {
197: int id;
198: // #generated# Last update: 2007-05-09 08:16:01 EDT
199: L0: {
200: id = 0;
201: String X = null;
202: L: switch (s.length()) {
203: case 4:
204: X = "exec";
205: id = Id_exec;
206: break L;
207: case 7:
208: X = "compile";
209: id = Id_compile;
210: break L;
211: case 8:
212: X = "toString";
213: id = Id_toString;
214: break L;
215: case 11:
216: X = "constructor";
217: id = Id_constructor;
218: break L;
219: }
220: if (X != null && X != s && !X.equals(s))
221: id = 0;
222: break L0;
223: }
224: // #/generated#
225: return id;
226: }
227:
228: private static final int Id_constructor = 1, Id_toString = 2,
229: Id_compile = 3, Id_exec = 4, MAX_PROTOTYPE_ID = 4;
230:
231: // #/string_id_map#
232:
233: private Script script;
234: }
|