// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Flags: --allow-natives-syntax const MIN_DICTIONARY_INDEX = 8192; function ArrayTests() { (function ToStringThrows() { function TestError() {} let callCount = 0; const toStringThrows = { toString() { callCount++; throw new TestError; } }; const a = [toStringThrows]; assertThrows(() => a.join(), TestError); assertSame(1, callCount); // Verifies cycle detection still works properly after thrown error. a[0] = 1; a[1] = 2; assertSame('1,2', a.join()); })(); (function ArrayLengthIncreased() { let callCount = 0; const a = [ { toString() { callCount++; a.push(2); return '1'; } } ]; assertSame('1', a.join()); assertSame(1, callCount); assertSame('1,2', a.join()); })(); (function ArrayLengthDecreased() { let callCount = 0; const a = [ { toString() { callCount++; a.pop(); return '1'; } }, '2' ]; assertSame('1,', a.join()); assertSame(1, callCount); assertSame('1', a.join()); })(); (function ElementsKindChangedToHoley() { let callCount = 0; const a = [ { toString() { callCount++; a.length = 4; a[1] = 777; a[2] = 7.7; return '1'; } }, 2, 3 ]; assertSame('1,777,7.7', a.join()); assertSame(1, callCount); assertSame('1,777,7.7,', a.join()); })(); (function ElementsKindChangedToHoleyThroughDeletion() { let callCount = 0; const a = [ { toString() { callCount++; delete a[1]; a[2] = 7.7; return '1'; } }, 2, 3 ]; assertSame('1,,7.7', a.join()); assertSame(1, callCount); assertSame('1,,7.7', a.join()); })(); (function NumberDictionaryChanged() { let callCount = 0; const a = []; a[MIN_DICTIONARY_INDEX - 1] = { toString() { callCount++; a[MIN_DICTIONARY_INDEX] = '2'; return '1'; } }; a[MIN_DICTIONARY_INDEX] = 'NOPE'; assertTrue(%HasDictionaryElements(a)); assertSame('12', a.join('')); assertSame(1, callCount); assertSame('12', a.join('')); })(); (function NumberDictionaryLengthChange() { let callCount = 0; const a = []; a[MIN_DICTIONARY_INDEX - 1] = { toString() { callCount++; a.length = MIN_DICTIONARY_INDEX; return '1'; } }; a[MIN_DICTIONARY_INDEX] = '2'; assertTrue(%HasDictionaryElements(a)); assertSame('1', a.join('')); assertSame(1, callCount); assertSame('1', a.join('')); })(); } (function NonArrayCycleDetection() { const a = { length: 3, toString() { return Array.prototype.join.call(this); } }; a[0] = '1'; a[1] = a; a[2] = '3'; assertSame("1,,3", Array.prototype.join.call(a)); }); ArrayTests(); %SetForceSlowPath(true); ArrayTests();