001: /* ***** BEGIN LICENSE BLOCK *****
002: * Version: MPL 1.1/GPL 2.0
003: *
004: * The contents of this file are subject to the Mozilla Public License Version
005: * 1.1 (the "License"); you may not use this file except in compliance with
006: * the License. You may obtain a copy of the License at
007: * http://www.mozilla.org/MPL/
008: *
009: * Software distributed under the License is distributed on an "AS IS" basis,
010: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011: * for the specific language governing rights and limitations under the
012: * License.
013: *
014: * The Original Code is Rhino code, released
015: * May 6, 1999.
016: *
017: * The Initial Developer of the Original Code is
018: * Netscape Communications Corporation.
019: * Portions created by the Initial Developer are Copyright (C) 1997-2000
020: * the Initial Developer. All Rights Reserved.
021: *
022: * Contributor(s):
023: * Norris Boyd
024: * Roger Lawrence
025: * Hannes Wallnoefer
026: *
027: * Alternatively, the contents of this file may be used under the terms of
028: * the GNU General Public License Version 2 or later (the "GPL"), in which
029: * case the provisions of the GPL are applicable instead of those above. If
030: * you wish to allow use of your version of this file only under the terms of
031: * the GPL and not to allow others to use your version of this file under the
032: * MPL, indicate your decision by deleting the provisions above and replacing
033: * them with the notice and other provisions required by the GPL. If you do
034: * not delete the provisions above, a recipient may use your version of this
035: * file under either the MPL or the GPL.
036: *
037: * ***** END LICENSE BLOCK ***** */
038:
039: package org.mozilla.javascript.optimizer;
040:
041: import org.mozilla.javascript.*;
042:
043: public final class OptRuntime extends ScriptRuntime {
044:
045: public static final Double zeroObj = new Double(0.0);
046: public static final Double oneObj = new Double(1.0);
047: public static final Double minusOneObj = new Double(-1.0);
048:
049: /**
050: * Implement ....() call shrinking optimizer code.
051: */
052: public static Object call0(Callable fun, Scriptable this Obj,
053: Context cx, Scriptable scope) {
054: return fun.call(cx, scope, this Obj, ScriptRuntime.emptyArgs);
055: }
056:
057: /**
058: * Implement ....(arg) call shrinking optimizer code.
059: */
060: public static Object call1(Callable fun, Scriptable this Obj,
061: Object arg0, Context cx, Scriptable scope) {
062: return fun.call(cx, scope, this Obj, new Object[] { arg0 });
063: }
064:
065: /**
066: * Implement ....(arg0, arg1) call shrinking optimizer code.
067: */
068: public static Object call2(Callable fun, Scriptable this Obj,
069: Object arg0, Object arg1, Context cx, Scriptable scope) {
070: return fun
071: .call(cx, scope, this Obj, new Object[] { arg0, arg1 });
072: }
073:
074: /**
075: * Implement ....(arg0, arg1, ...) call shrinking optimizer code.
076: */
077: public static Object callN(Callable fun, Scriptable this Obj,
078: Object[] args, Context cx, Scriptable scope) {
079: return fun.call(cx, scope, this Obj, args);
080: }
081:
082: /**
083: * Implement name(args) call shrinking optimizer code.
084: */
085: public static Object callName(Object[] args, String name,
086: Context cx, Scriptable scope) {
087: Callable f = getNameFunctionAndThis(name, cx, scope);
088: Scriptable this Obj = lastStoredScriptable(cx);
089: return f.call(cx, scope, this Obj, args);
090: }
091:
092: /**
093: * Implement name() call shrinking optimizer code.
094: */
095: public static Object callName0(String name, Context cx,
096: Scriptable scope) {
097: Callable f = getNameFunctionAndThis(name, cx, scope);
098: Scriptable this Obj = lastStoredScriptable(cx);
099: return f.call(cx, scope, this Obj, ScriptRuntime.emptyArgs);
100: }
101:
102: /**
103: * Implement x.property() call shrinking optimizer code.
104: */
105: public static Object callProp0(Object value, String property,
106: Context cx, Scriptable scope) {
107: Callable f = getPropFunctionAndThis(value, property, cx);
108: Scriptable this Obj = lastStoredScriptable(cx);
109: return f.call(cx, scope, this Obj, ScriptRuntime.emptyArgs);
110: }
111:
112: public static Object add(Object val1, double val2) {
113: if (val1 instanceof Scriptable)
114: val1 = ((Scriptable) val1).getDefaultValue(null);
115: if (!(val1 instanceof String))
116: return wrapDouble(toNumber(val1) + val2);
117: return ((String) val1).concat(toString(val2));
118: }
119:
120: public static Object add(double val1, Object val2) {
121: if (val2 instanceof Scriptable)
122: val2 = ((Scriptable) val2).getDefaultValue(null);
123: if (!(val2 instanceof String))
124: return wrapDouble(toNumber(val2) + val1);
125: return toString(val1).concat((String) val2);
126: }
127:
128: public static Object elemIncrDecr(Object obj, double index,
129: Context cx, int incrDecrMask) {
130: return ScriptRuntime.elemIncrDecr(obj, new Double(index), cx,
131: incrDecrMask);
132: }
133:
134: public static Object[] padStart(Object[] currentArgs, int count) {
135: Object[] result = new Object[currentArgs.length + count];
136: System.arraycopy(currentArgs, 0, result, count,
137: currentArgs.length);
138: return result;
139: }
140:
141: public static void initFunction(NativeFunction fn,
142: int functionType, Scriptable scope, Context cx) {
143: ScriptRuntime.initFunction(cx, scope, fn, functionType, false);
144: }
145:
146: public static Object callSpecial(Context cx, Callable fun,
147: Scriptable this Obj, Object[] args, Scriptable scope,
148: Scriptable callerThis, int callType, String fileName,
149: int lineNumber) {
150: return ScriptRuntime.callSpecial(cx, fun, this Obj, args, scope,
151: callerThis, callType, fileName, lineNumber);
152: }
153:
154: public static Object newObjectSpecial(Context cx, Object fun,
155: Object[] args, Scriptable scope, Scriptable callerThis,
156: int callType) {
157: return ScriptRuntime.newSpecial(cx, fun, args, scope, callType);
158: }
159:
160: public static Double wrapDouble(double num) {
161: if (num == 0.0) {
162: if (1 / num > 0) {
163: // +0.0
164: return zeroObj;
165: }
166: } else if (num == 1.0) {
167: return oneObj;
168: } else if (num == -1.0) {
169: return minusOneObj;
170: } else if (num != num) {
171: return NaNobj;
172: }
173: return new Double(num);
174: }
175:
176: static String encodeIntArray(int[] array) {
177: // XXX: this extremely inefficient for small integers
178: if (array == null) {
179: return null;
180: }
181: int n = array.length;
182: char[] buffer = new char[1 + n * 2];
183: buffer[0] = 1;
184: for (int i = 0; i != n; ++i) {
185: int value = array[i];
186: int shift = 1 + i * 2;
187: buffer[shift] = (char) (value >>> 16);
188: buffer[shift + 1] = (char) value;
189: }
190: return new String(buffer);
191: }
192:
193: private static int[] decodeIntArray(String str, int arraySize) {
194: // XXX: this extremely inefficient for small integers
195: if (arraySize == 0) {
196: if (str != null)
197: throw new IllegalArgumentException();
198: return null;
199: }
200: if (str.length() != 1 + arraySize * 2 && str.charAt(0) != 1) {
201: throw new IllegalArgumentException();
202: }
203: int[] array = new int[arraySize];
204: for (int i = 0; i != arraySize; ++i) {
205: int shift = 1 + i * 2;
206: array[i] = (str.charAt(shift) << 16)
207: | str.charAt(shift + 1);
208: }
209: return array;
210: }
211:
212: public static Scriptable newArrayLiteral(Object[] objects,
213: String encodedInts, int skipCount, Context cx,
214: Scriptable scope) {
215: int[] skipIndexces = decodeIntArray(encodedInts, skipCount);
216: return newArrayLiteral(objects, skipIndexces, cx, scope);
217: }
218:
219: public static void main(final Script script, final String[] args) {
220: Context.call(new ContextAction() {
221: public Object run(Context cx) {
222: ScriptableObject global = getGlobal(cx);
223:
224: // get the command line arguments and define "arguments"
225: // array in the top-level object
226: Object[] argsCopy = new Object[args.length];
227: System.arraycopy(args, 0, argsCopy, 0, args.length);
228: Scriptable argsObj = cx.newArray(global, argsCopy);
229: global.defineProperty("arguments", argsObj,
230: ScriptableObject.DONTENUM);
231: script.exec(cx, global);
232: return null;
233: }
234: });
235: }
236:
237: public static void throwStopIteration(Object obj) {
238: throw new JavaScriptException(NativeIterator
239: .getStopIterationObject((Scriptable) obj), "", 0);
240: }
241:
242: public static Scriptable createNativeGenerator(
243: NativeFunction funObj, Scriptable scope,
244: Scriptable this Obj, int maxLocals, int maxStack) {
245: return new NativeGenerator(scope, funObj, new GeneratorState(
246: this Obj, maxLocals, maxStack));
247: }
248:
249: public static Object[] getGeneratorStackState(Object obj) {
250: GeneratorState rgs = (GeneratorState) obj;
251: if (rgs.stackState == null)
252: rgs.stackState = new Object[rgs.maxStack];
253: return rgs.stackState;
254: }
255:
256: public static Object[] getGeneratorLocalsState(Object obj) {
257: GeneratorState rgs = (GeneratorState) obj;
258: if (rgs.localsState == null)
259: rgs.localsState = new Object[rgs.maxLocals];
260: return rgs.localsState;
261: }
262:
263: public static class GeneratorState {
264: static final String CLASS_NAME = "org/mozilla/javascript/optimizer/OptRuntime$GeneratorState";
265:
266: public int resumptionPoint;
267: static final String resumptionPoint_NAME = "resumptionPoint";
268: static final String resumptionPoint_TYPE = "I";
269:
270: public Scriptable this Obj;
271: static final String this Obj_NAME = "thisObj";
272: static final String this Obj_TYPE = "Lorg/mozilla/javascript/Scriptable;";
273:
274: Object[] stackState;
275: Object[] localsState;
276: int maxLocals;
277: int maxStack;
278:
279: GeneratorState(Scriptable this Obj, int maxLocals, int maxStack) {
280: this.thisObj = thisObj;
281: this.maxLocals = maxLocals;
282: this.maxStack = maxStack;
283: }
284: }
285: }
|