Bug 1167029 - Remove support for let blocks. (r=jorendorff)
authorShu-yu Guo <shu@rfrn.org>
Mon, 26 Oct 2015 14:13:25 -0700
changeset 304802 a6f01cc9c740cc536a8d4e73565e1ee0db55427b
parent 304801 a944e7136866c0a95a0ef18918d04840c4905bf5
child 304803 d70472571f1d0313456c99d8f34e3ecbc9831cfe
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1167029
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1167029 - Remove support for let blocks. (r=jorendorff)
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/jit-test/lib/syntax.js
js/src/jit-test/tests/arguments/bug956173.js
js/src/jit-test/tests/auto-regress/bug1147907.js
js/src/jit-test/tests/auto-regress/bug475658.js
js/src/jit-test/tests/auto-regress/bug496251.js
js/src/jit-test/tests/auto-regress/bug521163.js
js/src/jit-test/tests/basic/bug590006.js
js/src/jit-test/tests/basic/bug601398.js
js/src/jit-test/tests/basic/bug601401.js
js/src/jit-test/tests/basic/bug639311.js
js/src/jit-test/tests/basic/bug646968-7.js
js/src/jit-test/tests/basic/bug646968-8.js
js/src/jit-test/tests/basic/bug667504-syntax.js
js/src/jit-test/tests/basic/bug727921.js
js/src/jit-test/tests/basic/bug806522.js
js/src/jit-test/tests/basic/destructuring-default.js
js/src/jit-test/tests/basic/destructuring-rest.js
js/src/jit-test/tests/basic/eif-generator.js
js/src/jit-test/tests/basic/expression-autopsy.js
js/src/jit-test/tests/basic/testAliasedLet.js
js/src/jit-test/tests/basic/testBadLetBodyWithArguments.js
js/src/jit-test/tests/basic/testBug703857.js
js/src/jit-test/tests/basic/testBug714650.js
js/src/jit-test/tests/basic/testBug776191.js
js/src/jit-test/tests/basic/testClosureIncrSideExit.js
js/src/jit-test/tests/basic/testDynamicLookup.js
js/src/jit-test/tests/basic/testDynamicUsage.js
js/src/jit-test/tests/basic/testGlobalOptimize-2.js
js/src/jit-test/tests/basic/testGlobalOptimize-3.js
js/src/jit-test/tests/basic/testGlobalOptimize-5.js
js/src/jit-test/tests/basic/testGlobalOptimize-6.js
js/src/jit-test/tests/basic/testLet.js
js/src/jit-test/tests/basic/testLetOverridingArgs.js
js/src/jit-test/tests/basic/testNonStubGetter.js
js/src/jit-test/tests/basic/testReplaceWithLambda.js
js/src/jit-test/tests/basic/testScriptCloning.js
js/src/jit-test/tests/basic/testStaticEvalScope.js
js/src/jit-test/tests/bug1213574.js
js/src/jit-test/tests/closures/bug496922.js
js/src/jit-test/tests/closures/bug540131.js
js/src/jit-test/tests/closures/flat-closure-2.js
js/src/jit-test/tests/closures/flat-closure-7.js
js/src/jit-test/tests/closures/incr-exit-2.js
js/src/jit-test/tests/closures/incr-exit-3.js
js/src/jit-test/tests/closures/incr-exit.js
js/src/jit-test/tests/closures/lambda-light.js
js/src/jit-test/tests/closures/t020.js
js/src/jit-test/tests/debug/Environment-callee-01.js
js/src/jit-test/tests/debug/Environment-getVariable-03.js
js/src/jit-test/tests/debug/Environment-getVariable-12.js
js/src/jit-test/tests/debug/Environment-identity-03.js
js/src/jit-test/tests/debug/Environment-setVariable-07.js
js/src/jit-test/tests/debug/Environment-type-01.js
js/src/jit-test/tests/debug/Environment-variables.js
js/src/jit-test/tests/debug/Frame-eval-14.js
js/src/jit-test/tests/debug/Frame-evalWithBindings-01.js
js/src/jit-test/tests/debug/bug1188334.js
js/src/jit-test/tests/for-of/syntax-2.js
js/src/jit-test/tests/gc/jsscript-mark-children.js
js/src/jit-test/tests/jaeger/bug549521.js
js/src/jit-test/tests/jaeger/bug555922.js
js/src/jit-test/tests/jaeger/bug582897.js
js/src/jit-test/tests/jaeger/bug582898.js
js/src/jit-test/tests/jaeger/chunk/bug712265.js
js/src/js.msg
js/src/jsapi-tests/testEnclosingFunction.cpp
js/src/tests/js1_7/block/browser.js
js/src/tests/js1_7/block/order-of-operation.js
js/src/tests/js1_7/block/regress-341939.js
js/src/tests/js1_7/block/regress-343765.js
js/src/tests/js1_7/block/regress-344139.js
js/src/tests/js1_7/block/regress-344370.js
js/src/tests/js1_7/block/regress-348685.js
js/src/tests/js1_7/block/regress-349283.js
js/src/tests/js1_7/block/regress-349298.js
js/src/tests/js1_7/block/regress-349507.js
js/src/tests/js1_7/block/regress-349962.js
js/src/tests/js1_7/block/regress-350279.js
js/src/tests/js1_7/block/regress-350730.js
js/src/tests/js1_7/block/regress-350793-01.js
js/src/tests/js1_7/block/regress-351606.js
js/src/tests/js1_7/block/regress-352092.js
js/src/tests/js1_7/block/regress-352267.js
js/src/tests/js1_7/block/regress-352422.js
js/src/tests/js1_7/block/regress-352609.js
js/src/tests/js1_7/block/regress-352624.js
js/src/tests/js1_7/block/regress-352786.js
js/src/tests/js1_7/block/regress-352907.js
js/src/tests/js1_7/block/regress-357754.js
js/src/tests/js1_7/block/regress-358508.js
js/src/tests/js1_7/block/regress-376410.js
js/src/tests/js1_7/block/regress-396900.js
js/src/tests/js1_7/block/shell.js
js/src/tests/js1_7/extensions/regress-349619.js
js/src/tests/js1_7/extensions/regress-366668-02.js
js/src/tests/js1_7/regress/regress-353079.js
js/src/tests/js1_7/regress/regress-355832-01.js
js/src/tests/js1_7/regress/regress-355832-02.js
js/src/tests/js1_7/regress/regress-373827-01.js
js/src/tests/js1_7/regress/regress-373827-02.js
js/src/tests/js1_7/regress/regress-414553.js
js/src/tests/js1_8/regress/regress-471660.js
js/src/tests/js1_8_1/regress/regress-452498-050.js
js/src/tests/js1_8_1/regress/regress-452498-053.js
js/src/tests/js1_8_1/regress/regress-496922.js
js/src/tests/js1_8_1/regress/regress-522123.js
js/src/tests/js1_8_1/strict/let-block-eval-arguments.js
js/src/tests/js1_8_5/reflect-parse/lexicals.js
js/src/tests/js1_8_5/regress/regress-541255-3.js
js/src/tests/js1_8_5/regress/regress-554955-1.js
js/src/tests/js1_8_5/regress/regress-554955-3.js
js/src/tests/js1_8_5/regress/regress-554955-4.js
js/src/tests/js1_8_5/regress/regress-554955-6.js
js/src/tests/js1_8_5/regress/regress-673070-1.js
js/src/tests/js1_8_5/regress/regress-673070-2.js
js/src/vm/Xdr.h
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -4063,67 +4063,16 @@ Parser<FullParseHandler>::pushLetScope(H
 template <>
 SyntaxParseHandler::Node
 Parser<SyntaxParseHandler>::pushLetScope(HandleStaticBlockObject blockObj, AutoPushStmtInfoPC& stmt)
 {
     JS_ALWAYS_FALSE(abortIfSyntaxParser());
     return SyntaxParseHandler::NodeFailure;
 }
 
-/*
- * Parse a let block statement.
- * In both cases, bindings are not hoisted to the top of the enclosing block
- * and thus must be carefully injected between variables() and the let body.
- */
-template <typename ParseHandler>
-typename ParseHandler::Node
-Parser<ParseHandler>::deprecatedLetBlock(YieldHandling yieldHandling)
-{
-    MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LET));
-
-    RootedStaticBlockObject blockObj(context, StaticBlockObject::create(context));
-    if (!blockObj)
-        return null();
-    // Initialize the enclosing scope manually for the call to |variables|
-    // below.
-    blockObj->initEnclosingScopeFromParser(pc->innermostStaticScope());
-
-    uint32_t begin = pos().begin;
-
-    MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_LET);
-
-    Node vars = variables(yieldHandling, PNK_LET, NotInForInit, nullptr, blockObj, DontHoistVars);
-    if (!vars)
-        return null();
-
-    MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_LET);
-
-    AutoPushStmtInfoPC stmtInfo(*this, StmtType::BLOCK);
-    Node block = pushLetScope(blockObj, stmtInfo);
-    if (!block)
-        return null();
-
-    MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_LET);
-
-    Node expr = statements(yieldHandling);
-    if (!expr)
-        return null();
-    MUST_MATCH_TOKEN_MOD(TOK_RC, TokenStream::Operand, JSMSG_CURLY_AFTER_LET);
-
-    addTelemetry(JSCompartment::DeprecatedLetBlock);
-    if (!report(ParseWarning, pc->sc->strict(), expr, JSMSG_DEPRECATED_LET_BLOCK))
-        return null();
-
-    handler.setLexicalScopeBody(block, expr);
-
-    TokenPos letPos(begin, pos().end);
-
-    return handler.newLetBlock(vars, block, letPos);
-}
-
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::blockStatement(YieldHandling yieldHandling)
 {
     MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LC));
 
     AutoPushStmtInfoPC stmtInfo(*this, StmtType::BLOCK);
     if (!stmtInfo.generateBlockId())
@@ -4527,55 +4476,16 @@ Parser<FullParseHandler>::lexicalDeclara
 template <>
 SyntaxParseHandler::Node
 Parser<SyntaxParseHandler>::lexicalDeclaration(YieldHandling, bool)
 {
     JS_ALWAYS_FALSE(abortIfSyntaxParser());
     return SyntaxParseHandler::NodeFailure;
 }
 
-template <>
-ParseNode*
-Parser<FullParseHandler>::letDeclarationOrBlock(YieldHandling yieldHandling)
-{
-    handler.disableSyntaxParser();
-
-    /* Check for a let statement. */
-    TokenKind tt;
-    if (!tokenStream.peekToken(&tt))
-        return null();
-    if (tt == TOK_LP) {
-        ParseNode* node = deprecatedLetBlock(yieldHandling);
-        if (!node)
-            return nullptr;
-
-        MOZ_ASSERT(node->isKind(PNK_LETBLOCK));
-        MOZ_ASSERT(node->isArity(PN_BINARY));
-        return node;
-    }
-
-    ParseNode* decl = lexicalDeclaration(yieldHandling, /* isConst = */ false);
-    if (!decl)
-        return nullptr;
-
-    // let-declarations at global scope are currently treated as plain old var.
-    // See bug 589199.
-    MOZ_ASSERT(decl->isKind(PNK_LET) || decl->isKind(PNK_VAR));
-    MOZ_ASSERT(decl->isArity(PN_LIST));
-    return decl;
-}
-
-template <>
-SyntaxParseHandler::Node
-Parser<SyntaxParseHandler>::letDeclarationOrBlock(YieldHandling yieldHandling)
-{
-    JS_ALWAYS_FALSE(abortIfSyntaxParser());
-    return SyntaxParseHandler::NodeFailure;
-}
-
 template<>
 ParseNode*
 Parser<FullParseHandler>::newBoundImportForCurrentName()
 {
     Node importNode = newName(tokenStream.currentName());
     if (!importNode)
         return null();
 
@@ -6866,23 +6776,22 @@ Parser<ParseHandler>::statement(YieldHan
       // ClassDeclaration[?Yield]
       case TOK_CLASS:
         if (!abortIfSyntaxParser())
             return null();
         return classDefinition(yieldHandling, ClassStatement, NameRequired);
 
       // LexicalDeclaration[In, ?Yield]
       case TOK_LET:
+      case TOK_CONST:
+        if (!abortIfSyntaxParser())
+            return null();
         // [In] is the default behavior, because for-loops currently specially
         // parse their heads to handle |in| in this situation.
-        return letDeclarationOrBlock(yieldHandling);
-      case TOK_CONST:
-        if (!abortIfSyntaxParser())
-            return null();
-        return lexicalDeclaration(yieldHandling, /* isConst = */ true);
+        return lexicalDeclaration(yieldHandling, /* isConst = */ tt == TOK_CONST);
 
       // ImportDeclaration (only inside modules)
       case TOK_IMPORT:
         return importDeclaration();
 
       // ExportDeclaration (only inside modules)
       case TOK_EXPORT:
         return exportDeclaration();
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -677,17 +677,16 @@ class Parser : private JS::AutoGCRooter,
     Node returnStatement(YieldHandling yieldHandling);
     Node withStatement(YieldHandling yieldHandling);
     Node labeledStatement(YieldHandling yieldHandling);
     Node throwStatement(YieldHandling yieldHandling);
     Node tryStatement(YieldHandling yieldHandling);
     Node debuggerStatement();
 
     Node lexicalDeclaration(YieldHandling yieldHandling, bool isConst);
-    Node letDeclarationOrBlock(YieldHandling yieldHandling);
     Node importDeclaration();
     Node exportDeclaration();
     Node expressionStatement(YieldHandling yieldHandling,
                              InvokedPrediction invoked = PredictUninvoked);
     Node variables(YieldHandling yieldHandling,
                    ParseNodeKind kind,
                    ForInitLocation location,
                    bool* psimple = nullptr, StaticBlockObject* blockObj = nullptr,
@@ -750,17 +749,16 @@ class Parser : private JS::AutoGCRooter,
     Node comprehensionTail(GeneratorKind comprehensionKind);
     Node comprehensionIf(GeneratorKind comprehensionKind);
     Node comprehensionFor(GeneratorKind comprehensionKind);
     Node comprehension(GeneratorKind comprehensionKind);
     Node arrayComprehension(uint32_t begin);
     Node generatorComprehension(uint32_t begin);
 
     bool argumentList(YieldHandling yieldHandling, Node listNode, bool* isSpread);
-    Node deprecatedLetBlock(YieldHandling yieldHandling);
     Node destructuringExpr(YieldHandling yieldHandling, BindData<ParseHandler>* data,
                            TokenKind tt);
     Node destructuringExprWithoutYield(YieldHandling yieldHandling, BindData<ParseHandler>* data,
                                        TokenKind tt, unsigned msg);
 
     Node newBoundImportForCurrentName();
     bool namedImportsOrNamespaceImport(TokenKind tt, Node importSpecSet);
     bool addExportName(JSAtom* exportName);
--- a/js/src/jit-test/lib/syntax.js
+++ b/js/src/jit-test/lib/syntax.js
@@ -1149,32 +1149,16 @@ function test_syntax(postfixes, check_er
 
   test_fun_arg("");
   test_fun_arg("a ");
   test_fun_arg("... ");
   test_fun_arg("...a ");
 
   // ==== Legacy ====
 
-  // let statement
-
-  test("let ( ");
-  test("let ( x ");
-  test("let ( x = ");
-  test("let ( x = 1 ");
-  test("let ( x = 1, ");
-  test("let ( x = 1, y ");
-  test("let ( x = 1, y = ");
-  test("let ( x = 1, y = 2 ");
-  test("let ( x = 1, y = 2 ) ");
-  test("let ( x = 1, y = 2 ) { ");
-  test("let ( x = 1, y = 2 ) { x ");
-  test("let ( x = 1, y = 2 ) { x; ");
-  test("let ( x = 1, y = 2 ) { x; } ");
-
   // Expression closures
 
   test("function f() 1 ");
   test("function f() 1; ");
   test("(function () 1 ");
   test("(function () 1); ");
 
   // Legacy generator
--- a/js/src/jit-test/tests/arguments/bug956173.js
+++ b/js/src/jit-test/tests/arguments/bug956173.js
@@ -1,6 +1,7 @@
 function foo() {
-    let (x=arguments) {
+    {
+      let x=arguments;
       return function() { return x; };
     }
 }
 foo()();
--- a/js/src/jit-test/tests/auto-regress/bug1147907.js
+++ b/js/src/jit-test/tests/auto-regress/bug1147907.js
@@ -3,11 +3,12 @@ var evalInFrame = (function (global) {
   var dbg = new dbgGlobal.Debugger();
   return function evalInFrame(upCount, code) {
     dbg.addDebuggee(global);
     var frame = dbg.getNewestFrame().older;
     var completion = frame.eval(code);
   };
 })(this);
 var x = 5;
-let (x = eval("x++")) {
+{
+  let x = eval("this.x++");
   evalInFrame(0, ("for (var x = 0; x < 3; ++x) { (function(){})() } "))
 }
deleted file mode 100644
--- a/js/src/jit-test/tests/auto-regress/bug475658.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Binary: cache/js-dbg-32-6739e046d870-linux
-// Flags: -j
-//
-for each (b in [2, new Number(7), 2, {}, 2, 2]) {
-    let (f = function (g) {for each (let h in [{}, {}, {}, 4, 4, {}]) {}}) {
-        f();
-    }
-    [new Number(1) for each (e in [{}, {}])];
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/auto-regress/bug496251.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// Binary: cache/js-dbg-32-9d6f5ab54933-linux
-// Flags: -j
-//
-let (z = {}) {
-    for (var i = 0; i < 4; ++i) {
-        for each (var e in [{}, 1, {}]) {
-            +(function () z)();
-        }
-    }
-}
--- a/js/src/jit-test/tests/auto-regress/bug521163.js
+++ b/js/src/jit-test/tests/auto-regress/bug521163.js
@@ -1,10 +1,11 @@
 // |jit-test| error:ReferenceError
 
 // Binary: cache/js-dbg-32-c08baee44cf4-linux
 // Flags:
 //
 for (c in [0]) {
-    let(c = __defineGetter__("", function(){})) {
+    {
+        let c = __defineGetter__("", function(){});
         eval("function w(){}")++
     }
 }
--- a/js/src/jit-test/tests/basic/bug590006.js
+++ b/js/src/jit-test/tests/basic/bug590006.js
@@ -1,11 +1,12 @@
 function f() {
     var ret;
     for (var i = 0; i < 10; ++i) {
-        let (local = 3) {
+        {
+            let local = 3;
             ret = function() { print(local++); }
         }
     }
     return ret;
 }
 f()();  // test.js:5: ReferenceError: local is not defined
 
--- a/js/src/jit-test/tests/basic/bug601398.js
+++ b/js/src/jit-test/tests/basic/bug601398.js
@@ -1,7 +1,8 @@
 (function () {
     try {} finally {
-        let(z) {
+        {
+            let z;
             return;
         }
     }
 })()
--- a/js/src/jit-test/tests/basic/bug601401.js
+++ b/js/src/jit-test/tests/basic/bug601401.js
@@ -1,5 +1,6 @@
-let(e) {
+{
+    let e;
     with({}) try {} catch (x) {} finally {
-        let(y) {}
+        { let y; }
     }
 }
--- a/js/src/jit-test/tests/basic/bug639311.js
+++ b/js/src/jit-test/tests/basic/bug639311.js
@@ -9,10 +9,10 @@ try {
     for (a = 0;; j) {
       gc()
     }
   })()
 } catch(e) {
   delete this.Math
 }
 gc()
-Reflect.parse("let(x){}")
+Reflect.parse("{ let x; }")
 gc()
--- a/js/src/jit-test/tests/basic/bug646968-7.js
+++ b/js/src/jit-test/tests/basic/bug646968-7.js
@@ -1,9 +1,10 @@
 load(libdir + "evalInFrame.js");
 
 function test(s) {
     eval(s);
-    let (y = evalInFrame(0, '3'), x = x) {
-	assertEq(x, 5);
+    {
+      let y = evalInFrame(0, '3'), x = x0;
+	    assertEq(x, 5);
     }
 }
-test('var x = 5;');
+test('var x0= 5;');
--- a/js/src/jit-test/tests/basic/bug646968-8.js
+++ b/js/src/jit-test/tests/basic/bug646968-8.js
@@ -1,7 +1,8 @@
 load(libdir + "evalInFrame.js");
 
 var x = 5;
-let (x = eval("x++")) {
+{
+    let x = eval("this.x++");
     assertEq(evalInFrame(0, "x"), 5);
 }
 assertEq(x, 6);
--- a/js/src/jit-test/tests/basic/bug667504-syntax.js
+++ b/js/src/jit-test/tests/basic/bug667504-syntax.js
@@ -1,3 +1,2 @@
 for (var x in x)
-let(x) {}
 function x() {}
--- a/js/src/jit-test/tests/basic/bug727921.js
+++ b/js/src/jit-test/tests/basic/bug727921.js
@@ -1,10 +1,11 @@
 (function() {
-    let(d) {
+    {
+        let d;
         yield
     }
 })()
 eval("\
     (function(){\
         schedulegc(5), 'a'.replace(/a/,function(){yield})\
     })\
 ")()
--- a/js/src/jit-test/tests/basic/bug806522.js
+++ b/js/src/jit-test/tests/basic/bug806522.js
@@ -1,7 +1,7 @@
 load(libdir + "asserts.js");
 
 var g = evalcx("lazy");
 assertThrowsInstanceOf(
-    () => evaluate("let (eval) {eval()}", {global: g}),
+    () => evaluate("{ let eval; eval()}", {global: g}),
     g.TypeError); // eval is not a function
-assertEq(evaluate("let (eval = parseInt) {eval()}", {global: g}), NaN);
+assertEq(evaluate("{ let eval = parseInt; eval()}", {global: g}), NaN);
--- a/js/src/jit-test/tests/basic/destructuring-default.js
+++ b/js/src/jit-test/tests/basic/destructuring-default.js
@@ -87,27 +87,16 @@ function testThrow(pattern, input) {
   return new Function('input',
     'try { throw input }' +
     'catch(' + pattern + ') {' +
     'return [a, b, c, d, e, f]; }'
   )(input);
 }
 testAll(testThrow);
 
-// XXX: Support for let blocks will be removed in bug 1023609.
-// However, they test a special code path in destructuring assignment so having
-// these tests here for now seems like a good idea.
-function testLetBlock(pattern, input) {
-  return new Function('input',
-    'let (' + pattern + ' = input)' +
-    '{ return [a, b, c, d, e, f]; }'
-  )(input);
-}
-testAll(testLetBlock);
-
 // test global const
 const [ca = 1, cb = 2] = [];
 assertEq(ca, 1);
 assertEq(cb, 2);
 
 const {a: {a: cc = 3} = {a: undefined}} = {};
 assertEq(cc, 3);
 
--- a/js/src/jit-test/tests/basic/destructuring-rest.js
+++ b/js/src/jit-test/tests/basic/destructuring-rest.js
@@ -121,20 +121,8 @@ function testThrow(pattern, input, bindi
   binding = binding || 'rest';
   return new Function('input',
     'try { throw input }' +
     'catch(' + pattern + ') {' +
     'return ' + binding + '; }'
   )(input);
 }
 testDeclaration(testThrow);
-
-// XXX: Support for let blocks will be removed in bug 1023609.
-// However, they test a special code path in destructuring assignment so having
-// these tests here for now seems like a good idea.
-function testLetBlock(pattern, input, binding) {
-  binding = binding || 'rest';
-  return new Function('input',
-    'let (' + pattern + ' = input)' +
-    '{ return ' + binding + '; }'
-  )(input);
-}
-testDeclaration(testLetBlock);
--- a/js/src/jit-test/tests/basic/eif-generator.js
+++ b/js/src/jit-test/tests/basic/eif-generator.js
@@ -1,16 +1,18 @@
 load(libdir + "evalInFrame.js");
 
 function f() {
-    let (x = 1) {
+    {
+        let x = 1;
         while (true) {
             yield evalInFrame(0, "x");
             x++;
-            let (y = 1) {
+            {
+                let y = 1;
                 yield evalInFrame(0, "++y");
                 yield evalInFrame(0, "++y");
             }
         }
     }
 }
 
 var gen = f();
@@ -27,17 +29,18 @@ gc();
 assertEq(gen.next(), 3);
 assertEq(gen.next(), 2);
 gc();
 assertEq(gen.next(), 3);
 gen = null;
 gc();
 
 function g() {
-    let (x = 1) {
+    {
+        let x = 1;
         while (true) {
             var inner = function (inc) { x += inc; return evalInFrame(0, "x") };
             assertEq(inner(0), x);
             yield inner;
             assertEq(inner(0), x);
         }
     }
 }
--- a/js/src/jit-test/tests/basic/expression-autopsy.js
+++ b/js/src/jit-test/tests/basic/expression-autopsy.js
@@ -34,30 +34,20 @@ function check(expr, expected=expr) {
             // Deoptimized function scope
             Function("o", "undef", "with (Object) {}\n" + statement),
             // Inside with
             Function("with (Object) { " + statement + " }"),
             // Closure
             Function("o", "undef", "function myfunc() { return o + undef; }\n" + statement),
             // Let definitions in a block
             Function("{ let o, undef;\n" + statement + "}"),
-            // Let block
-            Function("let (o, undef) { " + statement + " }"),
-            // Let block with some other variables
-            Function("var v1, v2; let (o, undef) { " + statement + " }"),
-            // Shadowed let block
-            Function("o", "undef", "let (o, undef) { " + statement + " }"),
             // Let in a switch
             Function("var x = 4; switch (x) { case 4: let o, undef;" + statement + "\ncase 6: break;}"),
-            // The more lets the merrier
-            Function("let (x=4, y=5) { x + y; }\nlet (a, b, c) { a + b - c; }\nlet (o, undef) {" + statement + " }"),
-            // Let destructuring
-            Function("o", "undef", "let ([] = []) {} let (o, undef) { " + statement + " }"),
             // Try-catch blocks
-            Function("o", "undef", "try { let q = 4; try { let p = 4; } catch (e) {} } catch (e) {} let (o, undef) { " + statement + " }")
+            Function("o", "undef", "try { let q = 4; try { let p = 4; } catch (e) {} } catch (e) {} { let o, undef; " + statement + " }")
         ];
 
         try {
             // Let in for-in
             check_one(expected,
                       Function("var undef, o; for (let z in [1, 2]) { " + statement + " }"),
                       err);
         } catch (ex) {
@@ -107,17 +97,17 @@ check("o[~(o)]");
 check("o[+ (o)]");
 check("o[- (o)]");
 
 
 // A few one off tests
 check_one("6", (function () { 6() }), " is not a function");
 check_one("0", (function () { Array.prototype.reverse.call('123'); }), " is read-only");
 check_one("(intermediate value)[Symbol.iterator](...).next(...).value",
-          function () { ieval("let (x) { var [a, b, [c0, c1]] = [x, x, x]; }") }, " is undefined");
+          function () { ieval("{ let x; var [a, b, [c0, c1]] = [x, x, x]; }") }, " is undefined");
 check_one("void 1", function() { (void 1)(); }, " is not a function");
 check_one("void o[1]", function() { var o = []; (void o[1])() }, " is not a function");
 
 // Manual testing for this case: the only way to trigger an error is *not* on
 // an attempted property access during destructuring, and the error message
 // invoking ToObject(null) is different: "can't convert {0} to object".
 try
 {
--- a/js/src/jit-test/tests/basic/testAliasedLet.js
+++ b/js/src/jit-test/tests/basic/testAliasedLet.js
@@ -1,10 +1,11 @@
 function f() {
-    let (x, y, z) {
+    {
+        let x, y, z;
         eval('x = 1; y = 2; z = 3');
         for (var i = 0; i < 10000; ++i) {
             assertEq(x, 1);
             assertEq(y, 2);
             assertEq(z, 3);
         }
     }
 }
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/testBadLetBodyWithArguments.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// |jit-test| error:SyntaxError
-
-function test() {
-    arguments;
-    let (arguments);
-}
--- a/js/src/jit-test/tests/basic/testBug703857.js
+++ b/js/src/jit-test/tests/basic/testBug703857.js
@@ -1,12 +1,13 @@
 Function.prototype.X = 42;
 function ownProperties() {
     var props = {};
     var r = function () {};
     for (var a in r) {
-        let (a = function() { for (var r=0;r<6;++r) ++a; }) {
+        {
+            let a = function() { for (var r=0;r<6;++r) ++a; };
             a();
         }
         props[a] = true;
     }
 }
 ownProperties();
--- a/js/src/jit-test/tests/basic/testBug714650.js
+++ b/js/src/jit-test/tests/basic/testBug714650.js
@@ -1,9 +1,10 @@
-let ([] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
+{ 
+ let [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
@@ -25,12 +26,11 @@ let ([] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
      [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [],
-     [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [])
-{
+     [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [];
     print("ok");
 }
--- a/js/src/jit-test/tests/basic/testBug776191.js
+++ b/js/src/jit-test/tests/basic/testBug776191.js
@@ -1,7 +1,8 @@
 (function() {
-    let(a, b, c) {
+    {
+      let a, b, c;
         ((function() {
-            with({}) let(b) { ((function() { c = 0 })()) }
+            with({}) { { let b; { ((function() { c = 0 })()) } } }
         })())
     }
 })()
--- a/js/src/jit-test/tests/basic/testClosureIncrSideExit.js
+++ b/js/src/jit-test/tests/basic/testClosureIncrSideExit.js
@@ -1,17 +1,19 @@
 function testClosureIncrSideExit() {
-    let(f = function (y) {
-        let(ff = function (g) {
+    {
+      let f = function (y) {
+        {
+          let ff = function (g) {
             for each(let h in g) {
                 if (++y > 5) {
                     return 'ddd';
                 }
             }
             return 'qqq';
-        }) {
+        };
             return ff(['', null, '', false, '', '', null]);
         }
-    }) {
+      };
         return f(-1);
     }
 }
 assertEq(testClosureIncrSideExit(), "ddd");
--- a/js/src/jit-test/tests/basic/testDynamicLookup.js
+++ b/js/src/jit-test/tests/basic/testDynamicLookup.js
@@ -34,28 +34,22 @@
 (function() { var x = 2; (function() { eval("(function() { eval('assertEq(x, 2)') })()") })() })();
 (function() { var x = 2; (function() { eval("(function() { eval('(function() { assertEq(x, 2) })()') })()") })() })();
 
 (function() { var [x] = [2]; eval('assertEq(x, 2)') })();
 (function() { var [x] = [2]; (function() { assertEq(x, 2) })() })();
 (function() { var [x] = [2]; (function() { eval('assertEq(x, 2)') })() })();
 (function() { for (var [x] = [2];;) { return (function() { return assertEq(x, 2); })() } })();
 (function() { for (var [x] = [2];;) { return (function() { return eval('assertEq(x, 2)'); })() } })();
-(function() { let ([x] = [2]) { eval('assertEq(x, 2)') } })();
-(function() { let ([x] = [2]) { (function() { assertEq(x, 2) })() } })();
-(function() { let ([x] = [2]) { (function() { eval('assertEq(x, 2)') })() } })();
 
 (function() { var {y:x} = {y:2}; eval('assertEq(x, 2)') })();
 (function() { var {y:x} = {y:2}; (function() { assertEq(x, 2) })() })();
 (function() { var {y:x} = {y:2}; (function() { eval('assertEq(x, 2)') })() })();
 (function() { for (var {y:x} = {y:2};;) { return (function() { return assertEq(x, 2); })() } })();
 (function() { for (var {y:x} = {y:2};;) { return (function() { return eval('assertEq(x, 2)'); })() } })();
-(function() { let ({y:x} = {y:2}) { eval('assertEq(x, 2)') } })();
-(function() { let ({y:x} = {y:2}) { (function() { assertEq(x, 2) })() } })();
-(function() { let ({y:x} = {y:2}) { (function() { eval('assertEq(x, 2)') })() } })();
 
 (function([x]) { eval('assertEq(x, 2)') })([2]);
 (function([x]) { (function() { assertEq(x, 2) })() })([2]);
 (function([x]) { (function() { eval('assertEq(x, 2)') })() })([2]);
 
 (function f() { assertEq(f.length, 0) })();
 (function f() { eval('assertEq(f.length, 0)') })();
 (function f() { (function f(x) { eval('assertEq(f.length, 1)') })() })();
--- a/js/src/jit-test/tests/basic/testDynamicUsage.js
+++ b/js/src/jit-test/tests/basic/testDynamicUsage.js
@@ -32,46 +32,46 @@ assertEq((function(a) { var [x,y] = a; e
 assertEq((function(a) { var [x,y] = a; x += y; return eval('x') })([1,2]), 3);
 assertEq((function(a) { var [x,y] = a; (function() { x += y })(); return x })([1,2]), 3);
 assertEq((function(a) { var [x,y] = a; x += y; return (function() x)() })([1,2]), 3);
 assertEq((function(a,x,y) { [x,y] = a; (function() { eval('x += y') })(); return x })([1,2]), 3);
 assertEq((function(a,x,y) { [x,y] = a; x += y; return (function() eval('x'))() })([1,2]), 3);
 
 assertEq((function() { var [x,y] = [1,2]; x += y; return (function() x)() })(), 3);
 assertEq((function() { var [x,y] = [1,2]; (function() x += y)(); return x })(), 3);
-assertEq((function() { let ([x,y] = [1,2]) { x += y; return (function() x)() } })(), 3);
-assertEq((function() { let ([x,y] = [1,2]) { (function() x += y)(); return x } })(), 3);
+assertEq((function() { { let [x,y] = [1,2]; x += y; return (function() x)() } })(), 3);
+assertEq((function() { { let [x,y] = [1,2]; (function() x += y)(); return x } })(), 3);
 
 assertEq((function([x,y]) { (function() { x += y })(); return x })([1,2]), 3);
 assertEq((function([x,y]) { x += y; return (function() x)() })([1,2]), 3);
 assertEq((function([[l,x],[m,y]]) { (function() { x += y })(); return x })([[0,1],[0,2]]), 3);
 assertEq((function([[l,x],[m,y]]) { x += y; return (function() x)() })([[0,1],[0,2]]), 3);
 assertEq((function([x,y]) { (function() { eval('x += y') })(); return x })([1,2]), 3);
 assertEq((function([x,y]) { x += y; return (function() eval('x'))() })([1,2]), 3);
 assertEq((function() { try { throw [1,2] } catch([x,y]) { eval('x += y'); return x }})(), 3);
 assertEq((function() { try { throw [1,2] } catch([x,y]) { x += y; return eval('x') }})(), 3);
 assertEq((function() { try { throw [1,2] } catch([x,y]) { (function() { x += y })(); return x }})(), 3);
 assertEq((function() { try { throw [1,2] } catch([x,y]) { x += y; return (function() x)() }})(), 3);
 assertEq((function() { try { throw [1,2] } catch([x,y]) { (function() { eval('x += y') })(); return x }})(), 3);
 assertEq((function() { try { throw [1,2] } catch([x,y]) { x += y; return (function() eval('x'))() }})(), 3);
 
 assertEq((function(a) { let [x,y] = a; (function() { x += y })(); return x })([1,2]), 3);
 assertEq((function(a) { let [x,y] = a; x += y; return (function() x)() })([1,2]), 3);
-assertEq((function(a) { let ([x,y] = a) { (function() { x += y })(); return x } })([1,2]), 3);
-assertEq((function(a) { let ([x,y] = a) { x += y; return (function() x)() } })([1,2]), 3);
-assertEq((function(a) { let ([[l, x],[m, y]] = a) { (function() { x += y })(); return x } })([[0,1],[0,2]]), 3);
-assertEq((function(a) { let ([[l, x],[m, y]] = a) { x += y; return (function() x)() } })([[0,1],[0,2]]), 3);
+assertEq((function(a) { { let [x,y] = a; (function() { x += y })(); return x } })([1,2]), 3);
+assertEq((function(a) { { let [x,y] = a; x += y; return (function() x)() } })([1,2]), 3);
+assertEq((function(a) { { let [[l, x],[m, y]] = a; (function() { x += y })(); return x } })([[0,1],[0,2]]), 3);
+assertEq((function(a) { { let [[l, x],[m, y]] = a; x += y; return (function() x)() } })([[0,1],[0,2]]), 3);
 
 assertEq((function() { let x = 3; return (function() { return x })() })(), 3);
 assertEq((function() { let g = function() { return x }; let x = 3; return g() })(), 3);
 
-assertEq((function() { let (x = 3) { return (function() { return x })() } })(), 3);
-assertEq((function() { let (x = 3) { (function() { assertEq(x, 3) })(); return x } })(), 3);
-assertEq((function() { let (x = 2) { x = 3; return (function() { return x })() } })(), 3);
-assertEq((function() { let (x = 1) { let (x = 3) { (function() { assertEq(x,3) })() } return x } })(), 1);
+assertEq((function() { { let x = 3; return (function() { return x })() } })(), 3);
+assertEq((function() { { let x = 3; (function() { assertEq(x, 3) })(); return x } })(), 3);
+assertEq((function() { { let x = 2; x = 3; return (function() { return x })() } })(), 3);
+assertEq((function() { { let x = 1; { let x = 3; (function() { assertEq(x,3) })() } return x } })(), 1);
 
 assertEq((function() { try { throw 3 } catch (e) { (function(){assertEq(e,3)})(); return e } })(), 3);
 assertEq((function() { try { throw 3 } catch (e) { assertEq(e, 3); return (function() e)() } })(), 3);
 assertEq((function() { try { throw 3 } catch (e) { (function(){eval('assertEq(e,3)')})(); return e } })(), 3);
 
 assertEq((function() { return [(function() i)() for (i of [3])][0] })(), 3);
 assertEq((function() { return [((function() i++)(), i) for (i of [2])][0] })(), 3);
 assertEq((function() { return [(i++, (function() i)()) for (i of [2])][0] })(), 3);
--- a/js/src/jit-test/tests/basic/testGlobalOptimize-2.js
+++ b/js/src/jit-test/tests/basic/testGlobalOptimize-2.js
@@ -1,9 +1,8 @@
 var test;
 {
-  let (a = 5) {
+  let a = 5;
     with ({a: 2}) {
       test = (function () { return a; })();
     }
-  }
 }
 assertEq(test, 2);
--- a/js/src/jit-test/tests/basic/testGlobalOptimize-3.js
+++ b/js/src/jit-test/tests/basic/testGlobalOptimize-3.js
@@ -1,9 +1,10 @@
 var test;
 {
   with ({a: 2}) {
-    let (a = 5) {
+    {
+      let a = 5;
       test = (function () { return a; })();
     }
   }
 }
 assertEq(test, 5);
--- a/js/src/jit-test/tests/basic/testGlobalOptimize-5.js
+++ b/js/src/jit-test/tests/basic/testGlobalOptimize-5.js
@@ -1,10 +1,11 @@
 var test;
 function f() {
-  let (a = 5) {
+  {
+    let a = 5;
     with ({a: 2}) {
       test = (function () { return a;} )();
     }
   }
 }
 f();
 assertEq(test, 2);
--- a/js/src/jit-test/tests/basic/testGlobalOptimize-6.js
+++ b/js/src/jit-test/tests/basic/testGlobalOptimize-6.js
@@ -1,10 +1,11 @@
 var test;
 function f() {
   with ({a: 2}) {
-    let (a = 5) {
+    {
+      let a = 5;
       test = (function () { return a; })();
     }
   }
 }
 f();
 assertEq(test, 5);
--- a/js/src/jit-test/tests/basic/testLet.js
+++ b/js/src/jit-test/tests/basic/testLet.js
@@ -63,120 +63,25 @@ function isReferenceError(str)
         (new Function(str))();
     } catch(e) {
         assertEq(e instanceof ReferenceError, true);
         caught = true;
     }
     assertEq(caught, true);
 }
 
-// let expr
-isParseError('return let (y) x;');
-isParseError('return let (x) "" + x;', 'unicorns', 'undefined');
-isParseError('return let (y = x) (y++, "" + y);', 'unicorns', 'NaN');
-isParseError('return let (y = 1) (y = x, y);');
-isParseError('return let ([] = x) x;');
-isParseError('return let (x = {a: x}) x.a;');
-isParseError('return let ({a: x} = {a: x}) x;');
-isParseError('return let ([x] = [x]) x;');
-isParseError('return let ({0: x} = [x]) x;');
-isParseError('return let ({0: []} = [[]]) x;');
-isParseError('return let ([, ] = x) x;');
-isParseError('return let ([, , , , ] = x) x;');
-isParseError('return let (x = x) x;');
-isParseError('return let (x = eval("x")) x;');
-isParseError('return let (x = (let (x = x + 1) x) + 1) x;', 1, 3);
-isParseError('return let (x = (let (x = eval("x") + 1) eval("x")) + 1) eval("x");', 1, 3);
-isParseError('return let (x = x + 1, y = x) y;');
-isParseError('return let (x = x + 1, [] = x, /*[[, , ]] = x, */y = x) y;');
-isParseError('return let ([{a: x}] = x, [, {b: y}] = x) let (x = x + 1, y = y + 2) x + y;', [{a:"p"},{b:"p"}], "p1p2");
-isParseError('return let ([] = []) x;');
-isParseError('return let ([] = [x]) x;');
-isParseError('return let ([a] = (1, [x])) a;');
-isParseError('return let ([a] = (1, x, 1, x)) a;', ['ponies']);
-isParseError('return let ([x] = [x]) x;');
-isParseError('return let ([[a, [b, c]]] = [[x, []]]) a;');
-isParseError('return let ([x, y] = [x, x + 1]) x + y;', 1, 3);
-isParseError('return let ([x, y, z] = [x, x + 1, x + 2]) x + y + z;', 1, 6);
-isParseError('return let ([[x]] = [[x]]) x;');
-isParseError('return let ([x, y] = [x, x + 1]) x;');
-isParseError('return let ([x, [y, z]] = [x, x + 1]) x;');
-isParseError('return let ([{x: [x]}, {y1: y, z1: z}] = [x, x + 1]) x;',{x:['ponies']});
-isParseError('return let (x = (3, x)) x;');
-isParseError('return let (x = x + "s") x;', 'ponie');
-isParseError('return let ([x] = (3, [x])) x;');
-isParseError('return let (y = x) function () {return eval("y");}();');
-isParseError('return let (y = x) (eval("var y = 2"), y);', 'ponies', 2);
-isParseError('"use strict";return let (y = x) (eval("var y = 2"), y);');
-isParseError('this.y = x;return let (y = 1) this.eval("y");');
-isParseError('try {let (x = x) eval("throw x");} catch (e) {return e;}');
-isParseError('try {return let (x = eval("throw x")) x;} catch (e) {return e;}');
-isParseError('let (x = 1, x = 2) x');
-isParseError('let ([x, y] = a, {a:x} = b) x');
-isParseError('let ([x, y, x] = a) x');
-isParseError('let ([x, [y, [x]]] = a) x');
-isParseError('let (x = function() { return x}) x()return x;');
-isParseError('(let (x = function() { return x}) x())return x;');
-
-// let block
-test('let (y) {return x;}');
-test('let (y = x) {y++;return "" + y;}', 'unicorns', 'NaN');
-test('let (y = 1) {y = x;return y;}');
-test('let (x) {return "" + x;}', 'unicorns', 'undefined');
-test('let ([] = x) {return x;}');
-test('let (x) {}return x;');
-test('let (x = {a: x}) {return x.a;}');
-test('let ({a: x} = {a: x}) {return x;}');
-test('let ([x] = [x]) {return x;}');
-test('let ({0: x} = [x]) {return x;}');
-test('let ({0: []} = [[]]) {return x;}');
-test('let ([, ] = x) {return x;}');
-test('let ([, , , , ] = x) {return x;}');
-test('let (x = x) {return x;}');
-test('let (x = eval("x")) {return x;}');
-isParseError('let (x = (let (x = x + 1) x) + 1) {return x;}', 1, 3);
-isParseError('let (x = (let (x = eval("x") + 1) eval("x")) + 1) {return eval("x");}', 1, 3);
-test('let (x = x + 1, y = x) {return y;}');
-test('let (x = x + 1, [] = x, [[, , ]] = x, y = x) {return y;}');
-test('let ([{a: x}] = x, [, {b: y}] = x) {let (x = x + 1, y = y + 2) {return x + y;}}', [{a:"p"},{b:"p"}], "p1p2");
-test('let ([] = []) {return x;}');
-test('let ([] = [x]) {return x;}');
-test('let ([a] = (1, [x])) {return a;}');
-test('let ([a] = (1, x, 1, x)) {return a;}', ['ponies']);
-test('let ([x] = [x]) {return x;}');
-test('let ([[a, [b, c]]] = [[x, []]]) {return a;}');
-test('let ([x, y] = [x, x + 1]) {return x + y;}', 1, 3);
-test('let ([x, y, z] = [x, x + 1, x + 2]) {return x + y + z;}', 1, 6);
-test('let ([[x]] = [[x]]) {return x;}');
-test('let ([x, y] = [x, x + 1]) {return x;}');
-test('let ([x, [y, z]] = [x, x + 1]) {return x;}');
-test('let ([{x: [x]}, {y1: y, z1: z}] = [x, x + 1]) {return x;}',{x:['ponies']});
-test('let (y = x[1]) {let (x = x[0]) {try {let (y = "unicorns") {throw y;}} catch (e) {return x + y;}}}', ['pon','ies']);
-isParseError('let (x = x) {try {let (x = "unicorns") eval("throw x");} catch (e) {return x;}}');
-test('let (y = x) {return function () {return eval("y");}();}');
-test('return eval("let (y = x) {y;}");');
-isRuntimeParseError('let (y = x) {eval("var y = 2");return y;}', 'ponies');
-test('"use strict";let (y = x) {eval("var y = 2");return y;}');
-test('this.y = x;let (y = 1) {return this.eval("y");}');
-isParseError('let (x = 1, x = 2) {x}');
-isParseError('let ([x, y] = a, {a:x} = b) {x}');
-isParseError('let ([x, y, x] = a) {x}');
-isParseError('let ([x, [y, [x]]] = a) {x}');
-
 // var declarations
 test('var y;return x;');
 test('var y = x;return x;');
 test('var [] = x;return x;');
 test('var [, ] = x;return x;');
 test('var [, , , , ] = x;return x;');
 test('var x = x;return x;');
 test('var y = y;return "" + y;', 'unicorns', 'undefined');
 test('var x = eval("x");return x;');
-isParseError('var x = (let (x = x + 1) x) + 1;return x;', 1, 3);
-isParseError('var x = (let (x = eval("x") + 1) eval("x")) + 1;return eval("x");', 1, 3);
 test('var X = x + 1, y = x;return y;');
 test('var X = x + 1, [] = X, [[, , ]] = X, y = x;return y;');
 test('var [{a: X}] = x, [, {b: y}] = x;var X = X + 1, y = y + 2;return X + y;', [{a:"p"},{b:"p"}], "p1p2");
 test('var [x] = [x];return x;');
 test('var [[a, [b, c]]] = [[x, []]];return a;');
 test('var [y] = [x];return y;');
 test('var [a] = (1, [x]);return a;');
 test('var [a] = (1, x, 1, x);return a;', ['ponies']);
@@ -193,63 +98,47 @@ test('if (x) {var z = y;var [y] = x;z +=
 // let declaration in context
 test('if (x) {let y;return x;}');
 test('if (x) {let x;return "" + x;}', 'unicorns', 'undefined');
 test('if (x) {let y = x;return x;}');
 test('if (x) {let y = x;return x;}');
 test('if (x) {let [] = x;return x;}');
 test('if (x) {let [, ] = x;return x;}');
 test('if (x) {let [, , , , ] = x;return x;}');
-isParseError('if (x) {let y = (let (x = x + 1) x) + 1;return y;}', 1, 3);
-isParseError('if (x) {let y = (let (x = eval("x") + 1) eval("x")) + 1;return eval("y");}', 1, 3);
 test('if (x) {let X = x + 1, y = x;return y;}');
 test('if (x) {let X = x + 1, [] = X, [[, , ]] = X, y = x;return y;}');
 test('if (x) {let [{a: X}] = x, [, {b: Y}] = x;var XX = X + 1, YY = Y + 2;return XX + YY;}', [{a:"p"},{b:"p"}], "p1p2");
 test('if (x) {let [[a, [b, c]]] = [[x, []]];return a;}');
 test('if (x) {let [X] = [x];return X;}');
 test('if (x) {let [y] = [x];return y;}');
 test('if (x) {let [a] = (1, [x]);return a;}');
 test('if (x) {let [a] = (1, x, 1, x);return a;}', ['ponies']);
 test('if (x) {let [X, y] = [x, x + 1];return X + y;}', 1, 3);
 test('if (x) {let [X, y, z] = [x, x + 1, x + 2];return X + y + z;}', 1, 6);
 test('if (x) {let [[X]] = [[x]];return X;}');
 test('if (x) {let [X, y] = [x, x + 1];return X;}');
 test('if (x) {let [X, [y, z]] = [x, x + 1];return X;}');
 test('if (x) {let [{x: [X]}, {y1: y, z1: z}] = [x, x + 1];return X;}',{x:['ponies']});
 test('if (x) {let y = x;try {let x = 1;throw 2;} catch (e) {return y;}}');
-test('let (y, [] = x) {}try {let a = b(), b;} catch (e) {return x;}');
 test('try {let x = 1;throw 2;} catch (e) {return x;}');
-test('let (y = x) {let x;return y;}');
-test('let (y = x) {let x = y;return x;}');
-test('let ([y, z] = x) {let a = x, b = y;return a;}');
-test('let ([y, z] = x, a = x, [] = x) {let b = x, c = y;return a;}');
-test('function f() {return unicorns;}try {let (x = 1) {let a, b;f();}} catch (e) {return x;}');
-test('function f() {return unicorns;}try {let (x = 1) {let a, b;}f();} catch (e) {return x;}');
 test('x.foo;{let y = x;return y;}');
 test('x.foo;if (x) {x.bar;let y = x;return y;}');
 test('if (x) {let y = x;return function () {return eval("y");}();}');
 test('return eval("let y = x; y");');
 isRuntimeParseError('if (x) {let y = x;eval("var y = 2");return y;}', 'ponies');
 test('"use strict";if (x) {let y = x;eval("var y = 2");return y;}');
 test('"use strict";if (x) {let y = x;eval("let y = 2");return y;}');
 test('"use strict";if (x) {let y = 1;return eval("let y = x;y;");}');
 test('this.y = x;if (x) {let y = 1;return this.eval("y");}');
-isParseError('if (x) {let (x = 1, x = 2) {x}}');
-isParseError('if (x) {let ([x, y] = a, {a:x} = b) {x}}');
-isParseError('if (x) {let ([x, y, x] = a) {x}}');
-isParseError('if (x) {let ([x, [y, [x]]] = a) {x}}');
-isParseError('let ([x, y] = x) {let x;}');
 
 // for(;;)
 test('for (;;) {return x;}');
 test('for (let y = 1;;) {return x;}');
 test('for (let y = 1;; ++y) {return x;}');
 test('for (let y = 1; ++y;) {return x;}');
-isParseError('for (let (x = 1) x; x != 1; ++x) {return x;}');
-isParseError('for (let (x = 1, [{a: b, c: d}] = [{a: 1, c: 2}]) x; x != 1; ++x) {return x;}');
 test('for (let [[a, [b, c]]] = [[x, []]];;) {return a;}');
 test('var sum = 0;for (let y = x; y < 4; ++y) {sum += y;}return sum;', 1, 6);
 test('var sum = 0;for (let x = x, y = 10; x < 4; ++x) {sum += x;}return sum;', 1, 6);
 test('var sum = 0;for (let x = x; x < 4; ++x) {sum += x;}return x;', 1, 1);
 test('var sum = 0;for (let x = eval("x"); x < 4; ++x) {sum += x;}return sum;', 1, 6);
 test('var sum = 0;for (let x = x; eval("x") < 4; ++x) {sum += eval("x");}return sum;', 1, 6);
 test('var sum = 0;for (let x = eval("x"); eval("x") < 4; ++x) {sum += eval("x");}return sum;', 1, 6);
 test('for (var y = 1;;) {return x;}');
@@ -275,28 +164,26 @@ isParseError('for (let x = 1, x = 2;;) {
 isParseError('for (let [x, y] = a, {a:x} = b;;) {}');
 isParseError('for (let [x, y, x] = a;;) {}');
 isParseError('for (let [x, [y, [x]]] = a;;) {}');
 
 // for(in)
 test('for (let i in x) {return x;}');
 test('for (let i in x) {let y;return x;}');
 test('for each (let [a, b] in x) {let y;return x;}');
-test('for (let i in x) {let (i = x) {return i;}}');
 test('for (let i in x) {let i = x;return i;}');
 test('for each (let [x, y] in x) {return x + y;}', [['ponies', '']]);
 test('for each (let [{0: x, 1: y}, z] in x) {return x + y + z;}', [[['po','nies'], '']]);
 test('var s = "";for (let a in x) {for (let b in x) {s += a + b;}}return s;', [1,2], '00011011');
 test('var res = "";for (let i in x) {res += x[i];}return res;');
 test('var res = "";for (var i in x) {res += x[i];}return res;');
 test('for each (let {x: y, y: x} in [{x: x, y: x}]) {return y;}');
 test('for (let x in eval("x")) {return x;}', {ponies:true});
 test('for (let x in x) {return eval("x");}', {ponies:true});
 test('for (let x in eval("x")) {return eval("x");}', {ponies:true});
-isParseError('for ((let (x = {y: true}) x).y in eval("x")) {return eval("x");}');
 test('for (let i in x) {break;}return x;');
 test('for (let i in x) {break;}return eval("x");');
 test('for (let x in x) {break;}return x;');
 test('for (let x in x) {break;}return eval("x");');
 test('a:for (let i in x) {for (let j in x) {break a;}}return x;');
 test('a:for (let i in x) {for (let j in x) {break a;}}return eval("x");');
 test('var j;for (let i in x) {j = i;break;}return j;', {ponies:true});
 test('try {for (let x in eval("throw x")) {}} catch (e) {return e;}');
@@ -315,17 +202,16 @@ test('try {return (eval("throw i") for (
 test('return [i for (i in x)][0];', {ponies:true});
 test('return [eval("i") for (i in x)][0];', {ponies:true});
 test('return [eval("i") for (i in eval("x"))][0];', {ponies:true});
 test('try {return [eval("throw i") for (i in x)][0];} catch (e) {return e;}', {ponies:true});
 
 // don't forget about switch craziness
 test('var y = 3;switch (function () {return eval("y");}()) {case 3:let y;return x;default:;}');
 test('switch (x) {case 3:let y;return 3;case 4:let z;return 4;default:return x;}');
-test('switch (x) {case 3:default:let y;let (y = x) {return y;}}');
 isParseError('switch (x) {case 3:let y;return 3;case 4:let y;return 4;default:;}');
 
 // TDZ checks
 isReferenceError('x + 1; let x = 42;');
 isReferenceError('x = 42; let x;');
 isReferenceError('inner(); function inner() { x++; } let x;');
 isReferenceError('inner(); let x; function inner() { x++; }');
 isReferenceError('inner(); let x; function inner() { function innerer() { x++; } innerer(); }');
--- a/js/src/jit-test/tests/basic/testLetOverridingArgs.js
+++ b/js/src/jit-test/tests/basic/testLetOverridingArgs.js
@@ -1,5 +1,5 @@
-function f1() { let (arguments = 42) { return arguments } }
+function f1() { { let arguments = 42; return arguments } }
 assertEq(f1(), 42);
 
-function f2() { let (arguments) { return arguments } }
+function f2() { { let arguments; return arguments } }
 assertEq(f2(), undefined);
--- a/js/src/jit-test/tests/basic/testNonStubGetter.js
+++ b/js/src/jit-test/tests/basic/testNonStubGetter.js
@@ -1,7 +1,7 @@
 function testNonStubGetter() {
-    let ([] = []) { (this.watch("x", function(p, o, n) { return /a/g.exec(p, o, n); })); };
+    { let [] = []; (this.watch("x", function(p, o, n) { return /a/g.exec(p, o, n); })); };
     (function () { (eval("(function(){for each (x in [1, 2, 2]);});"))(); })();
     this.unwatch("x");
     return "ok";
 }
 assertEq(testNonStubGetter(), "ok");
--- a/js/src/jit-test/tests/basic/testReplaceWithLambda.js
+++ b/js/src/jit-test/tests/basic/testReplaceWithLambda.js
@@ -2,28 +2,30 @@
 (function(b) {
     assertEq("abc".replace(/a|b/g, function(a) { return b[a] }), 'ABc');
 })({a:'A', b:'B' });
 (function() {
     var b = {a:'A', b:'B' };
     assertEq("abc".replace(/a|b/g, function(a) { return b[a] }), 'ABc');
 })();
 (function() {
-    let (b = {a:'A', b:'B' }) {
+    {
+        let b = {a:'A', b:'B' };
         assertEq("abc".replace(/a|b/g, function(a) { return b[a] }), 'ABc');
     }
 })();
 (function() {
     var b = {a:'A', b:'B' };
     (function () {
         assertEq("abc".replace(/a|b/g, function(a) { return b[a] }), 'ABc');
     })();
 })();
 (function() {
-    let (b = {a:'A', b:'B' }) {
+    {
+        let b = {a:'A', b:'B' };
         (function () {
             assertEq("abc".replace(/a|b/g, function(a) { return b[a] }), 'ABc');
         })();
     }
 })();
 (function() {
     var b = {a:'A', b:'B' };
     (function () {
--- a/js/src/jit-test/tests/basic/testScriptCloning.js
+++ b/js/src/jit-test/tests/basic/testScriptCloning.js
@@ -1,17 +1,17 @@
 var g = newGlobal();
 
 g.f = new Function('return function(x) { return x };');
 assertEq(g.eval("clone(f)()(9)"), 9);
 
-g.f = new Function('return function(x) { let(y = x+1) { return y } };');
+g.f = new Function('return function(x) { { let y = x+1; return y } };');
 assertEq(g.eval("clone(f)()(9)"), 10);
 
-g.f = new Function('return function(x) { let(y = x, z = 1) { return y+z } };');
+g.f = new Function('return function(x) { { let y = x, z = 1; return y+z } };');
 assertEq(g.eval("clone(f)()(9)"), 10);
 
 g.f = new Function('return function(x) { return x.search(/ponies/) };');
 assertEq(g.eval("clone(f)()('123ponies')"), 3);
 
 g.f = new Function('return function(x,y) { return x.search(/a/) + y.search(/b/) };');
 assertEq(g.eval("clone(f)()('12a','foo')"), 1);
 
--- a/js/src/jit-test/tests/basic/testStaticEvalScope.js
+++ b/js/src/jit-test/tests/basic/testStaticEvalScope.js
@@ -1,3 +1,3 @@
 // Test that static eval scopes don't mess with statement nested scope logic in
 // the frontend.
-eval("if (true) { let(y){} } else {}")
+eval("if (true) { { let y; } } else {}")
--- a/js/src/jit-test/tests/bug1213574.js
+++ b/js/src/jit-test/tests/bug1213574.js
@@ -1,13 +1,13 @@
 if (helperThreadCount() === 0)
     quit(0);
 
 var lfGlobal = newGlobal();
-lfGlobal.offThreadCompileScript(`let (x) { throw 42; }`);
+lfGlobal.offThreadCompileScript(`{ let x; throw 42; }`);
 try {
     lfGlobal.runOffThreadScript();
 } catch (e) {
 }
 
 lfGlobal.offThreadCompileScript(`function f() { { let x = 42; return x; } }`);
 try {
     lfGlobal.runOffThreadScript();
--- a/js/src/jit-test/tests/closures/bug496922.js
+++ b/js/src/jit-test/tests/closures/bug496922.js
@@ -1,20 +1,21 @@
 actual = '';
 expected = '0,0,1,1,2,2,3,3,';
 
 v = 0
-let(
-f = function() {
+{
+let f = function() {
     for (let x = 0; x < 4; ++x) {
         v >> x;
         (function() {
             for (let y = 0; y < 2; ++y) {
                 appendToActual(x)
             }
         })()
     }
-}) { (function() {})()
+};
+(function() {})()
     f(v)
 }
 
 
 assertEq(actual, expected)
--- a/js/src/jit-test/tests/closures/bug540131.js
+++ b/js/src/jit-test/tests/closures/bug540131.js
@@ -1,5 +1,5 @@
 try {
  (function() {
-   let(x = (eval("for(y in[0,0,0,0]){}"))) {}
+   { let x = (eval("for(y in[0,0,0,0]){}")); }
  })()
 } catch(e) {}
--- a/js/src/jit-test/tests/closures/flat-closure-2.js
+++ b/js/src/jit-test/tests/closures/flat-closure-2.js
@@ -1,15 +1,14 @@
 actual = '';
 expected = 'nocrash,';
 
-let (z = {}) {
-    for (var i = 0; i < 4; ++i) {
-        for each (var e in [{}, 1, {}]) {
-            +(function () z)();
-        }
+let z = {};
+for (var i = 0; i < 4; ++i) {
+    for each (var e in [{}, 1, {}]) {
+        +(function () z)();
     }
 }
 
 appendToActual('nocrash')
 
 
 assertEq(actual, expected)
--- a/js/src/jit-test/tests/closures/flat-closure-7.js
+++ b/js/src/jit-test/tests/closures/flat-closure-7.js
@@ -1,16 +1,15 @@
 actual = '';
 expected = '0 0 0 0 0 0 0 0 0,';
 
     var o = [];
     for (var a = 0; a < 9; ++a) {
         var unused = 0;
-        let (zero = 0) {
-            for (var ee = 0; ee < 1; ++ee) {
-                o.push((function () zero)());
-            }
+        let zero = 0;
+        for (var ee = 0; ee < 1; ++ee) {
+          o.push((function () zero)());
         }
     }
     appendToActual(o.join(" "));
 
 
 assertEq(actual, expected)
--- a/js/src/jit-test/tests/closures/incr-exit-2.js
+++ b/js/src/jit-test/tests/closures/incr-exit-2.js
@@ -1,20 +1,20 @@
 actual = '';
 expected = '-3,';
 
 v = 0
-let(f = function (y) {
-    let(f = function (g) {
+{ let f = function (y) {
+    { let f = function (g) {
         for each(let h in g) {
             if (++y > 2) {
                 appendToActual(h)
             }
         }
-    }) {
+    };
         f([(--y), false, true, (--y), false, (--y)])
     }
-}) {
+};
     f(v)
 }
 
 
 assertEq(actual, expected)
--- a/js/src/jit-test/tests/closures/incr-exit-3.js
+++ b/js/src/jit-test/tests/closures/incr-exit-3.js
@@ -1,28 +1,28 @@
 actual = '';
 expected = 'foo4,foo4,';
 
 v = 0
-let(f = function (y) {
-    let(f = function (y) {
-        let(f = function (g) {
+{ let f = function (y) {
+    { let f = function (y) {
+        { let f = function (g) {
             for (h in g) {
                 if (++y > 3) {
                     appendToActual('foo' + y)
                 }
             }
-        }) {
+        };
             f([y
             for (b in [1, []])]);
             f(['', false])
         }
         v = String
-    }) {
+    };
         f(y)
         f(y)
     }
-}) {
+};
     f(v)
 }
 
 
 assertEq(actual, expected)
--- a/js/src/jit-test/tests/closures/incr-exit.js
+++ b/js/src/jit-test/tests/closures/incr-exit.js
@@ -1,20 +1,20 @@
 actual = '';
 expected = 'ddd,';
 
 // Bug 508187
-let(f = function (y) {
-    let(ff = function (g) {
+{ let f = function (y) {
+    { let ff = function (g) {
         for each(let h in g) {
             if (++y > 5) {
 	        appendToActual('ddd')
             }
         }
-    }) {
+    };
       ff(['', null, '', false, '', '', null])
     }
-}) {
+};
     f(-1)
 }
 
 
 assertEq(actual, expected)
--- a/js/src/jit-test/tests/closures/lambda-light.js
+++ b/js/src/jit-test/tests/closures/lambda-light.js
@@ -1,16 +1,17 @@
 actual = '';
 expected = '10,';
 
 function f(x) {
-  let (x = 10) {
+  {
+    let x2 = 10;
     for (var i = 0; i < 5; ++i) {
       var g = function () {
-	appendToActual(x);
+	appendToActual(x2);
       };
     }
     g();
   }
 }
 
 f(1);
 
--- a/js/src/jit-test/tests/closures/t020.js
+++ b/js/src/jit-test/tests/closures/t020.js
@@ -1,17 +1,17 @@
 actual = '';
 expected = '0,0,1,1,2,2,3,3,';
 
-let(f = function() {
+{ let f = function() {
     for (let x = 0; x < 4; ++x) {
       (function() {
 	for (let y = 0; y < 2; ++y) {
 	  appendToActual(x);
 	}
       })()
 	}
-}) { 
+};
     f(0)
 }
 
 
 assertEq(actual, expected)
--- a/js/src/jit-test/tests/debug/Environment-callee-01.js
+++ b/js/src/jit-test/tests/debug/Environment-callee-01.js
@@ -16,17 +16,17 @@ function check(code, expectedType, expec
   };
   hits = 0;
   g.eval(code);
   assertEq(hits, 1);
 }
 
 check('debugger;', 'declarative', null);
 check('with({}) { debugger; };', 'with', null);
-check('let (x=1) { debugger; };', 'declarative', null);
+check('{ let x=1; debugger; };', 'declarative', null);
 
 g.eval('function f() { debugger; }');
 check('f()', 'declarative', gw.makeDebuggeeValue(g.f));
 
 g.eval('function g() { h(); }');
 g.eval('function h() { debugger; }');
 check('g()', 'declarative', gw.makeDebuggeeValue(g.h));
 
@@ -36,13 +36,13 @@ g.eval('function j() { "use strict"; eva
 check('j()', 'declarative', null);
 
 // All evals get a lexical scope.
 check('eval("debugger");', 'declarative', null);
 
 g.eval('function m() { debugger; yield true; }');
 check('m().next();', 'declarative', gw.makeDebuggeeValue(g.m));
 
-g.eval('function n() { let (x = 1) { debugger; } }');
+g.eval('function n() { { let x = 1; debugger; } }');
 check('n()', 'declarative', null);
 
 g.eval('function* o() { debugger; yield true; }');
 check('o().next();', 'declarative', gw.makeDebuggeeValue(g.o));
--- a/js/src/jit-test/tests/debug/Environment-getVariable-03.js
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-03.js
@@ -12,11 +12,10 @@ g.eval("function f() {\n" +
        "    for (let x = 0; x < 2; x++)\n" + 
        "        if (x === 0)\n" +
        "            debugger;\n" +
        "        else {\n" +
        "            let x = 'b'; debugger;\n" +
        "        }\n" +
        "}\n");
 g.f();
-g.eval("let (x = 'c') { debugger; }");
 g.eval("{ let x = 'd'; debugger; }");
-assertEq(log, 'a0bcd');
+assertEq(log, 'a0bd');
--- a/js/src/jit-test/tests/debug/Environment-getVariable-12.js
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-12.js
@@ -5,17 +5,17 @@ var gw = dbg.addDebuggee(g);
 var hits = 0;
 dbg.onDebuggerStatement = function (frame) {
     hits++;
     assertEq(frame.environment.parent.parent.getVariable('y'), true);
 };
 
 g.eval("var g;" +
        "function f(x) {" +
-       "  let (y = x) {" +
+       "  { let y = x; " +
        "    if (x)" +
        "      g = function() { eval('debugger') };" +
        "    else" +
        "      g();" +
        "  }" +
        "}" +
        "f(true);" +
        "f(false);");
@@ -24,19 +24,19 @@ assertEq(hits, 1);
 var hits = 0;
 dbg.onDebuggerStatement = function (frame) {
     hits++;
     assertEq(frame.environment.parent.getVariable('y'), 1);
     assertEq(frame.environment.parent.names().indexOf('z'), -1);
 };
 
 g.eval("var g;" +
-       "let (y = 1) {" +
+       "{ let y = 1; " +
        "  g = function () { debugger; };" +
-       "  let (z = 2) {" +
+       "  { let z = 2; " +
        "    g();" +
        "  }"+
        "}");
 assertEq(hits, 1);
 
 var hits = 0;
 dbg.onDebuggerStatement = function (frame) {
     hits++;
@@ -44,18 +44,18 @@ dbg.onDebuggerStatement = function (fram
     assertEq(e.getVariable('z'), true);
     e = e.parent;
     assertEq(e.getVariable('y'), true);
 };
 
 g.eval("var g;" +
        "function h() { debugger };" +
        "for (var x of [true, false]) {" +
-       "  let (y = x) {" +
-       "    let (z = x) {" +
+       "  { let y = x; " +
+       "    { let z = x; " +
        "      if (x)" +
        "        g = function () { print(z); h() };" +
        "      else" +
        "        g();" +
        "    }" +
        "  }" +
        "}");
 assertEq(hits, 1);
--- a/js/src/jit-test/tests/debug/Environment-identity-03.js
+++ b/js/src/jit-test/tests/debug/Environment-identity-03.js
@@ -49,17 +49,17 @@ function test(sharedName, expectedHits, 
 // (The stray "a = b" assignments in these tests are to inhibit the flat closure
 // optimization, which Environments expose. There's nothing really wrong with
 // the optimization or with the debugger exposing it, but that's not what we
 // want to test here.)
 
 test("q", 2, "let q = function (a) { h(); }; q(1); q(2);");
 test("a", 2, "q = function (a) { (function (b) { h(); a = b; })(2); h(); }; q(1);");
 test("a", 2, "q = function (a) { h(); return function (b) { h(); a = b; }; }; q(1)(2);");
-test("n", 3, "q = function (n) { for (var i = 0; i < n; i++) { let (j = i) { h(); } } }; q(3);");
+test("n", 3, "q = function (n) { for (var i = 0; i < n; i++) { { let j = i; h(); } } }; q(3);");
 
 // A function with long dynamic and static chains.
 var N = 80;
 
 var code = "function f" + N + "(a" + N + ") {\neval('a0 + a1'); h();\n}\n";
 for (var i = N; --i >= 0;) {
     var call = "f" + (i + 1) + "(a" + i + " - 1);\n";
     code = ("function f" + i + "(a" + i + ") {\n" +
--- a/js/src/jit-test/tests/debug/Environment-setVariable-07.js
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-07.js
@@ -7,9 +7,8 @@ function test(code, val) {
     dbg.onDebuggerStatement = function (frame) {
         frame.environment.setVariable("a", val);
     };
     assertEq(g.f(), val);
 }
 
 test("let a = 1; debugger; return a;", "xyzzy");
 test("{ let a = 1; debugger; return a; }", "plugh");
-test("let (a = 1) { debugger; return a; }", "wcgr");
--- a/js/src/jit-test/tests/debug/Environment-type-01.js
+++ b/js/src/jit-test/tests/debug/Environment-type-01.js
@@ -10,17 +10,17 @@ function test(code, expected) {
 }
 
 test("h();", 'declarative');
 test("(function (s) { eval(s); })('var v = h();')", 'declarative');
 test("(function (s) { h(); })();", 'declarative');
 test("{let x = 1, y = 2; h();}", 'declarative');
 test("with({x: 1, y: 2}) h();", 'with');
 test("(function (s) { with ({x: 1, y: 2}) h(); })();", 'with');
-test("let (x = 1) { h(); }", 'declarative');
+test("{ let x = 1; h(); }", 'declarative');
 test("for (let x = 0; x < 1; x++) h();", 'declarative');
 test("for (let x in h()) ;", 'declarative');
 test("for (let x in {a:1}) h();", 'declarative');
 test("try { throw new Error; } catch (x) { h(x) }", 'declarative');
 test("'use strict'; eval('var z = 1; h();');", 'declarative');
 test("for (var x in [h(m) for (m in [1])]) ;", 'declarative');
 test("for (var x in (h(m) for (m in [1]))) ;", 'declarative');
 
--- a/js/src/jit-test/tests/debug/Environment-variables.js
+++ b/js/src/jit-test/tests/debug/Environment-variables.js
@@ -7,17 +7,16 @@ var cases = [
     // global bindings and bindings on the global prototype chain
     "x = VAL; @@",
     "var x = VAL; @@",
     "Object.prototype.x = VAL; @@",
 
     // let, catch, and comprehension bindings
     "let x = VAL; @@",
     "{ let x = VAL; @@ }",
-    "let (x = VAL) { @@ }",
     "try { throw VAL; } catch (x) { @@ }",
     "try { throw VAL; } catch (x) { @@ }",
     "for (let x of [VAL]) { @@ }",
     "for each (let x in [VAL]) { @@ }",
     "switch (0) { default: let x = VAL; @@ }",
     "[function () { @@ }() for (x of [VAL])];",
     // "((function () { @@ })() for (x of [VAL])).next();",  // bug 709367
 
@@ -75,15 +74,15 @@ function test(code, debugStmts, followup
 for (var s of cases) {
     // Test triggering the debugger right in the scope in which x is bound.
     test(s, "debugger; assertEq(x, 'ok');");
 
     // Test calling a function that triggers the debugger.
     test(s, "debugMe(); assertEq(x, 'ok');");
 
     // Test triggering the debugger from a scope nested in x's scope.
-    test(s, "let (y = 'irrelevant') { (function (z) { let (zz = y) { debugger; }})(); } assertEq(x, 'ok');"),
+    test(s, "{ let y = 'irrelevant'; (function (z) { { let zz = y; debugger; } })(); } assertEq(x, 'ok');"),
 
     // Test closing over the variable and triggering the debugger later, after
     // leaving the variable's scope.
     test(s, "capture = {dbg: function () { debugger; }, get x() { return x; }};",
             "assertEq(capture.x, VAL); capture.dbg(); assertEq(capture.x, 'ok');");
 }
--- a/js/src/jit-test/tests/debug/Frame-eval-14.js
+++ b/js/src/jit-test/tests/debug/Frame-eval-14.js
@@ -1,14 +1,14 @@
 // Test the corner case of accessing an unaliased variable of a block
 // while the block is not live.
 
 var g = newGlobal();
 g.eval("function h() { debugger }");
-g.eval("function f() { let (x = 1, y) { (function() { y = 0 })(); h() } }");
+g.eval("function f() { { let x = 1, y; (function() { y = 0 })(); h() } }");
 g.eval("var surprise = null");
 
 var dbg = new Debugger(g);
 dbg.onDebuggerStatement = function(hFrame) {
     var fFrame = hFrame.older;
     assertEq(fFrame.environment.getVariable('x'), 1);
     assertEq(fFrame.environment.getVariable('y'), 0);
     fFrame.eval("surprise = function() { return ++x }");
--- a/js/src/jit-test/tests/debug/Frame-evalWithBindings-01.js
+++ b/js/src/jit-test/tests/debug/Frame-evalWithBindings-01.js
@@ -25,11 +25,11 @@ g.f();
 // in strict eval code with var
 g.eval("function f() { 'use strict'; eval('var y = 3; debugger;'); }");
 g.f();
 
 // in a with block
 g.eval("with ({y: 3}) { debugger; }");
 
 // shadowing
-g.eval("let (x = 50, y = 3) { debugger; }");
+g.eval("{ let x = 50, y = 3; debugger; }");
 
 assertEq(hits, 6);
--- a/js/src/jit-test/tests/debug/bug1188334.js
+++ b/js/src/jit-test/tests/debug/bug1188334.js
@@ -3,15 +3,16 @@ var evalInFrame = (function (global) {
   var dbg = new dbgGlobal.Debugger();
   return function evalInFrame(upCount, code) {
     dbg.addDebuggee(global);
     var frame = dbg.getNewestFrame().older;
     var completion = frame.eval(code);
   };
 })(this);
 function f() {
-    let ({} = "xxx") {
+    {
+        let {} = "xxx";
         yield evalInFrame(0, "x");
     }
 }
 var gen = f();
 gen.next()
 
--- a/js/src/jit-test/tests/for-of/syntax-2.js
+++ b/js/src/jit-test/tests/for-of/syntax-2.js
@@ -1,9 +1,7 @@
 // "of" is not a keyword.
 
 var of;
 
 Function("var of;");
 
-let (of = 12) {}
-
 function of(of) {}
--- a/js/src/jit-test/tests/gc/jsscript-mark-children.js
+++ b/js/src/jit-test/tests/gc/jsscript-mark-children.js
@@ -3,22 +3,22 @@
 // only occurs after bytecode generation.  This means that
 // JSScript::markChildren() must deal with partially-initialized JSScripts.
 // This test forces that to happen, because each let block allocates a
 // StaticBlockObject.  All that should happen is that we don't crash.
 
 let t = 0;
 gczeal(2,1);
 eval("\
-let x = 3, y = 4;\
-let (x = x+0, y = 12) { t += (x + y); }  \
-let (x = x+1, y = 12) { t += (x + y); }  \
-let (x = x+2, y = 12) { t += (x + y); }  \
-let (x = x+3, y = 12) { t += (x + y); }  \
-let (x = x+4, y = 12) { t += (x + y); }  \
-let (x = x+5, y = 12) { t += (x + y); }  \
-let (x = x+6, y = 12) { t += (x + y); }  \
-let (x = x+7, y = 12) { t += (x + y); }  \
-let (x = x+8, y = 12) { t += (x + y); }  \
-let (x = x+9, y = 12) { t += (x + y); }  \
-t += (x + y);\
+let x0 = 3, y = 4;\
+{ let x = x0+0, y = 12; t += (x + y); }  \
+{ let x = x0+1, y = 12; t += (x + y); }  \
+{ let x = x0+2, y = 12; t += (x + y); }  \
+{ let x = x0+3, y = 12; t += (x + y); }  \
+{ let x = x0+4, y = 12; t += (x + y); }  \
+{ let x = x0+5, y = 12; t += (x + y); }  \
+{ let x = x0+6, y = 12; t += (x + y); }  \
+{ let x = x0+7, y = 12; t += (x + y); }  \
+{ let x = x0+8, y = 12; t += (x + y); }  \
+{ let x = x0+9, y = 12; t += (x + y); }  \
+t += (x0 + y);\
 assertEq(t, 202);\
 ");
--- a/js/src/jit-test/tests/jaeger/bug549521.js
+++ b/js/src/jit-test/tests/jaeger/bug549521.js
@@ -1,12 +1,13 @@
 function f(y) {
     if (y)
         return;
-    let(x) {
+    {
+        let x;
         for (;;) {}
     }
 }
 
 
 /* Don't assert. */
 f(1);
 
--- a/js/src/jit-test/tests/jaeger/bug555922.js
+++ b/js/src/jit-test/tests/jaeger/bug555922.js
@@ -1,12 +1,13 @@
 enableNoSuchMethod();
 
 (function() {
-  let(z) {
+  {
+    let z;
     for each(b in [{}]) { ({
         get __noSuchMethod__() { return Function }
       }).w()
     }
   }
 })()
 
 /* Don't crash/assert. */
--- a/js/src/jit-test/tests/jaeger/bug582897.js
+++ b/js/src/jit-test/tests/jaeger/bug582897.js
@@ -1,6 +1,7 @@
-let(x) {
+{
+    let x;
     x + x--
 }
 
 /* Don't assert. */
 
--- a/js/src/jit-test/tests/jaeger/bug582898.js
+++ b/js/src/jit-test/tests/jaeger/bug582898.js
@@ -1,6 +1,7 @@
-let(x = "") {
+{
+    let x = "";
     x++
     assertEq(x, 1);
 }
 
 /* Test no assert. */
deleted file mode 100644
--- a/js/src/jit-test/tests/jaeger/chunk/bug712265.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// |jit-test| error: ReferenceError
-mjitChunkLimit(5);
-eval("\
-try { \
-  let (t1 = x) {}\
-}  finally {}");
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -239,17 +239,16 @@ MSG_DEF(JSMSG_CURLY_BEFORE_LET,        0
 MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY,    0, JSEXN_SYNTAXERR, "missing { before finally block")
 MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH,     0, JSEXN_SYNTAXERR, "missing { before switch body")
 MSG_DEF(JSMSG_CURLY_BEFORE_TRY,        0, JSEXN_SYNTAXERR, "missing { before try block")
 MSG_DEF(JSMSG_CURLY_IN_COMPOUND,       0, JSEXN_SYNTAXERR, "missing } in compound statement")
 MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword")
 MSG_DEF(JSMSG_DECLARATION_AFTER_IMPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'import' keyword")
 MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated")
 MSG_DEF(JSMSG_DEPRECATED_FLAGS_ARG,    0, JSEXN_NONE, "flags argument of String.prototype.{search,match,replace} is deprecated")
-MSG_DEF(JSMSG_DEPRECATED_LET_BLOCK,      0, JSEXN_NONE, "JavaScript 1.7's let blocks are deprecated")
 MSG_DEF(JSMSG_DEPRECATED_FOR_EACH,     0, JSEXN_NONE, "JavaScript 1.6's for-each-in loops are deprecated; consider using ES6 for-of instead")
 MSG_DEF(JSMSG_DEPRECATED_OCTAL,        0, JSEXN_SYNTAXERR, "octal literals and octal escape sequences are deprecated")
 MSG_DEF(JSMSG_DEPRECATED_PRAGMA,       1, JSEXN_NONE, "Using //@ to indicate {0} pragmas is deprecated. Use //# instead")
 MSG_DEF(JSMSG_DUPLICATE_EXPORT_NAME,   1, JSEXN_SYNTAXERR, "duplicate export name '{0}'")
 MSG_DEF(JSMSG_DUPLICATE_FORMAL,        1, JSEXN_SYNTAXERR, "duplicate formal argument {0}")
 MSG_DEF(JSMSG_DUPLICATE_LABEL,         0, JSEXN_SYNTAXERR, "duplicate label")
 MSG_DEF(JSMSG_DUPLICATE_PROPERTY,      1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal")
 MSG_DEF(JSMSG_EMPTY_CONSEQUENT,        0, JSEXN_SYNTAXERR, "mistyped ; after conditional?")
--- a/js/src/jsapi-tests/testEnclosingFunction.cpp
+++ b/js/src/jsapi-tests/testEnclosingFunction.cpp
@@ -50,17 +50,17 @@ BEGIN_TEST(test_enclosingFunction)
     const char s2chars[] = "return function() { checkEnclosing() }";
     CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "s2", 0, nullptr, s2chars,
                               strlen(s2chars), &fun));
     CHECK(fun);
     CHECK(JS_DefineProperty(cx, global, "s2", fun, JSPROP_ENUMERATE));
     EXEC("s2()()");
     CHECK(foundFun == fun);
 
-    const char s3chars[] = "return function() { let (x) { function g() { checkEnclosing() } return g() } }";
+    const char s3chars[] = "return function() { { let x; function g() { checkEnclosing() } return g() } }";
     CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "s3", 0, nullptr, s3chars,
                               strlen(s3chars), &fun));
     CHECK(fun);
     CHECK(JS_DefineProperty(cx, global, "s3", fun, JSPROP_ENUMERATE));
     EXEC("s3()()");
     CHECK(foundFun == fun);
 
     return true;
deleted file mode 100644
deleted file mode 100644
--- a/js/src/tests/js1_7/block/order-of-operation.js
+++ /dev/null
@@ -1,153 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER     = "(none)";
-var summary = "Test let and order of operation issues";
-var actual, expect;
-
-printBugNumber(BUGNUMBER);
-printStatus(summary);
-
-/**************
- * BEGIN TEST *
- **************/
-
-var failed = false;
-
-function f1(x)
-{
-  let (foo) {
-    // scope of lhs x includes rhs, so x is NaN here -- bug 344952
-    let x = ++x;
-    return x;
-  }
-}
-
-function f2(x)
-{
-  let (foo)
-  {
-    // scope of lhs x includes rhs, so x is NaN here -- bug 344952
-    let x = x++;
-    return x;
-  }
-}
-
-function f3(x)
-{
-  let (foo)
-  {
-    var q = x;
-    let (x = x++)
-    {
-      if (x != q)
-        throw "f3():\n" +
-          "  expected: x == q\n" +
-          "  actual:   x != q " +
-          "(where x == " + x + ", q == " + q + ")\n";
-    }
-    return x;
-  }
-}
-
-function f4(x)
-{
-  var y = 7;
-  let (y = x, x = 3)
-  {
-    var q = 7 + x;
-  }
-  return x + y + q;
-}
-
-function f5(x)
-{
-  var q = x++;
-  let (y = x, r = 17, m = 32) {
-    return function(code)
-    {
-      return eval(code);
-    };
-  }
-}
-
-function f6() {
-  let (foo)
-  {
-    var i=3;
-    for (let i=i;;) { if (i != 3) throw "f6(): fail 1"; i = 7; break; }
-    if (i != 3) throw "f6(): fail 2";
-  }
-}
-
-try
-{
-/*
-  var rv = f1(5);
-  if (!isNaN(rv))
-    throw "f1(5):\n" +
-      "  expected:  NaN\n" +
-      "  actual:    " + rv;
-
-  rv = f2(5);
-  if (!isNaN(rv))
-    throw "f2(5):\n" +
-      "  expected:  NaN\n" +
-      "  actual:    " + rv;
-
-  rv = f3(8);
-  if (rv != 9)
-  throw "f3(8):\n" +
-  "  expected:  9\n" +
-  "  actual:    " + rv;
-*/
-
-  rv = f4(13);
-  if (rv != 30)
-    throw "f4(13):\n" +
-      "  expected:  30\n" +
-      "  actual:    " + rv;
-
-  var fun = f5(2);
-
-  rv = fun("q");
-  if (rv != 2)
-    throw "fun('q'):\n" +
-      "  expected:  2\n" +
-      "  actual:    " + rv;
-
-  rv = fun("x");
-  if (rv != 3)
-    throw "fun('x'):\n" +
-      "  expected:  3\n" +
-      "  actual:    " + rv;
-
-  rv = fun("y");
-  if (rv != 3)
-    throw "fun('y'):\n" +
-      "  expected:  3\n" +
-      "  actual:    " + rv;
-
-  rv = fun("let (y = y) { y += 32; }; y");
-  if (rv != 3)
-    throw "fun('let (y = y) { y += 32; }; y'):\n" +
-      "  expected:  3\n" +
-      "  actual:    " + rv;
-
-/*
-  f6();
-*/
-}
-catch (e)
-{
-  print(e.toSource());
-  failed = e;
-}
-
-expect = false;
-actual = failed;
-
-reportCompare(expect, actual, summary);
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-341939.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 341939;
-var summary = 'Let block does not require semicolon';
-var actual = '';
-var expect = 'No Error';
-
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-try
-{ 
-  eval('let (a) {} print(42);');
-  actual = 'No Error';
-}
-catch(ex)
-{
-  actual = ex + '';
-}
-
-reportCompare(expect, actual, summary);
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-343765.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 343765;
-var summary = 'Function defined in a let statement/expression does not work correctly outside the let scope';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
- 
-  print("SECTION 1");
-  try {
-    let (a = 2, b = 3) { function f() { return String([a,b]); } f(); throw 42; }
-  } catch (e) {
-    f();
-  }
-
-  reportCompare(expect, actual, summary);
-
-  print("SECTION 2");
-  try {
-    with ({a:2,b:3}) { function f() { return String([a,b]); } f(); throw 42; }
-  } catch (e) {
-    f();
-  }
-
-  print("SECTION 3");
-  function g3() {
-    print("Here!");
-    with ({a:2,b:3}) {
-      function f() {
-        return String([a,b]);
-      }
-
-      f();
-      return f;
-    }
-  }
-
-  k = g3();
-  k();
-
-  print("SECTION 4");
-  function g4() {
-    print("Here!");
-    let (a=2,b=3) {
-      function f() {
-        return String([a,b]);
-      }
-
-      f();
-      return f;
-    }
-  }
-
-  k = g4();
-  k();
-
-  print("SECTION 5");
-  function g5() {
-    print("Here!");
-    let (a=2,b=3) {
-      function f() {
-        return String([a,b]);
-      }
-
-      f();
-      yield f;
-    }
-  }
-
-  k = g5().next();
-  k();
-
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
-
-function returnResult(a)
-{
-  return a + '';
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-344139.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER     = "344139";
-var summary = "Basic let functionality";
-var actual, expect;
-
-printBugNumber(BUGNUMBER);
-printStatus(summary);
-
-/**************
- * BEGIN TEST *
- **************/
-
-var failed = false;
-
-var x = 7;
-
-function f1()
-{
-  let x = 5;
-  return x;
-}
-
-function f2()
-{
-  let x = 5;
-  x = 3;
-  return x;
-}
-
-function f3()
-{
-  let x = 5;
-  x += x;
-  return x;
-}
-
-function f4()
-{
-  var v = 5;
-  let q = 17;
-
-  // 0+1+2+...+8+9 == 45
-  for (let v = 0; v < 10; v++)
-    q += v;
-
-  if (q != 62)
-    throw "f4(): wrong value for q\n" +
-      "  expected: 62\n" +
-      "  actual:   " + q;
-
-  return v;
-}
-
-try
-{
-  if (f1() != 5 || x != 7)
-    throw "f1() == 5";
-  if (f2() != 3 || x != 7)
-    throw "f2() == 3";
-  if (f3() != 10 || x != 7)
-    throw "f3() == 10";
-
-  if (f4() != 5)
-    throw "f4() == 5";
-
-  var bad = true;
-  try
-  {
-    eval("q++"); // force error at runtime
-  }
-  catch (e)
-  {
-    if (e instanceof ReferenceError)
-      bad = false;
-  }
-  if (bad)
-    throw "f4(): q escaping scope!";
-}
-catch (e)
-{
-  failed = e;
-}
-
-expect = false;
-actual = failed;
-
-reportCompare(expect, actual, summary);
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-344370.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 344370;
-var summary = 'let declaration in let statement shows assertion';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
- 
-  let (a = 2) { let b = 3; [a, b]; }
-
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-348685.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 348685;
-var summary = 'Let scoped variables should not be referenced outside blocks';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
- 
-  function f() {
-    for (let i = 0; i < 2; i++) {
-      let j = 42;
-      function g() {}
-    }
-    var a = i;
-    print(a);
-    print(i);
-    return i;
-  }
-
-  expect = /ReferenceError: (i|"i") is not defined/;
-
-  try
-  {
-    f();
-  }
-  catch(ex)
-  {
-    actual = ex + '';
-  }
-  reportMatch(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-349283.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 349283;
-var summary = 'Do not crash with let statement in with block';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
- 
-  with({b:2}) {
-    let c = 3;
-  }
-
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-349298.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 349298;
-var summary = 'Do not bogo assert';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
-
-  try
-  {
-    eval('(function() { for(i=0;i<4;++i) let x = 4; })');
-  }
-  catch(ex)
-  {
-    // See https://bugzilla.mozilla.org/show_bug.cgi?id=408957
-    summary = 'let declaration must be direct child of block or top-level implicit block';
-    expect = 'SyntaxError';
-    actual = ex.name;
-  }
- 
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-349507.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 349507;
-var summary = 'Do not assert with let block, let statement and const';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
-
-  try
-  {
-    eval('(function() { let(x = 1) { const b = 2 }; let b = 3; })');
-  }
-  catch(ex)
-  {
-    actual = ex + '';
-  }
-
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-349962.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 349962;
-var summary = 'let variable bound to nested function expressions'
-  var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
- 
-  (function() { let z = (function () { function a() { } })(); })()
-    reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-350279.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 350279;
-var summary = 'Do not assert: left->pn_type == TOK_RC';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
-
-  expect = /SyntaxError: /;
-  try
-  {
-    eval('let [2 for (x in [])] = 4;');
-  }
-  catch(ex)
-  {
-    actual = ex + '';
-  }
-
-  reportMatch(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-350730.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 350730;
-var summary = 'Do not assert: pn2->pn_slot >= 0 || varOrConst [@ EmitVariables]';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
-
-  try
-  {
-    eval('with({}) let y;');
-  }
-  catch(ex)
-  {
-    // See https://bugzilla.mozilla.org/show_bug.cgi?id=408957
-    summary = 'let declaration must be direct child of block or top-level implicit block';
-    expect = 'SyntaxError';
-    actual = ex.name;
-  }
-
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-350793-01.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 350793;
-var summary = 'for-in loops must be yieldable';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
-
-  function foo()
-  {
-    function gen() { for(let itty in [5,6,7,8]) yield ({ }); }
-
-    iter = gen();
-
-    let count = 0;
-    for each(let _ in iter)
-      ++count;
-  }
-
-  foo();
-
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-351606.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 351606;
-var summary = 'Do not assert with nested for..in and throw';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-enterFunc ('test');
-printBugNumber(BUGNUMBER);
-printStatus (summary);
-
-(function () {for (let d in [1,2,3,4]) try { for (let a in [5,6,7,8]) (( function() { throw 9; } )()); } catch(c) {  }});
-
-reportCompare(expect, actual, summary);
-
-
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-352092.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 352092;
-var summary = 'Do not assert on with() let';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
-
-  try
-  { 
-    eval('let(z) { with({}) let y = 3; }');
-  }
-  catch(ex)
-  {
-    // See https://bugzilla.mozilla.org/show_bug.cgi?id=408957
-    summary = 'let declaration must be direct child of block or top-level implicit block';
-    expect = 'SyntaxError';
-    actual = ex.name;
-  }
-
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-352267.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 352267;
-var summary = 'Do not assert with |if|, block, |let|';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
- 
-  uneval(function() { if (y) { { let set = 4.; } } else if ([1,2,3]) { } });
-
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-352422.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 352422;
-var summary = 'let declaration must be direct child of block, ' + 
-  'top-level implicit block, or switch body block';
-var actual = '';
-var expect = 'SyntaxError';
-
-// See https://bugzilla.mozilla.org/show_bug.cgi?id=408957
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
-
-  try
-  {
-    eval('(function() { with({}) let x; })');
-  }
-  catch(ex)
-  {
-    actual = ex.name;
-  }
- 
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-352609.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// |reftest| skip -- obsolete test
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 352609;
-var summary = 'decompilation of |let| expression for |is not a function| error';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
-
-  expect = /TypeError: (p.z = \(let \(x\) x\)|.*Undefined.*) is not a function/;
-  try
-  {
-    var p = {}; (p.z = let(x) x)()
-  }
-  catch(ex)
-  {
-    actual = ex + '';
-  }
-  reportMatch(expect, actual, 'p = {}; (p.z = let(x) x)()');
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-352624.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 352624;
-var summary = 'Do not crash with |let (map)| in WAY_TOO_MUCH_GC builds';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
-  printStatus('This bug can only be verified with a WAY_TOO_MUCH_GC build');
-
-  let (x = [].map(function () {})) { x; }
-  reportCompare(expect, actual, summary + ': 1');
-
-  var g = function() {};
-  (function() { let x = [].map(function () {}); g(x); })()
-    reportCompare(expect, actual, summary + ': 3');
-
-  for(let x in [1].map(function () { })) { }
-  reportCompare(expect, actual, summary + ': 4');
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-352786.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 352786;
-var summary = 'let declaration must be direct child of block, ' + 
-  'top-level implicit block, or switch body block';
-var actual = '';
-var expect = 'SyntaxError';
-
-// See https://bugzilla.mozilla.org/show_bug.cgi?id=408957
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
-
-  try
-  {
-    eval('(function() { { if(0) let x; } })');
-  }
-  catch(ex)
-  {
-    actual = ex.name;
-  }
- 
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-352907.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 352907;
-var summary = 'let declaration must be direct child of block, ' + 
-  'top-level implicit block, or switch body block';
-var actual = '';
-var expect = 'SyntaxError';
-
-// See https://bugzilla.mozilla.org/show_bug.cgi?id=408957
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
-
-  try
-  {
-    eval('(function() { while(0) while(0) let k=3; return k; })');
-  }
-  catch(ex)
-  {
-    actual = ex.name;
-  }
- 
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-357754.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- * Contributor: Blake Kaplan
- */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 357754;
-var summary = 'top level closures with let-bound varibles';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
- 
-  expect = 'No Error';
-  actual = 'No Error';
-  try
-  {
-    function f() { let k = 3; function g() { print(k); } g() }
-    f();
-  }
-  catch(ex)
-  {
-    actual = ex + '';
-  }
-  reportCompare(expect, actual, summary + ': 1');
-
-  expect = 'No Error';
-  actual = 'No Error';
-  try
-  {
-    function h() { let k = 3; if (1) function g() { print(k); } g() }
-    h();
-  }
-  catch(ex)
-  {
-    actual = ex + '';
-  }
-  reportCompare(expect, actual, summary + ': 2');
-
-  expect = 'No Error';
-  actual = 'No Error';
-  try
-  {
-    function i() { let k = 3; (function() { print(k); })() }
-    i();
-  }
-  catch(ex)
-  {
-    actual = ex + '';
-  }
-  reportCompare(expect, actual, summary + ': 3');
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-358508.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 358508;
-var summary = 'destructuring-parameters and block local functions';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
- 
-  try
-  {
-    (function({0x100000badf00d0: a}) {
-      function b() {}
-      let c;
-    })();
-  }
-  catch(ex)
-  {
-  }
-
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-376410.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 376410;
-var summary = 'let declaration must be direct child of block, ' + 
-  'top-level implicit block, or switch body block';
-var actual = '';
-var expect = 'SyntaxError';
-
-// See https://bugzilla.mozilla.org/show_bug.cgi?id=408957
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
-
-  try
-  {
-    eval('(function() { while(0) L: let x; print(x); })');
-  }
-  catch(ex)
-  {
-    actual = ex.name;
-  }
- 
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/block/regress-396900.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 396900;
-var summary = 'Destructuring bind in a let';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
- 
-  expect = '3, 4';
-  let ([x, y] = [3, 4]) { actual = x + ', ' + y}
-  reportCompare(expect, actual, summary);
-
-  expect = 'undefined, undefined';
-  actual = typeof x + ', ' + typeof y;
-  reportCompare(expect, actual, summary);
-  exitFunc ('test');
-}
deleted file mode 100644
deleted file mode 100644
--- a/js/src/tests/js1_7/extensions/regress-349619.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 349619;
-var summary = 'Do not assert with let block, object literal getter/setter';
-var actual = 'No Crash';
-var expect = 'No Crash';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
- 
-  (function() { let(y=3) { ({ get y() { }, set y(z) { } }) } });
-
-  reportCompare(expect, actual, summary);
-
-  exitFunc ('test');
-}
deleted file mode 100644
--- a/js/src/tests/js1_7/extensions/regress-366668-02.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 366668;
-var summary = 'decompilation of "let with with" ';
-var actual = '';
-var expect = '';
-
-
-//-----------------------------------------------------------------------------
-test();
-//-----------------------------------------------------------------------------
-
-function test()
-{
-  enterFunc ('test');
-  printBugNumber(BUGNUMBER);
-  printStatus (summary);
- 
-  var f;
-
-  f = function() { let (w) { with({x: w.something }) { } } };
-  expect = 'function() { let (w) { with({x: w.something }) { } } }';
-  actual = f + '';
-  compareSource(expect, actual, summary);
-
-  exitFunc ('test');
-}
--- a/js/src/tests/js1_7/regress/regress-353079.js
+++ b/js/src/tests/js1_7/regress/regress-353079.js
@@ -15,15 +15,15 @@ test();
 //-----------------------------------------------------------------------------
 
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
  
-  for (let a in [1]) let (x) {
-    for (let y in ((function(id2) { return id2; })( '' ))) { } }
+  for (let a in [1]) { { let x;
+    for (let y in ((function(id2) { return id2; })( '' ))) { } } }
 
   reportCompare(expect, actual, summary);
 
   exitFunc ('test');
 }
--- a/js/src/tests/js1_7/regress/regress-355832-01.js
+++ b/js/src/tests/js1_7/regress/regress-355832-01.js
@@ -17,14 +17,14 @@ test();
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
  
   expect = actual = 'No Crash';
 
-  let ([] = []) { }
+  { let [] = []; }
 
   reportCompare(expect, actual, summary);
 
   exitFunc ('test');
 }
--- a/js/src/tests/js1_7/regress/regress-355832-02.js
+++ b/js/src/tests/js1_7/regress/regress-355832-02.js
@@ -17,14 +17,14 @@ test();
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
  
   expect = actual = 'No Crash';
 
-  let ([] = []) { print(3) } print(4)
+  { let [] = []; print(3) } print(4)
 
 			       reportCompare(expect, actual, summary);
 
   exitFunc ('test');
 }
--- a/js/src/tests/js1_7/regress/regress-373827-01.js
+++ b/js/src/tests/js1_7/regress/regress-373827-01.js
@@ -15,14 +15,14 @@ test();
 //-----------------------------------------------------------------------------
 
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
  
-  let ([] = [{x: function(){}}]) { };
+  { let [] = [{x: function(){}}]; };
 
   reportCompare(expect, actual, summary);
 
   exitFunc ('test');
 }
--- a/js/src/tests/js1_7/regress/regress-373827-02.js
+++ b/js/src/tests/js1_7/regress/regress-373827-02.js
@@ -17,17 +17,17 @@ test();
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
  
   try
   {
-    let ([] = [{x: function(){}}]) { }; foo;
+    { let [] = [{x: function(){}}]; }; foo;
   }
   catch(ex)
   {
   }
 
   reportCompare(expect, actual, summary);
 
   exitFunc ('test');
--- a/js/src/tests/js1_7/regress/regress-414553.js
+++ b/js/src/tests/js1_7/regress/regress-414553.js
@@ -11,14 +11,15 @@ printStatus(summary);
 var expected = '1,2,3,4';
 
 let a = 1, [b,c] = [2,3], d = 4;
 var actual = String([a,b,c,d]);
 
 reportCompare(expected, actual, 'destructuring assignment in let');
 
 function f() {
-  let (a = 1, [b,c] = [2,3], d = 4) {
+  {
+    let a = 1, [b,c] = [2,3], d = 4;
     return String([a,b,c,d]);
   }
 }
 
 reportCompare(expected, f(), 'destructuring assignment in let inside func');
--- a/js/src/tests/js1_8/regress/regress-471660.js
+++ b/js/src/tests/js1_8/regress/regress-471660.js
@@ -21,17 +21,17 @@ function test()
   printStatus (summary);
 
   jit(true);
 
   y = {"a":1};
 
   for (var w = 0; w < 5; ++w) {
 
-    let (y) { do break ; while (true); }
+    { let y; do break ; while (true); }
     for each (let x in [{}, function(){}]) {y}
 
   }
 
   jit(false);
 
   reportCompare(expect, actual, summary);
 
--- a/js/src/tests/js1_8_1/regress/regress-452498-050.js
+++ b/js/src/tests/js1_8_1/regress/regress-452498-050.js
@@ -20,17 +20,17 @@ function test()
   printBugNumber(BUGNUMBER);
   printStatus (summary);
 
 // ------- Comment #50 From Jason Orendorff
 
 // Do not crash
 
 // compiler bug when a block introduces no names
-  let ({}={}) {}
+  { let {}={}; }
 
   try
   {
 // compiler incorrectly emits GETLOCAL for first `x`,
 // triggering decompiler assertion
     while (x.y) { let x; }
   }
   catch(ex)
--- a/js/src/tests/js1_8_1/regress/regress-452498-053.js
+++ b/js/src/tests/js1_8_1/regress/regress-452498-053.js
@@ -25,17 +25,17 @@ function test()
 // ------- Comment #53 From Jason Orendorff
 
 // Assertion failure: (slot) < (uint32_t)(obj)->dslots[-1]
 // at ../jsobj.cpp:5559
 // On the last line of BindLet, we have
 //    JS_SetReservedSlot(cx, blockObj, index, PRIVATE_TO_JSVAL(pn));
 // but this uses reserved slots as though they were unlimited.
 // blockObj only has 2.
-  let (a=0, b=1, c=2) {}
+  { let a=0, b=1, c=2; }
 
 // In RecycleTree at ../jsparse.cpp:315, we hit
 //     MOZ_CRASH("RecycleUseDefKids");
 // pn->pn_type is TOK_UNARYOP
 // pn->pn_op   is JSOP_XMLNAME
 // pn->pn_defn is 1
 // pn->pn_used is 1
   try
--- a/js/src/tests/js1_8_1/regress/regress-496922.js
+++ b/js/src/tests/js1_8_1/regress/regress-496922.js
@@ -14,26 +14,26 @@ var expect = '0,0,1,1,2,2,3,3';
 
 // The code must run as part of the top-level script in order to get the bug.
 enterFunc ('test');
 printBugNumber(BUGNUMBER);
 printStatus (summary);
 jit(true);
 
 var a = [];
-let(
-f = function() {
+{
+let f = function() {
     for (let x = 0; x < 4; ++x) {
         (function() {
             for (let y = 0; y < 2; ++y) {
               a.push(x);
             }
         })()
     }
-}) { (function() {})()
+}; (function() {})()
     f(99)
 }
 actual = '' + a;
 
 jit(false);
 reportCompare(expect, actual, summary);
 exitFunc ('test');
 //-----------------------------------------------------------------------------
--- a/js/src/tests/js1_8_1/regress/regress-522123.js
+++ b/js/src/tests/js1_8_1/regress/regress-522123.js
@@ -20,17 +20,18 @@ function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
  
   expect = 1;
 
   evil=eval;
-  let (x=2) {
+  {
+    let x=2;
     actual = evil("x");
   };
 
   reportCompare(expect, actual, summary);
 
   exitFunc ('test');
 }
 
deleted file mode 100644
--- a/js/src/tests/js1_8_1/strict/let-block-eval-arguments.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// |reftest| skip-if(Android)
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- */
-
-/* In strict mode, a 'let' block may not bind 'eval' or 'arguments'. */
-assertEq(testLenientAndStrict('let (eval=1) {}',
-                              parsesSuccessfully,
-                              parseRaisesException(SyntaxError)),
-         true);
-assertEq(testLenientAndStrict('let ([eval]=1) {}',
-                              parsesSuccessfully,
-                              parseRaisesException(SyntaxError)),
-         true);
-assertEq(testLenientAndStrict('let ({x:eval}=1) {}',
-                              parsesSuccessfully,
-                              parseRaisesException(SyntaxError)),
-         true);
-assertEq(testLenientAndStrict('let (arguments=1) {}',
-                              parsesSuccessfully,
-                              parseRaisesException(SyntaxError)),
-         true);
-assertEq(testLenientAndStrict('let ([arguments]=1) {}',
-                              parsesSuccessfully,
-                              parseRaisesException(SyntaxError)),
-         true);
-assertEq(testLenientAndStrict('let ({x:arguments}=1) {}',
-                              parsesSuccessfully,
-                              parseRaisesException(SyntaxError)),
-         true);
-
-reportCompare(true, true);
--- a/js/src/tests/js1_8_5/reflect-parse/lexicals.js
+++ b/js/src/tests/js1_8_5/reflect-parse/lexicals.js
@@ -9,34 +9,11 @@ assertLocalDecl("let {x:y} = foo;", letD
                                                init: ident("foo") }]));
 // block-local let is let
 assertBlockDecl("let {x:y} = foo;", letDecl([{ id: objPatt([assignProp("x", ident("y"))]),
                                                init: ident("foo") }]));
 
 assertDecl("const {x:y} = foo;", constDecl([{ id: objPatt([assignProp("x", ident("y"))]),
                                               init: ident("foo") }]));
 
-// let statements
-
-assertStmt("let (x=1) { }", letStmt([{ id: ident("x"), init: lit(1) }], blockStmt([])));
-assertStmt("let (x=1,y=2) { }", letStmt([{ id: ident("x"), init: lit(1) },
-                                         { id: ident("y"), init: lit(2) }],
-                                        blockStmt([])));
-assertStmt("let (x=1,y=2,z=3) { }", letStmt([{ id: ident("x"), init: lit(1) },
-                                             { id: ident("y"), init: lit(2) },
-                                             { id: ident("z"), init: lit(3) }],
-                                            blockStmt([])));
-assertStmt("let (x) { }", letStmt([{ id: ident("x"), init: null }], blockStmt([])));
-assertStmt("let (x,y) { }", letStmt([{ id: ident("x"), init: null },
-                                     { id: ident("y"), init: null }],
-                                    blockStmt([])));
-assertStmt("let (x,y,z) { }", letStmt([{ id: ident("x"), init: null },
-                                       { id: ident("y"), init: null },
-                                       { id: ident("z"), init: null }],
-                                      blockStmt([])));
-assertStmt("let (x = 1, y = x) { }", letStmt([{ id: ident("x"), init: lit(1) },
-                                              { id: ident("y"), init: ident("x") }],
-                                             blockStmt([])));
-assertError("let (x = 1, x = 2) { }", TypeError);
-
 }
 
 runtest(test);
--- a/js/src/tests/js1_8_5/regress/regress-541255-3.js
+++ b/js/src/tests/js1_8_5/regress/regress-541255-3.js
@@ -1,13 +1,13 @@
 /*
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/
  * Contributors: Gary Kwong and Jason Orendorff
  */
 
 function f(y) {
-    eval("let (z=2, w=y) { (function () { w.p = 7; })(); }");
+    eval("{ let z=2, w=y; (function () { w.p = 7; })(); }");
 }
 var x = {};
 f(x);
 assertEq(x.p, 7);
 reportCompare(0, 0, "");
--- a/js/src/tests/js1_8_5/regress/regress-554955-1.js
+++ b/js/src/tests/js1_8_5/regress/regress-554955-1.js
@@ -3,17 +3,18 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/
  */
 
 function f(s) {
   eval(s);
   return function(a) {
     var d;
-    let (c = 3) {
+    {
+      let c = 3;
       d = function() { a; }; // force Block object to be cloned
       with({}) {}; // repel J├ĄgerMonkey
       return b; // lookup occurs in scope of Block
     }
   };
 }
 
 var b = 1;
--- a/js/src/tests/js1_8_5/regress/regress-554955-3.js
+++ b/js/src/tests/js1_8_5/regress/regress-554955-3.js
@@ -4,17 +4,18 @@
  * http://creativecommons.org/licenses/publicdomain/
  */
 
 function f(s) {
     eval(s);
     return function(a) {
         with({}) {}; // repel J├ĄgerMonkey
         eval(a);
-        let (c = 3) {
+        {
+            let c = 3;
             return b;
         };
     };
 }
 
 var b = 1;
 var g1 = f("");
 var g2 = f("var b = 2;");
--- a/js/src/tests/js1_8_5/regress/regress-554955-4.js
+++ b/js/src/tests/js1_8_5/regress/regress-554955-4.js
@@ -6,17 +6,18 @@
 
 function f() {
     return function(a) {
         // This eval must take place before the block is cloned, when the
         // call object is still not marked as a delegate. The scope chain
         // purge for the JSOP_DEFVAR will not change the global's shape,
         // and the property cache entry will remain valid.
         eval(a);
-        let (c = 3) {
+        {
+            let c = 3;
             // This eval forces the block to be cloned, so its shape gets
             // used as the property cache key shape.
             eval('');
             return b;
         };
     };
 }
 
--- a/js/src/tests/js1_8_5/regress/regress-554955-6.js
+++ b/js/src/tests/js1_8_5/regress/regress-554955-6.js
@@ -5,17 +5,18 @@
  */
 
 var v="global";
 function f(a) {
   // This eval could extend f's call object. However, the call object has
   // not yet been marked as a delegate at this point, so no scope chain
   // purge takes place when it is extended.
   eval(a);
-  let (b=3) {
+  {
+    let b=3;
     // This eval causes the cloned block object to be added to the
     // scope chain. The block needs a unique shape: its parent call
     // could acquire bindings for anything without affecting the global
     // object's shape, so it's up to the block's shape to mismatch all
     // property cache entries for prior blocks.
     eval("");
     return v;
   };
@@ -28,18 +29,20 @@ assertEq("global", f(""));
 // Call the function again, adding a binding to the call, and ensure that
 // we do not see any property cache entry created by the previous reference
 // that would direct us to the global definition.
 assertEq("local", f("var v='local'"));
 
 // Similarly,but with a doubly-nested block; make sure everyone gets marked.
 function f2(a) {
   eval(a);
-  let (b=3) {
-    let (c=4) {
+  {
+    let b=3;
+    {
+      let c=4;
       eval("");
       return v;
     };
   };
 }
 
 assertEq("global", f2(""));
 assertEq("local",  f2("var v='local'"));
deleted file mode 100644
--- a/js/src/tests/js1_8_5/regress/regress-673070-1.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-var q = [2];
-let ([q] = eval("q")) {
-    assertEq(q, 2);
-}
-
-reportCompare(0, 0, 'ok');
deleted file mode 100644
--- a/js/src/tests/js1_8_5/regress/regress-673070-2.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-var q = 1;
-let ([q] = [eval("q")]) {
-    assertEq(q, 1);
-}
-
-reportCompare(0, 0, 'ok');
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -24,21 +24,21 @@ namespace js {
  * versions.  If deserialization fails, the data should be invalidated if
  * possible.
  *
  * When you change this, run make_opcode_doc.py and copy the new output into
  * this wiki page:
  *
  *  https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
  */
-static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 316;
+static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 317;
 static const uint32_t XDR_BYTECODE_VERSION =
     uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
 
-static_assert(JSErr_Limit == 419,
+static_assert(JSErr_Limit == 418,
               "GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
               "removed MSG_DEFs from js.msg, you should increment "
               "XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "
               "expected JSErr_Limit value.");
 
 class XDRBuffer {
   public:
     explicit XDRBuffer(JSContext* cx)