diff --git a/mozilla/js/rhino/build.properties b/mozilla/js/rhino/build.properties index 6cb2b109d41..8f5149e3cca 100644 --- a/mozilla/js/rhino/build.properties +++ b/mozilla/js/rhino/build.properties @@ -36,9 +36,9 @@ name: rhino Name: Rhino -version: 1_6R6pre +version: 1_7R1pre # See Context#getImplementationVersion() for format of this! -implementation.version: Rhino 1.6 release 6 Pre ${implementation.date} +implementation.version: Rhino 1.7 release 1 Pre ${implementation.date} build.dir: build rhino.jar: js.jar diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Context.java b/mozilla/js/rhino/src/org/mozilla/javascript/Context.java index 13f340991b7..d5e5fc5b2b2 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Context.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Context.java @@ -133,6 +133,11 @@ public class Context */ public static final int VERSION_1_6 = 160; + /** + * JavaScript 1.7 + */ + public static final int VERSION_1_7 = 170; + /** * Controls behaviour of Date.prototype.getYear(). * If hasFeature(FEATURE_NON_ECMA_GET_YEAR) returns true, @@ -758,6 +763,7 @@ public class Context case VERSION_1_4: case VERSION_1_5: case VERSION_1_6: + case VERSION_1_7: return true; } return false; diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Decompiler.java b/mozilla/js/rhino/src/org/mozilla/javascript/Decompiler.java index d4198feecf0..d57440e14a3 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Decompiler.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Decompiler.java @@ -747,6 +747,10 @@ public class Decompiler case Token.CONST: result.append("const "); break; + + case Token.YIELD: + result.append("yield "); + break; case Token.NOT: result.append('!'); diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/FunctionNode.java b/mozilla/js/rhino/src/org/mozilla/javascript/FunctionNode.java index 3c7ba325e8a..b427ebf7205 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/FunctionNode.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/FunctionNode.java @@ -57,6 +57,10 @@ public class FunctionNode extends ScriptOrFnNode { public boolean getIgnoreDynamicScope() { return itsIgnoreDynamicScope; } + + public boolean isGenerator() { + return itsIsGenerator; + } /** * There are three types of functions that can be defined. The first @@ -82,7 +86,8 @@ public class FunctionNode extends ScriptOrFnNode { } String functionName; - boolean itsNeedsActivation; int itsFunctionType; + boolean itsNeedsActivation; boolean itsIgnoreDynamicScope; + boolean itsIsGenerator; } diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/IRFactory.java b/mozilla/js/rhino/src/org/mozilla/javascript/IRFactory.java index 5db480dc5ec..0bcc9e5824d 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/IRFactory.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/IRFactory.java @@ -950,6 +950,19 @@ final class IRFactory return new Node(nodeType, child); } + Node createYield(Node child, int lineno) + { + if (!parser.insideFunction()) { + parser.reportError("msg.bad.yield"); + } + setRequiresActivation(); + setIsGenerator(); + if (child != null) + return new Node(Token.YIELD, child, lineno); + else + return new Node(Token.YIELD, lineno); + } + Node createCallOrNew(int nodeType, Node child) { int type = Node.NON_SPECIALCALL; @@ -1417,6 +1430,13 @@ final class IRFactory } } + private void setIsGenerator() + { + if (parser.insideFunction()) { + ((FunctionNode)parser.currentScriptOrFn).itsIsGenerator = true; + } + } + private Parser parser; private static final int LOOP_DO_WHILE = 0; diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/InterpretedFunction.java b/mozilla/js/rhino/src/org/mozilla/javascript/InterpretedFunction.java index ee9dbcc3349..bbb32928365 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/InterpretedFunction.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/InterpretedFunction.java @@ -187,6 +187,12 @@ final class InterpretedFunction extends NativeFunction implements Script return idata; } + Object resumeGenerator(Context cx, Scriptable scope, int operation, + Object state, Object value) + { + return Interpreter.resumeGenerator(cx, scope, operation, state, value); + } + protected int getLanguageVersion() { return idata.languageVersion; diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java b/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java index 5c45cd432ec..5b562e0a8dd 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java @@ -160,20 +160,24 @@ public class Interpreter Icode_TAIL_CALL = -55, - // Clear local to allow GC its context + // Clear local to allow GC its context Icode_LOCAL_CLEAR = -56, - // Literal get/set + // Literal get/set Icode_LITERAL_GETTER = -57, Icode_LITERAL_SETTER = -58, - // const + // const Icode_SETCONST = -59, Icode_SETCONSTVAR = -60, Icode_SETCONSTVAR1 = -61, + // Generator opcodes (along with Token.YIELD) + Icode_GENERATOR = -62, + Icode_GENERATOR_END = -63, + // Last icode - MIN_ICODE = -61; + MIN_ICODE = -63; // data for parsing @@ -335,7 +339,18 @@ public class Interpreter Kit.codeBug(); } } + } + private static CallFrame captureFrameForGenerator(CallFrame frame) { + frame.frozen = true; + CallFrame result = frame.cloneFrozen(); + frame.frozen = false; + + // now isolate this frame from its previous context + result.parentFrame = null; + result.frameIndex = 0; + + return result; } static { @@ -429,6 +444,8 @@ public class Interpreter case Icode_SETCONST: return "SETCONST"; case Icode_SETCONSTVAR: return "SETCONSTVAR"; case Icode_SETCONSTVAR1: return "SETCONSTVAR1"; + case Icode_GENERATOR: return "GENERATOR"; + case Icode_GENERATOR_END: return "GENERATOR_END"; } // icode without name @@ -517,6 +534,10 @@ public class Interpreter itsData.useDynamicScope = true; } } + if (theFunction.isGenerator()) { + addIcode(Icode_GENERATOR); + addUint16(theFunction.getBaseLineno() & 0xFFFF); + } generateICodeFromTree(theFunction.getLastChild()); } @@ -863,7 +884,11 @@ public class Interpreter case Token.RETURN: updateLineNumber(node); - if (child != null) { + if (node.getIntProp(Node.GENERATOR_END_PROP, 0) != 0) { + // We're in a generator, so change RETURN to GENERATOR_END + addIcode(Icode_GENERATOR_END); + addUint16(itsLineNumber & 0xFFFF); + } else if (child != null) { visitExpression(child, ECF_TAIL); addToken(Token.RETURN); stackChange(-1); @@ -884,6 +909,9 @@ public class Interpreter stackChange(-1); break; + case Icode_GENERATOR: + break; + default: throw badTree(node); } @@ -1322,6 +1350,17 @@ public class Interpreter addToken(type); break; + case Token.YIELD: + if (child != null) { + visitExpression(child, 0); + } else { + addIcode(Icode_UNDEF); + stackChange(1); + } + addToken(Token.YIELD); + addUint16(node.getLineno() & 0xFFFF); + break; + default: throw badTree(node); } @@ -1605,7 +1644,7 @@ public class Interpreter byte[] array = itsData.itsICode; int top = itsICodeTop; if (top == array.length) { - array = increaseICodeCapasity(1); + array = increaseICodeCapacity(1); } array[top] = (byte)value; itsICodeTop = top + 1; @@ -1617,7 +1656,7 @@ public class Interpreter byte[] array = itsData.itsICode; int top = itsICodeTop; if (top + 2 > array.length) { - array = increaseICodeCapasity(2); + array = increaseICodeCapacity(2); } array[top] = (byte)(value >>> 8); array[top + 1] = (byte)value; @@ -1629,7 +1668,7 @@ public class Interpreter byte[] array = itsData.itsICode; int top = itsICodeTop; if (top + 4 > array.length) { - array = increaseICodeCapasity(4); + array = increaseICodeCapacity(4); } array[top] = (byte)(i >>> 24); array[top + 1] = (byte)(i >>> 16); @@ -1658,7 +1697,7 @@ public class Interpreter byte[] array = itsData.itsICode; int top = itsICodeTop; if (top + 3 > array.length) { - array = increaseICodeCapasity(3); + array = increaseICodeCapacity(3); } array[top] = (byte)gotoOp; // Offset would written later @@ -1774,7 +1813,7 @@ public class Interpreter itsExceptionTableTop = top + EXCEPTION_SLOT_SIZE; } - private byte[] increaseICodeCapasity(int extraSize) + private byte[] increaseICodeCapacity(int extraSize) { int capacity = itsData.itsICode.length; int top = itsICodeTop; @@ -1958,7 +1997,11 @@ public class Interpreter case Token.NEW : out.println(tname+' '+indexReg); break; - case Token.THROW : { + case Token.THROW : + case Token.YIELD : + case Icode_GENERATOR : + case Icode_GENERATOR_END : + { int line = getIndex(iCode, pc); out.println(tname + " : " + line); pc += 2; @@ -2006,6 +2049,24 @@ public class Interpreter pc += 4; break; } + case Icode_REG_IND_C0: + indexReg = 0; + break; + case Icode_REG_IND_C1: + indexReg = 1; + break; + case Icode_REG_IND_C2: + indexReg = 2; + break; + case Icode_REG_IND_C3: + indexReg = 3; + break; + case Icode_REG_IND_C4: + indexReg = 4; + break; + case Icode_REG_IND_C5: + indexReg = 5; + break; case Icode_REG_IND1: { indexReg = 0xFF & iCode[pc]; out.println(tname+" "+indexReg); @@ -2062,6 +2123,9 @@ public class Interpreter { switch (bytecode) { case Token.THROW : + case Token.YIELD: + case Icode_GENERATOR: + case Icode_GENERATOR_END: // source line return 1 + 2; @@ -2326,6 +2390,40 @@ public class Interpreter return interpretLoop(cx, frame, null); } + static class GeneratorState { + GeneratorState(int operation, Object value) { + this.operation = operation; + this.value = value; + } + int operation; + Object value; + RuntimeException returnedException; + } + + public static Object resumeGenerator(Context cx, + Scriptable scope, + int operation, + Object savedState, + Object value) + { + CallFrame frame = (CallFrame) savedState; + GeneratorState generatorState = new GeneratorState(operation, value); + if (operation == NativeGenerator.GENERATOR_CLOSE) { + try { + return interpretLoop(cx, frame, generatorState); + } catch (RuntimeException e) { + // Only propagate exceptions other than closingException + if (e != value) + throw e; + } + return Undefined.instance; + } + Object result = interpretLoop(cx, frame, generatorState); + if (generatorState.returnedException != null) + throw generatorState.returnedException; + return result; + } + public static Object restartContinuation(Continuation c, Context cx, Scriptable scope, Object[] args) { @@ -2388,9 +2486,15 @@ public class Interpreter // catch bugs with using indeReg to access array eleemnts before // initializing indexReg. + GeneratorState generatorState = null; if (throwable != null) { - // Assert assumptions - if (!(throwable instanceof ContinuationJump)) { + if (throwable instanceof GeneratorState) { + generatorState = (GeneratorState) throwable; + + // reestablish this call frame + enterFrame(cx, frame, ScriptRuntime.emptyArgs, true); + throwable = null; + } else if (!(throwable instanceof ContinuationJump)) { // It should be continuation Kit.codeBug(); } @@ -2493,7 +2597,7 @@ public class Interpreter } } else { - if (frame.frozen) Kit.codeBug(); + if (generatorState == null && frame.frozen) Kit.codeBug(); } // Use local variables for constant values in frame @@ -2508,7 +2612,7 @@ public class Interpreter // Use local for stackTop as well. Since execption handlers // can only exist at statement level where stack is empty, - // it is necessary to save/restore stackTop only accross + // it is necessary to save/restore stackTop only across // function calls and normal returns. int stackTop = frame.savedStackTop; @@ -2523,8 +2627,76 @@ public class Interpreter int op = iCode[frame.pc++]; jumplessRun: { - // Back indent to ease imlementation reading + // Back indent to ease implementation reading switch (op) { + case Icode_GENERATOR: { + if (!frame.frozen) { + // First time encountering this opcode: create new generator + // object and return + frame.pc--; // we want to come back here when we resume + CallFrame generatorFrame = captureFrameForGenerator(frame); + generatorFrame.frozen = true; + NativeGenerator generator + = new NativeGenerator(generatorFrame.fnOrScript, generatorFrame); + ScriptRuntime.setObjectProtoAndParent(generator, + ScriptRuntime.getTopCallScope(cx)); + frame.result = generator; + break Loop; + } else { + // We are now resuming execution. Fall through to YIELD case. + } + } + // fall through... + case Token.YIELD: { + if (!frame.frozen) { + if (generatorState.operation == NativeGenerator.GENERATOR_CLOSE) { + // Error: no yields when generator is closing + throw ScriptRuntime.typeError0("msg.yield.closing"); + } + // return to our caller (which should be a method of NativeGenerator) + frame.frozen = true; + frame.result = stack[stackTop]; + frame.resultDbl = sDbl[stackTop]; + frame.savedStackTop = stackTop; + frame.pc--; // we want to come back here when we resume + ScriptRuntime.exitActivationFunction(cx); + return (frame.result != DBL_MRK) + ? frame.result + : ScriptRuntime.wrapNumber(frame.resultDbl); + } else { + // we are resuming execution + frame.frozen = false; + int sourceLine = getIndex(iCode, frame.pc); + frame.pc += 2; // skip line number data + if (generatorState.operation == NativeGenerator.GENERATOR_THROW) { + // processing a call to .throw(exception): must + // act as if exception was thrown from resumption point + throwable = new JavaScriptException(generatorState.value, + frame.idata.itsSourceFile, + sourceLine); + break withoutExceptions; + } + if (generatorState.operation == NativeGenerator.GENERATOR_CLOSE) { + throwable = generatorState.value; + break withoutExceptions; + } + if (generatorState.operation != NativeGenerator.GENERATOR_SEND) + throw Kit.codeBug(); + if (op == Token.YIELD) + stack[stackTop] = generatorState.value; + continue Loop; + } + } + case Icode_GENERATOR_END: { + // throw StopIteration + frame.frozen = true; + Scriptable top = ScriptableObject.getTopLevelScope(frame.scope); + Object e = top.get(NativeGenerator.STOP_ITERATION, frame.scope); + int sourceLine = getIndex(iCode, frame.pc); + generatorState.returnedException = + new JavaScriptException(e, frame.idata.itsSourceFile, sourceLine); + break Loop; + } case Token.THROW: { Object value = stack[stackTop]; if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]); @@ -3124,7 +3296,8 @@ switch (op) { // optimization will create a "hole" in the context stack. // The correct thing to do may be to disable tail call // optimization if the code is being debugged. - exitFrame(cx, frame, null); } + exitFrame(cx, frame, null); + } initFrame(cx, calleeScope, funThisObj, stack, sDbl, stackTop + 2, indexReg, ifun, callParentFrame, calleeFrame); @@ -3704,7 +3877,12 @@ switch (op) { int exState; ContinuationJump cjump = null; - if (throwable instanceof JavaScriptException) { + if (generatorState != null && + generatorState.operation == NativeGenerator.GENERATOR_CLOSE && + throwable == generatorState.value) + { + exState = EX_FINALLY_STATE; + } else if (throwable instanceof JavaScriptException) { exState = EX_CATCH_STATE; } else if (throwable instanceof EcmaError) { // an offical ECMA error object, @@ -3762,7 +3940,7 @@ switch (op) { continue StateLoop; } } - // No allowed execption handlers in this frame, unwind + // No allowed exception handlers in this frame, unwind // to parent and try to look there exitFrame(cx, frame, throwable); @@ -3988,7 +4166,8 @@ switch (op) { return frame.debuggerFrame != null || frame.idata.itsNeedsActivation; } - private static void enterFrame(Context cx, CallFrame frame, Object[] args, boolean continuationRestart) + private static void enterFrame(Context cx, CallFrame frame, Object[] args, + boolean continuationRestart) { boolean usesActivation = frame.idata.itsNeedsActivation; boolean isDebugged = frame.debuggerFrame != null; @@ -3996,7 +4175,7 @@ switch (op) { Scriptable scope = frame.scope; if(scope == null) { Kit.codeBug(); - } else if(continuationRestart) { + } else if (continuationRestart) { // Walk the parent chain of frame.scope until a NativeCall is // found. Normally, frame.scope is a NativeCall when called // from initFrame() for a debugged or activatable function. @@ -4010,7 +4189,9 @@ switch (op) { break; } else { scope = scope.getParentScope(); - if(scope == null || (frame.parentFrame != null && frame.parentFrame.scope == scope)) { + if (scope == null || (frame.parentFrame != null && + frame.parentFrame.scope == scope)) + { // If we get here, we didn't find a NativeCall in // the call chain before reaching parent frame's // scope. This should not be possible. diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/NativeFunction.java b/mozilla/js/rhino/src/org/mozilla/javascript/NativeFunction.java index 1392a3d954f..f4fb9e3a466 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/NativeFunction.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/NativeFunction.java @@ -116,6 +116,16 @@ public abstract class NativeFunction extends BaseFunction return null; } + /* + * Resumes execution of a JS 1.7 generator. + */ + /*abstract*/ Object resumeGenerator(Context cx, Scriptable scope, + int operation, Object state, Object value) + { + // TODO(js1.7gen): make abstract once bytecode generation is done + throw new EvaluatorException("Not yet implemented"); + } + protected abstract int getLanguageVersion(); /** diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/NativeGenerator.java b/mozilla/js/rhino/src/org/mozilla/javascript/NativeGenerator.java new file mode 100755 index 00000000000..6325b9411be --- /dev/null +++ b/mozilla/js/rhino/src/org/mozilla/javascript/NativeGenerator.java @@ -0,0 +1,227 @@ +/* -*- 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-1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Norris Boyd + * + * 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 ***** */ + +package org.mozilla.javascript; + +/** + * This class implements generator objects. See + * http://developer.mozilla.org/en/docs/New_in_JavaScript_1.7#Generators + * + * @author Norris Boyd + */ +public final class NativeGenerator extends IdScriptableObject { + private static final Object GENERATOR_TAG = new Object(); + + static void init(Scriptable scope, boolean sealed) { + // Generator + new NativeGenerator().exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed); + + // StopIteration + NativeObject obj = new StopIteration(); + obj.setPrototype(getObjectPrototype(scope)); + obj.setParentScope(scope); + if (sealed) { obj.sealObject(); } + ScriptableObject.defineProperty(scope, STOP_ITERATION, obj, + ScriptableObject.DONTENUM); + } + + /** + * Only for constructing the prototype object. + */ + private NativeGenerator() { } + + NativeGenerator(NativeFunction function, Object savedState) { + this.function = function; + this.savedState = savedState; + } + + public static final String STOP_ITERATION = "StopIteration"; + + static class StopIteration extends NativeObject { + public String getClassName() { return STOP_ITERATION; } + } + + public static final int GENERATOR_SEND = 0, + GENERATOR_THROW = 1, + GENERATOR_CLOSE = 2; + + public String getClassName() { + return "Generator"; + } + + protected void initPrototypeId(int id) { + String s; + int arity; + switch (id) { + case Id_constructor: arity=1; s="constructor"; break; + case Id_close: arity=1; s="close"; break; + case Id_next: arity=1; s="next"; break; + case Id_send: arity=0; s="send"; break; + case Id_throw: arity=0; s="throw"; break; + default: throw new IllegalArgumentException(String.valueOf(id)); + } + initPrototypeMethod(GENERATOR_TAG, id, s, arity); + } + + public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, + Scriptable thisObj, Object[] args) + { + if (!f.hasTag(GENERATOR_TAG)) { + return super.execIdCall(f, cx, scope, thisObj, args); + } + int id = f.methodId(); + + if (!(thisObj instanceof NativeGenerator)) + throw incompatibleCallError(f); + + NativeGenerator generator = (NativeGenerator) thisObj; + + switch (id) { + + case Id_constructor: + // TODO(js1.7gen): Shouldn't have a constructor. Currently need + // one to get Generator.prototype + return null; + + case Id_close: + // need to run any pending finally clauses + return generator.resume(cx, scope, GENERATOR_CLOSE, + new RuntimeException()); + + case Id_next: + // arguments to next() are ignored + generator.firstTime = false; + return generator.resume(cx, scope, GENERATOR_SEND, + Undefined.instance); + + case Id_send: + if (generator.firstTime) { + throw ScriptRuntime.typeError0("msg.send.newborn"); + } + return generator.resume(cx, scope, GENERATOR_SEND, + args.length > 0 ? args[0] : Undefined.instance); + + case Id_throw: + return generator.resume(cx, scope, GENERATOR_THROW, + args.length > 0 ? args[0] : Undefined.instance); + + default: + throw new IllegalArgumentException(String.valueOf(id)); + } + } + + private Object resume(Context cx, Scriptable scope, int operation, + Object value) + { + if (savedState == null) { + if (operation == GENERATOR_CLOSE) + return Undefined.instance; + Object thrown = operation == GENERATOR_THROW + ? value + : ScriptableObject.getTopLevelScope(scope).get(STOP_ITERATION, + scope); + throw new JavaScriptException(thrown, lineSource, lineNumber); + } + try { + synchronized (this) { + // generator execution is necessarily single-threaded and + // non-reentrant. + // See https://bugzilla.mozilla.org/show_bug.cgi?id=349263 + if (locked) + throw ScriptRuntime.typeError0("msg.already.exec.gen"); + locked = true; + } + return function.resumeGenerator(cx, scope, operation, savedState, + value); + } catch (RhinoException e) { + lineNumber = e.lineNumber(); + lineSource = e.lineSource(); + savedState = null; + throw e; + } finally { + synchronized (this) { + locked = false; + } + if (operation == GENERATOR_CLOSE) + savedState = null; + } + } + +// #string_id_map# + + protected int findPrototypeId(String s) { + int id; +// #generated# Last update: 2007-05-09 08:23:27 EDT + L0: { id = 0; String X = null; int c; + int s_length = s.length(); + if (s_length==4) { + c=s.charAt(0); + if (c=='n') { X="next";id=Id_next; } + else if (c=='s') { X="send";id=Id_send; } + } + else if (s_length==5) { + c=s.charAt(0); + if (c=='c') { X="close";id=Id_close; } + else if (c=='t') { X="throw";id=Id_throw; } + } + else if (s_length==11) { X="constructor";id=Id_constructor; } + if (X!=null && X!=s && !X.equals(s)) id = 0; + break L0; + } +// #/generated# + return id; + } + + private static final int + Id_constructor = 1, + Id_close = 2, + Id_next = 3, + Id_send = 4, + Id_throw = 5, + MAX_PROTOTYPE_ID = 5; + +// #/string_id_map# + + private NativeFunction function; + private Object savedState; + private String lineSource; + private int lineNumber; + private boolean firstTime = true; + private boolean locked; +} + diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Node.java b/mozilla/js/rhino/src/org/mozilla/javascript/Node.java index 6dedac3d1a9..b4bcdd9510f 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Node.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Node.java @@ -82,7 +82,8 @@ public class Node NAME_PROP = 17, // property name CONTROL_BLOCK_PROP = 18, // flags a control block that can drop off PARENTHESIZED_PROP = 19, // expression is parenthesized - LAST_PROP = 19; + GENERATOR_END_PROP = 20, + LAST_PROP = 20; // values of ISNUMBER_PROP to specify // which of the children are Number types @@ -460,6 +461,7 @@ public class Node case NAME_PROP: return "name_prop"; case CONTROL_BLOCK_PROP: return "control_block_prop"; case PARENTHESIZED_PROP: return "parenthesized_prop"; + case GENERATOR_END_PROP: return "generator_end"; default: Kit.codeBug(); } diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/NodeTransformer.java b/mozilla/js/rhino/src/org/mozilla/javascript/NodeTransformer.java index 53740a6434b..094dcac12f0 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/NodeTransformer.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/NodeTransformer.java @@ -135,6 +135,19 @@ public class NodeTransformer case Token.RETURN: { + boolean isGenerator = tree.getType() == Token.FUNCTION + && ((FunctionNode)tree).isGenerator(); + if (isGenerator) { + node.putIntProp(Node.GENERATOR_END_PROP, 1); + /* + // Replace returns inside generators with throw STOP_ITERATION + node = replaceCurrent(parent, previous, node, + new Node(Token.THROW, + Node.newString(Token.NAME, + NativeGenerator.STOP_ITERATION), + node.getLineno())); + */ + } /* If we didn't support try/finally, it wouldn't be * necessary to put LEAVEWITH nodes here... but as * we do need a series of JSR FINALLY nodes before @@ -169,7 +182,7 @@ public class NodeTransformer Node returnNode = node; Node returnExpr = returnNode.getFirstChild(); node = replaceCurrent(parent, previous, node, unwindBlock); - if (returnExpr == null) { + if (returnExpr == null || isGenerator) { unwindBlock.addChildToBack(returnNode); } else { Node store = new Node(Token.EXPR_RESULT, returnExpr); diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Parser.java b/mozilla/js/rhino/src/org/mozilla/javascript/Parser.java index 68029d42c1d..97d5c593cb2 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Parser.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Parser.java @@ -1069,44 +1069,9 @@ public class Parser break; } - case Token.RETURN: { - if (!insideFunction()) { - reportError("msg.bad.return"); - } - consumeToken(); - decompiler.addToken(Token.RETURN); - int lineno = ts.getLineno(); - - Node retExpr; - /* This is ugly, but we don't want to require a semicolon. */ - tt = peekTokenOrEOL(); - switch (tt) { - case Token.SEMI: - case Token.RC: - case Token.EOF: - case Token.EOL: - case Token.ERROR: - retExpr = null; - break; - default: - retExpr = expr(false); - hasReturnValue = true; - } - pn = nf.createReturn(retExpr, lineno); - - // see if we need a strict mode warning - if (retExpr == null) { - if (functionEndFlags == Node.END_RETURNS_VALUE) - addStrictWarning("msg.return.inconsistent", ""); - - functionEndFlags |= Node.END_RETURNS; - } else { - if (functionEndFlags == Node.END_RETURNS) - addStrictWarning("msg.return.inconsistent", ""); - - functionEndFlags |= Node.END_RETURNS_VALUE; - } - + case Token.RETURN: + case Token.YIELD: { + pn = returnOrYield(tt, false); break; } @@ -1241,6 +1206,58 @@ public class Parser return pn; } + + private Node returnOrYield(int tt, boolean exprContext) + throws IOException, ParserException + { + if (!insideFunction()) { + reportError(tt == Token.RETURN ? "msg.bad.return" + : "msg.bad.yield"); + } + consumeToken(); + decompiler.addToken(tt); + int lineno = ts.getLineno(); + + Node e; + /* This is ugly, but we don't want to require a semicolon. */ + switch (peekTokenOrEOL()) { + case Token.SEMI: + case Token.RC: + case Token.EOF: + case Token.EOL: + case Token.ERROR: + case Token.RB: + case Token.RP: + case Token.YIELD: + e = null; + break; + default: + e = expr(false); + break; + } + if (tt == Token.RETURN) { + // see if we need a strict mode warning + // TODO(js1.7gen): check for mixture of yield and value returns + if (e == null) { + if (functionEndFlags == Node.END_RETURNS_VALUE) + addStrictWarning("msg.return.inconsistent", ""); + + functionEndFlags |= Node.END_RETURNS; + } else { + hasReturnValue = true; + if (functionEndFlags == Node.END_RETURNS) + addStrictWarning("msg.return.inconsistent", ""); + + functionEndFlags |= Node.END_RETURNS_VALUE; + } + return nf.createReturn(e, lineno); + } else { + Node n = nf.createYield(e, lineno); + if (exprContext) + return n; + return new Node(Token.EXPR_VOID, n, lineno); + } + } /** * Parse a 'var' or 'const' statement, or a 'var' init list in a for @@ -1321,6 +1338,9 @@ public class Parser decompiler.addToken(Token.COMMA); if (!pn.hasSideEffects()) addStrictWarning("msg.no.side.effects", ""); + if (peekToken() == Token.YIELD) { + reportError("msg.yield.parenthesized"); + } pn = nf.createBinary(Token.COMMA, pn, assignExpr(inForInit)); } return pn; @@ -1329,9 +1349,14 @@ public class Parser private Node assignExpr(boolean inForInit) throws IOException, ParserException { + int tt = peekToken(); + if (tt == Token.YIELD) { + consumeToken(); + return returnOrYield(tt, true); + } Node pn = condExpr(inForInit); - int tt = peekToken(); + tt = peekToken(); if (Token.FIRST_ASSIGN <= tt && tt <= Token.LAST_ASSIGN) { consumeToken(); decompiler.addToken(tt); @@ -1687,6 +1712,9 @@ public class Parser if (!first) decompiler.addToken(Token.COMMA); first = false; + if (peekToken() == Token.YIELD) { + reportError("msg.yield.parenthesized"); + } nf.addChildToBack(listNode, assignExpr(false)); } while (matchToken(Token.COMMA)); @@ -1769,6 +1797,13 @@ public class Parser tt = nextToken(); switch (tt) { + + // needed for generator.throw(); + case Token.THROW: + decompiler.addName("throw"); + pn = propertyName(pn, "throw", memberTypeFlags); + break; + // handles: name, ns::name, ns::*, ns::[expr] case Token.NAME: s = ts.getString(); diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java b/mozilla/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java index 71ce92a0c44..4387e2b2422 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java @@ -202,6 +202,10 @@ public class ScriptRuntime { NativeWith.init(scope, sealed); NativeCall.init(scope, sealed); NativeScript.init(scope, sealed); + + // TODO(js1.7gen): jsshell marks generators as JSCLASS_IS_ANONYMOUS, + // meaning that "Generator" is not defined in the global scope + NativeGenerator.init(scope, sealed); boolean withXml = cx.hasFeature(Context.FEATURE_E4X) && cx.getE4xImplementationFactory() != null; diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Token.java b/mozilla/js/rhino/src/org/mozilla/javascript/Token.java index 7f7cdc2a2f0..43cd299fb5e 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Token.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Token.java @@ -144,113 +144,115 @@ public class Token DEL_REF = 67, // delete reference REF_CALL = 68, // f(args) = something or f(args)++ REF_SPECIAL = 69, // reference for special properties like __proto + YIELD = 70, // JS 1.7 yield pseudo keyword // For XML support: - DEFAULTNAMESPACE = 70, // default xml namespace = - ESCXMLATTR = 71, - ESCXMLTEXT = 72, - REF_MEMBER = 73, // Reference for x.@y, x..y etc. - REF_NS_MEMBER = 74, // Reference for x.ns::y, x..ns::y etc. - REF_NAME = 75, // Reference for @y, @[y] etc. - REF_NS_NAME = 76; // Reference for ns::y, @ns::y@[y] etc. + DEFAULTNAMESPACE = 71, // default xml namespace = + ESCXMLATTR = 72, + ESCXMLTEXT = 73, + REF_MEMBER = 74, // Reference for x.@y, x..y etc. + REF_NS_MEMBER = 75, // Reference for x.ns::y, x..ns::y etc. + REF_NAME = 76, // Reference for @y, @[y] etc. + REF_NS_NAME = 77; // Reference for ns::y, @ns::y@[y] etc. // End of interpreter bytecodes public final static int LAST_BYTECODE_TOKEN = REF_NS_NAME, - TRY = 77, - SEMI = 78, // semicolon - LB = 79, // left and right brackets - RB = 80, - LC = 81, // left and right curlies (braces) - RC = 82, - LP = 83, // left and right parentheses - RP = 84, - COMMA = 85, // comma operator + TRY = 78, + SEMI = 79, // semicolon + LB = 80, // left and right brackets + RB = 81, + LC = 82, // left and right curlies (braces) + RC = 83, + LP = 84, // left and right parentheses + RP = 85, + COMMA = 86, // comma operator - ASSIGN = 86, // simple assignment (=) - ASSIGN_BITOR = 87, // |= - ASSIGN_BITXOR = 88, // ^= - ASSIGN_BITAND = 89, // |= - ASSIGN_LSH = 90, // <<= - ASSIGN_RSH = 91, // >>= - ASSIGN_URSH = 92, // >>>= - ASSIGN_ADD = 93, // += - ASSIGN_SUB = 94, // -= - ASSIGN_MUL = 95, // *= - ASSIGN_DIV = 96, // /= - ASSIGN_MOD = 97; // %= + ASSIGN = 87, // simple assignment (=) + ASSIGN_BITOR = 88, // |= + ASSIGN_BITXOR = 89, // ^= + ASSIGN_BITAND = 90, // |= + ASSIGN_LSH = 91, // <<= + ASSIGN_RSH = 92, // >>= + ASSIGN_URSH = 93, // >>>= + ASSIGN_ADD = 94, // += + ASSIGN_SUB = 95, // -= + ASSIGN_MUL = 96, // *= + ASSIGN_DIV = 97, // /= + ASSIGN_MOD = 98; // %= public final static int FIRST_ASSIGN = ASSIGN, LAST_ASSIGN = ASSIGN_MOD, - HOOK = 98, // conditional (?:) - COLON = 99, - OR = 100, // logical or (||) - AND = 101, // logical and (&&) - INC = 102, // increment/decrement (++ --) - DEC = 103, - DOT = 104, // member operator (.) - FUNCTION = 105, // function keyword - EXPORT = 106, // export keyword - IMPORT = 107, // import keyword - IF = 108, // if keyword - ELSE = 109, // else keyword - SWITCH = 110, // switch keyword - CASE = 111, // case keyword - DEFAULT = 112, // default keyword - WHILE = 113, // while keyword - DO = 114, // do keyword - FOR = 115, // for keyword - BREAK = 116, // break keyword - CONTINUE = 117, // continue keyword - VAR = 118, // var keyword - WITH = 119, // with keyword - CATCH = 120, // catch keyword - FINALLY = 121, // finally keyword - VOID = 122, // void keyword - RESERVED = 123, // reserved keywords + HOOK = 99, // conditional (?:) + COLON = 100, + OR = 101, // logical or (||) + AND = 102, // logical and (&&) + INC = 103, // increment/decrement (++ --) + DEC = 104, + DOT = 105, // member operator (.) + FUNCTION = 106, // function keyword + EXPORT = 107, // export keyword + IMPORT = 108, // import keyword + IF = 109, // if keyword + ELSE = 110, // else keyword + SWITCH = 111, // switch keyword + CASE = 112, // case keyword + DEFAULT = 113, // default keyword + WHILE = 114, // while keyword + DO = 115, // do keyword + FOR = 116, // for keyword + BREAK = 117, // break keyword + CONTINUE = 118, // continue keyword + VAR = 119, // var keyword + WITH = 120, // with keyword + CATCH = 121, // catch keyword + FINALLY = 122, // finally keyword + VOID = 123, // void keyword + RESERVED = 124, // reserved keywords - EMPTY = 124, + EMPTY = 125, /* types used for the parse tree - these never get returned * by the scanner. */ - BLOCK = 125, // statement block - LABEL = 126, // label - TARGET = 127, - LOOP = 128, - EXPR_VOID = 129, // expression statement in functions - EXPR_RESULT = 130, // expression statement in scripts - JSR = 131, - SCRIPT = 132, // top-level node for entire script - TYPEOFNAME = 133, // for typeof(simple-name) - USE_STACK = 134, - SETPROP_OP = 135, // x.y op= something - SETELEM_OP = 136, // x[y] op= something - LOCAL_BLOCK = 137, - SET_REF_OP = 138, // *reference op= something + BLOCK = 126, // statement block + LABEL = 127, // label + TARGET = 128, + LOOP = 129, + EXPR_VOID = 130, // expression statement in functions + EXPR_RESULT = 131, // expression statement in scripts + JSR = 132, + SCRIPT = 133, // top-level node for entire script + TYPEOFNAME = 134, // for typeof(simple-name) + USE_STACK = 135, + SETPROP_OP = 136, // x.y op= something + SETELEM_OP = 137, // x[y] op= something + LOCAL_BLOCK = 138, + SET_REF_OP = 139, // *reference op= something // For XML support: - DOTDOT = 139, // member operator (..) - COLONCOLON = 140, // namespace::name - XML = 141, // XML type - DOTQUERY = 142, // .() -- e.g., x.emps.emp.(name == "terry") - XMLATTR = 143, // @ - XMLEND = 144, + DOTDOT = 140, // member operator (..) + COLONCOLON = 141, // namespace::name + XML = 142, // XML type + DOTQUERY = 143, // .() -- e.g., x.emps.emp.(name == "terry") + XMLATTR = 144, // @ + XMLEND = 145, // Optimizer-only-tokens - TO_OBJECT = 145, - TO_DOUBLE = 146, + TO_OBJECT = 146, + TO_DOUBLE = 147, - GET = 147, // JS 1.5 get pseudo keyword - SET = 148, // JS 1.5 set pseudo keyword - CONST = 149, - SETCONST = 150, - SETCONSTVAR = 151, - LAST_TOKEN = 152; + GET = 148, // JS 1.5 get pseudo keyword + SET = 149, // JS 1.5 set pseudo keyword + LET = 150, // JS 1.7 let pseudo keyword + CONST = 151, + SETCONST = 152, + SETCONSTVAR = 153, + LAST_TOKEN = 154; public static String name(int token) { @@ -407,6 +409,8 @@ public class Token case TO_DOUBLE: return "TO_DOUBLE"; case GET: return "GET"; case SET: return "SET"; + case LET: return "LET"; + case YIELD: return "YIELD"; case CONST: return "CONST"; case SETCONST: return "SETCONST"; } diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/TokenStream.java b/mozilla/js/rhino/src/org/mozilla/javascript/TokenStream.java index c276894b14f..39fa807d185 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/TokenStream.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/TokenStream.java @@ -133,6 +133,7 @@ class TokenStream Id_function = Token.FUNCTION, Id_if = Token.IF, Id_in = Token.IN, + Id_let = Token.LET, Id_new = Token.NEW, Id_null = Token.NULL, Id_return = Token.RETURN, @@ -144,6 +145,7 @@ class TokenStream Id_void = Token.VOID, Id_while = Token.WHILE, Id_with = Token.WITH, + Id_yield = Token.YIELD, // the following are #ifdef RESERVE_JAVA_KEYWORDS in jsscan.c Id_abstract = Token.RESERVED, @@ -184,7 +186,7 @@ class TokenStream int id; String s = name; -// #generated# Last update: 2001-06-01 17:45:01 CEST +// #generated# Last update: 2007-04-18 13:53:30 PDT L0: { id = 0; String X = null; int c; L: switch (s.length()) { case 2: c=s.charAt(1); @@ -195,6 +197,7 @@ class TokenStream case 3: switch (s.charAt(0)) { case 'f': if (s.charAt(2)=='r' && s.charAt(1)=='o') {id=Id_for; break L0;} break L; case 'i': if (s.charAt(2)=='t' && s.charAt(1)=='n') {id=Id_int; break L0;} break L; + case 'l': if (s.charAt(2)=='t' && s.charAt(1)=='e') {id=Id_let; break L0;} break L; case 'n': if (s.charAt(2)=='w' && s.charAt(1)=='e') {id=Id_new; break L0;} break L; case 't': if (s.charAt(2)=='y' && s.charAt(1)=='r') {id=Id_try; break L0;} break L; case 'v': if (s.charAt(2)=='r' && s.charAt(1)=='a') {id=Id_var; break L0;} break L; @@ -221,7 +224,10 @@ class TokenStream } break L; case 5: switch (s.charAt(2)) { case 'a': X="class";id=Id_class; break L; - case 'e': X="break";id=Id_break; break L; + case 'e': c=s.charAt(0); + if (c=='b') { X="break";id=Id_break; } + else if (c=='y') { X="yield";id=Id_yield; } + break L; case 'i': X="while";id=Id_while; break L; case 'l': X="false";id=Id_false; break L; case 'n': c=s.charAt(0); @@ -394,6 +400,13 @@ class TokenStream // Return the corresponding token if it's a keyword int result = stringToKeyword(str); if (result != Token.EOF) { + if ((result == Token.LET || result == Token.YIELD) && + parser.compilerEnv.getLanguageVersion() + < Context.VERSION_1_7) + { + // LET and YIELD are tokens only in 1.7 and later + result = Token.NAME; + } if (result != Token.RESERVED) { return result; } else if (!parser.compilerEnv. diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java b/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java index df8dcb46fda..5ac2a7f3c41 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java @@ -372,6 +372,10 @@ public class Codegen extends Interpreter cfw.stopMethod((short)(firstLocal + 1)); } + // TODO(js1.7gen): make name a parameter, generalize to + // work for "call" and for "resumeGenerator". + // The "call" method should call "resumeGenerator" with a "start" operation + // (need to add "args" parameter to "resumeGenerator"). private void generateCallMethod(ClassFileWriter cfw) { cfw.startMethod("call", @@ -1271,6 +1275,14 @@ class BodyCodegen */ private void generatePrologue() { + /* + * TODO(js1.7gen): + * For resumeGenerator, generate prologue that looks at the value + * of the operation argument, does some setup, and jumps to the + * appropriate resumption point. + * Can assume inDirectCallFunction = false and hasVarsInRegs = false + * for generators. + */ if (inDirectCallFunction) { int directParameterCount = scriptOrFn.getParamCount(); // 0 is reserved for function Object 'this' @@ -2355,6 +2367,60 @@ class BodyCodegen +")Ljava/lang/Object;"); break; + case Token.YIELD: + /* + * TODO(js1.7gen): Generate code to save the execution state + * of the JVM. This may not be too bad: since generators + * require an activation, all variables are in the activation + * object. Look through the prologue code at the java + * registers that are initialized. Look to see if any of those + * values are altered during execution; if not, you can + * just rely on shared prologue code for the generator. + * Hardest part will be the stack. You'll need to create a + * compile-time data structure that tracks the type of every + * element on the stack. Then when you generate code for the + * yield, you'll generate code to take the contents of the + * stack and save it to an in-memory object (Object[] or pair + * of Object[] double[], I'm not sure which). You'll also + * need the inverse operation of taking an object like that + * and pushing all its saved values onto the stack. It may + * make sense to alter ClassFileWriter to maintain stack + * information, or maintain a parallel data structure in + * Codegen. + * + * Each yield point will need to have a unique integer number + * determined at compile time. When a program encounters a + * yield, the yield number will be saved in the state object. + * The "resumeGenerator" prologue code will need to have a + * code to take the integer and then jump to the appropriate + * yield. You'll need to run the validator with yields in + * various points in control flow to make sure that the + * validator doesn't object to these jumps into the middle of + * various control structures. I think it should be okay since + * the register save code will ensure that you never jump + * into a place with different stack height or uninitialized + * variables. + * + * The biggest unknown area for me is exception handling. + * There are cases of yields in finally clauses that suspend + * a function with an in-flight exception. It may have to be + * that Rhino doesn't generate any finally clauses but instead + * catches all exceptions, processes finally clauses (including + * yields) and rethrows. Then in-flight exceptions will just + * be variables that can be captured. The other question is + * whether the validator will object to jumps in and out of + * try and catch blocks. + * + * Probably don't need analog to Icode_GENERATOR: all setup + * code can be handled in "resumeGenerator" prologue. + * + * Probably do need analog to Icode_GENERATOR_END. Perhaps + * during code generation for returns, can check to see if + * in generator and if so generate code for the analog + * to Icode_GENERATOR_END. + */ + break; + default: throw new RuntimeException("Unexpected node type "+type); } diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/resources/Messages.properties b/mozilla/js/rhino/src/org/mozilla/javascript/resources/Messages.properties index b4d0c38a7ee..90df7fe548e 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/resources/Messages.properties +++ b/mozilla/js/rhino/src/org/mozilla/javascript/resources/Messages.properties @@ -126,6 +126,12 @@ msg.bad.decr =\ msg.bad.incr =\ Invalid increment operand. +msg.bad.yield =\ + yield must be in a function. + +msg.yield.parenthesized =\ + yield expression must be parenthesized. + # NativeGlobal msg.cant.call.indirect =\ Function "{0}" must be called directly, and not by way of a \ @@ -448,7 +454,7 @@ msg.assn.create.strict =\ Assignment to undeclared variable {0} msg.ref.undefined.prop =\ - Referenced to undefined property "{0}" + Referenced to undefined property "{0}" msg.prop.not.found =\ Property {0} not found. @@ -691,3 +697,14 @@ msg.bad.uri =\ # Number msg.bad.precision =\ Precision {0} out of range. + +# NativeGenerator +msg.send.newborn =\ + Attempt to send value to newborn generator + +msg.already.exec.gen =\ + Already executing generator + +# Interpreter +msg.yield.closing =\ + Yield from closing generator diff --git a/mozilla/js/rhino/testsrc/base.skip b/mozilla/js/rhino/testsrc/base.skip index 553584c15fa..e15e7cf181b 100644 --- a/mozilla/js/rhino/testsrc/base.skip +++ b/mozilla/js/rhino/testsrc/base.skip @@ -167,8 +167,29 @@ js1_7/geniter/regress-347739.js js1_7/geniter/regress-349012-01.js js1_7/geniter/regress-349331.js +# Generator functionality not yet implemented: +# "Iterator" constructor +js1_7/geniter/builtin-Iterator-function.js +# array comprehensions +js1_7/geniter/regress-345736.js +# let statements +js1_7/geniter/regress-347593.js +# yield and xml-filtering predicate +js1_7/geniter/regress-352605.js +# destructuring assignment +js1_7/geniter/regress-366941.js +# for (i in ) +js1_7/geniter/regress-350621.js + # JS 1.7 not yet implemented -js1_7 +js1_7/block +js1_7/decompilation +js1_7/expressions +js1_7/extensions +js1_7/iterable +js1_7/lexical +js1_7/regexp +js1_7/regress # JS 1.8 not yet implemented js1_8 diff --git a/mozilla/js/rhino/testsrc/opt1.skip b/mozilla/js/rhino/testsrc/opt1.skip index e1607e6c337..70068826188 100644 --- a/mozilla/js/rhino/testsrc/opt1.skip +++ b/mozilla/js/rhino/testsrc/opt1.skip @@ -13,11 +13,14 @@ js1_5/Regress/regress-80981.js js1_5/Regress/regress-89443.js js1_5/extensions/regress-226507.js -# Needs investigation -#js1_5/Exceptions/regress-257751.js -#js1_5/Regress/regress-111557.js -#js1_5/Regress/regress-155081-2.js -#js1_5/Regress/regress-155081.js -#js1_5/Regress/regress-167328.js -#js1_5/extensions/regress-50447.js -#js1_5/extensions/regress-311161.js +# program too large/complex; could have better error message +js1_5/Regress/regress-111557.js +js1_5/Regress/regress-155081-2.js +js1_5/Regress/regress-155081.js +js1_5/extensions/regress-311161.js + +# Missing line number information on error +js1_5/Regress/regress-167328.js +js1_5/extensions/regress-50447.js +js1_5/Exceptions/regress-257751.js + diff --git a/mozilla/js/rhino/toolsrc/org/mozilla/javascript/tools/resources/Messages.properties b/mozilla/js/rhino/toolsrc/org/mozilla/javascript/tools/resources/Messages.properties index 119dd851454..4009efc94fd 100644 --- a/mozilla/js/rhino/toolsrc/org/mozilla/javascript/tools/resources/Messages.properties +++ b/mozilla/js/rhino/toolsrc/org/mozilla/javascript/tools/resources/Messages.properties @@ -57,7 +57,7 @@ msg.shell.usage =\ Valid options are:\n\ \ -?, -help Displays help messages.\n\ \ -w Enable warnings.\n\ - \ -version 100|110|120|130|140|150|160\n\ + \ -version 100|110|120|130|140|150|160|170\n\ \ Set a specific language version.\n\ \ -opt [-1|0-9] Set optimization level.\n\ \ -f script-filename Execute script file.\n\ @@ -66,7 +66,6 @@ msg.shell.usage =\ \ -strict Enable strict mode warnings.\n\ \ -fatal-warnings Treat warnings as errors. - msg.help =\ \n\ Command Description \n\