Ver código fonte

Merge branch 'master' into linux

Hitesh Kanwathirtha 9 anos atrás
pai
commit
9eba31c889

+ 31 - 8
Build/Chakra.Core.sln

@@ -1,13 +1,33 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 14
-VisualStudioVersion = 14.0.23107.0
+VisualStudioVersion = 14.0.24720.0
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChakraCore", "..\bin\ChakraCore\ChakraCore.vcxproj", "{EA882C8D-81FC-42FE-ABD5-2666DB933FDB}"
+	ProjectSection(ProjectDependencies) = postProject
+		{1876E800-AD77-48C4-A2F7-E5265F24AC38} = {1876E800-AD77-48C4-A2F7-E5265F24AC38}
+		{5643D42A-C38D-4D82-9662-58470B3AC9F7} = {5643D42A-C38D-4D82-9662-58470B3AC9F7}
+		{FD8EEC40-4141-448A-BF4B-1589FBE4F60D} = {FD8EEC40-4141-448A-BF4B-1589FBE4F60D}
+		{6979EC58-7A28-465C-A694-F3323A1F5401} = {6979EC58-7A28-465C-A694-F3323A1F5401}
+		{F6FAD160-5A4B-476A-93AC-33E0B3A18C0C} = {F6FAD160-5A4B-476A-93AC-33E0B3A18C0C}
+		{18CF279F-188D-4655-B03D-74F65388E7D1} = {18CF279F-188D-4655-B03D-74F65388E7D1}
+		{ABC904AD-9415-46F8-AA23-E33193F81F7C} = {ABC904AD-9415-46F8-AA23-E33193F81F7C}
+		{8C61E4E7-F0D6-420D-A352-3E6E50D406DD} = {8C61E4E7-F0D6-420D-A352-3E6E50D406DD}
+		{706083F7-6AA4-4558-A153-6352EF9110EE} = {706083F7-6AA4-4558-A153-6352EF9110EE}
+		{706083F7-6AA4-4558-A153-6352EF9110F5} = {706083F7-6AA4-4558-A153-6352EF9110F5}
+		{706083F7-6AA4-4558-A153-6352EF9110F6} = {706083F7-6AA4-4558-A153-6352EF9110F6}
+		{706083F7-6AA4-4558-A153-6352EF9110F7} = {706083F7-6AA4-4558-A153-6352EF9110F7}
+		{706083F7-6AA4-4558-A153-6352EF9110F8} = {706083F7-6AA4-4558-A153-6352EF9110F8}
+		{706083F7-6AA4-4558-A153-6352EF9220EE} = {706083F7-6AA4-4558-A153-6352EF9220EE}
+		{706083F7-6AA4-4558-A153-6352EF9220F5} = {706083F7-6AA4-4558-A153-6352EF9220F5}
+		{BB4153FF-AC3E-4734-B562-CC23812DF31B} = {BB4153FF-AC3E-4734-B562-CC23812DF31B}
+		{BB4153FF-AC3E-4734-B562-FF23812DF31B} = {BB4153FF-AC3E-4734-B562-FF23812DF31B}
+		{CC4153FF-AC3E-4734-B562-CC23812DF31B} = {CC4153FF-AC3E-4734-B562-CC23812DF31B}
+	EndProjectSection
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{D8216B93-BD6E-4293-8D98-79CEF7CF66BC}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.Codex", "..\lib\Common\Codex\Chakra.Common.Codex.vcxproj", "{1876E800-AD77-48C4-A2F7-E5265F24AC38}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.Codex", "..\lib\common\Codex\Chakra.Common.Codex.vcxproj", "{1876E800-AD77-48C4-A2F7-E5265F24AC38}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Runtime.ByteCode", "..\lib\Runtime\ByteCode\Chakra.Runtime.ByteCode.vcxproj", "{706083F7-6AA4-4558-A153-6352EF9110F5}"
 EndProject
@@ -19,19 +39,19 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Runtime.Library", ".
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Runtime.Types", "..\lib\Runtime\Types\Chakra.Runtime.Types.vcxproj", "{706083F7-6AA4-4558-A153-6352EF9110F6}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.Common", "..\lib\Common\Common\Chakra.Common.Common.vcxproj", "{BB4153FF-AC3E-4734-B562-CC23812DF31B}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.Common", "..\lib\common\Common\Chakra.Common.Common.vcxproj", "{BB4153FF-AC3E-4734-B562-CC23812DF31B}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Runtime", "Runtime", "{DDF436E7-0A8E-41AA-82B3-902B5D2D0809}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{546172B2-F084-4363-BE35-06010663D319}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.Core", "..\lib\Common\Core\Chakra.Common.Core.vcxproj", "{CC4153FF-AC3E-4734-B562-CC23812DF31B}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.Core", "..\lib\common\Core\Chakra.Common.Core.vcxproj", "{CC4153FF-AC3E-4734-B562-CC23812DF31B}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.DataStructures", "..\lib\Common\DataStructures\Chakra.Common.DataStructures.vcxproj", "{5643D42A-C38D-4D82-9662-58470B3AC9F7}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.DataStructures", "..\lib\common\DataStructures\Chakra.Common.DataStructures.vcxproj", "{5643D42A-C38D-4D82-9662-58470B3AC9F7}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.Exceptions", "..\lib\Common\Exceptions\Chakra.Common.Exceptions.vcxproj", "{FD8EEC40-4141-448A-BF4B-1589FBE4F60D}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.Exceptions", "..\lib\common\Exceptions\Chakra.Common.Exceptions.vcxproj", "{FD8EEC40-4141-448A-BF4B-1589FBE4F60D}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.Memory", "..\lib\Common\Memory\Chakra.Common.Memory.vcxproj", "{BB4153FF-AC3E-4734-B562-FF23812DF31B}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.Memory", "..\lib\common\Memory\Chakra.Common.Memory.vcxproj", "{BB4153FF-AC3E-4734-B562-FF23812DF31B}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Backend", "..\lib\Backend\Chakra.Backend.vcxproj", "{18CF279F-188D-4655-B03D-74F65388E7D1}"
 EndProject
@@ -43,7 +63,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Jsrt.Core", "..\lib\
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Runtime.Math", "..\lib\Runtime\Math\Chakra.Runtime.Math.vcxproj", "{ABC904AD-9415-46F8-AA23-E33193F81F7C}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.Util", "..\lib\Common\Util\Chakra.Common.Util.vcxproj", "{6979EC58-7A28-465C-A694-F3323A1F5401}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra.Common.Util", "..\lib\common\util\Chakra.Common.Util.vcxproj", "{6979EC58-7A28-465C-A694-F3323A1F5401}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{158C8616-750C-4E0E-BD3D-5721D3C555E6}"
 EndProject
@@ -52,6 +72,9 @@ EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Bin", "Bin", "{D3BA0BFC-4757-4B73-994F-3556950884A1}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ch", "..\bin\ch\ch.vcxproj", "{0216C4BE-86CE-478D-A134-23EAEE545B9D}"
+	ProjectSection(ProjectDependencies) = postProject
+		{EA882C8D-81FC-42FE-ABD5-2666DB933FDB} = {EA882C8D-81FC-42FE-ABD5-2666DB933FDB}
+	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rl", "..\bin\rl\rl.vcxproj", "{80A70F57-0F89-458F-AFD3-CE2159EB9BB1}"
 EndProject

+ 5 - 3
Build/scripts/pgo/pogo_training.ps1

@@ -27,7 +27,8 @@ param (
 
     [string]$vcinstallroot = ${env:ProgramFiles(x86)},
     [string]$vcbinpath = "Microsoft Visual Studio 14.0\VC\bin",
-    [string]$dllname = "pgort140.dll"
+    [string]$dllname = "pgort140.dll",
+    [string]$dllCheckName = "pgort*.dll"
 )
 
 if (${Env:PogoConfig} -eq "False") {
@@ -36,8 +37,9 @@ if (${Env:PogoConfig} -eq "False") {
 }
 
 $binpath = Split-Path -Path $binary -Parent
-$pgoOutDll = Join-Path $binpath $dllname;
-if (-not (Test-Path ($pgoOutDll))) {
+$pgoOutDllCheck = Join-Path $binpath $dllCheckName
+$pgoOutDll = Join-Path $binpath $dllname
+if (-not (Test-Path $pgoOutDllCheck)) {
     if ($arch -eq "x64") {
         $dllname = Join-Path "amd64" $dllname
     } elseif ($arch -eq "arm") {

+ 46 - 19
lib/Backend/GlobOpt.cpp

@@ -127,6 +127,7 @@
     Output::Print(__VA_ARGS__);\
     IR::Instr* __instr__ = instr;\
     if(__instr__) __instr__->DumpByteCodeOffset();\
+    if(__instr__) Output::Print(_u(" (%s)"), Js::OpCodeUtil::GetOpCodeName(__instr__->m_opcode));\
     Output::Print(_u("\n"));\
     Output::Flush(); \
 }
@@ -4531,27 +4532,9 @@ MemOpCheckInductionVariable:
         // Fallthrough if not an induction variable
     }
     default:
-        // Check prev instr because it could have been added by an optimization and we won't see it here.
-        if (OpCodeAttr::FastFldInstr(instr->m_opcode) || (instr->m_prev && OpCodeAttr::FastFldInstr(instr->m_prev->m_opcode)))
+        if (IsInstrInvalidForMemOp(instr, loop, src1Val, src2Val))
         {
-            // Refuse any operations interacting with Fields
             loop->memOpInfo->doMemOp = false;
-            TRACE_MEMOP_VERBOSE(loop, instr, _u("Field interaction detected"));
-            return false;
-        }
-
-        if (Js::OpCodeUtil::GetOpCodeLayout(instr->m_opcode) == Js::OpLayoutType::ElementSlot)
-        {
-            // Refuse any operations interacting with slots
-            loop->memOpInfo->doMemOp = false;
-            TRACE_MEMOP_VERBOSE(loop, instr, _u("Slot interaction detected"));
-            return false;
-        }
-
-        if (this->MayNeedBailOnImplicitCall(instr, src1Val, src2Val))
-        {
-            loop->memOpInfo->doMemOp = false;
-            TRACE_MEMOP_VERBOSE(loop, instr, _u("Implicit call bailout detected"));
             return false;
         }
 
@@ -4578,6 +4561,48 @@ MemOpCheckInductionVariable:
     return true;
 }
 
+bool
+GlobOpt::IsInstrInvalidForMemOp(IR::Instr *instr, Loop *loop, Value *src1Val, Value *src2Val)
+{
+    // List of instruction that are valid with memop (ie: instr that gets removed if memop is emitted)
+    if (
+        this->currentBlock != loop->GetHeadBlock() &&
+        !instr->IsLabelInstr() &&
+        instr->IsRealInstr() &&
+        instr->m_opcode != Js::OpCode::IncrLoopBodyCount &&
+        instr->m_opcode != Js::OpCode::StLoopBodyCount &&
+        instr->m_opcode != Js::OpCode::Ld_A &&
+        instr->m_opcode != Js::OpCode::Ld_I4 &&
+        !(instr->IsBranchInstr() && instr->AsBranchInstr()->IsUnconditional())
+    )
+    {
+        TRACE_MEMOP_VERBOSE(loop, instr, _u("Instruction not accepted for memop"));
+        return true;
+    }
+
+    // Check prev instr because it could have been added by an optimization and we won't see it here.
+    if (OpCodeAttr::FastFldInstr(instr->m_opcode) || (instr->m_prev && OpCodeAttr::FastFldInstr(instr->m_prev->m_opcode)))
+    {
+        // Refuse any operations interacting with Fields
+        TRACE_MEMOP_VERBOSE(loop, instr, _u("Field interaction detected"));
+        return true;
+    }
+
+    if (Js::OpCodeUtil::GetOpCodeLayout(instr->m_opcode) == Js::OpLayoutType::ElementSlot)
+    {
+        // Refuse any operations interacting with slots
+        TRACE_MEMOP_VERBOSE(loop, instr, _u("Slot interaction detected"));
+        return true;
+    }
+
+    if (this->MayNeedBailOnImplicitCall(instr, src1Val, src2Val))
+    {
+        TRACE_MEMOP_VERBOSE(loop, instr, _u("Implicit call bailout detected"));
+        return true;
+    }
+    return false;
+}
+
 IR::Instr *
 GlobOpt::OptInstr(IR::Instr *&instr, bool* isInstrRemoved)
 {
@@ -20939,6 +20964,7 @@ GlobOpt::RemoveMemOpSrcInstr(IR::Instr* memopInstr, IR::Instr* srcInstr, BasicBl
         {
             switch (topInstr->m_prev->m_opcode)
             {
+            case Js::OpCode::BailOnNotArray:
             case Js::OpCode::NoImplicitCallUses:
             case Js::OpCode::ByteCodeUses:
                 topInstr = topInstr->m_prev;
@@ -20956,6 +20982,7 @@ GlobOpt::RemoveMemOpSrcInstr(IR::Instr* memopInstr, IR::Instr* srcInstr, BasicBl
         IR::Instr* removeInstr = topInstr;
         topInstr = topInstr->m_next;
         Assert(
+            removeInstr->m_opcode == Js::OpCode::BailOnNotArray ||
             removeInstr->m_opcode == Js::OpCode::NoImplicitCallUses ||
             removeInstr->m_opcode == Js::OpCode::ByteCodeUses ||
             removeInstr->m_opcode == Js::OpCode::LdIndir ||

+ 1 - 0
lib/Backend/GlobOpt.h

@@ -1430,6 +1430,7 @@ private:
     bool                    ShouldExpectConventionalArrayIndexValue(IR::IndirOpnd *const indirOpnd);
     ValueType               GetDivValueType(IR::Instr* instr, Value* src1Val, Value* src2Val, bool specialize);
 
+    bool                    IsInstrInvalidForMemOp(IR::Instr *, Loop *, Value *, Value *);
     bool                    CollectMemOpInfo(IR::Instr *, Value *, Value *);
     bool                    CollectMemOpStElementI(IR::Instr *, Loop *);
     bool                    CollectMemsetStElementI(IR::Instr *, Loop *);

+ 23 - 17
lib/Backend/IRBuilder.cpp

@@ -540,24 +540,7 @@ IRBuilder::Build()
             this->AddInstr(instr, offset);
         }
 
-        Js::RegSlot frameDisplayReg = funcBody->GetLocalFrameDisplayRegister();
         Js::RegSlot funcExprScopeReg = funcBody->GetFuncExprScopeRegister();
-        IR::RegOpnd *frameDisplayOpnd = nullptr;
-        if (funcExprScopeReg != Js::Constants::NoRegister)
-        {
-            IR::RegOpnd *funcExprScopeOpnd = BuildDstOpnd(funcExprScopeReg);
-            instr = IR::Instr::New(Js::OpCode::NewPseudoScope, funcExprScopeOpnd, m_func);
-            this->AddInstr(instr, (uint)-1);
-
-            frameDisplayOpnd = BuildDstOpnd(frameDisplayReg);
-            instr = IR::Instr::New(Js::OpCode::LdFrameDisplay, frameDisplayOpnd, funcExprScopeOpnd, m_func);
-            if (envReg != Js::Constants::NoRegister)
-            {
-                instr->SetSrc2(BuildSrcOpnd(envReg));
-            }
-            this->AddInstr(instr, (uint)-1);
-        }
-
         Js::RegSlot closureReg = funcBody->GetLocalClosureRegister();
         IR::RegOpnd *closureOpnd = nullptr;
         if (closureReg != Js::Constants::NoRegister)
@@ -573,6 +556,13 @@ IRBuilder::Build()
             }
             if (funcBody->HasScopeObject())
             {
+                if (funcExprScopeReg != Js::Constants::NoRegister)
+                {
+                    IR::RegOpnd *funcExprScopeOpnd = BuildDstOpnd(funcExprScopeReg);
+                    instr = IR::Instr::New(Js::OpCode::NewPseudoScope, funcExprScopeOpnd, m_func);
+                    this->AddInstr(instr, (uint)-1);
+                }
+
                 if (funcBody->HasCachedScopePropIds())
                 {
                     this->BuildInitCachedScope(0, offset);
@@ -616,11 +606,25 @@ IRBuilder::Build()
             }
         }
 
+        Js::RegSlot frameDisplayReg = funcBody->GetLocalFrameDisplayRegister();
         if (frameDisplayReg != Js::Constants::NoRegister && closureReg != Js::Constants::NoRegister)
         {
             Assert(!this->RegIsConstant(frameDisplayReg));
 
             Js::OpCode op = m_func->DoStackScopeSlots() ? Js::OpCode::NewStackFrameDisplay : Js::OpCode::LdFrameDisplay;
+            IR::RegOpnd * frameDisplayOpnd = nullptr;
+            if (funcExprScopeReg != Js::Constants::NoRegister)
+            {
+                // Insert the function expression scope ahead of any enclosing scopes.
+                IR::RegOpnd * funcExprScopeOpnd = BuildSrcOpnd(funcExprScopeReg);
+                frameDisplayOpnd = IR::RegOpnd::New(TyVar, m_func);
+                instr = IR::Instr::New(Js::OpCode::LdFrameDisplay, frameDisplayOpnd, funcExprScopeOpnd, m_func);
+                if (envReg != Js::Constants::NoRegister)
+                {
+                    instr->SetSrc2(this->BuildSrcOpnd(envReg));
+                }
+                this->AddInstr(instr, (uint)-1);
+            }
 
             IR::RegOpnd *dstOpnd;
             if (m_func->DoStackScopeSlots() && m_func->IsTopFunc())
@@ -634,10 +638,12 @@ IRBuilder::Build()
             instr = IR::Instr::New(op, dstOpnd, closureOpnd, m_func);
             if (frameDisplayOpnd != nullptr)
             {
+                // We're building on an intermediate LdFrameDisplay result.
                 instr->SetSrc2(frameDisplayOpnd);
             }
             else if (envReg != Js::Constants::NoRegister)
             {
+                // We're building on the environment created by the enclosing function.
                 instr->SetSrc2(this->BuildSrcOpnd(envReg));
             }
             this->AddInstr(instr, offset);

+ 4 - 2
lib/Runtime/ByteCode/ByteCodeEmitter.cpp

@@ -6166,9 +6166,10 @@ void EmitDestructuredArray(
             elem = list;
         }
 
-        if (elem->nop == knopEllipsis)
+        if (elem->nop == knopEllipsis
+            || (elem->nop == knopEmpty && list->nop == knopEmpty))
         {
-            // Rest must be the last argument - no need to continue.
+            // Rest and last empty slot do not require any more processing.
             break;
         }
 
@@ -6190,6 +6191,7 @@ void EmitDestructuredArray(
             break;
         }
 
+
         byteCodeGenerator->StartStatement(elem);
 
         Js::RegSlot itemLocation = funcInfo->AcquireTmpRegister();

+ 5 - 1
lib/Runtime/ByteCode/ByteCodeGenerator.cpp

@@ -2677,7 +2677,11 @@ FuncInfo* PostVisitFunction(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerat
                 top->GetChildCallsEval() ||
                 (top->GetHasArguments() && ByteCodeGenerator::NeedScopeObjectForArguments(top, pnode) && pnode->sxFnc.pnodeParams != nullptr) ||
                 top->GetHasLocalInClosure() ||
-                (top->funcExprScope && top->funcExprScope->GetMustInstantiate()))
+                (top->funcExprScope && top->funcExprScope->GetMustInstantiate()) ||
+                // When we have split scope normally either eval will be present or the GetHasLocalInClosure will be true as one of the formal is
+                // captured. But when we force split scope or split scope happens due to some other reasons we have to make sure we allocate frame
+                // slot register here.
+                (top->paramScope != nullptr && !top->paramScope->GetCanMergeWithBodyScope()))
             {
                 if (!top->GetCallsEval())
                 {

+ 7 - 2
lib/Runtime/Language/InterpreterStackFrame.cpp

@@ -1401,6 +1401,7 @@ namespace Js
         }
 
         RegSlot closureReg = executeFunction->GetLocalClosureRegister();
+        Var funcExprScope = nullptr;
         if (closureReg != Js::Constants::NoRegister)
         {
             Assert(closureReg >= executeFunction->GetConstantCount());
@@ -1412,9 +1413,8 @@ namespace Js
                     // t0 = NewPseudoScope
                     // t1 = LdFrameDisplay t0 env
 
-                    Var funcExprScope = JavascriptOperators::OP_NewPseudoScope(GetScriptContext());
+                    funcExprScope = JavascriptOperators::OP_NewPseudoScope(GetScriptContext());
                     SetReg(funcExprScopeReg, funcExprScope);
-                    environment = OP_LdFrameDisplay(funcExprScope, environment, GetScriptContext());
                 }
 
                 this->NewScopeObject();
@@ -1431,6 +1431,11 @@ namespace Js
         {
             Assert(frameDisplayReg >= executeFunction->GetConstantCount());
 
+            if (funcExprScope != nullptr)
+            {
+                environment = OP_LdFrameDisplay(funcExprScope, environment, GetScriptContext());
+            }
+
             void *argHead = this->GetLocalClosure();
             this->SetLocalFrameDisplay(this->NewFrameDisplay(argHead, environment));
 

+ 14 - 1
test/Function/funcExpr.js

@@ -194,7 +194,20 @@ var Test22 = function F_Test22()
     return e;
 }
 
-var numTests = 23;
+var Test23 = function F_Test23() {
+    var x = 1;
+    new (function g() { 
+        with({}) { 
+            WScript.Echo('typeof g === ' + typeof g);
+            WScript.Echo('typeof F_Test23 === ' + typeof F_Test23);
+            WScript.Echo('typeof x === ' + typeof x);
+            if (!x) 
+                g(); 
+        } 
+    } );
+}
+
+var numTests = 24;
 
 for (var i=0;i<numTests;i++)
 {

+ 9 - 0
test/Function/funcExpr5.baseline

@@ -271,3 +271,12 @@ check66: F_Test21(); @'F_Test21' is undefined
 check67: Test22(); @'e' is undefined
 check68: Test22('hello'); @'e' is undefined
 check69: F_Test22(); @'F_Test22' is undefined
+typeof g === function
+typeof F_Test23 === function
+typeof x === number
+check70: Test23(); #undefined
+typeof g === function
+typeof F_Test23 === function
+typeof x === number
+check71: Test23('hello'); #undefined
+check72: F_Test23(); @'F_Test23' is undefined

+ 7 - 0
test/es6/default-splitscope.js

@@ -89,6 +89,13 @@ var tests = [
         }
         f9();
         f9();
+        
+        function f12() {
+            var result = ((a = (w = a => a * a) => w) => a)()()(10); 
+            
+            assert.areEqual(100, result, "The inner lambda function properly maps to the right symbol for a");
+        };
+        f12();
     } 
  }, 
  { 

+ 34 - 0
test/es6/destructuring.js

@@ -581,6 +581,40 @@ var tests = [
         }
         assert.isTrue(foo(), "Array destructuring pattern on for..in is initialized correctly");
       }
+      
+      {
+         let obj1 = {};
+         obj1[Symbol.iterator] = function () {
+            return {
+                next: function() {
+                    assert.fail("next function should not be called");
+                }
+            };
+         };
+         
+         // Empty slot should not call next on the iterator.
+         var [] = obj1;
+      }
+
+      {
+         let obj1 = {};
+         obj1[Symbol.iterator] = function () {
+            return {
+                next: function() {
+                    this.counter++;
+                    if (this.counter > 1)
+                    {
+                        assert.fail("next function should not be called for the second time");
+                    }
+                    return {value : undefined, done: false};
+                },
+                counter : 0
+            };
+         };
+         
+         // Second empty slot should not call next on the iterator.
+         var [,] = obj1;
+      }
 
     }
   }