Revision: 22960
Author: [email protected]
Date: Thu Aug 7 08:39:21 2014 UTC
Log: Version 3.28.62 (based on bleeding_edge revision r22958)
Only escape U+0022 in argument values of `String.prototype` HTML methods
(issue 2217).
Update webkit test for expected own properties.
This implements unscopables (issue 3401).
Add `CheckObjectCoercible` for the `String.prototype` HTML methods (issue
2218).
Add initial support for compiler unit tests using GTest/GMock (issue 3489).
Trigger exception debug events on Promise reject (Chromium issue 393913).
Refactor unit tests for the base library to use GTest (issue 3489).
Performance and stability improvements on all platforms.
http://code.google.com/p/v8/source/detail?r=22960
Added:
/trunk/src/unscopables.js
/trunk/test/base-unittests
/trunk/test/base-unittests/DEPS
/trunk/test/base-unittests/base-unittests.gyp
/trunk/test/base-unittests/base-unittests.status
/trunk/test/base-unittests/cpu-unittest.cc
/trunk/test/base-unittests/platform
/trunk/test/base-unittests/platform/condition-variable-unittest.cc
/trunk/test/base-unittests/platform/mutex-unittest.cc
/trunk/test/base-unittests/platform/platform-unittest.cc
/trunk/test/base-unittests/platform/time-unittest.cc
/trunk/test/base-unittests/testcfg.py
/trunk/test/base-unittests/utils
/trunk/test/base-unittests/utils/random-number-generator-unittest.cc
/trunk/test/cctest/test-unscopables-hidden-prototype.cc
/trunk/test/mjsunit/es6/debug-promises
/trunk/test/mjsunit/es6/debug-promises/async-task-event.js
/trunk/test/mjsunit/es6/debug-promises/events.js
/trunk/test/mjsunit/es6/debug-promises/reentry.js
/trunk/test/mjsunit/es6/debug-promises/reject-after-resolve.js
/trunk/test/mjsunit/es6/debug-promises/reject-caught-all.js
/trunk/test/mjsunit/es6/debug-promises/reject-caught-late.js
/trunk/test/mjsunit/es6/debug-promises/reject-caught-uncaught.js
/trunk/test/mjsunit/es6/debug-promises/reject-in-constructor.js
/trunk/test/mjsunit/es6/debug-promises/reject-uncaught-all.js
/trunk/test/mjsunit/es6/debug-promises/reject-uncaught-late.js
/trunk/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js
/trunk/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js
/trunk/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js
/trunk/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js
/trunk/test/mjsunit/es6/debug-promises/throw-caught-all.js
/trunk/test/mjsunit/es6/debug-promises/throw-caught-late.js
/trunk/test/mjsunit/es6/debug-promises/throw-caught-uncaught.js
/trunk/test/mjsunit/es6/debug-promises/throw-in-constructor.js
/trunk/test/mjsunit/es6/debug-promises/throw-uncaught-all.js
/trunk/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js
/trunk/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js
/trunk/test/mjsunit/es6/debug-promises/throw-with-undefined-reject.js
/trunk/test/mjsunit/es6/debug-promises/try-reject-in-constructor.js
/trunk/test/mjsunit/es6/debug-promises/try-throw-reject-in-constructor.js
/trunk/test/mjsunit/es6/string-html.js
/trunk/test/mjsunit/harmony/proxies-with-unscopables.js
/trunk/test/mjsunit/harmony/unscopables.js
/trunk/test/mjsunit/runtime-gen/debugpoppromise.js
/trunk/test/mjsunit/runtime-gen/debugpromiserejectevent.js
/trunk/test/mjsunit/runtime-gen/debugpushpromise.js
/trunk/test/mjsunit/runtime-gen/rempio2.js
/trunk/third_party
/trunk/third_party/fdlibm
/trunk/third_party/fdlibm/LICENSE
/trunk/third_party/fdlibm/README.v8
/trunk/third_party/fdlibm/fdlibm.cc
/trunk/third_party/fdlibm/fdlibm.h
/trunk/third_party/fdlibm/fdlibm.js
/trunk/tools/external-reference-check.py
Deleted:
/trunk/src/trig-table.h
/trunk/test/cctest/test-condition-variable.cc
/trunk/test/cctest/test-cpu-ia32.cc
/trunk/test/cctest/test-cpu-x64.cc
/trunk/test/cctest/test-cpu-x87.cc
/trunk/test/cctest/test-cpu.cc
/trunk/test/cctest/test-mutex.cc
/trunk/test/cctest/test-platform-macos.cc
/trunk/test/cctest/test-platform-tls.cc
/trunk/test/cctest/test-time.cc
/trunk/test/mjsunit/es6/debug-promise-events.js
/trunk/test/mjsunit/es6/debug-promises-async-task-event.js
/trunk/test/mjsunit/es6/debug-promises-caught-all.js
/trunk/test/mjsunit/es6/debug-promises-caught-late.js
/trunk/test/mjsunit/es6/debug-promises-caught-uncaught.js
/trunk/test/mjsunit/es6/debug-promises-reentry.js
/trunk/test/mjsunit/es6/debug-promises-throw-in-constructor.js
/trunk/test/mjsunit/es6/debug-promises-throw-in-reject.js
/trunk/test/mjsunit/es6/debug-promises-uncaught-all.js
/trunk/test/mjsunit/es6/debug-promises-uncaught-uncaught.js
/trunk/test/mjsunit/es6/debug-promises-undefined-reject.js
/trunk/test/mjsunit/runtime-gen/debugpromisehandleepilogue.js
/trunk/test/mjsunit/runtime-gen/debugpromisehandleprologue.js
/trunk/tools/generate-trig-table.py
Modified:
/trunk/.gitignore
/trunk/BUILD.gn
/trunk/ChangeLog
/trunk/DEPS
/trunk/PRESUBMIT.py
/trunk/build/all.gyp
/trunk/src/arm/assembler-arm-inl.h
/trunk/src/arm/assembler-arm.cc
/trunk/src/arm/assembler-arm.h
/trunk/src/arm/codegen-arm.cc
/trunk/src/arm/stub-cache-arm.cc
/trunk/src/arm64/assembler-arm64-inl.h
/trunk/src/arm64/assembler-arm64.cc
/trunk/src/arm64/assembler-arm64.h
/trunk/src/arm64/codegen-arm64.cc
/trunk/src/arm64/macro-assembler-arm64.h
/trunk/src/arm64/stub-cache-arm64.cc
/trunk/src/assembler.cc
/trunk/src/assembler.h
/trunk/src/bootstrapper.cc
/trunk/src/checks.h
/trunk/src/code-stubs-hydrogen.cc
/trunk/src/code-stubs.cc
/trunk/src/code-stubs.h
/trunk/src/compiler/ast-graph-builder.cc
/trunk/src/compiler/ast-graph-builder.h
/trunk/src/compiler/code-generator.cc
/trunk/src/compiler/code-generator.h
/trunk/src/compiler/common-operator.h
/trunk/src/compiler/instruction-selector.cc
/trunk/src/compiler/instruction-selector.h
/trunk/src/compiler/instruction.cc
/trunk/src/compiler/instruction.h
/trunk/src/compiler/js-generic-lowering.cc
/trunk/src/compiler/js-operator.h
/trunk/src/compiler/js-typed-lowering.h
/trunk/src/compiler/opcodes.h
/trunk/src/compiler/typer.cc
/trunk/src/compiler.h
/trunk/src/contexts.cc
/trunk/src/contexts.h
/trunk/src/debug.cc
/trunk/src/debug.h
/trunk/src/deoptimizer.cc
/trunk/src/field-index.h
/trunk/src/flag-definitions.h
/trunk/src/ia32/assembler-ia32-inl.h
/trunk/src/ia32/assembler-ia32.cc
/trunk/src/ia32/assembler-ia32.h
/trunk/src/ia32/codegen-ia32.cc
/trunk/src/ia32/disasm-ia32.cc
/trunk/src/ia32/macro-assembler-ia32.cc
/trunk/src/ia32/stub-cache-ia32.cc
/trunk/src/ic.cc
/trunk/src/isolate.cc
/trunk/src/isolate.h
/trunk/src/lookup.cc
/trunk/src/lookup.h
/trunk/src/math.js
/trunk/src/mips/assembler-mips-inl.h
/trunk/src/mips/assembler-mips.cc
/trunk/src/mips/assembler-mips.h
/trunk/src/mips/codegen-mips.cc
/trunk/src/mips/stub-cache-mips.cc
/trunk/src/mips64/assembler-mips64-inl.h
/trunk/src/mips64/assembler-mips64.cc
/trunk/src/mips64/assembler-mips64.h
/trunk/src/mips64/codegen-mips64.cc
/trunk/src/mips64/stub-cache-mips64.cc
/trunk/src/objects-inl.h
/trunk/src/objects.h
/trunk/src/parser.h
/trunk/src/preparser.h
/trunk/src/promise.js
/trunk/src/runtime.cc
/trunk/src/runtime.h
/trunk/src/serialize.cc
/trunk/src/serialize.h
/trunk/src/string.js
/trunk/src/stub-cache.cc
/trunk/src/stub-cache.h
/trunk/src/symbol.js
/trunk/src/types.cc
/trunk/src/types.h
/trunk/src/version.cc
/trunk/src/x64/assembler-x64-inl.h
/trunk/src/x64/assembler-x64.cc
/trunk/src/x64/assembler-x64.h
/trunk/src/x64/codegen-x64.cc
/trunk/src/x64/stub-cache-x64.cc
/trunk/src/x87/assembler-x87-inl.h
/trunk/src/x87/assembler-x87.cc
/trunk/src/x87/assembler-x87.h
/trunk/src/x87/disasm-x87.cc
/trunk/src/x87/macro-assembler-x87.cc
/trunk/src/x87/stub-cache-x87.cc
/trunk/test/cctest/cctest.gyp
/trunk/test/cctest/cctest.status
/trunk/test/cctest/compiler/test-codegen-deopt.cc
/trunk/test/cctest/compiler/test-run-deopt.cc
/trunk/test/cctest/compiler/test-scheduler.cc
/trunk/test/cctest/test-platform-linux.cc
/trunk/test/cctest/test-platform-win32.cc
/trunk/test/cctest/test-random-number-generator.cc
/trunk/test/cctest/test-serialize.cc
/trunk/test/cctest/test-threads.cc
/trunk/test/cctest/test-types.cc
/trunk/test/mjsunit/debug-script.js
/trunk/test/mjsunit/es6/symbols.js
/trunk/test/mjsunit/mirror-script.js
/trunk/test/mjsunit/mjsunit.status
/trunk/test/mjsunit/sin-cos.js
/trunk/test/test262/test262.status
/trunk/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
/trunk/test/webkit/fast/js/Object-getOwnPropertyNames.js
/trunk/test/webkit/fast/js/string-anchor-expected.txt
/trunk/test/webkit/fast/js/string-fontcolor-expected.txt
/trunk/test/webkit/fast/js/string-fontsize-expected.txt
/trunk/test/webkit/fast/js/string-link-expected.txt
/trunk/test/webkit/webkit.status
/trunk/testing/gtest.gyp
/trunk/tools/generate-runtime-tests.py
/trunk/tools/gyp/v8.gyp
/trunk/tools/js2c.py
/trunk/tools/presubmit.py
/trunk/tools/run-tests.py
/trunk/tools/whitespace.txt
=======================================
--- /dev/null
+++ /trunk/src/unscopables.js Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,39 @@
+// Copyright 2014 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.
+
+'use strict';
+
+// This file relies on the fact that the following declaration has been
made.
+// var $Array = global.Array;
+// var $Symbol = global.Symbol;
+
+function ExtendSymbol() {
+ %CheckIsBootstrapping();
+ InstallConstants($Symbol, $Array(
+ "unscopables", symbolUnscopables
+ ));
+}
+
+ExtendSymbol();
+
+
+var arrayUnscopables = {
+ __proto__: null,
+ copyWithin: true,
+ entries: true,
+ fill: true,
+ find: true,
+ findIndex: true,
+ keys: true,
+ values: true,
+};
+
+
+function ExtendArrayPrototype() {
+ %CheckIsBootstrapping();
+ %AddNamedProperty($Array.prototype, symbolUnscopables, arrayUnscopables,
+ DONT_ENUM | READ_ONLY);
+}
+
+ExtendArrayPrototype();
=======================================
--- /dev/null
+++ /trunk/test/base-unittests/DEPS Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,8 @@
+include_rules = [
+ "-include",
+ "+include/v8config.h",
+ "+include/v8stdint.h",
+ "-src",
+ "+src/base",
+ "+testing",
+]
=======================================
--- /dev/null
+++ /trunk/test/base-unittests/base-unittests.gyp Thu Aug 7 08:39:21 2014
UTC
@@ -0,0 +1,32 @@
+# Copyright 2014 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.
+
+{
+ 'variables': {
+ 'v8_code': 1,
+ },
+ 'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
+ 'targets': [
+ {
+ 'target_name': 'base-unittests',
+ 'type': 'executable',
+ 'dependencies': [
+ '../../testing/gtest.gyp:gtest',
+ '../../testing/gtest.gyp:gtest_main',
+ '../../tools/gyp/v8.gyp:v8_libbase',
+ ],
+ 'include_dirs': [
+ '../..',
+ ],
+ 'sources': [ ### gcmole(all) ###
+ 'cpu-unittest.cc',
+ 'platform/condition-variable-unittest.cc',
+ 'platform/mutex-unittest.cc',
+ 'platform/platform-unittest.cc',
+ 'platform/time-unittest.cc',
+ 'utils/random-number-generator-unittest.cc',
+ ],
+ },
+ ],
+}
=======================================
--- /dev/null
+++ /trunk/test/base-unittests/base-unittests.status Thu Aug 7 08:39:21
2014 UTC
@@ -0,0 +1,6 @@
+# Copyright 2014 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.
+
+[
+]
=======================================
--- /dev/null
+++ /trunk/test/base-unittests/cpu-unittest.cc Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,49 @@
+// Copyright 2014 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.
+
+#include "src/base/cpu.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+TEST(CPUTest, FeatureImplications) {
+ CPU cpu;
+
+ // ia32 and x64 features
+ EXPECT_TRUE(!cpu.has_sse() || cpu.has_mmx());
+ EXPECT_TRUE(!cpu.has_sse2() || cpu.has_sse());
+ EXPECT_TRUE(!cpu.has_sse3() || cpu.has_sse2());
+ EXPECT_TRUE(!cpu.has_ssse3() || cpu.has_sse3());
+ EXPECT_TRUE(!cpu.has_sse41() || cpu.has_sse3());
+ EXPECT_TRUE(!cpu.has_sse42() || cpu.has_sse41());
+
+ // arm features
+ EXPECT_TRUE(!cpu.has_vfp3_d32() || cpu.has_vfp3());
+}
+
+
+TEST(CPUTest, RequiredFeatures) {
+ CPU cpu;
+
+#if V8_HOST_ARCH_ARM
+ EXPECT_TRUE(cpu.has_fpu());
+#endif
+
+#if V8_HOST_ARCH_IA32
+ EXPECT_TRUE(cpu.has_fpu());
+ EXPECT_TRUE(cpu.has_sahf());
+#endif
+
+#if V8_HOST_ARCH_X64
+ EXPECT_TRUE(cpu.has_fpu());
+ EXPECT_TRUE(cpu.has_cmov());
+ EXPECT_TRUE(cpu.has_mmx());
+ EXPECT_TRUE(cpu.has_sse());
+ EXPECT_TRUE(cpu.has_sse2());
+#endif
+}
+
+} // namespace base
+} // namespace v8
=======================================
--- /dev/null
+++ /trunk/test/base-unittests/platform/condition-variable-unittest.cc Thu
Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,296 @@
+// Copyright 2014 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.
+
+#include "src/base/platform/condition-variable.h"
+
+#include "src/base/platform/platform.h"
+#include "src/base/platform/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+TEST(ConditionVariable, WaitForAfterNofityOnSameThread) {
+ for (int n = 0; n < 10; ++n) {
+ Mutex mutex;
+ ConditionVariable cv;
+
+ LockGuard<Mutex> lock_guard(&mutex);
+
+ cv.NotifyOne();
+ EXPECT_FALSE(cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n)));
+
+ cv.NotifyAll();
+ EXPECT_FALSE(cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n)));
+ }
+}
+
+
+namespace {
+
+class ThreadWithMutexAndConditionVariable V8_FINAL : public Thread {
+ public:
+ ThreadWithMutexAndConditionVariable()
+ : Thread("ThreadWithMutexAndConditionVariable"),
+ running_(false), finished_(false) {}
+ virtual ~ThreadWithMutexAndConditionVariable() {}
+
+ virtual void Run() V8_OVERRIDE {
+ LockGuard<Mutex> lock_guard(&mutex_);
+ running_ = true;
+ cv_.NotifyOne();
+ while (running_) {
+ cv_.Wait(&mutex_);
+ }
+ finished_ = true;
+ cv_.NotifyAll();
+ }
+
+ bool running_;
+ bool finished_;
+ ConditionVariable cv_;
+ Mutex mutex_;
+};
+
+}
+
+
+TEST(ConditionVariable, MultipleThreadsWithSeparateConditionVariables) {
+ static const int kThreadCount = 128;
+ ThreadWithMutexAndConditionVariable threads[kThreadCount];
+
+ for (int n = 0; n < kThreadCount; ++n) {
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ EXPECT_FALSE(threads[n].running_);
+ EXPECT_FALSE(threads[n].finished_);
+ threads[n].Start();
+ // Wait for nth thread to start.
+ while (!threads[n].running_) {
+ threads[n].cv_.Wait(&threads[n].mutex_);
+ }
+ }
+
+ for (int n = kThreadCount - 1; n >= 0; --n) {
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ EXPECT_TRUE(threads[n].running_);
+ EXPECT_FALSE(threads[n].finished_);
+ }
+
+ for (int n = 0; n < kThreadCount; ++n) {
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ EXPECT_TRUE(threads[n].running_);
+ EXPECT_FALSE(threads[n].finished_);
+ // Tell the nth thread to quit.
+ threads[n].running_ = false;
+ threads[n].cv_.NotifyOne();
+ }
+
+ for (int n = kThreadCount - 1; n >= 0; --n) {
+ // Wait for nth thread to quit.
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ while (!threads[n].finished_) {
+ threads[n].cv_.Wait(&threads[n].mutex_);
+ }
+ EXPECT_FALSE(threads[n].running_);
+ EXPECT_TRUE(threads[n].finished_);
+ }
+
+ for (int n = 0; n < kThreadCount; ++n) {
+ threads[n].Join();
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ EXPECT_FALSE(threads[n].running_);
+ EXPECT_TRUE(threads[n].finished_);
+ }
+}
+
+
+namespace {
+
+class ThreadWithSharedMutexAndConditionVariable V8_FINAL : public Thread {
+ public:
+ ThreadWithSharedMutexAndConditionVariable()
+ : Thread("ThreadWithSharedMutexAndConditionVariable"),
+ running_(false), finished_(false), cv_(NULL), mutex_(NULL) {}
+ virtual ~ThreadWithSharedMutexAndConditionVariable() {}
+
+ virtual void Run() V8_OVERRIDE {
+ LockGuard<Mutex> lock_guard(mutex_);
+ running_ = true;
+ cv_->NotifyAll();
+ while (running_) {
+ cv_->Wait(mutex_);
+ }
+ finished_ = true;
+ cv_->NotifyAll();
+ }
+
+ bool running_;
+ bool finished_;
+ ConditionVariable* cv_;
+ Mutex* mutex_;
+};
+
+}
+
+
+TEST(ConditionVariable,
MultipleThreadsWithSharedSeparateConditionVariables) {
+ static const int kThreadCount = 128;
+ ThreadWithSharedMutexAndConditionVariable threads[kThreadCount];
+ ConditionVariable cv;
+ Mutex mutex;
+
+ for (int n = 0; n < kThreadCount; ++n) {
+ threads[n].mutex_ = &mutex;
+ threads[n].cv_ = &cv;
+ }
+
+ // Start all threads.
+ {
+ LockGuard<Mutex> lock_guard(&mutex);
+ for (int n = 0; n < kThreadCount; ++n) {
+ EXPECT_FALSE(threads[n].running_);
+ EXPECT_FALSE(threads[n].finished_);
+ threads[n].Start();
+ }
+ }
+
+ // Wait for all threads to start.
+ {
+ LockGuard<Mutex> lock_guard(&mutex);
+ for (int n = kThreadCount - 1; n >= 0; --n) {
+ while (!threads[n].running_) {
+ cv.Wait(&mutex);
+ }
+ }
+ }
+
+ // Make sure that all threads are running.
+ {
+ LockGuard<Mutex> lock_guard(&mutex);
+ for (int n = 0; n < kThreadCount; ++n) {
+ EXPECT_TRUE(threads[n].running_);
+ EXPECT_FALSE(threads[n].finished_);
+ }
+ }
+
+ // Tell all threads to quit.
+ {
+ LockGuard<Mutex> lock_guard(&mutex);
+ for (int n = kThreadCount - 1; n >= 0; --n) {
+ EXPECT_TRUE(threads[n].running_);
+ EXPECT_FALSE(threads[n].finished_);
+ // Tell the nth thread to quit.
+ threads[n].running_ = false;
+ }
+ cv.NotifyAll();
+ }
+
+ // Wait for all threads to quit.
+ {
+ LockGuard<Mutex> lock_guard(&mutex);
+ for (int n = 0; n < kThreadCount; ++n) {
+ while (!threads[n].finished_) {
+ cv.Wait(&mutex);
+ }
+ }
+ }
+
+ // Make sure all threads are finished.
+ {
+ LockGuard<Mutex> lock_guard(&mutex);
+ for (int n = kThreadCount - 1; n >= 0; --n) {
+ EXPECT_FALSE(threads[n].running_);
+ EXPECT_TRUE(threads[n].finished_);
+ }
+ }
+
+ // Join all threads.
+ for (int n = 0; n < kThreadCount; ++n) {
+ threads[n].Join();
+ }
+}
+
+
+namespace {
+
+class LoopIncrementThread V8_FINAL : public Thread {
+ public:
+ LoopIncrementThread(int rem,
+ int* counter,
+ int limit,
+ int thread_count,
+ ConditionVariable* cv,
+ Mutex* mutex)
+ : Thread("LoopIncrementThread"), rem_(rem), counter_(counter),
+ limit_(limit), thread_count_(thread_count), cv_(cv), mutex_(mutex)
{
+ EXPECT_LT(rem, thread_count);
+ EXPECT_EQ(0, limit % thread_count);
+ }
+
+ virtual void Run() V8_OVERRIDE {
+ int last_count = -1;
+ while (true) {
+ LockGuard<Mutex> lock_guard(mutex_);
+ int count = *counter_;
+ while (count % thread_count_ != rem_ && count < limit_) {
+ cv_->Wait(mutex_);
+ count = *counter_;
+ }
+ if (count >= limit_) break;
+ EXPECT_EQ(*counter_, count);
+ if (last_count != -1) {
+ EXPECT_EQ(last_count + (thread_count_ - 1), count);
+ }
+ count++;
+ *counter_ = count;
+ last_count = count;
+ cv_->NotifyAll();
+ }
+ }
+
+ private:
+ const int rem_;
+ int* counter_;
+ const int limit_;
+ const int thread_count_;
+ ConditionVariable* cv_;
+ Mutex* mutex_;
+};
+
+}
+
+
+TEST(ConditionVariable, LoopIncrement) {
+ static const int kMaxThreadCount = 16;
+ Mutex mutex;
+ ConditionVariable cv;
+ for (int thread_count = 1; thread_count < kMaxThreadCount;
++thread_count) {
+ int limit = thread_count * 10;
+ int counter = 0;
+
+ // Setup the threads.
+ Thread** threads = new Thread*[thread_count];
+ for (int n = 0; n < thread_count; ++n) {
+ threads[n] = new LoopIncrementThread(
+ n, &counter, limit, thread_count, &cv, &mutex);
+ }
+
+ // Start all threads.
+ for (int n = thread_count - 1; n >= 0; --n) {
+ threads[n]->Start();
+ }
+
+ // Join and cleanup all threads.
+ for (int n = 0; n < thread_count; ++n) {
+ threads[n]->Join();
+ delete threads[n];
+ }
+ delete[] threads;
+
+ EXPECT_EQ(limit, counter);
+ }
+}
+
+} // namespace base
+} // namespace v8
=======================================
--- /dev/null
+++ /trunk/test/base-unittests/platform/mutex-unittest.cc Thu Aug 7
08:39:21 2014 UTC
@@ -0,0 +1,91 @@
+// Copyright 2014 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.
+
+#include "src/base/platform/mutex.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+TEST(Mutex, LockGuardMutex) {
+ Mutex mutex;
+ { LockGuard<Mutex> lock_guard(&mutex); }
+ { LockGuard<Mutex> lock_guard(&mutex); }
+}
+
+
+TEST(Mutex, LockGuardRecursiveMutex) {
+ RecursiveMutex recursive_mutex;
+ { LockGuard<RecursiveMutex> lock_guard(&recursive_mutex); }
+ {
+ LockGuard<RecursiveMutex> lock_guard1(&recursive_mutex);
+ LockGuard<RecursiveMutex> lock_guard2(&recursive_mutex);
+ }
+}
+
+
+TEST(Mutex, LockGuardLazyMutex) {
+ LazyMutex lazy_mutex = LAZY_MUTEX_INITIALIZER;
+ { LockGuard<Mutex> lock_guard(lazy_mutex.Pointer()); }
+ { LockGuard<Mutex> lock_guard(lazy_mutex.Pointer()); }
+}
+
+
+TEST(Mutex, LockGuardLazyRecursiveMutex) {
+ LazyRecursiveMutex lazy_recursive_mutex =
LAZY_RECURSIVE_MUTEX_INITIALIZER;
+ { LockGuard<RecursiveMutex> lock_guard(lazy_recursive_mutex.Pointer()); }
+ {
+ LockGuard<RecursiveMutex> lock_guard1(lazy_recursive_mutex.Pointer());
+ LockGuard<RecursiveMutex> lock_guard2(lazy_recursive_mutex.Pointer());
+ }
+}
+
+
+TEST(Mutex, MultipleMutexes) {
+ Mutex mutex1;
+ Mutex mutex2;
+ Mutex mutex3;
+ // Order 1
+ mutex1.Lock();
+ mutex2.Lock();
+ mutex3.Lock();
+ mutex1.Unlock();
+ mutex2.Unlock();
+ mutex3.Unlock();
+ // Order 2
+ mutex1.Lock();
+ mutex2.Lock();
+ mutex3.Lock();
+ mutex3.Unlock();
+ mutex2.Unlock();
+ mutex1.Unlock();
+}
+
+
+TEST(Mutex, MultipleRecursiveMutexes) {
+ RecursiveMutex recursive_mutex1;
+ RecursiveMutex recursive_mutex2;
+ // Order 1
+ recursive_mutex1.Lock();
+ recursive_mutex2.Lock();
+ EXPECT_TRUE(recursive_mutex1.TryLock());
+ EXPECT_TRUE(recursive_mutex2.TryLock());
+ recursive_mutex1.Unlock();
+ recursive_mutex1.Unlock();
+ recursive_mutex2.Unlock();
+ recursive_mutex2.Unlock();
+ // Order 2
+ recursive_mutex1.Lock();
+ EXPECT_TRUE(recursive_mutex1.TryLock());
+ recursive_mutex2.Lock();
+ EXPECT_TRUE(recursive_mutex2.TryLock());
+ recursive_mutex2.Unlock();
+ recursive_mutex1.Unlock();
+ recursive_mutex2.Unlock();
+ recursive_mutex1.Unlock();
+}
+
+} // namespace base
+} // namespace v8
=======================================
--- /dev/null
+++ /trunk/test/base-unittests/platform/platform-unittest.cc Thu Aug 7
08:39:21 2014 UTC
@@ -0,0 +1,115 @@
+// Copyright 2014 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.
+
+#include "src/base/platform/platform.h"
+
+#if V8_OS_POSIX
+#include <unistd.h> // NOLINT
+#endif
+
+#if V8_OS_WIN
+#include "src/base/win32-headers.h"
+#endif
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+TEST(OS, GetCurrentProcessId) {
+#if V8_OS_POSIX
+ EXPECT_EQ(static_cast<int>(getpid()), OS::GetCurrentProcessId());
+#endif
+
+#if V8_OS_WIN
+ EXPECT_EQ(static_cast<int>(::GetCurrentProcessId()),
+ OS::GetCurrentProcessId());
+#endif
+}
+
+
+TEST(OS, NumberOfProcessorsOnline) {
+ EXPECT_GT(OS::NumberOfProcessorsOnline(), 0);
+}
+
+
+namespace {
+
+class SelfJoinThread V8_FINAL : public Thread {
+ public:
+ SelfJoinThread() : Thread("SelfJoinThread") {}
+ virtual void Run() V8_OVERRIDE { Join(); }
+};
+
+}
+
+
+TEST(Thread, SelfJoin) {
+ SelfJoinThread thread;
+ thread.Start();
+ thread.Join();
+}
+
+
+namespace {
+
+class ThreadLocalStorageTest : public Thread, public ::testing::Test {
+ public:
+ ThreadLocalStorageTest() : Thread("ThreadLocalStorageTest") {
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); ++i) {
+ keys_[i] = Thread::CreateThreadLocalKey();
+ }
+ }
+ ~ThreadLocalStorageTest() {
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); ++i) {
+ Thread::DeleteThreadLocalKey(keys_[i]);
+ }
+ }
+
+ virtual void Run() V8_FINAL V8_OVERRIDE {
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ CHECK(!Thread::HasThreadLocal(keys_[i]));
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ Thread::SetThreadLocal(keys_[i], GetValue(i));
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ CHECK(Thread::HasThreadLocal(keys_[i]));
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ CHECK_EQ(GetValue(i), Thread::GetThreadLocal(keys_[i]));
+ CHECK_EQ(GetValue(i), Thread::GetExistingThreadLocal(keys_[i]));
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ Thread::SetThreadLocal(keys_[i], GetValue(ARRAY_SIZE(keys_) - i -
1));
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ CHECK(Thread::HasThreadLocal(keys_[i]));
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(keys_); i++) {
+ CHECK_EQ(GetValue(ARRAY_SIZE(keys_) - i - 1),
+ Thread::GetThreadLocal(keys_[i]));
+ CHECK_EQ(GetValue(ARRAY_SIZE(keys_) - i - 1),
+ Thread::GetExistingThreadLocal(keys_[i]));
+ }
+ }
+
+ private:
+ static void* GetValue(size_t x) {
+ return reinterpret_cast<void*>(static_cast<uintptr_t>(x + 1));
+ }
+
+ Thread::LocalStorageKey keys_[256];
+};
+
+}
+
+
+TEST_F(ThreadLocalStorageTest, DoTest) {
+ Run();
+ Start();
+ Join();
+}
+
+} // namespace base
+} // namespace v8
=======================================
--- /dev/null
+++ /trunk/test/base-unittests/platform/time-unittest.cc Thu Aug 7
08:39:21 2014 UTC
@@ -0,0 +1,186 @@
+// Copyright 2014 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.
+
+#include "src/base/platform/time.h"
+
+#if V8_OS_MACOSX
+#include <mach/mach_time.h>
+#endif
+#if V8_OS_POSIX
+#include <sys/time.h>
+#endif
+
+#if V8_OS_WIN
+#include "src/base/win32-headers.h"
+#endif
+
+#include "src/base/platform/elapsed-timer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+TEST(TimeDelta, FromAndIn) {
+ EXPECT_EQ(TimeDelta::FromDays(2), TimeDelta::FromHours(48));
+ EXPECT_EQ(TimeDelta::FromHours(3), TimeDelta::FromMinutes(180));
+ EXPECT_EQ(TimeDelta::FromMinutes(2), TimeDelta::FromSeconds(120));
+ EXPECT_EQ(TimeDelta::FromSeconds(2), TimeDelta::FromMilliseconds(2000));
+ EXPECT_EQ(TimeDelta::FromMilliseconds(2),
TimeDelta::FromMicroseconds(2000));
+ EXPECT_EQ(static_cast<int>(13), TimeDelta::FromDays(13).InDays());
+ EXPECT_EQ(static_cast<int>(13), TimeDelta::FromHours(13).InHours());
+ EXPECT_EQ(static_cast<int>(13), TimeDelta::FromMinutes(13).InMinutes());
+ EXPECT_EQ(static_cast<int64_t>(13),
TimeDelta::FromSeconds(13).InSeconds());
+ EXPECT_DOUBLE_EQ(13.0, TimeDelta::FromSeconds(13).InSecondsF());
+ EXPECT_EQ(static_cast<int64_t>(13),
+ TimeDelta::FromMilliseconds(13).InMilliseconds());
+ EXPECT_DOUBLE_EQ(13.0,
TimeDelta::FromMilliseconds(13).InMillisecondsF());
+ EXPECT_EQ(static_cast<int64_t>(13),
+ TimeDelta::FromMicroseconds(13).InMicroseconds());
+}
+
+
+#if V8_OS_MACOSX
+TEST(TimeDelta, MachTimespec) {
+ TimeDelta null = TimeDelta();
+ EXPECT_EQ(null, TimeDelta::FromMachTimespec(null.ToMachTimespec()));
+ TimeDelta delta1 = TimeDelta::FromMilliseconds(42);
+ EXPECT_EQ(delta1, TimeDelta::FromMachTimespec(delta1.ToMachTimespec()));
+ TimeDelta delta2 = TimeDelta::FromDays(42);
+ EXPECT_EQ(delta2, TimeDelta::FromMachTimespec(delta2.ToMachTimespec()));
+}
+#endif
+
+
+TEST(Time, JsTime) {
+ Time t = Time::FromJsTime(700000.3);
+ EXPECT_DOUBLE_EQ(700000.3, t.ToJsTime());
+}
+
+
+#if V8_OS_POSIX
+TEST(Time, Timespec) {
+ Time null;
+ EXPECT_TRUE(null.IsNull());
+ EXPECT_EQ(null, Time::FromTimespec(null.ToTimespec()));
+ Time now = Time::Now();
+ EXPECT_EQ(now, Time::FromTimespec(now.ToTimespec()));
+ Time now_sys = Time::NowFromSystemTime();
+ EXPECT_EQ(now_sys, Time::FromTimespec(now_sys.ToTimespec()));
+ Time unix_epoch = Time::UnixEpoch();
+ EXPECT_EQ(unix_epoch, Time::FromTimespec(unix_epoch.ToTimespec()));
+ Time max = Time::Max();
+ EXPECT_TRUE(max.IsMax());
+ EXPECT_EQ(max, Time::FromTimespec(max.ToTimespec()));
+}
+
+
+TEST(Time, Timeval) {
+ Time null;
+ EXPECT_TRUE(null.IsNull());
+ EXPECT_EQ(null, Time::FromTimeval(null.ToTimeval()));
+ Time now = Time::Now();
+ EXPECT_EQ(now, Time::FromTimeval(now.ToTimeval()));
+ Time now_sys = Time::NowFromSystemTime();
+ EXPECT_EQ(now_sys, Time::FromTimeval(now_sys.ToTimeval()));
+ Time unix_epoch = Time::UnixEpoch();
+ EXPECT_EQ(unix_epoch, Time::FromTimeval(unix_epoch.ToTimeval()));
+ Time max = Time::Max();
+ EXPECT_TRUE(max.IsMax());
+ EXPECT_EQ(max, Time::FromTimeval(max.ToTimeval()));
+}
+#endif
+
+
+#if V8_OS_WIN
+TEST(Time, Filetime) {
+ Time null;
+ EXPECT_TRUE(null.IsNull());
+ EXPECT_EQ(null, Time::FromFiletime(null.ToFiletime()));
+ Time now = Time::Now();
+ EXPECT_EQ(now, Time::FromFiletime(now.ToFiletime()));
+ Time now_sys = Time::NowFromSystemTime();
+ EXPECT_EQ(now_sys, Time::FromFiletime(now_sys.ToFiletime()));
+ Time unix_epoch = Time::UnixEpoch();
+ EXPECT_EQ(unix_epoch, Time::FromFiletime(unix_epoch.ToFiletime()));
+ Time max = Time::Max();
+ EXPECT_TRUE(max.IsMax());
+ EXPECT_EQ(max, Time::FromFiletime(max.ToFiletime()));
+}
+#endif
+
+
+namespace {
+
+template <typename T>
+static void ResolutionTest(T (*Now)(), TimeDelta target_granularity) {
+ // We're trying to measure that intervals increment in a VERY small
amount
+ // of time -- according to the specified target granularity.
Unfortunately,
+ // if we happen to have a context switch in the middle of our test, the
+ // context switch could easily exceed our limit. So, we iterate on this
+ // several times. As long as we're able to detect the fine-granularity
+ // timers at least once, then the test has succeeded.
+ static const TimeDelta kExpirationTimeout = TimeDelta::FromSeconds(1);
+ ElapsedTimer timer;
+ timer.Start();
+ TimeDelta delta;
+ do {
+ T start = Now();
+ T now = start;
+ // Loop until we can detect that the clock has changed. Non-HighRes
timers
+ // will increment in chunks, i.e. 15ms. By spinning until we see a
clock
+ // change, we detect the minimum time between measurements.
+ do {
+ now = Now();
+ delta = now - start;
+ } while (now <= start);
+ EXPECT_NE(static_cast<int64_t>(0), delta.InMicroseconds());
+ } while (delta > target_granularity
&& !timer.HasExpired(kExpirationTimeout));
+ EXPECT_LE(delta, target_granularity);
+}
+
+}
+
+
+TEST(Time, NowResolution) {
+ // We assume that Time::Now() has at least 16ms resolution.
+ static const TimeDelta kTargetGranularity =
TimeDelta::FromMilliseconds(16);
+ ResolutionTest<Time>(&Time::Now, kTargetGranularity);
+}
+
+
+TEST(TimeTicks, NowResolution) {
+ // We assume that TimeTicks::Now() has at least 16ms resolution.
+ static const TimeDelta kTargetGranularity =
TimeDelta::FromMilliseconds(16);
+ ResolutionTest<TimeTicks>(&TimeTicks::Now, kTargetGranularity);
+}
+
+
+TEST(TimeTicks, HighResolutionNowResolution) {
+ if (!TimeTicks::IsHighResolutionClockWorking()) return;
+
+ // We assume that TimeTicks::HighResolutionNow() has sub-ms resolution.
+ static const TimeDelta kTargetGranularity =
TimeDelta::FromMilliseconds(1);
+ ResolutionTest<TimeTicks>(&TimeTicks::HighResolutionNow,
kTargetGranularity);
+}
+
+
+TEST(TimeTicks, IsMonotonic) {
+ TimeTicks previous_normal_ticks;
+ TimeTicks previous_highres_ticks;
+ ElapsedTimer timer;
+ timer.Start();
+ while (!timer.HasExpired(TimeDelta::FromMilliseconds(100))) {
+ TimeTicks normal_ticks = TimeTicks::Now();
+ TimeTicks highres_ticks = TimeTicks::HighResolutionNow();
+ EXPECT_GE(normal_ticks, previous_normal_ticks);
+ EXPECT_GE((normal_ticks - previous_normal_ticks).InMicroseconds(), 0);
+ EXPECT_GE(highres_ticks, previous_highres_ticks);
+ EXPECT_GE((highres_ticks - previous_highres_ticks).InMicroseconds(),
0);
+ previous_normal_ticks = normal_ticks;
+ previous_highres_ticks = highres_ticks;
+ }
+}
+
+} // namespace base
+} // namespace v8
=======================================
--- /dev/null
+++ /trunk/test/base-unittests/testcfg.py Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,51 @@
+# Copyright 2014 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.
+
+import os
+import shutil
+
+from testrunner.local import commands
+from testrunner.local import testsuite
+from testrunner.local import utils
+from testrunner.objects import testcase
+
+
+class BaseUnitTestsSuite(testsuite.TestSuite):
+ def __init__(self, name, root):
+ super(BaseUnitTestsSuite, self).__init__(name, root)
+
+ def ListTests(self, context):
+ shell = os.path.abspath(os.path.join(context.shell_dir, self.shell()))
+ if utils.IsWindows():
+ shell += ".exe"
+ output = commands.Execute(context.command_prefix +
+ [shell, "--gtest_list_tests"] +
+ context.extra_flags)
+ if output.exit_code != 0:
+ print output.stdout
+ print output.stderr
+ return []
+ tests = []
+ test_case = ''
+ for test_desc in output.stdout.strip().split():
+ if test_desc.endswith('.'):
+ test_case = test_desc
+ else:
+ test = testcase.TestCase(self, test_case + test_desc,
dependency=None)
+ tests.append(test)
+ tests.sort()
+ return tests
+
+ def GetFlagsForTestCase(self, testcase, context):
+ return (testcase.flags + ["--gtest_filter=" + testcase.path] +
+ ["--gtest_random_seed=%s" % context.random_seed] +
+ ["--gtest_print_time=0"] +
+ context.mode_flags)
+
+ def shell(self):
+ return "base-unittests"
+
+
+def GetSuite(name, root):
+ return BaseUnitTestsSuite(name, root)
=======================================
--- /dev/null
+++ /trunk/test/base-unittests/utils/random-number-generator-unittest.cc
Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,53 @@
+// Copyright 2014 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.
+
+#include <climits>
+
+#include "src/base/utils/random-number-generator.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+class RandomNumberGeneratorTest : public ::testing::TestWithParam<int> {};
+
+
+static const int kMaxRuns = 12345;
+
+
+TEST_P(RandomNumberGeneratorTest, NextIntWithMaxValue) {
+ RandomNumberGenerator rng(GetParam());
+ for (int max = 1; max <= kMaxRuns; ++max) {
+ int n = rng.NextInt(max);
+ EXPECT_LE(0, n);
+ EXPECT_LT(n, max);
+ }
+}
+
+
+TEST_P(RandomNumberGeneratorTest, NextBooleanReturnsFalseOrTrue) {
+ RandomNumberGenerator rng(GetParam());
+ for (int k = 0; k < kMaxRuns; ++k) {
+ bool b = rng.NextBool();
+ EXPECT_TRUE(b == false || b == true);
+ }
+}
+
+
+TEST_P(RandomNumberGeneratorTest, NextDoubleReturnsValueBetween0And1) {
+ RandomNumberGenerator rng(GetParam());
+ for (int k = 0; k < kMaxRuns; ++k) {
+ double d = rng.NextDouble();
+ EXPECT_LE(0.0, d);
+ EXPECT_LT(d, 1.0);
+ }
+}
+
+
+INSTANTIATE_TEST_CASE_P(RandomSeeds, RandomNumberGeneratorTest,
+ ::testing::Values(INT_MIN, -1, 0, 1, 42, 100,
+ 1234567890, 987654321, INT_MAX));
+
+} // namespace base
+} // namespace v8
=======================================
--- /dev/null
+++ /trunk/test/cctest/test-unscopables-hidden-prototype.cc Thu Aug 7
08:39:21 2014 UTC
@@ -0,0 +1,105 @@
+// Copyright 2014 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.
+
+#include <stdlib.h>
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+namespace {
+
+
+static void Cleanup() {
+ CompileRun(
+ "delete object.x;"
+ "delete hidden_prototype.x;"
+ "delete object[Symbol.unscopables];"
+ "delete hidden_prototype[Symbol.unscopables];");
+}
+
+
+TEST(Unscopables) {
+ i::FLAG_harmony_unscopables = true;
+
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate);
+ v8::Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate);
+
+ t1->SetHiddenPrototype(true);
+
+ v8::Local<v8::Object> object = t0->GetFunction()->NewInstance();
+ v8::Local<v8::Object> hidden_prototype =
t1->GetFunction()->NewInstance();
+
+ object->SetPrototype(hidden_prototype);
+
+ context->Global()->Set(v8_str("object"), object);
+ context->Global()->Set(v8_str("hidden_prototype"), hidden_prototype);
+
+ CHECK_EQ(1, CompileRun(
+ "var result;"
+ "var x = 0;"
+ "object.x = 1;"
+ "with (object) {"
+ " result = x;"
+ "}"
+ "result")->Int32Value());
+
+ Cleanup();
+ CHECK_EQ(2, CompileRun(
+ "var result;"
+ "var x = 0;"
+ "hidden_prototype.x = 2;"
+ "with (object) {"
+ " result = x;"
+ "}"
+ "result")->Int32Value());
+
+ Cleanup();
+ CHECK_EQ(0, CompileRun(
+ "var result;"
+ "var x = 0;"
+ "object.x = 3;"
+ "object[Symbol.unscopables] = {x: true};"
+ "with (object) {"
+ " result = x;"
+ "}"
+ "result")->Int32Value());
+
+ Cleanup();
+ CHECK_EQ(0, CompileRun(
+ "var result;"
+ "var x = 0;"
+ "hidden_prototype.x = 4;"
+ "hidden_prototype[Symbol.unscopables] = {x: true};"
+ "with (object) {"
+ " result = x;"
+ "}"
+ "result")->Int32Value());
+
+ Cleanup();
+ CHECK_EQ(0, CompileRun(
+ "var result;"
+ "var x = 0;"
+ "object.x = 5;"
+ "hidden_prototype[Symbol.unscopables] = {x: true};"
+ "with (object) {"
+ " result = x;"
+ "}"
+ "result;")->Int32Value());
+
+ Cleanup();
+ CHECK_EQ(0, CompileRun(
+ "var result;"
+ "var x = 0;"
+ "hidden_prototype.x = 6;"
+ "object[Symbol.unscopables] = {x: true};"
+ "with (object) {"
+ " result = x;"
+ "}"
+ "result")->Int32Value());
+}
+}
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/async-task-event.js Thu Aug 7
08:39:21 2014 UTC
@@ -0,0 +1,61 @@
+// Copyright 2014 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: --expose-debug-as debug
+
+Debug = debug.Debug;
+
+var base_id = -1;
+var exception = null;
+var expected = [
+ "enqueue #1",
+ "willHandle #1",
+ "then #1",
+ "enqueue #2",
+ "didHandle #1",
+ "willHandle #2",
+ "then #2",
+ "enqueue #3",
+ "didHandle #2",
+ "willHandle #3",
+ "didHandle #3"
+];
+
+function assertLog(msg) {
+ print(msg);
+ assertTrue(expected.length > 0);
+ assertEquals(expected.shift(), msg);
+ if (!expected.length) {
+ Debug.setListener(null);
+ }
+}
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.AsyncTaskEvent) return;
+ try {
+ if (base_id < 0)
+ base_id = event_data.id();
+ var id = event_data.id() - base_id + 1;
+ assertEquals("Promise.resolve", event_data.name());
+ assertLog(event_data.type() + " #" + id);
+ } catch (e) {
+ print(e + e.stack)
+ exception = e;
+ }
+}
+
+Debug.setListener(listener);
+
+var resolver;
+var p = new Promise(function(resolve, reject) {
+ resolver = resolve;
+});
+p.then(function() {
+ assertLog("then #1");
+}).then(function() {
+ assertLog("then #2");
+});
+resolver();
+
+assertNull(exception);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/events.js Thu Aug 7 08:39:21
2014 UTC
@@ -0,0 +1,124 @@
+// Copyright 2014 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 --expose-debug-as debug
+
+Debug = debug.Debug;
+
+var eventsExpected = 16;
+var exception = null;
+var result = [];
+
+function updatePromise(promise, parentPromise, status, value) {
+ var i;
+ for (i = 0; i < result.length; ++i) {
+ if (result[i].promise === promise) {
+ result[i].parentPromise = parentPromise || result[i].parentPromise;
+ result[i].status = status || result[i].status;
+ result[i].value = value || result[i].value;
+ break;
+ }
+ }
+ assertTrue(i < result.length);
+}
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.PromiseEvent) return;
+ try {
+ eventsExpected--;
+ assertTrue(event_data.promise().isPromise());
+ if (event_data.status() === 0) {
+ // New promise.
+ assertEquals("pending", event_data.promise().status());
+ result.push({ promise: event_data.promise().value(), status: 0 });
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event")
0);
+ } else if (event_data.status() !== undefined) {
+ // Resolve/reject promise.
+ updatePromise(event_data.promise().value(),
+ undefined,
+ event_data.status(),
+ event_data.value().value());
+ } else {
+ // Chain promises.
+ assertTrue(event_data.parentPromise().isPromise());
+ updatePromise(event_data.promise().value(),
+ event_data.parentPromise().value());
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event")
0);
+ }
+ } catch (e) {
+ print(e + e.stack)
+ exception = e;
+ }
+}
+
+Debug.setListener(listener);
+
+function resolver(resolve, reject) { resolve(); }
+
+var p1 = new Promise(resolver); // event
+var p2 = p1.then().then(); // event
+var p3 = new Promise(function(resolve, reject) { // event
+ reject("rejected");
+});
+var p4 = p3.then(); // event
+var p5 = p1.then(); // event
+
+function assertAsync(b, s) {
+ if (b) {
+ print(s, "succeeded");
+ } else {
+ %AbortJS(s + " FAILED!");
+ }
+}
+
+function testDone(iteration) {
+ function checkResult() {
+ if (eventsExpected === 0) {
+ assertAsync(result.length === 6, "result.length");
+
+ assertAsync(result[0].promise === p1, "result[0].promise");
+ assertAsync(result[0].parentPromise === undefined,
+ "result[0].parentPromise");
+ assertAsync(result[0].status === 1, "result[0].status");
+ assertAsync(result[0].value === undefined, "result[0].value");
+
+ assertAsync(result[1].parentPromise === p1,
+ "result[1].parentPromise");
+ assertAsync(result[1].status === 1, "result[1].status");
+
+ assertAsync(result[2].promise === p2, "result[2].promise");
+
+ assertAsync(result[3].promise === p3, "result[3].promise");
+ assertAsync(result[3].parentPromise === undefined,
+ "result[3].parentPromise");
+ assertAsync(result[3].status === -1, "result[3].status");
+ assertAsync(result[3].value === "rejected", "result[3].value");
+
+ assertAsync(result[4].promise === p4, "result[4].promise");
+ assertAsync(result[4].parentPromise === p3,
+ "result[4].parentPromise");
+ assertAsync(result[4].status === -1, "result[4].status");
+ assertAsync(result[4].value === "rejected", "result[4].value");
+
+ assertAsync(result[5].promise === p5, "result[5].promise");
+ assertAsync(result[5].parentPromise === p1,
+ "result[5].parentPromise");
+ assertAsync(result[5].status === 1, "result[5].status");
+
+ assertAsync(exception === null, "exception === null");
+ Debug.setListener(null);
+ } else if (iteration > 10) {
+ %AbortJS("Not all events were received!");
+ } else {
+ testDone(iteration + 1);
+ }
+ }
+
+ var iteration = iteration || 0;
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone();
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/reentry.js Thu Aug 7 08:39:21
2014 UTC
@@ -0,0 +1,17 @@
+// Copyright 2014 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: --expose-debug-as debug
+
+// Test reentry of special try catch for Promises.
+
+Debug = debug.Debug;
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(function(event, exec_state, event_data, data) { });
+
+var p = new Promise(function(resolve, reject) { resolve(); });
+var q = p.chain(function() {
+ new Promise(function(resolve, reject) { resolve(); });
+});
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/reject-after-resolve.js Thu Aug
7 08:39:21 2014 UTC
@@ -0,0 +1,37 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we listen to uncaught exceptions and
+// the Promise is rejected in a chained closure after it has been resolved.
+// We expect no Exception debug event to be triggered.
+
+Debug = debug.Debug;
+
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve(reject);
+});
+
+var q = p.chain(
+ function(value) {
+ assertEquals(["resolve", "end main"], log);
+ value(new Error("reject"));
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ assertTrue(event != Debug.DebugEvent.Exception);
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnException();
+Debug.setListener(listener);
+
+log.push("end main");
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/reject-caught-all.js Thu Aug 7
08:39:21 2014 UTC
@@ -0,0 +1,72 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we listen to all exceptions and
+// there is a catch handler for the to-be-rejected Promise.
+// We expect a normal Exception debug event to be triggered.
+
+Debug = debug.Debug;
+
+var log = [];
+var expected_events = 1;
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+var q = p.chain(
+ function(value) {
+ log.push("reject");
+ return Promise.reject(new Error("reject"));
+ });
+
+q.catch(
+ function(e) {
+ assertEquals("reject", e.message);
+ });
+
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("reject", event_data.exception().message);
+ assertEquals(q, event_data.promise());
+ assertFalse(event_data.uncaught());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "end main", "reject"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/reject-caught-late.js Thu Aug 7
08:39:21 2014 UTC
@@ -0,0 +1,34 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we only listen to uncaught exceptions, the
Promise
+// is rejected, and a catch handler is installed right before the
rejection.
+// We expect no debug event to be triggered.
+
+Debug = debug.Debug;
+
+var p = new Promise(function(resolve, reject) {
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ q.catch(function(e) {
+ assertEquals("caught", e.message);
+ });
+ return Promise.reject(Error("caught"));
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ assertTrue(event != Debug.DebugEvent.Exception);
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/reject-caught-uncaught.js Thu
Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,36 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we only listen to uncaught exceptions and
+// there is a catch handler for the to-be-rejected Promise.
+// We expect no debug event to be triggered.
+
+Debug = debug.Debug;
+
+var p = new Promise(function(resolve, reject) {
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ return Promise.reject(Error("caught reject"));
+ });
+
+q.catch(
+ function(e) {
+ assertEquals("caught reject", e.message);
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ assertTrue(event != Debug.DebugEvent.Exception);
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/reject-in-constructor.js Thu
Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,39 @@
+// Copyright 2014 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: --expose-debug-as debug
+
+// Test debug events when we only listen to uncaught exceptions and
+// the Promise is rejected in the Promise constructor.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var steps = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ steps++;
+ assertEquals("uncaught", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertTrue(event_data.uncaught());
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event")
0);
+ }
+ } catch (e) {
+ exception = e;
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+var p = new Promise(function(resolve, reject) {
+ reject(new Error("uncaught")); // event
+});
+
+assertEquals(1, steps);
+assertNull(exception);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/reject-uncaught-all.js Thu Aug
7 08:39:21 2014 UTC
@@ -0,0 +1,69 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we listen to all exceptions and
+// there is a catch handler for the to-be-rejected Promise.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ log.push("reject");
+ return Promise.reject(new Error("uncaught reject"));
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("uncaught reject", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertEquals(q, event_data.promise());
+ assertTrue(event_data.uncaught());
+ // All of the frames on the stack are from native Javascript.
+ assertEquals(0, exec_state.frameCount());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "end main", "reject"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/reject-uncaught-late.js Thu Aug
7 08:39:21 2014 UTC
@@ -0,0 +1,76 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we only listen to uncaught exceptions and
+// there is a catch handler for the to-be-rejected Promise.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var reject_closure;
+
+var p = new Promise(function(resolve, reject) {
+ log.push("postpone p");
+ reject_closure = reject;
+});
+
+var q = new Promise(function(resolve, reject) {
+ log.push("resolve q");
+ resolve();
+});
+
+q.then(function() {
+ log.push("reject p");
+ reject_closure(new Error("uncaught reject p")); // event
+})
+
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("uncaught reject p", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertEquals(p, event_data.promise());
+ assertTrue(event_data.uncaught());
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event")
0);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["postpone p", "resolve q", "end main", "reject p"],
log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js Thu
Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,69 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we only listen to uncaught exceptions and
+// there is no catch handler for the to-be-rejected Promise.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ log.push("reject");
+ return Promise.reject(Error("uncaught reject")); // event
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("uncaught reject", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertEquals(q, event_data.promise());
+ assertTrue(event_data.uncaught());
+ // All of the frames on the stack are from native Javascript.
+ assertEquals(0, exec_state.frameCount());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "end main", "reject"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js
Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,78 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when a Promise is rejected, which is caught by a
custom
+// promise, which has a number for reject closure. We expect an Exception
debug
+// events trying to call the invalid reject closure.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+function MyPromise(resolver) {
+ var reject = 1;
+ var resolve = function() { };
+ log.push("construct");
+ resolver(resolve, reject);
+};
+
+MyPromise.prototype = new Promise(function() {});
+p.constructor = MyPromise;
+
+var q = p.chain(
+ function() {
+ log.push("reject caught");
+ return Promise.reject(new Error("caught"));
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("number is not a function",
event_data.exception().message);
+ // All of the frames on the stack are from native Javascript.
+ assertEquals(0, exec_state.frameCount());
+ assertEquals(q, event_data.promise());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "construct", "end main", "reject caught"],
+ log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
+
+log.push("end main");
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js
Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,87 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when a Promise is rejected, which is caught by a
+// custom promise, which throws a new exception in its reject handler.
+// We expect two Exception debug events:
+// 1) when promise q is rejected.
+// 2) when the custom reject closure in MyPromise throws an exception.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+function MyPromise(resolver) {
+ var reject = function() {
+ log.push("throw in reject");
+ throw new Error("reject"); // event
+ };
+ var resolve = function() { };
+ log.push("construct");
+ resolver(resolve, reject);
+};
+
+MyPromise.prototype = new Promise(function() {});
+p.constructor = MyPromise;
+
+var q = p.chain(
+ function() {
+ log.push("reject caught");
+ return Promise.reject(new Error("caught"));
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("reject", event_data.exception().message);
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(
+ exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
+ }
+ } catch (e) {
+ // Signal a failure with exit code 1. This is necessary since the
+ // debugger swallows exceptions and we expect the chained function
+ // and this listener to be executed after the main script is finished.
+ print("Unexpected exception: " + e + "\n" + e.stack);
+ quit(1);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "construct", "end main",
+ "reject caught", "throw in reject"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js
Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,78 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when a Promise is rejected, which is caught by a
custom
+// promise, which has undefined for reject closure. We expect an Exception
+// debug even calling the (undefined) custom rejected closure.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+function MyPromise(resolver) {
+ var reject = undefined;
+ var resolve = function() { };
+ log.push("construct");
+ resolver(resolve, reject);
+};
+
+MyPromise.prototype = new Promise(function() {});
+p.constructor = MyPromise;
+
+var q = p.chain(
+ function() {
+ log.push("reject caught");
+ return Promise.reject(new Error("caught"));
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("caught", event_data.exception().message);
+ // All of the frames on the stack are from native Javascript.
+ assertEquals(0, exec_state.frameCount());
+ assertEquals(q, event_data.promise());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "construct", "end main", "reject caught"],
+ log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
+
+log.push("end main");
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/throw-caught-all.js Thu Aug 7
08:39:21 2014 UTC
@@ -0,0 +1,71 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we listen to all exceptions and
+// there is a catch handler for the exception thrown in a Promise.
+// We expect a normal Exception debug event to be triggered.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ log.push("throw");
+ throw new Error("caught");
+ });
+
+q.catch(
+ function(e) {
+ assertEquals("caught", e.message);
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("caught", event_data.exception().message);
+ assertEquals(q, event_data.promise());
+ assertFalse(event_data.uncaught());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "end main", "throw"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/throw-caught-late.js Thu Aug 7
08:39:21 2014 UTC
@@ -0,0 +1,34 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we only listen to uncaught exceptions, the
Promise
+// throws, and a catch handler is installed right before throwing.
+// We expect no debug event to be triggered.
+
+Debug = debug.Debug;
+
+var p = new Promise(function(resolve, reject) {
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ q.catch(function(e) {
+ assertEquals("caught", e.message);
+ });
+ throw new Error("caught");
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ assertTrue(event != Debug.DebugEvent.Exception);
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/throw-caught-uncaught.js Thu
Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,36 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we only listen to uncaught exceptions and
+// there is a catch handler for the exception thrown in a Promise.
+// We expect no debug event to be triggered.
+
+Debug = debug.Debug;
+
+var p = new Promise(function(resolve, reject) {
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ throw new Error("caught throw");
+ });
+
+q.catch(
+ function(e) {
+ assertEquals("caught throw", e.message);
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ assertTrue(event != Debug.DebugEvent.Exception);
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/throw-in-constructor.js Thu Aug
7 08:39:21 2014 UTC
@@ -0,0 +1,40 @@
+// Copyright 2014 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: --expose-debug-as debug
+
+// Test debug events when we only listen to uncaught exceptions and
+// an exception is thrown in the Promise constructor.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var step = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ assertEquals(0, step);
+ assertEquals("uncaught", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertTrue(event_data.uncaught());
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event")
0);
+ step++;
+ }
+ } catch (e) {
+ exception = e;
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+var p = new Promise(function(resolve, reject) {
+ throw new Error("uncaught"); // event
+});
+
+assertEquals(1, step);
+assertNull(exception);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/throw-uncaught-all.js Thu Aug 7
08:39:21 2014 UTC
@@ -0,0 +1,70 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we listen to all exceptions and
+// there is no catch handler for the exception thrown in a Promise.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ log.push("throw");
+ throw new Error("uncaught"); // event
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ // Ignore exceptions during startup in stress runs.
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("uncaught", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertEquals(q, event_data.promise());
+ assertTrue(event_data.uncaught());
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event")
0);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "end main", "throw"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Rerun testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js Thu
Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,70 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we only listen to uncaught exceptions and
+// there is a catch handler for the exception thrown in a Promise.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+var q = p.chain(
+ function() {
+ log.push("throw");
+ throw new Error("uncaught"); // event
+ });
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.AsyncTaskEvent) return;
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ assertEquals("uncaught", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertEquals(q, event_data.promise());
+ assertTrue(event_data.uncaught());
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event")
0);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "end main", "throw"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js
Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,90 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when an exception is thrown inside a Promise, which is
+// caught by a custom promise, which throws a new exception in its reject
+// handler. We expect two Exception debug events:
+// 1) when the exception is thrown in the promise q.
+// 2) when the custom reject closure in MyPromise throws an exception.
+
+Debug = debug.Debug;
+
+var expected_events = 2;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+function MyPromise(resolver) {
+ var reject = function() {
+ log.push("throw in reject");
+ throw new Error("reject"); // event
+ };
+ var resolve = function() { };
+ log.push("construct");
+ resolver(resolve, reject);
+};
+
+MyPromise.prototype = new Promise(function() {});
+p.constructor = MyPromise;
+
+var q = p.chain(
+ function() {
+ log.push("throw caught");
+ throw new Error("caught"); // event
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ if (expected_events == 1) {
+ assertEquals(["resolve", "construct", "end main",
+ "throw caught"], log);
+ assertEquals("caught", event_data.exception().message);
+ } else if (expected_events == 0) {
+ assertEquals("reject", event_data.exception().message);
+ } else {
+ assertUnreachable();
+ }
+ assertEquals(q, event_data.promise());
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf('// event')
0);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "construct", "end main",
+ "throw caught", "throw in reject"], log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/throw-with-undefined-reject.js
Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,88 @@
+// Copyright 2014 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: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when an exception is thrown inside a Promise, which is
+// caught by a custom promise, which has no reject handler.
+// We expect two Exception debug events:
+// 1) when the exception is thrown in the promise q.
+// 2) when calling the undefined custom reject closure in MyPromise
throws.
+
+Debug = debug.Debug;
+
+var expected_events = 2;
+var log = [];
+
+var p = new Promise(function(resolve, reject) {
+ log.push("resolve");
+ resolve();
+});
+
+function MyPromise(resolver) {
+ var reject = undefined;
+ var resolve = function() { };
+ log.push("construct");
+ resolver(resolve, reject);
+};
+
+MyPromise.prototype = new Promise(function() {});
+p.constructor = MyPromise;
+
+var q = p.chain(
+ function() {
+ log.push("throw caught");
+ throw new Error("caught"); // event
+ });
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ expected_events--;
+ assertTrue(expected_events >= 0);
+ if (expected_events == 1) {
+ assertTrue(
+ exec_state.frame(0).sourceLineText().indexOf('// event') > 0);
+ assertEquals("caught", event_data.exception().message);
+ } else if (expected_events == 0) {
+ // All of the frames on the stack are from native Javascript.
+ assertEquals(0, exec_state.frameCount());
+ assertEquals("undefined is not a function",
+ event_data.exception().message);
+ } else {
+ assertUnreachable();
+ }
+ assertEquals(q, event_data.promise());
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+log.push("end main");
+
+function testDone(iteration) {
+ function checkResult() {
+ try {
+ assertTrue(iteration < 10);
+ if (expected_events === 0) {
+ assertEquals(["resolve", "construct", "end main", "throw caught"],
log);
+ } else {
+ testDone(iteration + 1);
+ }
+ } catch (e) {
+ %AbortJS(e + "\n" + e.stack);
+ }
+ }
+
+ // Run testDone through the Object.observe processing loop.
+ var dummy = {};
+ Object.observe(dummy, checkResult);
+ dummy.dummy = dummy;
+}
+
+testDone(0);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/debug-promises/try-reject-in-constructor.js Thu
Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,42 @@
+// Copyright 2014 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: --expose-debug-as debug
+
+// Test debug events when we only listen to uncaught exceptions and
+// the Promise is rejected within a try-catch in the Promise constructor.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var step = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ assertEquals(0, step);
+ assertEquals("uncaught", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertTrue(event_data.uncaught());
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event")
0);
+ step++;
+ }
+ } catch (e) {
+ exception = e;
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+var p = new Promise(function(resolve, reject) {
+ try { // This try-catch must not prevent this uncaught reject event.
+ reject(new Error("uncaught")); // event
+ } catch (e) { }
+});
+
+assertEquals(1, step);
+assertNull(exception);
=======================================
--- /dev/null
+++
/trunk/test/mjsunit/es6/debug-promises/try-throw-reject-in-constructor.js
Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,44 @@
+// Copyright 2014 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: --expose-debug-as debug
+
+// Test debug events when we only listen to uncaught exceptions and
+// an exception is thrown in the Promise constructor, but caught in an
+// inner try-catch. The Promise is rejected afterwards.
+// We expect an Exception debug event with a promise to be triggered.
+
+Debug = debug.Debug;
+
+var step = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Exception) {
+ assertEquals(0, step);
+ assertEquals("uncaught", event_data.exception().message);
+ assertTrue(event_data.promise() instanceof Promise);
+ assertTrue(event_data.uncaught());
+ // Assert that the debug event is triggered at the throw site.
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event")
0);
+ step++;
+ }
+ } catch (e) {
+ exception = e;
+ }
+}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+var p = new Promise(function(resolve, reject) {
+ try { // This try-catch must not prevent this uncaught reject event.
+ throw new Error("caught");
+ } catch (e) { }
+ reject(new Error("uncaught")); // event
+});
+
+assertEquals(1, step);
+assertNull(exception);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/string-html.js Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,159 @@
+// Copyright 2014 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.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+assertEquals('_'.anchor('b'), '<a name="b">_</a>');
+assertEquals('<'.anchor('<'), '<a name="<"><</a>');
+assertEquals('_'.anchor(0x2A), '<a name="42">_</a>');
+assertEquals('_'.anchor('\x22'), '<a name=""">_</a>');
+assertEquals(String.prototype.anchor.call(0x2A, 0x2A), '<a
name="42">42</a>');
+assertThrows(function() {
+ String.prototype.anchor.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.anchor.call(null);
+}, TypeError);
+assertEquals(String.prototype.anchor.length, 1);
+
+assertEquals('_'.big(), '<big>_</big>');
+assertEquals('<'.big(), '<big><</big>');
+assertEquals(String.prototype.big.call(0x2A), '<big>42</big>');
+assertThrows(function() {
+ String.prototype.big.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.big.call(null);
+}, TypeError);
+assertEquals(String.prototype.big.length, 0);
+
+assertEquals('_'.blink(), '<blink>_</blink>');
+assertEquals('<'.blink(), '<blink><</blink>');
+assertEquals(String.prototype.blink.call(0x2A), '<blink>42</blink>');
+assertThrows(function() {
+ String.prototype.blink.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.blink.call(null);
+}, TypeError);
+assertEquals(String.prototype.blink.length, 0);
+
+assertEquals('_'.bold(), '<b>_</b>');
+assertEquals('<'.bold(), '<b><</b>');
+assertEquals(String.prototype.bold.call(0x2A), '<b>42</b>');
+assertThrows(function() {
+ String.prototype.bold.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.bold.call(null);
+}, TypeError);
+assertEquals(String.prototype.bold.length, 0);
+
+assertEquals('_'.fixed(), '<tt>_</tt>');
+assertEquals('<'.fixed(), '<tt><</tt>');
+assertEquals(String.prototype.fixed.call(0x2A), '<tt>42</tt>');
+assertThrows(function() {
+ String.prototype.fixed.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.fixed.call(null);
+}, TypeError);
+assertEquals(String.prototype.fixed.length, 0);
+
+assertEquals('_'.fontcolor('b'), '<font color="b">_</font>');
+assertEquals('<'.fontcolor('<'), '<font color="<"><</font>');
+assertEquals('_'.fontcolor(0x2A), '<font color="42">_</font>');
+assertEquals('_'.fontcolor('\x22'), '<font color=""">_</font>');
+assertEquals(String.prototype.fontcolor.call(0x2A, 0x2A),
+ '<font color="42">42</font>');
+assertThrows(function() {
+ String.prototype.fontcolor.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.fontcolor.call(null);
+}, TypeError);
+assertEquals(String.prototype.fontcolor.length, 1);
+
+assertEquals('_'.fontsize('b'), '<font size="b">_</font>');
+assertEquals('<'.fontsize('<'), '<font size="<"><</font>');
+assertEquals('_'.fontsize(0x2A), '<font size="42">_</font>');
+assertEquals('_'.fontsize('\x22'), '<font size=""">_</font>');
+assertEquals(String.prototype.fontsize.call(0x2A, 0x2A),
+ '<font size="42">42</font>');
+assertThrows(function() {
+ String.prototype.fontsize.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.fontsize.call(null);
+}, TypeError);
+assertEquals(String.prototype.fontsize.length, 1);
+
+assertEquals('_'.italics(), '<i>_</i>');
+assertEquals('<'.italics(), '<i><</i>');
+assertEquals(String.prototype.italics.call(0x2A), '<i>42</i>');
+assertThrows(function() {
+ String.prototype.italics.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.italics.call(null);
+}, TypeError);
+assertEquals(String.prototype.italics.length, 0);
+
+assertEquals('_'.link('b'), '<a href="b">_</a>');
+assertEquals('<'.link('<'), '<a href="<"><</a>');
+assertEquals('_'.link(0x2A), '<a href="42">_</a>');
+assertEquals('_'.link('\x22'), '<a href=""">_</a>');
+assertEquals(String.prototype.link.call(0x2A, 0x2A), '<a
href="42">42</a>');
+assertThrows(function() {
+ String.prototype.link.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.link.call(null);
+}, TypeError);
+assertEquals(String.prototype.link.length, 1);
+
+assertEquals('_'.small(), '<small>_</small>');
+assertEquals('<'.small(), '<small><</small>');
+assertEquals(String.prototype.small.call(0x2A), '<small>42</small>');
+assertThrows(function() {
+ String.prototype.small.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.small.call(null);
+}, TypeError);
+assertEquals(String.prototype.small.length, 0);
+
+assertEquals('_'.strike(), '<strike>_</strike>');
+assertEquals('<'.strike(), '<strike><</strike>');
+assertEquals(String.prototype.strike.call(0x2A), '<strike>42</strike>');
+assertThrows(function() {
+ String.prototype.strike.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.strike.call(null);
+}, TypeError);
+assertEquals(String.prototype.strike.length, 0);
+
+assertEquals('_'.sub(), '<sub>_</sub>');
+assertEquals('<'.sub(), '<sub><</sub>');
+assertEquals(String.prototype.sub.call(0x2A), '<sub>42</sub>');
+assertThrows(function() {
+ String.prototype.sub.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.sub.call(null);
+}, TypeError);
+assertEquals(String.prototype.sub.length, 0);
+
+assertEquals('_'.sup(), '<sup>_</sup>');
+assertEquals('<'.sup(), '<sup><</sup>');
+assertEquals(String.prototype.sup.call(0x2A), '<sup>42</sup>');
+assertThrows(function() {
+ String.prototype.sup.call(undefined);
+}, TypeError);
+assertThrows(function() {
+ String.prototype.sup.call(null);
+}, TypeError);
+assertEquals(String.prototype.sup.length, 0);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/harmony/proxies-with-unscopables.js Thu Aug 7
08:39:21 2014 UTC
@@ -0,0 +1,153 @@
+// Copyright 2014 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: --harmony-unscopables
+// Flags: --harmony-proxies
+
+
+// TODO(arv): Once proxies can intercept symbols, add more tests.
+
+
+function TestBasics() {
+ var log = [];
+
+ var proxy = Proxy.create({
+ getPropertyDescriptor: function(key) {
+ log.push(key);
+ if (key === 'x') {
+ return {
+ value: 1,
+ configurable: true
+ };
+ }
+ return undefined;
+ }
+ });
+
+ var x = 'local';
+
+ with (proxy) {
+ assertEquals(1, x);
+ }
+
+ // One 'x' for HasBinding and one for GetBindingValue
+ assertEquals(['assertEquals', 'x', 'x'], log);
+}
+TestBasics();
+
+
+function TestInconsistent() {
+ var log = [];
+ var calls = 0;
+
+ var proxy = Proxy.create({
+ getPropertyDescriptor: function(key) {
+ log.push(key);
+ if (key === 'x' && calls < 1) {
+ calls++;
+ return {
+ value: 1,
+ configurable: true
+ };
+ }
+ return undefined;
+ }
+ });
+
+ var x = 'local';
+
+ with (proxy) {
+ assertEquals(void 0, x);
+ }
+
+ // One 'x' for HasBinding and one for GetBindingValue
+ assertEquals(['assertEquals', 'x', 'x'], log);
+}
+TestInconsistent();
+
+
+function TestUseProxyAsUnscopables() {
+ var x = 1;
+ var object = {
+ x: 2
+ };
+ var calls = 0;
+ var proxy = Proxy.create({
+ has: function(key) {
+ calls++;
+ assertEquals('x', key);
+ return calls === 2;
+ },
+ getPropertyDescriptor: function(key) {
+ assertUnreachable();
+ }
+ });
+
+ object[Symbol.unscopables] = proxy;
+
+ with (object) {
+ assertEquals(2, x);
+ assertEquals(1, x);
+ }
+
+ // HasBinding, HasBinding
+ assertEquals(2, calls);
+}
+TestUseProxyAsUnscopables();
+
+
+function TestThrowInHasUnscopables() {
+ var x = 1;
+ var object = {
+ x: 2
+ };
+
+ function CustomError() {}
+
+ var calls = 0;
+ var proxy = Proxy.create({
+ has: function(key) {
+ if (calls++ === 0) {
+ throw new CustomError();
+ }
+ assertUnreachable();
+ },
+ getPropertyDescriptor: function(key) {
+ assertUnreachable();
+ }
+ });
+
+ object[Symbol.unscopables] = proxy;
+
+ assertThrows(function() {
+ with (object) {
+ x;
+ }
+ }, CustomError);
+}
+TestThrowInHasUnscopables();
+
+
+var global = this;
+function TestGlobalShouldIgnoreUnscopables() {
+ global.x = 1;
+ var proxy = Proxy.create({
+ getPropertyDescriptor: function() {
+ assertUnreachable();
+ }
+ });
+ global[Symbol.unscopables] = proxy;
+
+ assertEquals(1, global.x);
+ assertEquals(1, x);
+
+ global.x = 2;
+ assertEquals(2, global.x);
+ assertEquals(2, x);
+
+ x = 3;
+ assertEquals(3, global.x);
+ assertEquals(3, x);
+}
+TestGlobalShouldIgnoreUnscopables();
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/harmony/unscopables.js Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,664 @@
+// Copyright 2014 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: --harmony-unscopables
+// Flags: --harmony-collections
+
+var global = this;
+var globalProto = Object.getPrototypeOf(global);
+
+// Number of objects being tested. There is an assert ensuring this is
correct.
+var objectCount = 21;
+
+
+function runTest(f) {
+ function restore(object, oldProto) {
+ delete object[Symbol.unscopables];
+ delete object.x;
+ delete object.x_;
+ delete object.y;
+ delete object.z;
+ Object.setPrototypeOf(object, oldProto);
+ }
+
+ function getObject(i) {
+ var objects = [
+ {},
+ [],
+ function() {},
+ function() {
+ return arguments;
+ }(),
+ function() {
+ 'use strict';
+ return arguments;
+ }(),
+ Object(1),
+ Object(true),
+ Object('bla'),
+ new Date,
+ new RegExp,
+ new Set,
+ new Map,
+ new WeakMap,
+ new WeakSet,
+ new ArrayBuffer(10),
+ new Int32Array(5),
+ Object,
+ Function,
+ Date,
+ RegExp,
+ global
+ ];
+
+ assertEquals(objectCount, objects.length);
+ return objects[i];
+ }
+
+ // Tests depends on this not being there to start with.
+ delete Array.prototype[Symbol.unscopables];
+
+ if (f.length === 1) {
+ for (var i = 0; i < objectCount; i++) {
+ var object = getObject(i);
+ var oldObjectProto = Object.getPrototypeOf(object);
+ f(object);
+ restore(object, oldObjectProto);
+ }
+ } else {
+ for (var i = 0; i < objectCount; i++) {
+ for (var j = 0; j < objectCount; j++) {
+ var object = getObject(i);
+ var proto = getObject(j);
+ if (object === proto) {
+ continue;
+ }
+ var oldObjectProto = Object.getPrototypeOf(object);
+ var oldProtoProto = Object.getPrototypeOf(proto);
+ f(object, proto);
+ restore(object, oldObjectProto);
+ restore(proto, oldProtoProto);
+ }
+ }
+ }
+}
+
+// Test array first, since other tests are changing
+// Array.prototype[Symbol.unscopables].
+function TestArrayPrototypeUnscopables() {
+ var descr = Object.getOwnPropertyDescriptor(Array.prototype,
+ Symbol.unscopables);
+ assertFalse(descr.enumerable);
+ assertFalse(descr.writable);
+ assertTrue(descr.configurable);
+ assertEquals(null, Object.getPrototypeOf(descr.value));
+
+ var copyWithin = 'local copyWithin';
+ var entries = 'local entries';
+ var fill = 'local fill';
+ var find = 'local find';
+ var findIndex = 'local findIndex';
+ var keys = 'local keys';
+ var values = 'local values';
+
+ var array = [];
+ array.toString = 42;
+
+ with (array) {
+ assertEquals('local copyWithin', copyWithin);
+ assertEquals('local entries', entries);
+ assertEquals('local fill', fill);
+ assertEquals('local find', find);
+ assertEquals('local findIndex', findIndex);
+ assertEquals('local keys', keys);
+ assertEquals('local values', values);
+ assertEquals(42, toString);
+ }
+}
+TestArrayPrototypeUnscopables();
+
+
+
+function TestBasics(object) {
+ var x = 1;
+ var y = 2;
+ var z = 3;
+ object.x = 4;
+ object.y = 5;
+
+ with (object) {
+ assertEquals(4, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+
+ object[Symbol.unscopables] = {x: 0, y: true};
+ with (object) {
+ assertEquals(1, x);
+ assertEquals(2, y);
+ assertEquals(3, z);
+ }
+}
+runTest(TestBasics);
+
+
+function TestUnscopableChain(object) {
+ var x = 1;
+ object.x = 2;
+
+ with (object) {
+ assertEquals(2, x);
+ }
+
+ object[Symbol.unscopables] = {
+ __proto__: {x: true}
+ };
+ with (object) {
+ assertEquals(1, x);
+ }
+}
+runTest(TestUnscopableChain);
+
+
+function TestBasicsSet(object) {
+ var x = 1;
+ object.x = 2;
+
+ with (object) {
+ assertEquals(2, x);
+ }
+
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ x = 3;
+ assertEquals(3, x);
+ }
+
+ assertEquals(3, x);
+ assertEquals(2, object.x);
+}
+runTest(TestBasicsSet);
+
+
+function TestOnProto(object, proto) {
+ var x = 1;
+ var y = 2;
+ var z = 3;
+ proto.x = 4;
+
+ Object.setPrototypeOf(object, proto);
+ object.y = 5;
+
+ with (object) {
+ assertEquals(4, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+
+ proto[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+
+ object[Symbol.unscopables] = {y: true};
+ with (object) {
+ assertEquals(4, x);
+ assertEquals(2, y);
+ assertEquals(3, z);
+ }
+
+ proto[Symbol.unscopables] = {y: true};
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+}
+runTest(TestOnProto);
+
+
+function TestSetBlockedOnProto(object, proto) {
+ var x = 1;
+ object.x = 2;
+
+ with (object) {
+ assertEquals(2, x);
+ }
+
+ Object.setPrototypeOf(object, proto);
+ proto[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ x = 3;
+ assertEquals(3, x);
+ }
+
+ assertEquals(3, x);
+ assertEquals(2, object.x);
+}
+runTest(TestSetBlockedOnProto);
+
+
+function TestNonObject(object) {
+ var x = 1;
+ var y = 2;
+ object.x = 3;
+ object.y = 4;
+
+ object[Symbol.unscopables] = 'xy';
+ with (object) {
+ assertEquals(3, x);
+ assertEquals(4, y);
+ }
+
+ object[Symbol.unscopables] = null;
+ with (object) {
+ assertEquals(3, x);
+ assertEquals(4, y);
+ }
+}
+runTest(TestNonObject);
+
+
+function TestChangeDuringWith(object) {
+ var x = 1;
+ var y = 2;
+ object.x = 3;
+ object.y = 4;
+
+ with (object) {
+ assertEquals(3, x);
+ assertEquals(4, y);
+ object[Symbol.unscopables] = {x: true};
+ assertEquals(1, x);
+ assertEquals(4, y);
+ }
+}
+runTest(TestChangeDuringWith);
+
+
+function TestChangeDuringWithWithPossibleOptimization(object) {
+ var x = 1;
+ object.x = 2;
+ with (object) {
+ for (var i = 0; i < 1000; i++) {
+ if (i === 500) object[Symbol.unscopables] = {x: true};
+ assertEquals(i < 500 ? 2: 1, x);
+ }
+ }
+}
+TestChangeDuringWithWithPossibleOptimization({});
+
+
+function TestChangeDuringWithWithPossibleOptimization2(object) {
+ var x = 1;
+ object.x = 2;
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ for (var i = 0; i < 1000; i++) {
+ if (i === 500) delete object[Symbol.unscopables];
+ assertEquals(i < 500 ? 1 : 2, x);
+ }
+ }
+}
+TestChangeDuringWithWithPossibleOptimization2({});
+
+
+function TestChangeDuringWithWithPossibleOptimization3(object) {
+ var x = 1;
+ object.x = 2;
+ object[Symbol.unscopables] = {};
+ with (object) {
+ for (var i = 0; i < 1000; i++) {
+ if (i === 500) object[Symbol.unscopables].x = true;
+ assertEquals(i < 500 ? 2 : 1, x);
+ }
+ }
+}
+TestChangeDuringWithWithPossibleOptimization3({});
+
+
+function TestChangeDuringWithWithPossibleOptimization4(object) {
+ var x = 1;
+ object.x = 2;
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ for (var i = 0; i < 1000; i++) {
+ if (i === 500) delete object[Symbol.unscopables].x;
+ assertEquals(i < 500 ? 1 : 2, x);
+ }
+ }
+}
+TestChangeDuringWithWithPossibleOptimization4({});
+
+
+function TestAccessorReceiver(object, proto) {
+ var x = 'local';
+
+ Object.defineProperty(proto, 'x', {
+ get: function() {
+ assertEquals(object, this);
+ return this.x_;
+ },
+ configurable: true
+ });
+ proto.x_ = 'proto';
+
+ Object.setPrototypeOf(object, proto);
+ proto.x_ = 'object';
+
+ with (object) {
+ assertEquals('object', x);
+ }
+}
+runTest(TestAccessorReceiver);
+
+
+function TestUnscopablesGetter(object) {
+ // This test gets really messy when object is the global since the assert
+ // functions are properties on the global object and the call count gets
+ // completely different.
+ if (object === global) return;
+
+ var x = 'local';
+ object.x = 'object';
+
+ var callCount = 0;
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ callCount++;
+ return {};
+ },
+ configurable: true
+ });
+ with (object) {
+ assertEquals('object', x);
+ }
+ // Once for HasBinding
+ assertEquals(1, callCount);
+
+ callCount = 0;
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ callCount++;
+ return {x: true};
+ },
+ configurable: true
+ });
+ with (object) {
+ assertEquals('local', x);
+ }
+ // Once for HasBinding
+ assertEquals(1, callCount);
+
+ callCount = 0;
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ callCount++;
+ return callCount == 1 ? {} : {x: true};
+ },
+ configurable: true
+ });
+ with (object) {
+ x = 1;
+ }
+ // Once for HasBinding
+ assertEquals(1, callCount);
+ assertEquals(1, object.x);
+ assertEquals('local', x);
+ with (object) {
+ x = 2;
+ }
+ // One more HasBinding.
+ assertEquals(2, callCount);
+ assertEquals(1, object.x);
+ assertEquals(2, x);
+}
+runTest(TestUnscopablesGetter);
+
+
+var global = this;
+function TestUnscopablesGetter2() {
+ var x = 'local';
+
+ var globalProto = Object.getPrototypeOf(global);
+ var protos = [{}, [], function() {}, global];
+ var objects = [{}, [], function() {}];
+
+ protos.forEach(function(proto) {
+ objects.forEach(function(object) {
+ Object.defineProperty(proto, 'x', {
+ get: function() {
+ assertEquals(object, this);
+ return 'proto';
+ },
+ configurable: true
+ });
+
+ object.__proto__ = proto;
+ Object.defineProperty(object, 'x', {
+ get: function() {
+ assertEquals(object, this);
+ return 'object';
+ },
+ configurable: true
+ });
+
+ with (object) {
+ assertEquals('object', x);
+ }
+
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals('local', x);
+ }
+
+ delete proto[Symbol.unscopables];
+ delete object[Symbol.unscopables];
+ });
+ });
+
+ delete global.x;
+ Object.setPrototypeOf(global, globalProto);
+}
+TestUnscopablesGetter2();
+
+
+function TestSetterOnBlacklisted(object, proto) {
+ var x = 'local';
+ Object.defineProperty(proto, 'x', {
+ set: function(x) {
+ assertUnreachable();
+ },
+ get: function() {
+ return 'proto';
+ },
+ configurable: true
+ });
+ Object.setPrototypeOf(object, proto);
+ Object.defineProperty(object, 'x', {
+ get: function() {
+ return this.x_;
+ },
+ set: function(x) {
+ this.x_ = x;
+ },
+ configurable: true
+ });
+ object.x_ = 1;
+
+ with (object) {
+ x = 2;
+ assertEquals(2, x);
+ }
+
+ assertEquals(2, object.x);
+
+ object[Symbol.unscopables] = {x: true};
+
+ with (object) {
+ x = 3;
+ assertEquals(3, x);
+ }
+
+ assertEquals(2, object.x);
+}
+runTest(TestSetterOnBlacklisted);
+
+
+function TestObjectsAsUnscopables(object, unscopables) {
+ var x = 1;
+ object.x = 2;
+
+ with (object) {
+ assertEquals(2, x);
+ object[Symbol.unscopables] = unscopables;
+ assertEquals(2, x);
+ }
+}
+runTest(TestObjectsAsUnscopables);
+
+
+function TestAccessorOnUnscopables(object) {
+ var x = 1;
+ object.x = 2;
+
+ var unscopables = {
+ get x() {
+ assertUnreachable();
+ }
+ };
+
+ with (object) {
+ assertEquals(2, x);
+ object[Symbol.unscopables] = unscopables;
+ assertEquals(1, x);
+ }
+}
+runTest(TestAccessorOnUnscopables);
+
+
+function TestLengthUnscopables(object, proto) {
+ var length = 2;
+ with (object) {
+ assertEquals(1, length);
+ object[Symbol.unscopables] = {length: true};
+ assertEquals(2, length);
+ delete object[Symbol.unscopables];
+ assertEquals(1, length);
+ }
+}
+TestLengthUnscopables([1], Array.prototype);
+TestLengthUnscopables(function(x) {}, Function.prototype);
+TestLengthUnscopables(new String('x'), String.prototype);
+
+
+function TestFunctionNameUnscopables(object) {
+ var name = 'local';
+ with (object) {
+ assertEquals('f', name);
+ object[Symbol.unscopables] = {name: true};
+ assertEquals('local', name);
+ delete object[Symbol.unscopables];
+ assertEquals('f', name);
+ }
+}
+TestFunctionNameUnscopables(function f() {});
+
+
+function TestFunctionPrototypeUnscopables() {
+ var prototype = 'local';
+ var f = function() {};
+ var g = function() {};
+ Object.setPrototypeOf(f, g);
+ var fp = f.prototype;
+ var gp = g.prototype;
+ with (f) {
+ assertEquals(fp, prototype);
+ f[Symbol.unscopables] = {prototype: true};
+ assertEquals('local', prototype);
+ delete f[Symbol.unscopables];
+ assertEquals(fp, prototype);
+ }
+}
+TestFunctionPrototypeUnscopables(function() {});
+
+
+function TestFunctionArgumentsUnscopables() {
+ var func = function() {
+ var arguments = 'local';
+ var args = func.arguments;
+ with (func) {
+ assertEquals(args, arguments);
+ func[Symbol.unscopables] = {arguments: true};
+ assertEquals('local', arguments);
+ delete func[Symbol.unscopables];
+ assertEquals(args, arguments);
+ }
+ }
+ func(1);
+}
+TestFunctionArgumentsUnscopables();
+
+
+function TestArgumentsLengthUnscopables() {
+ var func = function() {
+ var length = 'local';
+ with (arguments) {
+ assertEquals(1, length);
+ arguments[Symbol.unscopables] = {length: true};
+ assertEquals('local', length);
+ }
+ }
+ func(1);
+}
+TestArgumentsLengthUnscopables();
+
+
+function TestFunctionCallerUnscopables() {
+ var func = function() {
+ var caller = 'local';
+ with (func) {
+ assertEquals(TestFunctionCallerUnscopables, caller);
+ func[Symbol.unscopables] = {caller: true};
+ assertEquals('local', caller);
+ delete func[Symbol.unscopables];
+ assertEquals(TestFunctionCallerUnscopables, caller);
+ }
+ }
+ func(1);
+}
+TestFunctionCallerUnscopables();
+
+
+function TestGetUnscopablesGetterThrows() {
+ var object = {
+ get x() {
+ assertUnreachable();
+ }
+ };
+ function CustomError() {}
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ throw new CustomError();
+ }
+ });
+ assertThrows(function() {
+ with (object) {
+ x;
+ }
+ }, CustomError);
+}
+TestGetUnscopablesGetterThrows();
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/runtime-gen/debugpoppromise.js Thu Aug 7 08:39:21
2014 UTC
@@ -0,0 +1,4 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony
+%DebugPopPromise();
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/runtime-gen/debugpromiserejectevent.js Thu Aug 7
08:39:21 2014 UTC
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony
+var _promise = new Object();
+var _value = new Object();
+%DebugPromiseRejectEvent(_promise, _value);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/runtime-gen/debugpushpromise.js Thu Aug 7 08:39:21
2014 UTC
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony
+var _promise = new Object();
+%DebugPushPromise(_promise);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/runtime-gen/rempio2.js Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony
+var _x = 1.5;
+%RemPiO2(_x);
=======================================
--- /dev/null
+++ /trunk/third_party/fdlibm/LICENSE Thu Aug 7 08:39:21 2014 UTC
@@ -0,0 +1,6 @@
+Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+
+Developed at SunSoft, a Sun Microsystems, Inc. business.
+Permission to use, copy, modify, and distribute this
+software is freely granted, provided that this notice
+is preserved.
=======================================
***Additional files exist in this changeset.***
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.