Przeglądaj źródła

TTD - Tests and Bug Fixes

Mark Marron 9 lat temu
rodzic
commit
830fa57243
100 zmienionych plików z 2881 dodań i 156 usunięć
  1. 8 0
      lib/Jsrt/Jsrt.cpp
  2. 2 2
      lib/Runtime/Debug/TTEventLog.cpp
  3. 1 1
      lib/Runtime/Debug/TTEventLog.h
  4. 1 1
      lib/Runtime/Debug/TTEvents.h
  5. 1 3
      lib/Runtime/Debug/TTSerialize.cpp
  6. 61 42
      lib/Runtime/Debug/TTSnapObjects.cpp
  7. 63 31
      lib/Runtime/Debug/TTSnapObjects.h
  8. 1 0
      lib/Runtime/Debug/TTSnapTypes.cpp
  9. 1 0
      lib/Runtime/Debug/TTSnapTypes.h
  10. 13 8
      lib/Runtime/Debug/TTSnapValues.cpp
  11. 1 0
      lib/Runtime/Debug/TTSnapValues.h
  12. 1 0
      lib/Runtime/Library/ES5Array.cpp
  13. 10 1
      lib/Runtime/Library/JavascriptLibrary.cpp
  14. 1 0
      lib/Runtime/Library/JavascriptLibrary.h
  15. 18 21
      lib/Runtime/Types/DictionaryTypeHandler.cpp
  16. 1 1
      lib/Runtime/Types/DictionaryTypeHandler.h
  17. 1 3
      lib/Runtime/Types/DynamicObject.cpp
  18. 2 2
      lib/Runtime/Types/PathTypeHandler.cpp
  19. 1 1
      lib/Runtime/Types/PathTypeHandler.h
  20. 7 5
      lib/Runtime/Types/SimpleDictionaryTypeHandler.cpp
  21. 1 1
      lib/Runtime/Types/SimpleDictionaryTypeHandler.h
  22. 4 3
      lib/Runtime/Types/SimpleTypeHandler.cpp
  23. 1 1
      lib/Runtime/Types/SimpleTypeHandler.h
  24. 4 2
      lib/Runtime/Types/TypeHandler.cpp
  25. 1 1
      lib/Runtime/Types/TypeHandler.h
  26. 29 0
      test/TTBasic/accessor.js
  27. 10 0
      test/TTBasic/accessorRecord.baseline
  28. 10 0
      test/TTBasic/accessorReplay.baseline
  29. 33 0
      test/TTBasic/array.js
  30. 10 0
      test/TTBasic/arrayRecord.baseline
  31. 10 0
      test/TTBasic/arrayReplay.baseline
  32. 63 0
      test/TTBasic/bind.js
  33. 20 0
      test/TTBasic/bindRecord.baseline
  34. 22 0
      test/TTBasic/bindReplay.baseline
  35. 50 0
      test/TTBasic/constructor.js
  36. 3 0
      test/TTBasic/constructorRecord.baseline
  37. 5 0
      test/TTBasic/constructorReplay.baseline
  38. 12 0
      test/TTBasic/dateBasic.js
  39. 2 0
      test/TTBasic/dateBasicRecord.baseline
  40. 2 0
      test/TTBasic/dateBasicReplay.baseline
  41. 35 0
      test/TTBasic/deleteArray.js
  42. 4 0
      test/TTBasic/deleteArrayRecord.baseline
  43. 6 0
      test/TTBasic/deleteArrayReplay.baseline
  44. 33 1
      test/TTBasic/es5Array.js
  45. 6 0
      test/TTBasic/es5ArrayRecord.baseline
  46. 6 0
      test/TTBasic/es5ArrayReplay.baseline
  47. 52 0
      test/TTBasic/extensible.js
  48. 11 0
      test/TTBasic/extensibleRecord.baseline
  49. 13 0
      test/TTBasic/extensibleReplay.baseline
  50. 0 9
      test/TTBasic/forEachRecord.baseline
  51. 0 11
      test/TTBasic/forEachReplay.baseline
  52. 81 0
      test/TTBasic/forInShadowing.js
  53. 8 0
      test/TTBasic/forInShadowingRecord.baseline
  54. 10 0
      test/TTBasic/forInShadowingReplay.baseline
  55. 44 0
      test/TTBasic/freeze.js
  56. 9 0
      test/TTBasic/freezeRecord.baseline
  57. 11 0
      test/TTBasic/freezeReplay.baseline
  58. 33 0
      test/TTBasic/largeAuxArray.js
  59. 1 0
      test/TTBasic/largeAuxArrayRecord.baseline
  60. 3 0
      test/TTBasic/largeAuxArrayReplay.baseline
  61. 55 0
      test/TTBasic/missingArray.js
  62. 10 0
      test/TTBasic/missingArrayRecord.baseline
  63. 12 0
      test/TTBasic/missingArrayReplay.baseline
  64. 25 0
      test/TTBasic/newFromArgs.js
  65. 2 0
      test/TTBasic/newFromArgsRecord.baseline
  66. 4 0
      test/TTBasic/newFromArgsReplay.baseline
  67. 23 0
      test/TTBasic/numericPropertyIsEnumerable.js
  68. 6 0
      test/TTBasic/numericPropertyIsEnumerableRecord.baseline
  69. 8 0
      test/TTBasic/numericPropertyIsEnumerableReplay.baseline
  70. 33 0
      test/TTBasic/popArrayImplicitCall.js
  71. 3 0
      test/TTBasic/popArrayImplicitCallRecord.baseline
  72. 5 0
      test/TTBasic/popArrayImplicitCallReplay.baseline
  73. 11 0
      test/TTBasic/regex.js
  74. 6 0
      test/TTBasic/regexRecord.baseline
  75. 6 0
      test/TTBasic/regexReplay.baseline
  76. 261 5
      test/TTBasic/rlexe.xml
  77. 56 0
      test/TTBasic/scopedAccessors.js
  78. 10 0
      test/TTBasic/scopedAccessorsRecord.baseline
  79. 12 0
      test/TTBasic/scopedAccessorsReplay.baseline
  80. 39 0
      test/TTBasic/seal.js
  81. 7 0
      test/TTBasic/sealRecord.baseline
  82. 9 0
      test/TTBasic/sealReplay.baseline
  83. 47 0
      test/TTBasic/shadowPrototype.js
  84. 3 0
      test/TTBasic/shadowPrototypeRecord.baseline
  85. 5 0
      test/TTBasic/shadowPrototypeReplay.baseline
  86. 80 0
      test/TTBasic/sparseArray.js
  87. 17 0
      test/TTBasic/sparseArrayRecord.baseline
  88. 19 0
      test/TTBasic/sparseArrayReplay.baseline
  89. 86 0
      test/TTBasic/typeConversions.js
  90. 9 0
      test/TTBasic/typeConversionsRecord.baseline
  91. 11 0
      test/TTBasic/typeConversionsReplay.baseline
  92. 29 0
      test/TTBasic/typePromotion.js
  93. 4 0
      test/TTBasic/typePromotionRecord.baseline
  94. 6 0
      test/TTBasic/typePromotionReplay.baseline
  95. 133 0
      test/TTExecuteBasic/enumerable.js
  96. 4 0
      test/TTExecuteBasic/enumerableRecord.baseline
  97. 6 0
      test/TTExecuteBasic/enumerableReplay.baseline
  98. 206 0
      test/TTExecuteBasic/enumeratingWithES5.js
  99. 379 0
      test/TTExecuteBasic/enumeratingWithES5Record.baseline
  100. 381 0
      test/TTExecuteBasic/enumeratingWithES5Replay.baseline

+ 8 - 0
lib/Jsrt/Jsrt.cpp

@@ -3986,6 +3986,10 @@ CHAKRA_API JsTTDPreExecuteSnapShotInterval(_In_ int64_t startSnapTime, _In_ int6
     }
     catch(TTD::TTDebuggerAbortException abortException)
     {
+        //
+        //TODO: we need to clear out the exception state if needed otherwise when we try to re-enter execution we will fail
+        //
+
         //If we hit the end of the log or we hit a terminal exception that is fine -- anything else is a problem
         if(!abortException.IsEndOfLog() && !abortException.IsTopLevelException())
         {
@@ -4196,6 +4200,10 @@ CHAKRA_API JsTTDReplayExecution(_Inout_ JsTTDMoveMode* moveMode, _Inout_ int64_t
 
             if(abortException.IsTopLevelException())
             {
+                //
+                //TODO: we need to clear out the exception state if needed otherwise when we try to re-enter execution we will fail
+                //
+
                 bool markedAsJustMyCode = false;
                 TTD::TTDebuggerSourceLocation throwLocation;
                 elog->GetLastExecutedTimeAndPositionForDebugger(&markedAsJustMyCode, throwLocation);

+ 2 - 2
lib/Runtime/Debug/TTEventLog.cpp

@@ -979,7 +979,7 @@ namespace TTD
 #endif
     }
 
-    void EventLog::ReplayPropertyEnumEvent(BOOL* returnCode, int32* newIndex, const Js::DynamicObject* obj, Js::PropertyId* pid, Js::PropertyAttributes* attributes, Js::JavascriptString** propertyName)
+    void EventLog::ReplayPropertyEnumEvent(BOOL* returnCode, Js::BigPropertyIndex* newIndex, const Js::DynamicObject* obj, Js::PropertyId* pid, Js::PropertyAttributes* attributes, Js::JavascriptString** propertyName)
     {
         const NSLogEvents::PropertyEnumStepEventLogEntry* peEvent = this->ReplayGetReplayEvent_Helper<NSLogEvents::PropertyEnumStepEventLogEntry, NSLogEvents::EventKind::PropertyEnumTag>();
 
@@ -996,7 +996,7 @@ namespace TTD
             const Js::PropertyRecord* pRecord = obj->GetScriptContext()->GetPropertyName(*pid);
             *newIndex = obj->GetDynamicType()->GetTypeHandler()->GetPropertyIndex_EnumerateTTD(pRecord);
 
-            AssertMsg(*newIndex != Js::Constants::NoSlot, "If *returnCode is true then we found it during record -- but missing in replay.");
+            AssertMsg(*newIndex != Js::Constants::NoBigSlot, "If *returnCode is true then we found it during record -- but missing in replay.");
         }
         else
         {

+ 1 - 1
lib/Runtime/Debug/TTEventLog.h

@@ -481,7 +481,7 @@ namespace TTD
         void RecordPropertyEnumEvent(BOOL returnCode, Js::PropertyId pid, Js::PropertyAttributes attributes, Js::JavascriptString* propertyName);
 
         //Replay a property enumeration step
-        void ReplayPropertyEnumEvent(BOOL* returnCode, int32* newIndex, const Js::DynamicObject* obj, Js::PropertyId* pid, Js::PropertyAttributes* attributes, Js::JavascriptString** propertyName);
+        void ReplayPropertyEnumEvent(BOOL* returnCode, Js::BigPropertyIndex* newIndex, const Js::DynamicObject* obj, Js::PropertyId* pid, Js::PropertyAttributes* attributes, Js::JavascriptString** propertyName);
 
         //Log symbol creation
         void RecordSymbolCreationEvent(Js::PropertyId pid);

+ 1 - 1
lib/Runtime/Debug/TTEvents.h

@@ -86,7 +86,7 @@ namespace TTD
         int64 m_ltime;  //-1 indicates any ltime is OK
 
         //The document
-        wchar* m_sourceFile; //temp use until we make docid stable
+        char16* m_sourceFile; //temp use until we make docid stable
         uint32 m_docid;
 
         //The position of the function in the document

+ 1 - 3
lib/Runtime/Debug/TTSerialize.cpp

@@ -15,10 +15,8 @@ namespace TTD
             const char16** nameArray = TT_HEAP_ALLOC_ARRAY(const char16*, (uint32)Key::Count);
             size_t* lengthArray = TT_HEAP_ALLOC_ARRAY(size_t, (uint32)Key::Count);
 
-#define __STEXT(X) ((const char16*)__TEXT(X))
-#define ENTRY_SERIALIZE_ENUM(K) { nameArray[(uint32)Key::##K] = __STEXT(#K); lengthArray[(uint32)Key::##K] = wcslen(__STEXT(#K)); }
+#define ENTRY_SERIALIZE_ENUM(K) { nameArray[(uint32)Key::##K] = _u(#K); lengthArray[(uint32)Key::##K] = wcslen(_u(#K)); }
 #include "TTSerializeEnum.h"
-#undef __STEXT
 
             *names = nameArray;
             *lengths = lengthArray;

+ 61 - 42
lib/Runtime/Debug/TTSnapObjects.cpp

@@ -230,62 +230,70 @@ namespace TTD
                 AssertMsg(!Js::JavascriptProxy::Is(obj), "I didn't think proxies could have real properties directly on them.");
 
                 Js::PropertyId pid = handler->PropertyInfoArray[i].PropertyRecordId;
-                TTDVar ttdVal = snpObject->VarArray[i];
-                Js::Var pVal = inflator->InflateTTDVar(ttdVal);
 
-                if(handler->PropertyInfoArray[i].DataKind == NSSnapType::SnapEntryDataKindTag::Data)
+                if(handler->PropertyInfoArray[i].DataKind == NSSnapType::SnapEntryDataKindTag::Uninitialized)
                 {
-                    BOOL success = FALSE;
-                    if(!obj->HasOwnProperty(pid))
-                    {
-                        //easy case just set the property
-                        success = obj->SetProperty(pid, pVal, Js::PropertyOperationFlags::PropertyOperation_Force, nullptr);
-                    }
-                    else
+                    AssertMsg(!obj->HasOwnProperty(pid), "Shouldn't have this defined, or we should have cleared it, and nothing more to do.");
+
+                    BOOL success = obj->EnsureProperty(pid);
+
+                    AssertMsg(success, "Failed to set property during restore!!!");
+                }
+                else
+                {
+                    TTDVar ttdVal = snpObject->VarArray[i];
+                    Js::Var pVal = (ttdVal != nullptr) ? inflator->InflateTTDVar(ttdVal) : nullptr;
+
+                    if(handler->PropertyInfoArray[i].DataKind == NSSnapType::SnapEntryDataKindTag::Data)
                     {
-                        if(obj->IsWritable(pid))
+                        BOOL success = FALSE;
+                        if(!obj->HasOwnProperty(pid))
                         {
-                            //also easy just write the property
+                            //easy case just set the property
                             success = obj->SetProperty(pid, pVal, Js::PropertyOperationFlags::PropertyOperation_Force, nullptr);
                         }
                         else
                         {
-                            //get the value to see if it is alreay ok
-                            Js::Var currentValue = nullptr;
-                            Js::JavascriptOperators::GetProperty(obj, pid, obj->GetScriptContext(), nullptr);
-
-                            if(currentValue == pVal)
+                            if(obj->IsWritable(pid))
                             {
-                                //the right value is already there -- easy
-                                success = TRUE;
+                                //also easy just write the property
+                                success = obj->SetProperty(pid, pVal, Js::PropertyOperationFlags::PropertyOperation_Force, nullptr);
                             }
                             else
                             {
-                                //Ok so now we force set the property
-                                success = obj->SetPropertyWithAttributes(pid, pVal, PropertyDynamicTypeDefaults, nullptr);
+                                //get the value to see if it is alreay ok
+                                Js::Var currentValue = nullptr;
+                                Js::JavascriptOperators::GetProperty(obj, pid, obj->GetScriptContext(), nullptr);
+
+                                if(currentValue == pVal)
+                                {
+                                    //the right value is already there -- easy
+                                    success = TRUE;
+                                }
+                                else
+                                {
+                                    //Ok so now we force set the property
+                                    success = obj->SetPropertyWithAttributes(pid, pVal, PropertyDynamicTypeDefaults, nullptr);
+                                }
                             }
                         }
-                    }
-                    AssertMsg(success, "Failed to set property during restore!!!");
-                }
-                else
-                {
-                    //
-                    //TODO: we could have a problem if we set a getter (and make it not writable say) then what happens with the setter -- or maybe set accessors just ignores this?
-                    //
-
-                    NSSnapType::SnapEntryDataKindTag ttag = handler->PropertyInfoArray[i].DataKind;
-                    if(ttag == NSSnapType::SnapEntryDataKindTag::Getter)
-                    {
-                        obj->SetAccessors(pid, pVal, nullptr);
-                    }
-                    else if(ttag == NSSnapType::SnapEntryDataKindTag::Setter)
-                    {
-                        obj->SetAccessors(pid, nullptr, pVal);
+                        AssertMsg(success, "Failed to set property during restore!!!");
                     }
                     else
                     {
-                        AssertMsg(false, "Don't know how to restore this accesstag!!");
+                        NSSnapType::SnapEntryDataKindTag ttag = handler->PropertyInfoArray[i].DataKind;
+                        if(ttag == NSSnapType::SnapEntryDataKindTag::Getter)
+                        {
+                            obj->SetAccessors(pid, pVal, nullptr);
+                        }
+                        else if(ttag == NSSnapType::SnapEntryDataKindTag::Setter)
+                        {
+                            obj->SetAccessors(pid, nullptr, pVal);
+                        }
+                        else
+                        {
+                            AssertMsg(false, "Don't know how to restore this accesstag!!");
+                        }
                     }
                 }
 
@@ -550,7 +558,7 @@ namespace TTD
                 for(uint32 i = 0; i < handler2->MaxPropertyIndex; ++i)
                 {
                     const NSSnapType::SnapHandlerPropertyEntry spe = handler2->PropertyInfoArray[i];
-                    if(spe.DataKind != NSSnapType::SnapEntryDataKindTag::Clear)
+                    if(spe.DataKind != NSSnapType::SnapEntryDataKindTag::Clear && spe.DataKind != NSSnapType::SnapEntryDataKindTag::Uninitialized)
                     {
                         int64 locationTag = ComputeLocationTagForAssertCompare(spe);
 
@@ -1285,7 +1293,7 @@ namespace TTD
             const double* dateInfo1 = SnapObjectGetAddtlInfoAs<double*, SnapObjectType::SnapDateObject>(sobj1);
             const double* dateInfo2 = SnapObjectGetAddtlInfoAs<double*, SnapObjectType::SnapDateObject>(sobj2);
 
-            compareMap.DiagnosticAssert(*dateInfo1 == *dateInfo2);
+            compareMap.DiagnosticAssert(NSSnapValues::CheckSnapEquivTTDDouble(*dateInfo1, *dateInfo2));
         }
 #endif
 
@@ -1435,6 +1443,9 @@ namespace TTD
 
                 arrayObj->SetItemAttributes(entry->Index, entry->Attributes);
             }
+
+            //do length writable as needed
+            Js::JavascriptLibrary::SetLengthWritableES5Array_TTD(arrayObj, es5Info->IsLengthWritable);
         }
 
         void EmitAddtlInfo_SnapES5ArrayInfo(const SnapObject* snpObject, FileWriter* writer)
@@ -1442,6 +1453,8 @@ namespace TTD
             SnapES5ArrayInfo* es5Info = SnapObjectGetAddtlInfoAs<SnapES5ArrayInfo*, SnapObjectType::SnapES5ArrayObject>(snpObject);
 
             writer->WriteLengthValue(es5Info->GetterSetterCount, NSTokens::Separator::CommaSeparator);
+            writer->WriteBool(NSTokens::Key::boolVal, es5Info->IsLengthWritable, NSTokens::Separator::CommaSeparator);
+
             writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
             for(uint32 i = 0; i < es5Info->GetterSetterCount; ++i)
             {
@@ -1471,6 +1484,8 @@ namespace TTD
             SnapES5ArrayInfo* es5Info = alloc.SlabAllocateStruct<SnapES5ArrayInfo>();
 
             es5Info->GetterSetterCount = reader->ReadLengthValue(true);
+            es5Info->IsLengthWritable = reader->ReadBool(NSTokens::Key::boolVal, true);
+
             if(es5Info->GetterSetterCount == 0)
             {
                 es5Info->GetterSetterEntries = nullptr;
@@ -1512,6 +1527,8 @@ namespace TTD
             SnapES5ArrayInfo* es5Info2 = SnapObjectGetAddtlInfoAs<SnapES5ArrayInfo*, SnapObjectType::SnapES5ArrayObject>(sobj2);
 
             compareMap.DiagnosticAssert(es5Info1->GetterSetterCount == es5Info2->GetterSetterCount);
+            compareMap.DiagnosticAssert(es5Info1->IsLengthWritable == es5Info2->IsLengthWritable);
+
             for(uint32 i = 0; i < es5Info1->GetterSetterCount; ++i)
             {
                 const SnapES5ArrayGetterSetterEntry* entry1 = es5Info1->GetterSetterEntries + i;
@@ -1524,7 +1541,9 @@ namespace TTD
                 NSSnapValues::AssertSnapEquivTTDVar_SpecialArray(entry1->Setter, entry2->Setter, compareMap, _u("es5Setter"), entry1->Index);
             }
 
-            AssertSnapEquiv_SnapArrayInfoCore<TTDVar>(es5Info1->BasicArrayData, es5Info2->BasicArrayData, compareMap);
+            compareMap.DiagnosticAssert(es5Info1->BasicArrayData->Length == es5Info2->BasicArrayData->Length);
+
+            AssertSnapEquiv_SnapArrayInfoCore<TTDVar>(es5Info1->BasicArrayData->Data, es5Info2->BasicArrayData->Data, compareMap);
         }
 #endif
 

+ 63 - 31
lib/Runtime/Debug/TTSnapObjects.h

@@ -490,7 +490,7 @@ namespace TTD
 
         //A struct that represents Javascript arrays and Native arrays (T can be Var, int32, or double)
         template<typename T>
-        struct SnapArrayInfo
+        struct SnapArrayInfoBlock
         {
             //The index ranges that this info holds
             uint32 FirstIndex;
@@ -501,13 +501,24 @@ namespace TTD
             byte* ArrayValidTags; //0 is invalid 1 is valid
 
                                   //The next slice of array elements
-            SnapArrayInfo<T>* Next;
+            SnapArrayInfoBlock<T>* Next;
+        };
+
+        //A struct that represents Javascript arrays and Native arrays (T can be Var, int32, or double)
+        template<typename T>
+        struct SnapArrayInfo
+        {
+            //The index ranges that this info holds
+            uint32 Length;
+
+            //The array elements or null if this is empty
+            SnapArrayInfoBlock<T>* Data;
         };
 
         template<typename T, bool zeroFillValid>
-        SnapArrayInfo<T>* AllocateArrayInfoBlock(SlabAllocator& alloc, uint32 firstIndex, uint32 lastIndex)
+        SnapArrayInfoBlock<T>* AllocateArrayInfoBlock(SlabAllocator& alloc, uint32 firstIndex, uint32 lastIndex)
         {
-            SnapArrayInfo<T>* sai = alloc.SlabAllocateStruct< SnapArrayInfo<T> >();
+            SnapArrayInfoBlock<T>* sai = alloc.SlabAllocateStruct< SnapArrayInfoBlock<T> >();
             sai->FirstIndex = firstIndex;
             sai->LastIndex = lastIndex;
 
@@ -528,7 +539,7 @@ namespace TTD
         template<typename T>
         SnapArrayInfo<T>* ExtractArrayValues(Js::JavascriptArray* arrayObject, SlabAllocator& alloc)
         {
-            SnapArrayInfo<T>* sai = nullptr;
+            SnapArrayInfoBlock<T>* sai = nullptr;
 
             uint32 length = arrayObject->GetLength();
             if(length == 0)
@@ -545,18 +556,20 @@ namespace TTD
             }
             else
             {
-                SnapArrayInfo<T>* curr = nullptr;
+                SnapArrayInfoBlock<T>* curr = nullptr;
                 for(uint32 idx = arrayObject->GetNextIndex(Js::JavascriptArray::InvalidIndex); idx != Js::JavascriptArray::InvalidIndex; idx = arrayObject->GetNextIndex(idx))
                 {
                     if(sai == nullptr)
                     {
-                        sai = AllocateArrayInfoBlock<T, true>(alloc, idx, idx + TTD_ARRAY_BLOCK_SIZE);
+                        uint32 endIdx = (idx <= (Js::JavascriptArray::MaxArrayLength - TTD_ARRAY_BLOCK_SIZE)) ? (idx + TTD_ARRAY_BLOCK_SIZE) : Js::JavascriptArray::MaxArrayLength;
+                        sai = AllocateArrayInfoBlock<T, true>(alloc, idx, endIdx);
                         curr = sai;
                     }
 
                     if(idx >= curr->LastIndex)
                     {
-                        curr->Next = AllocateArrayInfoBlock<T, true>(alloc, idx, idx + TTD_ARRAY_BLOCK_SIZE);
+                        uint32 endIdx = (idx <= (Js::JavascriptArray::MaxArrayLength - TTD_ARRAY_BLOCK_SIZE)) ? (idx + TTD_ARRAY_BLOCK_SIZE) : Js::JavascriptArray::MaxArrayLength;
+                        curr->Next = AllocateArrayInfoBlock<T, true>(alloc, idx, endIdx);
                         curr = curr->Next;
                     }
 
@@ -565,7 +578,11 @@ namespace TTD
                 }
             }
 
-            return sai;
+            SnapArrayInfo<T>* res = alloc.SlabAllocateStruct< SnapArrayInfo<T> >();
+            res->Length = arrayObject->GetLength();
+            res->Data = sai;
+
+            return res;
         }
 
         int32 SnapArrayInfo_InflateValue(int32 value, InflateMap* inflator);
@@ -596,13 +613,14 @@ namespace TTD
             //We can re-evaluate this choice later if needed and add checks for same type-ness.
 
             const SnapArrayInfo<T>* arrayInfo = SnapObjectGetAddtlInfoAs<SnapArrayInfo<T>*, snapArrayKind>(snpObject);
+            const SnapArrayInfoBlock<T>* dataBlock = arrayInfo->Data;
             Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
 
             Js::JavascriptLibrary* jslib = ctx->GetLibrary();
             uint32 preAllocSpace = 0;
-            if(arrayInfo != nullptr && arrayInfo->Next == nullptr && arrayInfo->FirstIndex == 0 && arrayInfo->LastIndex <= TTD_ARRAY_SMALL_ARRAY)
+            if(dataBlock != nullptr && dataBlock->Next == nullptr && dataBlock->FirstIndex == 0 && dataBlock->LastIndex <= TTD_ARRAY_SMALL_ARRAY)
             {
-                preAllocSpace = arrayInfo->LastIndex; //first index is 0
+                preAllocSpace = dataBlock->LastIndex; //first index is 0
             }
 
             if(snpObject->SnapType->JsTypeId == Js::TypeIds_Array)
@@ -627,20 +645,25 @@ namespace TTD
         template<typename T, typename U>
         void DoAddtlValueInstantiation_SnapArrayInfoCore(SnapArrayInfo<T>* arrayInfo, Js::JavascriptArray* arrayObj, InflateMap* inflator)
         {
-            while(arrayInfo != nullptr)
+            const SnapArrayInfoBlock<T>* dataBlock = arrayInfo->Data;
+
+            while(dataBlock != nullptr)
             {
-                for(uint32 i = 0; i < (arrayInfo->LastIndex - arrayInfo->FirstIndex); ++i)
+                for(uint32 i = 0; i < (dataBlock->LastIndex - dataBlock->FirstIndex); ++i)
                 {
-                    if(arrayInfo->ArrayValidTags[i])
+                    if(dataBlock->ArrayValidTags[i])
                     {
-                        T ttdVal = arrayInfo->ArrayRangeContents[i];
+                        T ttdVal = dataBlock->ArrayRangeContents[i];
                         U jsVal = SnapArrayInfo_InflateValue(ttdVal, inflator);
 
-                        arrayObj->DirectSetItemAt<U>(i + arrayInfo->FirstIndex, jsVal);
+                        arrayObj->DirectSetItemAt<U>(i + dataBlock->FirstIndex, jsVal);
                     }
                 }
-                arrayInfo = arrayInfo->Next;
+                dataBlock = dataBlock->Next;
             }
+
+            //Ensure this value is set correctly in case of sparse arrays
+            arrayObj->SetLength(arrayInfo->Length);
         }
 
         template<typename T, typename U, SnapObjectType snapArrayKind>
@@ -655,8 +678,10 @@ namespace TTD
         template<typename T>
         void EmitAddtlInfo_SnapArrayInfoCore(SnapArrayInfo<T>* arrayInfo, FileWriter* writer)
         {
+            writer->WriteLengthValue(arrayInfo->Length, NSTokens::Separator::CommaSeparator);
+
             uint32 blockCount = 0;
-            for(SnapArrayInfo<T>* currInfo = arrayInfo; currInfo != nullptr; currInfo = currInfo->Next)
+            for(SnapArrayInfoBlock<T>* currInfo = arrayInfo->Data; currInfo != nullptr; currInfo = currInfo->Next)
             {
                 blockCount++;
             }
@@ -664,9 +689,9 @@ namespace TTD
             writer->WriteLengthValue(blockCount, NSTokens::Separator::CommaAndBigSpaceSeparator);
             writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
             writer->AdjustIndent(1);
-            for(SnapArrayInfo<T>* currInfo = arrayInfo; currInfo != nullptr; currInfo = currInfo->Next)
+            for(SnapArrayInfoBlock<T>* currInfo = arrayInfo->Data; currInfo != nullptr; currInfo = currInfo->Next)
             {
-                writer->WriteRecordStart(currInfo == arrayInfo ? NSTokens::Separator::BigSpaceSeparator : NSTokens::Separator::CommaAndBigSpaceSeparator);
+                writer->WriteRecordStart(currInfo == arrayInfo->Data ? NSTokens::Separator::BigSpaceSeparator : NSTokens::Separator::CommaAndBigSpaceSeparator);
                 writer->WriteUInt32(NSTokens::Key::index, currInfo->FirstIndex);
                 writer->WriteUInt32(NSTokens::Key::offset, currInfo->LastIndex, NSTokens::Separator::CommaSeparator);
 
@@ -701,8 +726,10 @@ namespace TTD
         template<typename T>
         SnapArrayInfo<T>* ParseAddtlInfo_SnapArrayInfoCore(FileReader* reader, SlabAllocator& alloc)
         {
-            SnapArrayInfo<T>* arrayInfo = nullptr;
-            SnapArrayInfo<T>* curr = nullptr;
+            uint32 alength = reader->ReadLengthValue(true);
+
+            SnapArrayInfoBlock<T>* arrayInfo = nullptr;
+            SnapArrayInfoBlock<T>* curr = nullptr;
 
             uint32 blockCount = reader->ReadLengthValue(true);
             reader->ReadSequenceStart_WDefaultKey(true);
@@ -710,7 +737,7 @@ namespace TTD
             {
                 reader->ReadRecordStart(k != 0);
 
-                SnapArrayInfo<T>* tmp = alloc.SlabAllocateStruct<SnapArrayInfo<T>>();
+                SnapArrayInfoBlock<T>* tmp = alloc.SlabAllocateStruct< SnapArrayInfoBlock<T> >();
                 tmp->FirstIndex = reader->ReadUInt32(NSTokens::Key::index);
                 tmp->LastIndex = reader->ReadUInt32(NSTokens::Key::offset, true);
 
@@ -747,7 +774,11 @@ namespace TTD
             }
             reader->ReadSequenceEnd();
 
-            return arrayInfo;
+            SnapArrayInfo<T>* res = alloc.SlabAllocateStruct< SnapArrayInfo<T> >();
+            res->Length = alength;
+            res->Data = arrayInfo;
+
+            return res;
         }
 
         template<typename T, SnapObjectType snapArrayKind>
@@ -760,7 +791,7 @@ namespace TTD
 
 #if ENABLE_SNAPSHOT_COMPARE
         template<typename T>
-        void AdvanceArrayIndex_SnapArrayInfoCompare(uint32* index, uint32* pos, const SnapArrayInfo<T>** segment)
+        void AdvanceArrayIndex_SnapArrayInfoCompare(uint32* index, uint32* pos, const SnapArrayInfoBlock<T>** segment)
         {
             *index = *index + 1;
             if(*index >= (*segment)->LastIndex)
@@ -782,7 +813,7 @@ namespace TTD
         }
 
         template<typename T>
-        void AssertSnapEquiv_SnapArrayInfoCore(const SnapArrayInfo<T>* arrayInfo1, const SnapArrayInfo<T>* arrayInfo2, TTDCompareMap& compareMap)
+        void AssertSnapEquiv_SnapArrayInfoCore(const SnapArrayInfoBlock<T>* arrayInfo1, const SnapArrayInfoBlock<T>* arrayInfo2, TTDCompareMap& compareMap)
         {
             uint32 index1 = (arrayInfo1 != nullptr) ? arrayInfo1->FirstIndex : 0;
             uint32 pos1 = 0;
@@ -835,7 +866,9 @@ namespace TTD
             const SnapArrayInfo<T>* arrayInfo1 = SnapObjectGetAddtlInfoAs<SnapArrayInfo<T>*, snapArrayKind>(sobj1);
             const SnapArrayInfo<T>* arrayInfo2 = SnapObjectGetAddtlInfoAs<SnapArrayInfo<T>*, snapArrayKind>(sobj2);
 
-            AssertSnapEquiv_SnapArrayInfoCore<T>(arrayInfo1, arrayInfo2, compareMap);
+            compareMap.DiagnosticAssert(arrayInfo1->Length == arrayInfo2->Length);
+
+            AssertSnapEquiv_SnapArrayInfoCore<T>(arrayInfo1->Data, arrayInfo2->Data, compareMap);
         }
 #endif
 
@@ -854,16 +887,15 @@ namespace TTD
         //A struct that represents Javascript ES5 arrays
         struct SnapES5ArrayInfo
         {
-            //
-            //TODO: lengthWritable and dataItemAttributes should get reset based on the overall object sealed/frozen settings but we should check this carefully
-            //
-
             //Values copied from the ES5ArrayTypeHandler indexed data map
             uint32 GetterSetterCount;
             SnapES5ArrayGetterSetterEntry* GetterSetterEntries;
 
             //Values that are copied from the underlying data array
             SnapArrayInfo<TTDVar>* BasicArrayData;
+
+            //True if the length is writable
+            bool IsLengthWritable;
         };
 
         Js::RecyclableObject* DoObjectInflation_SnapES5ArrayInfo(const SnapObject* snpObject, InflateMap* inflator);

+ 1 - 0
lib/Runtime/Debug/TTSnapTypes.cpp

@@ -221,6 +221,7 @@ namespace TTD
                 uint32 h1Idx = h1Dict.LookupWithKey(locationTag, 0);
                 uint32 h2Idx = h2Dict.LookupWithKey(locationTag, 0);
                 compareMap.DiagnosticAssert(h1->PropertyInfoArray[h1Idx].AttributeInfo == h2->PropertyInfoArray[h2Idx].AttributeInfo);
+                compareMap.DiagnosticAssert(h1->PropertyInfoArray[h1Idx].DataKind == h2->PropertyInfoArray[h2Idx].DataKind);
             }
         }
 #endif

+ 1 - 0
lib/Runtime/Debug/TTSnapTypes.h

@@ -52,6 +52,7 @@ namespace TTD
         enum class SnapEntryDataKindTag : uint8
         {
             Clear = 0x0,
+            Uninitialized,
             Data,   //the value in the location is a data entry
             Getter, //the value in the location is a getter function entry
             Setter  //the value in the location is a setter function entry

+ 13 - 8
lib/Runtime/Debug/TTSnapValues.cpp

@@ -231,6 +231,18 @@ namespace TTD
         }
 
 #if ENABLE_SNAPSHOT_COMPARE
+        bool CheckSnapEquivTTDDouble(double d1, double d2)
+        {
+            if(Js::JavascriptNumber::IsNan(d1) || Js::JavascriptNumber::IsNan(d2))
+            {
+                return (Js::JavascriptNumber::IsNan(d1) && Js::JavascriptNumber::IsNan(d2));
+            }
+            else
+            {
+                return (d1 == d2);
+            }
+        }
+
         void AssertSnapEquivTTDVar_Helper(const TTDVar v1, const TTDVar v2, TTDCompareMap& compareMap, TTDComparePath::StepKind stepKind, const TTDComparePath::PathEntry& next)
         {
             if(v1 == nullptr || v2 == nullptr)
@@ -250,14 +262,7 @@ namespace TTD
                 }
                 else
                 {
-                    if(Js::JavascriptNumber::IsNan(Js::JavascriptNumber::GetValue(v1)) || Js::JavascriptNumber::IsNan(Js::JavascriptNumber::GetValue(v2)))
-                    {
-                        compareMap.DiagnosticAssert(Js::JavascriptNumber::IsNan(Js::JavascriptNumber::GetValue(v1)) && Js::JavascriptNumber::IsNan(Js::JavascriptNumber::GetValue(v2)));
-                    }
-                    else
-                    {
-                        compareMap.DiagnosticAssert(Js::JavascriptNumber::GetValue(v1) == Js::JavascriptNumber::GetValue(v2));
-                    }
+                    compareMap.DiagnosticAssert(CheckSnapEquivTTDDouble(Js::JavascriptNumber::GetValue(v1), Js::JavascriptNumber::GetValue(v2)));
                 }
 #endif
             }

+ 1 - 0
lib/Runtime/Debug/TTSnapValues.h

@@ -77,6 +77,7 @@ namespace TTD
         TTDVar ParseTTDVar(bool readSeperator, FileReader* reader);
 
 #if ENABLE_SNAPSHOT_COMPARE 
+        bool CheckSnapEquivTTDDouble(double d1, double d2);
         void AssertSnapEquivTTDVar_Helper(const TTDVar v1, const TTDVar v2, TTDCompareMap& compareMap, TTDComparePath::StepKind stepKind, const TTDComparePath::PathEntry& next);
 
         void AssertSnapEquivTTDVar_Property(const TTDVar v1, const TTDVar v2, TTDCompareMap& compareMap, Js::PropertyId pid);

+ 1 - 0
lib/Runtime/Library/ES5Array.cpp

@@ -405,6 +405,7 @@ namespace Js
 
         uint32 length = this->GetLength();
 
+        es5ArrayInfo->IsLengthWritable = this->IsLengthWritable();
         es5ArrayInfo->GetterSetterCount = 0;
         es5ArrayInfo->GetterSetterEntries = alloc.SlabReserveArraySpace<TTD::NSSnapObjects::SnapES5ArrayGetterSetterEntry>(length + 1); //ensure we don't do a 0 reserve
 

+ 10 - 1
lib/Runtime/Library/JavascriptLibrary.cpp

@@ -4834,6 +4834,15 @@ namespace Js
         return arrayObj;
     }
 
+    void JavascriptLibrary::SetLengthWritableES5Array_TTD(Js::RecyclableObject* es5Array, bool isLengthWritable)
+    {
+        Js::ES5Array* es5a = Js::ES5Array::FromVar(es5Array);
+        if(es5a->IsLengthWritable() != isLengthWritable)
+        {
+            es5a->SetWritable(Js::PropertyIds::length, isLengthWritable ? TRUE : FALSE);
+        }
+    }
+
     Js::RecyclableObject* JavascriptLibrary::CreateSet_TTD()
     {
         return JavascriptSet::CreateForSnapshotRestore(this->scriptContext);
@@ -4903,7 +4912,7 @@ namespace Js
 
     Js::RecyclableObject* JavascriptLibrary::CreateRevokeFunction_TTD(RecyclableObject* proxy)
     {
-        RuntimeFunction* revoker = RecyclerNewEnumClass(this->scriptContext->GetRecycler(), this->EnumFunctionClass, RuntimeFunction, this->CreateFunctionWithLengthAndPrototypeType(&JavascriptProxy::EntryInfo::Revoke), &JavascriptProxy::EntryInfo::Revoke);
+        RuntimeFunction* revoker = RecyclerNewEnumClass(this->scriptContext->GetRecycler(), this->EnumFunctionClass, RuntimeFunction, this->CreateFunctionWithLengthType(&JavascriptProxy::EntryInfo::Revoke), &JavascriptProxy::EntryInfo::Revoke);
 
         revoker->SetPropertyWithAttributes(Js::PropertyIds::length, Js::TaggedInt::ToVarUnchecked(0), PropertyNone, NULL);
         revoker->SetInternalProperty(Js::InternalPropertyIds::RevocableProxy, proxy, PropertyOperationFlags::PropertyOperation_Force, nullptr);

+ 1 - 0
lib/Runtime/Library/JavascriptLibrary.h

@@ -648,6 +648,7 @@ namespace Js
         Js::RecyclableObject* CreateError_TTD();
 
         Js::RecyclableObject* CreateES5Array_TTD();
+        static void SetLengthWritableES5Array_TTD(Js::RecyclableObject* es5Array, bool isLengthWritable);
 
         Js::RecyclableObject* CreateSet_TTD();
         Js::RecyclableObject* CreateWeakSet_TTD();

+ 18 - 21
lib/Runtime/Types/DictionaryTypeHandler.cpp

@@ -2667,7 +2667,7 @@ namespace Js
                 continue;
             }
 
-            uint32 dIndex = descriptor.template GetDataPropertyIndex<false>();
+            T dIndex = descriptor.template GetDataPropertyIndex<false>();
             if(dIndex != NoSlots)
             {
                 Js::Var dValue = obj->GetSlot(dIndex);
@@ -2675,14 +2675,14 @@ namespace Js
             }
             else
             {
-                uint32 gIndex = descriptor.GetGetterPropertyIndex();
+                T gIndex = descriptor.GetGetterPropertyIndex();
                 if(gIndex != NoSlots)
                 {
                     Js::Var gValue = obj->GetSlot(gIndex);
                     extractor->MarkVisitVar(gValue);
                 }
 
-                uint32 sIndex = descriptor.GetSetterPropertyIndex();
+                T sIndex = descriptor.GetSetterPropertyIndex();
                 if(sIndex != NoSlots)
                 {
                     Js::Var sValue = obj->GetSlot(sIndex);
@@ -2695,38 +2695,40 @@ namespace Js
     template <typename T>
     uint32 DictionaryTypeHandlerBase<T>::ExtractSlotInfo_TTD(TTD::NSSnapType::SnapHandlerPropertyEntry* entryInfo, ThreadContext* threadContext, TTD::SlabAllocator& alloc) const
     {
-        uint32 maxSlot = 0;
+        T maxSlot = 0;
 
         for(auto iter = this->propertyMap->GetIterator(); iter.IsValid(); iter.MoveNext())
         {
             DictionaryPropertyDescriptor<T> descriptor = iter.CurrentValue();
             Js::PropertyId pid = iter.CurrentKey()->GetPropertyId();
 
-            uint32 dIndex = descriptor.template GetDataPropertyIndex<false>();
+            T dIndex = descriptor.template GetDataPropertyIndex<false>();
             if(dIndex != NoSlots)
             {
                 maxSlot = max(maxSlot, dIndex);
 
-                TTD::NSSnapType::SnapEntryDataKindTag tag = descriptor.IsInitialized ? TTD::NSSnapType::SnapEntryDataKindTag::Data : TTD::NSSnapType::SnapEntryDataKindTag::Clear;
+                TTD::NSSnapType::SnapEntryDataKindTag tag = descriptor.IsInitialized ? TTD::NSSnapType::SnapEntryDataKindTag::Data : TTD::NSSnapType::SnapEntryDataKindTag::Uninitialized;
                 TTD::NSSnapType::ExtractSnapPropertyEntryInfo(entryInfo + dIndex, pid, descriptor.Attributes, tag);
             }
             else
             {
-                uint32 gIndex = descriptor.GetGetterPropertyIndex();
+                AssertMsg(descriptor.IsInitialized, "How can this not be initialized?");
+
+                T gIndex = descriptor.GetGetterPropertyIndex();
                 if(gIndex != NoSlots)
                 {
                     maxSlot = max(maxSlot, gIndex);
 
-                    TTD::NSSnapType::SnapEntryDataKindTag tag = descriptor.IsInitialized ? TTD::NSSnapType::SnapEntryDataKindTag::Getter : TTD::NSSnapType::SnapEntryDataKindTag::Clear;
+                    TTD::NSSnapType::SnapEntryDataKindTag tag = TTD::NSSnapType::SnapEntryDataKindTag::Getter;
                     TTD::NSSnapType::ExtractSnapPropertyEntryInfo(entryInfo + gIndex, pid, descriptor.Attributes, tag);
                 }
 
-                uint32 sIndex = descriptor.GetSetterPropertyIndex();
+                T sIndex = descriptor.GetSetterPropertyIndex();
                 if(sIndex != NoSlots)
                 {
                     maxSlot = max(maxSlot, sIndex);
 
-                    TTD::NSSnapType::SnapEntryDataKindTag tag = descriptor.IsInitialized ? TTD::NSSnapType::SnapEntryDataKindTag::Setter : TTD::NSSnapType::SnapEntryDataKindTag::Clear;
+                    TTD::NSSnapType::SnapEntryDataKindTag tag = TTD::NSSnapType::SnapEntryDataKindTag::Setter;
                     TTD::NSSnapType::ExtractSnapPropertyEntryInfo(entryInfo + sIndex, pid, descriptor.Attributes, tag);
                 }
             }
@@ -2738,31 +2740,26 @@ namespace Js
         }
         else
         {
-            return maxSlot + 1;
+            return (uint32)(maxSlot + 1);
         }
     }
 
     template <typename T>
-    Js::PropertyIndex DictionaryTypeHandlerBase<T>::GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord)
+    Js::BigPropertyIndex DictionaryTypeHandlerBase<T>::GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord)
     {
-        T index = NoSlots;
-        for(index = 0; index < this->propertyMap->Count(); index++)
+        for(Js::BigPropertyIndex index = 0; index < this->propertyMap->Count(); index++)
         {
             Js::PropertyId pid = this->propertyMap->GetKeyAt(index)->GetPropertyId();
             const DictionaryPropertyDescriptor<T>& idescriptor = propertyMap->GetValueAt(index);
 
             if(pid == pRecord->GetPropertyId() && !(idescriptor.Attributes & PropertyDeleted))
             {
-                break;
+                return index;
             }
         }
-        AssertMsg(index != NoSlots, "We found this and not accessor but noslots for index?");
 
-        if(index <= Constants::PropertyIndexMax)
-        {
-            return (PropertyIndex)index;
-        }
-        return Constants::NoSlot;
+        AssertMsg(false, "We found this and not accessor but noslots for index?");
+        return Js::Constants::NoBigSlot;
     }
 #endif
 

+ 1 - 1
lib/Runtime/Types/DictionaryTypeHandler.h

@@ -249,7 +249,7 @@ namespace Js
 
         virtual uint32 ExtractSlotInfo_TTD(TTD::NSSnapType::SnapHandlerPropertyEntry* entryInfo, ThreadContext* threadContext, TTD::SlabAllocator& alloc) const override;
 
-        virtual Js::PropertyIndex GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord) override;
+        virtual Js::BigPropertyIndex GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord) override;
 #endif
     };
 

+ 1 - 3
lib/Runtime/Types/DynamicObject.cpp

@@ -386,10 +386,8 @@ namespace Js
         if(this->GetScriptContext()->ShouldPerformDebugAction())
         {
             BOOL res = FALSE;
-            int32 pIndex = -1;
             PropertyAttributes tmpAttributes = PropertyNone;
-            this->GetScriptContext()->GetThreadContext()->TTDLog->ReplayPropertyEnumEvent(&res, &pIndex, this, propertyId, &tmpAttributes, propertyString);
-            index = (Js::BigPropertyIndex)pIndex;
+            this->GetScriptContext()->GetThreadContext()->TTDLog->ReplayPropertyEnumEvent(&res, &index, this, propertyId, &tmpAttributes, propertyString);
 
             if(attributes != nullptr)
             {

+ 2 - 2
lib/Runtime/Types/PathTypeHandler.cpp

@@ -1933,10 +1933,10 @@ namespace Js
         return plength;
     }
 
-    Js::PropertyIndex PathTypeHandlerBase::GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord)
+    Js::BigPropertyIndex PathTypeHandlerBase::GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord)
     {
         //The regular LookupInline is fine for path types
-        return this->typePath->LookupInline(pRecord->GetPropertyId(), GetPathLength());
+        return (Js::BigPropertyIndex)this->typePath->LookupInline(pRecord->GetPropertyId(), GetPathLength());
     }
 #endif
 

+ 1 - 1
lib/Runtime/Types/PathTypeHandler.h

@@ -209,7 +209,7 @@ namespace Js
 
         virtual uint32 ExtractSlotInfo_TTD(TTD::NSSnapType::SnapHandlerPropertyEntry* entryInfo, ThreadContext* threadContext, TTD::SlabAllocator& alloc) const override;
 
-        virtual Js::PropertyIndex GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord) override;
+        virtual Js::BigPropertyIndex GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord) override;
 #endif
     };
 

+ 7 - 5
lib/Runtime/Types/SimpleDictionaryTypeHandler.cpp

@@ -3192,9 +3192,10 @@ namespace Js
 
             TMapKey key = iter.CurrentKey();
             const PropertyRecord* pRecord = TMapKey_ConvertKey_TTD<const Js::PropertyRecord*>(threadContext, key);
-            TTD::NSSnapType::SnapEntryDataKindTag tag = descriptor.isInitialized ? TTD::NSSnapType::SnapEntryDataKindTag::Data : TTD::NSSnapType::SnapEntryDataKindTag::Clear;
+            PropertyId pid = pRecord->GetPropertyId();
+            TTD::NSSnapType::SnapEntryDataKindTag tag = descriptor.isInitialized ? TTD::NSSnapType::SnapEntryDataKindTag::Data : TTD::NSSnapType::SnapEntryDataKindTag::Uninitialized;
 
-            TTD::NSSnapType::ExtractSnapPropertyEntryInfo(entryInfo + index, pRecord->GetPropertyId(), descriptor.Attributes, tag);
+            TTD::NSSnapType::ExtractSnapPropertyEntryInfo(entryInfo + index, pid, descriptor.Attributes, tag);
         }
 
         if(this->propertyMap->Count() == 0)
@@ -3208,17 +3209,18 @@ namespace Js
     }
 
     template <typename TPropertyIndex, typename TMapKey, bool IsNotExtensibleSupported>
-    Js::PropertyIndex SimpleDictionaryTypeHandlerBase<TPropertyIndex, TMapKey, IsNotExtensibleSupported>::GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord)
+    Js::BigPropertyIndex SimpleDictionaryTypeHandlerBase<TPropertyIndex, TMapKey, IsNotExtensibleSupported>::GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord)
     {
         SimpleDictionaryPropertyDescriptor<TPropertyIndex>* descriptor;
         if(propertyMap->TryGetReference(pRecord, &descriptor))
         {
             AssertMsg(!(descriptor->Attributes & PropertyDeleted), "We found this during enum so what is going on here?");
 
-            return DisallowBigPropertyIndex(descriptor->propertyIndex);
+            return (Js::BigPropertyIndex)descriptor->propertyIndex;
         }
 
-        return Constants::NoSlot;
+        AssertMsg(false, "We found this during enum so what is going on here?");
+        return Js::Constants::NoBigSlot;
     }
 #endif
 

+ 1 - 1
lib/Runtime/Types/SimpleDictionaryTypeHandler.h

@@ -305,7 +305,7 @@ namespace Js
 
         virtual uint32 ExtractSlotInfo_TTD(TTD::NSSnapType::SnapHandlerPropertyEntry* entryInfo, ThreadContext* threadContext, TTD::SlabAllocator& alloc) const override;
 
-        virtual Js::PropertyIndex GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord) override;
+        virtual Js::BigPropertyIndex GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord) override;
 #endif
     };
 

+ 4 - 3
lib/Runtime/Types/SimpleTypeHandler.cpp

@@ -1114,17 +1114,18 @@ namespace Js
     }
 
     template<size_t size>
-    Js::PropertyIndex SimpleTypeHandler<size>::GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord)
+    Js::BigPropertyIndex SimpleTypeHandler<size>::GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord)
     {
         int index;
         if(this->GetDescriptor(pRecord->GetPropertyId(), &index))
         {
             AssertMsg(!(this->descriptors[index].Attributes & PropertyDeleted), "How is this deleted but we enumerated it anyway???");
 
-            return (PropertyIndex)index;
+            return (Js::BigPropertyIndex)index;
         }
 
-        return Constants::NoSlot;
+        AssertMsg(false, "We found this during enum so what is going on here?");
+        return Js::Constants::NoBigSlot;
     }
 
 #endif

+ 1 - 1
lib/Runtime/Types/SimpleTypeHandler.h

@@ -101,7 +101,7 @@ namespace Js
 
         virtual uint32 ExtractSlotInfo_TTD(TTD::NSSnapType::SnapHandlerPropertyEntry* entryInfo, ThreadContext* threadContext, TTD::SlabAllocator& alloc) const override;
 
-        virtual Js::PropertyIndex GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord) override;
+        virtual Js::BigPropertyIndex GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord) override;
 #endif
     };
 

+ 4 - 2
lib/Runtime/Types/TypeHandler.cpp

@@ -700,9 +700,11 @@ namespace Js
     }
 
 #if ENABLE_TTD
-    Js::PropertyIndex DynamicTypeHandler::GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord)
+    Js::BigPropertyIndex DynamicTypeHandler::GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord)
     {
-        return Constants::NoSlot;
+        AssertMsg(false, "Should never be called.");
+
+        return Js::Constants::NoBigSlot;
     }
 
     void DynamicTypeHandler::ExtractSnapHandler(TTD::NSSnapType::SnapHandler* handler, ThreadContext* threadContext, TTD::SlabAllocator& alloc) const

+ 1 - 1
lib/Runtime/Types/TypeHandler.h

@@ -612,7 +612,7 @@ namespace Js
          virtual uint32 ExtractSlotInfo_TTD(TTD::NSSnapType::SnapHandlerPropertyEntry* entryInfo, ThreadContext* threadContext, TTD::SlabAllocator& alloc) const = 0;
 
          //Use to lookup the slotid for a propertyid 
-         virtual Js::PropertyIndex GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord);
+         virtual Js::BigPropertyIndex GetPropertyIndex_EnumerateTTD(const Js::PropertyRecord* pRecord);
 
          //Extract the snap handler info
          void ExtractSnapHandler(TTD::NSSnapType::SnapHandler* handler, ThreadContext* threadContext, TTD::SlabAllocator& alloc) const;

+ 29 - 0
test/TTBasic/accessor.js

@@ -14,6 +14,19 @@ Object.defineProperty(x, "onlyone", {
     get: function () { return this.bar; }
 });
 
+var y = {};
+Object.defineProperty(y, "pdata", { value : 24 });
+Object.defineProperty(y, "pwrite", {value : 12, writable: true});
+Object.defineProperty(y, "pdel", {get : function() {return "pdel";}, configurable: true});
+Object.defineProperty(y, "pconfig", {get : function() {return "pconfig";}, configurable: true});
+Object.defineProperty(y, "penum", {get : function() {return "penum";}, enumerable: true});
+
+var oWritable = {};
+Object.defineProperty(oWritable, "p", { writable: true });
+
+var oNotWritable = {};
+Object.defineProperty(oNotWritable, "p", { writable: false });
+
 WScript.SetTimeout(testFunction, 50);
 
 /////////////////
@@ -33,4 +46,20 @@ function testFunction()
 
     telemetryLog(`x.foo: ${x.foo}`, true); //6
     telemetryLog(`x.b: ${x.b}`, true); //7
+
+    telemetryLog(`Object.getOwnPropertyDescriptor(y.pdata): ${JSON.stringify(Object.getOwnPropertyDescriptor(y, "pdata"))}`, true); //asdf
+    telemetryLog(`Object.getOwnPropertyDescriptor(y.pwrite): ${JSON.stringify(Object.getOwnPropertyDescriptor(y, "pwrite"))}`, true); //asdf
+    telemetryLog(`Object.getOwnPropertyDescriptor(y.pdel): ${JSON.stringify(Object.getOwnPropertyDescriptor(y, "pdel"))}`, true); //asdf
+    telemetryLog(`Object.getOwnPropertyDescriptor(y.pconfig): ${JSON.stringify(Object.getOwnPropertyDescriptor(y, "pconfig"))}`, true); //asdf
+    telemetryLog(`Object.getOwnPropertyDescriptor(y.penum): ${JSON.stringify(Object.getOwnPropertyDescriptor(y, "penum"))}`, true); //asdf
+
+    telemetryLog(`y.pdel: ${y.pdel}`, true); //pdel
+    delete y.pdel; //no exception here
+    telemetryLog(`y.pdel: ${y.pdel}`, true); //undef
+    telemetryLog(`Object.getOwnPropertyDescriptor(y.pdel): ${JSON.stringify(Object.getOwnPropertyDescriptor(y, "pdel"))}`, true); //asdf
+
+    oWritable.p = 10;
+    oNotWritable.p = 10;
+    telemetryLog(`oWritable.p: ${oWritable.p}`, true); //10
+    telemetryLog(`oNotWritable.p: ${oNotWritable.p}`, true); //undef
 }

+ 10 - 0
test/TTBasic/accessorRecord.baseline

@@ -4,3 +4,13 @@ x.b: 4
 x.onlyone: null
 x.foo: 6
 x.b: 7
+Object.getOwnPropertyDescriptor(y.pdata): {"value":24,"writable":false,"enumerable":false,"configurable":false}
+Object.getOwnPropertyDescriptor(y.pwrite): {"value":12,"writable":true,"enumerable":false,"configurable":false}
+Object.getOwnPropertyDescriptor(y.pdel): {"enumerable":false,"configurable":true}
+Object.getOwnPropertyDescriptor(y.pconfig): {"enumerable":false,"configurable":true}
+Object.getOwnPropertyDescriptor(y.penum): {"enumerable":true,"configurable":false}
+y.pdel: pdel
+y.pdel: undefined
+Object.getOwnPropertyDescriptor(y.pdel): undefined
+oWritable.p: 10
+oNotWritable.p: undefined

+ 10 - 0
test/TTBasic/accessorReplay.baseline

@@ -4,5 +4,15 @@ x.b: 4
 x.onlyone: null
 x.foo: 6
 x.b: 7
+Object.getOwnPropertyDescriptor(y.pdata): {"value":24,"writable":false,"enumerable":false,"configurable":false}
+Object.getOwnPropertyDescriptor(y.pwrite): {"value":12,"writable":true,"enumerable":false,"configurable":false}
+Object.getOwnPropertyDescriptor(y.pdel): {"enumerable":false,"configurable":true}
+Object.getOwnPropertyDescriptor(y.pconfig): {"enumerable":false,"configurable":true}
+Object.getOwnPropertyDescriptor(y.penum): {"enumerable":true,"configurable":false}
+y.pdel: pdel
+y.pdel: undefined
+Object.getOwnPropertyDescriptor(y.pdel): undefined
+oWritable.p: 10
+oNotWritable.p: undefined
 
 Reached end of Execution -- Exiting.

+ 33 - 0
test/TTBasic/array.js

@@ -7,6 +7,25 @@ var x = [3, null, {}];
 var y = x;
 y.baz = 5;
 
+var q = [1, 2];
+q.length = 5;
+
+var qq = [1, 2, 3, 4, 5];
+qq.pop();
+qq.pop();
+
+var qqq = [1, 2, 3, 4, 5];
+delete qqq[3];
+
+var o = new Object();
+o.length = 10;
+
+var o1 = new Object();
+var a = [1000,2000,3000];
+
+a.x = 40;
+a[o] = 50;
+
 WScript.SetTimeout(testFunction, 50);
 
 /////////////////
@@ -32,4 +51,18 @@ function testFunction()
     telemetryLog(`post update -- x[5] !== null: ${x[5] !== null}`, true); //true
     telemetryLog(`post update -- x[5].bar: ${x[5].bar}`, true); //3
     telemetryLog(`post update -- y[6]: ${y[6]}`, true); //10
+
+    telemetryLog(`q.length: ${q.length}`, true); //5
+    telemetryLog(`q[3]: ${q[3]}`, true); //undefined
+
+    telemetryLog(`qq.length: ${qq.length}`, true); //3
+    telemetryLog(`qq[3]: ${qq[3]}`, true); //undefined
+
+    telemetryLog(`qqq.length: ${qqq.length}`, true); //5
+    telemetryLog(`qqq[3]: ${qq[undefined]}`, true); //undefined
+
+    telemetryLog(`a[o]: ${a[o]}`, true); //50
+    telemetryLog(`a[o1]: ${a[o1]}`, true); //50
+    telemetryLog(`a["[object Object]"]: ${a["[object Object]"]}`, true); //50
+    telemetryLog(`a["[object" + " Object]"]: ${a["[object" + " Object]"]}`, true); //50
 }

+ 10 - 0
test/TTBasic/arrayRecord.baseline

@@ -9,3 +9,13 @@ post update -- y[1]: non-null
 post update -- x[5] !== null: true
 post update -- x[5].bar: 3
 post update -- y[6]: 10
+q.length: 5
+q[3]: undefined
+qq.length: 3
+qq[3]: undefined
+qqq.length: 5
+qqq[3]: undefined
+a[o]: 50
+a[o1]: 50
+a["[object Object]"]: 50
+a["[object" + " Object]"]: 50

+ 10 - 0
test/TTBasic/arrayReplay.baseline

@@ -9,5 +9,15 @@ post update -- y[1]: non-null
 post update -- x[5] !== null: true
 post update -- x[5].bar: 3
 post update -- y[6]: 10
+q.length: 5
+q[3]: undefined
+qq.length: 3
+qq[3]: undefined
+qqq.length: 5
+qqq[3]: undefined
+a[o]: 50
+a[o1]: 50
+a["[object Object]"]: 50
+a["[object" + " Object]"]: 50
 
 Reached end of Execution -- Exiting.

+ 63 - 0
test/TTBasic/bind.js

@@ -0,0 +1,63 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+function PropertyExists(obj, propName)
+{
+    return obj.hasOwnProperty(propName);
+}
+
+var val = 100;
+function IncrVal()
+{
+    telemetryLog(`IncrVal:: ${this.val}  args.length : ${arguments.length}`, true);
+    this.val++;
+    return this.val + " " + arguments.length;
+}
+
+var fGlobalThis1 = IncrVal.bind();
+var fGlobalThis2 = IncrVal.bind(this);
+var fGlobalThis3 = IncrVal.bind(this, 50);
+
+var fGlobalThisNull = IncrVal.bind(null);
+
+var objWithVal1 = { val : 200 }
+var fLocal1 = IncrVal.bind(objWithVal1);
+
+var x = 20;
+var y = 30;
+
+function add()
+{
+    return this.x + this.y;
+}
+
+var o = { x: 5, y: 6};
+var f = add.bind(o);
+
+var f2 = new f();
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog(`global object 1 ${fGlobalThis1()}`, true);
+    telemetryLog(`global object 1 ${fGlobalThis1(10,20)}`, true);
+    telemetryLog(`global object 2 ${fGlobalThis2()}`, true);
+    telemetryLog(`global object 2 ${fGlobalThis2(10,20)}`, true);
+    telemetryLog(`global object 3 ${fGlobalThis3()}`, true);
+    telemetryLog(`global object 3 ${fGlobalThis3(10,20)}`, true);
+
+    telemetryLog(`global object null ${fGlobalThisNull(10,20)}`, true);
+
+    telemetryLog(`local length ${fLocal1.length}`, true);
+    telemetryLog(`Local object2 ${fLocal1(10)}`, true);
+
+    telemetryLog(`Add Test ${add()}`, true);
+    telemetryLog(`f Test ${f()}`, true);
+
+    telemetryLog(`Proto Test ${add.prototype.isPrototypeOf(f2)}`, true);
+}

+ 20 - 0
test/TTBasic/bindRecord.baseline

@@ -0,0 +1,20 @@
+IncrVal:: 100  args.length : 0
+global object 1 101 0
+IncrVal:: 101  args.length : 2
+global object 1 102 2
+IncrVal:: 102  args.length : 0
+global object 2 103 0
+IncrVal:: 103  args.length : 2
+global object 2 104 2
+IncrVal:: 104  args.length : 1
+global object 3 105 1
+IncrVal:: 105  args.length : 3
+global object 3 106 3
+IncrVal:: 106  args.length : 2
+global object null 107 2
+local length 0
+IncrVal:: 200  args.length : 1
+Local object2 201 1
+Add Test 50
+f Test 11
+Proto Test true

+ 22 - 0
test/TTBasic/bindReplay.baseline

@@ -0,0 +1,22 @@
+IncrVal:: 100  args.length : 0
+global object 1 101 0
+IncrVal:: 101  args.length : 2
+global object 1 102 2
+IncrVal:: 102  args.length : 0
+global object 2 103 0
+IncrVal:: 103  args.length : 2
+global object 2 104 2
+IncrVal:: 104  args.length : 1
+global object 3 105 1
+IncrVal:: 105  args.length : 3
+global object 3 106 3
+IncrVal:: 106  args.length : 2
+global object null 107 2
+local length 0
+IncrVal:: 200  args.length : 1
+Local object2 201 1
+Add Test 50
+f Test 11
+Proto Test true
+
+Reached end of Execution -- Exiting.

+ 50 - 0
test/TTBasic/constructor.js

@@ -0,0 +1,50 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+function foo(x) {
+    this.x = x;
+}
+
+var f = new foo(10);
+
+foo.prototype = { y : 10 };
+
+var f1 = new foo(20);
+
+function bar(x, y) {
+    this.x1 = x;
+    this.x2 = x;
+    this.x3 = x;
+    this.x4 = x;
+    this.x5 = x;
+    this.x6 = x;
+    this.x7 = x;
+    this.x8 = x;
+    this.x9 = x;
+    
+    this.y1 = y;
+    this.y2 = y;
+    this.y3 = y;
+    this.y4 = y;
+    this.y5 = y;
+    this.y6 = y;
+    this.y7 = y;
+    this.y8 = y;
+    this.y9 = y;
+}
+
+var b1 = new bar(10, 20);
+var b2 = new bar(30, 40);
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog(`f.y ${f.y}`, true);
+    telemetryLog(`f1.y ${f1.y}`, true);
+    telemetryLog(`b2.y8 ${b2.y8}`, true);
+}

+ 3 - 0
test/TTBasic/constructorRecord.baseline

@@ -0,0 +1,3 @@
+f.y undefined
+f1.y 10
+b2.y8 40

+ 5 - 0
test/TTBasic/constructorReplay.baseline

@@ -0,0 +1,5 @@
+f.y undefined
+f1.y 10
+b2.y8 40
+
+Reached end of Execution -- Exiting.

+ 12 - 0
test/TTBasic/dateBasic.js

@@ -12,6 +12,8 @@ y.foo = 3;
 
 var w = Date.now();
 
+var dinfty = new Date(Infinity);
+
 WScript.SetTimeout(testFunction, 50);
 
 /////////////////
@@ -26,4 +28,14 @@ function testFunction()
 
     telemetryLog(`w - z > 0: ${w - z.valueOf() > 0}`, true); //true
     telemetryLog(`x - y: ${x.valueOf() - y.valueOf()}`, true); //0
+
+    try 
+    {
+        telemetryLog(dinfty.toISOString(), true);
+    } 
+    catch(e) 
+    {
+        telemetryLog(`Infinity Date toISOString : ${e.name}  : ${e.message}`, true);
+    }
+    telemetryLog(`Infinity Date toJSON : ${dinfty.toJSON()}`, true);
 }

+ 2 - 0
test/TTBasic/dateBasicRecord.baseline

@@ -4,3 +4,5 @@ y.foo: 3
 x.foo: 3
 w - z > 0: true
 x - y: 0
+Infinity Date toISOString : RangeError  : Number expected
+Infinity Date toJSON : null

+ 2 - 0
test/TTBasic/dateBasicReplay.baseline

@@ -4,5 +4,7 @@ y.foo: 3
 x.foo: 3
 w - z > 0: true
 x - y: 0
+Infinity Date toISOString : RangeError  : Number expected
+Infinity Date toJSON : null
 
 Reached end of Execution -- Exiting.

+ 35 - 0
test/TTBasic/deleteArray.js

@@ -0,0 +1,35 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+Object.prototype[5]  = "obj.proto5";
+Object.prototype[7]  = "obj.proto7";
+
+Array.prototype[1]   = "arr.proto.1";
+Array.prototype[2]   = "arr.proto.2";
+Array.prototype[3]   = "arr.proto.3";
+Array.prototype[6]   = "arr.proto.6";
+
+var n=8;
+var i=0;
+
+var arr = new Array(n);
+
+for (i=3;i<n;i++) { arr[i] = i * i + 1; }
+
+delete arr[1];
+delete arr[3];
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog(`${delete arr[n-1]}`, true); 
+    telemetryLog(`T3:${arr.length} : ${arr}`, true);
+    
+    telemetryLog(`${delete arr[n+1]}`, true); 
+    telemetryLog(`T4:${arr.length} : ${arr}`, true);
+}

+ 4 - 0
test/TTBasic/deleteArrayRecord.baseline

@@ -0,0 +1,4 @@
+true
+T3:8 : ,arr.proto.1,arr.proto.2,arr.proto.3,17,26,37,obj.proto7
+true
+T4:8 : ,arr.proto.1,arr.proto.2,arr.proto.3,17,26,37,obj.proto7

+ 6 - 0
test/TTBasic/deleteArrayReplay.baseline

@@ -0,0 +1,6 @@
+true
+T3:8 : ,arr.proto.1,arr.proto.2,arr.proto.3,17,26,37,obj.proto7
+true
+T4:8 : ,arr.proto.1,arr.proto.2,arr.proto.3,17,26,37,obj.proto7
+
+Reached end of Execution -- Exiting.

+ 33 - 1
test/TTBasic/es5Array.js

@@ -12,10 +12,27 @@ Object.defineProperty(x, '1', {
     set: function (x) { this.foo = x / 2; }
 });
 
-Object.defineProperty(x, '11', {
+Object.defineProperty(x, 11, {
     get: function () { return this.foo; }
 });
 
+var simpleArrayEmptyLength = [];
+Object.defineProperty(simpleArrayEmptyLength, "length", {});
+
+var aFixedInfo = [0, 1, 2, 3, 4, 5];
+Object.defineProperty(aFixedInfo, "length", { writable: false });
+Object.defineProperty(aFixedInfo, "2", { writable: false });
+
+var aFrozen = [0, 1, 2, 3, 4, 5];
+Object.freeze(aFrozen);
+
+var oIncFreeze = [0, 1, 2, 3, 4, 5];
+for (var i = 0; i < oIncFreeze.length; i++) 
+{
+    Object.defineProperty(oIncFreeze, i, { writable: false, configurable: false });
+}
+Object.preventExtensions(oIncFreeze);
+
 WScript.SetTimeout(testFunction, 50);
 
 /////////////////
@@ -35,4 +52,19 @@ function testFunction()
 
     telemetryLog(`x[1]: ${x[1]}`, true); //7
     telemetryLog(`x[11]: ${x[11]}`, true); //6
+
+    ////
+    telemetryLog(`Object.getOwnPropertyDescriptor(simpleArrayEmptyLength.length): ${JSON.stringify(Object.getOwnPropertyDescriptor(simpleArrayEmptyLength, "length"))}`, true); //asdf
+
+    aFixedInfo[9] = 9; // This would throw in strict mode
+    telemetryLog(`aFixedInfo: ${JSON.stringify(aFixedInfo)}`, true); //0, 1, 2, 3, 4, 5
+    aFixedInfo[1] = -1;
+    aFixedInfo[2] = -2;
+    telemetryLog(`aFixedInfo: ${JSON.stringify(aFixedInfo)}`, true); //0, 1, 2, 3, 4, 5
+
+    telemetryLog(`Object.getOwnPropertyDescriptor(aFrozen.length): ${JSON.stringify(Object.getOwnPropertyDescriptor(aFrozen, "length"))}`, true); //asdf
+
+    telemetryLog(`isFrozen: ${Object.isFrozen(oIncFreeze)}`, true); // false, because length writable
+    Object.defineProperty(oIncFreeze, "length", { writable: false });
+    telemetryLog(`isFrozen: ${Object.isFrozen(oIncFreeze)}`, true);
 }

+ 6 - 0
test/TTBasic/es5ArrayRecord.baseline

@@ -4,3 +4,9 @@ x[1]: 4
 x[11]: 3
 x[1]: 7
 x[11]: 6
+Object.getOwnPropertyDescriptor(simpleArrayEmptyLength.length): {"value":0,"writable":true,"enumerable":false,"configurable":false}
+aFixedInfo: [0,1,2,3,4,5]
+aFixedInfo: [0,-1,2,3,4,5]
+Object.getOwnPropertyDescriptor(aFrozen.length): {"value":6,"writable":false,"enumerable":false,"configurable":false}
+isFrozen: false
+isFrozen: true

+ 6 - 0
test/TTBasic/es5ArrayReplay.baseline

@@ -4,5 +4,11 @@ x[1]: 4
 x[11]: 3
 x[1]: 7
 x[11]: 6
+Object.getOwnPropertyDescriptor(simpleArrayEmptyLength.length): {"value":0,"writable":true,"enumerable":false,"configurable":false}
+aFixedInfo: [0,1,2,3,4,5]
+aFixedInfo: [0,-1,2,3,4,5]
+Object.getOwnPropertyDescriptor(aFrozen.length): {"value":6,"writable":false,"enumerable":false,"configurable":false}
+isFrozen: false
+isFrozen: true
 
 Reached end of Execution -- Exiting.

+ 52 - 0
test/TTBasic/extensible.js

@@ -0,0 +1,52 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+var a = {x:20, y:30};
+Object.preventExtensions(a);
+
+var b = {x:20, y:30};
+Object.preventExtensions(b);
+
+var c = {x:20, y:30};
+Object.preventExtensions(c);
+
+var d = {x:20, y:30};
+Object.preventExtensions(d);
+
+var e = {get x() {return 0;}, y:30};
+Object.preventExtensions(e);
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    a.z = 50;
+    telemetryLog(`${Object.getOwnPropertyNames(a)}`, true);
+    telemetryLog(`${Object.isExtensible(a)}`, true);
+
+    delete b.x;
+    telemetryLog(`${b.x}`, true);
+    telemetryLog(`${Object.isExtensible(b)}`, true);
+
+    c.x = 40;
+    c.y = 60;
+    telemetryLog(`${Object.getOwnPropertyNames(c)}`, true);
+    telemetryLog(`${Object.isExtensible(c)}`, true);
+    telemetryLog(`${c.x}`, true);
+
+    delete d.x;
+    Object.defineProperty(d, "y", {configurable: false});
+    telemetryLog(`${Object.isSealed(d)}`, true);
+    Object.defineProperty(d, "y", {writable: false});
+    telemetryLog(`${Object.isFrozen(d)}`, true);
+
+    delete e.x;
+    Object.defineProperty(e, "y", {configurable: false});
+    telemetryLog(`${Object.isSealed(e)}`, true);
+    Object.defineProperty(e, "y", {writable: false});
+    telemetryLog(`${Object.isFrozen(e)}`, true);
+}

+ 11 - 0
test/TTBasic/extensibleRecord.baseline

@@ -0,0 +1,11 @@
+x,y
+false
+undefined
+false
+x,y
+false
+40
+true
+true
+true
+true

+ 13 - 0
test/TTBasic/extensibleReplay.baseline

@@ -0,0 +1,13 @@
+x,y
+false
+undefined
+false
+x,y
+false
+40
+true
+true
+true
+true
+
+Reached end of Execution -- Exiting.

+ 0 - 9
test/TTBasic/forEachRecord.baseline

@@ -1,9 +0,0 @@
-xname: foo
-xname: bar
-xname: foo2
-yname: foo
-yname: baz
-yname: bar2
-zname: foo
-zname: bar
-zname: baz

+ 0 - 11
test/TTBasic/forEachReplay.baseline

@@ -1,11 +0,0 @@
-xname: foo
-xname: bar
-xname: foo2
-yname: foo
-yname: baz
-yname: bar2
-zname: foo
-zname: bar
-zname: baz
-
-Reached end of Execution -- Exiting.

+ 81 - 0
test/TTBasic/forInShadowing.js

@@ -0,0 +1,81 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+function forInKeysToArray(obj) {
+    var s = [];
+    
+    for (key in obj) { 
+        s.push(key);
+    }
+    
+    return s;
+}
+
+var proto1 = { x: 1 };
+var child1 = Object.create(proto1, { x: { value: 2, enumerable: false} });
+
+var proto2 = { a: 1, b: 2, c: 3, d: 4, e: 5 };
+var child2 = Object.create(proto2, { b: { value: 20, enumerable: false} });
+Object.defineProperty(child2, 'c', { enumerable: false, value: 30 });
+child2['d'] = 4;
+
+var o1 = [0,1,2];
+o1[4] = 4;
+Object.defineProperty(o1, 3, { enumerable: false, value: '3' })
+
+var proto3 = Object.create(null, { x: { value: 1, enumerable: false} });
+var child3 = Object.create(proto3, { x: { value: 2, enumerable: true} });
+
+var proto4 = Object.create(null, { x: { value: 1, enumerable: false} });
+var child4 = Object.create(proto4, { x: { value: 2, enumerable: false} });
+
+var proto5 = Object.create(null, { 
+    a: { value: 1, enumerable: false},
+    b: { value: 1, enumerable: true},
+    c: { value: 1, enumerable: false},
+    d: { value: 1, enumerable: false},
+    w: { value: 1, enumerable: true},
+    x: { value: 1, enumerable: false},
+    y: { value: 1, enumerable: true},
+    z: { value: 1, enumerable: true},
+    });
+var child5 = Object.create(proto5, { 
+    a: { value: 2, enumerable: false},
+    b: { value: 2, enumerable: false},
+    c: { value: 2, enumerable: true},
+    d: { value: 2, enumerable: false},
+    w: { value: 2, enumerable: true},
+    x: { value: 2, enumerable: true},
+    y: { value: 2, enumerable: false},
+    z: { value: 2, enumerable: true},
+    });
+var childchild5 = Object.create(child5, { 
+    a: { value: 3, enumerable: false},
+    b: { value: 3, enumerable: false},
+    c: { value: 3, enumerable: false},
+    d: { value: 3, enumerable: true},
+    w: { value: 3, enumerable: false},
+    x: { value: 3, enumerable: true},
+    y: { value: 3, enumerable: true},
+    z: { value: 3, enumerable: true},
+    });
+
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog(`${JSON.stringify(forInKeysToArray(child1))}`, true); //[]
+    telemetryLog(`${JSON.stringify(forInKeysToArray(child2))}`, true); //['d','a','e']
+    telemetryLog(`${JSON.stringify(forInKeysToArray(o1))}`, true); //['0','1','2','4']
+    telemetryLog(`${JSON.stringify(forInKeysToArray(child3))}`, true); //['x']
+    telemetryLog(`${JSON.stringify(forInKeysToArray(child4))}`, true); //[]
+
+    telemetryLog(`${JSON.stringify(forInKeysToArray(childchild5))}`, true); //['d','x','y','z']
+    telemetryLog(`${JSON.stringify(forInKeysToArray(child5))}`, true); //['c','w','x','z']
+    telemetryLog(`${JSON.stringify(forInKeysToArray(proto5))}`, true); //['b','w','y','z']
+}

+ 8 - 0
test/TTBasic/forInShadowingRecord.baseline

@@ -0,0 +1,8 @@
+[]
+["d","a","e"]
+["0","1","2","4"]
+["x"]
+[]
+["d","x","y","z"]
+["c","w","x","z"]
+["b","w","y","z"]

+ 10 - 0
test/TTBasic/forInShadowingReplay.baseline

@@ -0,0 +1,10 @@
+[]
+["d","a","e"]
+["0","1","2","4"]
+["x"]
+[]
+["d","x","y","z"]
+["c","w","x","z"]
+["b","w","y","z"]
+
+Reached end of Execution -- Exiting.

+ 44 - 0
test/TTBasic/freeze.js

@@ -0,0 +1,44 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+var a = {x:20, y:30};
+Object.freeze(a);
+
+var b = {x:20, y:30};
+Object.freeze(b);
+
+var c = {x:20, y:30};
+Object.freeze(c);
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    a.z = 50;
+    try 
+    {
+        Object.defineProperty(a, 'ohai', { value: 17 });
+    }
+    catch(e)
+    {
+        telemetryLog(`${e}`, true);
+    }
+
+    telemetryLog(`${Object.getOwnPropertyNames(a)}`, true);
+    telemetryLog(`${Object.isFrozen(a)}`, true);
+
+    delete b.x;
+    telemetryLog(`${Object.getOwnPropertyNames(b)}`, true);
+    telemetryLog(`${Object.isFrozen(b)}`, true);
+    telemetryLog(`${b.x}`, true);
+
+    a.c = 40;
+    a.c = 60;
+    telemetryLog(`${Object.getOwnPropertyNames(c)}`, true);
+    telemetryLog(`${Object.isFrozen(c)}`, true);
+    telemetryLog(`${c.x}`, true);
+}

+ 9 - 0
test/TTBasic/freezeRecord.baseline

@@ -0,0 +1,9 @@
+TypeError: Cannot define property 'ohai': object is not extensible
+x,y
+true
+x,y
+true
+20
+x,y
+true
+20

+ 11 - 0
test/TTBasic/freezeReplay.baseline

@@ -0,0 +1,11 @@
+TypeError: Cannot define property 'ohai': object is not extensible
+x,y
+true
+x,y
+true
+20
+x,y
+true
+20
+
+Reached end of Execution -- Exiting.

+ 33 - 0
test/TTBasic/largeAuxArray.js

@@ -0,0 +1,33 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+var o = { };
+
+function AddAccessorProperty()
+{
+    // add accessor property (converts to DictionaryTypeHandler)
+    Object.defineProperty(o, "a", { get: function () { return 10; } , configurable: true} );
+}
+
+function AddPropertiesToObjectArray()
+{
+    // add enough properties to convert to BigDictionaryTypeHandler
+    for (var i = 0; i < 25000; i++) {
+        o["p" + i] = 0;
+    }
+}
+
+AddAccessorProperty();
+AddPropertiesToObjectArray();
+AddAccessorProperty();
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog(`o.a === 10: ${o.a === 10}`, true);
+}

+ 1 - 0
test/TTBasic/largeAuxArrayRecord.baseline

@@ -0,0 +1 @@
+o.a === 10: true

+ 3 - 0
test/TTBasic/largeAuxArrayReplay.baseline

@@ -0,0 +1,3 @@
+o.a === 10: true
+
+Reached end of Execution -- Exiting.

+ 55 - 0
test/TTBasic/missingArray.js

@@ -0,0 +1,55 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+Object.prototype[5]  = "obj.proto5";
+Object.prototype[7]  = "obj.proto7";
+
+Array.prototype[1]   = "arr.proto.1";
+Array.prototype[2]   = "arr.proto.2";
+Array.prototype[3]   = "arr.proto.3";
+Array.prototype[6]   = "arr.proto.6";
+
+var n=8;
+
+var arr = new Array(4);
+arr[1] = null;
+arr[2] = undefined;
+
+function test() {
+        var x;
+        switch (x) {
+        default:
+                [1, , ];
+        }
+};
+
+function ArrayLiteralMissingValue()
+{
+  return [1, 1, -2147483646];
+}
+var arr1 = ArrayLiteralMissingValue();
+
+function ArrayConstructorMissingValue()
+{
+  return new Array(-1, -2147483646);
+}
+var IntArr0 = ArrayConstructorMissingValue();
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    for (var i=0;i<n;i++) {
+        telemetryLog(`arr[${i}] : ${arr[i]}`, true);
+    }
+
+    test();
+    test();
+
+    telemetryLog(`[] missing value:${arr1[2]}`, true);
+    telemetryLog(`Array() missing value:${IntArr0[1]}`, true);
+}

+ 10 - 0
test/TTBasic/missingArrayRecord.baseline

@@ -0,0 +1,10 @@
+arr[0] : undefined
+arr[1] : null
+arr[2] : undefined
+arr[3] : arr.proto.3
+arr[4] : undefined
+arr[5] : obj.proto5
+arr[6] : arr.proto.6
+arr[7] : obj.proto7
+[] missing value:-2147483646
+Array() missing value:-2147483646

+ 12 - 0
test/TTBasic/missingArrayReplay.baseline

@@ -0,0 +1,12 @@
+arr[0] : undefined
+arr[1] : null
+arr[2] : undefined
+arr[3] : arr.proto.3
+arr[4] : undefined
+arr[5] : obj.proto5
+arr[6] : arr.proto.6
+arr[7] : obj.proto7
+[] missing value:-2147483646
+Array() missing value:-2147483646
+
+Reached end of Execution -- Exiting.

+ 25 - 0
test/TTBasic/newFromArgs.js

@@ -0,0 +1,25 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+
+Array.prototype[1] = 100;
+function f(param)
+{
+    var a = new Array(1, param, 3);
+    return a;
+}
+
+var a1 = f(undefined)[1];
+var a2 = f(undefined)[1];
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog(`${a1}`, true);
+    telemetryLog(`${a2}`, true);  // undefined in array parameter should still be set (legacy behavior is missing value)
+}

+ 2 - 0
test/TTBasic/newFromArgsRecord.baseline

@@ -0,0 +1,2 @@
+undefined
+undefined

+ 4 - 0
test/TTBasic/newFromArgsReplay.baseline

@@ -0,0 +1,4 @@
+undefined
+undefined
+
+Reached end of Execution -- Exiting.

+ 23 - 0
test/TTBasic/numericPropertyIsEnumerable.js

@@ -0,0 +1,23 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+var myobj = { a: "apple", 101: 1 }
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog(`myobj.propertyIsEnumerable('a'): ${myobj.propertyIsEnumerable('a')}`, true);
+    telemetryLog(`myobj.propertyIsEnumerable(101): ${myobj.propertyIsEnumerable(101)}`, true);
+    telemetryLog(`myobj.propertyIsEnumerable("101"): ${myobj.propertyIsEnumerable("101")}`, true);
+    telemetryLog(`myobj.propertyIsEnumerable("10"): ${myobj.propertyIsEnumerable("10")}`, true);
+
+    for (o in myobj)
+    {
+        telemetryLog(`${o} is enumerable ${myobj.propertyIsEnumerable(o)}`, true);
+    }
+}

+ 6 - 0
test/TTBasic/numericPropertyIsEnumerableRecord.baseline

@@ -0,0 +1,6 @@
+myobj.propertyIsEnumerable('a'): true
+myobj.propertyIsEnumerable(101): true
+myobj.propertyIsEnumerable("101"): true
+myobj.propertyIsEnumerable("10"): false
+101 is enumerable true
+a is enumerable true

+ 8 - 0
test/TTBasic/numericPropertyIsEnumerableReplay.baseline

@@ -0,0 +1,8 @@
+myobj.propertyIsEnumerable('a'): true
+myobj.propertyIsEnumerable(101): true
+myobj.propertyIsEnumerable("101"): true
+myobj.propertyIsEnumerable("10"): false
+101 is enumerable true
+a is enumerable true
+
+Reached end of Execution -- Exiting.

+ 33 - 0
test/TTBasic/popArrayImplicitCall.js

@@ -0,0 +1,33 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+var obj = {};
+
+Object.prototype.push = Array.prototype.push;
+Object.prototype.pop = Array.prototype.pop;
+var x;
+Object.defineProperty(obj, "length", {get: function() {x = true; return 5;}});
+
+x = false;
+
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    try
+    {
+        var len = obj.pop();
+    }
+    catch (e)
+    {
+        telemetryLog('caught exception calling pop', true);
+    }
+
+    telemetryLog(`${x}`, true);
+    telemetryLog(`${len}`, true);
+}

+ 3 - 0
test/TTBasic/popArrayImplicitCallRecord.baseline

@@ -0,0 +1,3 @@
+caught exception calling pop
+true
+undefined

+ 5 - 0
test/TTBasic/popArrayImplicitCallReplay.baseline

@@ -0,0 +1,5 @@
+caught exception calling pop
+true
+undefined
+
+Reached end of Execution -- Exiting.

+ 11 - 0
test/TTBasic/regex.js

@@ -10,12 +10,23 @@ var z = new RegExp("l", "g");
 y.exec("Hello World");
 z.lastIndex = -1;
 
+var re = /abc/i;
+var re1 = new RegExp(re, "gm");
+
 WScript.SetTimeout(testFunction, 50);
 
 /////////////////
 
 function testFunction()
 {
+    telemetryLog(`re.global == ${re.global}`, true); //false
+    telemetryLog(`re.multiline == ${re.multiline}`, true); //false
+    telemetryLog(`re.ignoreCase == ${re.ignoreCase}`, true); //true
+
+    telemetryLog(`re1.global == ${re1.global}`, true); //true
+    telemetryLog(`re1.multiline == ${re1.multiline}`, true); //true
+    telemetryLog(`re1.ignoreCase == ${re1.ignoreCase}`, true); //false
+
     telemetryLog(`y.lastIndex: ${y.lastIndex}`, true); //3
     telemetryLog(`z.lastIndex: ${z.lastIndex}`, true); //3
 

+ 6 - 0
test/TTBasic/regexRecord.baseline

@@ -1,3 +1,9 @@
+re.global == false
+re.multiline == false
+re.ignoreCase == true
+re1.global == true
+re1.multiline == true
+re1.ignoreCase == false
 y.lastIndex: 3
 z.lastIndex: -1
 m.index: 6

+ 6 - 0
test/TTBasic/regexReplay.baseline

@@ -1,3 +1,9 @@
+re.global == false
+re.multiline == false
+re.ignoreCase == true
+re1.global == true
+re1.multiline == true
+re1.ignoreCase == false
 y.lastIndex: 3
 z.lastIndex: -1
 m.index: 6

+ 261 - 5
test/TTBasic/rlexe.xml

@@ -48,6 +48,22 @@
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>bind.js</files>
+      <compile-flags>-TTRecord=~bindTest -TTSnapInterval=0</compile-flags>
+      <baseline>bindRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~bindTest -TTDStartEvent=2</compile-flags>
+      <baseline>bindReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
   <test>
     <default>
       <files>boolean.js</files>
@@ -95,6 +111,22 @@
       <baseline>boxedObjectReplay.baseline</baseline>
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
+  </test>
+    <test>
+    <default>
+      <files>constructor.js</files>
+      <compile-flags>-TTRecord=~constructorTest -TTSnapInterval=0</compile-flags>
+      <baseline>constructorRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~constructorTest -TTDStartEvent=2</compile-flags>
+      <baseline>constructorReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
   </test>
   <test>
     <default>
@@ -120,6 +152,22 @@
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>deleteArray.js</files>
+      <compile-flags>-TTRecord=~deleteArrayTest -TTSnapInterval=0</compile-flags>
+      <baseline>deleteArrayRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~deleteArrayTest -TTDStartEvent=2</compile-flags>
+      <baseline>deleteArrayReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
   <test>
     <default>
       <files>es5Array.js</files>
@@ -170,17 +218,49 @@
   </test>
   <test>
     <default>
-      <files>forEach.js</files>
-      <compile-flags>-TTRecord=~forEachTest -TTSnapInterval=0</compile-flags>
-      <baseline>forEachRecord.baseline</baseline>
+      <files>extensible.js</files>
+      <compile-flags>-TTRecord=~extensibleTest -TTSnapInterval=0</compile-flags>
+      <baseline>extensibleRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~extensibleTest -TTDStartEvent=2</compile-flags>
+      <baseline>extensibleReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>forInShadowing.js</files>
+      <compile-flags>-TTRecord=~forInShadowingTest -TTSnapInterval=0</compile-flags>
+      <baseline>forInShadowingRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~forInShadowingTest -TTDStartEvent=2</compile-flags>
+      <baseline>forInShadowingReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>freeze.js</files>
+      <compile-flags>-TTRecord=~freezeTest -TTSnapInterval=0</compile-flags>
+      <baseline>freezeRecord.baseline</baseline>
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
   <test>
     <default>
       <files>ttdSentinal.js</files>
-      <compile-flags>-TTDebug=~forEachTest -TTDStartEvent=2</compile-flags>
-      <baseline>forEachReplay.baseline</baseline>
+      <compile-flags>-TTDebug=~freezeTest -TTDStartEvent=2</compile-flags>
+      <baseline>freezeReplay.baseline</baseline>
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
@@ -200,6 +280,22 @@
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>largeAuxArray.js</files>
+      <compile-flags>-TTRecord=~largeAuxArrayTest -TTSnapInterval=0</compile-flags>
+      <baseline>largeAuxArrayRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~largeAuxArrayTest -TTDStartEvent=2</compile-flags>
+      <baseline>largeAuxArrayReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
   <test>
     <default>
       <files>loadReEntrant.js</files>
@@ -240,6 +336,22 @@
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>missingArray.js</files>
+      <compile-flags>-TTRecord=~missingArrayTest -TTSnapInterval=0</compile-flags>
+      <baseline>missingArrayRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~missingArrayTest -TTDStartEvent=2</compile-flags>
+      <baseline>missingArrayReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
   <test>
     <default>
       <files>nativeArray.js</files>
@@ -256,6 +368,22 @@
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>newFromArgs.js</files>
+      <compile-flags>-TTRecord=~newFromArgsTest -TTSnapInterval=0</compile-flags>
+      <baseline>newFromArgsRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~newFromArgsTest -TTDStartEvent=2</compile-flags>
+      <baseline>newFromArgsReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
   <test>
     <default>
       <files>newFunction.js</files>
@@ -288,6 +416,22 @@
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>numericPropertyIsEnumerable.js</files>
+      <compile-flags>-TTRecord=~numericPropertyIsEnumerableTest -TTSnapInterval=0</compile-flags>
+      <baseline>numericPropertyIsEnumerableRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~numericPropertyIsEnumerableTest -TTDStartEvent=2</compile-flags>
+      <baseline>numericPropertyIsEnumerableReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
   <test>
     <default>
       <files>object.js</files>
@@ -304,6 +448,22 @@
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>popArrayImplicitCall.js</files>
+      <compile-flags>-TTRecord=~popArrayImplicitCallTest -TTSnapInterval=0</compile-flags>
+      <baseline>popArrayImplicitCallRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~popArrayImplicitCallTest -TTDStartEvent=2</compile-flags>
+      <baseline>popArrayImplicitCallReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
   <test>
     <default>
       <files>promise.js</files>
@@ -384,6 +544,38 @@
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>seal.js</files>
+      <compile-flags>-TTRecord=~sealTest -TTSnapInterval=0</compile-flags>
+      <baseline>sealRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~sealTest -TTDStartEvent=2</compile-flags>
+      <baseline>sealReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>scopedAccessors.js</files>
+      <compile-flags>-TTRecord=~scopedAccessorsTest -TTSnapInterval=0</compile-flags>
+      <baseline>scopedAccessorsRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~scopedAccessorsTest -TTDStartEvent=2</compile-flags>
+      <baseline>scopedAccessorsReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
   <test>
     <default>
       <files>scopeFunction.js</files>
@@ -416,6 +608,38 @@
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>shadowPrototype.js</files>
+      <compile-flags>-TTRecord=~shadowPrototypeTest -TTSnapInterval=0</compile-flags>
+      <baseline>shadowPrototypeRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~shadowPrototypeTest -TTDStartEvent=2</compile-flags>
+      <baseline>shadowPrototypeReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>sparseArray.js</files>
+      <compile-flags>-TTRecord=~sparseArrayTest -TTSnapInterval=0</compile-flags>
+      <baseline>sparseArrayRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~sparseArrayTest -TTDStartEvent=2</compile-flags>
+      <baseline>sparseArrayReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
   <test>
     <default>
       <files>string.js</files>
@@ -456,6 +680,22 @@
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>typeConversions.js</files>
+      <compile-flags>-TTRecord=~typeConversionTest -TTSnapInterval=0</compile-flags>
+      <baseline>typeConversionsRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~typeConversionTest -TTDStartEvent=2</compile-flags>
+      <baseline>typeConversionsReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
   <test>
     <default>
       <files>typedArray.js</files>
@@ -472,4 +712,20 @@
       <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>typePromotion.js</files>
+      <compile-flags>-TTRecord=~typePromotionTest -TTSnapInterval=0</compile-flags>
+      <baseline>typePromotionRecord.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>ttdSentinal.js</files>
+      <compile-flags>-TTDebug=~typePromotionTest -TTDStartEvent=2</compile-flags>
+      <baseline>typePromotionReplay.baseline</baseline>
+      <tags>exclude_dynapogo,exclude_jshost,exclude_snap,exclude_serialized</tags>
+    </default>
+  </test>
 </regress-exe>

+ 56 - 0
test/TTBasic/scopedAccessors.js

@@ -0,0 +1,56 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+function top1() {
+    var xx = new Object();
+    Object.defineProperty(xx, "yy", { set: function(val) {telemetryLog("in nested setter1", true); this.val = 10;} });
+    var z = function() {
+       xx.yy = 20;
+       telemetryLog(`val is ${xx.yy}`, true);
+    }
+    return z;
+}
+var foo1 = top1();
+
+function top2() {
+    var xx = new Object();
+    Object.defineProperty(xx, "yy", { get: function() { return this; },
+    set: function(val) {telemetryLog("in nested setter2", true); this.val = 11;} });
+    var z = function() {
+       xx.yy = 20;
+       telemetryLog(`val is ${xx.yy}`, true);
+       telemetryLog(`val is ${xx.yy.val}`, true);
+    }
+    return z;
+}
+var foo2 = top2();
+
+function top3() {
+    Object.defineProperty(this, "yy", { get: function() { return this; },
+    set: function(val) {telemetryLog("in nested setter3"); this.val = 12;} });
+    var z = function() {
+       yy = 20;
+       telemetryLog(`val is ${yy}`, true);
+       telemetryLog(`val is ${yy.val}`, true);    
+    }
+    return z;
+}
+var foo3 = top3();
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog("test1: nested setter without getter", true);
+    foo1();
+
+    telemetryLog("test2: nested setter and setter", true);
+    foo2();
+
+    telemetryLog("test3: nested setter and setter from this", true);
+    foo3();
+}

+ 10 - 0
test/TTBasic/scopedAccessorsRecord.baseline

@@ -0,0 +1,10 @@
+test1: nested setter without getter
+in nested setter1
+val is undefined
+test2: nested setter and setter
+in nested setter2
+val is [object Object]
+val is 11
+test3: nested setter and setter from this
+val is [object Object]
+val is 12

+ 12 - 0
test/TTBasic/scopedAccessorsReplay.baseline

@@ -0,0 +1,12 @@
+test1: nested setter without getter
+in nested setter1
+val is undefined
+test2: nested setter and setter
+in nested setter2
+val is [object Object]
+val is 11
+test3: nested setter and setter from this
+val is [object Object]
+val is 12
+
+Reached end of Execution -- Exiting.

+ 39 - 0
test/TTBasic/seal.js

@@ -0,0 +1,39 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+var a = {x:20, y:30};
+Object.seal(a);
+
+var b = {x:20, y:30};
+Object.seal(b);
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    a.x = 40;
+    a.z = 50;
+    telemetryLog(`${Object.getOwnPropertyNames(a)}`, true);
+    telemetryLog(`${Object.isSealed(a)}`, true);
+    telemetryLog(`${a.x}`, true);
+
+    try 
+    {
+        Object.defineProperty(a, 'x', { get: function() { return 'ohai'; } }); 
+    }
+    catch(e)
+    {
+        telemetryLog(`${e}`, true);
+    }
+
+    b.x = 40;
+    delete b.x;
+    b.z = 50;
+    telemetryLog(`${Object.getOwnPropertyNames(b)}`, true);
+    telemetryLog(`${Object.isSealed(b)}`, true);
+    telemetryLog(`${b.x}`, true);
+}

+ 7 - 0
test/TTBasic/sealRecord.baseline

@@ -0,0 +1,7 @@
+x,y
+true
+40
+TypeError: Cannot redefine non-configurable property 'x'
+x,y
+true
+40

+ 9 - 0
test/TTBasic/sealReplay.baseline

@@ -0,0 +1,9 @@
+x,y
+true
+40
+TypeError: Cannot redefine non-configurable property 'x'
+x,y
+true
+40
+
+Reached end of Execution -- Exiting.

+ 47 - 0
test/TTBasic/shadowPrototype.js

@@ -0,0 +1,47 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+function check(o, v)
+{
+    o.value(v);
+}
+
+function first()
+{
+}
+
+function isFirst(v) { telemetryLog(`v is ${v} expecting 1.`, true); }
+function isSecond(v) { telemetryLog(`v is ${v} expecting 2.`, true); }
+
+first.value = isFirst;
+
+function second()
+{
+}
+second.prototype = first;
+
+function third()
+{}
+
+third.prototype = new second();
+
+var obj1 = new third();
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    check(obj1, 1);
+
+    third.prototype.value = isSecond;
+
+    check(obj1, 2);
+
+    delete third.prototype.value;
+
+    check(obj1, 1);
+}

+ 3 - 0
test/TTBasic/shadowPrototypeRecord.baseline

@@ -0,0 +1,3 @@
+v is 1 expecting 1.
+v is 2 expecting 2.
+v is 1 expecting 1.

+ 5 - 0
test/TTBasic/shadowPrototypeReplay.baseline

@@ -0,0 +1,5 @@
+v is 1 expecting 1.
+v is 2 expecting 2.
+v is 1 expecting 1.
+
+Reached end of Execution -- Exiting.

+ 80 - 0
test/TTBasic/sparseArray.js

@@ -0,0 +1,80 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+var a = new Array(0x15000); //makes this sparse
+
+var i=0;
+
+for(var i=50;i<60;i++)
+{
+  a[i] = i+10;
+}
+
+for(var i=0;i<10;i++)
+{
+  a[i] = i+20;
+}
+
+for(var i=100;i<110;i++)
+{
+  a[i] = i*10;
+}
+
+var b = new Array(0x15000); //makes this sparse
+
+for(var i=50;i<60;i++)
+{
+  a[i] = i+10;
+}
+
+for(var i=0;i<10;i++)
+{
+  a[i] = i+20;
+}
+
+for(var i=100;i<110;i++)
+{
+  a[i] = i+40;
+}
+
+var c = a.concat(b);
+
+var  d = a.slice(10);
+
+var x = [];
+x[0xFFFFFFFF] = 0;
+x[0xFFFFFFFE] = 1;
+x[0xFFFFFFFD] = 2;
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog(`${c[50]}`, true);
+    telemetryLog(`${c[0]}`, true);
+
+    telemetryLog(`${a.shift()}`, true);
+    telemetryLog(`${a[7]}`, true);
+    telemetryLog(`${a[8]}`, true);
+    telemetryLog(`${a.shift()}`, true);
+    telemetryLog(`${a.length}`, true);
+
+    telemetryLog(`${d[41]}`, true);
+    telemetryLog(`${d[90]}`, true);
+
+    a.splice(45,3,"a","b","c");
+
+    telemetryLog(`${a[45]}`, true);
+    telemetryLog(`${a[46]}`, true);
+    telemetryLog(`${a[50]}`, true);
+    telemetryLog(`${a[100]}`, true);
+    telemetryLog(`${a.length}`, true);
+
+    telemetryLog(`${x[0xFFFFFFFF]} ${x.length}`, true);
+    telemetryLog(`${x[0xFFFFFFFE]} ${x.length === 0xFFFFFFFF}`, true);
+    telemetryLog(`${x[0xFFFFFFFD]} ${x.length === 0xFFFFFFFF}`, true);
+}

+ 17 - 0
test/TTBasic/sparseArrayRecord.baseline

@@ -0,0 +1,17 @@
+60
+20
+20
+28
+29
+21
+86014
+61
+140
+a
+b
+62
+142
+86014
+0 4294967295
+1 true
+2 true

+ 19 - 0
test/TTBasic/sparseArrayReplay.baseline

@@ -0,0 +1,19 @@
+60
+20
+20
+28
+29
+21
+86014
+61
+140
+a
+b
+62
+142
+86014
+0 4294967295
+1 true
+2 true
+
+Reached end of Execution -- Exiting.

+ 86 - 0
test/TTBasic/typeConversions.js

@@ -0,0 +1,86 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+var x1 = {p01: 0};
+Object.preventExtensions(x1);
+var y1 = {p01: 0};
+
+////
+
+var f2 = function f(o) { var tepm = o["p02_2"]; o["p02_2"] = 10; };
+var x2 = {p02_1: 0};
+f2(x2);
+var y2 = {p02_1: 0};
+Object.preventExtensions(y2);
+f2(y2);
+
+////
+
+var x3 = {p03: 0};
+Object.preventExtensions(x3);
+delete x3["p03"];
+var y3 = {p03: 0}; // new object with same layout as previous one.
+y3["p03"] = 2;
+Object.preventExtensions(y3); // Earlier bug: this was associated a with evolved type.
+y3["p03"] = 3; // Can modify writable property but not on evolved type.
+
+////
+
+var x5 = {p05: 0};
+Object.seal(x5);
+Object.defineProperty(x5, "p05", {writable: false, value: 100}); // this should succeed
+var y5 = {p05: 0};
+Object.seal(y5); // Now y shares same s.d.t.h as x used to before defineProperty on x.
+Object.defineProperty(y5, "p05", {writable: false, value: 200}); // this should succeed again (defineProperty on x should not corrupt shared t.h.)
+
+var values6 = [0, 1, 2, 3];
+var x6 = {p06: 0};
+x6["p06"] = values6[0];
+Object.freeze(x6);
+x6["p06"] = values6[1];  // this should not work
+var y6 = {p06: 0};
+Object.seal(y6);
+y6["p06"] = values6[2];   // this should work
+var z6 = {p06: 0};
+Object.preventExtensions(z6);
+z6["p06"] = values6[3];   // this should work
+
+var x9 = {p09: 0};
+x9[0] = 0;
+Object.preventExtensions(x9);
+x9[1] = 1; // Should fail.
+Object.defineProperty(x9, '0', {value: 2}); // Another way to add a property, should fail as well.
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog(`Object.isExtensible(x1): ${Object.isExtensible(x1)}`, true);
+    telemetryLog(`Object.isExtensible(y1): ${Object.isExtensible(y1)}`, true);
+
+    ////
+
+    telemetryLog(`y2["p02_2"]: ${y2["p02_2"]}`, true);
+
+    ////
+
+    telemetryLog(`Object.isExtensible(x3): ${Object.isExtensible(x3)}`, true);
+    telemetryLog(`y3["p03"]: ${y3["p03"]}`, true); //3
+
+    ////
+
+    telemetryLog(`y5["p05"]: ${y5["p05"]}`, true); //200
+
+    ////
+
+    telemetryLog(`[x6["p06"], y6["p06"], z6["p06"]]: ${[x6["p06"], y6["p06"], z6["p06"]]}`, true); //[0, 2, 3]
+
+    ////
+
+    telemetryLog(`x9[0]: ${x9[0]}`, true); //0
+    telemetryLog(`x9[1]: ${x9[1]}`, true); //undef
+}

+ 9 - 0
test/TTBasic/typeConversionsRecord.baseline

@@ -0,0 +1,9 @@
+Object.isExtensible(x1): false
+Object.isExtensible(y1): true
+y2["p02_2"]: undefined
+Object.isExtensible(x3): false
+y3["p03"]: 3
+y5["p05"]: 200
+[x6["p06"], y6["p06"], z6["p06"]]: 0,2,3
+x9[0]: 2
+x9[1]: undefined

+ 11 - 0
test/TTBasic/typeConversionsReplay.baseline

@@ -0,0 +1,11 @@
+Object.isExtensible(x1): false
+Object.isExtensible(y1): true
+y2["p02_2"]: undefined
+Object.isExtensible(x3): false
+y3["p03"]: 3
+y5["p05"]: 200
+[x6["p06"], y6["p06"], z6["p06"]]: 0,2,3
+x9[0]: 2
+x9[1]: undefined
+
+Reached end of Execution -- Exiting.

+ 29 - 0
test/TTBasic/typePromotion.js

@@ -0,0 +1,29 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+//
+// Verify type promotion by creating two types, then adding similar named fields in a different
+// order.  This will verify that the slot indices don't collide between promotions.
+//
+
+var o1 = {},o2 = {};
+
+o1.x = "A";
+o1.y = "B";
+
+o2.y = "C";
+o2.x = "D";
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog(o1.x, true);
+    telemetryLog(o1.y, true);
+    telemetryLog(o2.x, true);
+    telemetryLog(o2.y, true);
+}

+ 4 - 0
test/TTBasic/typePromotionRecord.baseline

@@ -0,0 +1,4 @@
+A
+B
+D
+C

+ 6 - 0
test/TTBasic/typePromotionReplay.baseline

@@ -0,0 +1,6 @@
+A
+B
+D
+C
+
+Reached end of Execution -- Exiting.

+ 133 - 0
test/TTExecuteBasic/enumerable.js

@@ -0,0 +1,133 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+// dump obj through for-in enumerator
+function enumObj(obj, lines) {
+    for (var p in obj) {
+        lines.push("  " + p + ": " + obj[p]);
+    }
+}
+
+// dump obj through for-in enumerator + verify
+function enumAndVerifyObj(obj, lines) {
+    var ctr = 0;
+    for (var p in obj) {
+        var thisl = "  " + p + ": " + obj[p];
+        if(lines[ctr] !== thisl) {
+            telemetryLog(`Failed on ${lines[ctr]} !== ${thisl}`, true);
+        }
+        ctr++;
+    }
+}
+
+// add a bunch of data/attribute properties with different attributes
+function addProp(o, prefix) {
+    Object.defineProperty(o, prefix + "10", {
+        value: "value 10"
+    });
+    Object.defineProperty(o, prefix + "11", {
+        value: "value 11",
+        enumerable: true
+    });
+    Object.defineProperty(o, prefix + "12", {
+        value: "value 12",
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(o, prefix + "13", {
+        value: "value 13",
+        enumerable: true,
+        configurable: true,
+        writable: true
+    });
+
+    Object.defineProperty(o, prefix + "20", {
+        get: function() { return "get 20"; },
+    });
+    Object.defineProperty(o, prefix + "21", {
+        get: function () { return "get 21"; },
+        enumerable: true,
+    });
+    Object.defineProperty(o, prefix + "22", {
+        get: function () { return "get 22"; },
+        enumerable: true,
+        configurable: true
+    });
+
+    Object.defineProperty(o, prefix + "25", {
+        set: function() { echo("do not call 25"); },
+    });
+    Object.defineProperty(o, prefix + "26", {
+        set: function() { echo("do not call 26"); },
+        enumerable: true,
+    });
+    Object.defineProperty(o, prefix + "27", {
+        set: function() { echo("do not call 27"); },
+        enumerable: true,
+        configurable: true
+    });
+}
+
+function testWithObj(o, lines) {
+    addProp(o, "xx");
+    addProp(o, "1");
+    enumObj(o, lines);
+}
+
+var s1 = {abc: -12, def: "hello", 1: undefined, 3: null};
+var l1 = [];
+testWithObj(s1, l1);
+
+var s2 = [-12, "hello", undefined, null];
+var l2 = [];
+testWithObj(s2, l2);
+
+// Test Object.defineProperties, Object.create
+function testPrototype(proto) {
+    Object.defineProperties(proto, {
+        name: { value: "SHOULD_NOT_enumerate_prototype" },
+        0: { get: function() { return "get 0"; } },
+        3: { value: 3 },
+        1: { get: function() { return "get 1"; }, enumerable: true },
+        5: { value: 5, enumerable: true },
+        2: { get: function() { return this.name; }, enumerable: true },
+    });
+
+    return Object.create(proto, {
+        name: { value: "correct_original_instance" },
+        10: { get: function() { return "get 10"; } },
+        13: { value: 13 },
+        11: { get: function() { return "get 11"; }, enumerable: true },
+        15: { value: 15, enumerable: true },
+        12: { get: function() { return this.name; }, enumerable: true },        
+    });
+}
+
+var s3 = testPrototype({});
+var l3 = [];
+testWithObj(s3, l3);
+
+var s4 = testPrototype([]);
+var l4 = [];
+testWithObj(s4, l4);
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog('Testing obj enumeration', true);
+    enumAndVerifyObj(s1, l1);
+
+    telemetryLog('Testing array enumeration', true);
+    enumAndVerifyObj(s2, l2);
+
+    telemetryLog('Testing obj proto enumeration', true);
+    enumAndVerifyObj(s3, l3);
+
+    telemetryLog('Testing array proto enumeration', true);
+    enumAndVerifyObj(s4, l4);
+}

+ 4 - 0
test/TTExecuteBasic/enumerableRecord.baseline

@@ -0,0 +1,4 @@
+Testing obj enumeration
+Testing array enumeration
+Testing obj proto enumeration
+Testing array proto enumeration

+ 6 - 0
test/TTExecuteBasic/enumerableReplay.baseline

@@ -0,0 +1,6 @@
+Testing obj enumeration
+Testing array enumeration
+Testing obj proto enumeration
+Testing array proto enumeration
+
+Reached end of Execution -- Exiting.

+ 206 - 0
test/TTExecuteBasic/enumeratingWithES5.js

@@ -0,0 +1,206 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+var propName = "d";
+var propValue = "dvalue";
+
+function CreateSimpleTypeHandlerObject()
+{
+  var obj = Object.create(null);
+  obj[propName] = propValue;
+  return obj;
+}
+
+function CreateSimpleDictionaryTypeHandlerObject()
+{
+  var obj = {};
+  obj[propName] = propValue;
+  return obj;
+}
+
+function CreateDictionaryTypeHandlerObject()
+{
+  var obj = {};
+  Object.defineProperty(obj, propName,
+    {
+      get : function() {},
+      configurable : true,
+      enumerable : true
+    });
+
+  delete obj[propName];
+  obj[propName] = propValue;
+  return obj;
+}
+
+function TestNonWritable(o)
+{
+  var beforeTestValue = null;
+  var value = 1;
+  value = TestEnumerations(o, beforeTestValue, value);
+
+  SetWritable(o, propName, false);
+  value = TestEnumerations(o, beforeTestValue, value);
+
+  SetWritable(o, propName, true);
+  value = TestEnumerations(o, beforeTestValue, value);
+
+  telemetryLog("Changing writability during enumeration...", true);
+  beforeTestValue = function(o, i, value)
+  {
+    SetWritable(o, propName, false);
+    return value;
+  };
+  value = TestEnumerations(o, beforeTestValue, value);
+
+  beforeTestValue = function(o, i, value)
+  {
+    SetWritable(o, propName, true);
+    return value;
+  };
+  value = TestEnumerations(o, beforeTestValue, value);
+
+  telemetryLog("Freezing object", true);
+  Object.freeze(o);
+  beforeTestValue = null;
+  value = TestEnumerations(o, beforeTestValue, value);
+}
+
+function TestAccessors()
+{
+  var o = { a:"aValue" };
+  DefineAccessor(o, 'b',
+    function() { return "GETTER FOR b"; },
+    function(v) { telemetryLog("SETTER FOR b", true); }
+  );
+  o.c = "cValue";  // to be deleted
+  o.d = "dValue";
+
+  // Throw in a non-enumerable property
+  Object.defineProperty(o, 'e',
+    {
+      value : "eValue",
+      configurable : true,
+      writable : true,
+      enumerable : false
+    });
+  DefineAccessor(o, 'f',
+    function() { return "GETTER FOR f"; },
+    function(v) { telemetryLog("SETTER FOR f", true); }
+  );
+  o.g = "gValue";
+
+  delete o.c;
+
+  var value = 1;
+  var beforeTestValue = null;
+  value = TestEnumerations(o, beforeTestValue, value);
+
+  DefineAccessor(o, propName);  
+  value = TestEnumerations(o, beforeTestValue, value);
+
+  DefineDataProperty(o, propName, value++);
+  value = TestEnumerations(o, beforeTestValue, value);
+
+  telemetryLog("Defining accessor property during enumeration...", true);
+  beforeTestValue = function(o, i, value)
+  {
+    if (i === propName) DefineAccessor(o, propName);
+    return value;
+  };
+
+  value = TestEnumerations(o, beforeTestValue, value);
+
+  telemetryLog("Defining data property during enumeration...", true);
+  beforeTestValue = function(o, i, value)
+  {
+    if (i === propName) DefineDataProperty(o, propName, value);
+    return value + 1;
+  };
+  value = TestEnumerations(o, beforeTestValue, value);
+}
+
+function SetWritable(o, p, v)
+{
+  telemetryLog("Setting writability of " + p + " to " + v, true);
+  Object.defineProperty(o, p, { writable : v });
+}
+
+function DefineAccessor(o, p, getter, setter)
+{
+  if (!getter) getter = function() { return "GETTER"; };
+  if (!setter) setter = function(v) { telemetryLog("SETTER", true); }
+  telemetryLog("Defining accessors for " + p, true);
+  Object.defineProperty(o, p,
+    {
+      get : getter,
+      set : setter,
+      configurable : true,
+      enumerable : true
+    });
+}
+
+function DefineDataProperty(o, p, v)
+{
+  telemetryLog("Defining data property " + p + " with value " + v, true);
+  Object.defineProperty(o, p,
+    {
+      value : v,
+      writable : true,
+      configurable : true,
+      enumerable : true
+    });  
+}
+
+function TestEnumerations(o, beforeTestValue, value)
+{
+  telemetryLog("Testing for-in enumeration", true);
+  for (var i in o)
+  {
+    if (beforeTestValue) value = beforeTestValue(o, i, value);
+    TestValue(o, i, value++);
+  }
+
+  telemetryLog("Testing getOwnPropertyNames enumeration", true);
+  var names = Object.getOwnPropertyNames(o);
+  for (var i = 0; i < names.length; i++)
+  {
+    if (beforeTestValue) value = beforeTestValue(o, i, value);
+    TestValue(o, names[i], value++);
+  }
+
+  return value;
+}
+
+function TestValue(o, i, value)
+{
+  telemetryLog(i + ": " + o[i], true);
+  telemetryLog("Setting value to " + value, true);
+  o[i] = value;
+  telemetryLog(i + ": " + o[i], true);
+}
+
+var th1 = CreateSimpleTypeHandlerObject();
+var th2 = CreateSimpleDictionaryTypeHandlerObject();
+var th3 = CreateDictionaryTypeHandlerObject();
+
+WScript.SetTimeout(testFunction, 50);
+
+/////////////////
+
+function testFunction()
+{
+    telemetryLog("Test 1: Non-writable, simple type handler", true);
+    TestNonWritable(th1);
+
+    telemetryLog("Test 2: Non-writable, simple dictionary type handler", true);
+    TestNonWritable(th2);
+
+    telemetryLog("Test 3: Non-writable, dictionary type handler", true);
+    TestNonWritable(th3);
+
+    telemetryLog("Test 4: Accessors", true);
+    TestAccessors();
+}

+ 379 - 0
test/TTExecuteBasic/enumeratingWithES5Record.baseline

@@ -0,0 +1,379 @@
+Test 1: Non-writable, simple type handler
+Testing for-in enumeration
+d: dvalue
+Setting value to 1
+d: 1
+Testing getOwnPropertyNames enumeration
+d: 1
+Setting value to 2
+d: 2
+Setting writability of d to false
+Testing for-in enumeration
+d: 2
+Setting value to 3
+d: 2
+Testing getOwnPropertyNames enumeration
+d: 2
+Setting value to 4
+d: 2
+Setting writability of d to true
+Testing for-in enumeration
+d: 2
+Setting value to 5
+d: 5
+Testing getOwnPropertyNames enumeration
+d: 5
+Setting value to 6
+d: 6
+Changing writability during enumeration...
+Testing for-in enumeration
+Setting writability of d to false
+d: 6
+Setting value to 7
+d: 6
+Testing getOwnPropertyNames enumeration
+Setting writability of d to false
+d: 6
+Setting value to 8
+d: 6
+Testing for-in enumeration
+Setting writability of d to true
+d: 6
+Setting value to 9
+d: 9
+Testing getOwnPropertyNames enumeration
+Setting writability of d to true
+d: 9
+Setting value to 10
+d: 10
+Freezing object
+Testing for-in enumeration
+d: 10
+Setting value to 11
+d: 10
+Testing getOwnPropertyNames enumeration
+d: 10
+Setting value to 12
+d: 10
+Test 2: Non-writable, simple dictionary type handler
+Testing for-in enumeration
+d: dvalue
+Setting value to 1
+d: 1
+Testing getOwnPropertyNames enumeration
+d: 1
+Setting value to 2
+d: 2
+Setting writability of d to false
+Testing for-in enumeration
+d: 2
+Setting value to 3
+d: 2
+Testing getOwnPropertyNames enumeration
+d: 2
+Setting value to 4
+d: 2
+Setting writability of d to true
+Testing for-in enumeration
+d: 2
+Setting value to 5
+d: 5
+Testing getOwnPropertyNames enumeration
+d: 5
+Setting value to 6
+d: 6
+Changing writability during enumeration...
+Testing for-in enumeration
+Setting writability of d to false
+d: 6
+Setting value to 7
+d: 6
+Testing getOwnPropertyNames enumeration
+Setting writability of d to false
+d: 6
+Setting value to 8
+d: 6
+Testing for-in enumeration
+Setting writability of d to true
+d: 6
+Setting value to 9
+d: 9
+Testing getOwnPropertyNames enumeration
+Setting writability of d to true
+d: 9
+Setting value to 10
+d: 10
+Freezing object
+Testing for-in enumeration
+d: 10
+Setting value to 11
+d: 10
+Testing getOwnPropertyNames enumeration
+d: 10
+Setting value to 12
+d: 10
+Test 3: Non-writable, dictionary type handler
+Testing for-in enumeration
+d: dvalue
+Setting value to 1
+d: 1
+Testing getOwnPropertyNames enumeration
+d: 1
+Setting value to 2
+d: 2
+Setting writability of d to false
+Testing for-in enumeration
+d: 2
+Setting value to 3
+d: 2
+Testing getOwnPropertyNames enumeration
+d: 2
+Setting value to 4
+d: 2
+Setting writability of d to true
+Testing for-in enumeration
+d: 2
+Setting value to 5
+d: 5
+Testing getOwnPropertyNames enumeration
+d: 5
+Setting value to 6
+d: 6
+Changing writability during enumeration...
+Testing for-in enumeration
+Setting writability of d to false
+d: 6
+Setting value to 7
+d: 6
+Testing getOwnPropertyNames enumeration
+Setting writability of d to false
+d: 6
+Setting value to 8
+d: 6
+Testing for-in enumeration
+Setting writability of d to true
+d: 6
+Setting value to 9
+d: 9
+Testing getOwnPropertyNames enumeration
+Setting writability of d to true
+d: 9
+Setting value to 10
+d: 10
+Freezing object
+Testing for-in enumeration
+d: 10
+Setting value to 11
+d: 10
+Testing getOwnPropertyNames enumeration
+d: 10
+Setting value to 12
+d: 10
+Test 4: Accessors
+Defining accessors for b
+Defining accessors for f
+Testing for-in enumeration
+a: aValue
+Setting value to 1
+a: 1
+b: GETTER FOR b
+Setting value to 2
+SETTER FOR b
+b: GETTER FOR b
+d: dValue
+Setting value to 3
+d: 3
+f: GETTER FOR f
+Setting value to 4
+SETTER FOR f
+f: GETTER FOR f
+g: gValue
+Setting value to 5
+g: 5
+Testing getOwnPropertyNames enumeration
+a: 1
+Setting value to 6
+a: 6
+b: GETTER FOR b
+Setting value to 7
+SETTER FOR b
+b: GETTER FOR b
+d: 3
+Setting value to 8
+d: 8
+e: eValue
+Setting value to 9
+e: 9
+f: GETTER FOR f
+Setting value to 10
+SETTER FOR f
+f: GETTER FOR f
+g: 5
+Setting value to 11
+g: 11
+Defining accessors for d
+Testing for-in enumeration
+a: 6
+Setting value to 12
+a: 12
+b: GETTER FOR b
+Setting value to 13
+SETTER FOR b
+b: GETTER FOR b
+d: GETTER
+Setting value to 14
+SETTER
+d: GETTER
+f: GETTER FOR f
+Setting value to 15
+SETTER FOR f
+f: GETTER FOR f
+g: 11
+Setting value to 16
+g: 16
+Testing getOwnPropertyNames enumeration
+a: 12
+Setting value to 17
+a: 17
+b: GETTER FOR b
+Setting value to 18
+SETTER FOR b
+b: GETTER FOR b
+d: GETTER
+Setting value to 19
+SETTER
+d: GETTER
+e: 9
+Setting value to 20
+e: 20
+f: GETTER FOR f
+Setting value to 21
+SETTER FOR f
+f: GETTER FOR f
+g: 16
+Setting value to 22
+g: 22
+Defining data property d with value 23
+Testing for-in enumeration
+a: 17
+Setting value to 24
+a: 24
+b: GETTER FOR b
+Setting value to 25
+SETTER FOR b
+b: GETTER FOR b
+d: 23
+Setting value to 26
+d: 26
+f: GETTER FOR f
+Setting value to 27
+SETTER FOR f
+f: GETTER FOR f
+g: 22
+Setting value to 28
+g: 28
+Testing getOwnPropertyNames enumeration
+a: 24
+Setting value to 29
+a: 29
+b: GETTER FOR b
+Setting value to 30
+SETTER FOR b
+b: GETTER FOR b
+d: 26
+Setting value to 31
+d: 31
+e: 20
+Setting value to 32
+e: 32
+f: GETTER FOR f
+Setting value to 33
+SETTER FOR f
+f: GETTER FOR f
+g: 28
+Setting value to 34
+g: 34
+Defining accessor property during enumeration...
+Testing for-in enumeration
+a: 29
+Setting value to 35
+a: 35
+b: GETTER FOR b
+Setting value to 36
+SETTER FOR b
+b: GETTER FOR b
+Defining accessors for d
+d: GETTER
+Setting value to 37
+SETTER
+d: GETTER
+f: GETTER FOR f
+Setting value to 38
+SETTER FOR f
+f: GETTER FOR f
+g: 34
+Setting value to 39
+g: 39
+Testing getOwnPropertyNames enumeration
+a: 35
+Setting value to 40
+a: 40
+b: GETTER FOR b
+Setting value to 41
+SETTER FOR b
+b: GETTER FOR b
+d: GETTER
+Setting value to 42
+SETTER
+d: GETTER
+e: 32
+Setting value to 43
+e: 43
+f: GETTER FOR f
+Setting value to 44
+SETTER FOR f
+f: GETTER FOR f
+g: 39
+Setting value to 45
+g: 45
+Defining data property during enumeration...
+Testing for-in enumeration
+a: 40
+Setting value to 47
+a: 47
+b: GETTER FOR b
+Setting value to 49
+SETTER FOR b
+b: GETTER FOR b
+Defining data property d with value 50
+d: 50
+Setting value to 51
+d: 51
+f: GETTER FOR f
+Setting value to 53
+SETTER FOR f
+f: GETTER FOR f
+g: 45
+Setting value to 55
+g: 55
+Testing getOwnPropertyNames enumeration
+a: 47
+Setting value to 57
+a: 57
+b: GETTER FOR b
+Setting value to 59
+SETTER FOR b
+b: GETTER FOR b
+d: 51
+Setting value to 61
+d: 61
+e: 43
+Setting value to 63
+e: 63
+f: GETTER FOR f
+Setting value to 65
+SETTER FOR f
+f: GETTER FOR f
+g: 55
+Setting value to 67
+g: 67

+ 381 - 0
test/TTExecuteBasic/enumeratingWithES5Replay.baseline

@@ -0,0 +1,381 @@
+Test 1: Non-writable, simple type handler
+Testing for-in enumeration
+d: dvalue
+Setting value to 1
+d: 1
+Testing getOwnPropertyNames enumeration
+d: 1
+Setting value to 2
+d: 2
+Setting writability of d to false
+Testing for-in enumeration
+d: 2
+Setting value to 3
+d: 2
+Testing getOwnPropertyNames enumeration
+d: 2
+Setting value to 4
+d: 2
+Setting writability of d to true
+Testing for-in enumeration
+d: 2
+Setting value to 5
+d: 5
+Testing getOwnPropertyNames enumeration
+d: 5
+Setting value to 6
+d: 6
+Changing writability during enumeration...
+Testing for-in enumeration
+Setting writability of d to false
+d: 6
+Setting value to 7
+d: 6
+Testing getOwnPropertyNames enumeration
+Setting writability of d to false
+d: 6
+Setting value to 8
+d: 6
+Testing for-in enumeration
+Setting writability of d to true
+d: 6
+Setting value to 9
+d: 9
+Testing getOwnPropertyNames enumeration
+Setting writability of d to true
+d: 9
+Setting value to 10
+d: 10
+Freezing object
+Testing for-in enumeration
+d: 10
+Setting value to 11
+d: 10
+Testing getOwnPropertyNames enumeration
+d: 10
+Setting value to 12
+d: 10
+Test 2: Non-writable, simple dictionary type handler
+Testing for-in enumeration
+d: dvalue
+Setting value to 1
+d: 1
+Testing getOwnPropertyNames enumeration
+d: 1
+Setting value to 2
+d: 2
+Setting writability of d to false
+Testing for-in enumeration
+d: 2
+Setting value to 3
+d: 2
+Testing getOwnPropertyNames enumeration
+d: 2
+Setting value to 4
+d: 2
+Setting writability of d to true
+Testing for-in enumeration
+d: 2
+Setting value to 5
+d: 5
+Testing getOwnPropertyNames enumeration
+d: 5
+Setting value to 6
+d: 6
+Changing writability during enumeration...
+Testing for-in enumeration
+Setting writability of d to false
+d: 6
+Setting value to 7
+d: 6
+Testing getOwnPropertyNames enumeration
+Setting writability of d to false
+d: 6
+Setting value to 8
+d: 6
+Testing for-in enumeration
+Setting writability of d to true
+d: 6
+Setting value to 9
+d: 9
+Testing getOwnPropertyNames enumeration
+Setting writability of d to true
+d: 9
+Setting value to 10
+d: 10
+Freezing object
+Testing for-in enumeration
+d: 10
+Setting value to 11
+d: 10
+Testing getOwnPropertyNames enumeration
+d: 10
+Setting value to 12
+d: 10
+Test 3: Non-writable, dictionary type handler
+Testing for-in enumeration
+d: dvalue
+Setting value to 1
+d: 1
+Testing getOwnPropertyNames enumeration
+d: 1
+Setting value to 2
+d: 2
+Setting writability of d to false
+Testing for-in enumeration
+d: 2
+Setting value to 3
+d: 2
+Testing getOwnPropertyNames enumeration
+d: 2
+Setting value to 4
+d: 2
+Setting writability of d to true
+Testing for-in enumeration
+d: 2
+Setting value to 5
+d: 5
+Testing getOwnPropertyNames enumeration
+d: 5
+Setting value to 6
+d: 6
+Changing writability during enumeration...
+Testing for-in enumeration
+Setting writability of d to false
+d: 6
+Setting value to 7
+d: 6
+Testing getOwnPropertyNames enumeration
+Setting writability of d to false
+d: 6
+Setting value to 8
+d: 6
+Testing for-in enumeration
+Setting writability of d to true
+d: 6
+Setting value to 9
+d: 9
+Testing getOwnPropertyNames enumeration
+Setting writability of d to true
+d: 9
+Setting value to 10
+d: 10
+Freezing object
+Testing for-in enumeration
+d: 10
+Setting value to 11
+d: 10
+Testing getOwnPropertyNames enumeration
+d: 10
+Setting value to 12
+d: 10
+Test 4: Accessors
+Defining accessors for b
+Defining accessors for f
+Testing for-in enumeration
+a: aValue
+Setting value to 1
+a: 1
+b: GETTER FOR b
+Setting value to 2
+SETTER FOR b
+b: GETTER FOR b
+d: dValue
+Setting value to 3
+d: 3
+f: GETTER FOR f
+Setting value to 4
+SETTER FOR f
+f: GETTER FOR f
+g: gValue
+Setting value to 5
+g: 5
+Testing getOwnPropertyNames enumeration
+a: 1
+Setting value to 6
+a: 6
+b: GETTER FOR b
+Setting value to 7
+SETTER FOR b
+b: GETTER FOR b
+d: 3
+Setting value to 8
+d: 8
+e: eValue
+Setting value to 9
+e: 9
+f: GETTER FOR f
+Setting value to 10
+SETTER FOR f
+f: GETTER FOR f
+g: 5
+Setting value to 11
+g: 11
+Defining accessors for d
+Testing for-in enumeration
+a: 6
+Setting value to 12
+a: 12
+b: GETTER FOR b
+Setting value to 13
+SETTER FOR b
+b: GETTER FOR b
+d: GETTER
+Setting value to 14
+SETTER
+d: GETTER
+f: GETTER FOR f
+Setting value to 15
+SETTER FOR f
+f: GETTER FOR f
+g: 11
+Setting value to 16
+g: 16
+Testing getOwnPropertyNames enumeration
+a: 12
+Setting value to 17
+a: 17
+b: GETTER FOR b
+Setting value to 18
+SETTER FOR b
+b: GETTER FOR b
+d: GETTER
+Setting value to 19
+SETTER
+d: GETTER
+e: 9
+Setting value to 20
+e: 20
+f: GETTER FOR f
+Setting value to 21
+SETTER FOR f
+f: GETTER FOR f
+g: 16
+Setting value to 22
+g: 22
+Defining data property d with value 23
+Testing for-in enumeration
+a: 17
+Setting value to 24
+a: 24
+b: GETTER FOR b
+Setting value to 25
+SETTER FOR b
+b: GETTER FOR b
+d: 23
+Setting value to 26
+d: 26
+f: GETTER FOR f
+Setting value to 27
+SETTER FOR f
+f: GETTER FOR f
+g: 22
+Setting value to 28
+g: 28
+Testing getOwnPropertyNames enumeration
+a: 24
+Setting value to 29
+a: 29
+b: GETTER FOR b
+Setting value to 30
+SETTER FOR b
+b: GETTER FOR b
+d: 26
+Setting value to 31
+d: 31
+e: 20
+Setting value to 32
+e: 32
+f: GETTER FOR f
+Setting value to 33
+SETTER FOR f
+f: GETTER FOR f
+g: 28
+Setting value to 34
+g: 34
+Defining accessor property during enumeration...
+Testing for-in enumeration
+a: 29
+Setting value to 35
+a: 35
+b: GETTER FOR b
+Setting value to 36
+SETTER FOR b
+b: GETTER FOR b
+Defining accessors for d
+d: GETTER
+Setting value to 37
+SETTER
+d: GETTER
+f: GETTER FOR f
+Setting value to 38
+SETTER FOR f
+f: GETTER FOR f
+g: 34
+Setting value to 39
+g: 39
+Testing getOwnPropertyNames enumeration
+a: 35
+Setting value to 40
+a: 40
+b: GETTER FOR b
+Setting value to 41
+SETTER FOR b
+b: GETTER FOR b
+d: GETTER
+Setting value to 42
+SETTER
+d: GETTER
+e: 32
+Setting value to 43
+e: 43
+f: GETTER FOR f
+Setting value to 44
+SETTER FOR f
+f: GETTER FOR f
+g: 39
+Setting value to 45
+g: 45
+Defining data property during enumeration...
+Testing for-in enumeration
+a: 40
+Setting value to 47
+a: 47
+b: GETTER FOR b
+Setting value to 49
+SETTER FOR b
+b: GETTER FOR b
+Defining data property d with value 50
+d: 50
+Setting value to 51
+d: 51
+f: GETTER FOR f
+Setting value to 53
+SETTER FOR f
+f: GETTER FOR f
+g: 45
+Setting value to 55
+g: 55
+Testing getOwnPropertyNames enumeration
+a: 47
+Setting value to 57
+a: 57
+b: GETTER FOR b
+Setting value to 59
+SETTER FOR b
+b: GETTER FOR b
+d: 51
+Setting value to 61
+d: 61
+e: 43
+Setting value to 63
+e: 63
+f: GETTER FOR f
+Setting value to 65
+SETTER FOR f
+f: GETTER FOR f
+g: 55
+Setting value to 67
+g: 67
+
+Reached end of Execution -- Exiting.

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików