diff options
Diffstat (limited to 'deps/v8/test')
654 files changed, 32745 insertions, 6890 deletions
diff --git a/deps/v8/test/benchmarks/benchmarks.status b/deps/v8/test/benchmarks/benchmarks.status index 103eaeb126..d651b3c0f0 100644 --- a/deps/v8/test/benchmarks/benchmarks.status +++ b/deps/v8/test/benchmarks/benchmarks.status @@ -25,9 +25,9 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# Too slow in Debug mode. [ -['mode == debug', { - # Too slow in Debug mode. - 'octane/mandreel': [SKIP], -}], # 'mode == debug' +[ALWAYS, { + 'octane/mandreel': [PASS, ['mode == debug', SKIP]], +}], # ALWAYS ] diff --git a/deps/v8/test/benchmarks/testcfg.py b/deps/v8/test/benchmarks/testcfg.py index b15553a861..c94a35ffd9 100644 --- a/deps/v8/test/benchmarks/testcfg.py +++ b/deps/v8/test/benchmarks/testcfg.py @@ -64,7 +64,7 @@ class BenchmarksTestSuite(testsuite.TestSuite): "octane/crypto", "octane/deltablue", "octane/earley-boyer", - "octane/gbemu", + "octane/gbemu-part1", "octane/mandreel", "octane/navier-stokes", "octane/pdfjs", @@ -72,6 +72,8 @@ class BenchmarksTestSuite(testsuite.TestSuite): "octane/regexp", "octane/richards", "octane/splay", + "octane/typescript", + "octane/zlib", "sunspider/3d-cube", "sunspider/3d-morph", @@ -111,6 +113,14 @@ class BenchmarksTestSuite(testsuite.TestSuite): elif testcase.path.startswith("octane"): result.append(os.path.join(self.testroot, "octane/base.js")) result.append(os.path.join(self.testroot, "%s.js" % testcase.path)) + if testcase.path.startswith("octane/gbemu"): + result.append(os.path.join(self.testroot, "octane/gbemu-part2.js")) + elif testcase.path.startswith("octane/typescript"): + result.append(os.path.join(self.testroot, + "octane/typescript-compiler.js")) + result.append(os.path.join(self.testroot, "octane/typescript-input.js")) + elif testcase.path.startswith("octane/zlib"): + result.append(os.path.join(self.testroot, "octane/zlib-data.js")) result += ["-e", "BenchmarkSuite.RunSuites({});"] elif testcase.path.startswith("sunspider"): result.append(os.path.join(self.testroot, "%s.js" % testcase.path)) @@ -158,8 +168,8 @@ class BenchmarksTestSuite(testsuite.TestSuite): self._DownloadIfNecessary( ("http://svn.webkit.org/repository/webkit/trunk/PerformanceTests/" - "SunSpider/tests/sunspider-1.0/"), - "153700", "sunspider") + "SunSpider/tests/sunspider-1.0.2/"), + "159499", "sunspider") self._DownloadIfNecessary( ("http://kraken-mirror.googlecode.com/svn/trunk/kraken/tests/" @@ -168,7 +178,7 @@ class BenchmarksTestSuite(testsuite.TestSuite): self._DownloadIfNecessary( "http://octane-benchmark.googlecode.com/svn/trunk/", - "22", "octane") + "26", "octane") os.chdir(old_cwd) diff --git a/deps/v8/test/cctest/OWNERS b/deps/v8/test/cctest/OWNERS new file mode 100644 index 0000000000..6d5f927e73 --- /dev/null +++ b/deps/v8/test/cctest/OWNERS @@ -0,0 +1,2 @@ +per-file *-mips.*=plind44@gmail.com +per-file *-mips.*=gergely@homejinni.com diff --git a/deps/v8/test/cctest/cctest.cc b/deps/v8/test/cctest/cctest.cc index 4aa9c7eb71..b1cf5abb4e 100644 --- a/deps/v8/test/cctest/cctest.cc +++ b/deps/v8/test/cctest/cctest.cc @@ -27,6 +27,10 @@ #include <v8.h> #include "cctest.h" + +#include "print-extension.h" +#include "profiler-extension.h" +#include "trace-extension.h" #include "debug.h" enum InitializationState {kUnset, kUnintialized, kInitialized}; @@ -141,6 +145,13 @@ int main(int argc, char* argv[]) { CcTestArrayBufferAllocator array_buffer_allocator; v8::V8::SetArrayBufferAllocator(&array_buffer_allocator); + i::PrintExtension print_extension; + v8::RegisterExtension(&print_extension); + i::ProfilerExtension profiler_extension; + v8::RegisterExtension(&profiler_extension); + i::TraceExtension trace_extension; + v8::RegisterExtension(&trace_extension); + int tests_run = 0; bool print_run_count = true; for (int i = 1; i < argc; i++) { @@ -188,6 +199,7 @@ int main(int argc, char* argv[]) { } if (print_run_count && tests_run != 1) printf("Ran %i tests.\n", tests_run); + CcTest::TearDown(); if (!disable_automatic_dispose_) v8::V8::Dispose(); return 0; } diff --git a/deps/v8/test/cctest/cctest.gyp b/deps/v8/test/cctest/cctest.gyp index fbe38f2709..187bdf3236 100644 --- a/deps/v8/test/cctest/cctest.gyp +++ b/deps/v8/test/cctest/cctest.gyp @@ -47,6 +47,8 @@ 'gay-fixed.cc', 'gay-precision.cc', 'gay-shortest.cc', + 'print-extension.cc', + 'profiler-extension.cc', 'test-accessors.cc', 'test-alloc.cc', 'test-api.cc', @@ -80,21 +82,25 @@ 'test-hashmap.cc', 'test-heap.cc', 'test-heap-profiler.cc', + 'test-libplatform-task-queue.cc', + 'test-libplatform-worker-thread.cc', 'test-list.cc', 'test-liveedit.cc', 'test-lockers.cc', 'test-log.cc', + 'test-microtask-delivery.cc', 'test-mark-compact.cc', + 'test-mementos.cc', 'test-mutex.cc', 'test-object-observe.cc', 'test-parsing.cc', 'test-platform.cc', 'test-platform-tls.cc', 'test-profile-generator.cc', - 'test-random.cc', 'test-random-number-generator.cc', 'test-regexp.cc', 'test-reloc-info.cc', + 'test-representation.cc', 'test-semaphore.cc', 'test-serialize.cc', 'test-socket.cc', @@ -112,7 +118,8 @@ 'test-version.cc', 'test-weakmaps.cc', 'test-weaksets.cc', - 'test-weaktypedarrays.cc' + 'test-weaktypedarrays.cc', + 'trace-extension.cc' ], 'conditions': [ ['v8_target_arch=="ia32"', { @@ -122,6 +129,7 @@ 'test-code-stubs-ia32.cc', 'test-cpu-ia32.cc', 'test-disasm-ia32.cc', + 'test-macro-assembler-ia32.cc', 'test-log-stack-tracer.cc' ], }], @@ -144,14 +152,28 @@ 'test-macro-assembler-arm.cc' ], }], + ['v8_target_arch=="a64"', { + 'sources': [ + 'test-utils-a64.cc', + 'test-assembler-a64.cc', + 'test-code-stubs.cc', + 'test-code-stubs-a64.cc', + 'test-disasm-a64.cc', + 'test-fuzz-a64.cc', + 'test-javascript-a64.cc', + 'test-js-a64-variables.cc' + ], + }], ['v8_target_arch=="mipsel"', { 'sources': [ 'test-assembler-mips.cc', + 'test-code-stubs.cc', + 'test-code-stubs-mips.cc', 'test-disasm-mips.cc', 'test-macro-assembler-mips.cc' ], }], - [ 'OS=="linux"', { + [ 'OS=="linux" or OS=="qnx"', { 'sources': [ 'test-platform-linux.cc', ], diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h index 7f84c259f0..d9f76294e1 100644 --- a/deps/v8/test/cctest/cctest.h +++ b/deps/v8/test/cctest/cctest.h @@ -58,10 +58,11 @@ static void Test##Name() #endif -#define EXTENSION_LIST(V) \ - V(GC_EXTENSION, "v8/gc") \ - V(PRINT_EXTENSION, "v8/print") \ - V(TRACE_EXTENSION, "v8/trace") +#define EXTENSION_LIST(V) \ + V(GC_EXTENSION, "v8/gc") \ + V(PRINT_EXTENSION, "v8/print") \ + V(PROFILER_EXTENSION, "v8/profiler") \ + V(TRACE_EXTENSION, "v8/trace") #define DEFINE_EXTENSION_ID(Name, Ident) Name##_ID, enum CcTestExtensionIds { @@ -129,6 +130,10 @@ class CcTest { CcTestExtensionFlags extensions, v8::Isolate* isolate = CcTest::isolate()); + static void TearDown() { + if (isolate_ != NULL) isolate_->Dispose(); + } + private: friend int main(int argc, char** argv); TestFunction* callback_; @@ -255,7 +260,7 @@ class LocalContext { virtual ~LocalContext() { v8::HandleScope scope(isolate_); v8::Local<v8::Context>::New(isolate_, context_)->Exit(); - context_.Dispose(); + context_.Reset(); } v8::Context* operator->() { @@ -289,12 +294,12 @@ class LocalContext { }; static inline v8::Local<v8::Value> v8_num(double x) { - return v8::Number::New(x); + return v8::Number::New(v8::Isolate::GetCurrent(), x); } static inline v8::Local<v8::String> v8_str(const char* x) { - return v8::String::New(x); + return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x); } @@ -305,7 +310,8 @@ static inline v8::Local<v8::Script> v8_compile(const char* x) { // Helper function that compiles and runs the source. static inline v8::Local<v8::Value> CompileRun(const char* source) { - return v8::Script::Compile(v8::String::New(source))->Run(); + return v8::Script::Compile( + v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), source))->Run(); } @@ -314,10 +320,12 @@ static inline v8::Local<v8::Value> CompileRunWithOrigin(const char* source, const char* origin_url, int line_number, int column_number) { - v8::ScriptOrigin origin(v8::String::New(origin_url), - v8::Integer::New(line_number), - v8::Integer::New(column_number)); - return v8::Script::Compile(v8::String::New(source), &origin)->Run(); + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::ScriptOrigin origin(v8::String::NewFromUtf8(isolate, origin_url), + v8::Integer::New(isolate, line_number), + v8::Integer::New(isolate, column_number)); + return v8::Script::Compile(v8::String::NewFromUtf8(isolate, source), &origin) + ->Run(); } @@ -332,6 +340,7 @@ static inline int FlagDependentPortOffset() { static inline void SimulateFullSpace(v8::internal::NewSpace* space) { int new_linear_size = static_cast<int>( *space->allocation_limit_address() - *space->allocation_top_address()); + if (new_linear_size == 0) return; v8::internal::MaybeObject* maybe = space->AllocateRaw(new_linear_size); v8::internal::FreeListNode* node = v8::internal::FreeListNode::cast(maybe); node->set_size(space->heap(), new_linear_size); @@ -340,9 +349,7 @@ static inline void SimulateFullSpace(v8::internal::NewSpace* space) { // Helper function that simulates a full old-space in the heap. static inline void SimulateFullSpace(v8::internal::PagedSpace* space) { - int old_linear_size = static_cast<int>(space->limit() - space->top()); - space->Free(space->top(), old_linear_size); - space->SetTop(space->limit(), space->limit()); + space->EmptyAllocationInfo(); space->ResetFreeList(); space->ClearStats(); } @@ -356,13 +363,13 @@ class HeapObjectsTracker { HeapObjectsTracker() { heap_profiler_ = i::Isolate::Current()->heap_profiler(); CHECK_NE(NULL, heap_profiler_); - heap_profiler_->StartHeapAllocationsRecording(); + heap_profiler_->StartHeapObjectsTracking(true); } ~HeapObjectsTracker() { i::Isolate::Current()->heap()->CollectAllAvailableGarbage(); - CHECK_EQ(0, heap_profiler_->FindUntrackedObjects()); - heap_profiler_->StopHeapAllocationsRecording(); + CHECK_EQ(0, heap_profiler_->heap_object_map()->FindUntrackedObjects()); + heap_profiler_->StopHeapObjectsTracking(); } private: diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status index 59bf8268e9..f149ebe297 100644 --- a/deps/v8/test/cctest/cctest.status +++ b/deps/v8/test/cctest/cctest.status @@ -60,9 +60,84 @@ # running several variants. Note that this still takes ages, because there # are actually 13 * 38 * 5 * 128 = 316160 individual tests hidden here. 'test-parsing/ParserSync': [PASS, NO_VARIANTS], + + ############################################################################ + # Slow tests. + 'test-api/Threading1': [PASS, ['mode == debug', SLOW]], + 'test-api/Threading2': [PASS, ['mode == debug', SLOW]], + 'test-api/Threading3': [PASS, ['mode == debug', SLOW]], + 'test-api/Threading4': [PASS, ['mode == debug', SLOW]], }], # ALWAYS ############################################################################## +['arch == a64', { + + 'test-api/Bug618': [PASS], + + # BUG(v8:2999). + 'test-cpu-profiler/CollectCpuProfile': [PASS, FAIL], + + # Runs out of memory in debug mode. + 'test-api/OutOfMemory': [PASS, ['mode == debug', FAIL]], + 'test-api/OutOfMemoryNested': [PASS, ['mode == debug', FAIL]], + + # BUG(v8:3154). + 'test-heap/ReleaseOverReservedPages': [PASS, ['mode == debug', FAIL]], + + # BUG(v8:3155). + 'test-strings/AsciiArrayJoin': [PASS, ['mode == debug', FAIL]], +}], # 'arch == a64' + +['arch == a64 and simulator_run == True', { + + # Pass but take too long with the simulator. + 'test-api/ExternalArrays': [PASS, TIMEOUT], + 'test-api/Threading1': [SKIP], +}], # 'arch == a64 and simulator_run == True' + +['arch == a64 and mode == debug and simulator_run == True', { + + # Pass but take too long with the simulator in debug mode. + 'test-api/ExternalDoubleArray': [SKIP], + 'test-api/ExternalFloat32Array': [SKIP], + 'test-api/ExternalFloat64Array': [SKIP], + 'test-api/ExternalFloatArray': [SKIP], + 'test-api/Float32Array': [SKIP], + 'test-api/Float64Array': [SKIP], + 'test-debug/DebugBreakLoop': [SKIP], +}], # 'arch == a64 and mode == debug and simulator_run == True' + +############################################################################## +['asan == True', { + # Skip tests not suitable for ASAN. + 'test-assembler-x64/AssemblerX64XchglOperations': [SKIP], + 'test-lockers/MultithreadedParallelIsolates': [SKIP], +}], # 'asan == True' + +############################################################################## +['system == windows', { + + # BUG(2999). + 'test-cpu-profiler/CollectCpuProfile': [PASS, FAIL], + 'test-cpu-profiler/JsNativeJsSample': [PASS, FLAKY], + + # BUG(3055). + 'test-cpu-profiler/JsNative1JsNative2JsSample': [PASS, ['mode == release', FAIL], ['mode == debug', FLAKY]], + + # BUG(3005). + 'test-alloc/CodeRange': [PASS, FAIL], +}], # 'system == windows' + +############################################################################## +['system == macos', { + + # BUG(3125). + 'test-debug/DebugGetLoadedScripts': [PASS, FLAKY], + 'test-debug/DebugStepLinear': [PASS, FLAKY], + 'test-debug/DebuggerClearMessageHandler': [PASS, FLAKY], +}], # 'system == macos' + +############################################################################## ['arch == arm', { # We cannot assume that we can throw OutOfMemory exceptions in all situations. @@ -79,7 +154,18 @@ 'test-serialize/DeserializeFromSecondSerializationAndRunScript2': [SKIP], 'test-serialize/DeserializeAndRunScript2': [SKIP], 'test-serialize/DeserializeFromSecondSerialization': [SKIP], + + # BUG(2999). + 'test-cpu-profiler/CollectCpuProfile': [PASS, FLAKY], + + ############################################################################ + # Slow tests. + 'test-api/Threading1': [PASS, SLOW], + 'test-api/Threading2': [PASS, SLOW], + 'test-api/Threading3': [PASS, SLOW], + 'test-api/Threading4': [PASS, SLOW], }], # 'arch == arm' + ############################################################################## ['arch == mipsel', { @@ -132,5 +218,11 @@ # Fails since 16322 (new test). 'test-code-stubs-arm/ConvertDToI': [SKIP], + + # BUG(2998). + 'test-macro-assembler-arm/LoadAndStoreWithRepresentation': [SKIP], + + # BUG(3150). + 'test-api/PreCompileInvalidPreparseDataError': [SKIP], }], # 'arch == nacl_ia32 or arch == nacl_x64' ] diff --git a/deps/v8/test/cctest/print-extension.cc b/deps/v8/test/cctest/print-extension.cc new file mode 100644 index 0000000000..9f629195bd --- /dev/null +++ b/deps/v8/test/cctest/print-extension.cc @@ -0,0 +1,51 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "print-extension.h" + +namespace v8 { +namespace internal { + +v8::Handle<v8::FunctionTemplate> PrintExtension::GetNativeFunctionTemplate( + v8::Isolate* isolate, + v8::Handle<v8::String> str) { + return v8::FunctionTemplate::New(isolate, PrintExtension::Print); +} + + +void PrintExtension::Print(const v8::FunctionCallbackInfo<v8::Value>& args) { + for (int i = 0; i < args.Length(); i++) { + if (i != 0) printf(" "); + v8::HandleScope scope(args.GetIsolate()); + v8::String::Utf8Value str(args[i]); + if (*str == NULL) return; + printf("%s", *str); + } + printf("\n"); +} + +} } // namespace v8::internal diff --git a/deps/v8/test/cctest/print-extension.h b/deps/v8/test/cctest/print-extension.h new file mode 100644 index 0000000000..7fe9226f7b --- /dev/null +++ b/deps/v8/test/cctest/print-extension.h @@ -0,0 +1,47 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef V8_TEST_CCTEST_PRINT_EXTENSION_H_ +#define V8_TEST_CCTEST_PRINT_EXTENSION_H_ + +#include "v8.h" + +namespace v8 { +namespace internal { + +class PrintExtension : public v8::Extension { + public: + PrintExtension() : v8::Extension("v8/print", "native function print();") { } + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( + v8::Isolate* isolate, + v8::Handle<v8::String> name); + static void Print(const v8::FunctionCallbackInfo<v8::Value>& args); +}; + +} } // namespace v8::internal + +#endif diff --git a/deps/v8/test/cctest/profiler-extension.cc b/deps/v8/test/cctest/profiler-extension.cc new file mode 100644 index 0000000000..80d9f90412 --- /dev/null +++ b/deps/v8/test/cctest/profiler-extension.cc @@ -0,0 +1,75 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Tests of profiles generator and utilities. + +#include "profiler-extension.h" +#include "checks.h" + +namespace v8 { +namespace internal { + + +const v8::CpuProfile* ProfilerExtension::last_profile = NULL; +const char* ProfilerExtension::kSource = + "native function startProfiling();" + "native function stopProfiling();"; + +v8::Handle<v8::FunctionTemplate> ProfilerExtension::GetNativeFunctionTemplate( + v8::Isolate* isolate, v8::Handle<v8::String> name) { + if (name->Equals(v8::String::NewFromUtf8(isolate, "startProfiling"))) { + return v8::FunctionTemplate::New(isolate, + ProfilerExtension::StartProfiling); + } else if (name->Equals(v8::String::NewFromUtf8(isolate, "stopProfiling"))) { + return v8::FunctionTemplate::New(isolate, + ProfilerExtension::StopProfiling); + } else { + CHECK(false); + return v8::Handle<v8::FunctionTemplate>(); + } +} + + +void ProfilerExtension::StartProfiling( + const v8::FunctionCallbackInfo<v8::Value>& args) { + last_profile = NULL; + v8::CpuProfiler* cpu_profiler = args.GetIsolate()->GetCpuProfiler(); + cpu_profiler->StartCpuProfiling((args.Length() > 0) + ? args[0].As<v8::String>() + : v8::String::Empty(args.GetIsolate())); +} + + +void ProfilerExtension::StopProfiling( + const v8::FunctionCallbackInfo<v8::Value>& args) { + v8::CpuProfiler* cpu_profiler = args.GetIsolate()->GetCpuProfiler(); + last_profile = cpu_profiler->StopCpuProfiling((args.Length() > 0) + ? args[0].As<v8::String>() + : v8::String::Empty(args.GetIsolate())); +} + +} } // namespace v8::internal diff --git a/deps/v8/test/cctest/profiler-extension.h b/deps/v8/test/cctest/profiler-extension.h new file mode 100644 index 0000000000..392a7efbc7 --- /dev/null +++ b/deps/v8/test/cctest/profiler-extension.h @@ -0,0 +1,54 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Tests of profiles generator and utilities. + +#ifndef V8_TEST_CCTEST_PROFILER_EXTENSION_H_ +#define V8_TEST_CCTEST_PROFILER_EXTENSION_H_ + +#include "../include/v8-profiler.h" + +namespace v8 { +namespace internal { + +class ProfilerExtension : public v8::Extension { + public: + ProfilerExtension() : v8::Extension("v8/profiler", kSource) { } + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( + v8::Isolate* isolate, + v8::Handle<v8::String> name); + static void StartProfiling(const v8::FunctionCallbackInfo<v8::Value>& args); + static void StopProfiling(const v8::FunctionCallbackInfo<v8::Value>& args); + static const v8::CpuProfile* last_profile; + private: + static const char* kSource; +}; + + +} } // namespace v8::internal + +#endif diff --git a/deps/v8/test/cctest/test-accessors.cc b/deps/v8/test/cctest/test-accessors.cc index df4937ee28..daafb244e3 100644 --- a/deps/v8/test/cctest/test-accessors.cc +++ b/deps/v8/test/cctest/test-accessors.cc @@ -65,11 +65,12 @@ static void handle_property(const v8::FunctionCallbackInfo<v8::Value>& info) { THREADED_TEST(PropertyHandler) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); fun_templ->InstanceTemplate()->SetAccessor(v8_str("foo"), handle_property); Local<v8::FunctionTemplate> getter_templ = - v8::FunctionTemplate::New(handle_property); + v8::FunctionTemplate::New(isolate, handle_property); getter_templ->SetLength(0); fun_templ-> InstanceTemplate()->SetAccessorProperty(v8_str("bar"), getter_templ); @@ -120,20 +121,18 @@ THREADED_TEST(GlobalVariableAccess) { foo = 0; bar = -4; baz = 10; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); - templ->InstanceTemplate()->SetAccessor(v8_str("foo"), - GetIntValue, - SetIntValue, - v8::External::New(&foo)); - templ->InstanceTemplate()->SetAccessor(v8_str("bar"), - GetIntValue, - SetIntValue, - v8::External::New(&bar)); - templ->InstanceTemplate()->SetAccessor(v8_str("baz"), - GetIntValue, - SetIntValue, - v8::External::New(&baz)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); + templ->InstanceTemplate()->SetAccessor( + v8_str("foo"), GetIntValue, SetIntValue, + v8::External::New(isolate, &foo)); + templ->InstanceTemplate()->SetAccessor( + v8_str("bar"), GetIntValue, SetIntValue, + v8::External::New(isolate, &bar)); + templ->InstanceTemplate()->SetAccessor( + v8_str("baz"), GetIntValue, SetIntValue, + v8::External::New(isolate, &baz)); LocalContext env(0, templ->InstanceTemplate()); v8_compile("foo = (++bar) + baz")->Run(); CHECK_EQ(bar, -3); @@ -175,6 +174,7 @@ static void XSetter(Local<Value> value, const Info& info, int offset) { CHECK_EQ(x_holder, info.This()); CHECK_EQ(x_holder, info.Holder()); x_register[offset] = value->Int32Value(); + info.GetReturnValue().Set(v8_num(-1)); } @@ -193,36 +193,38 @@ static void XSetter(const v8::FunctionCallbackInfo<v8::Value>& info) { THREADED_TEST(AccessorIC) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("x0"), XGetter, XSetter); obj->SetAccessorProperty(v8_str("x1"), - v8::FunctionTemplate::New(XGetter), - v8::FunctionTemplate::New(XSetter)); + v8::FunctionTemplate::New(isolate, XGetter), + v8::FunctionTemplate::New(isolate, XSetter)); x_holder = obj->NewInstance(); context->Global()->Set(v8_str("holder"), x_holder); - x_receiver = v8::Object::New(); + x_receiver = v8::Object::New(isolate); context->Global()->Set(v8_str("obj"), x_receiver); v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(CompileRun( "obj.__proto__ = holder;" "var result = [];" "var key_0 = 'x0';" "var key_1 = 'x1';" - "for (var i = 0; i < 10; i++) {" - " holder.x0 = i;" + "for (var j = 0; j < 10; j++) {" + " var i = 4*j;" + " result.push(holder.x0 = i);" " result.push(obj.x0);" - " holder.x1 = i;" + " result.push(holder.x1 = i + 1);" " result.push(obj.x1);" - " holder[key_0] = i;" + " result.push(holder[key_0] = i + 2);" " result.push(obj[key_0]);" - " holder[key_1] = i;" + " result.push(holder[key_1] = i + 3);" " result.push(obj[key_1]);" "}" "result")); - CHECK_EQ(40, array->Length()); - for (int i = 0; i < 40; i++) { - v8::Handle<Value> entry = array->Get(v8::Integer::New(i)); - CHECK_EQ(v8::Integer::New(i/4), entry); + CHECK_EQ(80, array->Length()); + for (int i = 0; i < 80; i++) { + v8::Handle<Value> entry = array->Get(v8::Integer::New(isolate, i)); + CHECK_EQ(v8::Integer::New(isolate, i/2), entry); } } @@ -237,8 +239,9 @@ static void AccessorProhibitsOverwritingGetter( THREADED_TEST(AccessorProhibitsOverwriting) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), AccessorProhibitsOverwritingGetter, 0, @@ -280,30 +283,32 @@ static void HandleAllocatingGetter( const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); for (int i = 0; i < C; i++) - v8::String::New("foo"); - info.GetReturnValue().Set(v8::String::New("foo")); + v8::String::NewFromUtf8(info.GetIsolate(), "foo"); + info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "foo")); } THREADED_TEST(HandleScopePop) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("one"), HandleAllocatingGetter<1>); obj->SetAccessor(v8_str("many"), HandleAllocatingGetter<1024>); v8::Handle<v8::Object> inst = obj->NewInstance(); - context->Global()->Set(v8::String::New("obj"), inst); - i::Isolate* isolate = CcTest::i_isolate(); - int count_before = i::HandleScope::NumberOfHandles(isolate); + context->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), inst); + int count_before = + i::HandleScope::NumberOfHandles(reinterpret_cast<i::Isolate*>(isolate)); { - v8::HandleScope scope(context->GetIsolate()); + v8::HandleScope scope(isolate); CompileRun( "for (var i = 0; i < 1000; i++) {" " obj.one;" " obj.many;" "}"); } - int count_after = i::HandleScope::NumberOfHandles(isolate); + int count_after = + i::HandleScope::NumberOfHandles(reinterpret_cast<i::Isolate*>(isolate)); CHECK_EQ(count_before, count_after); } @@ -312,30 +317,36 @@ static void CheckAccessorArgsCorrect( const v8::PropertyCallbackInfo<v8::Value>& info) { CHECK(info.GetIsolate() == CcTest::isolate()); CHECK(info.This() == info.Holder()); - CHECK(info.Data()->Equals(v8::String::New("data"))); + CHECK( + info.Data()->Equals(v8::String::NewFromUtf8(CcTest::isolate(), "data"))); ApiTestFuzzer::Fuzz(); CHECK(info.GetIsolate() == CcTest::isolate()); CHECK(info.This() == info.Holder()); - CHECK(info.Data()->Equals(v8::String::New("data"))); + CHECK( + info.Data()->Equals(v8::String::NewFromUtf8(CcTest::isolate(), "data"))); CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); CHECK(info.GetIsolate() == CcTest::isolate()); CHECK(info.This() == info.Holder()); - CHECK(info.Data()->Equals(v8::String::New("data"))); + CHECK( + info.Data()->Equals(v8::String::NewFromUtf8(CcTest::isolate(), "data"))); info.GetReturnValue().Set(17); } THREADED_TEST(DirectCall) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("xxx"), CheckAccessorArgsCorrect, NULL, - v8::String::New("data")); + v8::String::NewFromUtf8(isolate, "data")); v8::Handle<v8::Object> inst = obj->NewInstance(); - context->Global()->Set(v8::String::New("obj"), inst); - Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx")); + context->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), + inst); + Local<Script> scr = v8::Script::Compile( + v8::String::NewFromUtf8(isolate, "obj.xxx")); for (int i = 0; i < 10; i++) { Local<Value> result = scr->Run(); CHECK(!result.IsEmpty()); @@ -356,11 +367,13 @@ THREADED_TEST(EmptyResult) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); - obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("data")); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); + obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, + v8::String::NewFromUtf8(isolate, "data")); v8::Handle<v8::Object> inst = obj->NewInstance(); - context->Global()->Set(v8::String::New("obj"), inst); - Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx")); + context->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), inst); + Local<Script> scr = + v8::Script::Compile(v8::String::NewFromUtf8(isolate, "obj.xxx")); for (int i = 0; i < 10; i++) { Local<Value> result = scr->Run(); CHECK(result == v8::Undefined(isolate)); @@ -374,27 +387,30 @@ THREADED_TEST(NoReuseRegress) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); { - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); - obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("data")); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); + obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, + v8::String::NewFromUtf8(isolate, "data")); LocalContext context; v8::Handle<v8::Object> inst = obj->NewInstance(); - context->Global()->Set(v8::String::New("obj"), inst); - Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx")); + context->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), inst); + Local<Script> scr = + v8::Script::Compile(v8::String::NewFromUtf8(isolate, "obj.xxx")); for (int i = 0; i < 2; i++) { Local<Value> result = scr->Run(); CHECK(result == v8::Undefined(isolate)); } } { - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("xxx"), CheckAccessorArgsCorrect, NULL, - v8::String::New("data")); + v8::String::NewFromUtf8(isolate, "data")); LocalContext context; v8::Handle<v8::Object> inst = obj->NewInstance(); - context->Global()->Set(v8::String::New("obj"), inst); - Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx")); + context->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), inst); + Local<Script> scr = + v8::Script::Compile(v8::String::NewFromUtf8(isolate, "obj.xxx")); for (int i = 0; i < 10; i++) { Local<Value> result = scr->Run(); CHECK(!result.IsEmpty()); @@ -420,8 +436,9 @@ static void ThrowingSetAccessor(Local<String> name, THREADED_TEST(Regress1054726) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("x"), ThrowingGetAccessor, ThrowingSetAccessor, @@ -439,7 +456,8 @@ THREADED_TEST(Regress1054726) { "}; result"))->Run(); CHECK_EQ(v8_str("ggggg"), result); - result = Script::Compile(String::New( + result = Script::Compile(String::NewFromUtf8( + isolate, "var result = '';" "for (var i = 0; i < 5; i++) {" " try { obj.x = i; } catch (e) { result += e; }" @@ -451,17 +469,19 @@ THREADED_TEST(Regress1054726) { static void AllocGetter(Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - info.GetReturnValue().Set(v8::Array::New(1000)); + info.GetReturnValue().Set(v8::Array::New(info.GetIsolate(), 1000)); } THREADED_TEST(Gc) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("xxx"), AllocGetter); env->Global()->Set(v8_str("obj"), obj->NewInstance()); - Script::Compile(String::New( + Script::Compile(String::NewFromUtf8( + isolate, "var last = [];" "for (var i = 0; i < 2048; i++) {" " var result = obj.xxx;" @@ -488,13 +508,15 @@ static void StackCheck(Local<String> name, THREADED_TEST(StackIteration) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate()); - i::StringStream::ClearMentionedObjectCache(isolate); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); + i::StringStream::ClearMentionedObjectCache( + reinterpret_cast<i::Isolate*>(isolate)); obj->SetAccessor(v8_str("xxx"), StackCheck); env->Global()->Set(v8_str("obj"), obj->NewInstance()); - Script::Compile(String::New( + Script::Compile(String::NewFromUtf8( + isolate, "function foo() {" " return obj.xxx;" "}" @@ -509,7 +531,7 @@ static void AllocateHandles(Local<String> name, for (int i = 0; i < i::kHandleBlockSize + 1; i++) { v8::Local<v8::Value>::New(info.GetIsolate(), name); } - info.GetReturnValue().Set(v8::Integer::New(100)); + info.GetReturnValue().Set(v8::Integer::New(info.GetIsolate(), 100)); } @@ -517,11 +539,13 @@ THREADED_TEST(HandleScopeSegment) { // Check that we can return values past popping of handle scope // segments. LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("xxx"), AllocateHandles); env->Global()->Set(v8_str("obj"), obj->NewInstance()); - v8::Handle<v8::Value> result = Script::Compile(String::New( + v8::Handle<v8::Value> result = Script::Compile(String::NewFromUtf8( + isolate, "var result;" "for (var i = 0; i < 4; i++)" " result = obj.xxx;" @@ -531,7 +555,7 @@ THREADED_TEST(HandleScopeSegment) { void JSONStringifyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) { - v8::Handle<v8::Array> array = v8::Array::New(1); + v8::Handle<v8::Array> array = v8::Array::New(info.GetIsolate(), 1); array->Set(0, v8_str("regress")); info.GetReturnValue().Set(array); } @@ -545,9 +569,10 @@ void JSONStringifyGetter(Local<String> name, THREADED_TEST(JSONStringifyNamedInterceptorObject) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetNamedPropertyHandler( JSONStringifyGetter, NULL, NULL, NULL, JSONStringifyEnumerator); env->Global()->Set(v8_str("obj"), obj->NewInstance()); @@ -556,16 +581,47 @@ THREADED_TEST(JSONStringifyNamedInterceptorObject) { } +static v8::Local<v8::Context> expected_current_context; +static v8::Local<v8::Context> expected_calling_context; + + +static void check_contexts(const v8::FunctionCallbackInfo<v8::Value>& info) { + ApiTestFuzzer::Fuzz(); + CHECK(expected_current_context == info.GetIsolate()->GetCurrentContext()); + CHECK(expected_calling_context == info.GetIsolate()->GetCallingContext()); +} + + THREADED_TEST(AccessorPropertyCrossContext) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::Function> fun = v8::Function::New(isolate, handle_property); + v8::Handle<v8::Function> fun = v8::Function::New(isolate, check_contexts); LocalContext switch_context; switch_context->Global()->Set(v8_str("fun"), fun); v8::TryCatch try_catch; + expected_current_context = env.local(); + expected_calling_context = switch_context.local(); CompileRun( "var o = Object.create(null, { n: { get:fun } });" "for (var i = 0; i < 10; i++) o.n;"); CHECK(!try_catch.HasCaught()); } + + +THREADED_TEST(GlobalObjectAccessor) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + CompileRun( + "var set_value = 1;" + "Object.defineProperty(this.__proto__, 'x', {" + " get : function() { return this; }," + " set : function() { set_value = this; }" + "});" + "function getter() { return x; }" + "function setter() { x = 1; }" + "for (var i = 0; i < 4; i++) { getter(); setter(); }"); + CHECK(v8::Utils::OpenHandle(*CompileRun("getter()"))->IsJSGlobalProxy()); + CHECK(v8::Utils::OpenHandle(*CompileRun("set_value"))->IsJSGlobalProxy()); +} diff --git a/deps/v8/test/cctest/test-alloc.cc b/deps/v8/test/cctest/test-alloc.cc index 7a5979a951..0d4ab886a3 100644 --- a/deps/v8/test/cctest/test-alloc.cc +++ b/deps/v8/test/cctest/test-alloc.cc @@ -148,10 +148,11 @@ TEST(StressJS) { map->AppendDescriptor(&d, witness); // Add the Foo constructor the global object. - env->Global()->Set(v8::String::New("Foo"), v8::Utils::ToLocal(function)); + env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "Foo"), + v8::Utils::ToLocal(function)); // Call the accessor through JavaScript. - v8::Handle<v8::Value> result = - v8::Script::Compile(v8::String::New("(new Foo).get"))->Run(); + v8::Handle<v8::Value> result = v8::Script::Compile( + v8::String::NewFromUtf8(CcTest::isolate(), "(new Foo).get"))->Run(); CHECK_EQ(42, result->Int32Value()); env->Exit(); } @@ -197,11 +198,11 @@ TEST(CodeRange) { if (current_allocated < code_range_size / 10) { // Allocate a block. // Geometrically distributed sizes, greater than - // Page::kMaxNonCodeHeapObjectSize (which is greater than code page area). + // Page::kMaxRegularHeapObjectSize (which is greater than code page area). // TODO(gc): instead of using 3 use some contant based on code_range_size // kMaxHeapObjectSize. size_t requested = - (Page::kMaxNonCodeHeapObjectSize << (Pseudorandom() % 3)) + + (Page::kMaxRegularHeapObjectSize << (Pseudorandom() % 3)) + Pseudorandom() % 5000 + 1; size_t allocated = 0; Address base = code_range.AllocateRawMemory(requested, diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index d5e838ebe0..9312057fa2 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -88,12 +88,13 @@ using ::v8::Value; void RunWithProfiler(void (*test)()) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Local<v8::String> profile_name = v8::String::New("my_profile1"); + v8::Local<v8::String> profile_name = + v8::String::NewFromUtf8(env->GetIsolate(), "my_profile1"); v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); cpu_profiler->StartCpuProfiling(profile_name); (*test)(); - cpu_profiler->DeleteAllCpuProfiles(); + reinterpret_cast<i::CpuProfiler*>(cpu_profiler)->DeleteAllProfiles(); } @@ -149,9 +150,10 @@ static void IncrementingSignatureCallback( signature_callback_count++; CHECK_EQ(signature_expected_receiver, args.Holder()); CHECK_EQ(signature_expected_receiver, args.This()); - v8::Handle<v8::Array> result = v8::Array::New(args.Length()); + v8::Handle<v8::Array> result = + v8::Array::New(args.GetIsolate(), args.Length()); for (int i = 0; i < args.Length(); i++) - result->Set(v8::Integer::New(i), args[i]); + result->Set(v8::Integer::New(args.GetIsolate(), i), args[i]); args.GetReturnValue().Set(result); } @@ -159,9 +161,10 @@ static void IncrementingSignatureCallback( static void SignatureCallback( const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); - v8::Handle<v8::Array> result = v8::Array::New(args.Length()); + v8::Handle<v8::Array> result = + v8::Array::New(args.GetIsolate(), args.Length()); for (int i = 0; i < args.Length(); i++) { - result->Set(v8::Integer::New(i), args[i]); + result->Set(v8::Integer::New(args.GetIsolate(), i), args[i]); } args.GetReturnValue().Set(result); } @@ -202,7 +205,7 @@ THREADED_TEST(Handles) { CHECK(undef->IsUndefined()); const char* c_source = "1 + 2 + 3"; - Local<String> source = String::New(c_source); + Local<String> source = String::NewFromUtf8(CcTest::isolate(), c_source); Local<Script> script = Script::Compile(source); CHECK_EQ(6, script->Run()->Int32Value()); @@ -214,13 +217,13 @@ THREADED_TEST(IsolateOfContext) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<Context> env = Context::New(CcTest::isolate()); - CHECK(!env->InContext()); + CHECK(!env->GetIsolate()->InContext()); CHECK(env->GetIsolate() == CcTest::isolate()); env->Enter(); - CHECK(env->InContext()); + CHECK(env->GetIsolate()->InContext()); CHECK(env->GetIsolate() == CcTest::isolate()); env->Exit(); - CHECK(!env->InContext()); + CHECK(!env->GetIsolate()->InContext()); CHECK(env->GetIsolate() == CcTest::isolate()); } @@ -249,18 +252,20 @@ static void TestSignature(const char* loop_js, Local<Value> receiver) { THREADED_TEST(ReceiverSignature) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Setup templates. - v8::Handle<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(); - v8::Handle<v8::Signature> sig = v8::Signature::New(fun); + v8::Handle<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate); + v8::Handle<v8::Signature> sig = v8::Signature::New(isolate, fun); v8::Handle<v8::FunctionTemplate> callback_sig = v8::FunctionTemplate::New( - IncrementingSignatureCallback, Local<Value>(), sig); + isolate, IncrementingSignatureCallback, Local<Value>(), sig); v8::Handle<v8::FunctionTemplate> callback = - v8::FunctionTemplate::New(IncrementingSignatureCallback); - v8::Handle<v8::FunctionTemplate> sub_fun = v8::FunctionTemplate::New(); + v8::FunctionTemplate::New(isolate, IncrementingSignatureCallback); + v8::Handle<v8::FunctionTemplate> sub_fun = v8::FunctionTemplate::New(isolate); sub_fun->Inherit(fun); - v8::Handle<v8::FunctionTemplate> unrel_fun = v8::FunctionTemplate::New(); + v8::Handle<v8::FunctionTemplate> unrel_fun = + v8::FunctionTemplate::New(isolate); // Install properties. v8::Handle<v8::ObjectTemplate> fun_proto = fun->PrototypeTemplate(); fun_proto->Set(v8_str("prop_sig"), callback_sig); @@ -322,13 +327,17 @@ THREADED_TEST(ReceiverSignature) { THREADED_TEST(ArgumentSignature) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::Handle<v8::FunctionTemplate> cons = v8::FunctionTemplate::New(); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> cons = v8::FunctionTemplate::New(isolate); cons->SetClassName(v8_str("Cons")); - v8::Handle<v8::Signature> sig = - v8::Signature::New(v8::Handle<v8::FunctionTemplate>(), 1, &cons); + v8::Handle<v8::Signature> sig = v8::Signature::New( + isolate, v8::Handle<v8::FunctionTemplate>(), 1, &cons); v8::Handle<v8::FunctionTemplate> fun = - v8::FunctionTemplate::New(SignatureCallback, v8::Handle<Value>(), sig); + v8::FunctionTemplate::New(isolate, + SignatureCallback, + v8::Handle<Value>(), + sig); env->Global()->Set(v8_str("Cons"), cons->GetFunction()); env->Global()->Set(v8_str("Fun1"), fun->GetFunction()); @@ -341,18 +350,21 @@ THREADED_TEST(ArgumentSignature) { v8::Handle<Value> value3 = CompileRun("Fun1() == '';"); CHECK(value3->IsTrue()); - v8::Handle<v8::FunctionTemplate> cons1 = v8::FunctionTemplate::New(); + v8::Handle<v8::FunctionTemplate> cons1 = v8::FunctionTemplate::New(isolate); cons1->SetClassName(v8_str("Cons1")); - v8::Handle<v8::FunctionTemplate> cons2 = v8::FunctionTemplate::New(); + v8::Handle<v8::FunctionTemplate> cons2 = v8::FunctionTemplate::New(isolate); cons2->SetClassName(v8_str("Cons2")); - v8::Handle<v8::FunctionTemplate> cons3 = v8::FunctionTemplate::New(); + v8::Handle<v8::FunctionTemplate> cons3 = v8::FunctionTemplate::New(isolate); cons3->SetClassName(v8_str("Cons3")); v8::Handle<v8::FunctionTemplate> args[3] = { cons1, cons2, cons3 }; - v8::Handle<v8::Signature> wsig = - v8::Signature::New(v8::Handle<v8::FunctionTemplate>(), 3, args); + v8::Handle<v8::Signature> wsig = v8::Signature::New( + isolate, v8::Handle<v8::FunctionTemplate>(), 3, args); v8::Handle<v8::FunctionTemplate> fun2 = - v8::FunctionTemplate::New(SignatureCallback, v8::Handle<Value>(), wsig); + v8::FunctionTemplate::New(isolate, + SignatureCallback, + v8::Handle<Value>(), + wsig); env->Global()->Set(v8_str("Cons1"), cons1->GetFunction()); env->Global()->Set(v8_str("Cons2"), cons2->GetFunction()); @@ -399,7 +411,7 @@ THREADED_TEST(Access) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - Local<v8::Object> obj = v8::Object::New(); + Local<v8::Object> obj = v8::Object::New(isolate); Local<Value> foo_before = obj->Get(v8_str("foo")); CHECK(foo_before->IsUndefined()); Local<String> bar_str = v8_str("bar"); @@ -414,7 +426,7 @@ THREADED_TEST(Access) { THREADED_TEST(AccessElement) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - Local<v8::Object> obj = v8::Object::New(); + Local<v8::Object> obj = v8::Object::New(env->GetIsolate()); Local<Value> before = obj->Get(1); CHECK(before->IsUndefined()); Local<String> bar_str = v8_str("bar"); @@ -434,7 +446,7 @@ THREADED_TEST(Script) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); const char* c_source = "1 + 2 + 3"; - Local<String> source = String::New(c_source); + Local<String> source = String::NewFromUtf8(env->GetIsolate(), c_source); Local<Script> script = Script::Compile(source); CHECK_EQ(6, script->Run()->Int32Value()); } @@ -450,13 +462,13 @@ static uint16_t* AsciiToTwoByteString(const char* source) { class TestResource: public String::ExternalStringResource { public: - explicit TestResource(uint16_t* data, int* counter = NULL) - : data_(data), length_(0), counter_(counter) { + TestResource(uint16_t* data, int* counter = NULL, bool owning_data = true) + : data_(data), length_(0), counter_(counter), owning_data_(owning_data) { while (data[length_]) ++length_; } ~TestResource() { - i::DeleteArray(data_); + if (owning_data_) i::DeleteArray(data_); if (counter_ != NULL) ++*counter_; } @@ -467,20 +479,25 @@ class TestResource: public String::ExternalStringResource { size_t length() const { return length_; } + private: uint16_t* data_; size_t length_; int* counter_; + bool owning_data_; }; class TestAsciiResource: public String::ExternalAsciiStringResource { public: - explicit TestAsciiResource(const char* data, int* counter = NULL) - : data_(data), length_(strlen(data)), counter_(counter) { } + TestAsciiResource(const char* data, int* counter = NULL, size_t offset = 0) + : orig_data_(data), + data_(data + offset), + length_(strlen(data) - offset), + counter_(counter) { } ~TestAsciiResource() { - i::DeleteArray(data_); + i::DeleteArray(orig_data_); if (counter_ != NULL) ++*counter_; } @@ -491,7 +508,9 @@ class TestAsciiResource: public String::ExternalAsciiStringResource { size_t length() const { return length_; } + private: + const char* orig_data_; const char* data_; size_t length_; int* counter_; @@ -506,7 +525,7 @@ THREADED_TEST(ScriptUsingStringResource) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); TestResource* resource = new TestResource(two_byte_source, &dispose_count); - Local<String> source = String::NewExternal(resource); + Local<String> source = String::NewExternal(env->GetIsolate(), resource); Local<Script> script = Script::Compile(source); Local<Value> value = script->Run(); CHECK(value->IsNumber()); @@ -535,7 +554,7 @@ THREADED_TEST(ScriptUsingAsciiStringResource) { v8::HandleScope scope(env->GetIsolate()); TestAsciiResource* resource = new TestAsciiResource(i::StrDup(c_source), &dispose_count); - Local<String> source = String::NewExternal(resource); + Local<String> source = String::NewExternal(env->GetIsolate(), resource); CHECK(source->IsExternalAscii()); CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource), source->GetExternalAsciiStringResource()); @@ -562,7 +581,8 @@ THREADED_TEST(ScriptMakingExternalString) { { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - Local<String> source = String::New(two_byte_source); + Local<String> source = + String::NewFromTwoByte(env->GetIsolate(), two_byte_source); // Trigger GCs so that the newly allocated string moves to old gen. CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now @@ -622,7 +642,8 @@ TEST(MakingExternalStringConditions) { CcTest::heap()->CollectGarbage(i::NEW_SPACE); uint16_t* two_byte_string = AsciiToTwoByteString("s1"); - Local<String> small_string = String::New(two_byte_string); + Local<String> small_string = + String::NewFromTwoByte(env->GetIsolate(), two_byte_string); i::DeleteArray(two_byte_string); // We should refuse to externalize newly created small string. @@ -634,7 +655,7 @@ TEST(MakingExternalStringConditions) { CHECK(small_string->CanMakeExternal()); two_byte_string = AsciiToTwoByteString("small string 2"); - small_string = String::New(two_byte_string); + small_string = String::NewFromTwoByte(env->GetIsolate(), two_byte_string); i::DeleteArray(two_byte_string); // We should refuse externalizing newly created small string. @@ -651,7 +672,8 @@ TEST(MakingExternalStringConditions) { buf[buf_size - 1] = '\0'; two_byte_string = AsciiToTwoByteString(buf); - Local<String> large_string = String::New(two_byte_string); + Local<String> large_string = + String::NewFromTwoByte(env->GetIsolate(), two_byte_string); i::DeleteArray(buf); i::DeleteArray(two_byte_string); // Large strings should be immediately accepted. @@ -667,7 +689,7 @@ TEST(MakingExternalAsciiStringConditions) { CcTest::heap()->CollectGarbage(i::NEW_SPACE); CcTest::heap()->CollectGarbage(i::NEW_SPACE); - Local<String> small_string = String::New("s1"); + Local<String> small_string = String::NewFromUtf8(env->GetIsolate(), "s1"); // We should refuse to externalize newly created small string. CHECK(!small_string->CanMakeExternal()); // Trigger GCs so that the newly allocated string moves to old gen. @@ -676,7 +698,7 @@ TEST(MakingExternalAsciiStringConditions) { // Old space strings should be accepted. CHECK(small_string->CanMakeExternal()); - small_string = String::New("small string 2"); + small_string = String::NewFromUtf8(env->GetIsolate(), "small string 2"); // We should refuse externalizing newly created small string. CHECK(!small_string->CanMakeExternal()); for (int i = 0; i < 100; i++) { @@ -689,7 +711,7 @@ TEST(MakingExternalAsciiStringConditions) { char* buf = i::NewArray<char>(buf_size); memset(buf, 'a', buf_size); buf[buf_size - 1] = '\0'; - Local<String> large_string = String::New(buf); + Local<String> large_string = String::NewFromUtf8(env->GetIsolate(), buf); i::DeleteArray(buf); // Large strings should be immediately accepted. CHECK(large_string->CanMakeExternal()); @@ -715,14 +737,13 @@ TEST(MakingExternalUnalignedAsciiString) { CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now // Turn into external string with unaligned resource data. - int dispose_count = 0; const char* c_cons = "_abcdefghijklmnopqrstuvwxyz"; bool success = cons->MakeExternal( - new TestAsciiResource(i::StrDup(c_cons) + 1, &dispose_count)); + new TestAsciiResource(i::StrDup(c_cons), NULL, 1)); CHECK(success); const char* c_slice = "_bcdefghijklmnopqrstuvwxyz"; success = slice->MakeExternal( - new TestAsciiResource(i::StrDup(c_slice) + 1, &dispose_count)); + new TestAsciiResource(i::StrDup(c_slice), NULL, 1)); CHECK(success); // Trigger GCs and force evacuation. @@ -736,14 +757,14 @@ THREADED_TEST(UsingExternalString) { { v8::HandleScope scope(CcTest::isolate()); uint16_t* two_byte_string = AsciiToTwoByteString("test string"); - Local<String> string = - String::NewExternal(new TestResource(two_byte_string)); + Local<String> string = String::NewExternal( + CcTest::isolate(), new TestResource(two_byte_string)); i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); // Trigger GCs so that the newly allocated string moves to old gen. CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now i::Handle<i::String> isymbol = - factory->InternalizedStringFromString(istring); + factory->InternalizeString(istring); CHECK(isymbol->IsInternalizedString()); } CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); @@ -757,13 +778,13 @@ THREADED_TEST(UsingExternalAsciiString) { v8::HandleScope scope(CcTest::isolate()); const char* one_byte_string = "test string"; Local<String> string = String::NewExternal( - new TestAsciiResource(i::StrDup(one_byte_string))); + CcTest::isolate(), new TestAsciiResource(i::StrDup(one_byte_string))); i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); // Trigger GCs so that the newly allocated string moves to old gen. CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now i::Handle<i::String> isymbol = - factory->InternalizedStringFromString(istring); + factory->InternalizeString(istring); CHECK(isymbol->IsInternalizedString()); } CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); @@ -779,9 +800,8 @@ THREADED_TEST(ScavengeExternalString) { { v8::HandleScope scope(CcTest::isolate()); uint16_t* two_byte_string = AsciiToTwoByteString("test string"); - Local<String> string = - String::NewExternal(new TestResource(two_byte_string, - &dispose_count)); + Local<String> string = String::NewExternal( + CcTest::isolate(), new TestResource(two_byte_string, &dispose_count)); i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); CcTest::heap()->CollectGarbage(i::NEW_SPACE); in_new_space = CcTest::heap()->InNewSpace(*istring); @@ -803,6 +823,7 @@ THREADED_TEST(ScavengeExternalAsciiString) { v8::HandleScope scope(CcTest::isolate()); const char* one_byte_string = "test string"; Local<String> string = String::NewExternal( + CcTest::isolate(), new TestAsciiResource(i::StrDup(one_byte_string), &dispose_count)); i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); CcTest::heap()->CollectGarbage(i::NEW_SPACE); @@ -849,7 +870,7 @@ TEST(ExternalStringWithDisposeHandling) { { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - Local<String> source = String::NewExternal(&res_stack); + Local<String> source = String::NewExternal(env->GetIsolate(), &res_stack); Local<Script> script = Script::Compile(source); Local<Value> value = script->Run(); CHECK(value->IsNumber()); @@ -870,7 +891,7 @@ TEST(ExternalStringWithDisposeHandling) { { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - Local<String> source = String::NewExternal(res_heap); + Local<String> source = String::NewExternal(env->GetIsolate(), res_heap); Local<Script> script = Script::Compile(source); Local<Value> value = script->Run(); CHECK(value->IsNumber()); @@ -899,25 +920,28 @@ THREADED_TEST(StringConcat) { Local<String> left = v8_str(one_byte_string_1); uint16_t* two_byte_source = AsciiToTwoByteString(two_byte_string_1); - Local<String> right = String::New(two_byte_source); + Local<String> right = + String::NewFromTwoByte(env->GetIsolate(), two_byte_source); i::DeleteArray(two_byte_source); Local<String> source = String::Concat(left, right); right = String::NewExternal( - new TestAsciiResource(i::StrDup(one_byte_extern_1))); + env->GetIsolate(), new TestAsciiResource(i::StrDup(one_byte_extern_1))); source = String::Concat(source, right); right = String::NewExternal( + env->GetIsolate(), new TestResource(AsciiToTwoByteString(two_byte_extern_1))); source = String::Concat(source, right); right = v8_str(one_byte_string_2); source = String::Concat(source, right); two_byte_source = AsciiToTwoByteString(two_byte_string_2); - right = String::New(two_byte_source); + right = String::NewFromTwoByte(env->GetIsolate(), two_byte_source); i::DeleteArray(two_byte_source); source = String::Concat(source, right); right = String::NewExternal( + env->GetIsolate(), new TestResource(AsciiToTwoByteString(two_byte_extern_2))); source = String::Concat(source, right); Local<Script> script = Script::Compile(source); @@ -1011,10 +1035,11 @@ static void TestFunctionTemplateInitializer(Handler handler, // Test constructor calls. { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); Local<v8::FunctionTemplate> fun_templ = - v8::FunctionTemplate::New(handler); + v8::FunctionTemplate::New(isolate, handler); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("obj"), fun); Local<Script> script = v8_compile("obj()"); @@ -1026,9 +1051,10 @@ static void TestFunctionTemplateInitializer(Handler handler, // the previous one. { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); fun_templ->SetCallHandler(handler_2); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("obj"), fun); @@ -1047,7 +1073,7 @@ static void TestFunctionTemplateAccessor(Constructor constructor, v8::HandleScope scope(env->GetIsolate()); Local<v8::FunctionTemplate> fun_templ = - v8::FunctionTemplate::New(constructor); + v8::FunctionTemplate::New(env->GetIsolate(), constructor); fun_templ->SetClassName(v8_str("funky")); fun_templ->InstanceTemplate()->SetAccessor(v8_str("m"), accessor); Local<Function> fun = fun_templ->GetFunction(); @@ -1083,10 +1109,13 @@ static void SimpleCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { template<typename Callback> static void TestSimpleCallback(Callback callback) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(); - object_template->Set("callback", v8::FunctionTemplate::New(callback)); + v8::Handle<v8::ObjectTemplate> object_template = + v8::ObjectTemplate::New(isolate); + object_template->Set(isolate, "callback", + v8::FunctionTemplate::New(isolate, callback)); v8::Local<v8::Object> object = object_template->NewInstance(); (*env)->Global()->Set(v8_str("callback_object"), object); v8::Handle<v8::Script> script; @@ -1178,20 +1207,25 @@ template<> void FastReturnValueCallback<Object>( const v8::FunctionCallbackInfo<v8::Value>& info) { v8::Handle<v8::Object> object; - if (!fast_return_value_object_is_empty) object = Object::New(); + if (!fast_return_value_object_is_empty) { + object = Object::New(info.GetIsolate()); + } info.GetReturnValue().Set(object); } template<typename T> Handle<Value> TestFastReturnValues() { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(); + v8::Isolate* isolate = env->GetIsolate(); + v8::EscapableHandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> object_template = + v8::ObjectTemplate::New(isolate); v8::FunctionCallback callback = &FastReturnValueCallback<T>; - object_template->Set("callback", v8::FunctionTemplate::New(callback)); + object_template->Set(isolate, "callback", + v8::FunctionTemplate::New(isolate, callback)); v8::Local<v8::Object> object = object_template->NewInstance(); (*env)->Global()->Set(v8_str("callback_object"), object); - return scope.Close(CompileRun("callback_object.callback()")); + return scope.Escape(CompileRun("callback_object.callback()")); } @@ -1264,10 +1298,15 @@ THREADED_PROFILED_TEST(FastReturnValues) { THREADED_TEST(FunctionTemplateSetLength) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); { - Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New( - handle_callback, Handle<v8::Value>(), Handle<v8::Signature>(), 23); + Local<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate, + handle_callback, + Handle<v8::Value>(), + Handle<v8::Signature>(), + 23); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("obj"), fun); Local<Script> script = v8_compile("obj.length"); @@ -1275,7 +1314,7 @@ THREADED_TEST(FunctionTemplateSetLength) { } { Local<v8::FunctionTemplate> fun_templ = - v8::FunctionTemplate::New(handle_callback); + v8::FunctionTemplate::New(isolate, handle_callback); fun_templ->SetLength(22); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("obj"), fun); @@ -1285,7 +1324,7 @@ THREADED_TEST(FunctionTemplateSetLength) { { // Without setting length it defaults to 0. Local<v8::FunctionTemplate> fun_templ = - v8::FunctionTemplate::New(handle_callback); + v8::FunctionTemplate::New(isolate, handle_callback); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("obj"), fun); Local<Script> script = v8_compile("obj.length"); @@ -1304,13 +1343,15 @@ static void callback(const v8::FunctionCallbackInfo<v8::Value>& args) { static void TestExternalPointerWrapping() { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - v8::Handle<v8::Value> data = v8::External::New(expected_ptr); + v8::Handle<v8::Value> data = + v8::External::New(isolate, expected_ptr); - v8::Handle<v8::Object> obj = v8::Object::New(); + v8::Handle<v8::Object> obj = v8::Object::New(isolate); obj->Set(v8_str("func"), - v8::FunctionTemplate::New(callback, data)->GetFunction()); + v8::FunctionTemplate::New(isolate, callback, data)->GetFunction()); env->Global()->Set(v8_str("obj"), obj); CHECK(CompileRun( @@ -1369,11 +1410,12 @@ THREADED_TEST(ExternalWrap) { THREADED_TEST(FindInstanceInPrototypeChain) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - Local<v8::FunctionTemplate> base = v8::FunctionTemplate::New(); - Local<v8::FunctionTemplate> derived = v8::FunctionTemplate::New(); - Local<v8::FunctionTemplate> other = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> base = v8::FunctionTemplate::New(isolate); + Local<v8::FunctionTemplate> derived = v8::FunctionTemplate::New(isolate); + Local<v8::FunctionTemplate> other = v8::FunctionTemplate::New(isolate); derived->Inherit(base); Local<v8::Function> base_function = base->GetFunction(); @@ -1416,14 +1458,14 @@ THREADED_TEST(FindInstanceInPrototypeChain) { THREADED_TEST(TinyInteger) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::Isolate* isolate = CcTest::isolate(); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); int32_t value = 239; - Local<v8::Integer> value_obj = v8::Integer::New(value); + Local<v8::Integer> value_obj = v8::Integer::New(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); - value_obj = v8::Integer::New(value, isolate); + value_obj = v8::Integer::New(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); } @@ -1439,10 +1481,10 @@ THREADED_TEST(BigSmiInteger) { CHECK(i::Smi::IsValid(value)); CHECK(!i::Smi::IsValid(value + 1)); - Local<v8::Integer> value_obj = v8::Integer::New(value); + Local<v8::Integer> value_obj = v8::Integer::New(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); - value_obj = v8::Integer::New(value, isolate); + value_obj = v8::Integer::New(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); } } @@ -1462,10 +1504,10 @@ THREADED_TEST(BigInteger) { CHECK(value > i::Smi::kMaxValue); CHECK(!i::Smi::IsValid(value)); - Local<v8::Integer> value_obj = v8::Integer::New(value); + Local<v8::Integer> value_obj = v8::Integer::New(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); - value_obj = v8::Integer::New(value, isolate); + value_obj = v8::Integer::New(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); } } @@ -1478,10 +1520,10 @@ THREADED_TEST(TinyUnsignedInteger) { uint32_t value = 239; - Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value); + Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); - value_obj = v8::Integer::NewFromUnsigned(value, isolate); + value_obj = v8::Integer::NewFromUnsigned(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); } @@ -1495,10 +1537,10 @@ THREADED_TEST(BigUnsignedSmiInteger) { CHECK(i::Smi::IsValid(value)); CHECK(!i::Smi::IsValid(value + 1)); - Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value); + Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); - value_obj = v8::Integer::NewFromUnsigned(value, isolate); + value_obj = v8::Integer::NewFromUnsigned(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); } @@ -1512,10 +1554,10 @@ THREADED_TEST(BigUnsignedInteger) { CHECK(value > static_cast<uint32_t>(i::Smi::kMaxValue)); CHECK(!i::Smi::IsValid(value)); - Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value); + Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); - value_obj = v8::Integer::NewFromUnsigned(value, isolate); + value_obj = v8::Integer::NewFromUnsigned(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); } @@ -1529,10 +1571,10 @@ THREADED_TEST(OutOfSignedRangeUnsignedInteger) { uint32_t value = INT32_MAX_AS_UINT + 1; CHECK(value > INT32_MAX_AS_UINT); // No overflow. - Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value); + Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); - value_obj = v8::Integer::NewFromUnsigned(value, isolate); + value_obj = v8::Integer::NewFromUnsigned(isolate, value); CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); } @@ -1588,7 +1630,8 @@ THREADED_TEST(NumberObject) { CHECK(!as_boxed.IsEmpty()); double the_number = as_boxed->ValueOf(); CHECK_EQ(42.0, the_number); - v8::Handle<v8::Value> new_boxed_number = v8::NumberObject::New(43); + v8::Handle<v8::Value> new_boxed_number = + v8::NumberObject::New(env->GetIsolate(), 43); CHECK(new_boxed_number->IsNumberObject()); as_boxed = new_boxed_number.As<v8::NumberObject>(); the_number = as_boxed->ValueOf(); @@ -1625,7 +1668,7 @@ THREADED_TEST(PrimitiveAndWrappedBooleans) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - Local<Value> primitive_false = Boolean::New(false); + Local<Value> primitive_false = Boolean::New(env->GetIsolate(), false); CHECK(primitive_false->IsBoolean()); CHECK(!primitive_false->IsBooleanObject()); CHECK(!primitive_false->BooleanValue()); @@ -1648,7 +1691,7 @@ THREADED_TEST(PrimitiveAndWrappedBooleans) { CHECK(!false_boolean_object->IsTrue()); CHECK(!false_boolean_object->IsFalse()); - Local<Value> primitive_true = Boolean::New(true); + Local<Value> primitive_true = Boolean::New(env->GetIsolate(), true); CHECK(primitive_true->IsBoolean()); CHECK(!primitive_true->IsBooleanObject()); CHECK(primitive_true->BooleanValue()); @@ -1677,7 +1720,7 @@ THREADED_TEST(Number) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); double PI = 3.1415926; - Local<v8::Number> pi_obj = v8::Number::New(PI); + Local<v8::Number> pi_obj = v8::Number::New(env->GetIsolate(), PI); CHECK_EQ(PI, pi_obj->NumberValue()); } @@ -1699,32 +1742,34 @@ THREADED_TEST(Date) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); double PI = 3.1415926; - Local<Value> date = v8::Date::New(PI); + Local<Value> date = v8::Date::New(env->GetIsolate(), PI); CHECK_EQ(3.0, date->NumberValue()); - date.As<v8::Date>()->Set(v8_str("property"), v8::Integer::New(42)); + date.As<v8::Date>()->Set(v8_str("property"), + v8::Integer::New(env->GetIsolate(), 42)); CHECK_EQ(42, date.As<v8::Date>()->Get(v8_str("property"))->Int32Value()); } THREADED_TEST(Boolean) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::Handle<v8::Boolean> t = v8::True(CcTest::isolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::Boolean> t = v8::True(isolate); CHECK(t->Value()); - v8::Handle<v8::Boolean> f = v8::False(CcTest::isolate()); + v8::Handle<v8::Boolean> f = v8::False(isolate); CHECK(!f->Value()); - v8::Handle<v8::Primitive> u = v8::Undefined(CcTest::isolate()); + v8::Handle<v8::Primitive> u = v8::Undefined(isolate); CHECK(!u->BooleanValue()); - v8::Handle<v8::Primitive> n = v8::Null(CcTest::isolate()); + v8::Handle<v8::Primitive> n = v8::Null(isolate); CHECK(!n->BooleanValue()); v8::Handle<String> str1 = v8_str(""); CHECK(!str1->BooleanValue()); v8::Handle<String> str2 = v8_str("x"); CHECK(str2->BooleanValue()); - CHECK(!v8::Number::New(0)->BooleanValue()); - CHECK(v8::Number::New(-1)->BooleanValue()); - CHECK(v8::Number::New(1)->BooleanValue()); - CHECK(v8::Number::New(42)->BooleanValue()); + CHECK(!v8::Number::New(isolate, 0)->BooleanValue()); + CHECK(v8::Number::New(isolate, -1)->BooleanValue()); + CHECK(v8::Number::New(isolate, 1)->BooleanValue()); + CHECK(v8::Number::New(isolate, 42)->BooleanValue()); CHECK(!v8_compile("NaN")->Run()->BooleanValue()); } @@ -1743,13 +1788,14 @@ static void GetM(Local<String> name, THREADED_TEST(GlobalPrototype) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> func_templ = v8::FunctionTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> func_templ = + v8::FunctionTemplate::New(isolate); func_templ->PrototypeTemplate()->Set( - "dummy", - v8::FunctionTemplate::New(DummyCallHandler)); + isolate, "dummy", v8::FunctionTemplate::New(isolate, DummyCallHandler)); v8::Handle<ObjectTemplate> templ = func_templ->InstanceTemplate(); - templ->Set("x", v8_num(200)); + templ->Set(isolate, "x", v8_num(200)); templ->SetAccessor(v8_str("m"), GetM); LocalContext env(0, templ); v8::Handle<Script> script(v8_compile("dummy()")); @@ -1761,20 +1807,21 @@ THREADED_TEST(GlobalPrototype) { THREADED_TEST(ObjectTemplate) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ1 = ObjectTemplate::New(); - templ1->Set("x", v8_num(10)); - templ1->Set("y", v8_num(13)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ1 = ObjectTemplate::New(isolate); + templ1->Set(isolate, "x", v8_num(10)); + templ1->Set(isolate, "y", v8_num(13)); LocalContext env; Local<v8::Object> instance1 = templ1->NewInstance(); env->Global()->Set(v8_str("p"), instance1); CHECK(v8_compile("(p.x == 10)")->Run()->BooleanValue()); CHECK(v8_compile("(p.y == 13)")->Run()->BooleanValue()); - Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(); - fun->PrototypeTemplate()->Set("nirk", v8_num(123)); + Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate); + fun->PrototypeTemplate()->Set(isolate, "nirk", v8_num(123)); Local<ObjectTemplate> templ2 = fun->InstanceTemplate(); - templ2->Set("a", v8_num(12)); - templ2->Set("b", templ1); + templ2->Set(isolate, "a", v8_num(12)); + templ2->Set(isolate, "b", templ1); Local<v8::Object> instance2 = templ2->NewInstance(); env->Global()->Set(v8_str("q"), instance2); CHECK(v8_compile("(q.nirk == 123)")->Run()->BooleanValue()); @@ -1798,21 +1845,23 @@ static void GetKnurd(Local<String> property, THREADED_TEST(DescriptorInheritance) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> super = v8::FunctionTemplate::New(); - super->PrototypeTemplate()->Set("flabby", - v8::FunctionTemplate::New(GetFlabby)); - super->PrototypeTemplate()->Set("PI", v8_num(3.14)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> super = v8::FunctionTemplate::New(isolate); + super->PrototypeTemplate()->Set(isolate, "flabby", + v8::FunctionTemplate::New(isolate, + GetFlabby)); + super->PrototypeTemplate()->Set(isolate, "PI", v8_num(3.14)); super->InstanceTemplate()->SetAccessor(v8_str("knurd"), GetKnurd); - v8::Handle<v8::FunctionTemplate> base1 = v8::FunctionTemplate::New(); + v8::Handle<v8::FunctionTemplate> base1 = v8::FunctionTemplate::New(isolate); base1->Inherit(super); - base1->PrototypeTemplate()->Set("v1", v8_num(20.1)); + base1->PrototypeTemplate()->Set(isolate, "v1", v8_num(20.1)); - v8::Handle<v8::FunctionTemplate> base2 = v8::FunctionTemplate::New(); + v8::Handle<v8::FunctionTemplate> base2 = v8::FunctionTemplate::New(isolate); base2->Inherit(super); - base2->PrototypeTemplate()->Set("v2", v8_num(10.1)); + base2->PrototypeTemplate()->Set(isolate, "v2", v8_num(10.1)); LocalContext env; @@ -1940,8 +1989,8 @@ void AddInterceptor(Handle<FunctionTemplate> templ, THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> parent = FunctionTemplate::New(); - Handle<FunctionTemplate> child = FunctionTemplate::New(); + Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); + Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); child->Inherit(parent); AddAccessor(parent, v8_str("age"), SimpleAccessorGetter, SimpleAccessorSetter); @@ -1956,10 +2005,26 @@ THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { } -THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { +THREADED_TEST(EmptyInterceptorBreakTransitions) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> parent = FunctionTemplate::New(); - Handle<FunctionTemplate> child = FunctionTemplate::New(); + Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); + AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); + LocalContext env; + env->Global()->Set(v8_str("Constructor"), templ->GetFunction()); + CompileRun("var o1 = new Constructor;" + "o1.a = 1;" // Ensure a and x share the descriptor array. + "Object.defineProperty(o1, 'x', {value: 10});"); + CompileRun("var o2 = new Constructor;" + "o2.a = 1;" + "Object.defineProperty(o2, 'x', {value: 10});"); +} + + +THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); + Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); child->Inherit(parent); AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); LocalContext env; @@ -1978,9 +2043,10 @@ THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { - v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> parent = FunctionTemplate::New(); - Handle<FunctionTemplate> child = FunctionTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); + Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); child->Inherit(parent); AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); LocalContext env; @@ -1999,7 +2065,7 @@ THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { THREADED_TEST(SwitchFromInterceptorToAccessor) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(); + Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddAccessor(templ, v8_str("age"), SimpleAccessorGetter, SimpleAccessorSetter); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); @@ -2017,7 +2083,7 @@ THREADED_TEST(SwitchFromInterceptorToAccessor) { THREADED_TEST(SwitchFromAccessorToInterceptor) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(); + Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddAccessor(templ, v8_str("age"), SimpleAccessorGetter, SimpleAccessorSetter); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); @@ -2035,8 +2101,8 @@ THREADED_TEST(SwitchFromAccessorToInterceptor) { THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> parent = FunctionTemplate::New(); - Handle<FunctionTemplate> child = FunctionTemplate::New(); + Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); + Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); child->Inherit(parent); AddAccessor(parent, v8_str("age"), SimpleAccessorGetter, SimpleAccessorSetter); @@ -2055,8 +2121,8 @@ THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) { THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> parent = FunctionTemplate::New(); - Handle<FunctionTemplate> child = FunctionTemplate::New(); + Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); + Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); child->Inherit(parent); AddAccessor(parent, v8_str("age"), SimpleAccessorGetter, SimpleAccessorSetter); @@ -2075,7 +2141,7 @@ THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) { THREADED_TEST(SwitchFromInterceptorToJSAccessor) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(); + Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; env->Global()->Set(v8_str("Obj"), templ->GetFunction()); @@ -2100,7 +2166,7 @@ THREADED_TEST(SwitchFromInterceptorToJSAccessor) { THREADED_TEST(SwitchFromJSAccessorToInterceptor) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(); + Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; env->Global()->Set(v8_str("Obj"), templ->GetFunction()); @@ -2125,8 +2191,8 @@ THREADED_TEST(SwitchFromJSAccessorToInterceptor) { THREADED_TEST(SwitchFromInterceptorToProperty) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> parent = FunctionTemplate::New(); - Handle<FunctionTemplate> child = FunctionTemplate::New(); + Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); + Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); child->Inherit(parent); AddInterceptor(child, InterceptorGetter, InterceptorSetter); LocalContext env; @@ -2143,8 +2209,8 @@ THREADED_TEST(SwitchFromInterceptorToProperty) { THREADED_TEST(SwitchFromPropertyToInterceptor) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> parent = FunctionTemplate::New(); - Handle<FunctionTemplate> child = FunctionTemplate::New(); + Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); + Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); child->Inherit(parent); AddInterceptor(child, InterceptorGetter, InterceptorSetter); LocalContext env; @@ -2162,7 +2228,8 @@ THREADED_TEST(SwitchFromPropertyToInterceptor) { THREADED_TEST(NamedPropertyHandlerGetter) { echo_named_call_count = 0; v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); + v8::Handle<v8::FunctionTemplate> templ = + v8::FunctionTemplate::New(CcTest::isolate()); templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty, 0, 0, 0, 0, v8_str("data")); @@ -2197,8 +2264,9 @@ static void EchoIndexedProperty( THREADED_TEST(IndexedPropertyHandlerGetter) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); templ->InstanceTemplate()->SetIndexedPropertyHandler(EchoIndexedProperty, 0, 0, 0, 0, v8_num(637)); @@ -2301,10 +2369,11 @@ void CheckThisNamedPropertyEnumerator( THREADED_PROFILED_TEST(PropertyHandlerInPrototype) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Set up a prototype chain with three interceptors. - v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); + v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); templ->InstanceTemplate()->SetIndexedPropertyHandler( CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter, @@ -2368,8 +2437,9 @@ static void PrePropertyHandlerQuery( THREADED_TEST(PrePropertyHandler) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); desc->InstanceTemplate()->SetNamedPropertyHandler(PrePropertyHandlerGet, 0, PrePropertyHandlerQuery); @@ -2403,7 +2473,8 @@ static void CallScriptRecursivelyCall( ApiTestFuzzer::Fuzz(); int depth = args.This()->Get(v8_str("depth"))->Int32Value(); if (depth == kTargetRecursionDepth) return; - args.This()->Set(v8_str("depth"), v8::Integer::New(depth + 1)); + args.This()->Set(v8_str("depth"), + v8::Integer::New(args.GetIsolate(), depth + 1)); args.GetReturnValue().Set(call_recursively_script->Run()); } @@ -2416,7 +2487,8 @@ static void CallFunctionRecursivelyCall( printf("[depth = %d]\n", depth); return; } - args.This()->Set(v8_str("depth"), v8::Integer::New(depth + 1)); + args.This()->Set(v8_str("depth"), + v8::Integer::New(args.GetIsolate(), depth + 1)); v8::Handle<Value> function = args.This()->Get(v8_str("callFunctionRecursively")); args.GetReturnValue().Set( @@ -2425,20 +2497,21 @@ static void CallFunctionRecursivelyCall( THREADED_TEST(DeepCrossLanguageRecursion) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(isolate); global->Set(v8_str("callScriptRecursively"), - v8::FunctionTemplate::New(CallScriptRecursivelyCall)); + v8::FunctionTemplate::New(isolate, CallScriptRecursivelyCall)); global->Set(v8_str("callFunctionRecursively"), - v8::FunctionTemplate::New(CallFunctionRecursivelyCall)); + v8::FunctionTemplate::New(isolate, CallFunctionRecursivelyCall)); LocalContext env(NULL, global); - env->Global()->Set(v8_str("depth"), v8::Integer::New(0)); + env->Global()->Set(v8_str("depth"), v8::Integer::New(isolate, 0)); call_recursively_script = v8_compile("callScriptRecursively()"); call_recursively_script->Run(); call_recursively_script = v8::Handle<Script>(); - env->Global()->Set(v8_str("depth"), v8::Integer::New(0)); + env->Global()->Set(v8_str("depth"), v8::Integer::New(isolate, 0)); Script::Compile(v8_str("callFunctionRecursively()"))->Run(); } @@ -2461,8 +2534,9 @@ static void ThrowingPropertyHandlerSet( THREADED_TEST(CallbackExceptionRegression) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetNamedPropertyHandler(ThrowingPropertyHandlerGet, ThrowingPropertyHandlerSet); LocalContext env; @@ -2477,8 +2551,9 @@ THREADED_TEST(CallbackExceptionRegression) { THREADED_TEST(FunctionPrototype) { - v8::HandleScope scope(CcTest::isolate()); - Local<v8::FunctionTemplate> Foo = v8::FunctionTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<v8::FunctionTemplate> Foo = v8::FunctionTemplate::New(isolate); Foo->PrototypeTemplate()->Set(v8_str("plak"), v8_num(321)); LocalContext env; env->Global()->Set(v8_str("Foo"), Foo->GetFunction()); @@ -2489,9 +2564,10 @@ THREADED_TEST(FunctionPrototype) { THREADED_TEST(InternalFields) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); instance_templ->SetInternalFieldCount(1); Local<v8::Object> obj = templ->GetFunction()->NewInstance(); @@ -2503,8 +2579,9 @@ THREADED_TEST(InternalFields) { THREADED_TEST(GlobalObjectInternalFields) { - v8::HandleScope scope(CcTest::isolate()); - Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); global_template->SetInternalFieldCount(1); LocalContext env(NULL, global_template); v8::Handle<v8::Object> global_proxy = env->Global(); @@ -2521,7 +2598,7 @@ THREADED_TEST(GlobalObjectHasRealIndexedProperty) { v8::HandleScope scope(CcTest::isolate()); v8::Local<v8::Object> global = env->Global(); - global->Set(0, v8::String::New("value")); + global->Set(0, v8::String::NewFromUtf8(CcTest::isolate(), "value")); CHECK(global->HasRealIndexedProperty(0)); } @@ -2537,9 +2614,10 @@ static void CheckAlignedPointerInInternalField(Handle<v8::Object> obj, THREADED_TEST(InternalFieldsAlignedPointers) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); instance_templ->SetInternalFieldCount(1); Local<v8::Object> obj = templ->GetFunction()->NewInstance(); @@ -2611,33 +2689,38 @@ static void CheckEmbedderData(LocalContext* env, THREADED_TEST(EmbedderData) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - CheckEmbedderData(&env, 3, v8::String::New("The quick brown fox jumps")); - CheckEmbedderData(&env, 2, v8::String::New("over the lazy dog.")); - CheckEmbedderData(&env, 1, v8::Number::New(1.2345)); - CheckEmbedderData(&env, 0, v8::Boolean::New(true)); + CheckEmbedderData( + &env, 3, + v8::String::NewFromUtf8(isolate, "The quick brown fox jumps")); + CheckEmbedderData(&env, 2, v8::String::NewFromUtf8(isolate, + "over the lazy dog.")); + CheckEmbedderData(&env, 1, v8::Number::New(isolate, 1.2345)); + CheckEmbedderData(&env, 0, v8::Boolean::New(isolate, true)); } THREADED_TEST(IdentityHash) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Ensure that the test starts with an fresh heap to test whether the hash // code is based on the address. CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); - Local<v8::Object> obj = v8::Object::New(); + Local<v8::Object> obj = v8::Object::New(isolate); int hash = obj->GetIdentityHash(); int hash1 = obj->GetIdentityHash(); CHECK_EQ(hash, hash1); - int hash2 = v8::Object::New()->GetIdentityHash(); + int hash2 = v8::Object::New(isolate)->GetIdentityHash(); // Since the identity hash is essentially a random number two consecutive // objects should not be assigned the same hash code. If the test below fails // the random number generator should be evaluated. CHECK_NE(hash, hash2); CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); - int hash3 = v8::Object::New()->GetIdentityHash(); + int hash3 = v8::Object::New(isolate)->GetIdentityHash(); // Make sure that the identity hash is not based on the initial address of // the object alone. If the test below fails the random number generator // should be evaluated. @@ -2649,16 +2732,16 @@ THREADED_TEST(IdentityHash) { // Put a getter for 'v8::IdentityHash' on the Object's prototype: { CompileRun("Object.prototype['v8::IdentityHash'] = 42;\n"); - Local<v8::Object> o1 = v8::Object::New(); - Local<v8::Object> o2 = v8::Object::New(); + Local<v8::Object> o1 = v8::Object::New(isolate); + Local<v8::Object> o2 = v8::Object::New(isolate); CHECK_NE(o1->GetIdentityHash(), o2->GetIdentityHash()); } { CompileRun( "function cnst() { return 42; };\n" "Object.prototype.__defineGetter__('v8::IdentityHash', cnst);\n"); - Local<v8::Object> o1 = v8::Object::New(); - Local<v8::Object> o2 = v8::Object::New(); + Local<v8::Object> o1 = v8::Object::New(isolate); + Local<v8::Object> o2 = v8::Object::New(isolate); CHECK_NE(o1->GetIdentityHash(), o2->GetIdentityHash()); } } @@ -2671,7 +2754,7 @@ THREADED_TEST(SymbolProperties) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Local<v8::Object> obj = v8::Object::New(); + v8::Local<v8::Object> obj = v8::Object::New(isolate); v8::Local<v8::Symbol> sym1 = v8::Symbol::New(isolate); v8::Local<v8::Symbol> sym2 = v8::Symbol::New(isolate, "my-symbol"); @@ -2691,7 +2774,7 @@ THREADED_TEST(SymbolProperties) { CHECK(!sym1->StrictEquals(sym2)); CHECK(!sym2->StrictEquals(sym1)); - CHECK(sym2->Name()->Equals(v8::String::New("my-symbol"))); + CHECK(sym2->Name()->Equals(v8::String::NewFromUtf8(isolate, "my-symbol"))); v8::Local<v8::Value> sym_val = sym2; CHECK(sym_val->IsSymbol()); @@ -2712,17 +2795,18 @@ THREADED_TEST(SymbolProperties) { CHECK(obj->Delete(sym1)); CHECK(!obj->Has(sym1)); - CHECK(obj->Set(sym1, v8::Integer::New(1503))); + CHECK(obj->Set(sym1, v8::Integer::New(isolate, 1503))); CHECK(obj->Has(sym1)); CHECK_EQ(1503, obj->Get(sym1)->Int32Value()); - CHECK(obj->Set(sym1, v8::Integer::New(2002))); + CHECK(obj->Set(sym1, v8::Integer::New(isolate, 2002))); CHECK(obj->Has(sym1)); CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); CHECK_EQ(v8::None, obj->GetPropertyAttributes(sym1)); CHECK_EQ(0, obj->GetOwnPropertyNames()->Length()); int num_props = obj->GetPropertyNames()->Length(); - CHECK(obj->Set(v8::String::New("bla"), v8::Integer::New(20))); + CHECK(obj->Set(v8::String::NewFromUtf8(isolate, "bla"), + v8::Integer::New(isolate, 20))); CHECK_EQ(1, obj->GetOwnPropertyNames()->Length()); CHECK_EQ(num_props + 1, obj->GetPropertyNames()->Length()); @@ -2730,7 +2814,7 @@ THREADED_TEST(SymbolProperties) { // Add another property and delete it afterwards to force the object in // slow case. - CHECK(obj->Set(sym2, v8::Integer::New(2008))); + CHECK(obj->Set(sym2, v8::Integer::New(isolate, 2008))); CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); CHECK_EQ(2008, obj->Get(sym2)->Int32Value()); CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); @@ -2743,6 +2827,71 @@ THREADED_TEST(SymbolProperties) { CHECK(!obj->Has(sym2)); CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); CHECK_EQ(1, obj->GetOwnPropertyNames()->Length()); + + // Symbol properties are inherited. + v8::Local<v8::Object> child = v8::Object::New(isolate); + child->SetPrototype(obj); + CHECK(child->Has(sym1)); + CHECK_EQ(2002, child->Get(sym1)->Int32Value()); + CHECK_EQ(0, child->GetOwnPropertyNames()->Length()); +} + + +THREADED_TEST(PrivateProperties) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + + v8::Local<v8::Object> obj = v8::Object::New(isolate); + v8::Local<v8::Private> priv1 = v8::Private::New(isolate); + v8::Local<v8::Private> priv2 = v8::Private::New(isolate, "my-private"); + + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + + CHECK(priv2->Name()->Equals(v8::String::NewFromUtf8(isolate, "my-private"))); + + // Make sure delete of a non-existent private symbol property works. + CHECK(obj->DeletePrivate(priv1)); + CHECK(!obj->HasPrivate(priv1)); + + CHECK(obj->SetPrivate(priv1, v8::Integer::New(isolate, 1503))); + CHECK(obj->HasPrivate(priv1)); + CHECK_EQ(1503, obj->GetPrivate(priv1)->Int32Value()); + CHECK(obj->SetPrivate(priv1, v8::Integer::New(isolate, 2002))); + CHECK(obj->HasPrivate(priv1)); + CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value()); + + CHECK_EQ(0, obj->GetOwnPropertyNames()->Length()); + int num_props = obj->GetPropertyNames()->Length(); + CHECK(obj->Set(v8::String::NewFromUtf8(isolate, "bla"), + v8::Integer::New(isolate, 20))); + CHECK_EQ(1, obj->GetOwnPropertyNames()->Length()); + CHECK_EQ(num_props + 1, obj->GetPropertyNames()->Length()); + + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + + // Add another property and delete it afterwards to force the object in + // slow case. + CHECK(obj->SetPrivate(priv2, v8::Integer::New(isolate, 2008))); + CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value()); + CHECK_EQ(2008, obj->GetPrivate(priv2)->Int32Value()); + CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value()); + CHECK_EQ(1, obj->GetOwnPropertyNames()->Length()); + + CHECK(obj->HasPrivate(priv1)); + CHECK(obj->HasPrivate(priv2)); + CHECK(obj->DeletePrivate(priv2)); + CHECK(obj->HasPrivate(priv1)); + CHECK(!obj->HasPrivate(priv2)); + CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value()); + CHECK_EQ(1, obj->GetOwnPropertyNames()->Length()); + + // Private properties are inherited (for the time being). + v8::Local<v8::Object> child = v8::Object::New(isolate); + child->SetPrototype(obj); + CHECK(child->HasPrivate(priv1)); + CHECK_EQ(2002, child->GetPrivate(priv1)->Int32Value()); + CHECK_EQ(0, child->GetOwnPropertyNames()->Length()); } @@ -2772,7 +2921,7 @@ THREADED_TEST(ArrayBuffer_ApiInternalToExternal) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope handle_scope(isolate); - Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(1024); + Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 1024); CheckInternalFieldsAreZero(ab); CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); CHECK(!ab->IsExternal()); @@ -2852,7 +3001,8 @@ THREADED_TEST(ArrayBuffer_External) { i::ScopedVector<uint8_t> my_data(100); memset(my_data.start(), 0, 100); - Local<v8::ArrayBuffer> ab3 = v8::ArrayBuffer::New(my_data.start(), 100); + Local<v8::ArrayBuffer> ab3 = + v8::ArrayBuffer::New(isolate, my_data.start(), 100); CheckInternalFieldsAreZero(ab3); CHECK_EQ(100, static_cast<int>(ab3->ByteLength())); CHECK(ab3->IsExternal()); @@ -2919,7 +3069,7 @@ THREADED_TEST(ArrayBuffer_NeuteringApi) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(1024); + v8::Handle<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, 1024); v8::Handle<v8::Uint8Array> u8a = CreateAndCheck<v8::Uint8Array, 1>(buffer, 1, 1023); @@ -3011,9 +3161,10 @@ THREADED_TEST(ArrayBuffer_NeuteringScript) { THREADED_TEST(HiddenProperties) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - v8::Local<v8::Object> obj = v8::Object::New(); + v8::Local<v8::Object> obj = v8::Object::New(env->GetIsolate()); v8::Local<v8::String> key = v8_str("api-test::hidden-key"); v8::Local<v8::String> empty = v8_str(""); v8::Local<v8::String> prop_name = v8_str("prop_name"); @@ -3023,9 +3174,9 @@ THREADED_TEST(HiddenProperties) { // Make sure delete of a non-existent hidden value works CHECK(obj->DeleteHiddenValue(key)); - CHECK(obj->SetHiddenValue(key, v8::Integer::New(1503))); + CHECK(obj->SetHiddenValue(key, v8::Integer::New(isolate, 1503))); CHECK_EQ(1503, obj->GetHiddenValue(key)->Int32Value()); - CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002))); + CHECK(obj->SetHiddenValue(key, v8::Integer::New(isolate, 2002))); CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); @@ -3035,7 +3186,7 @@ THREADED_TEST(HiddenProperties) { CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); CHECK(obj->Get(empty)->IsUndefined()); CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); - CHECK(obj->Set(empty, v8::Integer::New(2003))); + CHECK(obj->Set(empty, v8::Integer::New(isolate, 2003))); CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); CHECK_EQ(2003, obj->Get(empty)->Int32Value()); @@ -3043,7 +3194,7 @@ THREADED_TEST(HiddenProperties) { // Add another property and delete it afterwards to force the object in // slow case. - CHECK(obj->Set(prop_name, v8::Integer::New(2008))); + CHECK(obj->Set(prop_name, v8::Integer::New(isolate, 2008))); CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); CHECK_EQ(2008, obj->Get(prop_name)->Int32Value()); CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); @@ -3055,7 +3206,7 @@ THREADED_TEST(HiddenProperties) { CHECK(obj->SetHiddenValue(key, Handle<Value>())); CHECK(obj->GetHiddenValue(key).IsEmpty()); - CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002))); + CHECK(obj->SetHiddenValue(key, v8::Integer::New(isolate, 2002))); CHECK(obj->DeleteHiddenValue(key)); CHECK(obj->GetHiddenValue(key).IsEmpty()); } @@ -3068,7 +3219,7 @@ THREADED_TEST(Regress97784) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Local<v8::Object> obj = v8::Object::New(); + v8::Local<v8::Object> obj = v8::Object::New(env->GetIsolate()); v8::Local<v8::String> key = v8_str("hidden"); CompileRun( @@ -3083,7 +3234,7 @@ THREADED_TEST(Regress97784) { // Make sure that the getter and setter from Object.prototype is not invoked. // If it did we would have full access to the hidden properties in // the accessor. - CHECK(obj->SetHiddenValue(key, v8::Integer::New(42))); + CHECK(obj->SetHiddenValue(key, v8::Integer::New(env->GetIsolate(), 42))); ExpectFalse("set_called"); CHECK_EQ(42, obj->GetHiddenValue(key)->Int32Value()); } @@ -3098,19 +3249,20 @@ static void InterceptorForHiddenProperties( THREADED_TEST(HiddenPropertiesWithInterceptors) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); interceptor_for_hidden_properties_called = false; v8::Local<v8::String> key = v8_str("api-test::hidden-key"); // Associate an interceptor with an object and start setting hidden values. - Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); instance_templ->SetNamedPropertyHandler(InterceptorForHiddenProperties); Local<v8::Function> function = fun_templ->GetFunction(); Local<v8::Object> obj = function->NewInstance(); - CHECK(obj->SetHiddenValue(key, v8::Integer::New(2302))); + CHECK(obj->SetHiddenValue(key, v8::Integer::New(isolate, 2302))); CHECK_EQ(2302, obj->GetHiddenValue(key)->Int32Value()); CHECK(!interceptor_for_hidden_properties_called); } @@ -3119,7 +3271,7 @@ THREADED_TEST(HiddenPropertiesWithInterceptors) { THREADED_TEST(External) { v8::HandleScope scope(CcTest::isolate()); int x = 3; - Local<v8::External> ext = v8::External::New(&x); + Local<v8::External> ext = v8::External::New(CcTest::isolate(), &x); LocalContext env; env->Global()->Set(v8_str("ext"), ext); Local<Value> reext_obj = Script::Compile(v8_str("this.ext"))->Run(); @@ -3131,10 +3283,10 @@ THREADED_TEST(External) { // Make sure unaligned pointers are wrapped properly. char* data = i::StrDup("0123456789"); - Local<v8::Value> zero = v8::External::New(&data[0]); - Local<v8::Value> one = v8::External::New(&data[1]); - Local<v8::Value> two = v8::External::New(&data[2]); - Local<v8::Value> three = v8::External::New(&data[3]); + Local<v8::Value> zero = v8::External::New(CcTest::isolate(), &data[0]); + Local<v8::Value> one = v8::External::New(CcTest::isolate(), &data[1]); + Local<v8::Value> two = v8::External::New(CcTest::isolate(), &data[2]); + Local<v8::Value> three = v8::External::New(CcTest::isolate(), &data[3]); char* char_ptr = reinterpret_cast<char*>(v8::External::Cast(*zero)->Value()); CHECK_EQ('0', *char_ptr); @@ -3159,8 +3311,7 @@ THREADED_TEST(GlobalHandle) { v8::HandleScope scope(isolate); CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 3); } - global.Dispose(); - global.Clear(); + global.Reset(); { v8::HandleScope scope(isolate); global.Reset(isolate, v8_str("str")); @@ -3169,7 +3320,7 @@ THREADED_TEST(GlobalHandle) { v8::HandleScope scope(isolate); CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 3); } - global.Dispose(); + global.Reset(); } @@ -3196,7 +3347,7 @@ THREADED_TEST(ResettingGlobalHandle) { v8::HandleScope scope(isolate); CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 6); } - global.Dispose(); + global.Reset(); CHECK_EQ(global_handles->global_handles_count(), initial_handle_count - 1); } @@ -3225,25 +3376,70 @@ THREADED_TEST(ResettingGlobalHandleToEmpty) { } -THREADED_TEST(ClearAndLeakGlobal) { +template<class T> +static v8::UniquePersistent<T> PassUnique(v8::UniquePersistent<T> unique) { + return unique.Pass(); +} + + +template<class T> +static v8::UniquePersistent<T> ReturnUnique(v8::Isolate* isolate, + const v8::Persistent<T> & global) { + v8::UniquePersistent<String> unique(isolate, global); + return unique.Pass(); +} + + +THREADED_TEST(UniquePersistent) { v8::Isolate* isolate = CcTest::isolate(); - v8::internal::GlobalHandles* global_handles = NULL; - int initial_handle_count = 0; v8::Persistent<String> global; { v8::HandleScope scope(isolate); - Local<String> str = v8_str("str"); - global_handles = - reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles(); - initial_handle_count = global_handles->global_handles_count(); - global.Reset(isolate, str); - } - CHECK_EQ(global_handles->global_handles_count(), initial_handle_count + 1); - String* str = global.ClearAndLeak(); - CHECK(global.IsEmpty()); - CHECK_EQ(global_handles->global_handles_count(), initial_handle_count + 1); - global_handles->Destroy(reinterpret_cast<i::Object**>(str)); - CHECK_EQ(global_handles->global_handles_count(), initial_handle_count); + global.Reset(isolate, v8_str("str")); + } + v8::internal::GlobalHandles* global_handles = + reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles(); + int initial_handle_count = global_handles->global_handles_count(); + { + v8::UniquePersistent<String> unique(isolate, global); + CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count()); + // Test assignment via Pass + { + v8::UniquePersistent<String> copy = unique.Pass(); + CHECK(unique.IsEmpty()); + CHECK(copy == global); + CHECK_EQ(initial_handle_count + 1, + global_handles->global_handles_count()); + unique = copy.Pass(); + } + // Test ctor via Pass + { + v8::UniquePersistent<String> copy(unique.Pass()); + CHECK(unique.IsEmpty()); + CHECK(copy == global); + CHECK_EQ(initial_handle_count + 1, + global_handles->global_handles_count()); + unique = copy.Pass(); + } + // Test pass through function call + { + v8::UniquePersistent<String> copy = PassUnique(unique.Pass()); + CHECK(unique.IsEmpty()); + CHECK(copy == global); + CHECK_EQ(initial_handle_count + 1, + global_handles->global_handles_count()); + unique = copy.Pass(); + } + CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count()); + } + // Test pass from function call + { + v8::UniquePersistent<String> unique = ReturnUnique(isolate, global); + CHECK(unique == global); + CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count()); + } + CHECK_EQ(initial_handle_count, global_handles->global_handles_count()); + global.Reset(); } @@ -3256,7 +3452,7 @@ THREADED_TEST(GlobalHandleUpcast) { v8::Persistent<Value>::Cast(global_string); CHECK(v8::Local<v8::Value>::New(isolate, global_value)->IsString()); CHECK(global_string == v8::Persistent<String>::Cast(global_value)); - global_string.Dispose(); + global_string.Reset(); } @@ -3293,8 +3489,8 @@ THREADED_TEST(HandleEquality) { CHECK_EQ(local1 == anotherLocal1, true); CHECK_EQ(local1 != anotherLocal1, false); } - global1.Dispose(); - global2.Dispose(); + global1.Reset(); + global2.Reset(); } @@ -3319,12 +3515,20 @@ class WeakCallCounter { template<typename T> -static void WeakPointerCallback(v8::Isolate* isolate, - Persistent<T>* handle, - WeakCallCounter* counter) { - CHECK_EQ(1234, counter->id()); - counter->increment(); - handle->Dispose(); +struct WeakCallCounterAndPersistent { + explicit WeakCallCounterAndPersistent(WeakCallCounter* counter) + : counter(counter) {} + WeakCallCounter* counter; + v8::Persistent<T> handle; +}; + + +template <typename T> +static void WeakPointerCallback( + const v8::WeakCallbackData<T, WeakCallCounterAndPersistent<T> >& data) { + CHECK_EQ(1234, data.GetParameter()->counter->id()); + data.GetParameter()->counter->increment(); + data.GetParameter()->handle.Reset(); } @@ -3339,52 +3543,53 @@ THREADED_TEST(ApiObjectGroups) { v8::Isolate* iso = env->GetIsolate(); HandleScope scope(iso); - Persistent<Value> g1s1; - Persistent<Value> g1s2; - Persistent<Value> g1c1; - Persistent<Value> g2s1; - Persistent<Value> g2s2; - Persistent<Value> g2c1; - WeakCallCounter counter(1234); + WeakCallCounterAndPersistent<Value> g1s1(&counter); + WeakCallCounterAndPersistent<Value> g1s2(&counter); + WeakCallCounterAndPersistent<Value> g1c1(&counter); + WeakCallCounterAndPersistent<Value> g2s1(&counter); + WeakCallCounterAndPersistent<Value> g2s2(&counter); + WeakCallCounterAndPersistent<Value> g2c1(&counter); + { HandleScope scope(iso); - g1s1.Reset(iso, Object::New()); - g1s2.Reset(iso, Object::New()); - g1c1.Reset(iso, Object::New()); - g1s1.MakeWeak(&counter, &WeakPointerCallback); - g1s2.MakeWeak(&counter, &WeakPointerCallback); - g1c1.MakeWeak(&counter, &WeakPointerCallback); + g1s1.handle.Reset(iso, Object::New(iso)); + g1s2.handle.Reset(iso, Object::New(iso)); + g1c1.handle.Reset(iso, Object::New(iso)); + g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback); + g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback); + g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback); - g2s1.Reset(iso, Object::New()); - g2s2.Reset(iso, Object::New()); - g2c1.Reset(iso, Object::New()); - g2s1.MakeWeak(&counter, &WeakPointerCallback); - g2s2.MakeWeak(&counter, &WeakPointerCallback); - g2c1.MakeWeak(&counter, &WeakPointerCallback); + g2s1.handle.Reset(iso, Object::New(iso)); + g2s2.handle.Reset(iso, Object::New(iso)); + g2c1.handle.Reset(iso, Object::New(iso)); + g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback); + g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback); + g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback); } - Persistent<Value> root(iso, g1s1); // make a root. + WeakCallCounterAndPersistent<Value> root(&counter); + root.handle.Reset(iso, g1s1.handle); // make a root. // Connect group 1 and 2, make a cycle. { HandleScope scope(iso); - CHECK(Local<Object>::New(iso, g1s2.As<Object>())-> - Set(0, Local<Value>::New(iso, g2s2))); - CHECK(Local<Object>::New(iso, g2s1.As<Object>())-> - Set(0, Local<Value>::New(iso, g1s1))); + CHECK(Local<Object>::New(iso, g1s2.handle.As<Object>())-> + Set(0, Local<Value>::New(iso, g2s2.handle))); + CHECK(Local<Object>::New(iso, g2s1.handle.As<Object>())-> + Set(0, Local<Value>::New(iso, g1s1.handle))); } { - UniqueId id1 = MakeUniqueId(g1s1); - UniqueId id2 = MakeUniqueId(g2s2); - iso->SetObjectGroupId(g1s1, id1); - iso->SetObjectGroupId(g1s2, id1); - iso->SetReferenceFromGroup(id1, g1c1); - iso->SetObjectGroupId(g2s1, id2); - iso->SetObjectGroupId(g2s2, id2); - iso->SetReferenceFromGroup(id2, g2c1); + UniqueId id1 = MakeUniqueId(g1s1.handle); + UniqueId id2 = MakeUniqueId(g2s2.handle); + iso->SetObjectGroupId(g1s1.handle, id1); + iso->SetObjectGroupId(g1s2.handle, id1); + iso->SetReferenceFromGroup(id1, g1c1.handle); + iso->SetObjectGroupId(g2s1.handle, id2); + iso->SetObjectGroupId(g2s2.handle, id2); + iso->SetReferenceFromGroup(id2, g2c1.handle); } // Do a single full GC, ensure incremental marking is stopped. v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( @@ -3395,22 +3600,22 @@ THREADED_TEST(ApiObjectGroups) { CHECK_EQ(0, counter.NumberOfWeakCalls()); // Weaken the root. - root.MakeWeak(&counter, &WeakPointerCallback); + root.handle.SetWeak(&root, &WeakPointerCallback); // But make children strong roots---all the objects (except for children) // should be collectable now. - g1c1.ClearWeak(); - g2c1.ClearWeak(); + g1c1.handle.ClearWeak(); + g2c1.handle.ClearWeak(); // Groups are deleted, rebuild groups. { - UniqueId id1 = MakeUniqueId(g1s1); - UniqueId id2 = MakeUniqueId(g2s2); - iso->SetObjectGroupId(g1s1, id1); - iso->SetObjectGroupId(g1s2, id1); - iso->SetReferenceFromGroup(id1, g1c1); - iso->SetObjectGroupId(g2s1, id2); - iso->SetObjectGroupId(g2s2, id2); - iso->SetReferenceFromGroup(id2, g2c1); + UniqueId id1 = MakeUniqueId(g1s1.handle); + UniqueId id2 = MakeUniqueId(g2s2.handle); + iso->SetObjectGroupId(g1s1.handle, id1); + iso->SetObjectGroupId(g1s2.handle, id1); + iso->SetReferenceFromGroup(id1, g1c1.handle); + iso->SetObjectGroupId(g2s1.handle, id2); + iso->SetObjectGroupId(g2s2.handle, id2); + iso->SetReferenceFromGroup(id2, g2c1.handle); } heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); @@ -3419,8 +3624,8 @@ THREADED_TEST(ApiObjectGroups) { CHECK_EQ(5, counter.NumberOfWeakCalls()); // And now make children weak again and collect them. - g1c1.MakeWeak(&counter, &WeakPointerCallback); - g2c1.MakeWeak(&counter, &WeakPointerCallback); + g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback); + g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback); heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); CHECK_EQ(7, counter.NumberOfWeakCalls()); @@ -3432,50 +3637,53 @@ THREADED_TEST(ApiObjectGroupsForSubtypes) { v8::Isolate* iso = env->GetIsolate(); HandleScope scope(iso); - Persistent<Object> g1s1; - Persistent<String> g1s2; - Persistent<String> g1c1; - Persistent<Object> g2s1; - Persistent<String> g2s2; - Persistent<String> g2c1; - WeakCallCounter counter(1234); + WeakCallCounterAndPersistent<Object> g1s1(&counter); + WeakCallCounterAndPersistent<String> g1s2(&counter); + WeakCallCounterAndPersistent<String> g1c1(&counter); + WeakCallCounterAndPersistent<Object> g2s1(&counter); + WeakCallCounterAndPersistent<String> g2s2(&counter); + WeakCallCounterAndPersistent<String> g2c1(&counter); + { HandleScope scope(iso); - g1s1.Reset(iso, Object::New()); - g1s2.Reset(iso, String::New("foo1")); - g1c1.Reset(iso, String::New("foo2")); - g1s1.MakeWeak(&counter, &WeakPointerCallback); - g1s2.MakeWeak(&counter, &WeakPointerCallback); - g1c1.MakeWeak(&counter, &WeakPointerCallback); + g1s1.handle.Reset(iso, Object::New(iso)); + g1s2.handle.Reset(iso, String::NewFromUtf8(iso, "foo1")); + g1c1.handle.Reset(iso, String::NewFromUtf8(iso, "foo2")); + g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback); + g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback); + g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback); - g2s1.Reset(iso, Object::New()); - g2s2.Reset(iso, String::New("foo3")); - g2c1.Reset(iso, String::New("foo4")); - g2s1.MakeWeak(&counter, &WeakPointerCallback); - g2s2.MakeWeak(&counter, &WeakPointerCallback); - g2c1.MakeWeak(&counter, &WeakPointerCallback); + g2s1.handle.Reset(iso, Object::New(iso)); + g2s2.handle.Reset(iso, String::NewFromUtf8(iso, "foo3")); + g2c1.handle.Reset(iso, String::NewFromUtf8(iso, "foo4")); + g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback); + g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback); + g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback); } - Persistent<Value> root(iso, g1s1); // make a root. + WeakCallCounterAndPersistent<Value> root(&counter); + root.handle.Reset(iso, g1s1.handle); // make a root. // Connect group 1 and 2, make a cycle. { HandleScope scope(iso); - CHECK(Local<Object>::New(iso, g1s1)->Set(0, Local<Object>::New(iso, g2s1))); - CHECK(Local<Object>::New(iso, g2s1)->Set(0, Local<Object>::New(iso, g1s1))); + CHECK(Local<Object>::New(iso, g1s1.handle) + ->Set(0, Local<Object>::New(iso, g2s1.handle))); + CHECK(Local<Object>::New(iso, g2s1.handle) + ->Set(0, Local<Object>::New(iso, g1s1.handle))); } { - UniqueId id1 = MakeUniqueId(g1s1); - UniqueId id2 = MakeUniqueId(g2s2); - iso->SetObjectGroupId(g1s1, id1); - iso->SetObjectGroupId(g1s2, id1); - iso->SetReference(g1s1, g1c1); - iso->SetObjectGroupId(g2s1, id2); - iso->SetObjectGroupId(g2s2, id2); - iso->SetReferenceFromGroup(id2, g2c1); + UniqueId id1 = MakeUniqueId(g1s1.handle); + UniqueId id2 = MakeUniqueId(g2s2.handle); + iso->SetObjectGroupId(g1s1.handle, id1); + iso->SetObjectGroupId(g1s2.handle, id1); + iso->SetReference(g1s1.handle, g1c1.handle); + iso->SetObjectGroupId(g2s1.handle, id2); + iso->SetObjectGroupId(g2s2.handle, id2); + iso->SetReferenceFromGroup(id2, g2c1.handle); } // Do a single full GC, ensure incremental marking is stopped. v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( @@ -3486,22 +3694,22 @@ THREADED_TEST(ApiObjectGroupsForSubtypes) { CHECK_EQ(0, counter.NumberOfWeakCalls()); // Weaken the root. - root.MakeWeak(&counter, &WeakPointerCallback); + root.handle.SetWeak(&root, &WeakPointerCallback); // But make children strong roots---all the objects (except for children) // should be collectable now. - g1c1.ClearWeak(); - g2c1.ClearWeak(); + g1c1.handle.ClearWeak(); + g2c1.handle.ClearWeak(); // Groups are deleted, rebuild groups. { - UniqueId id1 = MakeUniqueId(g1s1); - UniqueId id2 = MakeUniqueId(g2s2); - iso->SetObjectGroupId(g1s1, id1); - iso->SetObjectGroupId(g1s2, id1); - iso->SetReference(g1s1, g1c1); - iso->SetObjectGroupId(g2s1, id2); - iso->SetObjectGroupId(g2s2, id2); - iso->SetReferenceFromGroup(id2, g2c1); + UniqueId id1 = MakeUniqueId(g1s1.handle); + UniqueId id2 = MakeUniqueId(g2s2.handle); + iso->SetObjectGroupId(g1s1.handle, id1); + iso->SetObjectGroupId(g1s2.handle, id1); + iso->SetReference(g1s1.handle, g1c1.handle); + iso->SetObjectGroupId(g2s1.handle, id2); + iso->SetObjectGroupId(g2s2.handle, id2); + iso->SetReferenceFromGroup(id2, g2c1.handle); } heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); @@ -3510,8 +3718,8 @@ THREADED_TEST(ApiObjectGroupsForSubtypes) { CHECK_EQ(5, counter.NumberOfWeakCalls()); // And now make children weak again and collect them. - g1c1.MakeWeak(&counter, &WeakPointerCallback); - g2c1.MakeWeak(&counter, &WeakPointerCallback); + g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback); + g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback); heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); CHECK_EQ(7, counter.NumberOfWeakCalls()); @@ -3525,68 +3733,69 @@ THREADED_TEST(ApiObjectGroupsCycle) { WeakCallCounter counter(1234); - Persistent<Value> g1s1; - Persistent<Value> g1s2; - Persistent<Value> g2s1; - Persistent<Value> g2s2; - Persistent<Value> g3s1; - Persistent<Value> g3s2; - Persistent<Value> g4s1; - Persistent<Value> g4s2; + WeakCallCounterAndPersistent<Value> g1s1(&counter); + WeakCallCounterAndPersistent<Value> g1s2(&counter); + WeakCallCounterAndPersistent<Value> g2s1(&counter); + WeakCallCounterAndPersistent<Value> g2s2(&counter); + WeakCallCounterAndPersistent<Value> g3s1(&counter); + WeakCallCounterAndPersistent<Value> g3s2(&counter); + WeakCallCounterAndPersistent<Value> g4s1(&counter); + WeakCallCounterAndPersistent<Value> g4s2(&counter); { HandleScope scope(iso); - g1s1.Reset(iso, Object::New()); - g1s2.Reset(iso, Object::New()); - g1s1.MakeWeak(&counter, &WeakPointerCallback); - g1s2.MakeWeak(&counter, &WeakPointerCallback); - CHECK(g1s1.IsWeak()); - CHECK(g1s2.IsWeak()); - - g2s1.Reset(iso, Object::New()); - g2s2.Reset(iso, Object::New()); - g2s1.MakeWeak(&counter, &WeakPointerCallback); - g2s2.MakeWeak(&counter, &WeakPointerCallback); - CHECK(g2s1.IsWeak()); - CHECK(g2s2.IsWeak()); - - g3s1.Reset(iso, Object::New()); - g3s2.Reset(iso, Object::New()); - g3s1.MakeWeak(&counter, &WeakPointerCallback); - g3s2.MakeWeak(&counter, &WeakPointerCallback); - CHECK(g3s1.IsWeak()); - CHECK(g3s2.IsWeak()); - - g4s1.Reset(iso, Object::New()); - g4s2.Reset(iso, Object::New()); - g4s1.MakeWeak(&counter, &WeakPointerCallback); - g4s2.MakeWeak(&counter, &WeakPointerCallback); - CHECK(g4s1.IsWeak()); - CHECK(g4s2.IsWeak()); - } - - Persistent<Value> root(iso, g1s1); // make a root. + g1s1.handle.Reset(iso, Object::New(iso)); + g1s2.handle.Reset(iso, Object::New(iso)); + g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback); + g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback); + CHECK(g1s1.handle.IsWeak()); + CHECK(g1s2.handle.IsWeak()); + + g2s1.handle.Reset(iso, Object::New(iso)); + g2s2.handle.Reset(iso, Object::New(iso)); + g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback); + g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback); + CHECK(g2s1.handle.IsWeak()); + CHECK(g2s2.handle.IsWeak()); + + g3s1.handle.Reset(iso, Object::New(iso)); + g3s2.handle.Reset(iso, Object::New(iso)); + g3s1.handle.SetWeak(&g3s1, &WeakPointerCallback); + g3s2.handle.SetWeak(&g3s2, &WeakPointerCallback); + CHECK(g3s1.handle.IsWeak()); + CHECK(g3s2.handle.IsWeak()); + + g4s1.handle.Reset(iso, Object::New(iso)); + g4s2.handle.Reset(iso, Object::New(iso)); + g4s1.handle.SetWeak(&g4s1, &WeakPointerCallback); + g4s2.handle.SetWeak(&g4s2, &WeakPointerCallback); + CHECK(g4s1.handle.IsWeak()); + CHECK(g4s2.handle.IsWeak()); + } + + WeakCallCounterAndPersistent<Value> root(&counter); + root.handle.Reset(iso, g1s1.handle); // make a root. // Connect groups. We're building the following cycle: // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other // groups. { - UniqueId id1 = MakeUniqueId(g1s1); - UniqueId id2 = MakeUniqueId(g2s1); - UniqueId id3 = MakeUniqueId(g3s1); - UniqueId id4 = MakeUniqueId(g4s1); - iso->SetObjectGroupId(g1s1, id1); - iso->SetObjectGroupId(g1s2, id1); - iso->SetReferenceFromGroup(id1, g2s1); - iso->SetObjectGroupId(g2s1, id2); - iso->SetObjectGroupId(g2s2, id2); - iso->SetReferenceFromGroup(id2, g3s1); - iso->SetObjectGroupId(g3s1, id3); - iso->SetObjectGroupId(g3s2, id3); - iso->SetReferenceFromGroup(id3, g4s1); - iso->SetObjectGroupId(g4s1, id4); - iso->SetObjectGroupId(g4s2, id4); - iso->SetReferenceFromGroup(id4, g1s1); + UniqueId id1 = MakeUniqueId(g1s1.handle); + UniqueId id2 = MakeUniqueId(g2s1.handle); + UniqueId id3 = MakeUniqueId(g3s1.handle); + UniqueId id4 = MakeUniqueId(g4s1.handle); + iso->SetObjectGroupId(g1s1.handle, id1); + iso->SetObjectGroupId(g1s2.handle, id1); + iso->SetReferenceFromGroup(id1, g2s1.handle); + iso->SetObjectGroupId(g2s1.handle, id2); + iso->SetObjectGroupId(g2s2.handle, id2); + iso->SetReferenceFromGroup(id2, g3s1.handle); + iso->SetObjectGroupId(g3s1.handle, id3); + iso->SetObjectGroupId(g3s2.handle, id3); + iso->SetReferenceFromGroup(id3, g4s1.handle); + iso->SetObjectGroupId(g4s1.handle, id4); + iso->SetObjectGroupId(g4s2.handle, id4); + iso->SetReferenceFromGroup(id4, g1s1.handle); } // Do a single full GC v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( @@ -3597,26 +3806,26 @@ THREADED_TEST(ApiObjectGroupsCycle) { CHECK_EQ(0, counter.NumberOfWeakCalls()); // Weaken the root. - root.MakeWeak(&counter, &WeakPointerCallback); + root.handle.SetWeak(&root, &WeakPointerCallback); // Groups are deleted, rebuild groups. { - UniqueId id1 = MakeUniqueId(g1s1); - UniqueId id2 = MakeUniqueId(g2s1); - UniqueId id3 = MakeUniqueId(g3s1); - UniqueId id4 = MakeUniqueId(g4s1); - iso->SetObjectGroupId(g1s1, id1); - iso->SetObjectGroupId(g1s2, id1); - iso->SetReferenceFromGroup(id1, g2s1); - iso->SetObjectGroupId(g2s1, id2); - iso->SetObjectGroupId(g2s2, id2); - iso->SetReferenceFromGroup(id2, g3s1); - iso->SetObjectGroupId(g3s1, id3); - iso->SetObjectGroupId(g3s2, id3); - iso->SetReferenceFromGroup(id3, g4s1); - iso->SetObjectGroupId(g4s1, id4); - iso->SetObjectGroupId(g4s2, id4); - iso->SetReferenceFromGroup(id4, g1s1); + UniqueId id1 = MakeUniqueId(g1s1.handle); + UniqueId id2 = MakeUniqueId(g2s1.handle); + UniqueId id3 = MakeUniqueId(g3s1.handle); + UniqueId id4 = MakeUniqueId(g4s1.handle); + iso->SetObjectGroupId(g1s1.handle, id1); + iso->SetObjectGroupId(g1s2.handle, id1); + iso->SetReferenceFromGroup(id1, g2s1.handle); + iso->SetObjectGroupId(g2s1.handle, id2); + iso->SetObjectGroupId(g2s2.handle, id2); + iso->SetReferenceFromGroup(id2, g3s1.handle); + iso->SetObjectGroupId(g3s1.handle, id3); + iso->SetObjectGroupId(g3s2.handle, id3); + iso->SetReferenceFromGroup(id3, g4s1.handle); + iso->SetObjectGroupId(g4s1.handle, id4); + iso->SetObjectGroupId(g4s2.handle, id4); + iso->SetReferenceFromGroup(id4, g1s1.handle); } heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); @@ -3637,58 +3846,59 @@ TEST(ApiObjectGroupsCycleForScavenger) { WeakCallCounter counter(1234); - Persistent<Value> g1s1; - Persistent<Value> g1s2; - Persistent<Value> g2s1; - Persistent<Value> g2s2; - Persistent<Value> g3s1; - Persistent<Value> g3s2; + WeakCallCounterAndPersistent<Value> g1s1(&counter); + WeakCallCounterAndPersistent<Value> g1s2(&counter); + WeakCallCounterAndPersistent<Value> g2s1(&counter); + WeakCallCounterAndPersistent<Value> g2s2(&counter); + WeakCallCounterAndPersistent<Value> g3s1(&counter); + WeakCallCounterAndPersistent<Value> g3s2(&counter); { HandleScope scope(iso); - g1s1.Reset(iso, Object::New()); - g1s2.Reset(iso, Object::New()); - g1s1.MakeWeak(&counter, &WeakPointerCallback); - g1s2.MakeWeak(&counter, &WeakPointerCallback); + g1s1.handle.Reset(iso, Object::New(iso)); + g1s2.handle.Reset(iso, Object::New(iso)); + g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback); + g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback); - g2s1.Reset(iso, Object::New()); - g2s2.Reset(iso, Object::New()); - g2s1.MakeWeak(&counter, &WeakPointerCallback); - g2s2.MakeWeak(&counter, &WeakPointerCallback); + g2s1.handle.Reset(iso, Object::New(iso)); + g2s2.handle.Reset(iso, Object::New(iso)); + g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback); + g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback); - g3s1.Reset(iso, Object::New()); - g3s2.Reset(iso, Object::New()); - g3s1.MakeWeak(&counter, &WeakPointerCallback); - g3s2.MakeWeak(&counter, &WeakPointerCallback); + g3s1.handle.Reset(iso, Object::New(iso)); + g3s2.handle.Reset(iso, Object::New(iso)); + g3s1.handle.SetWeak(&g3s1, &WeakPointerCallback); + g3s2.handle.SetWeak(&g3s2, &WeakPointerCallback); } // Make a root. - Persistent<Value> root(iso, g1s1); - root.MarkPartiallyDependent(); + WeakCallCounterAndPersistent<Value> root(&counter); + root.handle.Reset(iso, g1s1.handle); + root.handle.MarkPartiallyDependent(); // Connect groups. We're building the following cycle: // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other // groups. { HandleScope handle_scope(iso); - g1s1.MarkPartiallyDependent(); - g1s2.MarkPartiallyDependent(); - g2s1.MarkPartiallyDependent(); - g2s2.MarkPartiallyDependent(); - g3s1.MarkPartiallyDependent(); - g3s2.MarkPartiallyDependent(); - iso->SetObjectGroupId(g1s1, UniqueId(1)); - iso->SetObjectGroupId(g1s2, UniqueId(1)); - Local<Object>::New(iso, g1s1.As<Object>())->Set( - v8_str("x"), Local<Value>::New(iso, g2s1)); - iso->SetObjectGroupId(g2s1, UniqueId(2)); - iso->SetObjectGroupId(g2s2, UniqueId(2)); - Local<Object>::New(iso, g2s1.As<Object>())->Set( - v8_str("x"), Local<Value>::New(iso, g3s1)); - iso->SetObjectGroupId(g3s1, UniqueId(3)); - iso->SetObjectGroupId(g3s2, UniqueId(3)); - Local<Object>::New(iso, g3s1.As<Object>())->Set( - v8_str("x"), Local<Value>::New(iso, g1s1)); + g1s1.handle.MarkPartiallyDependent(); + g1s2.handle.MarkPartiallyDependent(); + g2s1.handle.MarkPartiallyDependent(); + g2s2.handle.MarkPartiallyDependent(); + g3s1.handle.MarkPartiallyDependent(); + g3s2.handle.MarkPartiallyDependent(); + iso->SetObjectGroupId(g1s1.handle, UniqueId(1)); + iso->SetObjectGroupId(g1s2.handle, UniqueId(1)); + Local<Object>::New(iso, g1s1.handle.As<Object>())->Set( + v8_str("x"), Local<Value>::New(iso, g2s1.handle)); + iso->SetObjectGroupId(g2s1.handle, UniqueId(2)); + iso->SetObjectGroupId(g2s2.handle, UniqueId(2)); + Local<Object>::New(iso, g2s1.handle.As<Object>())->Set( + v8_str("x"), Local<Value>::New(iso, g3s1.handle)); + iso->SetObjectGroupId(g3s1.handle, UniqueId(3)); + iso->SetObjectGroupId(g3s2.handle, UniqueId(3)); + Local<Object>::New(iso, g3s1.handle.As<Object>())->Set( + v8_str("x"), Local<Value>::New(iso, g1s1.handle)); } v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( @@ -3699,30 +3909,30 @@ TEST(ApiObjectGroupsCycleForScavenger) { CHECK_EQ(0, counter.NumberOfWeakCalls()); // Weaken the root. - root.MakeWeak(&counter, &WeakPointerCallback); - root.MarkPartiallyDependent(); + root.handle.SetWeak(&root, &WeakPointerCallback); + root.handle.MarkPartiallyDependent(); // Groups are deleted, rebuild groups. { HandleScope handle_scope(iso); - g1s1.MarkPartiallyDependent(); - g1s2.MarkPartiallyDependent(); - g2s1.MarkPartiallyDependent(); - g2s2.MarkPartiallyDependent(); - g3s1.MarkPartiallyDependent(); - g3s2.MarkPartiallyDependent(); - iso->SetObjectGroupId(g1s1, UniqueId(1)); - iso->SetObjectGroupId(g1s2, UniqueId(1)); - Local<Object>::New(iso, g1s1.As<Object>())->Set( - v8_str("x"), Local<Value>::New(iso, g2s1)); - iso->SetObjectGroupId(g2s1, UniqueId(2)); - iso->SetObjectGroupId(g2s2, UniqueId(2)); - Local<Object>::New(iso, g2s1.As<Object>())->Set( - v8_str("x"), Local<Value>::New(iso, g3s1)); - iso->SetObjectGroupId(g3s1, UniqueId(3)); - iso->SetObjectGroupId(g3s2, UniqueId(3)); - Local<Object>::New(iso, g3s1.As<Object>())->Set( - v8_str("x"), Local<Value>::New(iso, g1s1)); + g1s1.handle.MarkPartiallyDependent(); + g1s2.handle.MarkPartiallyDependent(); + g2s1.handle.MarkPartiallyDependent(); + g2s2.handle.MarkPartiallyDependent(); + g3s1.handle.MarkPartiallyDependent(); + g3s2.handle.MarkPartiallyDependent(); + iso->SetObjectGroupId(g1s1.handle, UniqueId(1)); + iso->SetObjectGroupId(g1s2.handle, UniqueId(1)); + Local<Object>::New(iso, g1s1.handle.As<Object>())->Set( + v8_str("x"), Local<Value>::New(iso, g2s1.handle)); + iso->SetObjectGroupId(g2s1.handle, UniqueId(2)); + iso->SetObjectGroupId(g2s2.handle, UniqueId(2)); + Local<Object>::New(iso, g2s1.handle.As<Object>())->Set( + v8_str("x"), Local<Value>::New(iso, g3s1.handle)); + iso->SetObjectGroupId(g3s1.handle, UniqueId(3)); + iso->SetObjectGroupId(g3s2.handle, UniqueId(3)); + Local<Object>::New(iso, g3s1.handle.As<Object>())->Set( + v8_str("x"), Local<Value>::New(iso, g1s1.handle)); } heap->CollectGarbage(i::NEW_SPACE); @@ -3774,8 +3984,8 @@ THREADED_TEST(MessageHandler0) { message_received = false; v8::HandleScope scope(CcTest::isolate()); CHECK(!message_received); - v8::V8::AddMessageListener(check_message_0, v8_num(5.76)); LocalContext context; + v8::V8::AddMessageListener(check_message_0, v8_num(5.76)); v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("6.75")); v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), @@ -3856,8 +4066,8 @@ TEST(MessageHandler3) { LocalContext context; v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("6.75"), - v8::Integer::New(1, isolate), - v8::Integer::New(2, isolate), + v8::Integer::New(isolate, 1), + v8::Integer::New(isolate, 2), v8::True(isolate)); v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), &origin); @@ -3885,8 +4095,8 @@ TEST(MessageHandler4) { LocalContext context; v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("6.75"), - v8::Integer::New(1, isolate), - v8::Integer::New(2, isolate), + v8::Integer::New(isolate, 1), + v8::Integer::New(isolate, 2), v8::False(isolate)); v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), &origin); @@ -3922,8 +4132,8 @@ TEST(MessageHandler5) { LocalContext context; v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("6.75"), - v8::Integer::New(1, isolate), - v8::Integer::New(2, isolate), + v8::Integer::New(isolate, 1), + v8::Integer::New(isolate, 2), v8::True(isolate)); v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), &origin); @@ -3936,8 +4146,8 @@ TEST(MessageHandler5) { v8::V8::AddMessageListener(check_message_5b); origin = v8::ScriptOrigin(v8_str("6.75"), - v8::Integer::New(1, isolate), - v8::Integer::New(2, isolate), + v8::Integer::New(isolate, 1), + v8::Integer::New(isolate, 2), v8::False(isolate)); script = Script::Compile(v8_str("throw 'error'"), &origin); @@ -3950,10 +4160,11 @@ TEST(MessageHandler5) { THREADED_TEST(GetSetProperty) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); context->Global()->Set(v8_str("foo"), v8_num(14)); context->Global()->Set(v8_str("12"), v8_num(92)); - context->Global()->Set(v8::Integer::New(16), v8_num(32)); + context->Global()->Set(v8::Integer::New(isolate, 16), v8_num(32)); context->Global()->Set(v8_num(13), v8_num(56)); Local<Value> foo = Script::Compile(v8_str("this.foo"))->Run(); CHECK_EQ(14, foo->Int32Value()); @@ -3963,13 +4174,16 @@ THREADED_TEST(GetSetProperty) { CHECK_EQ(32, sixteen->Int32Value()); Local<Value> thirteen = Script::Compile(v8_str("this[13]"))->Run(); CHECK_EQ(56, thirteen->Int32Value()); - CHECK_EQ(92, context->Global()->Get(v8::Integer::New(12))->Int32Value()); + CHECK_EQ(92, + context->Global()->Get(v8::Integer::New(isolate, 12))->Int32Value()); CHECK_EQ(92, context->Global()->Get(v8_str("12"))->Int32Value()); CHECK_EQ(92, context->Global()->Get(v8_num(12))->Int32Value()); - CHECK_EQ(32, context->Global()->Get(v8::Integer::New(16))->Int32Value()); + CHECK_EQ(32, + context->Global()->Get(v8::Integer::New(isolate, 16))->Int32Value()); CHECK_EQ(32, context->Global()->Get(v8_str("16"))->Int32Value()); CHECK_EQ(32, context->Global()->Get(v8_num(16))->Int32Value()); - CHECK_EQ(56, context->Global()->Get(v8::Integer::New(13))->Int32Value()); + CHECK_EQ(56, + context->Global()->Get(v8::Integer::New(isolate, 13))->Int32Value()); CHECK_EQ(56, context->Global()->Get(v8_str("13"))->Int32Value()); CHECK_EQ(56, context->Global()->Get(v8_num(13))->Int32Value()); } @@ -4022,7 +4236,7 @@ THREADED_TEST(PropertyAttributes) { THREADED_TEST(Array) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - Local<v8::Array> array = v8::Array::New(); + Local<v8::Array> array = v8::Array::New(context->GetIsolate()); CHECK_EQ(0, array->Length()); CHECK(array->Get(0)->IsUndefined()); CHECK(!array->Has(0)); @@ -4040,27 +4254,28 @@ THREADED_TEST(Array) { CHECK_EQ(1, arr->Get(0)->Int32Value()); CHECK_EQ(2, arr->Get(1)->Int32Value()); CHECK_EQ(3, arr->Get(2)->Int32Value()); - array = v8::Array::New(27); + array = v8::Array::New(context->GetIsolate(), 27); CHECK_EQ(27, array->Length()); - array = v8::Array::New(-27); + array = v8::Array::New(context->GetIsolate(), -27); CHECK_EQ(0, array->Length()); } void HandleF(const v8::FunctionCallbackInfo<v8::Value>& args) { - v8::HandleScope scope(args.GetIsolate()); + v8::EscapableHandleScope scope(args.GetIsolate()); ApiTestFuzzer::Fuzz(); - Local<v8::Array> result = v8::Array::New(args.Length()); + Local<v8::Array> result = v8::Array::New(args.GetIsolate(), args.Length()); for (int i = 0; i < args.Length(); i++) result->Set(i, args[i]); - args.GetReturnValue().Set(scope.Close(result)); + args.GetReturnValue().Set(scope.Escape(result)); } THREADED_TEST(Vector) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> global = ObjectTemplate::New(); - global->Set(v8_str("f"), v8::FunctionTemplate::New(HandleF)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> global = ObjectTemplate::New(isolate); + global->Set(v8_str("f"), v8::FunctionTemplate::New(isolate, HandleF)); LocalContext context(0, global); const char* fun = "f()"; @@ -4128,23 +4343,23 @@ THREADED_TEST(FunctionCall) { v8::Handle<Value> args1[] = { v8_num(1.1) }; Local<v8::Array> a1 = Local<v8::Array>::Cast(Foo->Call(Foo, 1, args1)); CHECK_EQ(1, a1->Length()); - CHECK_EQ(1.1, a1->Get(v8::Integer::New(0))->NumberValue()); + CHECK_EQ(1.1, a1->Get(v8::Integer::New(isolate, 0))->NumberValue()); v8::Handle<Value> args2[] = { v8_num(2.2), v8_num(3.3) }; Local<v8::Array> a2 = Local<v8::Array>::Cast(Foo->Call(Foo, 2, args2)); CHECK_EQ(2, a2->Length()); - CHECK_EQ(2.2, a2->Get(v8::Integer::New(0))->NumberValue()); - CHECK_EQ(3.3, a2->Get(v8::Integer::New(1))->NumberValue()); + CHECK_EQ(2.2, a2->Get(v8::Integer::New(isolate, 0))->NumberValue()); + CHECK_EQ(3.3, a2->Get(v8::Integer::New(isolate, 1))->NumberValue()); v8::Handle<Value> args3[] = { v8_num(4.4), v8_num(5.5), v8_num(6.6) }; Local<v8::Array> a3 = Local<v8::Array>::Cast(Foo->Call(Foo, 3, args3)); CHECK_EQ(3, a3->Length()); - CHECK_EQ(4.4, a3->Get(v8::Integer::New(0))->NumberValue()); - CHECK_EQ(5.5, a3->Get(v8::Integer::New(1))->NumberValue()); - CHECK_EQ(6.6, a3->Get(v8::Integer::New(2))->NumberValue()); + CHECK_EQ(4.4, a3->Get(v8::Integer::New(isolate, 0))->NumberValue()); + CHECK_EQ(5.5, a3->Get(v8::Integer::New(isolate, 1))->NumberValue()); + CHECK_EQ(6.6, a3->Get(v8::Integer::New(isolate, 2))->NumberValue()); v8::Handle<Value> args4[] = { v8_num(7.7), v8_num(8.8), @@ -4152,10 +4367,10 @@ THREADED_TEST(FunctionCall) { v8_num(10.11) }; Local<v8::Array> a4 = Local<v8::Array>::Cast(Foo->Call(Foo, 4, args4)); CHECK_EQ(4, a4->Length()); - CHECK_EQ(7.7, a4->Get(v8::Integer::New(0))->NumberValue()); - CHECK_EQ(8.8, a4->Get(v8::Integer::New(1))->NumberValue()); - CHECK_EQ(9.9, a4->Get(v8::Integer::New(2))->NumberValue()); - CHECK_EQ(10.11, a4->Get(v8::Integer::New(3))->NumberValue()); + CHECK_EQ(7.7, a4->Get(v8::Integer::New(isolate, 0))->NumberValue()); + CHECK_EQ(8.8, a4->Get(v8::Integer::New(isolate, 1))->NumberValue()); + CHECK_EQ(9.9, a4->Get(v8::Integer::New(isolate, 2))->NumberValue()); + CHECK_EQ(10.11, a4->Get(v8::Integer::New(isolate, 3))->NumberValue()); Local<v8::Value> r1 = ReturnThisSloppy->Call(v8::Undefined(isolate), 0, NULL); CHECK(r1->StrictEquals(context->Global())); @@ -4198,14 +4413,14 @@ TEST(OutOfMemory) { v8::ResourceConstraints constraints; constraints.set_max_young_space_size(256 * K); constraints.set_max_old_space_size(5 * K * K); - v8::SetResourceConstraints(&constraints); + v8::SetResourceConstraints(CcTest::isolate(), &constraints); // Execute a script that causes out of memory. LocalContext context; v8::HandleScope scope(context->GetIsolate()); v8::V8::IgnoreOutOfMemoryException(); - Local<Script> script = - Script::Compile(String::New(js_code_causing_out_of_memory)); + Local<Script> script = Script::Compile(String::NewFromUtf8( + context->GetIsolate(), js_code_causing_out_of_memory)); Local<Value> result = script->Run(); // Check for out of memory state. @@ -4219,8 +4434,8 @@ void ProvokeOutOfMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - Local<Script> script = - Script::Compile(String::New(js_code_causing_out_of_memory)); + Local<Script> script = Script::Compile(String::NewFromUtf8( + context->GetIsolate(), js_code_causing_out_of_memory)); Local<Value> result = script->Run(); // Check for out of memory state. @@ -4239,12 +4454,13 @@ TEST(OutOfMemoryNested) { v8::ResourceConstraints constraints; constraints.set_max_young_space_size(256 * K); constraints.set_max_old_space_size(5 * K * K); - v8::SetResourceConstraints(&constraints); + v8::Isolate* isolate = CcTest::isolate(); + v8::SetResourceConstraints(isolate, &constraints); - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("ProvokeOutOfMemory"), - v8::FunctionTemplate::New(ProvokeOutOfMemory)); + v8::FunctionTemplate::New(isolate, ProvokeOutOfMemory)); LocalContext context(0, templ); v8::V8::IgnoreOutOfMemoryException(); Local<Value> result = CompileRun( @@ -4260,6 +4476,11 @@ TEST(OutOfMemoryNested) { } +void OOMCallback(const char* location, const char* message) { + exit(0); +} + + TEST(HugeConsStringOutOfMemory) { // It's not possible to read a snapshot into a heap with different dimensions. if (i::Snapshot::IsEnabled()) return; @@ -4268,28 +4489,27 @@ TEST(HugeConsStringOutOfMemory) { v8::ResourceConstraints constraints; constraints.set_max_young_space_size(256 * K); constraints.set_max_old_space_size(4 * K * K); - v8::SetResourceConstraints(&constraints); + v8::SetResourceConstraints(CcTest::isolate(), &constraints); // Execute a script that causes out of memory. - v8::V8::IgnoreOutOfMemoryException(); + v8::V8::SetFatalErrorHandler(OOMCallback); LocalContext context; v8::HandleScope scope(context->GetIsolate()); // Build huge string. This should fail with out of memory exception. - Local<Value> result = CompileRun( + CompileRun( "var str = Array.prototype.join.call({length: 513}, \"A\").toUpperCase();" "for (var i = 0; i < 22; i++) { str = str + str; }"); - // Check for out of memory state. - CHECK(result.IsEmpty()); - CHECK(context->HasOutOfMemoryException()); + CHECK(false); // Should not return. } THREADED_TEST(ConstructCall) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); CompileRun( "function Foo() {" " var result = [];" @@ -4308,23 +4528,23 @@ THREADED_TEST(ConstructCall) { v8::Handle<Value> args1[] = { v8_num(1.1) }; Local<v8::Array> a1 = Local<v8::Array>::Cast(Foo->NewInstance(1, args1)); CHECK_EQ(1, a1->Length()); - CHECK_EQ(1.1, a1->Get(v8::Integer::New(0))->NumberValue()); + CHECK_EQ(1.1, a1->Get(v8::Integer::New(isolate, 0))->NumberValue()); v8::Handle<Value> args2[] = { v8_num(2.2), v8_num(3.3) }; Local<v8::Array> a2 = Local<v8::Array>::Cast(Foo->NewInstance(2, args2)); CHECK_EQ(2, a2->Length()); - CHECK_EQ(2.2, a2->Get(v8::Integer::New(0))->NumberValue()); - CHECK_EQ(3.3, a2->Get(v8::Integer::New(1))->NumberValue()); + CHECK_EQ(2.2, a2->Get(v8::Integer::New(isolate, 0))->NumberValue()); + CHECK_EQ(3.3, a2->Get(v8::Integer::New(isolate, 1))->NumberValue()); v8::Handle<Value> args3[] = { v8_num(4.4), v8_num(5.5), v8_num(6.6) }; Local<v8::Array> a3 = Local<v8::Array>::Cast(Foo->NewInstance(3, args3)); CHECK_EQ(3, a3->Length()); - CHECK_EQ(4.4, a3->Get(v8::Integer::New(0))->NumberValue()); - CHECK_EQ(5.5, a3->Get(v8::Integer::New(1))->NumberValue()); - CHECK_EQ(6.6, a3->Get(v8::Integer::New(2))->NumberValue()); + CHECK_EQ(4.4, a3->Get(v8::Integer::New(isolate, 0))->NumberValue()); + CHECK_EQ(5.5, a3->Get(v8::Integer::New(isolate, 1))->NumberValue()); + CHECK_EQ(6.6, a3->Get(v8::Integer::New(isolate, 2))->NumberValue()); v8::Handle<Value> args4[] = { v8_num(7.7), v8_num(8.8), @@ -4332,10 +4552,10 @@ THREADED_TEST(ConstructCall) { v8_num(10.11) }; Local<v8::Array> a4 = Local<v8::Array>::Cast(Foo->NewInstance(4, args4)); CHECK_EQ(4, a4->Length()); - CHECK_EQ(7.7, a4->Get(v8::Integer::New(0))->NumberValue()); - CHECK_EQ(8.8, a4->Get(v8::Integer::New(1))->NumberValue()); - CHECK_EQ(9.9, a4->Get(v8::Integer::New(2))->NumberValue()); - CHECK_EQ(10.11, a4->Get(v8::Integer::New(3))->NumberValue()); + CHECK_EQ(7.7, a4->Get(v8::Integer::New(isolate, 0))->NumberValue()); + CHECK_EQ(8.8, a4->Get(v8::Integer::New(isolate, 1))->NumberValue()); + CHECK_EQ(9.9, a4->Get(v8::Integer::New(isolate, 2))->NumberValue()); + CHECK_EQ(10.11, a4->Get(v8::Integer::New(isolate, 3))->NumberValue()); } @@ -4521,10 +4741,11 @@ void CCatcher(const v8::FunctionCallbackInfo<v8::Value>& args) { THREADED_TEST(APICatch) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("ThrowFromC"), - v8::FunctionTemplate::New(ThrowFromC)); + v8::FunctionTemplate::New(isolate, ThrowFromC)); LocalContext context(0, templ); CompileRun( "var thrown = false;" @@ -4539,10 +4760,11 @@ THREADED_TEST(APICatch) { THREADED_TEST(APIThrowTryCatch) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("ThrowFromC"), - v8::FunctionTemplate::New(ThrowFromC)); + v8::FunctionTemplate::New(isolate, ThrowFromC)); LocalContext context(0, templ); v8::TryCatch try_catch; CompileRun("ThrowFromC();"); @@ -4558,10 +4780,11 @@ THREADED_TEST(APIThrowTryCatch) { // JS stack. This test therefore fails on the simulator. The test is // not threaded to allow the threading tests to run on the simulator. TEST(TryCatchInTryFinally) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("CCatcher"), - v8::FunctionTemplate::New(CCatcher)); + v8::FunctionTemplate::New(isolate, CCatcher)); LocalContext context(0, templ); Local<Value> result = CompileRun("try {" " try {" @@ -4592,10 +4815,11 @@ static void Fail(const v8::FunctionCallbackInfo<v8::Value>& args) { // formatting. However, they are invoked when performing normal error // string conversions. TEST(APIThrowMessageOverwrittenToString) { - v8::HandleScope scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); v8::V8::AddMessageListener(check_reference_error_message); - Local<ObjectTemplate> templ = ObjectTemplate::New(); - templ->Set(v8_str("fail"), v8::FunctionTemplate::New(Fail)); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); + templ->Set(v8_str("fail"), v8::FunctionTemplate::New(isolate, Fail)); LocalContext context(NULL, templ); CompileRun("asdf;"); CompileRun("var limit = {};" @@ -4716,11 +4940,12 @@ static void receive_message(v8::Handle<v8::Message> message, TEST(APIThrowMessage) { message_received = false; - v8::HandleScope scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); v8::V8::AddMessageListener(receive_message); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("ThrowFromC"), - v8::FunctionTemplate::New(ThrowFromC)); + v8::FunctionTemplate::New(isolate, ThrowFromC)); LocalContext context(0, templ); CompileRun("ThrowFromC();"); CHECK(message_received); @@ -4730,11 +4955,12 @@ TEST(APIThrowMessage) { TEST(APIThrowMessageAndVerboseTryCatch) { message_received = false; - v8::HandleScope scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); v8::V8::AddMessageListener(receive_message); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("ThrowFromC"), - v8::FunctionTemplate::New(ThrowFromC)); + v8::FunctionTemplate::New(isolate, ThrowFromC)); LocalContext context(0, templ); v8::TryCatch try_catch; try_catch.SetVerbose(true); @@ -4762,10 +4988,11 @@ TEST(APIStackOverflowAndVerboseTryCatch) { THREADED_TEST(ExternalScriptException) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("ThrowFromC"), - v8::FunctionTemplate::New(ThrowFromC)); + v8::FunctionTemplate::New(isolate, ThrowFromC)); LocalContext context(0, templ); v8::TryCatch try_catch; @@ -4867,11 +5094,12 @@ THREADED_TEST(EvalInTryFinally) { // JS stack. This test therefore fails on the simulator. The test is // not threaded to allow the threading tests to run on the simulator. TEST(ExceptionOrder) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); - templ->Set(v8_str("check"), v8::FunctionTemplate::New(JSCheck)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); + templ->Set(v8_str("check"), v8::FunctionTemplate::New(isolate, JSCheck)); templ->Set(v8_str("CThrowCountDown"), - v8::FunctionTemplate::New(CThrowCountDown)); + v8::FunctionTemplate::New(isolate, CThrowCountDown)); LocalContext context(0, templ); CompileRun( "function JSThrowCountDown(count, jsInterval, cInterval, expected) {" @@ -4931,9 +5159,10 @@ void ThrowValue(const v8::FunctionCallbackInfo<v8::Value>& args) { THREADED_TEST(ThrowValues) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); - templ->Set(v8_str("Throw"), v8::FunctionTemplate::New(ThrowValue)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); + templ->Set(v8_str("Throw"), v8::FunctionTemplate::New(isolate, ThrowValue)); LocalContext context(0, templ); v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( "function Run(obj) {" @@ -4946,13 +5175,13 @@ THREADED_TEST(ThrowValues) { "}" "[Run('str'), Run(1), Run(0), Run(null), Run(void 0)];")); CHECK_EQ(5, result->Length()); - CHECK(result->Get(v8::Integer::New(0))->IsString()); - CHECK(result->Get(v8::Integer::New(1))->IsNumber()); - CHECK_EQ(1, result->Get(v8::Integer::New(1))->Int32Value()); - CHECK(result->Get(v8::Integer::New(2))->IsNumber()); - CHECK_EQ(0, result->Get(v8::Integer::New(2))->Int32Value()); - CHECK(result->Get(v8::Integer::New(3))->IsNull()); - CHECK(result->Get(v8::Integer::New(4))->IsUndefined()); + CHECK(result->Get(v8::Integer::New(isolate, 0))->IsString()); + CHECK(result->Get(v8::Integer::New(isolate, 1))->IsNumber()); + CHECK_EQ(1, result->Get(v8::Integer::New(isolate, 1))->Int32Value()); + CHECK(result->Get(v8::Integer::New(isolate, 2))->IsNumber()); + CHECK_EQ(0, result->Get(v8::Integer::New(isolate, 2))->Int32Value()); + CHECK(result->Get(v8::Integer::New(isolate, 3))->IsNull()); + CHECK(result->Get(v8::Integer::New(isolate, 4))->IsUndefined()); } @@ -5000,10 +5229,11 @@ void WithTryCatch(const v8::FunctionCallbackInfo<v8::Value>& args) { THREADED_TEST(TryCatchAndFinally) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); context->Global()->Set( v8_str("native_with_try_catch"), - v8::FunctionTemplate::New(WithTryCatch)->GetFunction()); + v8::FunctionTemplate::New(isolate, WithTryCatch)->GetFunction()); v8::TryCatch try_catch; CHECK(!try_catch.HasCaught()); CompileRun( @@ -5069,12 +5299,13 @@ void TryCatchMixedNestingHelper( // This exercises the ability of TryCatch.ReThrow() to restore the // inner pending Message before throwing the exception again. TEST(TryCatchMixedNesting) { - v8::HandleScope scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); v8::V8::Initialize(); v8::TryCatch try_catch; - Local<ObjectTemplate> templ = ObjectTemplate::New(); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("TryCatchMixedNestingHelper"), - v8::FunctionTemplate::New(TryCatchMixedNestingHelper)); + v8::FunctionTemplate::New(isolate, TryCatchMixedNestingHelper)); LocalContext context(0, templ); CompileRunWithOrigin("TryCatchMixedNestingHelper();\n", "outer", 1, 1); TryCatchMixedNestingCheck(&try_catch); @@ -5107,10 +5338,10 @@ THREADED_TEST(Equality) { CHECK(v8::False(isolate)->StrictEquals(v8::False(isolate))); CHECK(!v8::False(isolate)->StrictEquals(v8::Undefined(isolate))); - v8::Handle<v8::Object> obj = v8::Object::New(); + v8::Handle<v8::Object> obj = v8::Object::New(isolate); v8::Persistent<v8::Object> alias(isolate, obj); CHECK(v8::Local<v8::Object>::New(isolate, alias)->StrictEquals(obj)); - alias.Dispose(); + alias.Reset(); CHECK(v8_str("a")->SameValue(v8_str("a"))); CHECK(!v8_str("a")->SameValue(v8_str("b"))); @@ -5144,8 +5375,9 @@ static void GetXValue(Local<String> name, THREADED_TEST(SimplePropertyRead) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); context->Global()->Set(v8_str("obj"), templ->NewInstance()); Local<Script> script = Script::Compile(v8_str("obj.x")); @@ -5158,8 +5390,9 @@ THREADED_TEST(SimplePropertyRead) { THREADED_TEST(DefinePropertyOnAPIAccessor) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); context->Global()->Set(v8_str("obj"), templ->NewInstance()); @@ -5205,8 +5438,9 @@ THREADED_TEST(DefinePropertyOnAPIAccessor) { THREADED_TEST(DefinePropertyOnDefineGetterSetter) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); LocalContext context; context->Global()->Set(v8_str("obj"), templ->NewInstance()); @@ -5257,8 +5491,9 @@ static v8::Handle<v8::Object> GetGlobalProperty(LocalContext* context, THREADED_TEST(DefineAPIAccessorOnObject) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); LocalContext context; context->Global()->Set(v8_str("obj1"), templ->NewInstance()); @@ -5331,8 +5566,9 @@ THREADED_TEST(DefineAPIAccessorOnObject) { THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); LocalContext context; context->Global()->Set(v8_str("obj1"), templ->NewInstance()); @@ -5387,8 +5623,9 @@ static void Get239Value(Local<String> name, THREADED_TEST(ElementAPIAccessor) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); LocalContext context; context->Global()->Set(v8_str("obj1"), templ->NewInstance()); @@ -5425,8 +5662,9 @@ static void SetXValue(Local<String> name, THREADED_TEST(SimplePropertyWrite) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), GetXValue, SetXValue, v8_str("donut")); LocalContext context; context->Global()->Set(v8_str("obj"), templ->NewInstance()); @@ -5435,15 +5673,15 @@ THREADED_TEST(SimplePropertyWrite) { CHECK(xValue.IsEmpty()); script->Run(); CHECK_EQ(v8_num(4), Local<Value>::New(CcTest::isolate(), xValue)); - xValue.Dispose(); - xValue.Clear(); + xValue.Reset(); } } THREADED_TEST(SetterOnly) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), NULL, SetXValue, v8_str("donut")); LocalContext context; context->Global()->Set(v8_str("obj"), templ->NewInstance()); @@ -5452,15 +5690,15 @@ THREADED_TEST(SetterOnly) { CHECK(xValue.IsEmpty()); script->Run(); CHECK_EQ(v8_num(4), Local<Value>::New(CcTest::isolate(), xValue)); - xValue.Dispose(); - xValue.Clear(); + xValue.Reset(); } } THREADED_TEST(NoAccessors) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), static_cast<v8::AccessorGetterCallback>(NULL), NULL, @@ -5483,8 +5721,9 @@ static void XPropertyGetter(Local<String> property, THREADED_TEST(NamedInterceptorPropertyRead) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(XPropertyGetter); LocalContext context; context->Global()->Set(v8_str("obj"), templ->NewInstance()); @@ -5497,8 +5736,9 @@ THREADED_TEST(NamedInterceptorPropertyRead) { THREADED_TEST(NamedInterceptorDictionaryIC) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(XPropertyGetter); LocalContext context; // Create an object with a named interceptor. @@ -5532,7 +5772,7 @@ THREADED_TEST(NamedInterceptorDictionaryICMultipleContext) { v8::Local<Context> context1 = Context::New(isolate); context1->Enter(); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(XPropertyGetter); // Create an object with a named interceptor. v8::Local<v8::Object> object = templ->NewInstance(); @@ -5572,15 +5812,18 @@ static void SetXOnPrototypeGetter( const v8::PropertyCallbackInfo<v8::Value>& info) { // Set x on the prototype object and do not handle the get request. v8::Handle<v8::Value> proto = info.Holder()->GetPrototype(); - proto.As<v8::Object>()->Set(v8_str("x"), v8::Integer::New(23)); + proto.As<v8::Object>()->Set(v8_str("x"), + v8::Integer::New(info.GetIsolate(), 23)); } // This is a regression test for http://crbug.com/20104. Map // transitions should not interfere with post interceptor lookup. THREADED_TEST(NamedInterceptorMapTransitionRead) { - v8::HandleScope scope(CcTest::isolate()); - Local<v8::FunctionTemplate> function_template = v8::FunctionTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<v8::FunctionTemplate> function_template = + v8::FunctionTemplate::New(isolate); Local<v8::ObjectTemplate> instance_template = function_template->InstanceTemplate(); instance_template->SetNamedPropertyHandler(SetXOnPrototypeGetter); @@ -5616,8 +5859,9 @@ static void IndexedPropertySetter( THREADED_TEST(IndexedInterceptorWithIndexedAccessor) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(IndexedPropertyGetter, IndexedPropertySetter); LocalContext context; @@ -5681,8 +5925,9 @@ void UnboxedDoubleIndexedPropertyEnumerator( // Make sure that the the interceptor code in the runtime properly handles // merging property name lists for double-array-backed arrays. THREADED_TEST(IndexedInterceptorUnboxedDoubleWithIndexedAccessor) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(UnboxedDoubleIndexedPropertyGetter, UnboxedDoubleIndexedPropertySetter, 0, @@ -5737,8 +5982,9 @@ static void NonStrictIndexedPropertyGetter( // Make sure that the the interceptor code in the runtime properly handles // merging property name lists for non-string arguments arrays. THREADED_TEST(IndexedInterceptorNonStrictArgsWithIndexedAccessor) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(NonStrictIndexedPropertyGetter, 0, 0, @@ -5763,8 +6009,9 @@ static void IdentityIndexedPropertyGetter( THREADED_TEST(IndexedInterceptorWithGetOwnPropertyDescriptor) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); LocalContext context; @@ -5784,8 +6031,9 @@ THREADED_TEST(IndexedInterceptorWithGetOwnPropertyDescriptor) { THREADED_TEST(IndexedInterceptorWithNoSetter) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); LocalContext context; @@ -5807,8 +6055,9 @@ THREADED_TEST(IndexedInterceptorWithNoSetter) { THREADED_TEST(IndexedInterceptorWithAccessorCheck) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); LocalContext context; @@ -5832,8 +6081,9 @@ THREADED_TEST(IndexedInterceptorWithAccessorCheck) { THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) { i::FLAG_allow_natives_syntax = true; - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); LocalContext context; @@ -5861,8 +6111,9 @@ THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) { THREADED_TEST(IndexedInterceptorWithDifferentIndices) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); LocalContext context; @@ -5884,8 +6135,9 @@ THREADED_TEST(IndexedInterceptorWithDifferentIndices) { THREADED_TEST(IndexedInterceptorWithNegativeIndices) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); LocalContext context; @@ -5923,8 +6175,9 @@ THREADED_TEST(IndexedInterceptorWithNegativeIndices) { THREADED_TEST(IndexedInterceptorWithNotSmiLookup) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); LocalContext context; @@ -5952,8 +6205,9 @@ THREADED_TEST(IndexedInterceptorWithNotSmiLookup) { THREADED_TEST(IndexedInterceptorGoingMegamorphic) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); LocalContext context; @@ -5982,8 +6236,9 @@ THREADED_TEST(IndexedInterceptorGoingMegamorphic) { THREADED_TEST(IndexedInterceptorReceiverTurningSmi) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); LocalContext context; @@ -6012,8 +6267,9 @@ THREADED_TEST(IndexedInterceptorReceiverTurningSmi) { THREADED_TEST(IndexedInterceptorOnProto) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter); LocalContext context; @@ -6036,9 +6292,11 @@ THREADED_TEST(IndexedInterceptorOnProto) { THREADED_TEST(MultiContexts) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<ObjectTemplate> templ = ObjectTemplate::New(); - templ->Set(v8_str("dummy"), v8::FunctionTemplate::New(DummyCallHandler)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); + templ->Set(v8_str("dummy"), v8::FunctionTemplate::New(isolate, + DummyCallHandler)); Local<String> password = v8_str("Password"); @@ -6125,7 +6383,8 @@ THREADED_TEST(UndetectableObject) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> desc = + v8::FunctionTemplate::New(env->GetIsolate()); desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable Local<v8::Object> obj = desc->GetFunction()->NewInstance(); @@ -6166,9 +6425,10 @@ THREADED_TEST(UndetectableObject) { THREADED_TEST(VoidLiteral) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable Local<v8::Object> obj = desc->GetFunction()->NewInstance(); @@ -6209,9 +6469,10 @@ THREADED_TEST(VoidLiteral) { THREADED_TEST(ExtensibleOnUndetectable) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable Local<v8::Object> obj = desc->GetFunction()->NewInstance(); @@ -6222,7 +6483,7 @@ THREADED_TEST(ExtensibleOnUndetectable) { Local<Script> script = Script::Compile(source); - CHECK_EQ(v8::Integer::New(42), script->Run()); + CHECK_EQ(v8::Integer::New(isolate, 42), script->Run()); ExpectBoolean("Object.isExtensible(undetectable)", true); @@ -6243,7 +6504,8 @@ THREADED_TEST(UndetectableString) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - Local<String> obj = String::NewUndetectable("foo"); + Local<String> obj = String::NewFromUtf8(env->GetIsolate(), "foo", + String::kUndetectableString); env->Global()->Set(v8_str("undetectable"), obj); ExpectString("undetectable", "foo"); @@ -6284,7 +6546,8 @@ TEST(UndetectableOptimized) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - Local<String> obj = String::NewUndetectable("foo"); + Local<String> obj = String::NewFromUtf8(env->GetIsolate(), "foo", + String::kUndetectableString); env->Global()->Set(v8_str("undetectable"), obj); env->Global()->Set(v8_str("detectable"), v8_str("bar")); @@ -6314,18 +6577,21 @@ TEST(UndetectableOptimized) { template <typename T> static void USE(T) { } -// This test is not intended to be run, just type checked. -static inline void PersistentHandles(v8::Isolate* isolate) { - USE(PersistentHandles); +// The point of this test is type checking. We run it only so compilers +// don't complain about an unused function. +TEST(PersistentHandles) { + LocalContext env; + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); Local<String> str = v8_str("foo"); v8::Persistent<String> p_str(isolate, str); - p_str.Dispose(); + p_str.Reset(); Local<Script> scr = Script::Compile(v8_str("")); v8::Persistent<Script> p_scr(isolate, scr); - p_scr.Dispose(); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + p_scr.Reset(); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); v8::Persistent<ObjectTemplate> p_templ(isolate, templ); - p_templ.Dispose(); + p_templ.Reset(); } @@ -6338,9 +6604,9 @@ static void HandleLogDelegator( THREADED_TEST(GlobalObjectTemplate) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - Local<ObjectTemplate> global_template = ObjectTemplate::New(); + Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate); global_template->Set(v8_str("JSNI_Log"), - v8::FunctionTemplate::New(HandleLogDelegator)); + v8::FunctionTemplate::New(isolate, HandleLogDelegator)); v8::Local<Context> context = Context::New(isolate, 0, global_template); Context::Scope context_scope(context); Script::Compile(v8_str("JSNI_Log('LOG')"))->Run(); @@ -6353,7 +6619,7 @@ static const char* kSimpleExtensionSource = "}"; -THREADED_TEST(SimpleExtensions) { +TEST(SimpleExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource)); const char* extension_names[] = { "simpletest" }; @@ -6362,11 +6628,11 @@ THREADED_TEST(SimpleExtensions) { Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("Foo()"))->Run(); - CHECK_EQ(result, v8::Integer::New(4)); + CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 4)); } -THREADED_TEST(NullExtensions) { +TEST(NullExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("nulltest", NULL)); const char* extension_names[] = { "nulltest" }; @@ -6375,7 +6641,7 @@ THREADED_TEST(NullExtensions) { Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("1+3"))->Run(); - CHECK_EQ(result, v8::Integer::New(4)); + CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 4)); } @@ -6385,7 +6651,7 @@ static const char* kEmbeddedExtensionSource = static const int kEmbeddedExtensionSourceValidLen = 34; -THREADED_TEST(ExtensionMissingSourceLength) { +TEST(ExtensionMissingSourceLength) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("srclentest_fail", kEmbeddedExtensionSource)); @@ -6397,7 +6663,7 @@ THREADED_TEST(ExtensionMissingSourceLength) { } -THREADED_TEST(ExtensionWithSourceLength) { +TEST(ExtensionWithSourceLength) { for (int source_len = kEmbeddedExtensionSourceValidLen - 1; source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) { v8::HandleScope handle_scope(CcTest::isolate()); @@ -6413,7 +6679,7 @@ THREADED_TEST(ExtensionWithSourceLength) { if (source_len == kEmbeddedExtensionSourceValidLen) { Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("Ret54321()"))->Run(); - CHECK_EQ(v8::Integer::New(54321), result); + CHECK_EQ(v8::Integer::New(CcTest::isolate(), 54321), result); } else { // Anything but exactly the right length should fail to compile. CHECK_EQ(0, *context); @@ -6439,7 +6705,7 @@ static const char* kEvalExtensionSource2 = "})()"; -THREADED_TEST(UseEvalFromExtension) { +TEST(UseEvalFromExtension) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("evaltest1", kEvalExtensionSource1)); v8::RegisterExtension(new Extension("evaltest2", kEvalExtensionSource2)); @@ -6449,9 +6715,9 @@ THREADED_TEST(UseEvalFromExtension) { Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("UseEval1()"))->Run(); - CHECK_EQ(result, v8::Integer::New(42)); + CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 42)); result = Script::Compile(v8_str("UseEval2()"))->Run(); - CHECK_EQ(result, v8::Integer::New(42)); + CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 42)); } @@ -6473,7 +6739,7 @@ static const char* kWithExtensionSource2 = "})()"; -THREADED_TEST(UseWithFromExtension) { +TEST(UseWithFromExtension) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("withtest1", kWithExtensionSource1)); v8::RegisterExtension(new Extension("withtest2", kWithExtensionSource2)); @@ -6483,13 +6749,13 @@ THREADED_TEST(UseWithFromExtension) { Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("UseWith1()"))->Run(); - CHECK_EQ(result, v8::Integer::New(87)); + CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 87)); result = Script::Compile(v8_str("UseWith2()"))->Run(); - CHECK_EQ(result, v8::Integer::New(87)); + CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 87)); } -THREADED_TEST(AutoExtensions) { +TEST(AutoExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); Extension* extension = new Extension("autotest", kSimpleExtensionSource); extension->set_auto_enable(true); @@ -6498,7 +6764,7 @@ THREADED_TEST(AutoExtensions) { Context::New(CcTest::isolate()); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("Foo()"))->Run(); - CHECK_EQ(result, v8::Integer::New(4)); + CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 4)); } @@ -6508,7 +6774,7 @@ static const char* kSyntaxErrorInExtensionSource = // Test that a syntax error in an extension does not cause a fatal // error but results in an empty context. -THREADED_TEST(SyntaxErrorExtensions) { +TEST(SyntaxErrorExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("syntaxerror", kSyntaxErrorInExtensionSource)); @@ -6526,7 +6792,7 @@ static const char* kExceptionInExtensionSource = // Test that an exception when installing an extension does not cause // a fatal error but results in an empty context. -THREADED_TEST(ExceptionExtensions) { +TEST(ExceptionExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("exception", kExceptionInExtensionSource)); @@ -6548,7 +6814,7 @@ static const char* kNativeCallTest = "call_runtime_last_index_of('bobbobboellebobboellebobbob');"; // Test that a native runtime calls are supported in extensions. -THREADED_TEST(NativeCallInExtensions) { +TEST(NativeCallInExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension(new Extension("nativecall", kNativeCallInExtensionSource)); @@ -6558,7 +6824,7 @@ THREADED_TEST(NativeCallInExtensions) { Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str(kNativeCallTest))->Run(); - CHECK_EQ(result, v8::Integer::New(3)); + CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 3)); } @@ -6570,9 +6836,10 @@ class NativeFunctionExtension : public Extension { : Extension(name, source), function_(fun) { } - virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( + v8::Isolate* isolate, v8::Handle<v8::String> name) { - return v8::FunctionTemplate::New(function_); + return v8::FunctionTemplate::New(isolate, function_); } static void Echo(const v8::FunctionCallbackInfo<v8::Value>& args) { @@ -6583,7 +6850,7 @@ class NativeFunctionExtension : public Extension { }; -THREADED_TEST(NativeFunctionDeclaration) { +TEST(NativeFunctionDeclaration) { v8::HandleScope handle_scope(CcTest::isolate()); const char* name = "nativedecl"; v8::RegisterExtension(new NativeFunctionExtension(name, @@ -6594,11 +6861,11 @@ THREADED_TEST(NativeFunctionDeclaration) { Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); v8::Handle<Value> result = Script::Compile(v8_str("foo(42);"))->Run(); - CHECK_EQ(result, v8::Integer::New(42)); + CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 42)); } -THREADED_TEST(NativeFunctionDeclarationError) { +TEST(NativeFunctionDeclarationError) { v8::HandleScope handle_scope(CcTest::isolate()); const char* name = "nativedeclerr"; // Syntax error in extension code. @@ -6612,7 +6879,7 @@ THREADED_TEST(NativeFunctionDeclarationError) { } -THREADED_TEST(NativeFunctionDeclarationErrorEscape) { +TEST(NativeFunctionDeclarationErrorEscape) { v8::HandleScope handle_scope(CcTest::isolate()); const char* name = "nativedeclerresc"; // Syntax error in extension code - escape code in "native" means that @@ -6632,7 +6899,8 @@ static void CheckDependencies(const char* name, const char* expected) { v8::HandleScope handle_scope(CcTest::isolate()); v8::ExtensionConfiguration config(1, &name); LocalContext context(&config); - CHECK_EQ(String::New(expected), context->Global()->Get(v8_str("loaded"))); + CHECK_EQ(String::NewFromUtf8(CcTest::isolate(), expected), + context->Global()->Get(v8_str("loaded"))); } @@ -6690,21 +6958,25 @@ static void CallFun(const v8::FunctionCallbackInfo<v8::Value>& args) { class FunctionExtension : public Extension { public: FunctionExtension() : Extension("functiontest", kExtensionTestScript) { } - virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( + v8::Isolate* isolate, v8::Handle<String> name); }; static int lookup_count = 0; -v8::Handle<v8::FunctionTemplate> FunctionExtension::GetNativeFunction( - v8::Handle<String> name) { +v8::Handle<v8::FunctionTemplate> FunctionExtension::GetNativeFunctionTemplate( + v8::Isolate* isolate, v8::Handle<String> name) { lookup_count++; if (name->Equals(v8_str("A"))) { - return v8::FunctionTemplate::New(CallFun, v8::Integer::New(8)); + return v8::FunctionTemplate::New( + isolate, CallFun, v8::Integer::New(isolate, 8)); } else if (name->Equals(v8_str("B"))) { - return v8::FunctionTemplate::New(CallFun, v8::Integer::New(7)); + return v8::FunctionTemplate::New( + isolate, CallFun, v8::Integer::New(isolate, 7)); } else if (name->Equals(v8_str("C"))) { - return v8::FunctionTemplate::New(CallFun, v8::Integer::New(6)); + return v8::FunctionTemplate::New( + isolate, CallFun, v8::Integer::New(isolate, 6)); } else { return v8::Handle<v8::FunctionTemplate>(); } @@ -6718,9 +6990,12 @@ THREADED_TEST(FunctionLookup) { v8::ExtensionConfiguration config(1, exts); LocalContext context(&config); CHECK_EQ(3, lookup_count); - CHECK_EQ(v8::Integer::New(8), Script::Compile(v8_str("Foo(0)"))->Run()); - CHECK_EQ(v8::Integer::New(7), Script::Compile(v8_str("Foo(1)"))->Run()); - CHECK_EQ(v8::Integer::New(6), Script::Compile(v8_str("Foo(2)"))->Run()); + CHECK_EQ(v8::Integer::New(CcTest::isolate(), 8), + Script::Compile(v8_str("Foo(0)"))->Run()); + CHECK_EQ(v8::Integer::New(CcTest::isolate(), 7), + Script::Compile(v8_str("Foo(1)"))->Run()); + CHECK_EQ(v8::Integer::New(CcTest::isolate(), 6), + Script::Compile(v8_str("Foo(2)"))->Run()); } @@ -6733,11 +7008,11 @@ THREADED_TEST(NativeFunctionConstructCall) { for (int i = 0; i < 10; i++) { // Run a few times to ensure that allocation of objects doesn't // change behavior of a constructor function. - CHECK_EQ(v8::Integer::New(8), + CHECK_EQ(v8::Integer::New(CcTest::isolate(), 8), Script::Compile(v8_str("(new A()).data"))->Run()); - CHECK_EQ(v8::Integer::New(7), + CHECK_EQ(v8::Integer::New(CcTest::isolate(), 7), Script::Compile(v8_str("(new B()).data"))->Run()); - CHECK_EQ(v8::Integer::New(6), + CHECK_EQ(v8::Integer::New(CcTest::isolate(), 6), Script::Compile(v8_str("(new C()).data"))->Run()); } } @@ -6771,33 +7046,6 @@ TEST(ErrorReporting) { } -static const char* js_code_causing_huge_string_flattening = - "var str = 'X';" - "for (var i = 0; i < 30; i++) {" - " str = str + str;" - "}" - "str.match(/X/);"; - - -void OOMCallback(const char* location, const char* message) { - exit(0); -} - - -TEST(RegexpOutOfMemory) { - // Execute a script that causes out of memory when flattening a string. - v8::HandleScope scope(CcTest::isolate()); - v8::V8::SetFatalErrorHandler(OOMCallback); - LocalContext context; - Local<Script> script = - Script::Compile(String::New(js_code_causing_huge_string_flattening)); - last_location = NULL; - script->Run(); - - CHECK(false); // Should not return. -} - - static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message, v8::Handle<Value> data) { CHECK(message->GetScriptResourceName()->IsUndefined()); @@ -6816,93 +7064,16 @@ THREADED_TEST(ErrorWithMissingScriptInfo) { } -int global_index = 0; - -class Snorkel { - public: - Snorkel() { index_ = global_index++; } - int index_; +struct FlagAndPersistent { + bool flag; + v8::Persistent<v8::Object> handle; }; -class Whammy { - public: - explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { } - ~Whammy() { script_.Dispose(); } - v8::Handle<Script> getScript() { - if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo")); - return Local<Script>::New(isolate_, script_); - } - public: - static const int kObjectCount = 256; - int cursor_; - v8::Isolate* isolate_; - v8::Persistent<v8::Object> objects_[kObjectCount]; - v8::Persistent<Script> script_; -}; - -static void HandleWeakReference(v8::Isolate* isolate, - v8::Persistent<v8::Value>* obj, - Snorkel* snorkel) { - delete snorkel; - obj->ClearWeak(); -} - -void WhammyPropertyGetter(Local<String> name, - const v8::PropertyCallbackInfo<v8::Value>& info) { - Whammy* whammy = - static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); - - v8::Persistent<v8::Object>& prev = whammy->objects_[whammy->cursor_]; - - v8::Handle<v8::Object> obj = v8::Object::New(); - if (!prev.IsEmpty()) { - v8::Local<v8::Object>::New(info.GetIsolate(), prev) - ->Set(v8_str("next"), obj); - prev.MakeWeak<Value, Snorkel>(new Snorkel(), &HandleWeakReference); - whammy->objects_[whammy->cursor_].Clear(); - } - whammy->objects_[whammy->cursor_].Reset(info.GetIsolate(), obj); - whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount; - info.GetReturnValue().Set(whammy->getScript()->Run()); -} - - -THREADED_TEST(WeakReference) { - v8::HandleScope handle_scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New(); - Whammy* whammy = new Whammy(CcTest::isolate()); - templ->SetNamedPropertyHandler(WhammyPropertyGetter, - 0, 0, 0, 0, - v8::External::New(whammy)); - const char* extension_list[] = { "v8/gc" }; - v8::ExtensionConfiguration extensions(1, extension_list); - v8::Handle<Context> context = - Context::New(CcTest::isolate(), &extensions); - Context::Scope context_scope(context); - - v8::Handle<v8::Object> interceptor = templ->NewInstance(); - context->Global()->Set(v8_str("whammy"), interceptor); - const char* code = - "var last;" - "for (var i = 0; i < 10000; i++) {" - " var obj = whammy.length;" - " if (last) last.next = obj;" - " last = obj;" - "}" - "gc();" - "4"; - v8::Handle<Value> result = CompileRun(code); - CHECK_EQ(4.0, result->NumberValue()); - delete whammy; -} - - -static void DisposeAndSetFlag(v8::Isolate* isolate, - v8::Persistent<v8::Object>* obj, - bool* data) { - obj->Dispose(); - *(data) = true; +static void DisposeAndSetFlag( + const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { + data.GetParameter()->handle.Reset(); + data.GetParameter()->flag = true; } @@ -6912,30 +7083,30 @@ THREADED_TEST(IndependentWeakHandle) { v8::Handle<Context> context = Context::New(iso); Context::Scope context_scope(context); - v8::Persistent<v8::Object> object_a, object_b; + FlagAndPersistent object_a, object_b; { v8::HandleScope handle_scope(iso); - object_a.Reset(iso, v8::Object::New()); - object_b.Reset(iso, v8::Object::New()); - } - - bool object_a_disposed = false; - bool object_b_disposed = false; - object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag); - object_b.MakeWeak(&object_b_disposed, &DisposeAndSetFlag); - CHECK(!object_b.IsIndependent()); - object_a.MarkIndependent(); - object_b.MarkIndependent(); - CHECK(object_b.IsIndependent()); - CcTest::heap()->PerformScavenge(); - CHECK(object_a_disposed); - CHECK(object_b_disposed); + object_a.handle.Reset(iso, v8::Object::New(iso)); + object_b.handle.Reset(iso, v8::Object::New(iso)); + } + + object_a.flag = false; + object_b.flag = false; + object_a.handle.SetWeak(&object_a, &DisposeAndSetFlag); + object_b.handle.SetWeak(&object_b, &DisposeAndSetFlag); + CHECK(!object_b.handle.IsIndependent()); + object_a.handle.MarkIndependent(); + object_b.handle.MarkIndependent(); + CHECK(object_b.handle.IsIndependent()); + CcTest::heap()->CollectGarbage(i::NEW_SPACE); + CHECK(object_a.flag); + CHECK(object_b.flag); } static void InvokeScavenge() { - CcTest::heap()->PerformScavenge(); + CcTest::heap()->CollectGarbage(i::NEW_SPACE); } @@ -6944,20 +7115,18 @@ static void InvokeMarkSweep() { } -static void ForceScavenge(v8::Isolate* isolate, - v8::Persistent<v8::Object>* obj, - bool* data) { - obj->Dispose(); - *(data) = true; +static void ForceScavenge( + const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { + data.GetParameter()->handle.Reset(); + data.GetParameter()->flag = true; InvokeScavenge(); } -static void ForceMarkSweep(v8::Isolate* isolate, - v8::Persistent<v8::Object>* obj, - bool* data) { - obj->Dispose(); - *(data) = true; +static void ForceMarkSweep( + const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { + data.GetParameter()->handle.Reset(); + data.GetParameter()->flag = true; InvokeMarkSweep(); } @@ -6969,7 +7138,8 @@ THREADED_TEST(GCFromWeakCallbacks) { Context::Scope context_scope(context); static const int kNumberOfGCTypes = 2; - typedef v8::WeakReferenceCallbacks<v8::Object, bool>::Revivable Callback; + typedef v8::WeakCallbackData<v8::Object, FlagAndPersistent>::Callback + Callback; Callback gc_forcing_callback[kNumberOfGCTypes] = {&ForceScavenge, &ForceMarkSweep}; @@ -6978,26 +7148,25 @@ THREADED_TEST(GCFromWeakCallbacks) { for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) { for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) { - v8::Persistent<v8::Object> object; + FlagAndPersistent object; { v8::HandleScope handle_scope(isolate); - object.Reset(isolate, v8::Object::New()); + object.handle.Reset(isolate, v8::Object::New(isolate)); } - bool disposed = false; - object.MakeWeak(&disposed, gc_forcing_callback[inner_gc]); - object.MarkIndependent(); + object.flag = false; + object.handle.SetWeak(&object, gc_forcing_callback[inner_gc]); + object.handle.MarkIndependent(); invoke_gc[outer_gc](); - CHECK(disposed); + CHECK(object.flag); } } } -static void RevivingCallback(v8::Isolate* isolate, - v8::Persistent<v8::Object>* obj, - bool* data) { - obj->ClearWeak(); - *(data) = true; +static void RevivingCallback( + const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { + data.GetParameter()->handle.ClearWeak(); + data.GetParameter()->flag = true; } @@ -7007,26 +7176,27 @@ THREADED_TEST(IndependentHandleRevival) { v8::Handle<Context> context = Context::New(isolate); Context::Scope context_scope(context); - v8::Persistent<v8::Object> object; + FlagAndPersistent object; { v8::HandleScope handle_scope(isolate); - v8::Local<v8::Object> o = v8::Object::New(); - object.Reset(isolate, o); - o->Set(v8_str("x"), v8::Integer::New(1)); + v8::Local<v8::Object> o = v8::Object::New(isolate); + object.handle.Reset(isolate, o); + o->Set(v8_str("x"), v8::Integer::New(isolate, 1)); v8::Local<String> y_str = v8_str("y"); o->Set(y_str, y_str); } - bool revived = false; - object.MakeWeak(&revived, &RevivingCallback); - object.MarkIndependent(); - CcTest::heap()->PerformScavenge(); - CHECK(revived); + object.flag = false; + object.handle.SetWeak(&object, &RevivingCallback); + object.handle.MarkIndependent(); + CcTest::heap()->CollectGarbage(i::NEW_SPACE); + CHECK(object.flag); CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); { v8::HandleScope handle_scope(isolate); - v8::Local<v8::Object> o = v8::Local<v8::Object>::New(isolate, object); + v8::Local<v8::Object> o = + v8::Local<v8::Object>::New(isolate, object.handle); v8::Local<String> y_str = v8_str("y"); - CHECK_EQ(v8::Integer::New(1), o->Get(v8_str("x"))); + CHECK_EQ(v8::Integer::New(isolate, 1), o->Get(v8_str("x"))); CHECK(o->Get(y_str)->Equals(y_str)); } } @@ -7041,9 +7211,9 @@ static void ArgumentsTestCallback( v8::Isolate* isolate = args.GetIsolate(); CHECK_EQ(args_fun, args.Callee()); CHECK_EQ(3, args.Length()); - CHECK_EQ(v8::Integer::New(1, isolate), args[0]); - CHECK_EQ(v8::Integer::New(2, isolate), args[1]); - CHECK_EQ(v8::Integer::New(3, isolate), args[2]); + CHECK_EQ(v8::Integer::New(isolate, 1), args[0]); + CHECK_EQ(v8::Integer::New(isolate, 2), args[1]); + CHECK_EQ(v8::Integer::New(isolate, 3), args[2]); CHECK_EQ(v8::Undefined(isolate), args[3]); v8::HandleScope scope(args.GetIsolate()); CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); @@ -7051,9 +7221,11 @@ static void ArgumentsTestCallback( THREADED_TEST(Arguments) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); - global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(isolate); + global->Set(v8_str("f"), + v8::FunctionTemplate::New(isolate, ArgumentsTestCallback)); LocalContext context(NULL, global); args_fun = context->Global()->Get(v8_str("f")).As<Function>(); v8_compile("f(1, 2, 3)")->Run(); @@ -7091,8 +7263,9 @@ static void IDeleter(uint32_t index, THREADED_TEST(Deleter) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetNamedPropertyHandler(NoBlockGetterX, NULL, NULL, PDeleter, NULL); obj->SetIndexedPropertyHandler(NoBlockGetterI, NULL, NULL, IDeleter, NULL); LocalContext context; @@ -7136,26 +7309,27 @@ static void IndexedGetK(uint32_t index, static void NamedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { ApiTestFuzzer::Fuzz(); - v8::Handle<v8::Array> result = v8::Array::New(3); - result->Set(v8::Integer::New(0), v8_str("foo")); - result->Set(v8::Integer::New(1), v8_str("bar")); - result->Set(v8::Integer::New(2), v8_str("baz")); + v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 3); + result->Set(v8::Integer::New(info.GetIsolate(), 0), v8_str("foo")); + result->Set(v8::Integer::New(info.GetIsolate(), 1), v8_str("bar")); + result->Set(v8::Integer::New(info.GetIsolate(), 2), v8_str("baz")); info.GetReturnValue().Set(result); } static void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { ApiTestFuzzer::Fuzz(); - v8::Handle<v8::Array> result = v8::Array::New(2); - result->Set(v8::Integer::New(0), v8_str("0")); - result->Set(v8::Integer::New(1), v8_str("1")); + v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2); + result->Set(v8::Integer::New(info.GetIsolate(), 0), v8_str("0")); + result->Set(v8::Integer::New(info.GetIsolate(), 1), v8_str("1")); info.GetReturnValue().Set(result); } THREADED_TEST(Enumerators) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetNamedPropertyHandler(GetK, NULL, NULL, NULL, NamedEnum); obj->SetIndexedPropertyHandler(IndexedGetK, NULL, NULL, NULL, IndexedEnum); LocalContext context; @@ -7186,27 +7360,27 @@ THREADED_TEST(Enumerators) { // documenting our behavior. CHECK_EQ(17, result->Length()); // Indexed properties in numerical order. - CHECK_EQ(v8_str("5"), result->Get(v8::Integer::New(0))); - CHECK_EQ(v8_str("10"), result->Get(v8::Integer::New(1))); - CHECK_EQ(v8_str("140000"), result->Get(v8::Integer::New(2))); - CHECK_EQ(v8_str("4294967295"), result->Get(v8::Integer::New(3))); + CHECK_EQ(v8_str("5"), result->Get(v8::Integer::New(isolate, 0))); + CHECK_EQ(v8_str("10"), result->Get(v8::Integer::New(isolate, 1))); + CHECK_EQ(v8_str("140000"), result->Get(v8::Integer::New(isolate, 2))); + CHECK_EQ(v8_str("4294967295"), result->Get(v8::Integer::New(isolate, 3))); // Indexed interceptor properties in the order they are returned // from the enumerator interceptor. - CHECK_EQ(v8_str("0"), result->Get(v8::Integer::New(4))); - CHECK_EQ(v8_str("1"), result->Get(v8::Integer::New(5))); + CHECK_EQ(v8_str("0"), result->Get(v8::Integer::New(isolate, 4))); + CHECK_EQ(v8_str("1"), result->Get(v8::Integer::New(isolate, 5))); // Named properties in insertion order. - CHECK_EQ(v8_str("a"), result->Get(v8::Integer::New(6))); - CHECK_EQ(v8_str("b"), result->Get(v8::Integer::New(7))); - CHECK_EQ(v8_str("c"), result->Get(v8::Integer::New(8))); - CHECK_EQ(v8_str("4294967296"), result->Get(v8::Integer::New(9))); - CHECK_EQ(v8_str("d"), result->Get(v8::Integer::New(10))); - CHECK_EQ(v8_str("e"), result->Get(v8::Integer::New(11))); - CHECK_EQ(v8_str("30000000000"), result->Get(v8::Integer::New(12))); - CHECK_EQ(v8_str("f"), result->Get(v8::Integer::New(13))); + CHECK_EQ(v8_str("a"), result->Get(v8::Integer::New(isolate, 6))); + CHECK_EQ(v8_str("b"), result->Get(v8::Integer::New(isolate, 7))); + CHECK_EQ(v8_str("c"), result->Get(v8::Integer::New(isolate, 8))); + CHECK_EQ(v8_str("4294967296"), result->Get(v8::Integer::New(isolate, 9))); + CHECK_EQ(v8_str("d"), result->Get(v8::Integer::New(isolate, 10))); + CHECK_EQ(v8_str("e"), result->Get(v8::Integer::New(isolate, 11))); + CHECK_EQ(v8_str("30000000000"), result->Get(v8::Integer::New(isolate, 12))); + CHECK_EQ(v8_str("f"), result->Get(v8::Integer::New(isolate, 13))); // Named interceptor properties. - CHECK_EQ(v8_str("foo"), result->Get(v8::Integer::New(14))); - CHECK_EQ(v8_str("bar"), result->Get(v8::Integer::New(15))); - CHECK_EQ(v8_str("baz"), result->Get(v8::Integer::New(16))); + CHECK_EQ(v8_str("foo"), result->Get(v8::Integer::New(isolate, 14))); + CHECK_EQ(v8_str("bar"), result->Get(v8::Integer::New(isolate, 15))); + CHECK_EQ(v8_str("baz"), result->Get(v8::Integer::New(isolate, 16))); } @@ -7269,8 +7443,9 @@ static void PGetter2(Local<String> name, THREADED_TEST(GetterHolders) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("p1"), PGetter); obj->SetAccessor(v8_str("p2"), PGetter); obj->SetAccessor(v8_str("p3"), PGetter); @@ -7282,8 +7457,9 @@ THREADED_TEST(GetterHolders) { THREADED_TEST(PreInterceptorHolders) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetNamedPropertyHandler(PGetter2); p_getter_count2 = 0; RunHolderTest(obj); @@ -7294,7 +7470,7 @@ THREADED_TEST(PreInterceptorHolders) { THREADED_TEST(ObjectInstantiation) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("t"), PGetter2); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -7349,7 +7525,24 @@ THREADED_TEST(StringWrite) { v8::Handle<String> str = v8_str("abcde"); // abc<Icelandic eth><Unicode snowman>. v8::Handle<String> str2 = v8_str("abc\303\260\342\230\203"); - v8::Handle<String> str3 = v8::String::New("abc\0def", 7); + v8::Handle<String> str3 = v8::String::NewFromUtf8( + context->GetIsolate(), "abc\0def", v8::String::kNormalString, 7); + // "ab" + lead surrogate + "cd" + trail surrogate + "ef" + uint16_t orphans[8] = { 0x61, 0x62, 0xd800, 0x63, 0x64, 0xdc00, 0x65, 0x66 }; + v8::Handle<String> orphans_str = v8::String::NewFromTwoByte( + context->GetIsolate(), orphans, v8::String::kNormalString, 8); + // single lead surrogate + uint16_t lead[1] = { 0xd800 }; + v8::Handle<String> lead_str = v8::String::NewFromTwoByte( + context->GetIsolate(), lead, v8::String::kNormalString, 1); + // single trail surrogate + uint16_t trail[1] = { 0xdc00 }; + v8::Handle<String> trail_str = v8::String::NewFromTwoByte( + context->GetIsolate(), trail, v8::String::kNormalString, 1); + // surrogate pair + uint16_t pair[2] = { 0xd800, 0xdc00 }; + v8::Handle<String> pair_str = v8::String::NewFromTwoByte( + context->GetIsolate(), pair, v8::String::kNormalString, 2); const int kStride = 4; // Must match stride in for loops in JS below. CompileRun( "var left = '';" @@ -7423,6 +7616,53 @@ THREADED_TEST(StringWrite) { CHECK_EQ(2, charlen); CHECK_EQ(0, strncmp(utf8buf, "ab\1", 3)); + // allow orphan surrogates by default + memset(utf8buf, 0x1, 1000); + len = orphans_str->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen); + CHECK_EQ(13, len); + CHECK_EQ(8, charlen); + CHECK_EQ(0, strcmp(utf8buf, "ab\355\240\200cd\355\260\200ef")); + + // replace orphan surrogates with unicode replacement character + memset(utf8buf, 0x1, 1000); + len = orphans_str->WriteUtf8(utf8buf, + sizeof(utf8buf), + &charlen, + String::REPLACE_INVALID_UTF8); + CHECK_EQ(13, len); + CHECK_EQ(8, charlen); + CHECK_EQ(0, strcmp(utf8buf, "ab\357\277\275cd\357\277\275ef")); + + // replace single lead surrogate with unicode replacement character + memset(utf8buf, 0x1, 1000); + len = lead_str->WriteUtf8(utf8buf, + sizeof(utf8buf), + &charlen, + String::REPLACE_INVALID_UTF8); + CHECK_EQ(4, len); + CHECK_EQ(1, charlen); + CHECK_EQ(0, strcmp(utf8buf, "\357\277\275")); + + // replace single trail surrogate with unicode replacement character + memset(utf8buf, 0x1, 1000); + len = trail_str->WriteUtf8(utf8buf, + sizeof(utf8buf), + &charlen, + String::REPLACE_INVALID_UTF8); + CHECK_EQ(4, len); + CHECK_EQ(1, charlen); + CHECK_EQ(0, strcmp(utf8buf, "\357\277\275")); + + // do not replace / write anything if surrogate pair does not fit the buffer + // space + memset(utf8buf, 0x1, 1000); + len = pair_str->WriteUtf8(utf8buf, + 3, + &charlen, + String::REPLACE_INVALID_UTF8); + CHECK_EQ(0, len); + CHECK_EQ(0, charlen); + memset(utf8buf, 0x1, sizeof(utf8buf)); len = GetUtf8Length(left_tree); int utf8_expected = @@ -7743,10 +7983,12 @@ static bool SameSymbol(Handle<String> s1, Handle<String> s2) { return *is1 == *is2; } - -static void SameSymbolHelper(const char* a, const char* b) { - Handle<String> symbol1 = v8::String::NewSymbol(a); - Handle<String> symbol2 = v8::String::NewSymbol(b); +static void SameSymbolHelper(v8::Isolate* isolate, const char* a, + const char* b) { + Handle<String> symbol1 = + v8::String::NewFromUtf8(isolate, a, v8::String::kInternalizedString); + Handle<String> symbol2 = + v8::String::NewFromUtf8(isolate, b, v8::String::kInternalizedString); CHECK(SameSymbol(symbol1, symbol2)); } @@ -7755,17 +7997,23 @@ THREADED_TEST(Utf16Symbol) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - Handle<String> symbol1 = v8::String::NewSymbol("abc"); - Handle<String> symbol2 = v8::String::NewSymbol("abc"); + Handle<String> symbol1 = v8::String::NewFromUtf8( + context->GetIsolate(), "abc", v8::String::kInternalizedString); + Handle<String> symbol2 = v8::String::NewFromUtf8( + context->GetIsolate(), "abc", v8::String::kInternalizedString); CHECK(SameSymbol(symbol1, symbol2)); - SameSymbolHelper("\360\220\220\205", // 4 byte encoding. + SameSymbolHelper(context->GetIsolate(), + "\360\220\220\205", // 4 byte encoding. "\355\240\201\355\260\205"); // 2 3-byte surrogates. - SameSymbolHelper("\355\240\201\355\260\206", // 2 3-byte surrogates. + SameSymbolHelper(context->GetIsolate(), + "\355\240\201\355\260\206", // 2 3-byte surrogates. "\360\220\220\206"); // 4 byte encoding. - SameSymbolHelper("x\360\220\220\205", // 4 byte encoding. + SameSymbolHelper(context->GetIsolate(), + "x\360\220\220\205", // 4 byte encoding. "x\355\240\201\355\260\205"); // 2 3-byte surrogates. - SameSymbolHelper("x\355\240\201\355\260\206", // 2 3-byte surrogates. + SameSymbolHelper(context->GetIsolate(), + "x\355\240\201\355\260\206", // 2 3-byte surrogates. "x\360\220\220\206"); // 4 byte encoding. CompileRun( "var sym0 = 'benedictus';" @@ -7782,12 +8030,22 @@ THREADED_TEST(Utf16Symbol) { "if (sym3.charCodeAt(2) != 0xdc07) throw sym1.charCodeAt(2);" "if (sym4.length != 3) throw sym4;" "if (sym4.charCodeAt(2) != 0xdc08) throw sym2.charCodeAt(2);"); - Handle<String> sym0 = v8::String::NewSymbol("benedictus"); - Handle<String> sym0b = v8::String::NewSymbol("S\303\270ren"); - Handle<String> sym1 = v8::String::NewSymbol("\355\240\201\355\260\207"); - Handle<String> sym2 = v8::String::NewSymbol("\360\220\220\210"); - Handle<String> sym3 = v8::String::NewSymbol("x\355\240\201\355\260\207"); - Handle<String> sym4 = v8::String::NewSymbol("x\360\220\220\210"); + Handle<String> sym0 = v8::String::NewFromUtf8( + context->GetIsolate(), "benedictus", v8::String::kInternalizedString); + Handle<String> sym0b = v8::String::NewFromUtf8( + context->GetIsolate(), "S\303\270ren", v8::String::kInternalizedString); + Handle<String> sym1 = + v8::String::NewFromUtf8(context->GetIsolate(), "\355\240\201\355\260\207", + v8::String::kInternalizedString); + Handle<String> sym2 = + v8::String::NewFromUtf8(context->GetIsolate(), "\360\220\220\210", + v8::String::kInternalizedString); + Handle<String> sym3 = v8::String::NewFromUtf8( + context->GetIsolate(), "x\355\240\201\355\260\207", + v8::String::kInternalizedString); + Handle<String> sym4 = + v8::String::NewFromUtf8(context->GetIsolate(), "x\360\220\220\210", + v8::String::kInternalizedString); v8::Local<v8::Object> global = context->Global(); Local<Value> s0 = global->Get(v8_str("sym0")); Local<Value> s0b = global->Get(v8_str("sym0b")); @@ -7806,7 +8064,8 @@ THREADED_TEST(Utf16Symbol) { THREADED_TEST(ToArrayIndex) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); v8::Handle<String> str = v8_str("42"); v8::Handle<v8::Uint32> index = str->ToArrayIndex(); @@ -7822,14 +8081,14 @@ THREADED_TEST(ToArrayIndex) { index = str->ToArrayIndex(); CHECK(!index.IsEmpty()); CHECK_EQ(4294967295.0, index->Uint32Value()); - v8::Handle<v8::Number> num = v8::Number::New(1); + v8::Handle<v8::Number> num = v8::Number::New(isolate, 1); index = num->ToArrayIndex(); CHECK(!index.IsEmpty()); CHECK_EQ(1.0, index->Uint32Value()); - num = v8::Number::New(-1); + num = v8::Number::New(isolate, -1); index = num->ToArrayIndex(); CHECK(index.IsEmpty()); - v8::Handle<v8::Object> obj = v8::Object::New(); + v8::Handle<v8::Object> obj = v8::Object::New(isolate); index = obj->ToArrayIndex(); CHECK(index.IsEmpty()); } @@ -7877,8 +8136,9 @@ static void YSetter(Local<String> name, THREADED_TEST(DeleteAccessor) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("y"), YGetter, YSetter); LocalContext context; v8::Handle<v8::Object> holder = obj->NewInstance(); @@ -7890,14 +8150,15 @@ THREADED_TEST(DeleteAccessor) { THREADED_TEST(TypeSwitch) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> templ1 = v8::FunctionTemplate::New(); - v8::Handle<v8::FunctionTemplate> templ2 = v8::FunctionTemplate::New(); - v8::Handle<v8::FunctionTemplate> templ3 = v8::FunctionTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> templ1 = v8::FunctionTemplate::New(isolate); + v8::Handle<v8::FunctionTemplate> templ2 = v8::FunctionTemplate::New(isolate); + v8::Handle<v8::FunctionTemplate> templ3 = v8::FunctionTemplate::New(isolate); v8::Handle<v8::FunctionTemplate> templs[3] = { templ1, templ2, templ3 }; v8::Handle<v8::TypeSwitch> type_switch = v8::TypeSwitch::New(3, templs); LocalContext context; - v8::Handle<v8::Object> obj0 = v8::Object::New(); + v8::Handle<v8::Object> obj0 = v8::Object::New(isolate); v8::Handle<v8::Object> obj1 = templ1->GetFunction()->NewInstance(); v8::Handle<v8::Object> obj2 = templ2->GetFunction()->NewInstance(); v8::Handle<v8::Object> obj3 = templ3->GetFunction()->NewInstance(); @@ -7971,10 +8232,12 @@ static void ApiUncaughtExceptionTestListener(v8::Handle<v8::Message>, TEST(ApiUncaughtException) { report_count = 0; LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); v8::V8::AddMessageListener(ApiUncaughtExceptionTestListener); - Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(TroubleCallback); + Local<v8::FunctionTemplate> fun = + v8::FunctionTemplate::New(isolate, TroubleCallback); v8::Local<v8::Object> global = env->Global(); global->Set(v8_str("trouble"), fun->GetFunction()); @@ -8011,17 +8274,22 @@ static void ExceptionInNativeScriptTestListener(v8::Handle<v8::Message> message, TEST(ExceptionInNativeScript) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); v8::V8::AddMessageListener(ExceptionInNativeScriptTestListener); - Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(TroubleCallback); + Local<v8::FunctionTemplate> fun = + v8::FunctionTemplate::New(isolate, TroubleCallback); v8::Local<v8::Object> global = env->Global(); global->Set(v8_str("trouble"), fun->GetFunction()); - Script::Compile(v8_str("function trouble() {\n" - " var o = {};\n" - " new o.foo();\n" - "};"), v8::String::New(script_resource_name))->Run(); + Script::Compile( + v8_str( + "function trouble() {\n" + " var o = {};\n" + " new o.foo();\n" + "};"), + v8::String::NewFromUtf8(isolate, script_resource_name))->Run(); Local<Value> trouble = global->Get(v8_str("trouble")); CHECK(trouble->IsFunction()); Function::Cast(*trouble)->Call(global, 0, NULL); @@ -8061,13 +8329,14 @@ TEST(TryCatchFinallyUsingTryCatchHandler) { // SecurityHandler can't be run twice TEST(SecurityHandler) { - v8::HandleScope scope0(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope0(isolate); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallbacks(NamedSecurityTestCallback, IndexedSecurityTestCallback); // Create an environment - v8::Handle<Context> context0 = - Context::New(CcTest::isolate(), NULL, global_template); + v8::Handle<Context> context0 = Context::New(isolate, NULL, global_template); context0->Enter(); v8::Handle<v8::Object> global0 = context0->Global(); @@ -8080,10 +8349,10 @@ TEST(SecurityHandler) { CHECK_EQ(999, z0->Int32Value()); // Create another environment, should fail security checks. - v8::HandleScope scope1(CcTest::isolate()); + v8::HandleScope scope1(isolate); v8::Handle<Context> context1 = - Context::New(CcTest::isolate(), NULL, global_template); + Context::New(isolate, NULL, global_template); context1->Enter(); v8::Handle<v8::Object> global1 = context1->Global(); @@ -8101,7 +8370,7 @@ TEST(SecurityHandler) { // Create another environment, should pass security checks. { g_security_callback_result = true; // allow security handler to pass. - v8::HandleScope scope2(CcTest::isolate()); + v8::HandleScope scope2(isolate); LocalContext context2; v8::Handle<v8::Object> global2 = context2->Global(); global2->Set(v8_str("othercontext"), global0); @@ -8343,7 +8612,7 @@ TEST(ContextDetachGlobal) { // Create a function in env2 and add a reference to it in env1. Local<v8::Object> global2 = env2->Global(); - global2->Set(v8_str("prop"), v8::Integer::New(1)); + global2->Set(v8_str("prop"), v8::Integer::New(env2->GetIsolate(), 1)); CompileRun("function getProp() {return prop;}"); env1->Global()->Set(v8_str("getProp"), @@ -8352,8 +8621,6 @@ TEST(ContextDetachGlobal) { // Detach env2's global, and reuse the global object of env2 env2->Exit(); env2->DetachGlobal(); - // env2 has a new global object. - CHECK(!env2->Global()->Equals(global2)); v8::Handle<Context> env3 = Context::New(env1->GetIsolate(), 0, @@ -8366,8 +8633,8 @@ TEST(ContextDetachGlobal) { CHECK_EQ(global2, global3); CHECK(global3->Get(v8_str("prop"))->IsUndefined()); CHECK(global3->Get(v8_str("getProp"))->IsUndefined()); - global3->Set(v8_str("prop"), v8::Integer::New(-1)); - global3->Set(v8_str("prop2"), v8::Integer::New(2)); + global3->Set(v8_str("prop"), v8::Integer::New(env3->GetIsolate(), -1)); + global3->Set(v8_str("prop2"), v8::Integer::New(env3->GetIsolate(), 2)); env3->Exit(); // Call getProp in env1, and it should return the value 1 @@ -8388,7 +8655,7 @@ TEST(ContextDetachGlobal) { } -TEST(DetachAndReattachGlobal) { +TEST(DetachGlobal) { LocalContext env1; v8::HandleScope scope(env1->GetIsolate()); @@ -8404,7 +8671,7 @@ TEST(DetachAndReattachGlobal) { // Create a property on the global object in env2. { v8::Context::Scope scope(env2); - env2->Global()->Set(v8_str("p"), v8::Integer::New(42)); + env2->Global()->Set(v8_str("p"), v8::Integer::New(env2->GetIsolate(), 42)); } // Create a reference to env2 global from env1 global. @@ -8437,7 +8704,7 @@ TEST(DetachAndReattachGlobal) { // Create a property on the global object in env3. { v8::Context::Scope scope(env3); - env3->Global()->Set(v8_str("p"), v8::Integer::New(24)); + env3->Global()->Set(v8_str("p"), v8::Integer::New(env3->GetIsolate(), 24)); } // Check that other.p is now the property in env3 and that we have access. @@ -8453,16 +8720,128 @@ TEST(DetachAndReattachGlobal) { // so access should be blocked. result = CompileRun("other.p"); CHECK(result->IsUndefined()); +} - // Detach the global for env3 and reattach it to env2. - env3->DetachGlobal(); - env2->ReattachGlobal(global2); - // Check that we have access to other.p again in env1. |other| is now - // the global object for env2 which has the same security token as env1. - result = CompileRun("other.p"); - CHECK(result->IsInt32()); - CHECK_EQ(42, result->Int32Value()); +void GetThisX(const v8::FunctionCallbackInfo<v8::Value>& info) { + info.GetReturnValue().Set( + info.GetIsolate()->GetCurrentContext()->Global()->Get(v8_str("x"))); +} + + +TEST(DetachedAccesses) { + LocalContext env1; + v8::HandleScope scope(env1->GetIsolate()); + + // Create second environment. + Local<ObjectTemplate> inner_global_template = + FunctionTemplate::New(env1->GetIsolate())->InstanceTemplate(); + inner_global_template ->SetAccessorProperty( + v8_str("this_x"), FunctionTemplate::New(env1->GetIsolate(), GetThisX)); + v8::Local<Context> env2 = + Context::New(env1->GetIsolate(), NULL, inner_global_template); + + Local<Value> foo = v8_str("foo"); + + // Set same security token for env1 and env2. + env1->SetSecurityToken(foo); + env2->SetSecurityToken(foo); + + env1->Global()->Set(v8_str("x"), v8_str("env1_x")); + + { + v8::Context::Scope scope(env2); + env2->Global()->Set(v8_str("x"), v8_str("env2_x")); + CompileRun( + "function bound_x() { return x; }" + "function get_x() { return this.x; }" + "function get_x_w() { return (function() {return this.x;})(); }"); + env1->Global()->Set(v8_str("bound_x"), CompileRun("bound_x")); + env1->Global()->Set(v8_str("get_x"), CompileRun("get_x")); + env1->Global()->Set(v8_str("get_x_w"), CompileRun("get_x_w")); + env1->Global()->Set( + v8_str("this_x"), + CompileRun("Object.getOwnPropertyDescriptor(this, 'this_x').get")); + } + + Local<Object> env2_global = env2->Global(); + env2_global->TurnOnAccessCheck(); + env2->DetachGlobal(); + + Local<Value> result; + result = CompileRun("bound_x()"); + CHECK_EQ(v8_str("env2_x"), result); + result = CompileRun("get_x()"); + CHECK(result->IsUndefined()); + result = CompileRun("get_x_w()"); + CHECK(result->IsUndefined()); + result = CompileRun("this_x()"); + CHECK_EQ(v8_str("env2_x"), result); + + // Reattach env2's proxy + env2 = Context::New(env1->GetIsolate(), + 0, + v8::Handle<v8::ObjectTemplate>(), + env2_global); + env2->SetSecurityToken(foo); + { + v8::Context::Scope scope(env2); + env2->Global()->Set(v8_str("x"), v8_str("env3_x")); + env2->Global()->Set(v8_str("env1"), env1->Global()); + result = CompileRun( + "results = [];" + "for (var i = 0; i < 4; i++ ) {" + " results.push(env1.bound_x());" + " results.push(env1.get_x());" + " results.push(env1.get_x_w());" + " results.push(env1.this_x());" + "}" + "results"); + Local<v8::Array> results = Local<v8::Array>::Cast(result); + CHECK_EQ(16, results->Length()); + for (int i = 0; i < 16; i += 4) { + CHECK_EQ(v8_str("env2_x"), results->Get(i + 0)); + CHECK_EQ(v8_str("env1_x"), results->Get(i + 1)); + CHECK_EQ(v8_str("env3_x"), results->Get(i + 2)); + CHECK_EQ(v8_str("env2_x"), results->Get(i + 3)); + } + } + + result = CompileRun( + "results = [];" + "for (var i = 0; i < 4; i++ ) {" + " results.push(bound_x());" + " results.push(get_x());" + " results.push(get_x_w());" + " results.push(this_x());" + "}" + "results"); + Local<v8::Array> results = Local<v8::Array>::Cast(result); + CHECK_EQ(16, results->Length()); + for (int i = 0; i < 16; i += 4) { + CHECK_EQ(v8_str("env2_x"), results->Get(i + 0)); + CHECK_EQ(v8_str("env3_x"), results->Get(i + 1)); + CHECK_EQ(v8_str("env3_x"), results->Get(i + 2)); + CHECK_EQ(v8_str("env2_x"), results->Get(i + 3)); + } + + result = CompileRun( + "results = [];" + "for (var i = 0; i < 4; i++ ) {" + " results.push(this.bound_x());" + " results.push(this.get_x());" + " results.push(this.get_x_w());" + " results.push(this.this_x());" + "}" + "results"); + results = Local<v8::Array>::Cast(result); + CHECK_EQ(16, results->Length()); + for (int i = 0; i < 16; i += 4) { + CHECK_EQ(v8_str("env2_x"), results->Get(i + 0)); + CHECK_EQ(v8_str("env1_x"), results->Get(i + 1)); + CHECK_EQ(v8_str("env3_x"), results->Get(i + 2)); + CHECK_EQ(v8_str("env2_x"), results->Get(i + 3)); + } } @@ -8539,7 +8918,8 @@ static void UnreachableFunction( TEST(AccessControl) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallbacks(NamedAccessBlocker, IndexedAccessBlocker); @@ -8554,8 +8934,8 @@ TEST(AccessControl) { global_template->SetAccessorProperty( v8_str("accessible_js_prop"), - v8::FunctionTemplate::New(EchoGetter), - v8::FunctionTemplate::New(EchoSetter), + v8::FunctionTemplate::New(isolate, EchoGetter), + v8::FunctionTemplate::New(isolate, EchoSetter), v8::None, v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE)); @@ -8567,8 +8947,8 @@ TEST(AccessControl) { global_template->SetAccessorProperty( v8_str("blocked_js_prop"), - v8::FunctionTemplate::New(UnreachableFunction), - v8::FunctionTemplate::New(UnreachableFunction), + v8::FunctionTemplate::New(isolate, UnreachableFunction), + v8::FunctionTemplate::New(isolate, UnreachableFunction), v8::None, v8::DEFAULT); @@ -8818,7 +9198,8 @@ TEST(AccessControl) { TEST(AccessControlES5) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallbacks(NamedAccessBlocker, IndexedAccessBlocker); @@ -8905,9 +9286,10 @@ static bool GetOwnPropertyNamesIndexedBlocker(Local<v8::Object> global, THREADED_TEST(AccessControlGetOwnPropertyNames) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> obj_template = + v8::ObjectTemplate::New(isolate); - obj_template->Set(v8_str("x"), v8::Integer::New(42)); + obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42)); obj_template->SetAccessCheckCallbacks(GetOwnPropertyNamesNamedBlocker, GetOwnPropertyNamesIndexedBlocker); @@ -8946,28 +9328,30 @@ THREADED_TEST(AccessControlGetOwnPropertyNames) { static void IndexedPropertyEnumerator( const v8::PropertyCallbackInfo<v8::Array>& info) { - v8::Handle<v8::Array> result = v8::Array::New(2); - result->Set(0, v8::Integer::New(7)); - result->Set(1, v8::Object::New()); + v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2); + result->Set(0, v8::Integer::New(info.GetIsolate(), 7)); + result->Set(1, v8::Object::New(info.GetIsolate())); info.GetReturnValue().Set(result); } static void NamedPropertyEnumerator( const v8::PropertyCallbackInfo<v8::Array>& info) { - v8::Handle<v8::Array> result = v8::Array::New(2); + v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2); result->Set(0, v8_str("x")); - result->Set(1, v8::Object::New()); + result->Set(1, v8::Object::New(info.GetIsolate())); info.GetReturnValue().Set(result); } THREADED_TEST(GetOwnPropertyNamesWithInterceptor) { - v8::HandleScope handle_scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope handle_scope(isolate); + v8::Handle<v8::ObjectTemplate> obj_template = + v8::ObjectTemplate::New(isolate); - obj_template->Set(v8_str("7"), v8::Integer::New(7)); - obj_template->Set(v8_str("x"), v8::Integer::New(42)); + obj_template->Set(v8_str("7"), v8::Integer::New(CcTest::isolate(), 7)); + obj_template->Set(v8_str("x"), v8::Integer::New(CcTest::isolate(), 42)); obj_template->SetIndexedPropertyHandler(NULL, NULL, NULL, NULL, IndexedPropertyEnumerator); obj_template->SetNamedPropertyHandler(NULL, NULL, NULL, NULL, @@ -9001,7 +9385,8 @@ THREADED_TEST(CrossDomainAccessors) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New(); + v8::Handle<v8::FunctionTemplate> func_template = + v8::FunctionTemplate::New(isolate); v8::Handle<v8::ObjectTemplate> global_template = func_template->InstanceTemplate(); @@ -9084,7 +9469,8 @@ TEST(AccessControlIC) { // Create an object that requires access-check functions to be // called for cross-domain access. - v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> object_template = + v8::ObjectTemplate::New(isolate); object_template->SetAccessCheckCallbacks(NamedAccessCounter, IndexedAccessCounter); Local<v8::Object> object = object_template->NewInstance(); @@ -9232,7 +9618,8 @@ THREADED_TEST(AccessControlFlatten) { // Create an object that requires access-check functions to be // called for cross-domain access. - v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> object_template = + v8::ObjectTemplate::New(isolate); object_template->SetAccessCheckCallbacks(NamedAccessFlatten, IndexedAccessFlatten); Local<v8::Object> object = object_template->NewInstance(); @@ -9301,7 +9688,8 @@ THREADED_TEST(AccessControlInterceptorIC) { // Create an object that requires access-check functions to be // called for cross-domain access. The object also has interceptors // interceptor. - v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> object_template = + v8::ObjectTemplate::New(isolate); object_template->SetAccessCheckCallbacks(NamedAccessCounter, IndexedAccessCounter); object_template->SetNamedPropertyHandler(AccessControlNamedGetter, @@ -9367,14 +9755,15 @@ static void InstanceFunctionCallback( THREADED_TEST(InstanceProperties) { LocalContext context; - v8::HandleScope handle_scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); - Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); Local<ObjectTemplate> instance = t->InstanceTemplate(); instance->Set(v8_str("x"), v8_num(42)); instance->Set(v8_str("f"), - v8::FunctionTemplate::New(InstanceFunctionCallback)); + v8::FunctionTemplate::New(isolate, InstanceFunctionCallback)); Local<Value> o = t->GetFunction()->NewInstance(); @@ -9395,17 +9784,19 @@ static void GlobalObjectInstancePropertiesGet( THREADED_TEST(GlobalObjectInstanceProperties) { - v8::HandleScope handle_scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope handle_scope(isolate); Local<Value> global_object; - Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); t->InstanceTemplate()->SetNamedPropertyHandler( GlobalObjectInstancePropertiesGet); Local<ObjectTemplate> instance_template = t->InstanceTemplate(); instance_template->Set(v8_str("x"), v8_num(42)); instance_template->Set(v8_str("f"), - v8::FunctionTemplate::New(InstanceFunctionCallback)); + v8::FunctionTemplate::New(isolate, + InstanceFunctionCallback)); // The script to check how Crankshaft compiles missing global function // invocations. function g is not defined and should throw on call. @@ -9451,11 +9842,12 @@ THREADED_TEST(GlobalObjectInstanceProperties) { THREADED_TEST(CallKnownGlobalReceiver) { - v8::HandleScope handle_scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope handle_scope(isolate); Local<Value> global_object; - Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); Local<ObjectTemplate> instance_template = t->InstanceTemplate(); // The script to check that we leave global object not @@ -9530,19 +9922,22 @@ static void ShadowNamedGet(Local<String> key, THREADED_TEST(ShadowObject) { shadow_y = shadow_y_setter_call_count = shadow_y_getter_call_count = 0; - v8::HandleScope handle_scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope handle_scope(isolate); - Local<ObjectTemplate> global_template = v8::ObjectTemplate::New(); + Local<ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); LocalContext context(NULL, global_template); - Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); t->InstanceTemplate()->SetNamedPropertyHandler(ShadowNamedGet); t->InstanceTemplate()->SetIndexedPropertyHandler(ShadowIndexedGet); Local<ObjectTemplate> proto = t->PrototypeTemplate(); Local<ObjectTemplate> instance = t->InstanceTemplate(); proto->Set(v8_str("f"), - v8::FunctionTemplate::New(ShadowFunctionCallback, Local<Value>())); + v8::FunctionTemplate::New(isolate, + ShadowFunctionCallback, + Local<Value>())); proto->Set(v8_str("x"), v8_num(12)); instance->SetAccessor(v8_str("y"), ShadowYGetter, ShadowYSetter); @@ -9571,17 +9966,18 @@ THREADED_TEST(ShadowObject) { THREADED_TEST(HiddenPrototype) { LocalContext context; - v8::HandleScope handle_scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); - Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); t0->InstanceTemplate()->Set(v8_str("x"), v8_num(0)); - Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); t1->SetHiddenPrototype(true); t1->InstanceTemplate()->Set(v8_str("y"), v8_num(1)); - Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate); t2->SetHiddenPrototype(true); t2->InstanceTemplate()->Set(v8_str("z"), v8_num(2)); - Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate); t3->InstanceTemplate()->Set(v8_str("u"), v8_num(3)); Local<v8::Object> o0 = t0->GetFunction()->NewInstance(); @@ -9615,12 +10011,13 @@ THREADED_TEST(HiddenPrototype) { THREADED_TEST(HiddenPrototypeSet) { LocalContext context; - v8::HandleScope handle_scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); - Local<v8::FunctionTemplate> ot = v8::FunctionTemplate::New(); - Local<v8::FunctionTemplate> ht = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> ot = v8::FunctionTemplate::New(isolate); + Local<v8::FunctionTemplate> ht = v8::FunctionTemplate::New(isolate); ht->SetHiddenPrototype(true); - Local<v8::FunctionTemplate> pt = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> pt = v8::FunctionTemplate::New(isolate); ht->InstanceTemplate()->Set(v8_str("x"), v8_num(0)); Local<v8::Object> o = ot->GetFunction()->NewInstance(); @@ -9659,11 +10056,11 @@ THREADED_TEST(HiddenPrototypeIdentityHash) { LocalContext context; v8::HandleScope handle_scope(context->GetIsolate()); - Handle<FunctionTemplate> t = FunctionTemplate::New(); + Handle<FunctionTemplate> t = FunctionTemplate::New(context->GetIsolate()); t->SetHiddenPrototype(true); t->InstanceTemplate()->Set(v8_str("foo"), v8_num(75)); Handle<Object> p = t->GetFunction()->NewInstance(); - Handle<Object> o = Object::New(); + Handle<Object> o = Object::New(context->GetIsolate()); o->SetPrototype(p); int hash = o->GetIdentityHash(); @@ -9675,17 +10072,18 @@ THREADED_TEST(HiddenPrototypeIdentityHash) { THREADED_TEST(SetPrototype) { LocalContext context; - v8::HandleScope handle_scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); - Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); t0->InstanceTemplate()->Set(v8_str("x"), v8_num(0)); - Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); t1->SetHiddenPrototype(true); t1->InstanceTemplate()->Set(v8_str("y"), v8_num(1)); - Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate); t2->SetHiddenPrototype(true); t2->InstanceTemplate()->Set(v8_str("z"), v8_num(2)); - Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate); t3->InstanceTemplate()->Set(v8_str("u"), v8_num(3)); Local<v8::Object> o0 = t0->GetFunction()->NewInstance(); @@ -9736,20 +10134,21 @@ THREADED_TEST(SetPrototype) { THREADED_TEST(Regress91517) { i::FLAG_allow_natives_syntax = true; LocalContext context; - v8::HandleScope handle_scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); - Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); t1->SetHiddenPrototype(true); t1->InstanceTemplate()->Set(v8_str("foo"), v8_num(1)); - Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate); t2->SetHiddenPrototype(true); t2->InstanceTemplate()->Set(v8_str("fuz1"), v8_num(2)); - t2->InstanceTemplate()->Set(v8_str("objects"), v8::Object::New()); + t2->InstanceTemplate()->Set(v8_str("objects"), v8::Object::New(isolate)); t2->InstanceTemplate()->Set(v8_str("fuz2"), v8_num(2)); - Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate); t3->SetHiddenPrototype(true); t3->InstanceTemplate()->Set(v8_str("boo"), v8_num(3)); - Local<v8::FunctionTemplate> t4 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t4 = v8::FunctionTemplate::New(isolate); t4->InstanceTemplate()->Set(v8_str("baz"), v8_num(4)); // Force dictionary-based properties. @@ -9772,7 +10171,8 @@ THREADED_TEST(Regress91517) { // Call the runtime version of GetLocalPropertyNames() on the natively // created object through JavaScript. context->Global()->Set(v8_str("obj"), o4); - CompileRun("var names = %GetLocalPropertyNames(obj, true);"); + // PROPERTY_ATTRIBUTES_NONE = 0 + CompileRun("var names = %GetLocalPropertyNames(obj, 0);"); ExpectInt32("names.length", 1006); ExpectTrue("names.indexOf(\"baz\") >= 0"); @@ -9784,12 +10184,69 @@ THREADED_TEST(Regress91517) { } -THREADED_TEST(FunctionReadOnlyPrototype) { +// Getting property names of an object with a hidden and inherited +// prototype should not duplicate the accessor properties inherited. +THREADED_TEST(Regress269562) { + i::FLAG_allow_natives_syntax = true; LocalContext context; v8::HandleScope handle_scope(context->GetIsolate()); - Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(); - t1->PrototypeTemplate()->Set(v8_str("x"), v8::Integer::New(42)); + Local<v8::FunctionTemplate> t1 = + v8::FunctionTemplate::New(context->GetIsolate()); + t1->SetHiddenPrototype(true); + + Local<v8::ObjectTemplate> i1 = t1->InstanceTemplate(); + i1->SetAccessor(v8_str("foo"), + SimpleAccessorGetter, SimpleAccessorSetter); + i1->SetAccessor(v8_str("bar"), + SimpleAccessorGetter, SimpleAccessorSetter); + i1->SetAccessor(v8_str("baz"), + SimpleAccessorGetter, SimpleAccessorSetter); + i1->Set(v8_str("n1"), v8_num(1)); + i1->Set(v8_str("n2"), v8_num(2)); + + Local<v8::Object> o1 = t1->GetFunction()->NewInstance(); + Local<v8::FunctionTemplate> t2 = + v8::FunctionTemplate::New(context->GetIsolate()); + t2->SetHiddenPrototype(true); + + // Inherit from t1 and mark prototype as hidden. + t2->Inherit(t1); + t2->InstanceTemplate()->Set(v8_str("mine"), v8_num(4)); + + Local<v8::Object> o2 = t2->GetFunction()->NewInstance(); + CHECK(o2->SetPrototype(o1)); + + v8::Local<v8::Symbol> sym = v8::Symbol::New(context->GetIsolate(), "s1"); + o1->Set(sym, v8_num(3)); + o1->SetHiddenValue(v8_str("h1"), + v8::Integer::New(context->GetIsolate(), 2013)); + + // Call the runtime version of GetLocalPropertyNames() on + // the natively created object through JavaScript. + context->Global()->Set(v8_str("obj"), o2); + context->Global()->Set(v8_str("sym"), sym); + // PROPERTY_ATTRIBUTES_NONE = 0 + CompileRun("var names = %GetLocalPropertyNames(obj, 0);"); + + ExpectInt32("names.length", 7); + ExpectTrue("names.indexOf(\"foo\") >= 0"); + ExpectTrue("names.indexOf(\"bar\") >= 0"); + ExpectTrue("names.indexOf(\"baz\") >= 0"); + ExpectTrue("names.indexOf(\"n1\") >= 0"); + ExpectTrue("names.indexOf(\"n2\") >= 0"); + ExpectTrue("names.indexOf(sym) >= 0"); + ExpectTrue("names.indexOf(\"mine\") >= 0"); +} + + +THREADED_TEST(FunctionReadOnlyPrototype) { + LocalContext context; + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); + t1->PrototypeTemplate()->Set(v8_str("x"), v8::Integer::New(isolate, 42)); t1->ReadOnlyPrototype(); context->Global()->Set(v8_str("func1"), t1->GetFunction()); // Configured value of ReadOnly flag. @@ -9802,8 +10259,8 @@ THREADED_TEST(FunctionReadOnlyPrototype) { CHECK_EQ(42, CompileRun("func1.prototype = {}; func1.prototype.x")->Int32Value()); - Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(); - t2->PrototypeTemplate()->Set(v8_str("x"), v8::Integer::New(42)); + Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate); + t2->PrototypeTemplate()->Set(v8_str("x"), v8::Integer::New(isolate, 42)); context->Global()->Set(v8_str("func2"), t2->GetFunction()); // Default value of ReadOnly flag. CHECK(CompileRun( @@ -9817,9 +10274,10 @@ THREADED_TEST(FunctionReadOnlyPrototype) { THREADED_TEST(SetPrototypeThrows) { LocalContext context; - v8::HandleScope handle_scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); - Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); Local<v8::Object> o0 = t->GetFunction()->NewInstance(); Local<v8::Object> o1 = t->GetFunction()->NewInstance(); @@ -9838,9 +10296,10 @@ THREADED_TEST(SetPrototypeThrows) { THREADED_TEST(FunctionRemovePrototype) { LocalContext context; - v8::HandleScope handle_scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); - Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); t1->RemovePrototype(); Local<v8::Function> fun = t1->GetFunction(); context->Global()->Set(v8_str("fun"), fun); @@ -9858,7 +10317,8 @@ THREADED_TEST(FunctionRemovePrototype) { THREADED_TEST(GetterSetterExceptions) { LocalContext context; - v8::HandleScope handle_scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); CompileRun( "function Foo() { };" "function Throw() { throw 5; };" @@ -9868,21 +10328,22 @@ THREADED_TEST(GetterSetterExceptions) { Local<v8::Object> x = Local<v8::Object>::Cast(context->Global()->Get(v8_str("x"))); v8::TryCatch try_catch; - x->Set(v8_str("set"), v8::Integer::New(8)); + x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); x->Get(v8_str("get")); - x->Set(v8_str("set"), v8::Integer::New(8)); + x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); x->Get(v8_str("get")); - x->Set(v8_str("set"), v8::Integer::New(8)); + x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); x->Get(v8_str("get")); - x->Set(v8_str("set"), v8::Integer::New(8)); + x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); x->Get(v8_str("get")); } THREADED_TEST(Constructor) { LocalContext context; - v8::HandleScope handle_scope(context->GetIsolate()); - Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); + Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); templ->SetClassName(v8_str("Fun")); Local<Function> cons = templ->GetFunction(); context->Global()->Set(v8_str("Fun"), cons); @@ -9901,7 +10362,7 @@ static void ConstructorCallback( if (args.IsConstructCall()) { Local<Object> Holder = args.Holder(); - This = Object::New(); + This = Object::New(args.GetIsolate()); Local<Value> proto = Holder->GetPrototype(); if (proto->IsObject()) { This->SetPrototype(proto); @@ -9927,7 +10388,7 @@ THREADED_TEST(ConstructorForObject) { v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope handle_scope(isolate); - { Local<ObjectTemplate> instance_template = ObjectTemplate::New(); + { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); instance_template->SetCallAsFunctionHandler(ConstructorCallback); Local<Object> instance = instance_template->NewInstance(); context->Global()->Set(v8_str("obj"), instance); @@ -10003,7 +10464,7 @@ THREADED_TEST(ConstructorForObject) { } // Check exception handling when there is no constructor set for the Object. - { Local<ObjectTemplate> instance_template = ObjectTemplate::New(); + { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); Local<Object> instance = instance_template->NewInstance(); context->Global()->Set(v8_str("obj2"), instance); v8::TryCatch try_catch; @@ -10025,7 +10486,7 @@ THREADED_TEST(ConstructorForObject) { } // Check the case when constructor throws exception. - { Local<ObjectTemplate> instance_template = ObjectTemplate::New(); + { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); instance_template->SetCallAsFunctionHandler(ThrowValue); Local<Object> instance = instance_template->NewInstance(); context->Global()->Set(v8_str("obj3"), instance); @@ -10049,7 +10510,7 @@ THREADED_TEST(ConstructorForObject) { // Check whether constructor returns with an object or non-object. { Local<FunctionTemplate> function_template = - FunctionTemplate::New(FakeConstructorCallback); + FunctionTemplate::New(isolate, FakeConstructorCallback); Local<Function> function = function_template->GetFunction(); Local<Object> instance1 = function; context->Global()->Set(v8_str("obj4"), instance1); @@ -10069,7 +10530,7 @@ THREADED_TEST(ConstructorForObject) { CHECK(!try_catch.HasCaught()); CHECK(value->IsObject()); - Local<ObjectTemplate> instance_template = ObjectTemplate::New(); + Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); instance_template->SetCallAsFunctionHandler(FakeConstructorCallback); Local<Object> instance2 = instance_template->NewInstance(); context->Global()->Set(v8_str("obj5"), instance2); @@ -10092,8 +10553,9 @@ THREADED_TEST(ConstructorForObject) { THREADED_TEST(FunctionDescriptorException) { LocalContext context; - v8::HandleScope handle_scope(context->GetIsolate()); - Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); + Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); templ->SetClassName(v8_str("Fun")); Local<Function> cons = templ->GetFunction(); context->Global()->Set(v8_str("Fun"), cons); @@ -10103,9 +10565,9 @@ THREADED_TEST(FunctionDescriptorException) { " (new Fun()).blah()" " } catch (e) {" " var str = String(e);" - " if (str.indexOf('TypeError') == -1) return 1;" - " if (str.indexOf('[object Fun]') != -1) return 2;" - " if (str.indexOf('#<Fun>') == -1) return 3;" + // " if (str.indexOf('TypeError') == -1) return 1;" + // " if (str.indexOf('[object Fun]') != -1) return 2;" + // " if (str.indexOf('#<Fun>') == -1) return 3;" " return 0;" " }" " return 4;" @@ -10310,9 +10772,10 @@ static void ReturnThis(const v8::FunctionCallbackInfo<v8::Value>& args) { // functions. THREADED_TEST(CallAsFunction) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); - { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); + { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); Local<ObjectTemplate> instance_template = t->InstanceTemplate(); instance_template->SetCallAsFunctionHandler(call_as_function); Local<v8::Object> instance = t->GetFunction()->NewInstance(); @@ -10365,7 +10828,7 @@ THREADED_TEST(CallAsFunction) { CHECK_EQ(28, value->Int32Value()); } - { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); + { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); Local<ObjectTemplate> instance_template(t->InstanceTemplate()); USE(instance_template); Local<v8::Object> instance = t->GetFunction()->NewInstance(); @@ -10379,7 +10842,8 @@ THREADED_TEST(CallAsFunction) { CHECK(value.IsEmpty()); CHECK(try_catch.HasCaught()); String::Utf8Value exception_value1(try_catch.Exception()); - CHECK_EQ("TypeError: Property 'obj2' of object #<Object> is not a function", + // TODO(verwaest): Better message + CHECK_EQ("TypeError: object is not a function", *exception_value1); try_catch.Reset(); @@ -10394,7 +10858,7 @@ THREADED_TEST(CallAsFunction) { try_catch.Reset(); } - { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); + { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); Local<ObjectTemplate> instance_template = t->InstanceTemplate(); instance_template->SetCallAsFunctionHandler(ThrowValue); Local<v8::Object> instance = t->GetFunction()->NewInstance(); @@ -10418,8 +10882,7 @@ THREADED_TEST(CallAsFunction) { try_catch.Reset(); } - { v8::Isolate* isolate = context->GetIsolate(); - Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); + { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); Local<ObjectTemplate> instance_template = t->InstanceTemplate(); instance_template->SetCallAsFunctionHandler(ReturnThis); Local<v8::Object> instance = t->GetFunction()->NewInstance(); @@ -10441,8 +10904,7 @@ THREADED_TEST(CallAsFunction) { CHECK(a5->StrictEquals(instance)); } - { v8::Isolate* isolate = context->GetIsolate(); - CompileRun( + { CompileRun( "function ReturnThisSloppy() {" " return this;" "}" @@ -10498,9 +10960,10 @@ THREADED_TEST(CallAsFunction) { // Check whether a non-function object is callable. THREADED_TEST(CallableObject) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); - { Local<ObjectTemplate> instance_template = ObjectTemplate::New(); + { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); instance_template->SetCallAsFunctionHandler(call_as_function); Local<Object> instance = instance_template->NewInstance(); v8::TryCatch try_catch; @@ -10509,7 +10972,7 @@ THREADED_TEST(CallableObject) { CHECK(!try_catch.HasCaught()); } - { Local<ObjectTemplate> instance_template = ObjectTemplate::New(); + { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); Local<Object> instance = instance_template->NewInstance(); v8::TryCatch try_catch; @@ -10518,7 +10981,7 @@ THREADED_TEST(CallableObject) { } { Local<FunctionTemplate> function_template = - FunctionTemplate::New(call_as_function); + FunctionTemplate::New(isolate, call_as_function); Local<Function> function = function_template->GetFunction(); Local<Object> instance = function; v8::TryCatch try_catch; @@ -10527,7 +10990,7 @@ THREADED_TEST(CallableObject) { CHECK(!try_catch.HasCaught()); } - { Local<FunctionTemplate> function_template = FunctionTemplate::New(); + { Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate); Local<Function> function = function_template->GetFunction(); Local<Object> instance = function; v8::TryCatch try_catch; @@ -10538,45 +11001,44 @@ THREADED_TEST(CallableObject) { } -static int CountHandles() { - return v8::HandleScope::NumberOfHandles(); -} - - -static int Recurse(int depth, int iterations) { - v8::HandleScope scope(CcTest::isolate()); - if (depth == 0) return CountHandles(); +static int Recurse(v8::Isolate* isolate, int depth, int iterations) { + v8::HandleScope scope(isolate); + if (depth == 0) return v8::HandleScope::NumberOfHandles(isolate); for (int i = 0; i < iterations; i++) { - Local<v8::Number> n(v8::Integer::New(42)); + Local<v8::Number> n(v8::Integer::New(isolate, 42)); } - return Recurse(depth - 1, iterations); + return Recurse(isolate, depth - 1, iterations); } THREADED_TEST(HandleIteration) { static const int kIterations = 500; static const int kNesting = 200; - CHECK_EQ(0, CountHandles()); + LocalContext context; + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope0(isolate); + CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate)); { - v8::HandleScope scope1(CcTest::isolate()); - CHECK_EQ(0, CountHandles()); + v8::HandleScope scope1(isolate); + CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate)); for (int i = 0; i < kIterations; i++) { - Local<v8::Number> n(v8::Integer::New(42)); - CHECK_EQ(i + 1, CountHandles()); + Local<v8::Number> n(v8::Integer::New(CcTest::isolate(), 42)); + CHECK_EQ(i + 1, v8::HandleScope::NumberOfHandles(isolate)); } - CHECK_EQ(kIterations, CountHandles()); + CHECK_EQ(kIterations, v8::HandleScope::NumberOfHandles(isolate)); { v8::HandleScope scope2(CcTest::isolate()); for (int j = 0; j < kIterations; j++) { - Local<v8::Number> n(v8::Integer::New(42)); - CHECK_EQ(j + 1 + kIterations, CountHandles()); + Local<v8::Number> n(v8::Integer::New(CcTest::isolate(), 42)); + CHECK_EQ(j + 1 + kIterations, + v8::HandleScope::NumberOfHandles(isolate)); } } - CHECK_EQ(kIterations, CountHandles()); + CHECK_EQ(kIterations, v8::HandleScope::NumberOfHandles(isolate)); } - CHECK_EQ(0, CountHandles()); - CHECK_EQ(kNesting * kIterations, Recurse(kNesting, kIterations)); + CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate)); + CHECK_EQ(kNesting * kIterations, Recurse(isolate, kNesting, kIterations)); } @@ -10589,8 +11051,9 @@ static void InterceptorHasOwnPropertyGetter( THREADED_TEST(InterceptorHasOwnProperty) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetter); Local<Function> function = fun_templ->GetFunction(); @@ -10620,8 +11083,9 @@ static void InterceptorHasOwnPropertyGetterGC( THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC); Local<Function> function = fun_templ->GetFunction(); @@ -10655,8 +11119,9 @@ typedef void (*NamedPropertyGetter)( static void CheckInterceptorLoadIC(NamedPropertyGetter getter, const char* source, int expected) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(getter, 0, 0, 0, 0, v8_str("data")); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -10673,7 +11138,7 @@ static void InterceptorLoadICGetter( CHECK_EQ(isolate, info.GetIsolate()); CHECK_EQ(v8_str("data"), info.Data()); CHECK_EQ(v8_str("x"), name); - info.GetReturnValue().Set(v8::Integer::New(42)); + info.GetReturnValue().Set(v8::Integer::New(isolate, 42)); } @@ -10698,7 +11163,7 @@ static void InterceptorLoadXICGetter( ApiTestFuzzer::Fuzz(); info.GetReturnValue().Set( v8_str("x")->Equals(name) ? - v8::Handle<v8::Value>(v8::Integer::New(42)) : + v8::Handle<v8::Value>(v8::Integer::New(info.GetIsolate(), 42)) : v8::Handle<v8::Value>()); } @@ -10868,8 +11333,9 @@ static void SetOnThis(Local<String> name, THREADED_TEST(InterceptorLoadICWithCallbackOnHolder) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(InterceptorLoadXICGetter); templ->SetAccessor(v8_str("y"), Return239Callback); LocalContext context; @@ -10897,10 +11363,11 @@ THREADED_TEST(InterceptorLoadICWithCallbackOnHolder) { THREADED_TEST(InterceptorLoadICWithCallbackOnProto) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter); - v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); templ_p->SetAccessor(v8_str("y"), Return239Callback); LocalContext context; @@ -10930,8 +11397,9 @@ THREADED_TEST(InterceptorLoadICWithCallbackOnProto) { THREADED_TEST(InterceptorLoadICForCallbackWithOverride) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(InterceptorLoadXICGetter); templ->SetAccessor(v8_str("y"), Return239Callback); @@ -10958,10 +11426,11 @@ THREADED_TEST(InterceptorLoadICForCallbackWithOverride) { // Test the case when we stored callback into // a stub, but interceptor produced value on its own. THREADED_TEST(InterceptorLoadICCallbackNotNeeded) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter); - v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); templ_p->SetAccessor(v8_str("y"), Return239Callback); LocalContext context; @@ -10986,10 +11455,11 @@ THREADED_TEST(InterceptorLoadICCallbackNotNeeded) { // Test the case when we stored callback into // a stub, but it got invalidated later on. THREADED_TEST(InterceptorLoadICInvalidatedCallback) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter); - v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis); LocalContext context; @@ -11018,10 +11488,11 @@ THREADED_TEST(InterceptorLoadICInvalidatedCallback) { // a stub, but it got invalidated later on due to override on // global object which is between interceptor and callbacks' holders. THREADED_TEST(InterceptorLoadICInvalidatedCallbackViaGlobal) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter); - v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis); LocalContext context; @@ -11050,7 +11521,7 @@ static void InterceptorLoadICGetter0( const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); CHECK(v8_str("x")->Equals(name)); - info.GetReturnValue().Set(v8::Integer::New(0)); + info.GetReturnValue().Set(v8::Integer::New(info.GetIsolate(), 0)); } @@ -11073,8 +11544,9 @@ static void InterceptorStoreICSetter( // This test should hit the store IC for the interceptor case. THREADED_TEST(InterceptorStoreIC) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(InterceptorLoadICGetter, InterceptorStoreICSetter, 0, 0, 0, v8_str("data")); @@ -11088,8 +11560,9 @@ THREADED_TEST(InterceptorStoreIC) { THREADED_TEST(InterceptorStoreICWithNoSetter) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(InterceptorLoadXICGetter); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -11119,8 +11592,9 @@ static void InterceptorCallICGetter( // This test should hit the call IC for the interceptor case. THREADED_TEST(InterceptorCallIC) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(InterceptorCallICGetter); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -11138,8 +11612,9 @@ THREADED_TEST(InterceptorCallIC) { // This test checks that if interceptor doesn't provide // a value, we can fetch regular value. THREADED_TEST(InterceptorCallICSeesOthers) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -11167,8 +11642,9 @@ static void InterceptorCallICGetter4( // even if we cached shadowed variant, interceptor's function // is invoked THREADED_TEST(InterceptorCallICCacheableNotNeeded) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(InterceptorCallICGetter4); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -11187,8 +11663,9 @@ THREADED_TEST(InterceptorCallICCacheableNotNeeded) { // Test the case when we stored cacheable lookup into // a stub, but it got invalidated later on THREADED_TEST(InterceptorCallICInvalidatedCacheable) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -11214,8 +11691,9 @@ THREADED_TEST(InterceptorCallICInvalidatedCacheable) { // This test checks that if interceptor doesn't provide a function, // cached constant function is used THREADED_TEST(InterceptorCallICConstantFunctionUsed) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -11245,8 +11723,9 @@ static void InterceptorCallICGetter5( // even if we cached constant function, interceptor's function // is invoked THREADED_TEST(InterceptorCallICConstantFunctionNotNeeded) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(InterceptorCallICGetter5); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -11278,8 +11757,9 @@ static void InterceptorCallICGetter6( // to test the optimized compiler. THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) { i::FLAG_allow_natives_syntax = true; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(InterceptorCallICGetter6); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -11308,8 +11788,9 @@ THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) { // Test the case when we stored constant function into // a stub, but it got invalidated later on THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -11338,8 +11819,9 @@ THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) { // a stub, but it got invalidated later on due to override on // global object which is between interceptor and constant function' holders. THREADED_TEST(InterceptorCallICInvalidatedConstantFunctionViaGlobal) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -11363,8 +11845,9 @@ THREADED_TEST(InterceptorCallICInvalidatedConstantFunctionViaGlobal) { // Test the case when actual function to call sits on global object. THREADED_TEST(InterceptorCallICCachedFromGlobal) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; @@ -11451,10 +11934,13 @@ void DirectApiCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { THREADED_TEST(CallICFastApi_DirectCall_GCMoveStub) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New(); - nativeobject_templ->Set("callback", - v8::FunctionTemplate::New(DirectApiCallback)); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> nativeobject_templ = + v8::ObjectTemplate::New(isolate); + nativeobject_templ->Set(isolate, "callback", + v8::FunctionTemplate::New(isolate, + DirectApiCallback)); v8::Local<v8::Object> nativeobject_obj = nativeobject_templ->NewInstance(); context->Global()->Set(v8_str("nativeobject"), nativeobject_obj); // call the api function multiple times to ensure direct call stub creation. @@ -11476,10 +11962,13 @@ void ThrowingDirectApiCallback( THREADED_TEST(CallICFastApi_DirectCall_Throw) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New(); - nativeobject_templ->Set("callback", - v8::FunctionTemplate::New(ThrowingDirectApiCallback)); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> nativeobject_templ = + v8::ObjectTemplate::New(isolate); + nativeobject_templ->Set(isolate, "callback", + v8::FunctionTemplate::New(isolate, + ThrowingDirectApiCallback)); v8::Local<v8::Object> nativeobject_obj = nativeobject_templ->NewInstance(); context->Global()->Set(v8_str("nativeobject"), nativeobject_obj); // call the api function multiple times to ensure direct call stub creation. @@ -11514,8 +12003,9 @@ static void DirectGetterCallback( template<typename Accessor> static void LoadICFastApi_DirectCall_GCMoveStub(Accessor accessor) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("p1"), accessor); context->Global()->Set(v8_str("o1"), obj->NewInstance()); p_getter_count = 0; @@ -11544,8 +12034,9 @@ void ThrowingDirectGetterCallback( THREADED_TEST(LoadICFastApi_DirectCall_Throw) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("p1"), ThrowingDirectGetterCallback); context->Global()->Set(v8_str("o1"), obj->NewInstance()); v8::Handle<Value> result = CompileRun( @@ -11560,18 +12051,21 @@ THREADED_TEST(LoadICFastApi_DirectCall_Throw) { THREADED_PROFILED_TEST(InterceptorCallICFastApi_TrivialSignature) { int interceptor_call_count = 0; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate); v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(FastApiCallback_TrivialSignature, + v8::FunctionTemplate::New(isolate, + FastApiCallback_TrivialSignature, v8_str("method_data"), v8::Handle<v8::Signature>()); v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); - templ->SetNamedPropertyHandler(InterceptorCallICFastApi, - NULL, NULL, NULL, NULL, - v8::External::New(&interceptor_call_count)); + templ->SetNamedPropertyHandler( + InterceptorCallICFastApi, NULL, NULL, NULL, NULL, + v8::External::New(isolate, &interceptor_call_count)); LocalContext context; v8::Handle<v8::Function> fun = fun_templ->GetFunction(); GenerateSomeGarbage(); @@ -11588,19 +12082,20 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_TrivialSignature) { THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature) { int interceptor_call_count = 0; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); - v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, - v8_str("method_data"), - v8::Signature::New(fun_templ)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate); + v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), + v8::Signature::New(isolate, fun_templ)); v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); - templ->SetNamedPropertyHandler(InterceptorCallICFastApi, - NULL, NULL, NULL, NULL, - v8::External::New(&interceptor_call_count)); + templ->SetNamedPropertyHandler( + InterceptorCallICFastApi, NULL, NULL, NULL, NULL, + v8::External::New(isolate, &interceptor_call_count)); LocalContext context; v8::Handle<v8::Function> fun = fun_templ->GetFunction(); GenerateSomeGarbage(); @@ -11620,19 +12115,20 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature) { THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) { int interceptor_call_count = 0; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); - v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, - v8_str("method_data"), - v8::Signature::New(fun_templ)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate); + v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), + v8::Signature::New(isolate, fun_templ)); v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); - templ->SetNamedPropertyHandler(InterceptorCallICFastApi, - NULL, NULL, NULL, NULL, - v8::External::New(&interceptor_call_count)); + templ->SetNamedPropertyHandler( + InterceptorCallICFastApi, NULL, NULL, NULL, NULL, + v8::External::New(isolate, &interceptor_call_count)); LocalContext context; v8::Handle<v8::Function> fun = fun_templ->GetFunction(); GenerateSomeGarbage(); @@ -11658,19 +12154,20 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) { THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) { int interceptor_call_count = 0; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); - v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, - v8_str("method_data"), - v8::Signature::New(fun_templ)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate); + v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), + v8::Signature::New(isolate, fun_templ)); v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); - templ->SetNamedPropertyHandler(InterceptorCallICFastApi, - NULL, NULL, NULL, NULL, - v8::External::New(&interceptor_call_count)); + templ->SetNamedPropertyHandler( + InterceptorCallICFastApi, NULL, NULL, NULL, NULL, + v8::External::New(isolate, &interceptor_call_count)); LocalContext context; v8::Handle<v8::Function> fun = fun_templ->GetFunction(); GenerateSomeGarbage(); @@ -11696,19 +12193,20 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) { THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) { int interceptor_call_count = 0; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); - v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, - v8_str("method_data"), - v8::Signature::New(fun_templ)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate); + v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), + v8::Signature::New(isolate, fun_templ)); v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); - templ->SetNamedPropertyHandler(InterceptorCallICFastApi, - NULL, NULL, NULL, NULL, - v8::External::New(&interceptor_call_count)); + templ->SetNamedPropertyHandler( + InterceptorCallICFastApi, NULL, NULL, NULL, NULL, + v8::External::New(isolate, &interceptor_call_count)); LocalContext context; v8::Handle<v8::Function> fun = fun_templ->GetFunction(); GenerateSomeGarbage(); @@ -11728,7 +12226,8 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) { " }" "}"); CHECK(try_catch.HasCaught()); - CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"), + // TODO(verwaest): Adjust message. + CHECK_EQ(v8_str("TypeError: undefined is not a function"), try_catch.Exception()->ToString()); CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); CHECK_GE(interceptor_call_count, 50); @@ -11737,19 +12236,20 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) { THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { int interceptor_call_count = 0; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); - v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, - v8_str("method_data"), - v8::Signature::New(fun_templ)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate); + v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), + v8::Signature::New(isolate, fun_templ)); v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); - templ->SetNamedPropertyHandler(InterceptorCallICFastApi, - NULL, NULL, NULL, NULL, - v8::External::New(&interceptor_call_count)); + templ->SetNamedPropertyHandler( + InterceptorCallICFastApi, NULL, NULL, NULL, NULL, + v8::External::New(isolate, &interceptor_call_count)); LocalContext context; v8::Handle<v8::Function> fun = fun_templ->GetFunction(); GenerateSomeGarbage(); @@ -11777,10 +12277,13 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { THREADED_PROFILED_TEST(CallICFastApi_TrivialSignature) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate); v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(FastApiCallback_TrivialSignature, + v8::FunctionTemplate::New(isolate, + FastApiCallback_TrivialSignature, v8_str("method_data"), v8::Handle<v8::Signature>()); v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); @@ -11802,12 +12305,13 @@ THREADED_PROFILED_TEST(CallICFastApi_TrivialSignature) { THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); - v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, - v8_str("method_data"), - v8::Signature::New(fun_templ)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate); + v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), + v8::Signature::New(isolate, fun_templ)); v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); @@ -11831,12 +12335,13 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature) { THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss1) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); - v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, - v8_str("method_data"), - v8::Signature::New(fun_templ)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate); + v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), + v8::Signature::New(isolate, fun_templ)); v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); @@ -11865,12 +12370,13 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss1) { THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss2) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); - v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, - v8_str("method_data"), - v8::Signature::New(fun_templ)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate); + v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), + v8::Signature::New(isolate, fun_templ)); v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); @@ -11895,19 +12401,21 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss2) { " }" "}"); CHECK(try_catch.HasCaught()); - CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"), + // TODO(verwaest): Adjust message. + CHECK_EQ(v8_str("TypeError: undefined is not a function"), try_catch.Exception()->ToString()); CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); } THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_TypeError) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); - v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, - v8_str("method_data"), - v8::Signature::New(fun_templ)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate); + v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), + v8::Signature::New(isolate, fun_templ)); v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); @@ -11953,8 +12461,9 @@ static void InterceptorKeyedCallICGetter( // Test the case when we stored cacheable lookup into // a stub, but the function name changed (to another cacheable function). THREADED_TEST(InterceptorKeyedCallICKeyChange1) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -11977,8 +12486,9 @@ THREADED_TEST(InterceptorKeyedCallICKeyChange1) { // a stub, but the function name changed (and the new function is present // both before and after the interceptor in the prototype chain). THREADED_TEST(InterceptorKeyedCallICKeyChange2) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(InterceptorKeyedCallICGetter); LocalContext context; context->Global()->Set(v8_str("proto1"), templ->NewInstance()); @@ -12004,8 +12514,9 @@ THREADED_TEST(InterceptorKeyedCallICKeyChange2) { // Same as InterceptorKeyedCallICKeyChange1 only the cacheable function sit // on the global object. THREADED_TEST(InterceptorKeyedCallICKeyChangeOnGlobal) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; context->Global()->Set(v8_str("o"), templ->NewInstance()); @@ -12029,8 +12540,9 @@ THREADED_TEST(InterceptorKeyedCallICKeyChangeOnGlobal) { // Test the case when actual function to call sits on global object. THREADED_TEST(InterceptorKeyedCallICFromGlobal) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; context->Global()->Set(v8_str("o"), templ_o->NewInstance()); @@ -12054,8 +12566,9 @@ THREADED_TEST(InterceptorKeyedCallICFromGlobal) { // Test the map transition before the interceptor. THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; context->Global()->Set(v8_str("proto"), templ_o->NewInstance()); @@ -12076,8 +12589,9 @@ THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) { // Test the map transition after the interceptor. THREADED_TEST(InterceptorKeyedCallICMapChangeAfter) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetNamedPropertyHandler(NoBlockGetterX); LocalContext context; context->Global()->Set(v8_str("o"), templ_o->NewInstance()); @@ -12112,8 +12626,9 @@ static void InterceptorICRefErrorGetter( // Once in a while, the interceptor will reply that a property was not // found in which case we should get a reference error. THREADED_TEST(InterceptorICReferenceErrors) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(InterceptorICRefErrorGetter); LocalContext context(0, templ, v8::Handle<Value>()); call_ic_function2 = v8_compile("function h(x) { return x; }; h")->Run(); @@ -12159,8 +12674,9 @@ static void InterceptorICExceptionGetter( // exception once in a while. THREADED_TEST(InterceptorICGetterExceptions) { interceptor_ic_exception_get_count = 0; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(InterceptorICExceptionGetter); LocalContext context(0, templ, v8::Handle<Value>()); call_ic_function3 = v8_compile("function h(x) { return x; }; h")->Run(); @@ -12203,8 +12719,9 @@ static void InterceptorICExceptionSetter( // once in a while. THREADED_TEST(InterceptorICSetterExceptions) { interceptor_ic_exception_set_count = 0; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(0, InterceptorICExceptionSetter); LocalContext context(0, templ, v8::Handle<Value>()); v8::Handle<Value> value = CompileRun( @@ -12221,12 +12738,13 @@ THREADED_TEST(InterceptorICSetterExceptions) { // Test that we ignore null interceptors. THREADED_TEST(NullNamedInterceptor) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler( static_cast<v8::NamedPropertyGetterCallback>(0)); LocalContext context; - templ->Set("x", v8_num(42)); + templ->Set(CcTest::isolate(), "x", v8_num(42)); v8::Handle<v8::Object> obj = templ->NewInstance(); context->Global()->Set(v8_str("obj"), obj); v8::Handle<Value> value = CompileRun("obj.x"); @@ -12237,12 +12755,13 @@ THREADED_TEST(NullNamedInterceptor) { // Test that we ignore null interceptors. THREADED_TEST(NullIndexedInterceptor) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler( static_cast<v8::IndexedPropertyGetterCallback>(0)); LocalContext context; - templ->Set("42", v8_num(42)); + templ->Set(CcTest::isolate(), "42", v8_num(42)); v8::Handle<v8::Object> obj = templ->NewInstance(); context->Global()->Set(v8_str("obj"), obj); v8::Handle<Value> value = CompileRun("obj[42]"); @@ -12252,8 +12771,9 @@ THREADED_TEST(NullIndexedInterceptor) { THREADED_TEST(NamedPropertyHandlerGetterAttributes) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); templ->InstanceTemplate()->SetNamedPropertyHandler(InterceptorLoadXICGetter); LocalContext env; env->Global()->Set(v8_str("obj"), @@ -12275,13 +12795,13 @@ THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) { LocalContext context; HandleScope scope(context->GetIsolate()); - Local<FunctionTemplate> templ = FunctionTemplate::New(); + Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); Local<ObjectTemplate> instance_templ = templ->InstanceTemplate(); instance_templ->SetAccessor(v8_str("f"), ThrowingGetter); Local<Object> instance = templ->GetFunction()->NewInstance(); - Local<Object> another = Object::New(); + Local<Object> another = Object::New(context->GetIsolate()); another->SetPrototype(instance); Local<Object> with_js_getter = CompileRun( @@ -12365,10 +12885,12 @@ static void WebKitLike(Handle<Message> message, Handle<Value> data) { THREADED_TEST(ExceptionsDoNotPropagatePastTryCatch) { LocalContext context; - HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + HandleScope scope(isolate); Local<Function> func = - FunctionTemplate::New(ThrowingCallbackWithTryCatch)->GetFunction(); + FunctionTemplate::New(isolate, + ThrowingCallbackWithTryCatch)->GetFunction(); context->Global()->Set(v8_str("func"), func); MessageCallback callbacks[] = @@ -12409,16 +12931,17 @@ static void ChildGetter(Local<String> name, THREADED_TEST(Overriding) { i::FLAG_es5_readonly = true; LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); // Parent template. - Local<v8::FunctionTemplate> parent_templ = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> parent_templ = v8::FunctionTemplate::New(isolate); Local<ObjectTemplate> parent_instance_templ = parent_templ->InstanceTemplate(); parent_instance_templ->SetAccessor(v8_str("f"), ParentGetter); // Template that inherits from the parent template. - Local<v8::FunctionTemplate> child_templ = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> child_templ = v8::FunctionTemplate::New(isolate); Local<ObjectTemplate> child_instance_templ = child_templ->InstanceTemplate(); child_templ->Inherit(parent_templ); @@ -12472,10 +12995,11 @@ static void IsConstructHandler( THREADED_TEST(IsConstructCall) { - v8::HandleScope scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); // Function template with call handler. - Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); templ->SetCallHandler(IsConstructHandler); LocalContext context; @@ -12489,8 +13013,9 @@ THREADED_TEST(IsConstructCall) { THREADED_TEST(ObjectProtoToString) { - v8::HandleScope scope(CcTest::isolate()); - Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); templ->SetClassName(v8_str("MyClass")); LocalContext context; @@ -12751,11 +13276,13 @@ static void ThrowInJSNoCatch(const v8::FunctionCallbackInfo<v8::Value>& args) { // These are locking tests that don't need to be run again // as part of the locking aggregation tests. TEST(NestedLockers) { - v8::Locker locker(CcTest::isolate()); - CHECK(v8::Locker::IsLocked(CcTest::isolate())); + v8::Isolate* isolate = CcTest::isolate(); + v8::Locker locker(isolate); + CHECK(v8::Locker::IsLocked(isolate)); LocalContext env; v8::HandleScope scope(env->GetIsolate()); - Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(ThrowInJS); + Local<v8::FunctionTemplate> fun_templ = + v8::FunctionTemplate::New(isolate, ThrowInJS); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("throw_in_js"), fun); Local<Script> script = v8_compile("(function () {" @@ -12777,7 +13304,7 @@ TEST(NestedLockersNoTryCatch) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); Local<v8::FunctionTemplate> fun_templ = - v8::FunctionTemplate::New(ThrowInJSNoCatch); + v8::FunctionTemplate::New(env->GetIsolate(), ThrowInJSNoCatch); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("throw_in_js"), fun); Local<Script> script = v8_compile("(function () {" @@ -12813,7 +13340,7 @@ THREADED_TEST(LockUnlockLock) { v8::HandleScope scope(CcTest::isolate()); LocalContext env; Local<v8::FunctionTemplate> fun_templ = - v8::FunctionTemplate::New(UnlockForAMoment); + v8::FunctionTemplate::New(CcTest::isolate(), UnlockForAMoment); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("unlock_for_a_moment"), fun); Local<Script> script = v8_compile("(function () {" @@ -12827,7 +13354,7 @@ THREADED_TEST(LockUnlockLock) { v8::HandleScope scope(CcTest::isolate()); LocalContext env; Local<v8::FunctionTemplate> fun_templ = - v8::FunctionTemplate::New(UnlockForAMoment); + v8::FunctionTemplate::New(CcTest::isolate(), UnlockForAMoment); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("unlock_for_a_moment"), fun); Local<Script> script = v8_compile("(function () {" @@ -12868,6 +13395,7 @@ static void CheckSurvivingGlobalObjectsCount(int expected) { TEST(DontLeakGlobalObjects) { // Regression test for issues 1139850 and 1174891. + i::FLAG_expose_gc = true; v8::V8::Initialize(); for (int i = 0; i < 5; i++) { @@ -12915,7 +13443,7 @@ TEST(CopyablePersistent) { CopyableObject handle1; { v8::HandleScope scope(isolate); - handle1.Reset(isolate, v8::Object::New()); + handle1.Reset(isolate, v8::Object::New(isolate)); } CHECK_EQ(initial_handles + 1, globals->global_handles_count()); CopyableObject handle2; @@ -12948,8 +13476,8 @@ TEST(WeakCallbackApi) { int initial_handles = globals->global_handles_count(); { v8::HandleScope scope(isolate); - v8::Local<v8::Object> obj = v8::Object::New(); - obj->Set(v8_str("key"), v8::Integer::New(231, isolate)); + v8::Local<v8::Object> obj = v8::Object::New(isolate); + obj->Set(v8_str("key"), v8::Integer::New(isolate, 231)); v8::Persistent<v8::Object>* handle = new v8::Persistent<v8::Object>(isolate, obj); handle->SetWeak<v8::Object, v8::Persistent<v8::Object> >(handle, @@ -12965,12 +13493,11 @@ TEST(WeakCallbackApi) { v8::Persistent<v8::Object> some_object; v8::Persistent<v8::Object> bad_handle; -void NewPersistentHandleCallback(v8::Isolate* isolate, - v8::Persistent<v8::Value>* handle, - void*) { - v8::HandleScope scope(isolate); - bad_handle.Reset(isolate, some_object); - handle->Dispose(); +void NewPersistentHandleCallback( + const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) { + v8::HandleScope scope(data.GetIsolate()); + bad_handle.Reset(data.GetIsolate(), some_object); + data.GetParameter()->Reset(); } @@ -12981,28 +13508,27 @@ THREADED_TEST(NewPersistentHandleFromWeakCallback) { v8::Persistent<v8::Object> handle1, handle2; { v8::HandleScope scope(isolate); - some_object.Reset(isolate, v8::Object::New()); - handle1.Reset(isolate, v8::Object::New()); - handle2.Reset(isolate, v8::Object::New()); + some_object.Reset(isolate, v8::Object::New(isolate)); + handle1.Reset(isolate, v8::Object::New(isolate)); + handle2.Reset(isolate, v8::Object::New(isolate)); } // Note: order is implementation dependent alas: currently // global handle nodes are processed by PostGarbageCollectionProcessing // in reverse allocation order, so if second allocated handle is deleted, // weak callback of the first handle would be able to 'reallocate' it. - handle1.MakeWeak<v8::Value, void>(NULL, NewPersistentHandleCallback); - handle2.Dispose(); - CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + handle1.SetWeak(&handle1, NewPersistentHandleCallback); + handle2.Reset(); + CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); } v8::Persistent<v8::Object> to_be_disposed; -void DisposeAndForceGcCallback(v8::Isolate* isolate, - v8::Persistent<v8::Value>* handle, - void*) { - to_be_disposed.Dispose(); +void DisposeAndForceGcCallback( + const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) { + to_be_disposed.Reset(); CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); - handle->Dispose(); + data.GetParameter()->Reset(); } @@ -13013,26 +13539,25 @@ THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { v8::Persistent<v8::Object> handle1, handle2; { v8::HandleScope scope(isolate); - handle1.Reset(isolate, v8::Object::New()); - handle2.Reset(isolate, v8::Object::New()); + handle1.Reset(isolate, v8::Object::New(isolate)); + handle2.Reset(isolate, v8::Object::New(isolate)); } - handle1.MakeWeak<v8::Value, void>(NULL, DisposeAndForceGcCallback); + handle1.SetWeak(&handle1, DisposeAndForceGcCallback); to_be_disposed.Reset(isolate, handle2); - CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); } -void DisposingCallback(v8::Isolate* isolate, - v8::Persistent<v8::Value>* handle, - void*) { - handle->Dispose(); +void DisposingCallback( + const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) { + data.GetParameter()->Reset(); } -void HandleCreatingCallback(v8::Isolate* isolate, - v8::Persistent<v8::Value>* handle, - void*) { - v8::HandleScope scope(isolate); - v8::Persistent<v8::Object>(isolate, v8::Object::New()); - handle->Dispose(); +void HandleCreatingCallback( + const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) { + v8::HandleScope scope(data.GetIsolate()); + v8::Persistent<v8::Object>(data.GetIsolate(), + v8::Object::New(data.GetIsolate())); + data.GetParameter()->Reset(); } @@ -13043,13 +13568,13 @@ THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { v8::Persistent<v8::Object> handle1, handle2, handle3; { v8::HandleScope scope(isolate); - handle3.Reset(isolate, v8::Object::New()); - handle2.Reset(isolate, v8::Object::New()); - handle1.Reset(isolate, v8::Object::New()); + handle3.Reset(isolate, v8::Object::New(isolate)); + handle2.Reset(isolate, v8::Object::New(isolate)); + handle1.Reset(isolate, v8::Object::New(isolate)); } - handle2.MakeWeak<v8::Value, void>(NULL, DisposingCallback); - handle3.MakeWeak<v8::Value, void>(NULL, HandleCreatingCallback); - CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + handle2.SetWeak(&handle2, DisposingCallback); + handle3.SetWeak(&handle3, HandleCreatingCallback); + CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); } @@ -13077,10 +13602,10 @@ THREADED_TEST(CheckForCrossContextObjectLiterals) { static v8::Handle<Value> NestedScope(v8::Local<Context> env) { - v8::HandleScope inner(env->GetIsolate()); + v8::EscapableHandleScope inner(env->GetIsolate()); env->Enter(); - v8::Handle<Value> three = v8_num(3); - v8::Handle<Value> value = inner.Close(three); + v8::Local<Value> three = v8_num(3); + v8::Local<Value> value = inner.Escape(three); env->Exit(); return value; } @@ -13337,8 +13862,8 @@ void SetFunctionEntryHookTest::RunLoopInNewEnv(v8::Isolate* isolate) { v8::Local<Context> env = Context::New(isolate); env->Enter(); - Local<ObjectTemplate> t = ObjectTemplate::New(); - t->Set(v8_str("asdf"), v8::FunctionTemplate::New(RuntimeCallback)); + Local<ObjectTemplate> t = ObjectTemplate::New(isolate); + t->Set(v8_str("asdf"), v8::FunctionTemplate::New(isolate, RuntimeCallback)); env->Global()->Set(v8_str("obj"), t->NewInstance()); const char* script = @@ -13683,20 +14208,17 @@ UNINITIALIZED_TEST(SetJitCodeEventHandler) { } -static int64_t cast(intptr_t x) { return static_cast<int64_t>(x); } - - THREADED_TEST(ExternalAllocatedMemory) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope outer(isolate); v8::Local<Context> env(Context::New(isolate)); CHECK(!env.IsEmpty()); - const intptr_t kSize = 1024*1024; - int64_t baseline = cast(isolate->AdjustAmountOfExternalAllocatedMemory(0)); - CHECK_EQ(baseline + cast(kSize), - cast(isolate->AdjustAmountOfExternalAllocatedMemory(kSize))); + const int64_t kSize = 1024*1024; + int64_t baseline = isolate->AdjustAmountOfExternalAllocatedMemory(0); + CHECK_EQ(baseline + kSize, + isolate->AdjustAmountOfExternalAllocatedMemory(kSize)); CHECK_EQ(baseline, - cast(isolate->AdjustAmountOfExternalAllocatedMemory(-kSize))); + isolate->AdjustAmountOfExternalAllocatedMemory(-kSize)); } @@ -13709,10 +14231,10 @@ THREADED_TEST(Regress54) { v8::HandleScope outer(isolate); static v8::Persistent<v8::ObjectTemplate> templ; if (templ.IsEmpty()) { - v8::HandleScope inner(isolate); - v8::Handle<v8::ObjectTemplate> local = v8::ObjectTemplate::New(); + v8::EscapableHandleScope inner(isolate); + v8::Local<v8::ObjectTemplate> local = v8::ObjectTemplate::New(isolate); local->SetInternalFieldCount(1); - templ.Reset(isolate, inner.Close(local)); + templ.Reset(isolate, inner.Escape(local)); } v8::Handle<v8::Object> result = v8::Local<v8::ObjectTemplate>::New(isolate, templ)->NewInstance(); @@ -13726,7 +14248,8 @@ TEST(CatchStackOverflow) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); v8::TryCatch try_catch; - v8::Handle<v8::Script> script = v8::Script::Compile(v8::String::New( + v8::Handle<v8::Script> script = v8::Script::Compile(v8::String::NewFromUtf8( + context->GetIsolate(), "function f() {" " return f();" "}" @@ -13762,7 +14285,8 @@ static void CheckTryCatchSourceInfo(v8::Handle<v8::Script> script, THREADED_TEST(TryCatchSourceInfo) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::String> source = v8::String::New( + v8::Handle<v8::String> source = v8::String::NewFromUtf8( + context->GetIsolate(), "function Foo() {\n" " return Bar();\n" "}\n" @@ -13780,16 +14304,20 @@ THREADED_TEST(TryCatchSourceInfo) { const char* resource_name; v8::Handle<v8::Script> script; resource_name = "test.js"; - script = v8::Script::Compile(source, v8::String::New(resource_name)); + script = v8::Script::Compile( + source, v8::String::NewFromUtf8(context->GetIsolate(), resource_name)); CheckTryCatchSourceInfo(script, resource_name, 0); resource_name = "test1.js"; - v8::ScriptOrigin origin1(v8::String::New(resource_name)); + v8::ScriptOrigin origin1( + v8::String::NewFromUtf8(context->GetIsolate(), resource_name)); script = v8::Script::Compile(source, &origin1); CheckTryCatchSourceInfo(script, resource_name, 0); resource_name = "test2.js"; - v8::ScriptOrigin origin2(v8::String::New(resource_name), v8::Integer::New(7)); + v8::ScriptOrigin origin2( + v8::String::NewFromUtf8(context->GetIsolate(), resource_name), + v8::Integer::New(context->GetIsolate(), 7)); script = v8::Script::Compile(source, &origin2); CheckTryCatchSourceInfo(script, resource_name, 7); } @@ -13798,12 +14326,14 @@ THREADED_TEST(TryCatchSourceInfo) { THREADED_TEST(CompilationCache) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::String> source0 = v8::String::New("1234"); - v8::Handle<v8::String> source1 = v8::String::New("1234"); - v8::Handle<v8::Script> script0 = - v8::Script::Compile(source0, v8::String::New("test.js")); - v8::Handle<v8::Script> script1 = - v8::Script::Compile(source1, v8::String::New("test.js")); + v8::Handle<v8::String> source0 = + v8::String::NewFromUtf8(context->GetIsolate(), "1234"); + v8::Handle<v8::String> source1 = + v8::String::NewFromUtf8(context->GetIsolate(), "1234"); + v8::Handle<v8::Script> script0 = v8::Script::Compile( + source0, v8::String::NewFromUtf8(context->GetIsolate(), "test.js")); + v8::Handle<v8::Script> script1 = v8::Script::Compile( + source1, v8::String::NewFromUtf8(context->GetIsolate(), "test.js")); v8::Handle<v8::Script> script2 = v8::Script::Compile(source0); // different origin CHECK_EQ(1234, script0->Run()->Int32Value()); @@ -13821,9 +14351,11 @@ static void FunctionNameCallback( THREADED_TEST(CallbackFunctionName) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Local<ObjectTemplate> t = ObjectTemplate::New(); - t->Set(v8_str("asdf"), v8::FunctionTemplate::New(FunctionNameCallback)); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> t = ObjectTemplate::New(isolate); + t->Set(v8_str("asdf"), + v8::FunctionTemplate::New(isolate, FunctionNameCallback)); context->Global()->Set(v8_str("obj"), t->NewInstance()); v8::Handle<v8::Value> value = CompileRun("obj.asdf.name"); CHECK(value->IsString()); @@ -13835,31 +14367,36 @@ THREADED_TEST(CallbackFunctionName) { THREADED_TEST(DateAccess) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::Value> date = v8::Date::New(1224744689038.0); + v8::Handle<v8::Value> date = + v8::Date::New(context->GetIsolate(), 1224744689038.0); CHECK(date->IsDate()); CHECK_EQ(1224744689038.0, date.As<v8::Date>()->ValueOf()); } -void CheckProperties(v8::Handle<v8::Value> val, int elmc, const char* elmv[]) { +void CheckProperties(v8::Isolate* isolate, + v8::Handle<v8::Value> val, + int elmc, + const char* elmv[]) { v8::Handle<v8::Object> obj = val.As<v8::Object>(); v8::Handle<v8::Array> props = obj->GetPropertyNames(); CHECK_EQ(elmc, props->Length()); for (int i = 0; i < elmc; i++) { - v8::String::Utf8Value elm(props->Get(v8::Integer::New(i))); + v8::String::Utf8Value elm(props->Get(v8::Integer::New(isolate, i))); CHECK_EQ(elmv[i], *elm); } } -void CheckOwnProperties(v8::Handle<v8::Value> val, +void CheckOwnProperties(v8::Isolate* isolate, + v8::Handle<v8::Value> val, int elmc, const char* elmv[]) { v8::Handle<v8::Object> obj = val.As<v8::Object>(); v8::Handle<v8::Array> props = obj->GetOwnPropertyNames(); CHECK_EQ(elmc, props->Length()); for (int i = 0; i < elmc; i++) { - v8::String::Utf8Value elm(props->Get(v8::Integer::New(i))); + v8::String::Utf8Value elm(props->Get(v8::Integer::New(isolate, i))); CHECK_EQ(elmv[i], *elm); } } @@ -13867,8 +14404,10 @@ void CheckOwnProperties(v8::Handle<v8::Value> val, THREADED_TEST(PropertyEnumeration) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New( + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::NewFromUtf8( + context->GetIsolate(), "var result = [];" "result[0] = {};" "result[1] = {a: 1, b: 2};" @@ -13881,29 +14420,39 @@ THREADED_TEST(PropertyEnumeration) { CHECK_EQ(4, elms->Length()); int elmc0 = 0; const char** elmv0 = NULL; - CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0); - CheckOwnProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0); + CheckProperties( + isolate, elms->Get(v8::Integer::New(isolate, 0)), elmc0, elmv0); + CheckOwnProperties( + isolate, elms->Get(v8::Integer::New(isolate, 0)), elmc0, elmv0); int elmc1 = 2; const char* elmv1[] = {"a", "b"}; - CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1); - CheckOwnProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1); + CheckProperties( + isolate, elms->Get(v8::Integer::New(isolate, 1)), elmc1, elmv1); + CheckOwnProperties( + isolate, elms->Get(v8::Integer::New(isolate, 1)), elmc1, elmv1); int elmc2 = 3; const char* elmv2[] = {"0", "1", "2"}; - CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); - CheckOwnProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); + CheckProperties( + isolate, elms->Get(v8::Integer::New(isolate, 2)), elmc2, elmv2); + CheckOwnProperties( + isolate, elms->Get(v8::Integer::New(isolate, 2)), elmc2, elmv2); int elmc3 = 4; const char* elmv3[] = {"w", "z", "x", "y"}; - CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); + CheckProperties( + isolate, elms->Get(v8::Integer::New(isolate, 3)), elmc3, elmv3); int elmc4 = 2; const char* elmv4[] = {"w", "z"}; - CheckOwnProperties(elms->Get(v8::Integer::New(3)), elmc4, elmv4); + CheckOwnProperties( + isolate, elms->Get(v8::Integer::New(isolate, 3)), elmc4, elmv4); } THREADED_TEST(PropertyEnumeration2) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New( + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::NewFromUtf8( + context->GetIsolate(), "var result = [];" "result[0] = {};" "result[1] = {a: 1, b: 2};" @@ -13916,9 +14465,10 @@ THREADED_TEST(PropertyEnumeration2) { CHECK_EQ(4, elms->Length()); int elmc0 = 0; const char** elmv0 = NULL; - CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0); + CheckProperties(isolate, + elms->Get(v8::Integer::New(isolate, 0)), elmc0, elmv0); - v8::Handle<v8::Value> val = elms->Get(v8::Integer::New(0)); + v8::Handle<v8::Value> val = elms->Get(v8::Integer::New(isolate, 0)); v8::Handle<v8::Array> props = val.As<v8::Object>()->GetPropertyNames(); CHECK_EQ(0, props->Length()); for (uint32_t i = 0; i < props->Length(); i++) { @@ -13946,7 +14496,7 @@ THREADED_TEST(DisableAccessChecksWhileConfiguring) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessCheckCallbacks(NamedSetAccessBlocker, IndexedSetAccessBlocker); templ->Set(v8_str("x"), v8::True(isolate)); @@ -13976,8 +14526,9 @@ static bool IndexedGetAccessBlocker(Local<v8::Object> obj, THREADED_TEST(AccessChecksReenabledCorrectly) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessCheckCallbacks(NamedGetAccessBlocker, IndexedGetAccessBlocker); templ->Set(v8_str("a"), v8_str("a")); @@ -13992,7 +14543,7 @@ THREADED_TEST(AccessChecksReenabledCorrectly) { for (char k = '0'; k <= '9'; k++) { buf[2] = k; buf[3] = 0; - templ->Set(v8_str(buf), v8::Number::New(k)); + templ->Set(v8_str(buf), v8::Number::New(isolate, k)); } } } @@ -14016,7 +14567,8 @@ THREADED_TEST(AccessChecksReenabledCorrectly) { THREADED_TEST(AccessControlRepeatedContextCreation) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallbacks(NamedSetAccessBlocker, IndexedSetAccessBlocker); i::Handle<i::ObjectTemplateInfo> internal_template = @@ -14037,7 +14589,8 @@ THREADED_TEST(TurnOnAccessCheck) { // Create an environment with access check to the global object disabled by // default. - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallbacks(NamedGetAccessBlocker, IndexedGetAccessBlocker, v8::Handle<v8::Value>(), @@ -14081,8 +14634,10 @@ THREADED_TEST(TurnOnAccessCheck) { } // Detach the global and turn on access check. + Local<Object> hidden_global = Local<Object>::Cast( + context->Global()->GetPrototype()); context->DetachGlobal(); - context->Global()->TurnOnAccessCheck(); + hidden_global->TurnOnAccessCheck(); // Failing access check to property get results in undefined. CHECK(f1->Call(global, 0, NULL)->IsUndefined()); @@ -14119,7 +14674,8 @@ THREADED_TEST(TurnOnAccessCheckAndRecompile) { // Create an environment with access check to the global object disabled by // default. When the registered access checker will block access to properties // a and h. - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallbacks(NamedGetAccessBlockAandH, IndexedGetAccessBlocker, v8::Handle<v8::Value>(), @@ -14166,8 +14722,10 @@ THREADED_TEST(TurnOnAccessCheckAndRecompile) { // Detach the global and turn on access check now blocking access to property // a and function h. + Local<Object> hidden_global = Local<Object>::Cast( + context->Global()->GetPrototype()); context->DetachGlobal(); - context->Global()->TurnOnAccessCheck(); + hidden_global->TurnOnAccessCheck(); // Failing access check to property get results in undefined. CHECK(f1->Call(global, 0, NULL)->IsUndefined()); @@ -14183,11 +14741,11 @@ THREADED_TEST(TurnOnAccessCheckAndRecompile) { // Now compile the source again. And get the newly compiled functions, except // for h for which access is blocked. CompileRun(source); - f1 = Local<Function>::Cast(context->Global()->Get(v8_str("f1"))); - f2 = Local<Function>::Cast(context->Global()->Get(v8_str("f2"))); - g1 = Local<Function>::Cast(context->Global()->Get(v8_str("g1"))); - g2 = Local<Function>::Cast(context->Global()->Get(v8_str("g2"))); - CHECK(context->Global()->Get(v8_str("h"))->IsUndefined()); + f1 = Local<Function>::Cast(hidden_global->Get(v8_str("f1"))); + f2 = Local<Function>::Cast(hidden_global->Get(v8_str("f2"))); + g1 = Local<Function>::Cast(hidden_global->Get(v8_str("g1"))); + g2 = Local<Function>::Cast(hidden_global->Get(v8_str("g2"))); + CHECK(hidden_global->Get(v8_str("h"))->IsUndefined()); // Failing access check to property get results in undefined. CHECK(f1->Call(global, 0, NULL)->IsUndefined()); @@ -14207,9 +14765,10 @@ TEST(PreCompile) { // a workaround for now to make this test not fail. v8::V8::Initialize(); v8::Isolate* isolate = CcTest::isolate(); + HandleScope handle_scope(isolate); const char* script = "function foo(a) { return a+1; }"; - v8::ScriptData* sd = - v8::ScriptData::PreCompile(isolate, script, i::StrLength(script)); + v8::ScriptData* sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( + isolate, script, v8::String::kNormalString, i::StrLength(script))); CHECK_NE(sd->Length(), 0); CHECK_NE(sd->Data(), NULL); CHECK(!sd->HasError()); @@ -14220,9 +14779,10 @@ TEST(PreCompile) { TEST(PreCompileWithError) { v8::V8::Initialize(); v8::Isolate* isolate = CcTest::isolate(); + HandleScope handle_scope(isolate); const char* script = "function foo(a) { return 1 * * 2; }"; - v8::ScriptData* sd = - v8::ScriptData::PreCompile(isolate, script, i::StrLength(script)); + v8::ScriptData* sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( + isolate, script, v8::String::kNormalString, i::StrLength(script))); CHECK(sd->HasError()); delete sd; } @@ -14231,9 +14791,10 @@ TEST(PreCompileWithError) { TEST(Regress31661) { v8::V8::Initialize(); v8::Isolate* isolate = CcTest::isolate(); + HandleScope handle_scope(isolate); const char* script = " The Definintive Guide"; - v8::ScriptData* sd = - v8::ScriptData::PreCompile(isolate, script, i::StrLength(script)); + v8::ScriptData* sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( + isolate, script, v8::String::kNormalString, i::StrLength(script))); CHECK(sd->HasError()); delete sd; } @@ -14243,9 +14804,10 @@ TEST(Regress31661) { TEST(PreCompileSerialization) { v8::V8::Initialize(); v8::Isolate* isolate = CcTest::isolate(); + HandleScope handle_scope(isolate); const char* script = "function foo(a) { return a+1; }"; - v8::ScriptData* sd = - v8::ScriptData::PreCompile(isolate, script, i::StrLength(script)); + v8::ScriptData* sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( + isolate, script, v8::String::kNormalString, i::StrLength(script))); // Serialize. int serialized_data_length = sd->Length(); @@ -14263,6 +14825,7 @@ TEST(PreCompileSerialization) { delete sd; delete deserialized_sd; + i::DeleteArray(serialized_data); } @@ -14288,8 +14851,8 @@ TEST(PreCompileInvalidPreparseDataError) { const char* script = "function foo(){ return 5;}\n" "function bar(){ return 6 + 7;} foo();"; - v8::ScriptData* sd = - v8::ScriptData::PreCompile(isolate, script, i::StrLength(script)); + v8::ScriptData* sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( + isolate, script, v8::String::kNormalString, i::StrLength(script))); CHECK(!sd->HasError()); // ScriptDataImpl private implementation details const int kHeaderSize = i::PreparseDataConstants::kHeaderSize; @@ -14303,7 +14866,7 @@ TEST(PreCompileInvalidPreparseDataError) { sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryEndOffset] = 0; v8::TryCatch try_catch; - Local<String> source = String::New(script); + Local<String> source = String::NewFromUtf8(isolate, script); Local<Script> compiled_script = Script::New(source, NULL, sd); CHECK(try_catch.HasCaught()); String::Utf8Value exception_value(try_catch.Message()->Get()); @@ -14311,11 +14874,13 @@ TEST(PreCompileInvalidPreparseDataError) { *exception_value); try_catch.Reset(); + delete sd; // Overwrite function bar's start position with 200. The function entry // will not be found when searching for it by position and we should fall // back on eager compilation. - sd = v8::ScriptData::PreCompile(isolate, script, i::StrLength(script)); + sd = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( + isolate, script, v8::String::kNormalString, i::StrLength(script))); sd_data = reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data())); sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryStartOffset] = 200; @@ -14326,42 +14891,6 @@ TEST(PreCompileInvalidPreparseDataError) { } -// Verifies that the Handle<String> and const char* versions of the API produce -// the same results (at least for one trivial case). -TEST(PreCompileAPIVariationsAreSame) { - v8::V8::Initialize(); - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - - const char* cstring = "function foo(a) { return a+1; }"; - - v8::ScriptData* sd_from_cstring = - v8::ScriptData::PreCompile(isolate, cstring, i::StrLength(cstring)); - - TestAsciiResource* resource = new TestAsciiResource(cstring); - v8::ScriptData* sd_from_external_string = v8::ScriptData::PreCompile( - v8::String::NewExternal(resource)); - - v8::ScriptData* sd_from_string = v8::ScriptData::PreCompile( - v8::String::New(cstring)); - - CHECK_EQ(sd_from_cstring->Length(), sd_from_external_string->Length()); - CHECK_EQ(0, memcmp(sd_from_cstring->Data(), - sd_from_external_string->Data(), - sd_from_cstring->Length())); - - CHECK_EQ(sd_from_cstring->Length(), sd_from_string->Length()); - CHECK_EQ(0, memcmp(sd_from_cstring->Data(), - sd_from_string->Data(), - sd_from_cstring->Length())); - - - delete sd_from_cstring; - delete sd_from_external_string; - delete sd_from_string; -} - - // This tests that we do not allow dictionary load/call inline caches // to use functions that have not yet been compiled. The potential // problem of loading a function that has not yet been compiled can @@ -14416,120 +14945,11 @@ THREADED_TEST(CrossContextNew) { } -class ApplyInterruptTest { - public: - ApplyInterruptTest() : block_(0) {} - ~ApplyInterruptTest() {} - void RunTest() { - gc_count_ = 0; - gc_during_apply_ = 0; - apply_success_ = false; - gc_success_ = false; - GCThread gc_thread(this); - gc_thread.Start(); - v8::Isolate* isolate = CcTest::isolate(); - v8::Locker::StartPreemption(isolate, 1); - - LongRunningApply(); - { - v8::Unlocker unlock(isolate); - gc_thread.Join(); - } - v8::Locker::StopPreemption(isolate); - CHECK(apply_success_); - CHECK(gc_success_); - } - - private: - // Number of garbage collections required. - static const int kRequiredGCs = 2; - - class GCThread : public i::Thread { - public: - explicit GCThread(ApplyInterruptTest* test) - : Thread("GCThread"), test_(test) {} - virtual void Run() { - test_->CollectGarbage(); - } - private: - ApplyInterruptTest* test_; - }; - - void CollectGarbage() { - block_.Wait(); - while (gc_during_apply_ < kRequiredGCs) { - { - v8::Locker lock(CcTest::isolate()); - v8::Isolate::Scope isolate_scope(CcTest::isolate()); - CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); - gc_count_++; - } - i::OS::Sleep(1); - } - gc_success_ = true; - } - - void LongRunningApply() { - block_.Signal(); - int rounds = 0; - while (gc_during_apply_ < kRequiredGCs) { - int gc_before = gc_count_; - { - const char* c_source = - "function do_very_little(bar) {" - " this.foo = bar;" - "}" - "for (var i = 0; i < 100000; i++) {" - " do_very_little.apply(this, ['bar']);" - "}"; - Local<String> source = String::New(c_source); - Local<Script> script = Script::Compile(source); - Local<Value> result = script->Run(); - // Check that no exception was thrown. - CHECK(!result.IsEmpty()); - } - int gc_after = gc_count_; - gc_during_apply_ += gc_after - gc_before; - rounds++; - } - apply_success_ = true; - } - - i::Semaphore block_; - int gc_count_; - int gc_during_apply_; - bool apply_success_; - bool gc_success_; -}; - - -// Test that nothing bad happens if we get a preemption just when we were -// about to do an apply(). -TEST(ApplyInterruption) { - v8::Locker lock(CcTest::isolate()); - v8::V8::Initialize(); - v8::HandleScope scope(CcTest::isolate()); - Local<Context> local_env; - { - LocalContext env; - local_env = env.local(); - } - - // Local context should still be live. - CHECK(!local_env.IsEmpty()); - local_env->Enter(); - - // Should complete without problems. - ApplyInterruptTest().RunTest(); - - local_env->Exit(); -} - - // Verify that we can clone an object TEST(ObjectClone) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); const char* sample = "var rv = {};" \ @@ -14544,19 +14964,19 @@ TEST(ObjectClone) { obj->Set(v8_str("gamma"), v8_str("cloneme")); CHECK_EQ(v8_str("hello"), obj->Get(v8_str("alpha"))); - CHECK_EQ(v8::Integer::New(123), obj->Get(v8_str("beta"))); + CHECK_EQ(v8::Integer::New(isolate, 123), obj->Get(v8_str("beta"))); CHECK_EQ(v8_str("cloneme"), obj->Get(v8_str("gamma"))); // Clone it. Local<v8::Object> clone = obj->Clone(); CHECK_EQ(v8_str("hello"), clone->Get(v8_str("alpha"))); - CHECK_EQ(v8::Integer::New(123), clone->Get(v8_str("beta"))); + CHECK_EQ(v8::Integer::New(isolate, 123), clone->Get(v8_str("beta"))); CHECK_EQ(v8_str("cloneme"), clone->Get(v8_str("gamma"))); // Set a property on the clone, verify each object. - clone->Set(v8_str("beta"), v8::Integer::New(456)); - CHECK_EQ(v8::Integer::New(123), obj->Get(v8_str("beta"))); - CHECK_EQ(v8::Integer::New(456), clone->Get(v8_str("beta"))); + clone->Set(v8_str("beta"), v8::Integer::New(isolate, 456)); + CHECK_EQ(v8::Integer::New(isolate, 123), obj->Get(v8_str("beta"))); + CHECK_EQ(v8::Integer::New(isolate, 456), clone->Get(v8_str("beta"))); } @@ -14668,11 +15088,11 @@ THREADED_TEST(MorphCompositeStringTest) { const char* expected_slice_on_cons = "ow is the time for all good men to come to the aid of the party" "Now is the time for all good men to come to the aid of the part"; - CHECK_EQ(String::New(expected_cons), + CHECK_EQ(String::NewFromUtf8(env->GetIsolate(), expected_cons), env->Global()->Get(v8_str("cons"))); - CHECK_EQ(String::New(expected_slice), + CHECK_EQ(String::NewFromUtf8(env->GetIsolate(), expected_slice), env->Global()->Get(v8_str("slice"))); - CHECK_EQ(String::New(expected_slice_on_cons), + CHECK_EQ(String::NewFromUtf8(env->GetIsolate(), expected_slice_on_cons), env->Global()->Get(v8_str("slice_on_cons"))); } i::DeleteArray(two_byte_string); @@ -14695,12 +15115,10 @@ TEST(CompileExternalTwoByteSource) { // Compile the sources as external two byte strings. for (int i = 0; ascii_sources[i] != NULL; i++) { uint16_t* two_byte_string = AsciiToTwoByteString(ascii_sources[i]); - UC16VectorResource uc16_resource( - i::Vector<const uint16_t>(two_byte_string, - i::StrLength(ascii_sources[i]))); - v8::Local<v8::String> source = v8::String::NewExternal(&uc16_resource); + TestResource* uc16_resource = new TestResource(two_byte_string); + v8::Local<v8::String> source = + v8::String::NewExternal(context->GetIsolate(), uc16_resource); v8::Script::Compile(source); - i::DeleteArray(two_byte_string); } } @@ -14772,8 +15190,8 @@ TEST(RegExpInterruption) { timeout_thread.Join(); - delete regexp_interruption_data.string_resource; - regexp_interruption_data.string.Dispose(); + regexp_interruption_data.string.Reset(); + i::DeleteArray(uc16_content); } #endif // V8_INTERPRETED_REGEXP @@ -14783,24 +15201,25 @@ TEST(RegExpInterruption) { // is a read-only property in the prototype chain. TEST(ReadOnlyPropertyInGlobalProto) { i::FLAG_es5_readonly = true; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); LocalContext context(0, templ); v8::Handle<v8::Object> global = context->Global(); v8::Handle<v8::Object> global_proto = v8::Handle<v8::Object>::Cast(global->Get(v8_str("__proto__"))); - global_proto->Set(v8_str("x"), v8::Integer::New(0), v8::ReadOnly); - global_proto->Set(v8_str("y"), v8::Integer::New(0), v8::ReadOnly); + global_proto->Set(v8_str("x"), v8::Integer::New(isolate, 0), v8::ReadOnly); + global_proto->Set(v8_str("y"), v8::Integer::New(isolate, 0), v8::ReadOnly); // Check without 'eval' or 'with'. v8::Handle<v8::Value> res = CompileRun("function f() { x = 42; return x; }; f()"); - CHECK_EQ(v8::Integer::New(0), res); + CHECK_EQ(v8::Integer::New(isolate, 0), res); // Check with 'eval'. res = CompileRun("function f() { eval('1'); y = 43; return y; }; f()"); - CHECK_EQ(v8::Integer::New(0), res); + CHECK_EQ(v8::Integer::New(isolate, 0), res); // Check with 'with'. res = CompileRun("function f() { with (this) { y = 44 }; return y; }; f()"); - CHECK_EQ(v8::Integer::New(0), res); + CHECK_EQ(v8::Integer::New(isolate, 0), res); } static int force_set_set_count = 0; @@ -14836,22 +15255,25 @@ TEST(ForceSet) { force_set_set_count = 0; pass_on_get = false; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); - v8::Handle<v8::String> access_property = v8::String::New("a"); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); + v8::Handle<v8::String> access_property = + v8::String::NewFromUtf8(isolate, "a"); templ->SetAccessor(access_property, ForceSetGetter, ForceSetSetter); LocalContext context(NULL, templ); v8::Handle<v8::Object> global = context->Global(); // Ordinary properties - v8::Handle<v8::String> simple_property = v8::String::New("p"); - global->Set(simple_property, v8::Int32::New(4), v8::ReadOnly); + v8::Handle<v8::String> simple_property = + v8::String::NewFromUtf8(isolate, "p"); + global->Set(simple_property, v8::Int32::New(isolate, 4), v8::ReadOnly); CHECK_EQ(4, global->Get(simple_property)->Int32Value()); // This should fail because the property is read-only - global->Set(simple_property, v8::Int32::New(5)); + global->Set(simple_property, v8::Int32::New(isolate, 5)); CHECK_EQ(4, global->Get(simple_property)->Int32Value()); // This should succeed even though the property is read-only - global->ForceSet(simple_property, v8::Int32::New(6)); + global->ForceSet(simple_property, v8::Int32::New(isolate, 6)); CHECK_EQ(6, global->Get(simple_property)->Int32Value()); // Accessors @@ -14860,13 +15282,13 @@ TEST(ForceSet) { CHECK_EQ(3, global->Get(access_property)->Int32Value()); // CHECK_EQ the property shouldn't override it, just call the setter // which in this case does nothing. - global->Set(access_property, v8::Int32::New(7)); + global->Set(access_property, v8::Int32::New(isolate, 7)); CHECK_EQ(3, global->Get(access_property)->Int32Value()); CHECK_EQ(1, force_set_set_count); CHECK_EQ(2, force_set_get_count); // Forcing the property to be set should override the accessor without // calling it - global->ForceSet(access_property, v8::Int32::New(8)); + global->ForceSet(access_property, v8::Int32::New(isolate, 8)); CHECK_EQ(8, global->Get(access_property)->Int32Value()); CHECK_EQ(1, force_set_set_count); CHECK_EQ(2, force_set_get_count); @@ -14878,19 +15300,21 @@ TEST(ForceSetWithInterceptor) { force_set_set_count = 0; pass_on_get = false; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(ForceSetGetter, ForceSetInterceptSetter); LocalContext context(NULL, templ); v8::Handle<v8::Object> global = context->Global(); - v8::Handle<v8::String> some_property = v8::String::New("a"); + v8::Handle<v8::String> some_property = + v8::String::NewFromUtf8(isolate, "a"); CHECK_EQ(0, force_set_set_count); CHECK_EQ(0, force_set_get_count); CHECK_EQ(3, global->Get(some_property)->Int32Value()); // Setting the property shouldn't override it, just call the setter // which in this case does nothing. - global->Set(some_property, v8::Int32::New(7)); + global->Set(some_property, v8::Int32::New(isolate, 7)); CHECK_EQ(3, global->Get(some_property)->Int32Value()); CHECK_EQ(1, force_set_set_count); CHECK_EQ(2, force_set_get_count); @@ -14903,7 +15327,7 @@ TEST(ForceSetWithInterceptor) { CHECK_EQ(3, force_set_get_count); // Forcing the property to be set should cause the value to be // set locally without calling the interceptor. - global->ForceSet(some_property, v8::Int32::New(8)); + global->ForceSet(some_property, v8::Int32::New(isolate, 8)); CHECK_EQ(8, global->Get(some_property)->Int32Value()); CHECK_EQ(1, force_set_set_count); CHECK_EQ(4, force_set_get_count); @@ -14914,21 +15338,24 @@ TEST(ForceSetWithInterceptor) { CHECK_EQ(1, force_set_set_count); CHECK_EQ(5, force_set_get_count); // The interceptor should also work for other properties - CHECK_EQ(3, global->Get(v8::String::New("b"))->Int32Value()); + CHECK_EQ(3, global->Get(v8::String::NewFromUtf8(isolate, "b")) + ->Int32Value()); CHECK_EQ(1, force_set_set_count); CHECK_EQ(6, force_set_get_count); } THREADED_TEST(ForceDelete) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); LocalContext context(NULL, templ); v8::Handle<v8::Object> global = context->Global(); // Ordinary properties - v8::Handle<v8::String> simple_property = v8::String::New("p"); - global->Set(simple_property, v8::Int32::New(4), v8::DontDelete); + v8::Handle<v8::String> simple_property = + v8::String::NewFromUtf8(isolate, "p"); + global->Set(simple_property, v8::Int32::New(isolate, 4), v8::DontDelete); CHECK_EQ(4, global->Get(simple_property)->Int32Value()); // This should fail because the property is dont-delete. CHECK(!global->Delete(simple_property)); @@ -14956,14 +15383,16 @@ THREADED_TEST(ForceDeleteWithInterceptor) { force_delete_interceptor_count = 0; pass_on_delete = false; - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(0, 0, 0, ForceDeleteDeleter); LocalContext context(NULL, templ); v8::Handle<v8::Object> global = context->Global(); - v8::Handle<v8::String> some_property = v8::String::New("a"); - global->Set(some_property, v8::Integer::New(42), v8::DontDelete); + v8::Handle<v8::String> some_property = + v8::String::NewFromUtf8(isolate, "a"); + global->Set(some_property, v8::Integer::New(isolate, 42), v8::DontDelete); // Deleting a property should get intercepted and nothing should // happen. @@ -15028,7 +15457,8 @@ TEST(InlinedFunctionAcrossContexts) { "f();"); CHECK_EQ(42, res->Int32Value()); ctx2->Exit(); - v8::Handle<v8::String> G_property = v8::String::New("G"); + v8::Handle<v8::String> G_property = + v8::String::NewFromUtf8(CcTest::isolate(), "G"); CHECK(ctx1->Global()->ForceDelete(G_property)); ctx2->Enter(); ExpectString( @@ -15096,7 +15526,7 @@ THREADED_TEST(GetCallingContext) { // Create an object with a C++ callback in context0. calling_context0->Enter(); Local<v8::FunctionTemplate> callback_templ = - v8::FunctionTemplate::New(GetCallingContextCallback); + v8::FunctionTemplate::New(isolate, GetCallingContextCallback); calling_context0->Global()->Set(v8_str("callback"), callback_templ->GetFunction()); calling_context0->Exit(); @@ -15143,34 +15573,21 @@ THREADED_TEST(InitGlobalVarInProtoChain) { // See http://code.google.com/p/v8/issues/detail?id=398 THREADED_TEST(ReplaceConstantFunction) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::Object> obj = v8::Object::New(); - v8::Handle<v8::FunctionTemplate> func_templ = v8::FunctionTemplate::New(); - v8::Handle<v8::String> foo_string = v8::String::New("foo"); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::Object> obj = v8::Object::New(isolate); + v8::Handle<v8::FunctionTemplate> func_templ = + v8::FunctionTemplate::New(isolate); + v8::Handle<v8::String> foo_string = + v8::String::NewFromUtf8(isolate, "foo"); obj->Set(foo_string, func_templ->GetFunction()); v8::Handle<v8::Object> obj_clone = obj->Clone(); - obj_clone->Set(foo_string, v8::String::New("Hello")); + obj_clone->Set(foo_string, + v8::String::NewFromUtf8(isolate, "Hello")); CHECK(!obj->Get(foo_string)->IsUndefined()); } -// Regression test for http://crbug.com/16276. -THREADED_TEST(Regress16276) { - LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - // Force the IC in f to be a dictionary load IC. - CompileRun("function f(obj) { return obj.x; }\n" - "var obj = { x: { foo: 42 }, y: 87 };\n" - "var x = obj.x;\n" - "delete obj.y;\n" - "for (var i = 0; i < 5; i++) f(obj);"); - // Detach the global object to make 'this' refer directly to the - // global object (not the proxy), and make sure that the dictionary - // load IC doesn't mess up loading directly from the global object. - context->DetachGlobal(); - CHECK_EQ(42, CompileRun("f(this).foo")->Int32Value()); -} - static void CheckElementValue(i::Isolate* isolate, int expected, i::Handle<i::Object> obj, @@ -15187,10 +15604,10 @@ THREADED_TEST(PixelArray) { v8::HandleScope scope(context->GetIsolate()); const int kElementCount = 260; uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); - i::Handle<i::ExternalPixelArray> pixels = - i::Handle<i::ExternalPixelArray>::cast( + i::Handle<i::ExternalUint8ClampedArray> pixels = + i::Handle<i::ExternalUint8ClampedArray>::cast( factory->NewExternalArray(kElementCount, - v8::kExternalPixelArray, + v8::kExternalUint8ClampedArray, pixel_data)); // Force GC to trigger verification. CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); @@ -15204,13 +15621,13 @@ THREADED_TEST(PixelArray) { CHECK_EQ(i % 256, pixel_data[i]); } - v8::Handle<v8::Object> obj = v8::Object::New(); + v8::Handle<v8::Object> obj = v8::Object::New(context->GetIsolate()); i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); // Set the elements to be the pixels. // jsobj->set_elements(*pixels); obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); CheckElementValue(isolate, 1, jsobj, 1); - obj->Set(v8_str("field"), v8::Int32::New(1503)); + obj->Set(v8_str("field"), v8::Int32::New(CcTest::isolate(), 1503)); context->Global()->Set(v8_str("pixels"), obj); v8::Handle<v8::Value> result = CompileRun("pixels.field"); CHECK_EQ(1503, result->Int32Value()); @@ -15569,7 +15986,7 @@ THREADED_TEST(PixelArrayInfo) { v8::HandleScope scope(context->GetIsolate()); for (int size = 0; size < 100; size += 10) { uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(size)); - v8::Handle<v8::Object> obj = v8::Object::New(); + v8::Handle<v8::Object> obj = v8::Object::New(context->GetIsolate()); obj->SetIndexedPropertiesToPixelData(pixel_data, size); CHECK(obj->HasIndexedPropertiesInPixelData()); CHECK_EQ(pixel_data, obj->GetIndexedPropertiesPixelData()); @@ -15597,18 +16014,20 @@ static void NotHandledIndexedPropertySetter( THREADED_TEST(PixelArrayWithInterceptor) { LocalContext context; i::Factory* factory = CcTest::i_isolate()->factory(); - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); const int kElementCount = 260; uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); - i::Handle<i::ExternalPixelArray> pixels = - i::Handle<i::ExternalPixelArray>::cast( + i::Handle<i::ExternalUint8ClampedArray> pixels = + i::Handle<i::ExternalUint8ClampedArray>::cast( factory->NewExternalArray(kElementCount, - v8::kExternalPixelArray, + v8::kExternalUint8ClampedArray, pixel_data)); for (int i = 0; i < kElementCount; i++) { pixels->set(i, i % 256); } - v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> templ = + v8::ObjectTemplate::New(context->GetIsolate()); templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter, NotHandledIndexedPropertySetter); v8::Handle<v8::Object> obj = templ->NewInstance(); @@ -15630,21 +16049,21 @@ THREADED_TEST(PixelArrayWithInterceptor) { static int ExternalArrayElementSize(v8::ExternalArrayType array_type) { switch (array_type) { - case v8::kExternalByteArray: - case v8::kExternalUnsignedByteArray: - case v8::kExternalPixelArray: + case v8::kExternalInt8Array: + case v8::kExternalUint8Array: + case v8::kExternalUint8ClampedArray: return 1; break; - case v8::kExternalShortArray: - case v8::kExternalUnsignedShortArray: + case v8::kExternalInt16Array: + case v8::kExternalUint16Array: return 2; break; - case v8::kExternalIntArray: - case v8::kExternalUnsignedIntArray: - case v8::kExternalFloatArray: + case v8::kExternalInt32Array: + case v8::kExternalUint32Array: + case v8::kExternalFloat32Array: return 4; break; - case v8::kExternalDoubleArray: + case v8::kExternalFloat64Array: return 8; break; default: @@ -15665,21 +16084,14 @@ static void ObjectWithExternalArrayTestHelper( int64_t low, int64_t high) { i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); i::Isolate* isolate = jsobj->GetIsolate(); - obj->Set(v8_str("field"), v8::Int32::New(1503)); + obj->Set(v8_str("field"), + v8::Int32::New(reinterpret_cast<v8::Isolate*>(isolate), 1503)); context->Global()->Set(v8_str("ext_array"), obj); v8::Handle<v8::Value> result = CompileRun("ext_array.field"); CHECK_EQ(1503, result->Int32Value()); result = CompileRun("ext_array[1]"); CHECK_EQ(1, result->Int32Value()); - // Check pass through of assigned smis - result = CompileRun("var sum = 0;" - "for (var i = 0; i < 8; i++) {" - " sum += ext_array[i] = ext_array[i] = -i;" - "}" - "sum;"); - CHECK_EQ(-28, result->Int32Value()); - // Check assigned smis result = CompileRun("for (var i = 0; i < 8; i++) {" " ext_array[i] = i;" @@ -15689,7 +16101,16 @@ static void ObjectWithExternalArrayTestHelper( " sum += ext_array[i];" "}" "sum;"); + CHECK_EQ(28, result->Int32Value()); + // Check pass through of assigned smis + result = CompileRun("var sum = 0;" + "for (var i = 0; i < 8; i++) {" + " sum += ext_array[i] = ext_array[i] = -i;" + "}" + "sum;"); + CHECK_EQ(-28, result->Int32Value()); + // Check assigned smis in reverse order result = CompileRun("for (var i = 8; --i >= 0; ) {" @@ -15804,8 +16225,8 @@ static void ObjectWithExternalArrayTestHelper( "}" "ext_array[7];"); CHECK_EQ(0, result->Int32Value()); - if (array_type == v8::kExternalDoubleArray || - array_type == v8::kExternalFloatArray) { + if (array_type == v8::kExternalFloat64Array || + array_type == v8::kExternalFloat32Array) { CHECK_EQ(static_cast<int>(i::OS::nan_value()), static_cast<int>( jsobj->GetElement(isolate, 7)->ToObjectChecked()->Number())); @@ -15822,8 +16243,8 @@ static void ObjectWithExternalArrayTestHelper( static_cast<int>( jsobj->GetElement(isolate, 6)->ToObjectChecked()->Number())); - if (array_type != v8::kExternalFloatArray && - array_type != v8::kExternalDoubleArray) { + if (array_type != v8::kExternalFloat32Array && + array_type != v8::kExternalFloat64Array) { // Though the specification doesn't state it, be explicit about // converting NaNs and +/-Infinity to zero. result = CompileRun("for (var i = 0; i < 8; i++) {" @@ -15844,7 +16265,7 @@ static void ObjectWithExternalArrayTestHelper( "}" "ext_array[5];"); int expected_value = - (array_type == v8::kExternalPixelArray) ? 255 : 0; + (array_type == v8::kExternalUint8ClampedArray) ? 255 : 0; CHECK_EQ(expected_value, result->Int32Value()); CheckElementValue(isolate, expected_value, jsobj, 5); @@ -15869,10 +16290,10 @@ static void ObjectWithExternalArrayTestHelper( "var source_data = [0.6, 10.6];" "var expected_results = [1, 11];"; bool is_unsigned = - (array_type == v8::kExternalUnsignedByteArray || - array_type == v8::kExternalUnsignedShortArray || - array_type == v8::kExternalUnsignedIntArray); - bool is_pixel_data = array_type == v8::kExternalPixelArray; + (array_type == v8::kExternalUint8Array || + array_type == v8::kExternalUint16Array || + array_type == v8::kExternalUint32Array); + bool is_pixel_data = array_type == v8::kExternalUint8ClampedArray; i::OS::SNPrintF(test_buf, "%s" @@ -15957,6 +16378,113 @@ static void ObjectWithExternalArrayTestHelper( } +template <class FixedTypedArrayClass, + i::ElementsKind elements_kind, + class ElementType> +static void FixedTypedArrayTestHelper( + v8::ExternalArrayType array_type, + ElementType low, + ElementType high) { + i::FLAG_allow_natives_syntax = true; + LocalContext context; + i::Isolate* isolate = CcTest::i_isolate(); + i::Factory* factory = isolate->factory(); + v8::HandleScope scope(context->GetIsolate()); + const int kElementCount = 260; + i::Handle<FixedTypedArrayClass> fixed_array = + i::Handle<FixedTypedArrayClass>::cast( + factory->NewFixedTypedArray(kElementCount, array_type)); + CHECK_EQ(FixedTypedArrayClass::kInstanceType, + fixed_array->map()->instance_type()); + CHECK_EQ(kElementCount, fixed_array->length()); + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + for (int i = 0; i < kElementCount; i++) { + fixed_array->set(i, static_cast<ElementType>(i)); + } + // Force GC to trigger verification. + CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); + for (int i = 0; i < kElementCount; i++) { + CHECK_EQ(static_cast<int64_t>(static_cast<ElementType>(i)), + static_cast<int64_t>(fixed_array->get_scalar(i))); + } + v8::Handle<v8::Object> obj = v8::Object::New(CcTest::isolate()); + i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); + i::Handle<i::Map> fixed_array_map = + isolate->factory()->GetElementsTransitionMap(jsobj, elements_kind); + jsobj->set_map(*fixed_array_map); + jsobj->set_elements(*fixed_array); + + ObjectWithExternalArrayTestHelper<FixedTypedArrayClass, ElementType>( + context.local(), obj, kElementCount, array_type, + static_cast<int64_t>(low), + static_cast<int64_t>(high)); +} + + +THREADED_TEST(FixedUint8Array) { + FixedTypedArrayTestHelper<i::FixedUint8Array, i::UINT8_ELEMENTS, uint8_t>( + v8::kExternalUint8Array, + 0x0, 0xFF); +} + + +THREADED_TEST(FixedUint8ClampedArray) { + FixedTypedArrayTestHelper<i::FixedUint8ClampedArray, + i::UINT8_CLAMPED_ELEMENTS, uint8_t>( + v8::kExternalUint8ClampedArray, + 0x0, 0xFF); +} + + +THREADED_TEST(FixedInt8Array) { + FixedTypedArrayTestHelper<i::FixedInt8Array, i::INT8_ELEMENTS, int8_t>( + v8::kExternalInt8Array, + -0x80, 0x7F); +} + + +THREADED_TEST(FixedUint16Array) { + FixedTypedArrayTestHelper<i::FixedUint16Array, i::UINT16_ELEMENTS, uint16_t>( + v8::kExternalUint16Array, + 0x0, 0xFFFF); +} + + +THREADED_TEST(FixedInt16Array) { + FixedTypedArrayTestHelper<i::FixedInt16Array, i::INT16_ELEMENTS, int16_t>( + v8::kExternalInt16Array, + -0x8000, 0x7FFF); +} + + +THREADED_TEST(FixedUint32Array) { + FixedTypedArrayTestHelper<i::FixedUint32Array, i::UINT32_ELEMENTS, uint32_t>( + v8::kExternalUint32Array, + 0x0, UINT_MAX); +} + + +THREADED_TEST(FixedInt32Array) { + FixedTypedArrayTestHelper<i::FixedInt32Array, i::INT32_ELEMENTS, int32_t>( + v8::kExternalInt32Array, + INT_MIN, INT_MAX); +} + + +THREADED_TEST(FixedFloat32Array) { + FixedTypedArrayTestHelper<i::FixedFloat32Array, i::FLOAT32_ELEMENTS, float>( + v8::kExternalFloat32Array, + -500, 500); +} + + +THREADED_TEST(FixedFloat64Array) { + FixedTypedArrayTestHelper<i::FixedFloat64Array, i::FLOAT64_ELEMENTS, float>( + v8::kExternalFloat64Array, + -500, 500); +} + + template <class ExternalArrayClass, class ElementType> static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, int64_t low, @@ -15985,7 +16513,7 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); } - v8::Handle<v8::Object> obj = v8::Object::New(); + v8::Handle<v8::Object> obj = v8::Object::New(context->GetIsolate()); i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); // Set the elements to be the external array. obj->SetIndexedPropertiesToExternalArrayData(array_data, @@ -16010,7 +16538,7 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, const int kLargeElementCount = kXSize * kYSize * 4; ElementType* large_array_data = static_cast<ElementType*>(malloc(kLargeElementCount * element_size)); - v8::Handle<v8::Object> large_obj = v8::Object::New(); + v8::Handle<v8::Object> large_obj = v8::Object::New(context->GetIsolate()); // Set the elements to be the external array. large_obj->SetIndexedPropertiesToExternalArrayData(large_array_data, array_type, @@ -16083,9 +16611,10 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, // Property "" set after the external array is associated with the object. { - v8::Handle<v8::Object> obj2 = v8::Object::New(); - obj2->Set(v8_str("ee_test_field"), v8::Int32::New(256)); - obj2->Set(v8_str(""), v8::Int32::New(1503)); + v8::Handle<v8::Object> obj2 = v8::Object::New(context->GetIsolate()); + obj2->Set(v8_str("ee_test_field"), + v8::Int32::New(context->GetIsolate(), 256)); + obj2->Set(v8_str(""), v8::Int32::New(context->GetIsolate(), 1503)); // Set the elements to be the external array. obj2->SetIndexedPropertiesToExternalArrayData(array_data, array_type, @@ -16097,13 +16626,14 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, // Property "" set after the external array is associated with the object. { - v8::Handle<v8::Object> obj2 = v8::Object::New(); - obj2->Set(v8_str("ee_test_field_2"), v8::Int32::New(256)); + v8::Handle<v8::Object> obj2 = v8::Object::New(context->GetIsolate()); + obj2->Set(v8_str("ee_test_field_2"), + v8::Int32::New(context->GetIsolate(), 256)); // Set the elements to be the external array. obj2->SetIndexedPropertiesToExternalArrayData(array_data, array_type, kElementCount); - obj2->Set(v8_str(""), v8::Int32::New(1503)); + obj2->Set(v8_str(""), v8::Int32::New(context->GetIsolate(), 1503)); context->Global()->Set(v8_str("ext_array"), obj2); result = CompileRun("ext_array['']"); CHECK_EQ(1503, result->Int32Value()); @@ -16111,8 +16641,9 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, // Should reuse the map from previous test. { - v8::Handle<v8::Object> obj2 = v8::Object::New(); - obj2->Set(v8_str("ee_test_field_2"), v8::Int32::New(256)); + v8::Handle<v8::Object> obj2 = v8::Object::New(context->GetIsolate()); + obj2->Set(v8_str("ee_test_field_2"), + v8::Int32::New(context->GetIsolate(), 256)); // Set the elements to be the external array. Should re-use the map // from previous test. obj2->SetIndexedPropertiesToExternalArrayData(array_data, @@ -16125,9 +16656,10 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, // Property "" is a constant function that shouldn't not be interfered with // when an external array is set. { - v8::Handle<v8::Object> obj2 = v8::Object::New(); + v8::Handle<v8::Object> obj2 = v8::Object::New(context->GetIsolate()); // Start - obj2->Set(v8_str("ee_test_field3"), v8::Int32::New(256)); + obj2->Set(v8_str("ee_test_field3"), + v8::Int32::New(context->GetIsolate(), 256)); // Add a constant function to an object. context->Global()->Set(v8_str("ext_array"), obj2); @@ -16136,8 +16668,9 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, // Add an external array transition to the same map that // has the constant transition. - v8::Handle<v8::Object> obj3 = v8::Object::New(); - obj3->Set(v8_str("ee_test_field3"), v8::Int32::New(256)); + v8::Handle<v8::Object> obj3 = v8::Object::New(context->GetIsolate()); + obj3->Set(v8_str("ee_test_field3"), + v8::Int32::New(context->GetIsolate(), 256)); obj3->SetIndexedPropertiesToExternalArrayData(array_data, array_type, kElementCount); @@ -16148,16 +16681,18 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, // by a constant function. { // Add an external array transition. - v8::Handle<v8::Object> obj3 = v8::Object::New(); - obj3->Set(v8_str("ee_test_field4"), v8::Int32::New(256)); + v8::Handle<v8::Object> obj3 = v8::Object::New(context->GetIsolate()); + obj3->Set(v8_str("ee_test_field4"), + v8::Int32::New(context->GetIsolate(), 256)); obj3->SetIndexedPropertiesToExternalArrayData(array_data, array_type, kElementCount); // Add a constant function to the same map that just got an external array // transition. - v8::Handle<v8::Object> obj2 = v8::Object::New(); - obj2->Set(v8_str("ee_test_field4"), v8::Int32::New(256)); + v8::Handle<v8::Object> obj2 = v8::Object::New(context->GetIsolate()); + obj2->Set(v8_str("ee_test_field4"), + v8::Int32::New(context->GetIsolate(), 256)); context->Global()->Set(v8_str("ext_array"), obj2); result = CompileRun("ext_array[''] = function() {return 1503;};" "ext_array['']();"); @@ -16167,86 +16702,86 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, } -THREADED_TEST(ExternalByteArray) { - ExternalArrayTestHelper<i::ExternalByteArray, int8_t>( - v8::kExternalByteArray, +THREADED_TEST(ExternalInt8Array) { + ExternalArrayTestHelper<i::ExternalInt8Array, int8_t>( + v8::kExternalInt8Array, -128, 127); } -THREADED_TEST(ExternalUnsignedByteArray) { - ExternalArrayTestHelper<i::ExternalUnsignedByteArray, uint8_t>( - v8::kExternalUnsignedByteArray, +THREADED_TEST(ExternalUint8Array) { + ExternalArrayTestHelper<i::ExternalUint8Array, uint8_t>( + v8::kExternalUint8Array, 0, 255); } -THREADED_TEST(ExternalPixelArray) { - ExternalArrayTestHelper<i::ExternalPixelArray, uint8_t>( - v8::kExternalPixelArray, +THREADED_TEST(ExternalUint8ClampedArray) { + ExternalArrayTestHelper<i::ExternalUint8ClampedArray, uint8_t>( + v8::kExternalUint8ClampedArray, 0, 255); } -THREADED_TEST(ExternalShortArray) { - ExternalArrayTestHelper<i::ExternalShortArray, int16_t>( - v8::kExternalShortArray, +THREADED_TEST(ExternalInt16Array) { + ExternalArrayTestHelper<i::ExternalInt16Array, int16_t>( + v8::kExternalInt16Array, -32768, 32767); } -THREADED_TEST(ExternalUnsignedShortArray) { - ExternalArrayTestHelper<i::ExternalUnsignedShortArray, uint16_t>( - v8::kExternalUnsignedShortArray, +THREADED_TEST(ExternalUint16Array) { + ExternalArrayTestHelper<i::ExternalUint16Array, uint16_t>( + v8::kExternalUint16Array, 0, 65535); } -THREADED_TEST(ExternalIntArray) { - ExternalArrayTestHelper<i::ExternalIntArray, int32_t>( - v8::kExternalIntArray, +THREADED_TEST(ExternalInt32Array) { + ExternalArrayTestHelper<i::ExternalInt32Array, int32_t>( + v8::kExternalInt32Array, INT_MIN, // -2147483648 INT_MAX); // 2147483647 } -THREADED_TEST(ExternalUnsignedIntArray) { - ExternalArrayTestHelper<i::ExternalUnsignedIntArray, uint32_t>( - v8::kExternalUnsignedIntArray, +THREADED_TEST(ExternalUint32Array) { + ExternalArrayTestHelper<i::ExternalUint32Array, uint32_t>( + v8::kExternalUint32Array, 0, UINT_MAX); // 4294967295 } -THREADED_TEST(ExternalFloatArray) { - ExternalArrayTestHelper<i::ExternalFloatArray, float>( - v8::kExternalFloatArray, +THREADED_TEST(ExternalFloat32Array) { + ExternalArrayTestHelper<i::ExternalFloat32Array, float>( + v8::kExternalFloat32Array, -500, 500); } -THREADED_TEST(ExternalDoubleArray) { - ExternalArrayTestHelper<i::ExternalDoubleArray, double>( - v8::kExternalDoubleArray, +THREADED_TEST(ExternalFloat64Array) { + ExternalArrayTestHelper<i::ExternalFloat64Array, double>( + v8::kExternalFloat64Array, -500, 500); } THREADED_TEST(ExternalArrays) { - TestExternalByteArray(); - TestExternalUnsignedByteArray(); - TestExternalShortArray(); - TestExternalUnsignedShortArray(); - TestExternalIntArray(); - TestExternalUnsignedIntArray(); - TestExternalFloatArray(); + TestExternalInt8Array(); + TestExternalUint8Array(); + TestExternalInt16Array(); + TestExternalUint16Array(); + TestExternalInt32Array(); + TestExternalUint32Array(); + TestExternalFloat32Array(); } @@ -16256,7 +16791,7 @@ void ExternalArrayInfoTestHelper(v8::ExternalArrayType array_type) { for (int size = 0; size < 100; size += 10) { int element_size = ExternalArrayElementSize(array_type); void* external_data = malloc(size * element_size); - v8::Handle<v8::Object> obj = v8::Object::New(); + v8::Handle<v8::Object> obj = v8::Object::New(context->GetIsolate()); obj->SetIndexedPropertiesToExternalArrayData( external_data, array_type, size); CHECK(obj->HasIndexedPropertiesInExternalArrayData()); @@ -16269,20 +16804,22 @@ void ExternalArrayInfoTestHelper(v8::ExternalArrayType array_type) { THREADED_TEST(ExternalArrayInfo) { - ExternalArrayInfoTestHelper(v8::kExternalByteArray); - ExternalArrayInfoTestHelper(v8::kExternalUnsignedByteArray); - ExternalArrayInfoTestHelper(v8::kExternalShortArray); - ExternalArrayInfoTestHelper(v8::kExternalUnsignedShortArray); - ExternalArrayInfoTestHelper(v8::kExternalIntArray); - ExternalArrayInfoTestHelper(v8::kExternalUnsignedIntArray); - ExternalArrayInfoTestHelper(v8::kExternalFloatArray); - ExternalArrayInfoTestHelper(v8::kExternalDoubleArray); - ExternalArrayInfoTestHelper(v8::kExternalPixelArray); -} - - -void ExternalArrayLimitTestHelper(v8::ExternalArrayType array_type, int size) { - v8::Handle<v8::Object> obj = v8::Object::New(); + ExternalArrayInfoTestHelper(v8::kExternalInt8Array); + ExternalArrayInfoTestHelper(v8::kExternalUint8Array); + ExternalArrayInfoTestHelper(v8::kExternalInt16Array); + ExternalArrayInfoTestHelper(v8::kExternalUint16Array); + ExternalArrayInfoTestHelper(v8::kExternalInt32Array); + ExternalArrayInfoTestHelper(v8::kExternalUint32Array); + ExternalArrayInfoTestHelper(v8::kExternalFloat32Array); + ExternalArrayInfoTestHelper(v8::kExternalFloat64Array); + ExternalArrayInfoTestHelper(v8::kExternalUint8ClampedArray); +} + + +void ExtArrayLimitsHelper(v8::Isolate* isolate, + v8::ExternalArrayType array_type, + int size) { + v8::Handle<v8::Object> obj = v8::Object::New(isolate); v8::V8::SetFatalErrorHandler(StoringErrorCallback); last_location = last_message = NULL; obj->SetIndexedPropertiesToExternalArrayData(NULL, array_type, size); @@ -16294,25 +16831,26 @@ void ExternalArrayLimitTestHelper(v8::ExternalArrayType array_type, int size) { TEST(ExternalArrayLimits) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - ExternalArrayLimitTestHelper(v8::kExternalByteArray, 0x40000000); - ExternalArrayLimitTestHelper(v8::kExternalByteArray, 0xffffffff); - ExternalArrayLimitTestHelper(v8::kExternalUnsignedByteArray, 0x40000000); - ExternalArrayLimitTestHelper(v8::kExternalUnsignedByteArray, 0xffffffff); - ExternalArrayLimitTestHelper(v8::kExternalShortArray, 0x40000000); - ExternalArrayLimitTestHelper(v8::kExternalShortArray, 0xffffffff); - ExternalArrayLimitTestHelper(v8::kExternalUnsignedShortArray, 0x40000000); - ExternalArrayLimitTestHelper(v8::kExternalUnsignedShortArray, 0xffffffff); - ExternalArrayLimitTestHelper(v8::kExternalIntArray, 0x40000000); - ExternalArrayLimitTestHelper(v8::kExternalIntArray, 0xffffffff); - ExternalArrayLimitTestHelper(v8::kExternalUnsignedIntArray, 0x40000000); - ExternalArrayLimitTestHelper(v8::kExternalUnsignedIntArray, 0xffffffff); - ExternalArrayLimitTestHelper(v8::kExternalFloatArray, 0x40000000); - ExternalArrayLimitTestHelper(v8::kExternalFloatArray, 0xffffffff); - ExternalArrayLimitTestHelper(v8::kExternalDoubleArray, 0x40000000); - ExternalArrayLimitTestHelper(v8::kExternalDoubleArray, 0xffffffff); - ExternalArrayLimitTestHelper(v8::kExternalPixelArray, 0x40000000); - ExternalArrayLimitTestHelper(v8::kExternalPixelArray, 0xffffffff); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + ExtArrayLimitsHelper(isolate, v8::kExternalInt8Array, 0x40000000); + ExtArrayLimitsHelper(isolate, v8::kExternalInt8Array, 0xffffffff); + ExtArrayLimitsHelper(isolate, v8::kExternalUint8Array, 0x40000000); + ExtArrayLimitsHelper(isolate, v8::kExternalUint8Array, 0xffffffff); + ExtArrayLimitsHelper(isolate, v8::kExternalInt16Array, 0x40000000); + ExtArrayLimitsHelper(isolate, v8::kExternalInt16Array, 0xffffffff); + ExtArrayLimitsHelper(isolate, v8::kExternalUint16Array, 0x40000000); + ExtArrayLimitsHelper(isolate, v8::kExternalUint16Array, 0xffffffff); + ExtArrayLimitsHelper(isolate, v8::kExternalInt32Array, 0x40000000); + ExtArrayLimitsHelper(isolate, v8::kExternalInt32Array, 0xffffffff); + ExtArrayLimitsHelper(isolate, v8::kExternalUint32Array, 0x40000000); + ExtArrayLimitsHelper(isolate, v8::kExternalUint32Array, 0xffffffff); + ExtArrayLimitsHelper(isolate, v8::kExternalFloat32Array, 0x40000000); + ExtArrayLimitsHelper(isolate, v8::kExternalFloat32Array, 0xffffffff); + ExtArrayLimitsHelper(isolate, v8::kExternalFloat64Array, 0x40000000); + ExtArrayLimitsHelper(isolate, v8::kExternalFloat64Array, 0xffffffff); + ExtArrayLimitsHelper(isolate, v8::kExternalUint8ClampedArray, 0x40000000); + ExtArrayLimitsHelper(isolate, v8::kExternalUint8ClampedArray, 0xffffffff); } @@ -16328,8 +16866,9 @@ void TypedArrayTestHelper(v8::ExternalArrayType array_type, v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope handle_scope(isolate); - Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New( - backing_store.start(), (kElementCount+2)*sizeof(ElementType)); + Local<v8::ArrayBuffer> ab = + v8::ArrayBuffer::New(isolate, backing_store.start(), + (kElementCount + 2) * sizeof(ElementType)); Local<TypedArray> ta = TypedArray::New(ab, 2*sizeof(ElementType), kElementCount); CheckInternalFieldsAreZero<v8::ArrayBufferView>(ta); @@ -16350,58 +16889,59 @@ void TypedArrayTestHelper(v8::ExternalArrayType array_type, THREADED_TEST(Uint8Array) { - TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUnsignedByteArray>( - v8::kExternalUnsignedByteArray, 0, 0xFF); + TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUint8Array>( + v8::kExternalUint8Array, 0, 0xFF); } THREADED_TEST(Int8Array) { - TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalByteArray>( - v8::kExternalByteArray, -0x80, 0x7F); + TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalInt8Array>( + v8::kExternalInt8Array, -0x80, 0x7F); } THREADED_TEST(Uint16Array) { TypedArrayTestHelper<uint16_t, v8::Uint16Array, - i::ExternalUnsignedShortArray>( - v8::kExternalUnsignedShortArray, 0, 0xFFFF); + i::ExternalUint16Array>( + v8::kExternalUint16Array, 0, 0xFFFF); } THREADED_TEST(Int16Array) { - TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalShortArray>( - v8::kExternalShortArray, -0x8000, 0x7FFF); + TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalInt16Array>( + v8::kExternalInt16Array, -0x8000, 0x7FFF); } THREADED_TEST(Uint32Array) { - TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUnsignedIntArray>( - v8::kExternalUnsignedIntArray, 0, UINT_MAX); + TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUint32Array>( + v8::kExternalUint32Array, 0, UINT_MAX); } THREADED_TEST(Int32Array) { - TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalIntArray>( - v8::kExternalIntArray, INT_MIN, INT_MAX); + TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalInt32Array>( + v8::kExternalInt32Array, INT_MIN, INT_MAX); } THREADED_TEST(Float32Array) { - TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloatArray>( - v8::kExternalFloatArray, -500, 500); + TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloat32Array>( + v8::kExternalFloat32Array, -500, 500); } THREADED_TEST(Float64Array) { - TypedArrayTestHelper<double, v8::Float64Array, i::ExternalDoubleArray>( - v8::kExternalDoubleArray, -500, 500); + TypedArrayTestHelper<double, v8::Float64Array, i::ExternalFloat64Array>( + v8::kExternalFloat64Array, -500, 500); } THREADED_TEST(Uint8ClampedArray) { - TypedArrayTestHelper<uint8_t, v8::Uint8ClampedArray, i::ExternalPixelArray>( - v8::kExternalPixelArray, 0, 0xFF); + TypedArrayTestHelper<uint8_t, + v8::Uint8ClampedArray, i::ExternalUint8ClampedArray>( + v8::kExternalUint8ClampedArray, 0, 0xFF); } @@ -16414,8 +16954,8 @@ THREADED_TEST(DataView) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope handle_scope(isolate); - Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New( - backing_store.start(), 2 + kSize); + Local<v8::ArrayBuffer> ab = + v8::ArrayBuffer::New(isolate, backing_store.start(), 2 + kSize); Local<v8::DataView> dv = v8::DataView::New(ab, 2, kSize); CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv); @@ -16458,13 +16998,17 @@ THREADED_TEST(ScriptContextDependence) { LocalContext c1; v8::HandleScope scope(c1->GetIsolate()); const char *source = "foo"; - v8::Handle<v8::Script> dep = v8::Script::Compile(v8::String::New(source)); - v8::Handle<v8::Script> indep = v8::Script::New(v8::String::New(source)); - c1->Global()->Set(v8::String::New("foo"), v8::Integer::New(100)); + v8::Handle<v8::Script> dep = + v8::Script::Compile(v8::String::NewFromUtf8(c1->GetIsolate(), source)); + v8::Handle<v8::Script> indep = + v8::Script::New(v8::String::NewFromUtf8(c1->GetIsolate(), source)); + c1->Global()->Set(v8::String::NewFromUtf8(c1->GetIsolate(), "foo"), + v8::Integer::New(c1->GetIsolate(), 100)); CHECK_EQ(dep->Run()->Int32Value(), 100); CHECK_EQ(indep->Run()->Int32Value(), 100); LocalContext c2; - c2->Global()->Set(v8::String::New("foo"), v8::Integer::New(101)); + c2->Global()->Set(v8::String::NewFromUtf8(c2->GetIsolate(), "foo"), + v8::Integer::New(c2->GetIsolate(), 101)); CHECK_EQ(dep->Run()->Int32Value(), 100); CHECK_EQ(indep->Run()->Int32Value(), 101); } @@ -16475,8 +17019,10 @@ THREADED_TEST(StackTrace) { v8::HandleScope scope(context->GetIsolate()); v8::TryCatch try_catch; const char *source = "function foo() { FAIL.FAIL; }; foo();"; - v8::Handle<v8::String> src = v8::String::New(source); - v8::Handle<v8::String> origin = v8::String::New("stack-trace-test"); + v8::Handle<v8::String> src = + v8::String::NewFromUtf8(context->GetIsolate(), source); + v8::Handle<v8::String> origin = + v8::String::NewFromUtf8(context->GetIsolate(), "stack-trace-test"); v8::Script::New(src, origin)->Run(); CHECK(try_catch.HasCaught()); v8::String::Utf8Value stack(try_catch.StackTrace()); @@ -16516,8 +17062,8 @@ void AnalyzeStackInNativeCode(const v8::FunctionCallbackInfo<v8::Value>& args) { int testGroup = args[0]->Int32Value(); if (testGroup == kOverviewTest) { - v8::Handle<v8::StackTrace> stackTrace = - v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kOverview); + v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + args.GetIsolate(), 10, v8::StackTrace::kOverview); CHECK_EQ(4, stackTrace->GetFrameCount()); checkStackFrame(origin, "bar", 2, 10, false, false, stackTrace->GetFrame(0)); @@ -16532,8 +17078,8 @@ void AnalyzeStackInNativeCode(const v8::FunctionCallbackInfo<v8::Value>& args) { CHECK(stackTrace->AsArray()->IsArray()); } else if (testGroup == kDetailedTest) { - v8::Handle<v8::StackTrace> stackTrace = - v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed); + v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + args.GetIsolate(), 10, v8::StackTrace::kDetailed); CHECK_EQ(4, stackTrace->GetFrameCount()); checkStackFrame(origin, "bat", 4, 22, false, false, stackTrace->GetFrame(0)); @@ -16561,11 +17107,13 @@ void AnalyzeStackInNativeCode(const v8::FunctionCallbackInfo<v8::Value>& args) { // TODO(3074796): Reenable this as a THREADED_TEST once it passes. // THREADED_TEST(CaptureStackTrace) { TEST(CaptureStackTrace) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::String> origin = v8::String::New("capture-stack-trace-test"); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::String> origin = + v8::String::NewFromUtf8(isolate, "capture-stack-trace-test"); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("AnalyzeStackInNativeCode"), - v8::FunctionTemplate::New(AnalyzeStackInNativeCode)); + v8::FunctionTemplate::New(isolate, AnalyzeStackInNativeCode)); LocalContext context(0, templ); // Test getting OVERVIEW information. Should ignore information that is not @@ -16579,7 +17127,8 @@ TEST(CaptureStackTrace) { " bar();\n" "}\n" "var x;eval('new foo();');"; - v8::Handle<v8::String> overview_src = v8::String::New(overview_source); + v8::Handle<v8::String> overview_src = + v8::String::NewFromUtf8(isolate, overview_source); v8::Handle<Value> overview_result( v8::Script::New(overview_src, origin)->Run()); CHECK(!overview_result.IsEmpty()); @@ -16594,10 +17143,11 @@ TEST(CaptureStackTrace) { " bat();\n" "}\n" "eval('new baz();');"; - v8::Handle<v8::String> detailed_src = v8::String::New(detailed_source); + v8::Handle<v8::String> detailed_src = + v8::String::NewFromUtf8(isolate, detailed_source); // Make the script using a non-zero line and column offset. - v8::Handle<v8::Integer> line_offset = v8::Integer::New(3); - v8::Handle<v8::Integer> column_offset = v8::Integer::New(5); + v8::Handle<v8::Integer> line_offset = v8::Integer::New(isolate, 3); + v8::Handle<v8::Integer> column_offset = v8::Integer::New(isolate, 5); v8::ScriptOrigin detailed_origin(origin, line_offset, column_offset); v8::Handle<v8::Script> detailed_script( v8::Script::New(detailed_src, &detailed_origin)); @@ -16796,8 +17346,8 @@ TEST(RethrowBogusErrorStackTrace) { void AnalyzeStackOfEvalWithSourceURL( const v8::FunctionCallbackInfo<v8::Value>& args) { v8::HandleScope scope(args.GetIsolate()); - v8::Handle<v8::StackTrace> stackTrace = - v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed); + v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + args.GetIsolate(), 10, v8::StackTrace::kDetailed); CHECK_EQ(5, stackTrace->GetFrameCount()); v8::Handle<v8::String> url = v8_str("eval_url"); for (int i = 0; i < 3; i++) { @@ -16810,10 +17360,12 @@ void AnalyzeStackOfEvalWithSourceURL( TEST(SourceURLInStackTrace) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("AnalyzeStackOfEvalWithSourceURL"), - v8::FunctionTemplate::New(AnalyzeStackOfEvalWithSourceURL)); + v8::FunctionTemplate::New(isolate, + AnalyzeStackOfEvalWithSourceURL)); LocalContext context(0, templ); const char *source = @@ -16842,8 +17394,8 @@ static int scriptIdInStack[2]; void AnalyzeScriptIdInStack( const v8::FunctionCallbackInfo<v8::Value>& args) { v8::HandleScope scope(args.GetIsolate()); - v8::Handle<v8::StackTrace> stackTrace = - v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kScriptId); + v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + args.GetIsolate(), 10, v8::StackTrace::kScriptId); CHECK_EQ(2, stackTrace->GetFrameCount()); for (int i = 0; i < 2; i++) { scriptIdInStack[i] = stackTrace->GetFrame(i)->GetScriptId(); @@ -16852,18 +17404,21 @@ void AnalyzeScriptIdInStack( TEST(ScriptIdInStackTrace) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("AnalyzeScriptIdInStack"), - v8::FunctionTemplate::New(AnalyzeScriptIdInStack)); + v8::FunctionTemplate::New(isolate, AnalyzeScriptIdInStack)); LocalContext context(0, templ); - v8::Handle<v8::String> scriptSource = v8::String::New( + v8::Handle<v8::String> scriptSource = v8::String::NewFromUtf8( + isolate, "function foo() {\n" " AnalyzeScriptIdInStack();" "}\n" "foo();\n"); - v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); + v8::ScriptOrigin origin = + v8::ScriptOrigin(v8::String::NewFromUtf8(isolate, "test")); v8::Local<v8::Script> script(v8::Script::Compile(scriptSource, &origin)); script->Run(); for (int i = 0; i < 2; i++) { @@ -16876,8 +17431,8 @@ TEST(ScriptIdInStackTrace) { void AnalyzeStackOfInlineScriptWithSourceURL( const v8::FunctionCallbackInfo<v8::Value>& args) { v8::HandleScope scope(args.GetIsolate()); - v8::Handle<v8::StackTrace> stackTrace = - v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed); + v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + args.GetIsolate(), 10, v8::StackTrace::kDetailed); CHECK_EQ(4, stackTrace->GetFrameCount()); v8::Handle<v8::String> url = v8_str("url"); for (int i = 0; i < 3; i++) { @@ -16890,11 +17445,12 @@ void AnalyzeStackOfInlineScriptWithSourceURL( TEST(InlineScriptWithSourceURLInStackTrace) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("AnalyzeStackOfInlineScriptWithSourceURL"), v8::FunctionTemplate::New( - AnalyzeStackOfInlineScriptWithSourceURL)); + CcTest::isolate(), AnalyzeStackOfInlineScriptWithSourceURL)); LocalContext context(0, templ); const char *source = @@ -16921,8 +17477,8 @@ TEST(InlineScriptWithSourceURLInStackTrace) { void AnalyzeStackOfDynamicScriptWithSourceURL( const v8::FunctionCallbackInfo<v8::Value>& args) { v8::HandleScope scope(args.GetIsolate()); - v8::Handle<v8::StackTrace> stackTrace = - v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed); + v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + args.GetIsolate(), 10, v8::StackTrace::kDetailed); CHECK_EQ(4, stackTrace->GetFrameCount()); v8::Handle<v8::String> url = v8_str("source_url"); for (int i = 0; i < 3; i++) { @@ -16935,11 +17491,12 @@ void AnalyzeStackOfDynamicScriptWithSourceURL( TEST(DynamicWithSourceURLInStackTrace) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("AnalyzeStackOfDynamicScriptWithSourceURL"), v8::FunctionTemplate::New( - AnalyzeStackOfDynamicScriptWithSourceURL)); + CcTest::isolate(), AnalyzeStackOfDynamicScriptWithSourceURL)); LocalContext context(0, templ); const char *source = @@ -16963,6 +17520,29 @@ TEST(DynamicWithSourceURLInStackTrace) { } +TEST(DynamicWithSourceURLInStackTraceString) { + LocalContext context; + v8::HandleScope scope(context->GetIsolate()); + + const char *source = + "function outer() {\n" + " function foo() {\n" + " FAIL.FAIL;\n" + " }\n" + " foo();\n" + "}\n" + "outer()\n%s"; + + i::ScopedVector<char> code(1024); + i::OS::SNPrintF(code, source, "//# sourceURL=source_url"); + v8::TryCatch try_catch; + CompileRunWithOrigin(code.start(), "", 0, 0); + CHECK(try_catch.HasCaught()); + v8::String::Utf8Value stack(try_catch.StackTrace()); + CHECK(strstr(*stack, "at foo (source_url:3:5)") != NULL); +} + + static void CreateGarbageInOldSpace() { i::Factory* factory = CcTest::i_isolate()->factory(); v8::HandleScope scope(CcTest::isolate()); @@ -17066,6 +17646,14 @@ TEST(Regress2107) { CHECK_LT(final_size, initial_size + 1); } + +TEST(Regress2333) { + LocalContext env; + for (int i = 0; i < 3; i++) { + CcTest::heap()->CollectGarbage(i::NEW_SPACE); + } +} + static uint32_t* stack_limit; static void GetStackLimitCallback( @@ -17099,13 +17687,13 @@ TEST(SetResourceConstraints) { // Set stack limit. v8::ResourceConstraints constraints; constraints.set_stack_limit(set_limit); - CHECK(v8::SetResourceConstraints(&constraints)); + CHECK(v8::SetResourceConstraints(CcTest::isolate(), &constraints)); // Execute a script. LocalContext env; v8::HandleScope scope(env->GetIsolate()); Local<v8::FunctionTemplate> fun_templ = - v8::FunctionTemplate::New(GetStackLimitCallback); + v8::FunctionTemplate::New(env->GetIsolate(), GetStackLimitCallback); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("get_stack_limit"), fun); CompileRun("get_stack_limit();"); @@ -17123,13 +17711,13 @@ TEST(SetResourceConstraintsInThread) { // Set stack limit. v8::ResourceConstraints constraints; constraints.set_stack_limit(set_limit); - CHECK(v8::SetResourceConstraints(&constraints)); + CHECK(v8::SetResourceConstraints(CcTest::isolate(), &constraints)); // Execute a script. v8::HandleScope scope(CcTest::isolate()); LocalContext env; Local<v8::FunctionTemplate> fun_templ = - v8::FunctionTemplate::New(GetStackLimitCallback); + v8::FunctionTemplate::New(CcTest::isolate(), GetStackLimitCallback); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("get_stack_limit"), fun); CompileRun("get_stack_limit();"); @@ -17191,6 +17779,50 @@ class VisitorImpl : public v8::ExternalResourceVisitor { }; +TEST(ExternalizeOldSpaceTwoByteCons) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::String> cons = + CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString(); + CHECK(v8::Utils::OpenHandle(*cons)->IsConsString()); + CcTest::heap()->CollectAllAvailableGarbage(); + CHECK(CcTest::heap()->old_pointer_space()->Contains( + *v8::Utils::OpenHandle(*cons))); + + TestResource* resource = new TestResource( + AsciiToTwoByteString("Romeo Montague Juliet Capulet")); + cons->MakeExternal(resource); + + CHECK(cons->IsExternal()); + CHECK_EQ(resource, cons->GetExternalStringResource()); + String::Encoding encoding; + CHECK_EQ(resource, cons->GetExternalStringResourceBase(&encoding)); + CHECK_EQ(String::TWO_BYTE_ENCODING, encoding); +} + + +TEST(ExternalizeOldSpaceOneByteCons) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::String> cons = + CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString(); + CHECK(v8::Utils::OpenHandle(*cons)->IsConsString()); + CcTest::heap()->CollectAllAvailableGarbage(); + CHECK(CcTest::heap()->old_pointer_space()->Contains( + *v8::Utils::OpenHandle(*cons))); + + TestAsciiResource* resource = + new TestAsciiResource(i::StrDup("Romeo Montague Juliet Capulet")); + cons->MakeExternal(resource); + + CHECK(cons->IsExternalAscii()); + CHECK_EQ(resource, cons->GetExternalAsciiStringResource()); + String::Encoding encoding; + CHECK_EQ(resource, cons->GetExternalStringResourceBase(&encoding)); + CHECK_EQ(String::ONE_BYTE_ENCODING, encoding); +} + + TEST(VisitExternalStrings) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -17198,18 +17830,22 @@ TEST(VisitExternalStrings) { uint16_t* two_byte_string = AsciiToTwoByteString(string); TestResource* resource[4]; resource[0] = new TestResource(two_byte_string); - v8::Local<v8::String> string0 = v8::String::NewExternal(resource[0]); - resource[1] = new TestResource(two_byte_string); - v8::Local<v8::String> string1 = v8::String::NewExternal(resource[1]); + v8::Local<v8::String> string0 = + v8::String::NewExternal(env->GetIsolate(), resource[0]); + resource[1] = new TestResource(two_byte_string, NULL, false); + v8::Local<v8::String> string1 = + v8::String::NewExternal(env->GetIsolate(), resource[1]); // Externalized symbol. - resource[2] = new TestResource(two_byte_string); - v8::Local<v8::String> string2 = v8::String::NewSymbol(string); + resource[2] = new TestResource(two_byte_string, NULL, false); + v8::Local<v8::String> string2 = v8::String::NewFromUtf8( + env->GetIsolate(), string, v8::String::kInternalizedString); CHECK(string2->MakeExternal(resource[2])); // Symbolized External. resource[3] = new TestResource(AsciiToTwoByteString("Some other string")); - v8::Local<v8::String> string3 = v8::String::NewExternal(resource[3]); + v8::Local<v8::String> string3 = + v8::String::NewExternal(env->GetIsolate(), resource[3]); CcTest::heap()->CollectAllAvailableGarbage(); // Tenure string. // Turn into a symbol. i::Handle<i::String> string3_i = v8::Utils::OpenHandle(*string3); @@ -17228,6 +17864,75 @@ TEST(VisitExternalStrings) { } +TEST(ExternalStringCollectedAtTearDown) { + int destroyed = 0; + v8::Isolate* isolate = v8::Isolate::New(); + { v8::Isolate::Scope isolate_scope(isolate); + v8::HandleScope handle_scope(isolate); + const char* s = "One string to test them all, one string to find them."; + TestAsciiResource* inscription = + new TestAsciiResource(i::StrDup(s), &destroyed); + v8::Local<v8::String> ring = v8::String::NewExternal(isolate, inscription); + // Ring is still alive. Orcs are roaming freely across our lands. + CHECK_EQ(0, destroyed); + USE(ring); + } + + isolate->Dispose(); + // Ring has been destroyed. Free Peoples of Middle-earth Rejoice. + CHECK_EQ(1, destroyed); +} + + +TEST(ExternalInternalizedStringCollectedAtTearDown) { + int destroyed = 0; + v8::Isolate* isolate = v8::Isolate::New(); + { v8::Isolate::Scope isolate_scope(isolate); + LocalContext env(isolate); + v8::HandleScope handle_scope(isolate); + CompileRun("var ring = 'One string to test them all';"); + const char* s = "One string to test them all"; + TestAsciiResource* inscription = + new TestAsciiResource(i::StrDup(s), &destroyed); + v8::Local<v8::String> ring = CompileRun("ring")->ToString(); + CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString()); + ring->MakeExternal(inscription); + // Ring is still alive. Orcs are roaming freely across our lands. + CHECK_EQ(0, destroyed); + USE(ring); + } + + isolate->Dispose(); + // Ring has been destroyed. Free Peoples of Middle-earth Rejoice. + CHECK_EQ(1, destroyed); +} + + +TEST(ExternalInternalizedStringCollectedAtGC) { + int destroyed = 0; + { LocalContext env; + v8::HandleScope handle_scope(env->GetIsolate()); + CompileRun("var ring = 'One string to test them all';"); + const char* s = "One string to test them all"; + TestAsciiResource* inscription = + new TestAsciiResource(i::StrDup(s), &destroyed); + v8::Local<v8::String> ring = CompileRun("ring")->ToString(); + CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString()); + ring->MakeExternal(inscription); + // Ring is still alive. Orcs are roaming freely across our lands. + CHECK_EQ(0, destroyed); + USE(ring); + } + + // Garbage collector deals swift blows to evil. + CcTest::i_isolate()->compilation_cache()->Clear(); + CcTest::heap()->CollectAllAvailableGarbage(); + + // Ring has been destroyed. Free Peoples of Middle-earth Rejoice. + CHECK_EQ(1, destroyed); +} + + static double DoubleFromBits(uint64_t value) { double target; i::OS::MemCopy(&target, &value, sizeof(target)); @@ -17247,7 +17952,7 @@ static double DoubleToDateTime(double input) { if (std::isnan(input) || input < -date_limit || input > date_limit) { return i::OS::nan_value(); } - return (input < 0) ? -(floor(-input)) : floor(input); + return (input < 0) ? -(std::floor(-input)) : std::floor(input); } @@ -17260,7 +17965,8 @@ static double DoubleFromBits(uint32_t high_bits, uint32_t low_bits) { THREADED_TEST(QuietSignalingNaNs) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); v8::TryCatch try_catch; // Special double values. @@ -17304,7 +18010,7 @@ THREADED_TEST(QuietSignalingNaNs) { double test_value = test_values[i]; // Check that Number::New preserves non-NaNs and quiets SNaNs. - v8::Handle<v8::Value> number = v8::Number::New(test_value); + v8::Handle<v8::Value> number = v8::Number::New(isolate, test_value); double stored_number = number->NumberValue(); if (!std::isnan(test_value)) { CHECK_EQ(test_value, stored_number); @@ -17322,7 +18028,8 @@ THREADED_TEST(QuietSignalingNaNs) { // Check that Date::New preserves non-NaNs in the date range and // quiets SNaNs. - v8::Handle<v8::Value> date = v8::Date::New(test_value); + v8::Handle<v8::Value> date = + v8::Date::New(isolate, test_value); double expected_stored_date = DoubleToDateTime(test_value); double stored_date = date->NumberValue(); if (!std::isnan(expected_stored_date)) { @@ -17356,11 +18063,12 @@ static void SpaghettiIncident( // Test that an exception can be propagated down through a spaghetti // stack using ReThrow. THREADED_TEST(SpaghettiStackReThrow) { - v8::HandleScope scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); LocalContext context; context->Global()->Set( - v8::String::New("s"), - v8::FunctionTemplate::New(SpaghettiIncident)->GetFunction()); + v8::String::NewFromUtf8(isolate, "s"), + v8::FunctionTemplate::New(isolate, SpaghettiIncident)->GetFunction()); v8::TryCatch try_catch; CompileRun( "var i = 0;" @@ -17400,7 +18108,7 @@ TEST(Regress528) { v8::Local<Context> context = Context::New(isolate); context->Enter(); - Local<v8::String> obj = v8::String::New(""); + Local<v8::String> obj = v8::String::NewFromUtf8(isolate, ""); context->SetEmbedderData(0, obj); CompileRun(source_simple); context->Exit(); @@ -17472,14 +18180,15 @@ TEST(Regress528) { THREADED_TEST(ScriptOrigin) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); - v8::Handle<v8::String> script = v8::String::New( - "function f() {}\n\nfunction g() {}"); + v8::ScriptOrigin origin = + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); + v8::Handle<v8::String> script = v8::String::NewFromUtf8( + env->GetIsolate(), "function f() {}\n\nfunction g() {}"); v8::Script::Compile(script, &origin)->Run(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("f"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("g"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); v8::ScriptOrigin script_origin_f = f->GetScriptOrigin(); CHECK_EQ("test", *v8::String::Utf8Value(script_origin_f.ResourceName())); @@ -17494,12 +18203,14 @@ THREADED_TEST(ScriptOrigin) { THREADED_TEST(FunctionGetInferredName) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); - v8::Handle<v8::String> script = v8::String::New( + v8::ScriptOrigin origin = + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); + v8::Handle<v8::String> script = v8::String::NewFromUtf8( + env->GetIsolate(), "var foo = { bar : { baz : function() {}}}; var f = foo.bar.baz;"); v8::Script::Compile(script, &origin)->Run(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("f"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); CHECK_EQ("foo.bar.baz", *v8::String::Utf8Value(f->GetInferredName())); } @@ -17540,23 +18251,26 @@ THREADED_TEST(FunctionGetDisplayName) { " arguments.callee.displayName = 'set_in_runtime';" "}; g();" ; - v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); - v8::Script::Compile(v8::String::New(code), &origin)->Run(); - v8::Local<v8::Value> error = env->Global()->Get(v8::String::New("error")); + v8::ScriptOrigin origin = + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), code), &origin) + ->Run(); + v8::Local<v8::Value> error = + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "error")); v8::Local<v8::Function> a = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("a"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "a"))); v8::Local<v8::Function> b = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("b"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "b"))); v8::Local<v8::Function> c = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("c"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "c"))); v8::Local<v8::Function> d = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("d"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "d"))); v8::Local<v8::Function> e = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("e"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "e"))); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("f"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("g"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); CHECK_EQ(false, error->BooleanValue()); CHECK_EQ("display_a", *v8::String::Utf8Value(a->GetDisplayName())); CHECK_EQ("display_b", *v8::String::Utf8Value(b->GetDisplayName())); @@ -17571,14 +18285,15 @@ THREADED_TEST(FunctionGetDisplayName) { THREADED_TEST(ScriptLineNumber) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); - v8::Handle<v8::String> script = v8::String::New( - "function f() {}\n\nfunction g() {}"); + v8::ScriptOrigin origin = + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); + v8::Handle<v8::String> script = v8::String::NewFromUtf8( + env->GetIsolate(), "function f() {}\n\nfunction g() {}"); v8::Script::Compile(script, &origin)->Run(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("f"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("g"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); CHECK_EQ(0, f->GetScriptLineNumber()); CHECK_EQ(2, g->GetScriptLineNumber()); } @@ -17586,16 +18301,19 @@ THREADED_TEST(ScriptLineNumber) { THREADED_TEST(ScriptColumnNumber) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"), - v8::Integer::New(3), v8::Integer::New(2)); - v8::Handle<v8::String> script = v8::String::New( - "function foo() {}\n\n function bar() {}"); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::ScriptOrigin origin = + v8::ScriptOrigin(v8::String::NewFromUtf8(isolate, "test"), + v8::Integer::New(isolate, 3), + v8::Integer::New(isolate, 2)); + v8::Handle<v8::String> script = v8::String::NewFromUtf8( + isolate, "function foo() {}\n\n function bar() {}"); v8::Script::Compile(script, &origin)->Run(); v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("foo"))); + env->Global()->Get(v8::String::NewFromUtf8(isolate, "foo"))); v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("bar"))); + env->Global()->Get(v8::String::NewFromUtf8(isolate, "bar"))); CHECK_EQ(14, foo->GetScriptColumnNumber()); CHECK_EQ(17, bar->GetScriptColumnNumber()); } @@ -17603,7 +18321,8 @@ THREADED_TEST(ScriptColumnNumber) { THREADED_TEST(FunctionIsBuiltin) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); v8::Local<v8::Function> f; f = v8::Local<v8::Function>::Cast(CompileRun("Math.floor")); CHECK(f->IsBuiltin()); @@ -17620,19 +18339,49 @@ THREADED_TEST(FunctionIsBuiltin) { THREADED_TEST(FunctionGetScriptId) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"), - v8::Integer::New(3), v8::Integer::New(2)); - v8::Handle<v8::String> scriptSource = v8::String::New( - "function foo() {}\n\n function bar() {}"); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::ScriptOrigin origin = + v8::ScriptOrigin(v8::String::NewFromUtf8(isolate, "test"), + v8::Integer::New(isolate, 3), + v8::Integer::New(isolate, 2)); + v8::Handle<v8::String> scriptSource = v8::String::NewFromUtf8( + isolate, "function foo() {}\n\n function bar() {}"); v8::Local<v8::Script> script(v8::Script::Compile(scriptSource, &origin)); script->Run(); v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("foo"))); + env->Global()->Get(v8::String::NewFromUtf8(isolate, "foo"))); v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("bar"))); - CHECK_EQ(script->Id(), foo->GetScriptId()); - CHECK_EQ(script->Id(), bar->GetScriptId()); + env->Global()->Get(v8::String::NewFromUtf8(isolate, "bar"))); + CHECK_EQ(script->GetId(), foo->ScriptId()); + CHECK_EQ(script->GetId(), bar->ScriptId()); +} + + +THREADED_TEST(FunctionGetBoundFunction) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::NewFromUtf8( + env->GetIsolate(), "test")); + v8::Handle<v8::String> script = v8::String::NewFromUtf8( + env->GetIsolate(), + "var a = new Object();\n" + "a.x = 1;\n" + "function f () { return this.x };\n" + "var g = f.bind(a);\n" + "var b = g();"); + v8::Script::Compile(script, &origin)->Run(); + v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); + CHECK(g->GetBoundFunction()->IsFunction()); + Local<v8::Function> original_function = Local<v8::Function>::Cast( + g->GetBoundFunction()); + CHECK_EQ(f->GetName(), original_function->GetName()); + CHECK_EQ(f->GetScriptLineNumber(), original_function->GetScriptLineNumber()); + CHECK_EQ(f->GetScriptColumnNumber(), + original_function->GetScriptColumnNumber()); } @@ -17676,8 +18425,9 @@ void FooSetInterceptor(Local<String> name, TEST(SetterOnConstructorPrototype) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), GetterWhichReturns42, SetterWhichSetsYOnThisTo23); @@ -17728,8 +18478,9 @@ static void NamedPropertySetterWhichSetsYOnThisTo23( THREADED_TEST(InterceptorOnConstructorPrototype) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(NamedPropertyGetterWhichReturns42, NamedPropertySetterWhichSetsYOnThisTo23); LocalContext context; @@ -17768,11 +18519,12 @@ TEST(Regress618) { "C1.prototype = P;"; LocalContext context; - v8::HandleScope scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); v8::Local<v8::Script> script; // Use a simple object as prototype. - v8::Local<v8::Object> prototype = v8::Object::New(); + v8::Local<v8::Object> prototype = v8::Object::New(isolate); prototype->Set(v8_str("y"), v8_num(42)); context->Global()->Set(v8_str("P"), prototype); @@ -17789,7 +18541,7 @@ TEST(Regress618) { } // Use an API object with accessors as prototype. - Local<ObjectTemplate> templ = ObjectTemplate::New(); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), GetterWhichReturns42, SetterWhichSetsYOnThisTo23); @@ -17967,8 +18719,6 @@ THREADED_TEST(AddToJSFunctionResultCache) { } -static const int k0CacheSize = 16; - THREADED_TEST(FillJSFunctionResultCache) { i::FLAG_allow_natives_syntax = true; LocalContext context; @@ -18155,15 +18905,17 @@ TEST(ContainsOnlyOneByte) { const int aligned_length = length*sizeof(uintptr_t)/sizeof(uint16_t); i::SmartArrayPointer<uintptr_t> aligned_contents(new uintptr_t[aligned_length]); - uint16_t* string_contents = reinterpret_cast<uint16_t*>(*aligned_contents); + uint16_t* string_contents = + reinterpret_cast<uint16_t*>(aligned_contents.get()); // Set to contain only one byte. for (int i = 0; i < length-1; i++) { string_contents[i] = 0x41; } string_contents[length-1] = 0; // Simple case. - Handle<String> string; - string = String::NewExternal(new TestResource(string_contents)); + Handle<String> string = + String::NewExternal(isolate, + new TestResource(string_contents, NULL, false)); CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte()); // Counter example. string = String::NewFromTwoByte(isolate, string_contents); @@ -18180,7 +18932,9 @@ TEST(ContainsOnlyOneByte) { balanced = String::Concat(balanced, right); Handle<String> cons_strings[] = {left, balanced, right}; Handle<String> two_byte = - String::NewExternal(new TestResource(string_contents)); + String::NewExternal(isolate, + new TestResource(string_contents, NULL, false)); + USE(two_byte); USE(cons_strings); for (size_t i = 0; i < ARRAY_SIZE(cons_strings); i++) { // Base assumptions. string = cons_strings[i]; @@ -18200,8 +18954,9 @@ TEST(ContainsOnlyOneByte) { for (int i = 0; i < size; i++) { int shift = 8 + (i % 7); string_contents[alignment + i] = 1 << shift; - string = - String::NewExternal(new TestResource(string_contents + alignment)); + string = String::NewExternal( + isolate, + new TestResource(string_contents + alignment, NULL, false)); CHECK_EQ(size, string->Length()); CHECK(!string->ContainsOnlyOneByte()); string_contents[alignment + i] = 0x41; @@ -18227,11 +18982,13 @@ TEST(GCInFailedAccessCheckCallback) { v8::V8::Initialize(); v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); - v8::HandleScope scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); // Create an ObjectTemplate for global objects and install access // check callbacks that will block access. - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallbacks(NamedGetAccessBlocker, IndexedGetAccessBlocker, v8::Handle<v8::Value>(), @@ -18316,18 +19073,20 @@ TEST(IsolateNewDispose) { UNINITIALIZED_TEST(DisposeIsolateWhenInUse) { v8::Isolate* isolate = v8::Isolate::New(); - CHECK(isolate); - isolate->Enter(); - v8::HandleScope scope(isolate); - LocalContext context(isolate); - // Run something in this isolate. - ExpectTrue("true"); - v8::V8::SetFatalErrorHandler(StoringErrorCallback); - last_location = last_message = NULL; - // Still entered, should fail. + { + v8::Isolate::Scope i_scope(isolate); + v8::HandleScope scope(isolate); + LocalContext context(isolate); + // Run something in this isolate. + ExpectTrue("true"); + v8::V8::SetFatalErrorHandler(StoringErrorCallback); + last_location = last_message = NULL; + // Still entered, should fail. + isolate->Dispose(); + CHECK_NE(last_location, NULL); + CHECK_NE(last_message, NULL); + } isolate->Dispose(); - CHECK_NE(last_location, NULL); - CHECK_NE(last_message, NULL); } @@ -18428,10 +19187,10 @@ TEST(RunTwoIsolatesOnSingleThread) { { v8::Isolate::Scope iscope(isolate2); - context2.Dispose(); + context2.Reset(); } - context1.Dispose(); + context1.Reset(); isolate1->Exit(); v8::V8::SetFatalErrorHandler(StoringErrorCallback); @@ -18542,6 +19301,7 @@ TEST(IsolateDifferentContexts) { CHECK(v->IsNumber()); CHECK_EQ(22, static_cast<int>(v->NumberValue())); } + isolate->Dispose(); } class InitDefaultIsolateThread : public v8::internal::Thread { @@ -18573,7 +19333,7 @@ class InitDefaultIsolateThread : public v8::internal::Thread { v8::ResourceConstraints constraints; constraints.set_max_young_space_size(256 * K); constraints.set_max_old_space_size(4 * K * K); - v8::SetResourceConstraints(&constraints); + v8::SetResourceConstraints(CcTest::isolate(), &constraints); break; } @@ -18837,7 +19597,7 @@ TEST(PersistentHandleVisitor) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - v8::Persistent<v8::Object> object(isolate, v8::Object::New()); + v8::Persistent<v8::Object> object(isolate, v8::Object::New(isolate)); CHECK_EQ(0, object.WrapperClassId()); object.SetWrapperClassId(42); CHECK_EQ(42, object.WrapperClassId()); @@ -18846,7 +19606,7 @@ TEST(PersistentHandleVisitor) { v8::V8::VisitHandlesWithClassIds(&visitor); CHECK_EQ(1, visitor.counter_); - object.Dispose(); + object.Reset(); } @@ -18854,11 +19614,11 @@ TEST(WrapperClassId) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - v8::Persistent<v8::Object> object(isolate, v8::Object::New()); + v8::Persistent<v8::Object> object(isolate, v8::Object::New(isolate)); CHECK_EQ(0, object.WrapperClassId()); object.SetWrapperClassId(65535); CHECK_EQ(65535, object.WrapperClassId()); - object.Dispose(); + object.Reset(); } @@ -18866,14 +19626,14 @@ TEST(PersistentHandleInNewSpaceVisitor) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - v8::Persistent<v8::Object> object1(isolate, v8::Object::New()); + v8::Persistent<v8::Object> object1(isolate, v8::Object::New(isolate)); CHECK_EQ(0, object1.WrapperClassId()); object1.SetWrapperClassId(42); CHECK_EQ(42, object1.WrapperClassId()); CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); - v8::Persistent<v8::Object> object2(isolate, v8::Object::New()); + v8::Persistent<v8::Object> object2(isolate, v8::Object::New(isolate)); CHECK_EQ(0, object2.WrapperClassId()); object2.SetWrapperClassId(42); CHECK_EQ(42, object2.WrapperClassId()); @@ -18882,8 +19642,8 @@ TEST(PersistentHandleInNewSpaceVisitor) { v8::V8::VisitHandlesForPartialDependence(isolate, &visitor); CHECK_EQ(1, visitor.counter_); - object1.Dispose(); - object2.Dispose(); + object1.Reset(); + object2.Reset(); } @@ -18944,7 +19704,7 @@ TEST(RegExp) { ExpectTrue("re.test('FoobarbaZ')"); // RegExps are objects on which you can set properties. - re->Set(v8_str("property"), v8::Integer::New(32)); + re->Set(v8_str("property"), v8::Integer::New(context->GetIsolate(), 32)); v8::Handle<v8::Value> value(CompileRun("re.property")); CHECK_EQ(32, value->Int32Value()); @@ -18983,7 +19743,7 @@ static void Getter(v8::Local<v8::String> property, static void Enumerator(const v8::PropertyCallbackInfo<v8::Array>& info) { - v8::Handle<v8::Array> result = v8::Array::New(); + v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate()); result->Set(0, v8_str("universalAnswer")); info.GetReturnValue().Set(result); } @@ -18991,10 +19751,11 @@ static void Enumerator(const v8::PropertyCallbackInfo<v8::Array>& info) { TEST(NamedEnumeratorAndForIn) { LocalContext context; - v8::HandleScope handle_scope(context->GetIsolate()); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); v8::Context::Scope context_scope(context.local()); - v8::Handle<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(isolate); tmpl->SetNamedPropertyHandler(Getter, NULL, NULL, NULL, Enumerator); context->Global()->Set(v8_str("o"), tmpl->NewInstance()); v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( @@ -19023,7 +19784,7 @@ TEST(DefinePropertyPostDetach) { static void InstallContextId(v8::Handle<Context> context, int id) { Context::Scope scope(context); CompileRun("Object.prototype").As<Object>()-> - Set(v8_str("context_id"), v8::Integer::New(id)); + Set(v8_str("context_id"), v8::Integer::New(context->GetIsolate(), id)); } @@ -19033,21 +19794,22 @@ static void CheckContextId(v8::Handle<Object> object, int expected) { THREADED_TEST(CreationContext) { - HandleScope handle_scope(CcTest::isolate()); - Handle<Context> context1 = Context::New(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + HandleScope handle_scope(isolate); + Handle<Context> context1 = Context::New(isolate); InstallContextId(context1, 1); - Handle<Context> context2 = Context::New(CcTest::isolate()); + Handle<Context> context2 = Context::New(isolate); InstallContextId(context2, 2); - Handle<Context> context3 = Context::New(CcTest::isolate()); + Handle<Context> context3 = Context::New(isolate); InstallContextId(context3, 3); - Local<v8::FunctionTemplate> tmpl = v8::FunctionTemplate::New(); + Local<v8::FunctionTemplate> tmpl = v8::FunctionTemplate::New(isolate); Local<Object> object1; Local<Function> func1; { Context::Scope scope(context1); - object1 = Object::New(); + object1 = Object::New(isolate); func1 = tmpl->GetFunction(); } @@ -19055,7 +19817,7 @@ THREADED_TEST(CreationContext) { Local<Function> func2; { Context::Scope scope(context2); - object2 = Object::New(); + object2 = Object::New(isolate); func2 = tmpl->GetFunction(); } @@ -19174,7 +19936,8 @@ void HasOwnPropertyAccessorGetter( TEST(HasOwnProperty) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); { // Check normal properties and defined getters. Handle<Value> value = CompileRun( "function Foo() {" @@ -19197,7 +19960,7 @@ TEST(HasOwnProperty) { CHECK(object->HasOwnProperty(v8_str("bla"))); } { // Check named getter interceptors. - Handle<ObjectTemplate> templ = ObjectTemplate::New(); + Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(HasOwnPropertyNamedPropertyGetter); Handle<Object> instance = templ->NewInstance(); CHECK(!instance->HasOwnProperty(v8_str("42"))); @@ -19205,7 +19968,7 @@ TEST(HasOwnProperty) { CHECK(!instance->HasOwnProperty(v8_str("bar"))); } { // Check indexed getter interceptors. - Handle<ObjectTemplate> templ = ObjectTemplate::New(); + Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(HasOwnPropertyIndexedPropertyGetter); Handle<Object> instance = templ->NewInstance(); CHECK(instance->HasOwnProperty(v8_str("42"))); @@ -19213,28 +19976,28 @@ TEST(HasOwnProperty) { CHECK(!instance->HasOwnProperty(v8_str("foo"))); } { // Check named query interceptors. - Handle<ObjectTemplate> templ = ObjectTemplate::New(); + Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(0, 0, HasOwnPropertyNamedPropertyQuery); Handle<Object> instance = templ->NewInstance(); CHECK(instance->HasOwnProperty(v8_str("foo"))); CHECK(!instance->HasOwnProperty(v8_str("bar"))); } { // Check indexed query interceptors. - Handle<ObjectTemplate> templ = ObjectTemplate::New(); + Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(0, 0, HasOwnPropertyIndexedPropertyQuery); Handle<Object> instance = templ->NewInstance(); CHECK(instance->HasOwnProperty(v8_str("42"))); CHECK(!instance->HasOwnProperty(v8_str("41"))); } { // Check callbacks. - Handle<ObjectTemplate> templ = ObjectTemplate::New(); + Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("foo"), HasOwnPropertyAccessorGetter); Handle<Object> instance = templ->NewInstance(); CHECK(instance->HasOwnProperty(v8_str("foo"))); CHECK(!instance->HasOwnProperty(v8_str("bar"))); } { // Check that query wins on disagreement. - Handle<ObjectTemplate> templ = ObjectTemplate::New(); + Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetNamedPropertyHandler(HasOwnPropertyNamedPropertyGetter, 0, HasOwnPropertyNamedPropertyQuery2); @@ -19246,8 +20009,9 @@ TEST(HasOwnProperty) { TEST(IndexedInterceptorWithStringProto) { - v8::HandleScope scope(CcTest::isolate()); - Handle<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetIndexedPropertyHandler(NULL, NULL, HasOwnPropertyIndexedPropertyQuery); @@ -19361,8 +20125,10 @@ static void NonObjectThis(const v8::FunctionCallbackInfo<v8::Value>& args) { THREADED_TEST(CallAPIFunctionOnNonObject) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Handle<FunctionTemplate> templ = v8::FunctionTemplate::New(NonObjectThis); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Handle<FunctionTemplate> templ = + v8::FunctionTemplate::New(isolate, NonObjectThis); Handle<Function> function = templ->GetFunction(); context->Global()->Set(v8_str("f"), function); TryCatch try_catch; @@ -19372,8 +20138,9 @@ THREADED_TEST(CallAPIFunctionOnNonObject) { // Regression test for issue 1470. THREADED_TEST(ReadOnlyIndexedProperties) { - v8::HandleScope scope(CcTest::isolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); LocalContext context; Local<v8::Object> obj = templ->NewInstance(); @@ -19441,18 +20208,19 @@ THREADED_TEST(Regress93759) { HandleScope scope(isolate); // Template for object with security check. - Local<ObjectTemplate> no_proto_template = v8::ObjectTemplate::New(); + Local<ObjectTemplate> no_proto_template = v8::ObjectTemplate::New(isolate); // We don't do indexing, so any callback can be used for that. no_proto_template->SetAccessCheckCallbacks( BlockProtoNamedSecurityTestCallback, IndexedSecurityTestCallback); // Templates for objects with hidden prototypes and possibly security check. - Local<FunctionTemplate> hidden_proto_template = v8::FunctionTemplate::New(); + Local<FunctionTemplate> hidden_proto_template = + v8::FunctionTemplate::New(isolate); hidden_proto_template->SetHiddenPrototype(true); Local<FunctionTemplate> protected_hidden_proto_template = - v8::FunctionTemplate::New(); + v8::FunctionTemplate::New(isolate); protected_hidden_proto_template->InstanceTemplate()->SetAccessCheckCallbacks( BlockProtoNamedSecurityTestCallback, IndexedSecurityTestCallback); @@ -19463,7 +20231,7 @@ THREADED_TEST(Regress93759) { context->Enter(); // Plain object, no security check. - Local<Object> simple_object = Object::New(); + Local<Object> simple_object = Object::New(isolate); // Object with explicit security check. Local<Object> protected_object = @@ -19481,21 +20249,21 @@ THREADED_TEST(Regress93759) { Local<Object> hidden_prototype = hidden_proto_template->GetFunction()->NewInstance(); Local<Object> object_with_hidden = - Object::New(); + Object::New(isolate); object_with_hidden->SetPrototype(hidden_prototype); // Hidden prototype with security check on the hidden prototype. Local<Object> protected_hidden_prototype = protected_hidden_proto_template->GetFunction()->NewInstance(); Local<Object> object_with_protected_hidden = - Object::New(); + Object::New(isolate); object_with_protected_hidden->SetPrototype(protected_hidden_prototype); context->Exit(); // Template for object for second context. Values to test are put on it as // properties. - Local<ObjectTemplate> global_template = ObjectTemplate::New(); + Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate); global_template->Set(v8_str("simple"), simple_object); global_template->Set(v8_str("protected"), protected_object); global_template->Set(v8_str("global"), global_object); @@ -19528,7 +20296,7 @@ THREADED_TEST(Regress93759) { THREADED_TEST(Regress125988) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> intercept = FunctionTemplate::New(); + Handle<FunctionTemplate> intercept = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(intercept, EmptyInterceptorGetter, EmptyInterceptorSetter); LocalContext env; env->Global()->Set(v8_str("Intercept"), intercept->GetFunction()); @@ -19645,11 +20413,10 @@ THREADED_TEST(ForeignFunctionReceiver) { CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[1]"))); CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); - // TODO(1547): Make the following also return "i". // Calling with environment record as base. - TestReceiver(o, context->Global(), "func()"); + TestReceiver(i, foreign_context->Global(), "func()"); // Calling with no base. - TestReceiver(o, context->Global(), "(1,func)()"); + TestReceiver(i, foreign_context->Global(), "(1,func)()"); } @@ -19690,7 +20457,7 @@ TEST(CallCompletedCallback) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); v8::Handle<v8::FunctionTemplate> recursive_runtime = - v8::FunctionTemplate::New(RecursiveCall); + v8::FunctionTemplate::New(env->GetIsolate(), RecursiveCall); env->Global()->Set(v8_str("recursion"), recursive_runtime->GetFunction()); // Adding the same callback a second time has no effect. @@ -19698,8 +20465,8 @@ TEST(CallCompletedCallback) { v8::V8::AddCallCompletedCallback(CallCompletedCallback1); v8::V8::AddCallCompletedCallback(CallCompletedCallback2); i::OS::Print("--- Script (1) ---\n"); - Local<Script> script = - v8::Script::Compile(v8::String::New("recursion(0)")); + Local<Script> script = v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), "recursion(0)")); script->Run(); CHECK_EQ(3, callback_fired); @@ -19747,6 +20514,102 @@ TEST(CallCompletedCallbackTwoExceptions) { } +static void MicrotaskOne(const v8::FunctionCallbackInfo<Value>& info) { + v8::HandleScope scope(info.GetIsolate()); + CompileRun("ext1Calls++;"); +} + + +static void MicrotaskTwo(const v8::FunctionCallbackInfo<Value>& info) { + v8::HandleScope scope(info.GetIsolate()); + CompileRun("ext2Calls++;"); +} + + +TEST(EnqueueMicrotask) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + CompileRun( + "var ext1Calls = 0;" + "var ext2Calls = 0;"); + CompileRun("1+1;"); + CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); + + v8::V8::EnqueueMicrotask(env->GetIsolate(), + Function::New(env->GetIsolate(), MicrotaskOne)); + CompileRun("1+1;"); + CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); + + v8::V8::EnqueueMicrotask(env->GetIsolate(), + Function::New(env->GetIsolate(), MicrotaskOne)); + v8::V8::EnqueueMicrotask(env->GetIsolate(), + Function::New(env->GetIsolate(), MicrotaskTwo)); + CompileRun("1+1;"); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value()); + + v8::V8::EnqueueMicrotask(env->GetIsolate(), + Function::New(env->GetIsolate(), MicrotaskTwo)); + CompileRun("1+1;"); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value()); + + CompileRun("1+1;"); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value()); +} + + +TEST(SetAutorunMicrotasks) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + CompileRun( + "var ext1Calls = 0;" + "var ext2Calls = 0;"); + CompileRun("1+1;"); + CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); + + v8::V8::EnqueueMicrotask(env->GetIsolate(), + Function::New(env->GetIsolate(), MicrotaskOne)); + CompileRun("1+1;"); + CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); + + V8::SetAutorunMicrotasks(env->GetIsolate(), false); + v8::V8::EnqueueMicrotask(env->GetIsolate(), + Function::New(env->GetIsolate(), MicrotaskOne)); + v8::V8::EnqueueMicrotask(env->GetIsolate(), + Function::New(env->GetIsolate(), MicrotaskTwo)); + CompileRun("1+1;"); + CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); + + V8::RunMicrotasks(env->GetIsolate()); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value()); + + v8::V8::EnqueueMicrotask(env->GetIsolate(), + Function::New(env->GetIsolate(), MicrotaskTwo)); + CompileRun("1+1;"); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value()); + + V8::RunMicrotasks(env->GetIsolate()); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value()); + + V8::SetAutorunMicrotasks(env->GetIsolate(), true); + v8::V8::EnqueueMicrotask(env->GetIsolate(), + Function::New(env->GetIsolate(), MicrotaskTwo)); + CompileRun("1+1;"); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value()); +} + + static int probes_counter = 0; static int misses_counter = 0; static int updates_counter = 0; @@ -19800,7 +20663,11 @@ static void StubCacheHelper(bool primary) { int updates = updates_counter - initial_updates; CHECK_LT(updates, 10); CHECK_LT(misses, 10); - CHECK_GE(probes, 10000); + // TODO(verwaest): Update this test to overflow the degree of polymorphism + // before megamorphism. The number of probes will only work once we teach the + // serializer to embed references to counters in the stubs, given that the + // megamorphic_stub_cache_probes is updated in a snapshot-generated stub. + CHECK_GE(probes, 0); #endif } @@ -19815,6 +20682,34 @@ TEST(PrimaryStubCache) { } +static int cow_arrays_created_runtime = 0; + + +static int* LookupCounterCOWArrays(const char* name) { + if (strcmp(name, "c:V8.COWArraysCreatedRuntime") == 0) { + return &cow_arrays_created_runtime; + } + return NULL; +} + + +TEST(CheckCOWArraysCreatedRuntimeCounter) { + V8::SetCounterFunction(LookupCounterCOWArrays); +#ifdef DEBUG + i::FLAG_native_code_counters = true; + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + int initial_cow_arrays = cow_arrays_created_runtime; + CompileRun("var o = [1, 2, 3];"); + CHECK_EQ(1, cow_arrays_created_runtime - initial_cow_arrays); + CompileRun("var o = {foo: [4, 5, 6], bar: [3, 0]};"); + CHECK_EQ(3, cow_arrays_created_runtime - initial_cow_arrays); + CompileRun("var o = {foo: [1, 2, 3, [4, 5, 6]], bar: 'hi'};"); + CHECK_EQ(4, cow_arrays_created_runtime - initial_cow_arrays); +#endif +} + + TEST(StaticGetters) { LocalContext context; i::Factory* factory = CcTest::i_isolate()->factory(); @@ -19836,16 +20731,28 @@ UNINITIALIZED_TEST(IsolateEmbedderData) { v8::Isolate* isolate = v8::Isolate::New(); isolate->Enter(); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); - CHECK_EQ(NULL, isolate->GetData()); - CHECK_EQ(NULL, i_isolate->GetData()); - static void* data1 = reinterpret_cast<void*>(0xacce55ed); - isolate->SetData(data1); - CHECK_EQ(data1, isolate->GetData()); - CHECK_EQ(data1, i_isolate->GetData()); - static void* data2 = reinterpret_cast<void*>(0xdecea5ed); - i_isolate->SetData(data2); - CHECK_EQ(data2, isolate->GetData()); - CHECK_EQ(data2, i_isolate->GetData()); + for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) { + CHECK_EQ(NULL, isolate->GetData(slot)); + CHECK_EQ(NULL, i_isolate->GetData(slot)); + } + for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) { + void* data = reinterpret_cast<void*>(0xacce55ed + slot); + isolate->SetData(slot, data); + } + for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) { + void* data = reinterpret_cast<void*>(0xacce55ed + slot); + CHECK_EQ(data, isolate->GetData(slot)); + CHECK_EQ(data, i_isolate->GetData(slot)); + } + for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) { + void* data = reinterpret_cast<void*>(0xdecea5ed + slot); + isolate->SetData(slot, data); + } + for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) { + void* data = reinterpret_cast<void*>(0xdecea5ed + slot); + CHECK_EQ(data, isolate->GetData(slot)); + CHECK_EQ(data, i_isolate->GetData(slot)); + } isolate->Exit(); isolate->Dispose(); } @@ -19857,7 +20764,6 @@ TEST(StringEmpty) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); i::Handle<i::Object> empty_string = factory->empty_string(); - CHECK(*v8::Utils::OpenHandle(*v8::String::Empty()) == *empty_string); CHECK(*v8::Utils::OpenHandle(*v8::String::Empty(isolate)) == *empty_string); } @@ -19947,14 +20853,14 @@ THREADED_TEST(InstanceCheckOnInstanceAccessor) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - Local<FunctionTemplate> templ = FunctionTemplate::New(); + Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); Local<ObjectTemplate> inst = templ->InstanceTemplate(); inst->SetAccessor(v8_str("foo"), InstanceCheckedGetter, InstanceCheckedSetter, Handle<Value>(), v8::DEFAULT, v8::None, - v8::AccessorSignature::New(templ)); + v8::AccessorSignature::New(context->GetIsolate(), templ)); context->Global()->Set(v8_str("f"), templ->GetFunction()); printf("Testing positive ...\n"); @@ -19975,7 +20881,7 @@ THREADED_TEST(InstanceCheckOnInstanceAccessorWithInterceptor) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - Local<FunctionTemplate> templ = FunctionTemplate::New(); + Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); Local<ObjectTemplate> inst = templ->InstanceTemplate(); AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); inst->SetAccessor(v8_str("foo"), @@ -19983,7 +20889,7 @@ THREADED_TEST(InstanceCheckOnInstanceAccessorWithInterceptor) { Handle<Value>(), v8::DEFAULT, v8::None, - v8::AccessorSignature::New(templ)); + v8::AccessorSignature::New(context->GetIsolate(), templ)); context->Global()->Set(v8_str("f"), templ->GetFunction()); printf("Testing positive ...\n"); @@ -20004,14 +20910,14 @@ THREADED_TEST(InstanceCheckOnPrototypeAccessor) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - Local<FunctionTemplate> templ = FunctionTemplate::New(); + Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); Local<ObjectTemplate> proto = templ->PrototypeTemplate(); proto->SetAccessor(v8_str("foo"), InstanceCheckedGetter, InstanceCheckedSetter, Handle<Value>(), v8::DEFAULT, v8::None, - v8::AccessorSignature::New(templ)); + v8::AccessorSignature::New(context->GetIsolate(), templ)); context->Global()->Set(v8_str("f"), templ->GetFunction()); printf("Testing positive ...\n"); @@ -20083,7 +20989,7 @@ static void Helper137002(bool do_store, bool remove_accessor, bool interceptor) { LocalContext context; - Local<ObjectTemplate> templ = ObjectTemplate::New(); + Local<ObjectTemplate> templ = ObjectTemplate::New(context->GetIsolate()); if (interceptor) { templ->SetNamedPropertyHandler(FooGetInterceptor, FooSetInterceptor); } else { @@ -20138,8 +21044,9 @@ THREADED_TEST(Regress137002a) { THREADED_TEST(Regress137002b) { i::FLAG_allow_natives_syntax = true; LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("foo"), GetterWhichReturns42, SetterWhichSetsYOnThisTo23); @@ -20206,8 +21113,9 @@ THREADED_TEST(Regress137002b) { THREADED_TEST(Regress142088) { i::FLAG_allow_natives_syntax = true; LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("foo"), GetterWhichReturns42, SetterWhichSetsYOnThisTo23); @@ -20237,7 +21145,7 @@ THREADED_TEST(Regress137496) { THREADED_TEST(Regress149912) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(); + Handle<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); context->Global()->Set(v8_str("Bug"), templ->GetFunction()); CompileRun("Number.prototype.__proto__ = new Bug; var x = 0; x.foo();"); @@ -20246,8 +21154,9 @@ THREADED_TEST(Regress149912) { THREADED_TEST(Regress157124) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Local<ObjectTemplate> templ = ObjectTemplate::New(); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); Local<Object> obj = templ->NewInstance(); obj->GetIdentityHash(); obj->DeleteHiddenValue(v8_str("Bug")); @@ -20271,8 +21180,8 @@ THREADED_TEST(Regress2746) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - Local<Object> obj = Object::New(); - Local<String> key = String::New("key"); + Local<Object> obj = Object::New(isolate); + Local<String> key = String::NewFromUtf8(context->GetIsolate(), "key"); obj->SetHiddenValue(key, v8::Undefined(isolate)); Local<Value> value = obj->GetHiddenValue(key); CHECK(!value.IsEmpty()); @@ -20282,8 +21191,10 @@ THREADED_TEST(Regress2746) { THREADED_TEST(Regress260106) { LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Local<FunctionTemplate> templ = FunctionTemplate::New(DummyCallHandler); + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Local<FunctionTemplate> templ = FunctionTemplate::New(isolate, + DummyCallHandler); CompileRun("for (var i = 0; i < 128; i++) Object.prototype[i] = 0;"); Local<Function> function = templ->GetFunction(); CHECK(!function.IsEmpty()); @@ -20372,6 +21283,9 @@ THREADED_TEST(SemaphoreInterruption) { } +#endif // V8_OS_POSIX + + static bool NamedAccessAlwaysBlocked(Local<v8::Object> global, Local<Value> name, v8::AccessType type, @@ -20397,11 +21311,13 @@ void UnreachableCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(JSONStringifyAccessCheck) { v8::V8::Initialize(); - v8::HandleScope scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); // Create an ObjectTemplate for global objects and install access // check callbacks that will block access. - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallbacks(NamedAccessAlwaysBlocked, IndexAccessAlwaysBlocked); @@ -20415,7 +21331,7 @@ TEST(JSONStringifyAccessCheck) { if (i == 1) { // Install a toJSON function on the second run. v8::Handle<v8::FunctionTemplate> toJSON = - v8::FunctionTemplate::New(UnreachableCallback); + v8::FunctionTemplate::New(isolate, UnreachableCallback); global0->Set(v8_str("toJSON"), toJSON->GetFunction()); } @@ -20430,7 +21346,7 @@ TEST(JSONStringifyAccessCheck) { ExpectString("JSON.stringify([other, 'b', 'c'])", "[{},\"b\",\"c\"]"); - v8::Handle<v8::Array> array = v8::Array::New(2); + v8::Handle<v8::Array> array = v8::Array::New(isolate, 2); array->Set(0, v8_str("a")); array->Set(1, v8_str("b")); context1->Global()->Set(v8_str("array"), array); @@ -20495,11 +21411,13 @@ TEST(AccessCheckThrows) { i::FLAG_allow_natives_syntax = true; v8::V8::Initialize(); v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckThrows); - v8::HandleScope scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); // Create an ObjectTemplate for global objects and install access // check callbacks that will block access. - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallbacks(NamedAccessAlwaysBlocked, IndexAccessAlwaysBlocked); @@ -20514,11 +21432,11 @@ TEST(AccessCheckThrows) { context1->Global()->Set(v8_str("other"), global0); v8::Handle<v8::FunctionTemplate> catcher_fun = - v8::FunctionTemplate::New(CatcherCallback); + v8::FunctionTemplate::New(isolate, CatcherCallback); context1->Global()->Set(v8_str("catcher"), catcher_fun->GetFunction()); v8::Handle<v8::FunctionTemplate> has_own_property_fun = - v8::FunctionTemplate::New(HasOwnPropertyCallback); + v8::FunctionTemplate::New(isolate, HasOwnPropertyCallback); context1->Global()->Set(v8_str("has_own_property"), has_own_property_fun->GetFunction()); @@ -20543,7 +21461,8 @@ TEST(AccessCheckThrows) { CheckCorrectThrow("%HasElement(other, 1)"); CheckCorrectThrow("%IsPropertyEnumerable(other, 'x')"); CheckCorrectThrow("%GetPropertyNames(other)"); - CheckCorrectThrow("%GetLocalPropertyNames(other, true)"); + // PROPERTY_ATTRIBUTES_NONE = 0 + CheckCorrectThrow("%GetLocalPropertyNames(other, 0)"); CheckCorrectThrow("%DefineOrRedefineAccessorProperty(" "other, 'x', null, null, 1)"); @@ -20557,7 +21476,7 @@ THREADED_TEST(Regress256330) { i::FLAG_allow_natives_syntax = true; LocalContext context; v8::HandleScope scope(context->GetIsolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(); + Handle<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); context->Global()->Set(v8_str("Bug"), templ->GetFunction()); CompileRun("\"use strict\"; var o = new Bug;" @@ -20572,7 +21491,7 @@ THREADED_TEST(Regress256330) { THREADED_TEST(CrankshaftInterceptorSetter) { i::FLAG_allow_natives_syntax = true; v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(); + Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; env->Global()->Set(v8_str("Obj"), templ->GetFunction()); @@ -20598,7 +21517,7 @@ THREADED_TEST(CrankshaftInterceptorSetter) { THREADED_TEST(CrankshaftInterceptorGetter) { i::FLAG_allow_natives_syntax = true; v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(); + Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; env->Global()->Set(v8_str("Obj"), templ->GetFunction()); @@ -20621,7 +21540,7 @@ THREADED_TEST(CrankshaftInterceptorGetter) { THREADED_TEST(CrankshaftInterceptorFieldRead) { i::FLAG_allow_natives_syntax = true; v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(); + Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; env->Global()->Set(v8_str("Obj"), templ->GetFunction()); @@ -20641,7 +21560,7 @@ THREADED_TEST(CrankshaftInterceptorFieldRead) { THREADED_TEST(CrankshaftInterceptorFieldWrite) { i::FLAG_allow_natives_syntax = true; v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(); + Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; env->Global()->Set(v8_str("Obj"), templ->GetFunction()); @@ -20658,7 +21577,259 @@ THREADED_TEST(CrankshaftInterceptorFieldWrite) { } -#endif // V8_OS_POSIX +class RequestInterruptTestBase { + public: + RequestInterruptTestBase() + : env_(), + isolate_(env_->GetIsolate()), + sem_(0), + warmup_(20000), + should_continue_(true) { + } + + virtual ~RequestInterruptTestBase() { } + + virtual void TestBody() = 0; + + void RunTest() { + InterruptThread i_thread(this); + i_thread.Start(); + + v8::HandleScope handle_scope(isolate_); + + TestBody(); + + isolate_->ClearInterrupt(); + + // Verify we arrived here because interruptor was called + // not due to a bug causing us to exit the loop too early. + CHECK(!should_continue()); + } + + void WakeUpInterruptor() { + sem_.Signal(); + } + + bool should_continue() const { return should_continue_; } + + bool ShouldContinue() { + if (warmup_ > 0) { + if (--warmup_ == 0) { + WakeUpInterruptor(); + } + } + + return should_continue_; + } + + protected: + static void ShouldContinueCallback( + const v8::FunctionCallbackInfo<Value>& info) { + RequestInterruptTestBase* test = + reinterpret_cast<RequestInterruptTestBase*>( + info.Data().As<v8::External>()->Value()); + info.GetReturnValue().Set(test->ShouldContinue()); + } + + class InterruptThread : public i::Thread { + public: + explicit InterruptThread(RequestInterruptTestBase* test) + : Thread("RequestInterruptTest"), test_(test) {} + + virtual void Run() { + test_->sem_.Wait(); + test_->isolate_->RequestInterrupt(&OnInterrupt, test_); + } + + static void OnInterrupt(v8::Isolate* isolate, void* data) { + reinterpret_cast<RequestInterruptTestBase*>(data)-> + should_continue_ = false; + } + + private: + RequestInterruptTestBase* test_; + }; + + LocalContext env_; + v8::Isolate* isolate_; + i::Semaphore sem_; + int warmup_; + bool should_continue_; +}; + + +class RequestInterruptTestWithFunctionCall : public RequestInterruptTestBase { + public: + virtual void TestBody() { + Local<Function> func = Function::New( + isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)); + env_->Global()->Set(v8_str("ShouldContinue"), func); + + CompileRun("while (ShouldContinue()) { }"); + } +}; + + +class RequestInterruptTestWithMethodCall : public RequestInterruptTestBase { + public: + virtual void TestBody() { + v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); + v8::Local<v8::Template> proto = t->PrototypeTemplate(); + proto->Set(v8_str("shouldContinue"), Function::New( + isolate_, ShouldContinueCallback, v8::External::New(isolate_, this))); + env_->Global()->Set(v8_str("Klass"), t->GetFunction()); + + CompileRun("var obj = new Klass; while (obj.shouldContinue()) { }"); + } +}; + + +class RequestInterruptTestWithAccessor : public RequestInterruptTestBase { + public: + virtual void TestBody() { + v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); + v8::Local<v8::Template> proto = t->PrototypeTemplate(); + proto->SetAccessorProperty(v8_str("shouldContinue"), FunctionTemplate::New( + isolate_, ShouldContinueCallback, v8::External::New(isolate_, this))); + env_->Global()->Set(v8_str("Klass"), t->GetFunction()); + + CompileRun("var obj = new Klass; while (obj.shouldContinue) { }"); + } +}; + + +class RequestInterruptTestWithNativeAccessor : public RequestInterruptTestBase { + public: + virtual void TestBody() { + v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); + t->InstanceTemplate()->SetNativeDataProperty( + v8_str("shouldContinue"), + &ShouldContinueNativeGetter, + NULL, + v8::External::New(isolate_, this)); + env_->Global()->Set(v8_str("Klass"), t->GetFunction()); + + CompileRun("var obj = new Klass; while (obj.shouldContinue) { }"); + } + + private: + static void ShouldContinueNativeGetter( + Local<String> property, + const v8::PropertyCallbackInfo<v8::Value>& info) { + RequestInterruptTestBase* test = + reinterpret_cast<RequestInterruptTestBase*>( + info.Data().As<v8::External>()->Value()); + info.GetReturnValue().Set(test->ShouldContinue()); + } +}; + + +class RequestInterruptTestWithMethodCallAndInterceptor + : public RequestInterruptTestBase { + public: + virtual void TestBody() { + v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); + v8::Local<v8::Template> proto = t->PrototypeTemplate(); + proto->Set(v8_str("shouldContinue"), Function::New( + isolate_, ShouldContinueCallback, v8::External::New(isolate_, this))); + v8::Local<v8::ObjectTemplate> instance_template = t->InstanceTemplate(); + instance_template->SetNamedPropertyHandler(EmptyInterceptor); + + env_->Global()->Set(v8_str("Klass"), t->GetFunction()); + + CompileRun("var obj = new Klass; while (obj.shouldContinue()) { }"); + } + + private: + static void EmptyInterceptor( + Local<String> property, + const v8::PropertyCallbackInfo<v8::Value>& info) { + } +}; + + +class RequestInterruptTestWithMathAbs : public RequestInterruptTestBase { + public: + virtual void TestBody() { + env_->Global()->Set(v8_str("WakeUpInterruptor"), Function::New( + isolate_, + WakeUpInterruptorCallback, + v8::External::New(isolate_, this))); + + env_->Global()->Set(v8_str("ShouldContinue"), Function::New( + isolate_, + ShouldContinueCallback, + v8::External::New(isolate_, this))); + + i::FLAG_allow_natives_syntax = true; + CompileRun("function loopish(o) {" + " var pre = 10;" + " while (o.abs(1) > 0) {" + " if (o.abs(1) >= 0 && !ShouldContinue()) break;" + " if (pre > 0) {" + " if (--pre === 0) WakeUpInterruptor(o === Math);" + " }" + " }" + "}" + "var i = 50;" + "var obj = {abs: function () { return i-- }, x: null};" + "delete obj.x;" + "loopish(obj);" + "%OptimizeFunctionOnNextCall(loopish);" + "loopish(Math);"); + + i::FLAG_allow_natives_syntax = false; + } + + private: + static void WakeUpInterruptorCallback( + const v8::FunctionCallbackInfo<Value>& info) { + if (!info[0]->BooleanValue()) return; + + RequestInterruptTestBase* test = + reinterpret_cast<RequestInterruptTestBase*>( + info.Data().As<v8::External>()->Value()); + test->WakeUpInterruptor(); + } + + static void ShouldContinueCallback( + const v8::FunctionCallbackInfo<Value>& info) { + RequestInterruptTestBase* test = + reinterpret_cast<RequestInterruptTestBase*>( + info.Data().As<v8::External>()->Value()); + info.GetReturnValue().Set(test->should_continue()); + } +}; + + +TEST(RequestInterruptTestWithFunctionCall) { + RequestInterruptTestWithFunctionCall().RunTest(); +} + + +TEST(RequestInterruptTestWithMethodCall) { + RequestInterruptTestWithMethodCall().RunTest(); +} + + +TEST(RequestInterruptTestWithAccessor) { + RequestInterruptTestWithAccessor().RunTest(); +} + + +TEST(RequestInterruptTestWithNativeAccessor) { + RequestInterruptTestWithNativeAccessor().RunTest(); +} + + +TEST(RequestInterruptTestWithMethodCallAndInterceptor) { + RequestInterruptTestWithMethodCallAndInterceptor().RunTest(); +} + + +TEST(RequestInterruptTestWithMathAbs) { + RequestInterruptTestWithMathAbs().RunTest(); +} static Local<Value> function_new_expected_env; @@ -20672,12 +21843,12 @@ THREADED_TEST(FunctionNew) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - Local<Object> data = v8::Object::New(); + Local<Object> data = v8::Object::New(isolate); function_new_expected_env = data; Local<Function> func = Function::New(isolate, FunctionNewCallback, data); env->Global()->Set(v8_str("func"), func); Local<Value> result = CompileRun("func();"); - CHECK_EQ(v8::Integer::New(17, isolate), result); + CHECK_EQ(v8::Integer::New(isolate, 17), result); // Verify function not cached int serial_number = i::Smi::cast(v8::Utils::OpenHandle(*func) @@ -20687,14 +21858,14 @@ THREADED_TEST(FunctionNew) { ->GetElementNoExceptionThrown(i_isolate, serial_number); CHECK(elm->IsUndefined()); // Verify that each Function::New creates a new function instance - Local<Object> data2 = v8::Object::New(); + Local<Object> data2 = v8::Object::New(isolate); function_new_expected_env = data2; Local<Function> func2 = Function::New(isolate, FunctionNewCallback, data2); CHECK(!func2->IsNull()); CHECK_NE(func, func2); env->Global()->Set(v8_str("func2"), func2); Local<Value> result2 = CompileRun("func2();"); - CHECK_EQ(v8::Integer::New(17, isolate), result2); + CHECK_EQ(v8::Integer::New(isolate, 17), result2); } @@ -20718,3 +21889,230 @@ TEST(EscapeableHandleScope) { } } } + + +static void SetterWhichExpectsThisAndHolderToDiffer( + Local<String>, Local<Value>, const v8::PropertyCallbackInfo<void>& info) { + CHECK(info.Holder() != info.This()); +} + + +TEST(Regress239669) { + LocalContext context; + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope scope(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); + templ->SetAccessor(v8_str("x"), 0, SetterWhichExpectsThisAndHolderToDiffer); + context->Global()->Set(v8_str("P"), templ->NewInstance()); + CompileRun( + "function C1() {" + " this.x = 23;" + "};" + "C1.prototype = P;" + "for (var i = 0; i < 4; i++ ) {" + " new C1();" + "}"); +} + + +class ApiCallOptimizationChecker { + private: + static Local<Object> data; + static Local<Object> receiver; + static Local<Object> holder; + static Local<Object> callee; + static int count; + + static void OptimizationCallback( + const v8::FunctionCallbackInfo<v8::Value>& info) { + CHECK(callee == info.Callee()); + CHECK(data == info.Data()); + CHECK(receiver == info.This()); + if (info.Length() == 1) { + CHECK_EQ(v8_num(1), info[0]); + } + CHECK(holder == info.Holder()); + count++; + info.GetReturnValue().Set(v8_str("returned")); + } + + // TODO(dcarney): move this to v8.h + static void SetAccessorProperty(Local<Object> object, + Local<String> name, + Local<Function> getter, + Local<Function> setter = Local<Function>()) { + i::Isolate* isolate = CcTest::i_isolate(); + v8::AccessControl settings = v8::DEFAULT; + v8::PropertyAttribute attribute = v8::None; + i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter); + i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true); + if (setter_i.is_null()) setter_i = isolate->factory()->null_value(); + i::JSObject::DefineAccessor(v8::Utils::OpenHandle(*object), + v8::Utils::OpenHandle(*name), + getter_i, + setter_i, + static_cast<PropertyAttributes>(attribute), + settings); + } + + public: + enum SignatureType { + kNoSignature, + kSignatureOnReceiver, + kSignatureOnPrototype + }; + + void RunAll() { + SignatureType signature_types[] = + {kNoSignature, kSignatureOnReceiver, kSignatureOnPrototype}; + for (unsigned i = 0; i < ARRAY_SIZE(signature_types); i++) { + SignatureType signature_type = signature_types[i]; + for (int j = 0; j < 2; j++) { + bool global = j == 0; + int key = signature_type + + ARRAY_SIZE(signature_types) * (global ? 1 : 0); + Run(signature_type, global, key); + } + } + } + + void Run(SignatureType signature_type, bool global, int key) { + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + // Build a template for signature checks. + Local<v8::ObjectTemplate> signature_template; + Local<v8::Signature> signature; + { + Local<v8::FunctionTemplate> parent_template = + FunctionTemplate::New(isolate); + parent_template->SetHiddenPrototype(true); + Local<v8::FunctionTemplate> function_template + = FunctionTemplate::New(isolate); + function_template->Inherit(parent_template); + switch (signature_type) { + case kNoSignature: + break; + case kSignatureOnReceiver: + signature = v8::Signature::New(isolate, function_template); + break; + case kSignatureOnPrototype: + signature = v8::Signature::New(isolate, parent_template); + break; + } + signature_template = function_template->InstanceTemplate(); + } + // Global object must pass checks. + Local<v8::Context> context = + v8::Context::New(isolate, NULL, signature_template); + v8::Context::Scope context_scope(context); + // Install regular object that can pass signature checks. + Local<Object> function_receiver = signature_template->NewInstance(); + context->Global()->Set(v8_str("function_receiver"), function_receiver); + // Get the holder objects. + Local<Object> inner_global = + Local<Object>::Cast(context->Global()->GetPrototype()); + // Install functions on hidden prototype object if there is one. + data = Object::New(isolate); + Local<FunctionTemplate> function_template = FunctionTemplate::New( + isolate, OptimizationCallback, data, signature); + Local<Function> function = function_template->GetFunction(); + Local<Object> global_holder = inner_global; + Local<Object> function_holder = function_receiver; + if (signature_type == kSignatureOnPrototype) { + function_holder = Local<Object>::Cast(function_holder->GetPrototype()); + global_holder = Local<Object>::Cast(global_holder->GetPrototype()); + } + global_holder->Set(v8_str("g_f"), function); + SetAccessorProperty(global_holder, v8_str("g_acc"), function, function); + function_holder->Set(v8_str("f"), function); + SetAccessorProperty(function_holder, v8_str("acc"), function, function); + // Initialize expected values. + callee = function; + count = 0; + if (global) { + receiver = context->Global(); + holder = inner_global; + } else { + holder = function_receiver; + // If not using a signature, add something else to the prototype chain + // to test the case that holder != receiver + if (signature_type == kNoSignature) { + receiver = Local<Object>::Cast(CompileRun( + "var receiver_subclass = {};\n" + "receiver_subclass.__proto__ = function_receiver;\n" + "receiver_subclass")); + } else { + receiver = Local<Object>::Cast(CompileRun( + "var receiver_subclass = function_receiver;\n" + "receiver_subclass")); + } + } + // With no signature, the holder is not set. + if (signature_type == kNoSignature) holder = receiver; + // build wrap_function + i::ScopedVector<char> wrap_function(200); + if (global) { + i::OS::SNPrintF( + wrap_function, + "function wrap_f_%d() { var f = g_f; return f(); }\n" + "function wrap_get_%d() { return this.g_acc; }\n" + "function wrap_set_%d() { return this.g_acc = 1; }\n", + key, key, key); + } else { + i::OS::SNPrintF( + wrap_function, + "function wrap_f_%d() { return receiver_subclass.f(); }\n" + "function wrap_get_%d() { return receiver_subclass.acc; }\n" + "function wrap_set_%d() { return receiver_subclass.acc = 1; }\n", + key, key, key); + } + // build source string + i::ScopedVector<char> source(1000); + i::OS::SNPrintF( + source, + "%s\n" // wrap functions + "function wrap_f() { return wrap_f_%d(); }\n" + "function wrap_get() { return wrap_get_%d(); }\n" + "function wrap_set() { return wrap_set_%d(); }\n" + "check = function(returned) {\n" + " if (returned !== 'returned') { throw returned; }\n" + "}\n" + "\n" + "check(wrap_f());\n" + "check(wrap_f());\n" + "%%OptimizeFunctionOnNextCall(wrap_f_%d);\n" + "check(wrap_f());\n" + "\n" + "check(wrap_get());\n" + "check(wrap_get());\n" + "%%OptimizeFunctionOnNextCall(wrap_get_%d);\n" + "check(wrap_get());\n" + "\n" + "check = function(returned) {\n" + " if (returned !== 1) { throw returned; }\n" + "}\n" + "check(wrap_set());\n" + "check(wrap_set());\n" + "%%OptimizeFunctionOnNextCall(wrap_set_%d);\n" + "check(wrap_set());\n", + wrap_function.start(), key, key, key, key, key, key); + v8::TryCatch try_catch; + CompileRun(source.start()); + ASSERT(!try_catch.HasCaught()); + CHECK_EQ(9, count); + } +}; + + +Local<Object> ApiCallOptimizationChecker::data; +Local<Object> ApiCallOptimizationChecker::receiver; +Local<Object> ApiCallOptimizationChecker::holder; +Local<Object> ApiCallOptimizationChecker::callee; +int ApiCallOptimizationChecker::count = 0; + + +TEST(TestFunctionCallOptimization) { + i::FLAG_allow_natives_syntax = true; + ApiCallOptimizationChecker checker; + checker.RunAll(); +} diff --git a/deps/v8/test/cctest/test-assembler-a64.cc b/deps/v8/test/cctest/test-assembler-a64.cc new file mode 100644 index 0000000000..656f3691ca --- /dev/null +++ b/deps/v8/test/cctest/test-assembler-a64.cc @@ -0,0 +1,9803 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <cmath> +#include <limits> + +#include "v8.h" + +#include "macro-assembler.h" +#include "a64/simulator-a64.h" +#include "a64/disasm-a64.h" +#include "a64/utils-a64.h" +#include "cctest.h" +#include "test-utils-a64.h" + +using namespace v8::internal; + +// Test infrastructure. +// +// Tests are functions which accept no parameters and have no return values. +// The testing code should not perform an explicit return once completed. For +// example to test the mov immediate instruction a very simple test would be: +// +// TEST(mov_x0_one) { +// SETUP(); +// +// START(); +// __ mov(x0, Operand(1)); +// END(); +// +// RUN(); +// +// ASSERT_EQUAL_64(1, x0); +// +// TEARDOWN(); +// } +// +// Within a START ... END block all registers but sp can be modified. sp has to +// be explicitly saved/restored. The END() macro replaces the function return +// so it may appear multiple times in a test if the test has multiple exit +// points. +// +// Once the test has been run all integer and floating point registers as well +// as flags are accessible through a RegisterDump instance, see +// utils-a64.cc for more info on RegisterDump. +// +// We provide some helper assert to handle common cases: +// +// ASSERT_EQUAL_32(int32_t, int_32t) +// ASSERT_EQUAL_FP32(float, float) +// ASSERT_EQUAL_32(int32_t, W register) +// ASSERT_EQUAL_FP32(float, S register) +// ASSERT_EQUAL_64(int64_t, int_64t) +// ASSERT_EQUAL_FP64(double, double) +// ASSERT_EQUAL_64(int64_t, X register) +// ASSERT_EQUAL_64(X register, X register) +// ASSERT_EQUAL_FP64(double, D register) +// +// e.g. ASSERT_EQUAL_64(0.5, d30); +// +// If more advance computation is required before the assert then access the +// RegisterDump named core directly: +// +// ASSERT_EQUAL_64(0x1234, core.xreg(0) & 0xffff); + + +#if 0 // TODO(all): enable. +static v8::Persistent<v8::Context> env; + +static void InitializeVM() { + if (env.IsEmpty()) { + env = v8::Context::New(); + } +} +#endif + +#define __ masm. + +#define BUF_SIZE 8192 +#define SETUP() SETUP_SIZE(BUF_SIZE) + +#define INIT_V8() \ + CcTest::InitializeVM(); \ + +#ifdef USE_SIMULATOR + +// Run tests with the simulator. +#define SETUP_SIZE(buf_size) \ + Isolate* isolate = Isolate::Current(); \ + HandleScope scope(isolate); \ + ASSERT(isolate != NULL); \ + byte* buf = new byte[buf_size]; \ + MacroAssembler masm(isolate, buf, buf_size); \ + Decoder decoder; \ + Simulator simulator(&decoder); \ + PrintDisassembler* pdis = NULL; \ + RegisterDump core; + +/* if (Cctest::trace_sim()) { \ + pdis = new PrintDisassembler(stdout); \ + decoder.PrependVisitor(pdis); \ + } \ + */ + +// Reset the assembler and simulator, so that instructions can be generated, +// but don't actually emit any code. This can be used by tests that need to +// emit instructions at the start of the buffer. Note that START_AFTER_RESET +// must be called before any callee-saved register is modified, and before an +// END is encountered. +// +// Most tests should call START, rather than call RESET directly. +#define RESET() \ + __ Reset(); \ + simulator.ResetState(); + +#define START_AFTER_RESET() \ + __ SetStackPointer(csp); \ + __ PushCalleeSavedRegisters(); \ + __ Debug("Start test.", __LINE__, TRACE_ENABLE | LOG_ALL); + +#define START() \ + RESET(); \ + START_AFTER_RESET(); + +#define RUN() \ + simulator.RunFrom(reinterpret_cast<Instruction*>(buf)) + +#define END() \ + __ Debug("End test.", __LINE__, TRACE_DISABLE | LOG_ALL); \ + core.Dump(&masm); \ + __ PopCalleeSavedRegisters(); \ + __ Ret(); \ + __ GetCode(NULL); + +#define TEARDOWN() \ + delete pdis; \ + delete[] buf; + +#else // ifdef USE_SIMULATOR. +// Run the test on real hardware or models. +#define SETUP_SIZE(buf_size) \ + Isolate* isolate = Isolate::Current(); \ + HandleScope scope(isolate); \ + ASSERT(isolate != NULL); \ + byte* buf = new byte[buf_size]; \ + MacroAssembler masm(isolate, buf, buf_size); \ + RegisterDump core; \ + CPU::SetUp(); + +#define RESET() \ + __ Reset(); + +#define START_AFTER_RESET() \ + __ SetStackPointer(csp); \ + __ PushCalleeSavedRegisters(); + +#define START() \ + RESET(); \ + START_AFTER_RESET(); + +#define RUN() \ + CPU::FlushICache(buf, masm.SizeOfGeneratedCode()); \ + { \ + void (*test_function)(void); \ + memcpy(&test_function, &buf, sizeof(buf)); \ + test_function(); \ + } + +#define END() \ + core.Dump(&masm); \ + __ PopCalleeSavedRegisters(); \ + __ Ret(); \ + __ GetCode(NULL); + +#define TEARDOWN() \ + delete[] buf; + +#endif // ifdef USE_SIMULATOR. + +#define ASSERT_EQUAL_NZCV(expected) \ + CHECK(EqualNzcv(expected, core.flags_nzcv())) + +#define ASSERT_EQUAL_REGISTERS(expected) \ + CHECK(EqualRegisters(&expected, &core)) + +#define ASSERT_EQUAL_32(expected, result) \ + CHECK(Equal32(static_cast<uint32_t>(expected), &core, result)) + +#define ASSERT_EQUAL_FP32(expected, result) \ + CHECK(EqualFP32(expected, &core, result)) + +#define ASSERT_EQUAL_64(expected, result) \ + CHECK(Equal64(expected, &core, result)) + +#define ASSERT_EQUAL_FP64(expected, result) \ + CHECK(EqualFP64(expected, &core, result)) + +#ifdef DEBUG +#define ASSERT_LITERAL_POOL_SIZE(expected) \ + CHECK((expected) == (__ LiteralPoolSize())) +#else +#define ASSERT_LITERAL_POOL_SIZE(expected) \ + ((void) 0) +#endif + + +TEST(stack_ops) { + INIT_V8(); + SETUP(); + + START(); + // save csp. + __ Mov(x29, csp); + + // Set the csp to a known value. + __ Mov(x16, 0x1000); + __ Mov(csp, x16); + __ Mov(x0, csp); + + // Add immediate to the csp, and move the result to a normal register. + __ Add(csp, csp, Operand(0x50)); + __ Mov(x1, csp); + + // Add extended to the csp, and move the result to a normal register. + __ Mov(x17, 0xfff); + __ Add(csp, csp, Operand(x17, SXTB)); + __ Mov(x2, csp); + + // Create an csp using a logical instruction, and move to normal register. + __ Orr(csp, xzr, Operand(0x1fff)); + __ Mov(x3, csp); + + // Write wcsp using a logical instruction. + __ Orr(wcsp, wzr, Operand(0xfffffff8L)); + __ Mov(x4, csp); + + // Write csp, and read back wcsp. + __ Orr(csp, xzr, Operand(0xfffffff8L)); + __ Mov(w5, wcsp); + + // restore csp. + __ Mov(csp, x29); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x1000, x0); + ASSERT_EQUAL_64(0x1050, x1); + ASSERT_EQUAL_64(0x104f, x2); + ASSERT_EQUAL_64(0x1fff, x3); + ASSERT_EQUAL_64(0xfffffff8, x4); + ASSERT_EQUAL_64(0xfffffff8, x5); + + TEARDOWN(); +} + + +TEST(mvn) { + INIT_V8(); + SETUP(); + + START(); + __ Mvn(w0, 0xfff); + __ Mvn(x1, 0xfff); + __ Mvn(w2, Operand(w0, LSL, 1)); + __ Mvn(x3, Operand(x1, LSL, 2)); + __ Mvn(w4, Operand(w0, LSR, 3)); + __ Mvn(x5, Operand(x1, LSR, 4)); + __ Mvn(w6, Operand(w0, ASR, 11)); + __ Mvn(x7, Operand(x1, ASR, 12)); + __ Mvn(w8, Operand(w0, ROR, 13)); + __ Mvn(x9, Operand(x1, ROR, 14)); + __ Mvn(w10, Operand(w2, UXTB)); + __ Mvn(x11, Operand(x2, SXTB, 1)); + __ Mvn(w12, Operand(w2, UXTH, 2)); + __ Mvn(x13, Operand(x2, SXTH, 3)); + __ Mvn(x14, Operand(w2, UXTW, 4)); + __ Mvn(x15, Operand(w2, SXTW, 4)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xfffff000, x0); + ASSERT_EQUAL_64(0xfffffffffffff000UL, x1); + ASSERT_EQUAL_64(0x00001fff, x2); + ASSERT_EQUAL_64(0x0000000000003fffUL, x3); + ASSERT_EQUAL_64(0xe00001ff, x4); + ASSERT_EQUAL_64(0xf0000000000000ffUL, x5); + ASSERT_EQUAL_64(0x00000001, x6); + ASSERT_EQUAL_64(0x0, x7); + ASSERT_EQUAL_64(0x7ff80000, x8); + ASSERT_EQUAL_64(0x3ffc000000000000UL, x9); + ASSERT_EQUAL_64(0xffffff00, x10); + ASSERT_EQUAL_64(0x0000000000000001UL, x11); + ASSERT_EQUAL_64(0xffff8003, x12); + ASSERT_EQUAL_64(0xffffffffffff0007UL, x13); + ASSERT_EQUAL_64(0xfffffffffffe000fUL, x14); + ASSERT_EQUAL_64(0xfffffffffffe000fUL, x15); + + TEARDOWN(); +} + + +TEST(mov) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0xffffffffffffffffL); + __ Mov(x1, 0xffffffffffffffffL); + __ Mov(x2, 0xffffffffffffffffL); + __ Mov(x3, 0xffffffffffffffffL); + + __ Mov(x0, 0x0123456789abcdefL); + + __ movz(x1, 0xabcdL << 16); + __ movk(x2, 0xabcdL << 32); + __ movn(x3, 0xabcdL << 48); + + __ Mov(x4, 0x0123456789abcdefL); + __ Mov(x5, x4); + + __ Mov(w6, -1); + + // Test that moves back to the same register have the desired effect. This + // is a no-op for X registers, and a truncation for W registers. + __ Mov(x7, 0x0123456789abcdefL); + __ Mov(x7, x7); + __ Mov(x8, 0x0123456789abcdefL); + __ Mov(w8, w8); + __ Mov(x9, 0x0123456789abcdefL); + __ Mov(x9, Operand(x9)); + __ Mov(x10, 0x0123456789abcdefL); + __ Mov(w10, Operand(w10)); + + __ Mov(w11, 0xfff); + __ Mov(x12, 0xfff); + __ Mov(w13, Operand(w11, LSL, 1)); + __ Mov(x14, Operand(x12, LSL, 2)); + __ Mov(w15, Operand(w11, LSR, 3)); + __ Mov(x18, Operand(x12, LSR, 4)); + __ Mov(w19, Operand(w11, ASR, 11)); + __ Mov(x20, Operand(x12, ASR, 12)); + __ Mov(w21, Operand(w11, ROR, 13)); + __ Mov(x22, Operand(x12, ROR, 14)); + __ Mov(w23, Operand(w13, UXTB)); + __ Mov(x24, Operand(x13, SXTB, 1)); + __ Mov(w25, Operand(w13, UXTH, 2)); + __ Mov(x26, Operand(x13, SXTH, 3)); + __ Mov(x27, Operand(w13, UXTW, 4)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x0123456789abcdefL, x0); + ASSERT_EQUAL_64(0x00000000abcd0000L, x1); + ASSERT_EQUAL_64(0xffffabcdffffffffL, x2); + ASSERT_EQUAL_64(0x5432ffffffffffffL, x3); + ASSERT_EQUAL_64(x4, x5); + ASSERT_EQUAL_32(-1, w6); + ASSERT_EQUAL_64(0x0123456789abcdefL, x7); + ASSERT_EQUAL_32(0x89abcdefL, w8); + ASSERT_EQUAL_64(0x0123456789abcdefL, x9); + ASSERT_EQUAL_32(0x89abcdefL, w10); + ASSERT_EQUAL_64(0x00000fff, x11); + ASSERT_EQUAL_64(0x0000000000000fffUL, x12); + ASSERT_EQUAL_64(0x00001ffe, x13); + ASSERT_EQUAL_64(0x0000000000003ffcUL, x14); + ASSERT_EQUAL_64(0x000001ff, x15); + ASSERT_EQUAL_64(0x00000000000000ffUL, x18); + ASSERT_EQUAL_64(0x00000001, x19); + ASSERT_EQUAL_64(0x0, x20); + ASSERT_EQUAL_64(0x7ff80000, x21); + ASSERT_EQUAL_64(0x3ffc000000000000UL, x22); + ASSERT_EQUAL_64(0x000000fe, x23); + ASSERT_EQUAL_64(0xfffffffffffffffcUL, x24); + ASSERT_EQUAL_64(0x00007ff8, x25); + ASSERT_EQUAL_64(0x000000000000fff0UL, x26); + ASSERT_EQUAL_64(0x000000000001ffe0UL, x27); + + TEARDOWN(); +} + + +TEST(mov_imm_w) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(w0, 0xffffffffL); + __ Mov(w1, 0xffff1234L); + __ Mov(w2, 0x1234ffffL); + __ Mov(w3, 0x00000000L); + __ Mov(w4, 0x00001234L); + __ Mov(w5, 0x12340000L); + __ Mov(w6, 0x12345678L); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xffffffffL, x0); + ASSERT_EQUAL_64(0xffff1234L, x1); + ASSERT_EQUAL_64(0x1234ffffL, x2); + ASSERT_EQUAL_64(0x00000000L, x3); + ASSERT_EQUAL_64(0x00001234L, x4); + ASSERT_EQUAL_64(0x12340000L, x5); + ASSERT_EQUAL_64(0x12345678L, x6); + + TEARDOWN(); +} + + +TEST(mov_imm_x) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0xffffffffffffffffL); + __ Mov(x1, 0xffffffffffff1234L); + __ Mov(x2, 0xffffffff12345678L); + __ Mov(x3, 0xffff1234ffff5678L); + __ Mov(x4, 0x1234ffffffff5678L); + __ Mov(x5, 0x1234ffff5678ffffL); + __ Mov(x6, 0x12345678ffffffffL); + __ Mov(x7, 0x1234ffffffffffffL); + __ Mov(x8, 0x123456789abcffffL); + __ Mov(x9, 0x12345678ffff9abcL); + __ Mov(x10, 0x1234ffff56789abcL); + __ Mov(x11, 0xffff123456789abcL); + __ Mov(x12, 0x0000000000000000L); + __ Mov(x13, 0x0000000000001234L); + __ Mov(x14, 0x0000000012345678L); + __ Mov(x15, 0x0000123400005678L); + __ Mov(x18, 0x1234000000005678L); + __ Mov(x19, 0x1234000056780000L); + __ Mov(x20, 0x1234567800000000L); + __ Mov(x21, 0x1234000000000000L); + __ Mov(x22, 0x123456789abc0000L); + __ Mov(x23, 0x1234567800009abcL); + __ Mov(x24, 0x1234000056789abcL); + __ Mov(x25, 0x0000123456789abcL); + __ Mov(x26, 0x123456789abcdef0L); + __ Mov(x27, 0xffff000000000001L); + __ Mov(x28, 0x8000ffff00000000L); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xffffffffffff1234L, x1); + ASSERT_EQUAL_64(0xffffffff12345678L, x2); + ASSERT_EQUAL_64(0xffff1234ffff5678L, x3); + ASSERT_EQUAL_64(0x1234ffffffff5678L, x4); + ASSERT_EQUAL_64(0x1234ffff5678ffffL, x5); + ASSERT_EQUAL_64(0x12345678ffffffffL, x6); + ASSERT_EQUAL_64(0x1234ffffffffffffL, x7); + ASSERT_EQUAL_64(0x123456789abcffffL, x8); + ASSERT_EQUAL_64(0x12345678ffff9abcL, x9); + ASSERT_EQUAL_64(0x1234ffff56789abcL, x10); + ASSERT_EQUAL_64(0xffff123456789abcL, x11); + ASSERT_EQUAL_64(0x0000000000000000L, x12); + ASSERT_EQUAL_64(0x0000000000001234L, x13); + ASSERT_EQUAL_64(0x0000000012345678L, x14); + ASSERT_EQUAL_64(0x0000123400005678L, x15); + ASSERT_EQUAL_64(0x1234000000005678L, x18); + ASSERT_EQUAL_64(0x1234000056780000L, x19); + ASSERT_EQUAL_64(0x1234567800000000L, x20); + ASSERT_EQUAL_64(0x1234000000000000L, x21); + ASSERT_EQUAL_64(0x123456789abc0000L, x22); + ASSERT_EQUAL_64(0x1234567800009abcL, x23); + ASSERT_EQUAL_64(0x1234000056789abcL, x24); + ASSERT_EQUAL_64(0x0000123456789abcL, x25); + ASSERT_EQUAL_64(0x123456789abcdef0L, x26); + ASSERT_EQUAL_64(0xffff000000000001L, x27); + ASSERT_EQUAL_64(0x8000ffff00000000L, x28); + + TEARDOWN(); +} + + +TEST(orr) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0xf0f0); + __ Mov(x1, 0xf00000ff); + + __ Orr(x2, x0, Operand(x1)); + __ Orr(w3, w0, Operand(w1, LSL, 28)); + __ Orr(x4, x0, Operand(x1, LSL, 32)); + __ Orr(x5, x0, Operand(x1, LSR, 4)); + __ Orr(w6, w0, Operand(w1, ASR, 4)); + __ Orr(x7, x0, Operand(x1, ASR, 4)); + __ Orr(w8, w0, Operand(w1, ROR, 12)); + __ Orr(x9, x0, Operand(x1, ROR, 12)); + __ Orr(w10, w0, Operand(0xf)); + __ Orr(x11, x0, Operand(0xf0000000f0000000L)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xf000f0ff, x2); + ASSERT_EQUAL_64(0xf000f0f0, x3); + ASSERT_EQUAL_64(0xf00000ff0000f0f0L, x4); + ASSERT_EQUAL_64(0x0f00f0ff, x5); + ASSERT_EQUAL_64(0xff00f0ff, x6); + ASSERT_EQUAL_64(0x0f00f0ff, x7); + ASSERT_EQUAL_64(0x0ffff0f0, x8); + ASSERT_EQUAL_64(0x0ff00000000ff0f0L, x9); + ASSERT_EQUAL_64(0xf0ff, x10); + ASSERT_EQUAL_64(0xf0000000f000f0f0L, x11); + + TEARDOWN(); +} + + +TEST(orr_extend) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 1); + __ Mov(x1, 0x8000000080008080UL); + __ Orr(w6, w0, Operand(w1, UXTB)); + __ Orr(x7, x0, Operand(x1, UXTH, 1)); + __ Orr(w8, w0, Operand(w1, UXTW, 2)); + __ Orr(x9, x0, Operand(x1, UXTX, 3)); + __ Orr(w10, w0, Operand(w1, SXTB)); + __ Orr(x11, x0, Operand(x1, SXTH, 1)); + __ Orr(x12, x0, Operand(x1, SXTW, 2)); + __ Orr(x13, x0, Operand(x1, SXTX, 3)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x00000081, x6); + ASSERT_EQUAL_64(0x00010101, x7); + ASSERT_EQUAL_64(0x00020201, x8); + ASSERT_EQUAL_64(0x0000000400040401UL, x9); + ASSERT_EQUAL_64(0x00000000ffffff81UL, x10); + ASSERT_EQUAL_64(0xffffffffffff0101UL, x11); + ASSERT_EQUAL_64(0xfffffffe00020201UL, x12); + ASSERT_EQUAL_64(0x0000000400040401UL, x13); + + TEARDOWN(); +} + + +TEST(bitwise_wide_imm) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0); + __ Mov(x1, 0xf0f0f0f0f0f0f0f0UL); + + __ Orr(x10, x0, Operand(0x1234567890abcdefUL)); + __ Orr(w11, w1, Operand(0x90abcdef)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0, x0); + ASSERT_EQUAL_64(0xf0f0f0f0f0f0f0f0UL, x1); + ASSERT_EQUAL_64(0x1234567890abcdefUL, x10); + ASSERT_EQUAL_64(0xf0fbfdffUL, x11); + + TEARDOWN(); +} + + +TEST(orn) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0xf0f0); + __ Mov(x1, 0xf00000ff); + + __ Orn(x2, x0, Operand(x1)); + __ Orn(w3, w0, Operand(w1, LSL, 4)); + __ Orn(x4, x0, Operand(x1, LSL, 4)); + __ Orn(x5, x0, Operand(x1, LSR, 1)); + __ Orn(w6, w0, Operand(w1, ASR, 1)); + __ Orn(x7, x0, Operand(x1, ASR, 1)); + __ Orn(w8, w0, Operand(w1, ROR, 16)); + __ Orn(x9, x0, Operand(x1, ROR, 16)); + __ Orn(w10, w0, Operand(0xffff)); + __ Orn(x11, x0, Operand(0xffff0000ffffL)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xffffffff0ffffff0L, x2); + ASSERT_EQUAL_64(0xfffff0ff, x3); + ASSERT_EQUAL_64(0xfffffff0fffff0ffL, x4); + ASSERT_EQUAL_64(0xffffffff87fffff0L, x5); + ASSERT_EQUAL_64(0x07fffff0, x6); + ASSERT_EQUAL_64(0xffffffff87fffff0L, x7); + ASSERT_EQUAL_64(0xff00ffff, x8); + ASSERT_EQUAL_64(0xff00ffffffffffffL, x9); + ASSERT_EQUAL_64(0xfffff0f0, x10); + ASSERT_EQUAL_64(0xffff0000fffff0f0L, x11); + + TEARDOWN(); +} + + +TEST(orn_extend) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 1); + __ Mov(x1, 0x8000000080008081UL); + __ Orn(w6, w0, Operand(w1, UXTB)); + __ Orn(x7, x0, Operand(x1, UXTH, 1)); + __ Orn(w8, w0, Operand(w1, UXTW, 2)); + __ Orn(x9, x0, Operand(x1, UXTX, 3)); + __ Orn(w10, w0, Operand(w1, SXTB)); + __ Orn(x11, x0, Operand(x1, SXTH, 1)); + __ Orn(x12, x0, Operand(x1, SXTW, 2)); + __ Orn(x13, x0, Operand(x1, SXTX, 3)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xffffff7f, x6); + ASSERT_EQUAL_64(0xfffffffffffefefdUL, x7); + ASSERT_EQUAL_64(0xfffdfdfb, x8); + ASSERT_EQUAL_64(0xfffffffbfffbfbf7UL, x9); + ASSERT_EQUAL_64(0x0000007f, x10); + ASSERT_EQUAL_64(0x0000fefd, x11); + ASSERT_EQUAL_64(0x00000001fffdfdfbUL, x12); + ASSERT_EQUAL_64(0xfffffffbfffbfbf7UL, x13); + + TEARDOWN(); +} + + +TEST(and_) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0xfff0); + __ Mov(x1, 0xf00000ff); + + __ And(x2, x0, Operand(x1)); + __ And(w3, w0, Operand(w1, LSL, 4)); + __ And(x4, x0, Operand(x1, LSL, 4)); + __ And(x5, x0, Operand(x1, LSR, 1)); + __ And(w6, w0, Operand(w1, ASR, 20)); + __ And(x7, x0, Operand(x1, ASR, 20)); + __ And(w8, w0, Operand(w1, ROR, 28)); + __ And(x9, x0, Operand(x1, ROR, 28)); + __ And(w10, w0, Operand(0xff00)); + __ And(x11, x0, Operand(0xff)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x000000f0, x2); + ASSERT_EQUAL_64(0x00000ff0, x3); + ASSERT_EQUAL_64(0x00000ff0, x4); + ASSERT_EQUAL_64(0x00000070, x5); + ASSERT_EQUAL_64(0x0000ff00, x6); + ASSERT_EQUAL_64(0x00000f00, x7); + ASSERT_EQUAL_64(0x00000ff0, x8); + ASSERT_EQUAL_64(0x00000000, x9); + ASSERT_EQUAL_64(0x0000ff00, x10); + ASSERT_EQUAL_64(0x000000f0, x11); + + TEARDOWN(); +} + + +TEST(and_extend) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0xffffffffffffffffUL); + __ Mov(x1, 0x8000000080008081UL); + __ And(w6, w0, Operand(w1, UXTB)); + __ And(x7, x0, Operand(x1, UXTH, 1)); + __ And(w8, w0, Operand(w1, UXTW, 2)); + __ And(x9, x0, Operand(x1, UXTX, 3)); + __ And(w10, w0, Operand(w1, SXTB)); + __ And(x11, x0, Operand(x1, SXTH, 1)); + __ And(x12, x0, Operand(x1, SXTW, 2)); + __ And(x13, x0, Operand(x1, SXTX, 3)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x00000081, x6); + ASSERT_EQUAL_64(0x00010102, x7); + ASSERT_EQUAL_64(0x00020204, x8); + ASSERT_EQUAL_64(0x0000000400040408UL, x9); + ASSERT_EQUAL_64(0xffffff81, x10); + ASSERT_EQUAL_64(0xffffffffffff0102UL, x11); + ASSERT_EQUAL_64(0xfffffffe00020204UL, x12); + ASSERT_EQUAL_64(0x0000000400040408UL, x13); + + TEARDOWN(); +} + + +TEST(ands) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x1, 0xf00000ff); + __ Ands(w0, w1, Operand(w1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + ASSERT_EQUAL_64(0xf00000ff, x0); + + START(); + __ Mov(x0, 0xfff0); + __ Mov(x1, 0xf00000ff); + __ Ands(w0, w0, Operand(w1, LSR, 4)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZFlag); + ASSERT_EQUAL_64(0x00000000, x0); + + START(); + __ Mov(x0, 0x8000000000000000L); + __ Mov(x1, 0x00000001); + __ Ands(x0, x0, Operand(x1, ROR, 1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + ASSERT_EQUAL_64(0x8000000000000000L, x0); + + START(); + __ Mov(x0, 0xfff0); + __ Ands(w0, w0, Operand(0xf)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZFlag); + ASSERT_EQUAL_64(0x00000000, x0); + + START(); + __ Mov(x0, 0xff000000); + __ Ands(w0, w0, Operand(0x80000000)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + ASSERT_EQUAL_64(0x80000000, x0); + + TEARDOWN(); +} + + +TEST(bic) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0xfff0); + __ Mov(x1, 0xf00000ff); + + __ Bic(x2, x0, Operand(x1)); + __ Bic(w3, w0, Operand(w1, LSL, 4)); + __ Bic(x4, x0, Operand(x1, LSL, 4)); + __ Bic(x5, x0, Operand(x1, LSR, 1)); + __ Bic(w6, w0, Operand(w1, ASR, 20)); + __ Bic(x7, x0, Operand(x1, ASR, 20)); + __ Bic(w8, w0, Operand(w1, ROR, 28)); + __ Bic(x9, x0, Operand(x1, ROR, 24)); + __ Bic(x10, x0, Operand(0x1f)); + __ Bic(x11, x0, Operand(0x100)); + + // Test bic into csp when the constant cannot be encoded in the immediate + // field. + // Use x20 to preserve csp. We check for the result via x21 because the + // test infrastructure requires that csp be restored to its original value. + __ Mov(x20, csp); + __ Mov(x0, 0xffffff); + __ Bic(csp, x0, Operand(0xabcdef)); + __ Mov(x21, csp); + __ Mov(csp, x20); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x0000ff00, x2); + ASSERT_EQUAL_64(0x0000f000, x3); + ASSERT_EQUAL_64(0x0000f000, x4); + ASSERT_EQUAL_64(0x0000ff80, x5); + ASSERT_EQUAL_64(0x000000f0, x6); + ASSERT_EQUAL_64(0x0000f0f0, x7); + ASSERT_EQUAL_64(0x0000f000, x8); + ASSERT_EQUAL_64(0x0000ff00, x9); + ASSERT_EQUAL_64(0x0000ffe0, x10); + ASSERT_EQUAL_64(0x0000fef0, x11); + + ASSERT_EQUAL_64(0x543210, x21); + + TEARDOWN(); +} + + +TEST(bic_extend) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0xffffffffffffffffUL); + __ Mov(x1, 0x8000000080008081UL); + __ Bic(w6, w0, Operand(w1, UXTB)); + __ Bic(x7, x0, Operand(x1, UXTH, 1)); + __ Bic(w8, w0, Operand(w1, UXTW, 2)); + __ Bic(x9, x0, Operand(x1, UXTX, 3)); + __ Bic(w10, w0, Operand(w1, SXTB)); + __ Bic(x11, x0, Operand(x1, SXTH, 1)); + __ Bic(x12, x0, Operand(x1, SXTW, 2)); + __ Bic(x13, x0, Operand(x1, SXTX, 3)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xffffff7e, x6); + ASSERT_EQUAL_64(0xfffffffffffefefdUL, x7); + ASSERT_EQUAL_64(0xfffdfdfb, x8); + ASSERT_EQUAL_64(0xfffffffbfffbfbf7UL, x9); + ASSERT_EQUAL_64(0x0000007e, x10); + ASSERT_EQUAL_64(0x0000fefd, x11); + ASSERT_EQUAL_64(0x00000001fffdfdfbUL, x12); + ASSERT_EQUAL_64(0xfffffffbfffbfbf7UL, x13); + + TEARDOWN(); +} + + +TEST(bics) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x1, 0xffff); + __ Bics(w0, w1, Operand(w1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZFlag); + ASSERT_EQUAL_64(0x00000000, x0); + + START(); + __ Mov(x0, 0xffffffff); + __ Bics(w0, w0, Operand(w0, LSR, 1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + ASSERT_EQUAL_64(0x80000000, x0); + + START(); + __ Mov(x0, 0x8000000000000000L); + __ Mov(x1, 0x00000001); + __ Bics(x0, x0, Operand(x1, ROR, 1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZFlag); + ASSERT_EQUAL_64(0x00000000, x0); + + START(); + __ Mov(x0, 0xffffffffffffffffL); + __ Bics(x0, x0, Operand(0x7fffffffffffffffL)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + ASSERT_EQUAL_64(0x8000000000000000L, x0); + + START(); + __ Mov(w0, 0xffff0000); + __ Bics(w0, w0, Operand(0xfffffff0)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZFlag); + ASSERT_EQUAL_64(0x00000000, x0); + + TEARDOWN(); +} + + +TEST(eor) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0xfff0); + __ Mov(x1, 0xf00000ff); + + __ Eor(x2, x0, Operand(x1)); + __ Eor(w3, w0, Operand(w1, LSL, 4)); + __ Eor(x4, x0, Operand(x1, LSL, 4)); + __ Eor(x5, x0, Operand(x1, LSR, 1)); + __ Eor(w6, w0, Operand(w1, ASR, 20)); + __ Eor(x7, x0, Operand(x1, ASR, 20)); + __ Eor(w8, w0, Operand(w1, ROR, 28)); + __ Eor(x9, x0, Operand(x1, ROR, 28)); + __ Eor(w10, w0, Operand(0xff00ff00)); + __ Eor(x11, x0, Operand(0xff00ff00ff00ff00L)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xf000ff0f, x2); + ASSERT_EQUAL_64(0x0000f000, x3); + ASSERT_EQUAL_64(0x0000000f0000f000L, x4); + ASSERT_EQUAL_64(0x7800ff8f, x5); + ASSERT_EQUAL_64(0xffff00f0, x6); + ASSERT_EQUAL_64(0x0000f0f0, x7); + ASSERT_EQUAL_64(0x0000f00f, x8); + ASSERT_EQUAL_64(0x00000ff00000ffffL, x9); + ASSERT_EQUAL_64(0xff0000f0, x10); + ASSERT_EQUAL_64(0xff00ff00ff0000f0L, x11); + + TEARDOWN(); +} + + +TEST(eor_extend) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0x1111111111111111UL); + __ Mov(x1, 0x8000000080008081UL); + __ Eor(w6, w0, Operand(w1, UXTB)); + __ Eor(x7, x0, Operand(x1, UXTH, 1)); + __ Eor(w8, w0, Operand(w1, UXTW, 2)); + __ Eor(x9, x0, Operand(x1, UXTX, 3)); + __ Eor(w10, w0, Operand(w1, SXTB)); + __ Eor(x11, x0, Operand(x1, SXTH, 1)); + __ Eor(x12, x0, Operand(x1, SXTW, 2)); + __ Eor(x13, x0, Operand(x1, SXTX, 3)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x11111190, x6); + ASSERT_EQUAL_64(0x1111111111101013UL, x7); + ASSERT_EQUAL_64(0x11131315, x8); + ASSERT_EQUAL_64(0x1111111511151519UL, x9); + ASSERT_EQUAL_64(0xeeeeee90, x10); + ASSERT_EQUAL_64(0xeeeeeeeeeeee1013UL, x11); + ASSERT_EQUAL_64(0xeeeeeeef11131315UL, x12); + ASSERT_EQUAL_64(0x1111111511151519UL, x13); + + TEARDOWN(); +} + + +TEST(eon) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0xfff0); + __ Mov(x1, 0xf00000ff); + + __ Eon(x2, x0, Operand(x1)); + __ Eon(w3, w0, Operand(w1, LSL, 4)); + __ Eon(x4, x0, Operand(x1, LSL, 4)); + __ Eon(x5, x0, Operand(x1, LSR, 1)); + __ Eon(w6, w0, Operand(w1, ASR, 20)); + __ Eon(x7, x0, Operand(x1, ASR, 20)); + __ Eon(w8, w0, Operand(w1, ROR, 28)); + __ Eon(x9, x0, Operand(x1, ROR, 28)); + __ Eon(w10, w0, Operand(0x03c003c0)); + __ Eon(x11, x0, Operand(0x0000100000001000L)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xffffffff0fff00f0L, x2); + ASSERT_EQUAL_64(0xffff0fff, x3); + ASSERT_EQUAL_64(0xfffffff0ffff0fffL, x4); + ASSERT_EQUAL_64(0xffffffff87ff0070L, x5); + ASSERT_EQUAL_64(0x0000ff0f, x6); + ASSERT_EQUAL_64(0xffffffffffff0f0fL, x7); + ASSERT_EQUAL_64(0xffff0ff0, x8); + ASSERT_EQUAL_64(0xfffff00fffff0000L, x9); + ASSERT_EQUAL_64(0xfc3f03cf, x10); + ASSERT_EQUAL_64(0xffffefffffff100fL, x11); + + TEARDOWN(); +} + + +TEST(eon_extend) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0x1111111111111111UL); + __ Mov(x1, 0x8000000080008081UL); + __ Eon(w6, w0, Operand(w1, UXTB)); + __ Eon(x7, x0, Operand(x1, UXTH, 1)); + __ Eon(w8, w0, Operand(w1, UXTW, 2)); + __ Eon(x9, x0, Operand(x1, UXTX, 3)); + __ Eon(w10, w0, Operand(w1, SXTB)); + __ Eon(x11, x0, Operand(x1, SXTH, 1)); + __ Eon(x12, x0, Operand(x1, SXTW, 2)); + __ Eon(x13, x0, Operand(x1, SXTX, 3)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xeeeeee6f, x6); + ASSERT_EQUAL_64(0xeeeeeeeeeeefefecUL, x7); + ASSERT_EQUAL_64(0xeeececea, x8); + ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6UL, x9); + ASSERT_EQUAL_64(0x1111116f, x10); + ASSERT_EQUAL_64(0x111111111111efecUL, x11); + ASSERT_EQUAL_64(0x11111110eeececeaUL, x12); + ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6UL, x13); + + TEARDOWN(); +} + + +TEST(mul) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x16, 0); + __ Mov(x17, 1); + __ Mov(x18, 0xffffffff); + __ Mov(x19, 0xffffffffffffffffUL); + + __ Mul(w0, w16, w16); + __ Mul(w1, w16, w17); + __ Mul(w2, w17, w18); + __ Mul(w3, w18, w19); + __ Mul(x4, x16, x16); + __ Mul(x5, x17, x18); + __ Mul(x6, x18, x19); + __ Mul(x7, x19, x19); + __ Smull(x8, w17, w18); + __ Smull(x9, w18, w18); + __ Smull(x10, w19, w19); + __ Mneg(w11, w16, w16); + __ Mneg(w12, w16, w17); + __ Mneg(w13, w17, w18); + __ Mneg(w14, w18, w19); + __ Mneg(x20, x16, x16); + __ Mneg(x21, x17, x18); + __ Mneg(x22, x18, x19); + __ Mneg(x23, x19, x19); + END(); + + RUN(); + + ASSERT_EQUAL_64(0, x0); + ASSERT_EQUAL_64(0, x1); + ASSERT_EQUAL_64(0xffffffff, x2); + ASSERT_EQUAL_64(1, x3); + ASSERT_EQUAL_64(0, x4); + ASSERT_EQUAL_64(0xffffffff, x5); + ASSERT_EQUAL_64(0xffffffff00000001UL, x6); + ASSERT_EQUAL_64(1, x7); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x8); + ASSERT_EQUAL_64(1, x9); + ASSERT_EQUAL_64(1, x10); + ASSERT_EQUAL_64(0, x11); + ASSERT_EQUAL_64(0, x12); + ASSERT_EQUAL_64(1, x13); + ASSERT_EQUAL_64(0xffffffff, x14); + ASSERT_EQUAL_64(0, x20); + ASSERT_EQUAL_64(0xffffffff00000001UL, x21); + ASSERT_EQUAL_64(0xffffffff, x22); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x23); + + TEARDOWN(); +} + + +static void SmullHelper(int64_t expected, int64_t a, int64_t b) { + SETUP(); + START(); + __ Mov(w0, a); + __ Mov(w1, b); + __ Smull(x2, w0, w1); + END(); + RUN(); + ASSERT_EQUAL_64(expected, x2); + TEARDOWN(); +} + + +TEST(smull) { + INIT_V8(); + SmullHelper(0, 0, 0); + SmullHelper(1, 1, 1); + SmullHelper(-1, -1, 1); + SmullHelper(1, -1, -1); + SmullHelper(0xffffffff80000000, 0x80000000, 1); + SmullHelper(0x0000000080000000, 0x00010000, 0x00008000); +} + + +TEST(madd) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x16, 0); + __ Mov(x17, 1); + __ Mov(x18, 0xffffffff); + __ Mov(x19, 0xffffffffffffffffUL); + + __ Madd(w0, w16, w16, w16); + __ Madd(w1, w16, w16, w17); + __ Madd(w2, w16, w16, w18); + __ Madd(w3, w16, w16, w19); + __ Madd(w4, w16, w17, w17); + __ Madd(w5, w17, w17, w18); + __ Madd(w6, w17, w17, w19); + __ Madd(w7, w17, w18, w16); + __ Madd(w8, w17, w18, w18); + __ Madd(w9, w18, w18, w17); + __ Madd(w10, w18, w19, w18); + __ Madd(w11, w19, w19, w19); + + __ Madd(x12, x16, x16, x16); + __ Madd(x13, x16, x16, x17); + __ Madd(x14, x16, x16, x18); + __ Madd(x15, x16, x16, x19); + __ Madd(x20, x16, x17, x17); + __ Madd(x21, x17, x17, x18); + __ Madd(x22, x17, x17, x19); + __ Madd(x23, x17, x18, x16); + __ Madd(x24, x17, x18, x18); + __ Madd(x25, x18, x18, x17); + __ Madd(x26, x18, x19, x18); + __ Madd(x27, x19, x19, x19); + + END(); + + RUN(); + + ASSERT_EQUAL_64(0, x0); + ASSERT_EQUAL_64(1, x1); + ASSERT_EQUAL_64(0xffffffff, x2); + ASSERT_EQUAL_64(0xffffffff, x3); + ASSERT_EQUAL_64(1, x4); + ASSERT_EQUAL_64(0, x5); + ASSERT_EQUAL_64(0, x6); + ASSERT_EQUAL_64(0xffffffff, x7); + ASSERT_EQUAL_64(0xfffffffe, x8); + ASSERT_EQUAL_64(2, x9); + ASSERT_EQUAL_64(0, x10); + ASSERT_EQUAL_64(0, x11); + + ASSERT_EQUAL_64(0, x12); + ASSERT_EQUAL_64(1, x13); + ASSERT_EQUAL_64(0xffffffff, x14); + ASSERT_EQUAL_64(0xffffffffffffffff, x15); + ASSERT_EQUAL_64(1, x20); + ASSERT_EQUAL_64(0x100000000UL, x21); + ASSERT_EQUAL_64(0, x22); + ASSERT_EQUAL_64(0xffffffff, x23); + ASSERT_EQUAL_64(0x1fffffffe, x24); + ASSERT_EQUAL_64(0xfffffffe00000002UL, x25); + ASSERT_EQUAL_64(0, x26); + ASSERT_EQUAL_64(0, x27); + + TEARDOWN(); +} + + +TEST(msub) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x16, 0); + __ Mov(x17, 1); + __ Mov(x18, 0xffffffff); + __ Mov(x19, 0xffffffffffffffffUL); + + __ Msub(w0, w16, w16, w16); + __ Msub(w1, w16, w16, w17); + __ Msub(w2, w16, w16, w18); + __ Msub(w3, w16, w16, w19); + __ Msub(w4, w16, w17, w17); + __ Msub(w5, w17, w17, w18); + __ Msub(w6, w17, w17, w19); + __ Msub(w7, w17, w18, w16); + __ Msub(w8, w17, w18, w18); + __ Msub(w9, w18, w18, w17); + __ Msub(w10, w18, w19, w18); + __ Msub(w11, w19, w19, w19); + + __ Msub(x12, x16, x16, x16); + __ Msub(x13, x16, x16, x17); + __ Msub(x14, x16, x16, x18); + __ Msub(x15, x16, x16, x19); + __ Msub(x20, x16, x17, x17); + __ Msub(x21, x17, x17, x18); + __ Msub(x22, x17, x17, x19); + __ Msub(x23, x17, x18, x16); + __ Msub(x24, x17, x18, x18); + __ Msub(x25, x18, x18, x17); + __ Msub(x26, x18, x19, x18); + __ Msub(x27, x19, x19, x19); + + END(); + + RUN(); + + ASSERT_EQUAL_64(0, x0); + ASSERT_EQUAL_64(1, x1); + ASSERT_EQUAL_64(0xffffffff, x2); + ASSERT_EQUAL_64(0xffffffff, x3); + ASSERT_EQUAL_64(1, x4); + ASSERT_EQUAL_64(0xfffffffe, x5); + ASSERT_EQUAL_64(0xfffffffe, x6); + ASSERT_EQUAL_64(1, x7); + ASSERT_EQUAL_64(0, x8); + ASSERT_EQUAL_64(0, x9); + ASSERT_EQUAL_64(0xfffffffe, x10); + ASSERT_EQUAL_64(0xfffffffe, x11); + + ASSERT_EQUAL_64(0, x12); + ASSERT_EQUAL_64(1, x13); + ASSERT_EQUAL_64(0xffffffff, x14); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x15); + ASSERT_EQUAL_64(1, x20); + ASSERT_EQUAL_64(0xfffffffeUL, x21); + ASSERT_EQUAL_64(0xfffffffffffffffeUL, x22); + ASSERT_EQUAL_64(0xffffffff00000001UL, x23); + ASSERT_EQUAL_64(0, x24); + ASSERT_EQUAL_64(0x200000000UL, x25); + ASSERT_EQUAL_64(0x1fffffffeUL, x26); + ASSERT_EQUAL_64(0xfffffffffffffffeUL, x27); + + TEARDOWN(); +} + + +TEST(smulh) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x20, 0); + __ Mov(x21, 1); + __ Mov(x22, 0x0000000100000000L); + __ Mov(x23, 0x12345678); + __ Mov(x24, 0x0123456789abcdefL); + __ Mov(x25, 0x0000000200000000L); + __ Mov(x26, 0x8000000000000000UL); + __ Mov(x27, 0xffffffffffffffffUL); + __ Mov(x28, 0x5555555555555555UL); + __ Mov(x29, 0xaaaaaaaaaaaaaaaaUL); + + __ Smulh(x0, x20, x24); + __ Smulh(x1, x21, x24); + __ Smulh(x2, x22, x23); + __ Smulh(x3, x22, x24); + __ Smulh(x4, x24, x25); + __ Smulh(x5, x23, x27); + __ Smulh(x6, x26, x26); + __ Smulh(x7, x26, x27); + __ Smulh(x8, x27, x27); + __ Smulh(x9, x28, x28); + __ Smulh(x10, x28, x29); + __ Smulh(x11, x29, x29); + END(); + + RUN(); + + ASSERT_EQUAL_64(0, x0); + ASSERT_EQUAL_64(0, x1); + ASSERT_EQUAL_64(0, x2); + ASSERT_EQUAL_64(0x01234567, x3); + ASSERT_EQUAL_64(0x02468acf, x4); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x5); + ASSERT_EQUAL_64(0x4000000000000000UL, x6); + ASSERT_EQUAL_64(0, x7); + ASSERT_EQUAL_64(0, x8); + ASSERT_EQUAL_64(0x1c71c71c71c71c71UL, x9); + ASSERT_EQUAL_64(0xe38e38e38e38e38eUL, x10); + ASSERT_EQUAL_64(0x1c71c71c71c71c72UL, x11); + + TEARDOWN(); +} + + +TEST(smaddl_umaddl) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x17, 1); + __ Mov(x18, 0xffffffff); + __ Mov(x19, 0xffffffffffffffffUL); + __ Mov(x20, 4); + __ Mov(x21, 0x200000000UL); + + __ Smaddl(x9, w17, w18, x20); + __ Smaddl(x10, w18, w18, x20); + __ Smaddl(x11, w19, w19, x20); + __ Smaddl(x12, w19, w19, x21); + __ Umaddl(x13, w17, w18, x20); + __ Umaddl(x14, w18, w18, x20); + __ Umaddl(x15, w19, w19, x20); + __ Umaddl(x22, w19, w19, x21); + END(); + + RUN(); + + ASSERT_EQUAL_64(3, x9); + ASSERT_EQUAL_64(5, x10); + ASSERT_EQUAL_64(5, x11); + ASSERT_EQUAL_64(0x200000001UL, x12); + ASSERT_EQUAL_64(0x100000003UL, x13); + ASSERT_EQUAL_64(0xfffffffe00000005UL, x14); + ASSERT_EQUAL_64(0xfffffffe00000005UL, x15); + ASSERT_EQUAL_64(0x1, x22); + + TEARDOWN(); +} + + +TEST(smsubl_umsubl) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x17, 1); + __ Mov(x18, 0xffffffff); + __ Mov(x19, 0xffffffffffffffffUL); + __ Mov(x20, 4); + __ Mov(x21, 0x200000000UL); + + __ Smsubl(x9, w17, w18, x20); + __ Smsubl(x10, w18, w18, x20); + __ Smsubl(x11, w19, w19, x20); + __ Smsubl(x12, w19, w19, x21); + __ Umsubl(x13, w17, w18, x20); + __ Umsubl(x14, w18, w18, x20); + __ Umsubl(x15, w19, w19, x20); + __ Umsubl(x22, w19, w19, x21); + END(); + + RUN(); + + ASSERT_EQUAL_64(5, x9); + ASSERT_EQUAL_64(3, x10); + ASSERT_EQUAL_64(3, x11); + ASSERT_EQUAL_64(0x1ffffffffUL, x12); + ASSERT_EQUAL_64(0xffffffff00000005UL, x13); + ASSERT_EQUAL_64(0x200000003UL, x14); + ASSERT_EQUAL_64(0x200000003UL, x15); + ASSERT_EQUAL_64(0x3ffffffffUL, x22); + + TEARDOWN(); +} + + +TEST(div) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x16, 1); + __ Mov(x17, 0xffffffff); + __ Mov(x18, 0xffffffffffffffffUL); + __ Mov(x19, 0x80000000); + __ Mov(x20, 0x8000000000000000UL); + __ Mov(x21, 2); + + __ Udiv(w0, w16, w16); + __ Udiv(w1, w17, w16); + __ Sdiv(w2, w16, w16); + __ Sdiv(w3, w16, w17); + __ Sdiv(w4, w17, w18); + + __ Udiv(x5, x16, x16); + __ Udiv(x6, x17, x18); + __ Sdiv(x7, x16, x16); + __ Sdiv(x8, x16, x17); + __ Sdiv(x9, x17, x18); + + __ Udiv(w10, w19, w21); + __ Sdiv(w11, w19, w21); + __ Udiv(x12, x19, x21); + __ Sdiv(x13, x19, x21); + __ Udiv(x14, x20, x21); + __ Sdiv(x15, x20, x21); + + __ Udiv(w22, w19, w17); + __ Sdiv(w23, w19, w17); + __ Udiv(x24, x20, x18); + __ Sdiv(x25, x20, x18); + + __ Udiv(x26, x16, x21); + __ Sdiv(x27, x16, x21); + __ Udiv(x28, x18, x21); + __ Sdiv(x29, x18, x21); + + __ Mov(x17, 0); + __ Udiv(w18, w16, w17); + __ Sdiv(w19, w16, w17); + __ Udiv(x20, x16, x17); + __ Sdiv(x21, x16, x17); + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + ASSERT_EQUAL_64(0xffffffff, x1); + ASSERT_EQUAL_64(1, x2); + ASSERT_EQUAL_64(0xffffffff, x3); + ASSERT_EQUAL_64(1, x4); + ASSERT_EQUAL_64(1, x5); + ASSERT_EQUAL_64(0, x6); + ASSERT_EQUAL_64(1, x7); + ASSERT_EQUAL_64(0, x8); + ASSERT_EQUAL_64(0xffffffff00000001UL, x9); + ASSERT_EQUAL_64(0x40000000, x10); + ASSERT_EQUAL_64(0xC0000000, x11); + ASSERT_EQUAL_64(0x40000000, x12); + ASSERT_EQUAL_64(0x40000000, x13); + ASSERT_EQUAL_64(0x4000000000000000UL, x14); + ASSERT_EQUAL_64(0xC000000000000000UL, x15); + ASSERT_EQUAL_64(0, x22); + ASSERT_EQUAL_64(0x80000000, x23); + ASSERT_EQUAL_64(0, x24); + ASSERT_EQUAL_64(0x8000000000000000UL, x25); + ASSERT_EQUAL_64(0, x26); + ASSERT_EQUAL_64(0, x27); + ASSERT_EQUAL_64(0x7fffffffffffffffUL, x28); + ASSERT_EQUAL_64(0, x29); + ASSERT_EQUAL_64(0, x18); + ASSERT_EQUAL_64(0, x19); + ASSERT_EQUAL_64(0, x20); + ASSERT_EQUAL_64(0, x21); + + TEARDOWN(); +} + + +TEST(rbit_rev) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x24, 0xfedcba9876543210UL); + __ Rbit(w0, w24); + __ Rbit(x1, x24); + __ Rev16(w2, w24); + __ Rev16(x3, x24); + __ Rev(w4, w24); + __ Rev32(x5, x24); + __ Rev(x6, x24); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x084c2a6e, x0); + ASSERT_EQUAL_64(0x084c2a6e195d3b7fUL, x1); + ASSERT_EQUAL_64(0x54761032, x2); + ASSERT_EQUAL_64(0xdcfe98ba54761032UL, x3); + ASSERT_EQUAL_64(0x10325476, x4); + ASSERT_EQUAL_64(0x98badcfe10325476UL, x5); + ASSERT_EQUAL_64(0x1032547698badcfeUL, x6); + + TEARDOWN(); +} + + +TEST(clz_cls) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x24, 0x0008000000800000UL); + __ Mov(x25, 0xff800000fff80000UL); + __ Mov(x26, 0); + __ Clz(w0, w24); + __ Clz(x1, x24); + __ Clz(w2, w25); + __ Clz(x3, x25); + __ Clz(w4, w26); + __ Clz(x5, x26); + __ Cls(w6, w24); + __ Cls(x7, x24); + __ Cls(w8, w25); + __ Cls(x9, x25); + __ Cls(w10, w26); + __ Cls(x11, x26); + END(); + + RUN(); + + ASSERT_EQUAL_64(8, x0); + ASSERT_EQUAL_64(12, x1); + ASSERT_EQUAL_64(0, x2); + ASSERT_EQUAL_64(0, x3); + ASSERT_EQUAL_64(32, x4); + ASSERT_EQUAL_64(64, x5); + ASSERT_EQUAL_64(7, x6); + ASSERT_EQUAL_64(11, x7); + ASSERT_EQUAL_64(12, x8); + ASSERT_EQUAL_64(8, x9); + ASSERT_EQUAL_64(31, x10); + ASSERT_EQUAL_64(63, x11); + + TEARDOWN(); +} + + +TEST(label) { + INIT_V8(); + SETUP(); + + Label label_1, label_2, label_3, label_4; + + START(); + __ Mov(x0, 0x1); + __ Mov(x1, 0x0); + __ Mov(x22, lr); // Save lr. + + __ B(&label_1); + __ B(&label_1); + __ B(&label_1); // Multiple branches to the same label. + __ Mov(x0, 0x0); + __ Bind(&label_2); + __ B(&label_3); // Forward branch. + __ Mov(x0, 0x0); + __ Bind(&label_1); + __ B(&label_2); // Backward branch. + __ Mov(x0, 0x0); + __ Bind(&label_3); + __ Bl(&label_4); + END(); + + __ Bind(&label_4); + __ Mov(x1, 0x1); + __ Mov(lr, x22); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x1, x0); + ASSERT_EQUAL_64(0x1, x1); + + TEARDOWN(); +} + + +TEST(branch_at_start) { + INIT_V8(); + SETUP(); + + Label good, exit; + + // Test that branches can exist at the start of the buffer. (This is a + // boundary condition in the label-handling code.) To achieve this, we have + // to work around the code generated by START. + RESET(); + __ B(&good); + + START_AFTER_RESET(); + __ Mov(x0, 0x0); + END(); + + __ Bind(&exit); + START_AFTER_RESET(); + __ Mov(x0, 0x1); + END(); + + __ Bind(&good); + __ B(&exit); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x1, x0); + TEARDOWN(); +} + + +TEST(adr) { + INIT_V8(); + SETUP(); + + Label label_1, label_2, label_3, label_4; + + START(); + __ Mov(x0, 0x0); // Set to non-zero to indicate failure. + __ Adr(x1, &label_3); // Set to zero to indicate success. + + __ Adr(x2, &label_1); // Multiple forward references to the same label. + __ Adr(x3, &label_1); + __ Adr(x4, &label_1); + + __ Bind(&label_2); + __ Eor(x5, x2, Operand(x3)); // Ensure that x2,x3 and x4 are identical. + __ Eor(x6, x2, Operand(x4)); + __ Orr(x0, x0, Operand(x5)); + __ Orr(x0, x0, Operand(x6)); + __ Br(x2); // label_1, label_3 + + __ Bind(&label_3); + __ Adr(x2, &label_3); // Self-reference (offset 0). + __ Eor(x1, x1, Operand(x2)); + __ Adr(x2, &label_4); // Simple forward reference. + __ Br(x2); // label_4 + + __ Bind(&label_1); + __ Adr(x2, &label_3); // Multiple reverse references to the same label. + __ Adr(x3, &label_3); + __ Adr(x4, &label_3); + __ Adr(x5, &label_2); // Simple reverse reference. + __ Br(x5); // label_2 + + __ Bind(&label_4); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x0, x0); + ASSERT_EQUAL_64(0x0, x1); + + TEARDOWN(); +} + + +TEST(branch_cond) { + INIT_V8(); + SETUP(); + + Label wrong; + + START(); + __ Mov(x0, 0x1); + __ Mov(x1, 0x1); + __ Mov(x2, 0x8000000000000000L); + + // For each 'cmp' instruction below, condition codes other than the ones + // following it would branch. + + __ Cmp(x1, 0); + __ B(&wrong, eq); + __ B(&wrong, lo); + __ B(&wrong, mi); + __ B(&wrong, vs); + __ B(&wrong, ls); + __ B(&wrong, lt); + __ B(&wrong, le); + Label ok_1; + __ B(&ok_1, ne); + __ Mov(x0, 0x0); + __ Bind(&ok_1); + + __ Cmp(x1, 1); + __ B(&wrong, ne); + __ B(&wrong, lo); + __ B(&wrong, mi); + __ B(&wrong, vs); + __ B(&wrong, hi); + __ B(&wrong, lt); + __ B(&wrong, gt); + Label ok_2; + __ B(&ok_2, pl); + __ Mov(x0, 0x0); + __ Bind(&ok_2); + + __ Cmp(x1, 2); + __ B(&wrong, eq); + __ B(&wrong, hs); + __ B(&wrong, pl); + __ B(&wrong, vs); + __ B(&wrong, hi); + __ B(&wrong, ge); + __ B(&wrong, gt); + Label ok_3; + __ B(&ok_3, vc); + __ Mov(x0, 0x0); + __ Bind(&ok_3); + + __ Cmp(x2, 1); + __ B(&wrong, eq); + __ B(&wrong, lo); + __ B(&wrong, mi); + __ B(&wrong, vc); + __ B(&wrong, ls); + __ B(&wrong, ge); + __ B(&wrong, gt); + Label ok_4; + __ B(&ok_4, le); + __ Mov(x0, 0x0); + __ Bind(&ok_4); + + Label ok_5; + __ b(&ok_5, al); + __ Mov(x0, 0x0); + __ Bind(&ok_5); + + Label ok_6; + __ b(&ok_6, nv); + __ Mov(x0, 0x0); + __ Bind(&ok_6); + + END(); + + __ Bind(&wrong); + __ Mov(x0, 0x0); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x1, x0); + + TEARDOWN(); +} + + +TEST(branch_to_reg) { + INIT_V8(); + SETUP(); + + // Test br. + Label fn1, after_fn1; + + START(); + __ Mov(x29, lr); + + __ Mov(x1, 0); + __ B(&after_fn1); + + __ Bind(&fn1); + __ Mov(x0, lr); + __ Mov(x1, 42); + __ Br(x0); + + __ Bind(&after_fn1); + __ Bl(&fn1); + + // Test blr. + Label fn2, after_fn2; + + __ Mov(x2, 0); + __ B(&after_fn2); + + __ Bind(&fn2); + __ Mov(x0, lr); + __ Mov(x2, 84); + __ Blr(x0); + + __ Bind(&after_fn2); + __ Bl(&fn2); + __ Mov(x3, lr); + + __ Mov(lr, x29); + END(); + + RUN(); + + ASSERT_EQUAL_64(core.xreg(3) + kInstructionSize, x0); + ASSERT_EQUAL_64(42, x1); + ASSERT_EQUAL_64(84, x2); + + TEARDOWN(); +} + + +TEST(compare_branch) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0); + __ Mov(x1, 0); + __ Mov(x2, 0); + __ Mov(x3, 0); + __ Mov(x4, 0); + __ Mov(x5, 0); + __ Mov(x16, 0); + __ Mov(x17, 42); + + Label zt, zt_end; + __ Cbz(w16, &zt); + __ B(&zt_end); + __ Bind(&zt); + __ Mov(x0, 1); + __ Bind(&zt_end); + + Label zf, zf_end; + __ Cbz(x17, &zf); + __ B(&zf_end); + __ Bind(&zf); + __ Mov(x1, 1); + __ Bind(&zf_end); + + Label nzt, nzt_end; + __ Cbnz(w17, &nzt); + __ B(&nzt_end); + __ Bind(&nzt); + __ Mov(x2, 1); + __ Bind(&nzt_end); + + Label nzf, nzf_end; + __ Cbnz(x16, &nzf); + __ B(&nzf_end); + __ Bind(&nzf); + __ Mov(x3, 1); + __ Bind(&nzf_end); + + __ Mov(x18, 0xffffffff00000000UL); + + Label a, a_end; + __ Cbz(w18, &a); + __ B(&a_end); + __ Bind(&a); + __ Mov(x4, 1); + __ Bind(&a_end); + + Label b, b_end; + __ Cbnz(w18, &b); + __ B(&b_end); + __ Bind(&b); + __ Mov(x5, 1); + __ Bind(&b_end); + + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + ASSERT_EQUAL_64(0, x1); + ASSERT_EQUAL_64(1, x2); + ASSERT_EQUAL_64(0, x3); + ASSERT_EQUAL_64(1, x4); + ASSERT_EQUAL_64(0, x5); + + TEARDOWN(); +} + + +TEST(test_branch) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0); + __ Mov(x1, 0); + __ Mov(x2, 0); + __ Mov(x3, 0); + __ Mov(x16, 0xaaaaaaaaaaaaaaaaUL); + + Label bz, bz_end; + __ Tbz(w16, 0, &bz); + __ B(&bz_end); + __ Bind(&bz); + __ Mov(x0, 1); + __ Bind(&bz_end); + + Label bo, bo_end; + __ Tbz(x16, 63, &bo); + __ B(&bo_end); + __ Bind(&bo); + __ Mov(x1, 1); + __ Bind(&bo_end); + + Label nbz, nbz_end; + __ Tbnz(x16, 61, &nbz); + __ B(&nbz_end); + __ Bind(&nbz); + __ Mov(x2, 1); + __ Bind(&nbz_end); + + Label nbo, nbo_end; + __ Tbnz(w16, 2, &nbo); + __ B(&nbo_end); + __ Bind(&nbo); + __ Mov(x3, 1); + __ Bind(&nbo_end); + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + ASSERT_EQUAL_64(0, x1); + ASSERT_EQUAL_64(1, x2); + ASSERT_EQUAL_64(0, x3); + + TEARDOWN(); +} + + +TEST(far_branch_backward) { + INIT_V8(); + + // Test that the MacroAssembler correctly resolves backward branches to labels + // that are outside the immediate range of branch instructions. + int max_range = + std::max(Instruction::ImmBranchRange(TestBranchType), + std::max(Instruction::ImmBranchRange(CompareBranchType), + Instruction::ImmBranchRange(CondBranchType))); + + SETUP_SIZE(max_range + 1000 * kInstructionSize); + + START(); + + Label done, fail; + Label test_tbz, test_cbz, test_bcond; + Label success_tbz, success_cbz, success_bcond; + + __ Mov(x0, 0); + __ Mov(x1, 1); + __ Mov(x10, 0); + + __ B(&test_tbz); + __ Bind(&success_tbz); + __ Orr(x0, x0, 1 << 0); + __ B(&test_cbz); + __ Bind(&success_cbz); + __ Orr(x0, x0, 1 << 1); + __ B(&test_bcond); + __ Bind(&success_bcond); + __ Orr(x0, x0, 1 << 2); + + __ B(&done); + + // Generate enough code to overflow the immediate range of the three types of + // branches below. + for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) { + if (i % 100 == 0) { + // If we do land in this code, we do not want to execute so many nops + // before reaching the end of test (especially if tracing is activated). + __ B(&fail); + } else { + __ Nop(); + } + } + __ B(&fail); + + __ Bind(&test_tbz); + __ Tbz(x10, 7, &success_tbz); + __ Bind(&test_cbz); + __ Cbz(x10, &success_cbz); + __ Bind(&test_bcond); + __ Cmp(x10, 0); + __ B(eq, &success_bcond); + + // For each out-of-range branch instructions, at least two instructions should + // have been generated. + CHECK_GE(7 * kInstructionSize, __ SizeOfCodeGeneratedSince(&test_tbz)); + + __ Bind(&fail); + __ Mov(x1, 0); + __ Bind(&done); + + END(); + + RUN(); + + ASSERT_EQUAL_64(0x7, x0); + ASSERT_EQUAL_64(0x1, x1); + + TEARDOWN(); +} + + +TEST(far_branch_simple_veneer) { + INIT_V8(); + + // Test that the MacroAssembler correctly emits veneers for forward branches + // to labels that are outside the immediate range of branch instructions. + int max_range = + std::max(Instruction::ImmBranchRange(TestBranchType), + std::max(Instruction::ImmBranchRange(CompareBranchType), + Instruction::ImmBranchRange(CondBranchType))); + + SETUP_SIZE(max_range + 1000 * kInstructionSize); + + START(); + + Label done, fail; + Label test_tbz, test_cbz, test_bcond; + Label success_tbz, success_cbz, success_bcond; + + __ Mov(x0, 0); + __ Mov(x1, 1); + __ Mov(x10, 0); + + __ Bind(&test_tbz); + __ Tbz(x10, 7, &success_tbz); + __ Bind(&test_cbz); + __ Cbz(x10, &success_cbz); + __ Bind(&test_bcond); + __ Cmp(x10, 0); + __ B(eq, &success_bcond); + + // Generate enough code to overflow the immediate range of the three types of + // branches below. + for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) { + if (i % 100 == 0) { + // If we do land in this code, we do not want to execute so many nops + // before reaching the end of test (especially if tracing is activated). + // Also, the branches give the MacroAssembler the opportunity to emit the + // veneers. + __ B(&fail); + } else { + __ Nop(); + } + } + __ B(&fail); + + __ Bind(&success_tbz); + __ Orr(x0, x0, 1 << 0); + __ B(&test_cbz); + __ Bind(&success_cbz); + __ Orr(x0, x0, 1 << 1); + __ B(&test_bcond); + __ Bind(&success_bcond); + __ Orr(x0, x0, 1 << 2); + + __ B(&done); + __ Bind(&fail); + __ Mov(x1, 0); + __ Bind(&done); + + END(); + + RUN(); + + ASSERT_EQUAL_64(0x7, x0); + ASSERT_EQUAL_64(0x1, x1); + + TEARDOWN(); +} + + +TEST(far_branch_veneer_link_chain) { + INIT_V8(); + + // Test that the MacroAssembler correctly emits veneers for forward branches + // that target out-of-range labels and are part of multiple instructions + // jumping to that label. + // + // We test the three situations with the different types of instruction: + // (1)- When the branch is at the start of the chain with tbz. + // (2)- When the branch is in the middle of the chain with cbz. + // (3)- When the branch is at the end of the chain with bcond. + int max_range = + std::max(Instruction::ImmBranchRange(TestBranchType), + std::max(Instruction::ImmBranchRange(CompareBranchType), + Instruction::ImmBranchRange(CondBranchType))); + + SETUP_SIZE(max_range + 1000 * kInstructionSize); + + START(); + + Label skip, fail, done; + Label test_tbz, test_cbz, test_bcond; + Label success_tbz, success_cbz, success_bcond; + + __ Mov(x0, 0); + __ Mov(x1, 1); + __ Mov(x10, 0); + + __ B(&skip); + // Branches at the start of the chain for situations (2) and (3). + __ B(&success_cbz); + __ B(&success_bcond); + __ Nop(); + __ B(&success_bcond); + __ B(&success_cbz); + __ Bind(&skip); + + __ Bind(&test_tbz); + __ Tbz(x10, 7, &success_tbz); + __ Bind(&test_cbz); + __ Cbz(x10, &success_cbz); + __ Bind(&test_bcond); + __ Cmp(x10, 0); + __ B(eq, &success_bcond); + + skip.Unuse(); + __ B(&skip); + // Branches at the end of the chain for situations (1) and (2). + __ B(&success_cbz); + __ B(&success_tbz); + __ Nop(); + __ B(&success_tbz); + __ B(&success_cbz); + __ Bind(&skip); + + // Generate enough code to overflow the immediate range of the three types of + // branches below. + for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) { + if (i % 100 == 0) { + // If we do land in this code, we do not want to execute so many nops + // before reaching the end of test (especially if tracing is activated). + // Also, the branches give the MacroAssembler the opportunity to emit the + // veneers. + __ B(&fail); + } else { + __ Nop(); + } + } + __ B(&fail); + + __ Bind(&success_tbz); + __ Orr(x0, x0, 1 << 0); + __ B(&test_cbz); + __ Bind(&success_cbz); + __ Orr(x0, x0, 1 << 1); + __ B(&test_bcond); + __ Bind(&success_bcond); + __ Orr(x0, x0, 1 << 2); + + __ B(&done); + __ Bind(&fail); + __ Mov(x1, 0); + __ Bind(&done); + + END(); + + RUN(); + + ASSERT_EQUAL_64(0x7, x0); + ASSERT_EQUAL_64(0x1, x1); + + TEARDOWN(); +} + + +TEST(far_branch_veneer_broken_link_chain) { + INIT_V8(); + + // Check that the MacroAssembler correctly handles the situation when removing + // a branch from the link chain of a label and the two links on each side of + // the removed branch cannot be linked together (out of range). + // + // We test with tbz because it has a small range. + int max_range = Instruction::ImmBranchRange(TestBranchType); + int inter_range = max_range / 2 + max_range / 10; + + SETUP_SIZE(3 * inter_range + 1000 * kInstructionSize); + + START(); + + Label skip, fail, done; + Label test_1, test_2, test_3; + Label far_target; + + __ Mov(x0, 0); // Indicates the origin of the branch. + __ Mov(x1, 1); + __ Mov(x10, 0); + + // First instruction in the label chain. + __ Bind(&test_1); + __ Mov(x0, 1); + __ B(&far_target); + + for (unsigned i = 0; i < inter_range / kInstructionSize; ++i) { + if (i % 100 == 0) { + // Do not allow generating veneers. They should not be needed. + __ b(&fail); + } else { + __ Nop(); + } + } + + // Will need a veneer to point to reach the target. + __ Bind(&test_2); + __ Mov(x0, 2); + __ Tbz(x10, 7, &far_target); + + for (unsigned i = 0; i < inter_range / kInstructionSize; ++i) { + if (i % 100 == 0) { + // Do not allow generating veneers. They should not be needed. + __ b(&fail); + } else { + __ Nop(); + } + } + + // Does not need a veneer to reach the target, but the initial branch + // instruction is out of range. + __ Bind(&test_3); + __ Mov(x0, 3); + __ Tbz(x10, 7, &far_target); + + for (unsigned i = 0; i < inter_range / kInstructionSize; ++i) { + if (i % 100 == 0) { + // Allow generating veneers. + __ B(&fail); + } else { + __ Nop(); + } + } + + __ B(&fail); + + __ Bind(&far_target); + __ Cmp(x0, 1); + __ B(eq, &test_2); + __ Cmp(x0, 2); + __ B(eq, &test_3); + + __ B(&done); + __ Bind(&fail); + __ Mov(x1, 0); + __ Bind(&done); + + END(); + + RUN(); + + ASSERT_EQUAL_64(0x3, x0); + ASSERT_EQUAL_64(0x1, x1); + + TEARDOWN(); +} + + +TEST(ldr_str_offset) { + INIT_V8(); + SETUP(); + + uint64_t src[2] = {0xfedcba9876543210UL, 0x0123456789abcdefUL}; + uint64_t dst[5] = {0, 0, 0, 0, 0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x17, src_base); + __ Mov(x18, dst_base); + __ Ldr(w0, MemOperand(x17)); + __ Str(w0, MemOperand(x18)); + __ Ldr(w1, MemOperand(x17, 4)); + __ Str(w1, MemOperand(x18, 12)); + __ Ldr(x2, MemOperand(x17, 8)); + __ Str(x2, MemOperand(x18, 16)); + __ Ldrb(w3, MemOperand(x17, 1)); + __ Strb(w3, MemOperand(x18, 25)); + __ Ldrh(w4, MemOperand(x17, 2)); + __ Strh(w4, MemOperand(x18, 33)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x76543210, x0); + ASSERT_EQUAL_64(0x76543210, dst[0]); + ASSERT_EQUAL_64(0xfedcba98, x1); + ASSERT_EQUAL_64(0xfedcba9800000000UL, dst[1]); + ASSERT_EQUAL_64(0x0123456789abcdefUL, x2); + ASSERT_EQUAL_64(0x0123456789abcdefUL, dst[2]); + ASSERT_EQUAL_64(0x32, x3); + ASSERT_EQUAL_64(0x3200, dst[3]); + ASSERT_EQUAL_64(0x7654, x4); + ASSERT_EQUAL_64(0x765400, dst[4]); + ASSERT_EQUAL_64(src_base, x17); + ASSERT_EQUAL_64(dst_base, x18); + + TEARDOWN(); +} + + +TEST(ldr_str_wide) { + INIT_V8(); + SETUP(); + + uint32_t src[8192]; + uint32_t dst[8192]; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + memset(src, 0xaa, 8192 * sizeof(src[0])); + memset(dst, 0xaa, 8192 * sizeof(dst[0])); + src[0] = 0; + src[6144] = 6144; + src[8191] = 8191; + + START(); + __ Mov(x22, src_base); + __ Mov(x23, dst_base); + __ Mov(x24, src_base); + __ Mov(x25, dst_base); + __ Mov(x26, src_base); + __ Mov(x27, dst_base); + + __ Ldr(w0, MemOperand(x22, 8191 * sizeof(src[0]))); + __ Str(w0, MemOperand(x23, 8191 * sizeof(dst[0]))); + __ Ldr(w1, MemOperand(x24, 4096 * sizeof(src[0]), PostIndex)); + __ Str(w1, MemOperand(x25, 4096 * sizeof(dst[0]), PostIndex)); + __ Ldr(w2, MemOperand(x26, 6144 * sizeof(src[0]), PreIndex)); + __ Str(w2, MemOperand(x27, 6144 * sizeof(dst[0]), PreIndex)); + END(); + + RUN(); + + ASSERT_EQUAL_32(8191, w0); + ASSERT_EQUAL_32(8191, dst[8191]); + ASSERT_EQUAL_64(src_base, x22); + ASSERT_EQUAL_64(dst_base, x23); + ASSERT_EQUAL_32(0, w1); + ASSERT_EQUAL_32(0, dst[0]); + ASSERT_EQUAL_64(src_base + 4096 * sizeof(src[0]), x24); + ASSERT_EQUAL_64(dst_base + 4096 * sizeof(dst[0]), x25); + ASSERT_EQUAL_32(6144, w2); + ASSERT_EQUAL_32(6144, dst[6144]); + ASSERT_EQUAL_64(src_base + 6144 * sizeof(src[0]), x26); + ASSERT_EQUAL_64(dst_base + 6144 * sizeof(dst[0]), x27); + + TEARDOWN(); +} + + +TEST(ldr_str_preindex) { + INIT_V8(); + SETUP(); + + uint64_t src[2] = {0xfedcba9876543210UL, 0x0123456789abcdefUL}; + uint64_t dst[6] = {0, 0, 0, 0, 0, 0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x17, src_base); + __ Mov(x18, dst_base); + __ Mov(x19, src_base); + __ Mov(x20, dst_base); + __ Mov(x21, src_base + 16); + __ Mov(x22, dst_base + 40); + __ Mov(x23, src_base); + __ Mov(x24, dst_base); + __ Mov(x25, src_base); + __ Mov(x26, dst_base); + __ Ldr(w0, MemOperand(x17, 4, PreIndex)); + __ Str(w0, MemOperand(x18, 12, PreIndex)); + __ Ldr(x1, MemOperand(x19, 8, PreIndex)); + __ Str(x1, MemOperand(x20, 16, PreIndex)); + __ Ldr(w2, MemOperand(x21, -4, PreIndex)); + __ Str(w2, MemOperand(x22, -4, PreIndex)); + __ Ldrb(w3, MemOperand(x23, 1, PreIndex)); + __ Strb(w3, MemOperand(x24, 25, PreIndex)); + __ Ldrh(w4, MemOperand(x25, 3, PreIndex)); + __ Strh(w4, MemOperand(x26, 41, PreIndex)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xfedcba98, x0); + ASSERT_EQUAL_64(0xfedcba9800000000UL, dst[1]); + ASSERT_EQUAL_64(0x0123456789abcdefUL, x1); + ASSERT_EQUAL_64(0x0123456789abcdefUL, dst[2]); + ASSERT_EQUAL_64(0x01234567, x2); + ASSERT_EQUAL_64(0x0123456700000000UL, dst[4]); + ASSERT_EQUAL_64(0x32, x3); + ASSERT_EQUAL_64(0x3200, dst[3]); + ASSERT_EQUAL_64(0x9876, x4); + ASSERT_EQUAL_64(0x987600, dst[5]); + ASSERT_EQUAL_64(src_base + 4, x17); + ASSERT_EQUAL_64(dst_base + 12, x18); + ASSERT_EQUAL_64(src_base + 8, x19); + ASSERT_EQUAL_64(dst_base + 16, x20); + ASSERT_EQUAL_64(src_base + 12, x21); + ASSERT_EQUAL_64(dst_base + 36, x22); + ASSERT_EQUAL_64(src_base + 1, x23); + ASSERT_EQUAL_64(dst_base + 25, x24); + ASSERT_EQUAL_64(src_base + 3, x25); + ASSERT_EQUAL_64(dst_base + 41, x26); + + TEARDOWN(); +} + + +TEST(ldr_str_postindex) { + INIT_V8(); + SETUP(); + + uint64_t src[2] = {0xfedcba9876543210UL, 0x0123456789abcdefUL}; + uint64_t dst[6] = {0, 0, 0, 0, 0, 0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x17, src_base + 4); + __ Mov(x18, dst_base + 12); + __ Mov(x19, src_base + 8); + __ Mov(x20, dst_base + 16); + __ Mov(x21, src_base + 8); + __ Mov(x22, dst_base + 32); + __ Mov(x23, src_base + 1); + __ Mov(x24, dst_base + 25); + __ Mov(x25, src_base + 3); + __ Mov(x26, dst_base + 41); + __ Ldr(w0, MemOperand(x17, 4, PostIndex)); + __ Str(w0, MemOperand(x18, 12, PostIndex)); + __ Ldr(x1, MemOperand(x19, 8, PostIndex)); + __ Str(x1, MemOperand(x20, 16, PostIndex)); + __ Ldr(x2, MemOperand(x21, -8, PostIndex)); + __ Str(x2, MemOperand(x22, -32, PostIndex)); + __ Ldrb(w3, MemOperand(x23, 1, PostIndex)); + __ Strb(w3, MemOperand(x24, 5, PostIndex)); + __ Ldrh(w4, MemOperand(x25, -3, PostIndex)); + __ Strh(w4, MemOperand(x26, -41, PostIndex)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xfedcba98, x0); + ASSERT_EQUAL_64(0xfedcba9800000000UL, dst[1]); + ASSERT_EQUAL_64(0x0123456789abcdefUL, x1); + ASSERT_EQUAL_64(0x0123456789abcdefUL, dst[2]); + ASSERT_EQUAL_64(0x0123456789abcdefUL, x2); + ASSERT_EQUAL_64(0x0123456789abcdefUL, dst[4]); + ASSERT_EQUAL_64(0x32, x3); + ASSERT_EQUAL_64(0x3200, dst[3]); + ASSERT_EQUAL_64(0x9876, x4); + ASSERT_EQUAL_64(0x987600, dst[5]); + ASSERT_EQUAL_64(src_base + 8, x17); + ASSERT_EQUAL_64(dst_base + 24, x18); + ASSERT_EQUAL_64(src_base + 16, x19); + ASSERT_EQUAL_64(dst_base + 32, x20); + ASSERT_EQUAL_64(src_base, x21); + ASSERT_EQUAL_64(dst_base, x22); + ASSERT_EQUAL_64(src_base + 2, x23); + ASSERT_EQUAL_64(dst_base + 30, x24); + ASSERT_EQUAL_64(src_base, x25); + ASSERT_EQUAL_64(dst_base, x26); + + TEARDOWN(); +} + + +TEST(load_signed) { + INIT_V8(); + SETUP(); + + uint32_t src[2] = {0x80008080, 0x7fff7f7f}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + + START(); + __ Mov(x24, src_base); + __ Ldrsb(w0, MemOperand(x24)); + __ Ldrsb(w1, MemOperand(x24, 4)); + __ Ldrsh(w2, MemOperand(x24)); + __ Ldrsh(w3, MemOperand(x24, 4)); + __ Ldrsb(x4, MemOperand(x24)); + __ Ldrsb(x5, MemOperand(x24, 4)); + __ Ldrsh(x6, MemOperand(x24)); + __ Ldrsh(x7, MemOperand(x24, 4)); + __ Ldrsw(x8, MemOperand(x24)); + __ Ldrsw(x9, MemOperand(x24, 4)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xffffff80, x0); + ASSERT_EQUAL_64(0x0000007f, x1); + ASSERT_EQUAL_64(0xffff8080, x2); + ASSERT_EQUAL_64(0x00007f7f, x3); + ASSERT_EQUAL_64(0xffffffffffffff80UL, x4); + ASSERT_EQUAL_64(0x000000000000007fUL, x5); + ASSERT_EQUAL_64(0xffffffffffff8080UL, x6); + ASSERT_EQUAL_64(0x0000000000007f7fUL, x7); + ASSERT_EQUAL_64(0xffffffff80008080UL, x8); + ASSERT_EQUAL_64(0x000000007fff7f7fUL, x9); + + TEARDOWN(); +} + + +TEST(load_store_regoffset) { + INIT_V8(); + SETUP(); + + uint32_t src[3] = {1, 2, 3}; + uint32_t dst[4] = {0, 0, 0, 0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x16, src_base); + __ Mov(x17, dst_base); + __ Mov(x18, src_base + 3 * sizeof(src[0])); + __ Mov(x19, dst_base + 3 * sizeof(dst[0])); + __ Mov(x20, dst_base + 4 * sizeof(dst[0])); + __ Mov(x24, 0); + __ Mov(x25, 4); + __ Mov(x26, -4); + __ Mov(x27, 0xfffffffc); // 32-bit -4. + __ Mov(x28, 0xfffffffe); // 32-bit -2. + __ Mov(x29, 0xffffffff); // 32-bit -1. + + __ Ldr(w0, MemOperand(x16, x24)); + __ Ldr(x1, MemOperand(x16, x25)); + __ Ldr(w2, MemOperand(x18, x26)); + __ Ldr(w3, MemOperand(x18, x27, SXTW)); + __ Ldr(w4, MemOperand(x18, x28, SXTW, 2)); + __ Str(w0, MemOperand(x17, x24)); + __ Str(x1, MemOperand(x17, x25)); + __ Str(w2, MemOperand(x20, x29, SXTW, 2)); + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + ASSERT_EQUAL_64(0x0000000300000002UL, x1); + ASSERT_EQUAL_64(3, x2); + ASSERT_EQUAL_64(3, x3); + ASSERT_EQUAL_64(2, x4); + ASSERT_EQUAL_32(1, dst[0]); + ASSERT_EQUAL_32(2, dst[1]); + ASSERT_EQUAL_32(3, dst[2]); + ASSERT_EQUAL_32(3, dst[3]); + + TEARDOWN(); +} + + +TEST(load_store_float) { + INIT_V8(); + SETUP(); + + float src[3] = {1.0, 2.0, 3.0}; + float dst[3] = {0.0, 0.0, 0.0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x17, src_base); + __ Mov(x18, dst_base); + __ Mov(x19, src_base); + __ Mov(x20, dst_base); + __ Mov(x21, src_base); + __ Mov(x22, dst_base); + __ Ldr(s0, MemOperand(x17, sizeof(src[0]))); + __ Str(s0, MemOperand(x18, sizeof(dst[0]), PostIndex)); + __ Ldr(s1, MemOperand(x19, sizeof(src[0]), PostIndex)); + __ Str(s1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex)); + __ Ldr(s2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex)); + __ Str(s2, MemOperand(x22, sizeof(dst[0]))); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(2.0, s0); + ASSERT_EQUAL_FP32(2.0, dst[0]); + ASSERT_EQUAL_FP32(1.0, s1); + ASSERT_EQUAL_FP32(1.0, dst[2]); + ASSERT_EQUAL_FP32(3.0, s2); + ASSERT_EQUAL_FP32(3.0, dst[1]); + ASSERT_EQUAL_64(src_base, x17); + ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18); + ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19); + ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20); + ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21); + ASSERT_EQUAL_64(dst_base, x22); + + TEARDOWN(); +} + + +TEST(load_store_double) { + INIT_V8(); + SETUP(); + + double src[3] = {1.0, 2.0, 3.0}; + double dst[3] = {0.0, 0.0, 0.0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x17, src_base); + __ Mov(x18, dst_base); + __ Mov(x19, src_base); + __ Mov(x20, dst_base); + __ Mov(x21, src_base); + __ Mov(x22, dst_base); + __ Ldr(d0, MemOperand(x17, sizeof(src[0]))); + __ Str(d0, MemOperand(x18, sizeof(dst[0]), PostIndex)); + __ Ldr(d1, MemOperand(x19, sizeof(src[0]), PostIndex)); + __ Str(d1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex)); + __ Ldr(d2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex)); + __ Str(d2, MemOperand(x22, sizeof(dst[0]))); + END(); + + RUN(); + + ASSERT_EQUAL_FP64(2.0, d0); + ASSERT_EQUAL_FP64(2.0, dst[0]); + ASSERT_EQUAL_FP64(1.0, d1); + ASSERT_EQUAL_FP64(1.0, dst[2]); + ASSERT_EQUAL_FP64(3.0, d2); + ASSERT_EQUAL_FP64(3.0, dst[1]); + ASSERT_EQUAL_64(src_base, x17); + ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18); + ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19); + ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20); + ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21); + ASSERT_EQUAL_64(dst_base, x22); + + TEARDOWN(); +} + + +TEST(ldp_stp_float) { + INIT_V8(); + SETUP(); + + float src[2] = {1.0, 2.0}; + float dst[3] = {0.0, 0.0, 0.0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x16, src_base); + __ Mov(x17, dst_base); + __ Ldp(s31, s0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex)); + __ Stp(s0, s31, MemOperand(x17, sizeof(dst[1]), PreIndex)); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(1.0, s31); + ASSERT_EQUAL_FP32(2.0, s0); + ASSERT_EQUAL_FP32(0.0, dst[0]); + ASSERT_EQUAL_FP32(2.0, dst[1]); + ASSERT_EQUAL_FP32(1.0, dst[2]); + ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16); + ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17); + + TEARDOWN(); +} + + +TEST(ldp_stp_double) { + INIT_V8(); + SETUP(); + + double src[2] = {1.0, 2.0}; + double dst[3] = {0.0, 0.0, 0.0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x16, src_base); + __ Mov(x17, dst_base); + __ Ldp(d31, d0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex)); + __ Stp(d0, d31, MemOperand(x17, sizeof(dst[1]), PreIndex)); + END(); + + RUN(); + + ASSERT_EQUAL_FP64(1.0, d31); + ASSERT_EQUAL_FP64(2.0, d0); + ASSERT_EQUAL_FP64(0.0, dst[0]); + ASSERT_EQUAL_FP64(2.0, dst[1]); + ASSERT_EQUAL_FP64(1.0, dst[2]); + ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16); + ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17); + + TEARDOWN(); +} + + +TEST(ldp_stp_offset) { + INIT_V8(); + SETUP(); + + uint64_t src[3] = {0x0011223344556677UL, 0x8899aabbccddeeffUL, + 0xffeeddccbbaa9988UL}; + uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x16, src_base); + __ Mov(x17, dst_base); + __ Mov(x18, src_base + 24); + __ Mov(x19, dst_base + 56); + __ Ldp(w0, w1, MemOperand(x16)); + __ Ldp(w2, w3, MemOperand(x16, 4)); + __ Ldp(x4, x5, MemOperand(x16, 8)); + __ Ldp(w6, w7, MemOperand(x18, -12)); + __ Ldp(x8, x9, MemOperand(x18, -16)); + __ Stp(w0, w1, MemOperand(x17)); + __ Stp(w2, w3, MemOperand(x17, 8)); + __ Stp(x4, x5, MemOperand(x17, 16)); + __ Stp(w6, w7, MemOperand(x19, -24)); + __ Stp(x8, x9, MemOperand(x19, -16)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x44556677, x0); + ASSERT_EQUAL_64(0x00112233, x1); + ASSERT_EQUAL_64(0x0011223344556677UL, dst[0]); + ASSERT_EQUAL_64(0x00112233, x2); + ASSERT_EQUAL_64(0xccddeeff, x3); + ASSERT_EQUAL_64(0xccddeeff00112233UL, dst[1]); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x4); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[2]); + ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x5); + ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]); + ASSERT_EQUAL_64(0x8899aabb, x6); + ASSERT_EQUAL_64(0xbbaa9988, x7); + ASSERT_EQUAL_64(0xbbaa99888899aabbUL, dst[4]); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x8); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[5]); + ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x9); + ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]); + ASSERT_EQUAL_64(src_base, x16); + ASSERT_EQUAL_64(dst_base, x17); + ASSERT_EQUAL_64(src_base + 24, x18); + ASSERT_EQUAL_64(dst_base + 56, x19); + + TEARDOWN(); +} + + +TEST(ldnp_stnp_offset) { + INIT_V8(); + SETUP(); + + uint64_t src[3] = {0x0011223344556677UL, 0x8899aabbccddeeffUL, + 0xffeeddccbbaa9988UL}; + uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x16, src_base); + __ Mov(x17, dst_base); + __ Mov(x18, src_base + 24); + __ Mov(x19, dst_base + 56); + __ Ldnp(w0, w1, MemOperand(x16)); + __ Ldnp(w2, w3, MemOperand(x16, 4)); + __ Ldnp(x4, x5, MemOperand(x16, 8)); + __ Ldnp(w6, w7, MemOperand(x18, -12)); + __ Ldnp(x8, x9, MemOperand(x18, -16)); + __ Stnp(w0, w1, MemOperand(x17)); + __ Stnp(w2, w3, MemOperand(x17, 8)); + __ Stnp(x4, x5, MemOperand(x17, 16)); + __ Stnp(w6, w7, MemOperand(x19, -24)); + __ Stnp(x8, x9, MemOperand(x19, -16)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x44556677, x0); + ASSERT_EQUAL_64(0x00112233, x1); + ASSERT_EQUAL_64(0x0011223344556677UL, dst[0]); + ASSERT_EQUAL_64(0x00112233, x2); + ASSERT_EQUAL_64(0xccddeeff, x3); + ASSERT_EQUAL_64(0xccddeeff00112233UL, dst[1]); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x4); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[2]); + ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x5); + ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]); + ASSERT_EQUAL_64(0x8899aabb, x6); + ASSERT_EQUAL_64(0xbbaa9988, x7); + ASSERT_EQUAL_64(0xbbaa99888899aabbUL, dst[4]); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x8); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[5]); + ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x9); + ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]); + ASSERT_EQUAL_64(src_base, x16); + ASSERT_EQUAL_64(dst_base, x17); + ASSERT_EQUAL_64(src_base + 24, x18); + ASSERT_EQUAL_64(dst_base + 56, x19); + + TEARDOWN(); +} + + +TEST(ldp_stp_preindex) { + INIT_V8(); + SETUP(); + + uint64_t src[3] = {0x0011223344556677UL, 0x8899aabbccddeeffUL, + 0xffeeddccbbaa9988UL}; + uint64_t dst[5] = {0, 0, 0, 0, 0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x16, src_base); + __ Mov(x17, dst_base); + __ Mov(x18, dst_base + 16); + __ Ldp(w0, w1, MemOperand(x16, 4, PreIndex)); + __ Mov(x19, x16); + __ Ldp(w2, w3, MemOperand(x16, -4, PreIndex)); + __ Stp(w2, w3, MemOperand(x17, 4, PreIndex)); + __ Mov(x20, x17); + __ Stp(w0, w1, MemOperand(x17, -4, PreIndex)); + __ Ldp(x4, x5, MemOperand(x16, 8, PreIndex)); + __ Mov(x21, x16); + __ Ldp(x6, x7, MemOperand(x16, -8, PreIndex)); + __ Stp(x7, x6, MemOperand(x18, 8, PreIndex)); + __ Mov(x22, x18); + __ Stp(x5, x4, MemOperand(x18, -8, PreIndex)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x00112233, x0); + ASSERT_EQUAL_64(0xccddeeff, x1); + ASSERT_EQUAL_64(0x44556677, x2); + ASSERT_EQUAL_64(0x00112233, x3); + ASSERT_EQUAL_64(0xccddeeff00112233UL, dst[0]); + ASSERT_EQUAL_64(0x0000000000112233UL, dst[1]); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x4); + ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x5); + ASSERT_EQUAL_64(0x0011223344556677UL, x6); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x7); + ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[3]); + ASSERT_EQUAL_64(0x0011223344556677UL, dst[4]); + ASSERT_EQUAL_64(src_base, x16); + ASSERT_EQUAL_64(dst_base, x17); + ASSERT_EQUAL_64(dst_base + 16, x18); + ASSERT_EQUAL_64(src_base + 4, x19); + ASSERT_EQUAL_64(dst_base + 4, x20); + ASSERT_EQUAL_64(src_base + 8, x21); + ASSERT_EQUAL_64(dst_base + 24, x22); + + TEARDOWN(); +} + + +TEST(ldp_stp_postindex) { + INIT_V8(); + SETUP(); + + uint64_t src[4] = {0x0011223344556677UL, 0x8899aabbccddeeffUL, + 0xffeeddccbbaa9988UL, 0x7766554433221100UL}; + uint64_t dst[5] = {0, 0, 0, 0, 0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x16, src_base); + __ Mov(x17, dst_base); + __ Mov(x18, dst_base + 16); + __ Ldp(w0, w1, MemOperand(x16, 4, PostIndex)); + __ Mov(x19, x16); + __ Ldp(w2, w3, MemOperand(x16, -4, PostIndex)); + __ Stp(w2, w3, MemOperand(x17, 4, PostIndex)); + __ Mov(x20, x17); + __ Stp(w0, w1, MemOperand(x17, -4, PostIndex)); + __ Ldp(x4, x5, MemOperand(x16, 8, PostIndex)); + __ Mov(x21, x16); + __ Ldp(x6, x7, MemOperand(x16, -8, PostIndex)); + __ Stp(x7, x6, MemOperand(x18, 8, PostIndex)); + __ Mov(x22, x18); + __ Stp(x5, x4, MemOperand(x18, -8, PostIndex)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x44556677, x0); + ASSERT_EQUAL_64(0x00112233, x1); + ASSERT_EQUAL_64(0x00112233, x2); + ASSERT_EQUAL_64(0xccddeeff, x3); + ASSERT_EQUAL_64(0x4455667700112233UL, dst[0]); + ASSERT_EQUAL_64(0x0000000000112233UL, dst[1]); + ASSERT_EQUAL_64(0x0011223344556677UL, x4); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x5); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, x6); + ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, x7); + ASSERT_EQUAL_64(0xffeeddccbbaa9988UL, dst[2]); + ASSERT_EQUAL_64(0x8899aabbccddeeffUL, dst[3]); + ASSERT_EQUAL_64(0x0011223344556677UL, dst[4]); + ASSERT_EQUAL_64(src_base, x16); + ASSERT_EQUAL_64(dst_base, x17); + ASSERT_EQUAL_64(dst_base + 16, x18); + ASSERT_EQUAL_64(src_base + 4, x19); + ASSERT_EQUAL_64(dst_base + 4, x20); + ASSERT_EQUAL_64(src_base + 8, x21); + ASSERT_EQUAL_64(dst_base + 24, x22); + + TEARDOWN(); +} + + +TEST(ldp_sign_extend) { + INIT_V8(); + SETUP(); + + uint32_t src[2] = {0x80000000, 0x7fffffff}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + + START(); + __ Mov(x24, src_base); + __ Ldpsw(x0, x1, MemOperand(x24)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xffffffff80000000UL, x0); + ASSERT_EQUAL_64(0x000000007fffffffUL, x1); + + TEARDOWN(); +} + + +TEST(ldur_stur) { + INIT_V8(); + SETUP(); + + int64_t src[2] = {0x0123456789abcdefUL, 0x0123456789abcdefUL}; + int64_t dst[5] = {0, 0, 0, 0, 0}; + uintptr_t src_base = reinterpret_cast<uintptr_t>(src); + uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); + + START(); + __ Mov(x17, src_base); + __ Mov(x18, dst_base); + __ Mov(x19, src_base + 16); + __ Mov(x20, dst_base + 32); + __ Mov(x21, dst_base + 40); + __ Ldr(w0, MemOperand(x17, 1)); + __ Str(w0, MemOperand(x18, 2)); + __ Ldr(x1, MemOperand(x17, 3)); + __ Str(x1, MemOperand(x18, 9)); + __ Ldr(w2, MemOperand(x19, -9)); + __ Str(w2, MemOperand(x20, -5)); + __ Ldrb(w3, MemOperand(x19, -1)); + __ Strb(w3, MemOperand(x21, -1)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x6789abcd, x0); + ASSERT_EQUAL_64(0x6789abcd0000L, dst[0]); + ASSERT_EQUAL_64(0xabcdef0123456789L, x1); + ASSERT_EQUAL_64(0xcdef012345678900L, dst[1]); + ASSERT_EQUAL_64(0x000000ab, dst[2]); + ASSERT_EQUAL_64(0xabcdef01, x2); + ASSERT_EQUAL_64(0x00abcdef01000000L, dst[3]); + ASSERT_EQUAL_64(0x00000001, x3); + ASSERT_EQUAL_64(0x0100000000000000L, dst[4]); + ASSERT_EQUAL_64(src_base, x17); + ASSERT_EQUAL_64(dst_base, x18); + ASSERT_EQUAL_64(src_base + 16, x19); + ASSERT_EQUAL_64(dst_base + 32, x20); + + TEARDOWN(); +} + + +#if 0 // TODO(all) enable. +// TODO(rodolph): Adapt w16 Literal tests for RelocInfo. +TEST(ldr_literal) { + INIT_V8(); + SETUP(); + + START(); + __ Ldr(x2, 0x1234567890abcdefUL); + __ Ldr(w3, 0xfedcba09); + __ Ldr(d13, 1.234); + __ Ldr(s25, 2.5); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x1234567890abcdefUL, x2); + ASSERT_EQUAL_64(0xfedcba09, x3); + ASSERT_EQUAL_FP64(1.234, d13); + ASSERT_EQUAL_FP32(2.5, s25); + + TEARDOWN(); +} + + +static void LdrLiteralRangeHelper(ptrdiff_t range_, + LiteralPoolEmitOption option, + bool expect_dump) { + ASSERT(range_ > 0); + SETUP_SIZE(range_ + 1024); + + Label label_1, label_2; + + size_t range = static_cast<size_t>(range_); + size_t code_size = 0; + size_t pool_guard_size; + + if (option == NoJumpRequired) { + // Space for an explicit branch. + pool_guard_size = sizeof(Instr); + } else { + pool_guard_size = 0; + } + + START(); + // Force a pool dump so the pool starts off empty. + __ EmitLiteralPool(JumpRequired); + ASSERT_LITERAL_POOL_SIZE(0); + + __ Ldr(x0, 0x1234567890abcdefUL); + __ Ldr(w1, 0xfedcba09); + __ Ldr(d0, 1.234); + __ Ldr(s1, 2.5); + ASSERT_LITERAL_POOL_SIZE(4); + + code_size += 4 * sizeof(Instr); + + // Check that the requested range (allowing space for a branch over the pool) + // can be handled by this test. + ASSERT((code_size + pool_guard_size) <= range); + + // Emit NOPs up to 'range', leaving space for the pool guard. + while ((code_size + pool_guard_size) < range) { + __ Nop(); + code_size += sizeof(Instr); + } + + // Emit the guard sequence before the literal pool. + if (option == NoJumpRequired) { + __ B(&label_1); + code_size += sizeof(Instr); + } + + ASSERT(code_size == range); + ASSERT_LITERAL_POOL_SIZE(4); + + // Possibly generate a literal pool. + __ CheckLiteralPool(option); + __ Bind(&label_1); + if (expect_dump) { + ASSERT_LITERAL_POOL_SIZE(0); + } else { + ASSERT_LITERAL_POOL_SIZE(4); + } + + // Force a pool flush to check that a second pool functions correctly. + __ EmitLiteralPool(JumpRequired); + ASSERT_LITERAL_POOL_SIZE(0); + + // These loads should be after the pool (and will require a new one). + __ Ldr(x4, 0x34567890abcdef12UL); + __ Ldr(w5, 0xdcba09fe); + __ Ldr(d4, 123.4); + __ Ldr(s5, 250.0); + ASSERT_LITERAL_POOL_SIZE(4); + END(); + + RUN(); + + // Check that the literals loaded correctly. + ASSERT_EQUAL_64(0x1234567890abcdefUL, x0); + ASSERT_EQUAL_64(0xfedcba09, x1); + ASSERT_EQUAL_FP64(1.234, d0); + ASSERT_EQUAL_FP32(2.5, s1); + ASSERT_EQUAL_64(0x34567890abcdef12UL, x4); + ASSERT_EQUAL_64(0xdcba09fe, x5); + ASSERT_EQUAL_FP64(123.4, d4); + ASSERT_EQUAL_FP32(250.0, s5); + + TEARDOWN(); +} + + +TEST(ldr_literal_range_1) { + INIT_V8(); + LdrLiteralRangeHelper(kRecommendedLiteralPoolRange, + NoJumpRequired, + true); +} + + +TEST(ldr_literal_range_2) { + INIT_V8(); + LdrLiteralRangeHelper(kRecommendedLiteralPoolRange-sizeof(Instr), + NoJumpRequired, + false); +} + + +TEST(ldr_literal_range_3) { + INIT_V8(); + LdrLiteralRangeHelper(2 * kRecommendedLiteralPoolRange, + JumpRequired, + true); +} + + +TEST(ldr_literal_range_4) { + INIT_V8(); + LdrLiteralRangeHelper(2 * kRecommendedLiteralPoolRange-sizeof(Instr), + JumpRequired, + false); +} + + +TEST(ldr_literal_range_5) { + INIT_V8(); + LdrLiteralRangeHelper(kLiteralPoolCheckInterval, + JumpRequired, + false); +} + + +TEST(ldr_literal_range_6) { + INIT_V8(); + LdrLiteralRangeHelper(kLiteralPoolCheckInterval-sizeof(Instr), + JumpRequired, + false); +} +#endif + +TEST(add_sub_imm) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0x0); + __ Mov(x1, 0x1111); + __ Mov(x2, 0xffffffffffffffffL); + __ Mov(x3, 0x8000000000000000L); + + __ Add(x10, x0, Operand(0x123)); + __ Add(x11, x1, Operand(0x122000)); + __ Add(x12, x0, Operand(0xabc << 12)); + __ Add(x13, x2, Operand(1)); + + __ Add(w14, w0, Operand(0x123)); + __ Add(w15, w1, Operand(0x122000)); + __ Add(w16, w0, Operand(0xabc << 12)); + __ Add(w17, w2, Operand(1)); + + __ Sub(x20, x0, Operand(0x1)); + __ Sub(x21, x1, Operand(0x111)); + __ Sub(x22, x1, Operand(0x1 << 12)); + __ Sub(x23, x3, Operand(1)); + + __ Sub(w24, w0, Operand(0x1)); + __ Sub(w25, w1, Operand(0x111)); + __ Sub(w26, w1, Operand(0x1 << 12)); + __ Sub(w27, w3, Operand(1)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x123, x10); + ASSERT_EQUAL_64(0x123111, x11); + ASSERT_EQUAL_64(0xabc000, x12); + ASSERT_EQUAL_64(0x0, x13); + + ASSERT_EQUAL_32(0x123, w14); + ASSERT_EQUAL_32(0x123111, w15); + ASSERT_EQUAL_32(0xabc000, w16); + ASSERT_EQUAL_32(0x0, w17); + + ASSERT_EQUAL_64(0xffffffffffffffffL, x20); + ASSERT_EQUAL_64(0x1000, x21); + ASSERT_EQUAL_64(0x111, x22); + ASSERT_EQUAL_64(0x7fffffffffffffffL, x23); + + ASSERT_EQUAL_32(0xffffffff, w24); + ASSERT_EQUAL_32(0x1000, w25); + ASSERT_EQUAL_32(0x111, w26); + ASSERT_EQUAL_32(0xffffffff, w27); + + TEARDOWN(); +} + + +TEST(add_sub_wide_imm) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0x0); + __ Mov(x1, 0x1); + + __ Add(x10, x0, Operand(0x1234567890abcdefUL)); + __ Add(x11, x1, Operand(0xffffffff)); + + __ Add(w12, w0, Operand(0x12345678)); + __ Add(w13, w1, Operand(0xffffffff)); + + __ Sub(x20, x0, Operand(0x1234567890abcdefUL)); + + __ Sub(w21, w0, Operand(0x12345678)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x1234567890abcdefUL, x10); + ASSERT_EQUAL_64(0x100000000UL, x11); + + ASSERT_EQUAL_32(0x12345678, w12); + ASSERT_EQUAL_64(0x0, x13); + + ASSERT_EQUAL_64(-0x1234567890abcdefUL, x20); + + ASSERT_EQUAL_32(-0x12345678, w21); + + TEARDOWN(); +} + + +TEST(add_sub_shifted) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0); + __ Mov(x1, 0x0123456789abcdefL); + __ Mov(x2, 0xfedcba9876543210L); + __ Mov(x3, 0xffffffffffffffffL); + + __ Add(x10, x1, Operand(x2)); + __ Add(x11, x0, Operand(x1, LSL, 8)); + __ Add(x12, x0, Operand(x1, LSR, 8)); + __ Add(x13, x0, Operand(x1, ASR, 8)); + __ Add(x14, x0, Operand(x2, ASR, 8)); + __ Add(w15, w0, Operand(w1, ASR, 8)); + __ Add(w18, w3, Operand(w1, ROR, 8)); + __ Add(x19, x3, Operand(x1, ROR, 8)); + + __ Sub(x20, x3, Operand(x2)); + __ Sub(x21, x3, Operand(x1, LSL, 8)); + __ Sub(x22, x3, Operand(x1, LSR, 8)); + __ Sub(x23, x3, Operand(x1, ASR, 8)); + __ Sub(x24, x3, Operand(x2, ASR, 8)); + __ Sub(w25, w3, Operand(w1, ASR, 8)); + __ Sub(w26, w3, Operand(w1, ROR, 8)); + __ Sub(x27, x3, Operand(x1, ROR, 8)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xffffffffffffffffL, x10); + ASSERT_EQUAL_64(0x23456789abcdef00L, x11); + ASSERT_EQUAL_64(0x000123456789abcdL, x12); + ASSERT_EQUAL_64(0x000123456789abcdL, x13); + ASSERT_EQUAL_64(0xfffedcba98765432L, x14); + ASSERT_EQUAL_64(0xff89abcd, x15); + ASSERT_EQUAL_64(0xef89abcc, x18); + ASSERT_EQUAL_64(0xef0123456789abccL, x19); + + ASSERT_EQUAL_64(0x0123456789abcdefL, x20); + ASSERT_EQUAL_64(0xdcba9876543210ffL, x21); + ASSERT_EQUAL_64(0xfffedcba98765432L, x22); + ASSERT_EQUAL_64(0xfffedcba98765432L, x23); + ASSERT_EQUAL_64(0x000123456789abcdL, x24); + ASSERT_EQUAL_64(0x00765432, x25); + ASSERT_EQUAL_64(0x10765432, x26); + ASSERT_EQUAL_64(0x10fedcba98765432L, x27); + + TEARDOWN(); +} + + +TEST(add_sub_extended) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0); + __ Mov(x1, 0x0123456789abcdefL); + __ Mov(x2, 0xfedcba9876543210L); + __ Mov(w3, 0x80); + + __ Add(x10, x0, Operand(x1, UXTB, 0)); + __ Add(x11, x0, Operand(x1, UXTB, 1)); + __ Add(x12, x0, Operand(x1, UXTH, 2)); + __ Add(x13, x0, Operand(x1, UXTW, 4)); + + __ Add(x14, x0, Operand(x1, SXTB, 0)); + __ Add(x15, x0, Operand(x1, SXTB, 1)); + __ Add(x16, x0, Operand(x1, SXTH, 2)); + __ Add(x17, x0, Operand(x1, SXTW, 3)); + __ Add(x18, x0, Operand(x2, SXTB, 0)); + __ Add(x19, x0, Operand(x2, SXTB, 1)); + __ Add(x20, x0, Operand(x2, SXTH, 2)); + __ Add(x21, x0, Operand(x2, SXTW, 3)); + + __ Add(x22, x1, Operand(x2, SXTB, 1)); + __ Sub(x23, x1, Operand(x2, SXTB, 1)); + + __ Add(w24, w1, Operand(w2, UXTB, 2)); + __ Add(w25, w0, Operand(w1, SXTB, 0)); + __ Add(w26, w0, Operand(w1, SXTB, 1)); + __ Add(w27, w2, Operand(w1, SXTW, 3)); + + __ Add(w28, w0, Operand(w1, SXTW, 3)); + __ Add(x29, x0, Operand(w1, SXTW, 3)); + + __ Sub(x30, x0, Operand(w3, SXTB, 1)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xefL, x10); + ASSERT_EQUAL_64(0x1deL, x11); + ASSERT_EQUAL_64(0x337bcL, x12); + ASSERT_EQUAL_64(0x89abcdef0L, x13); + + ASSERT_EQUAL_64(0xffffffffffffffefL, x14); + ASSERT_EQUAL_64(0xffffffffffffffdeL, x15); + ASSERT_EQUAL_64(0xffffffffffff37bcL, x16); + ASSERT_EQUAL_64(0xfffffffc4d5e6f78L, x17); + ASSERT_EQUAL_64(0x10L, x18); + ASSERT_EQUAL_64(0x20L, x19); + ASSERT_EQUAL_64(0xc840L, x20); + ASSERT_EQUAL_64(0x3b2a19080L, x21); + + ASSERT_EQUAL_64(0x0123456789abce0fL, x22); + ASSERT_EQUAL_64(0x0123456789abcdcfL, x23); + + ASSERT_EQUAL_32(0x89abce2f, w24); + ASSERT_EQUAL_32(0xffffffef, w25); + ASSERT_EQUAL_32(0xffffffde, w26); + ASSERT_EQUAL_32(0xc3b2a188, w27); + + ASSERT_EQUAL_32(0x4d5e6f78, w28); + ASSERT_EQUAL_64(0xfffffffc4d5e6f78L, x29); + + ASSERT_EQUAL_64(256, x30); + + TEARDOWN(); +} + + +TEST(add_sub_negative) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0); + __ Mov(x1, 4687); + __ Mov(x2, 0x1122334455667788); + __ Mov(w3, 0x11223344); + __ Mov(w4, 400000); + + __ Add(x10, x0, -42); + __ Add(x11, x1, -687); + __ Add(x12, x2, -0x88); + + __ Sub(x13, x0, -600); + __ Sub(x14, x1, -313); + __ Sub(x15, x2, -0x555); + + __ Add(w19, w3, -0x344); + __ Add(w20, w4, -2000); + + __ Sub(w21, w3, -0xbc); + __ Sub(w22, w4, -2000); + END(); + + RUN(); + + ASSERT_EQUAL_64(-42, x10); + ASSERT_EQUAL_64(4000, x11); + ASSERT_EQUAL_64(0x1122334455667700, x12); + + ASSERT_EQUAL_64(600, x13); + ASSERT_EQUAL_64(5000, x14); + ASSERT_EQUAL_64(0x1122334455667cdd, x15); + + ASSERT_EQUAL_32(0x11223000, w19); + ASSERT_EQUAL_32(398000, w20); + + ASSERT_EQUAL_32(0x11223400, w21); + ASSERT_EQUAL_32(402000, w22); + + TEARDOWN(); +} + + +TEST(add_sub_zero) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0); + __ Mov(x1, 0); + __ Mov(x2, 0); + + Label blob1; + __ Bind(&blob1); + __ Add(x0, x0, 0); + __ Sub(x1, x1, 0); + __ Sub(x2, x2, xzr); + CHECK_EQ(0, __ SizeOfCodeGeneratedSince(&blob1)); + + Label blob2; + __ Bind(&blob2); + __ Add(w3, w3, 0); + CHECK_NE(0, __ SizeOfCodeGeneratedSince(&blob2)); + + Label blob3; + __ Bind(&blob3); + __ Sub(w3, w3, wzr); + CHECK_NE(0, __ SizeOfCodeGeneratedSince(&blob3)); + + END(); + + RUN(); + + ASSERT_EQUAL_64(0, x0); + ASSERT_EQUAL_64(0, x1); + ASSERT_EQUAL_64(0, x2); + + TEARDOWN(); +} + + +TEST(claim_drop_zero) { + INIT_V8(); + SETUP(); + + START(); + + Label start; + __ Bind(&start); + __ Claim(0); + __ Drop(0); + __ Claim(xzr, 8); + __ Drop(xzr, 8); + __ Claim(xzr, 0); + __ Drop(xzr, 0); + __ Claim(x7, 0); + __ Drop(x7, 0); + __ ClaimBySMI(xzr, 8); + __ DropBySMI(xzr, 8); + __ ClaimBySMI(xzr, 0); + __ DropBySMI(xzr, 0); + CHECK_EQ(0, __ SizeOfCodeGeneratedSince(&start)); + + END(); + + RUN(); + + TEARDOWN(); +} + + +TEST(neg) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0xf123456789abcdefL); + + // Immediate. + __ Neg(x1, 0x123); + __ Neg(w2, 0x123); + + // Shifted. + __ Neg(x3, Operand(x0, LSL, 1)); + __ Neg(w4, Operand(w0, LSL, 2)); + __ Neg(x5, Operand(x0, LSR, 3)); + __ Neg(w6, Operand(w0, LSR, 4)); + __ Neg(x7, Operand(x0, ASR, 5)); + __ Neg(w8, Operand(w0, ASR, 6)); + + // Extended. + __ Neg(w9, Operand(w0, UXTB)); + __ Neg(x10, Operand(x0, SXTB, 1)); + __ Neg(w11, Operand(w0, UXTH, 2)); + __ Neg(x12, Operand(x0, SXTH, 3)); + __ Neg(w13, Operand(w0, UXTW, 4)); + __ Neg(x14, Operand(x0, SXTW, 4)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xfffffffffffffeddUL, x1); + ASSERT_EQUAL_64(0xfffffedd, x2); + ASSERT_EQUAL_64(0x1db97530eca86422UL, x3); + ASSERT_EQUAL_64(0xd950c844, x4); + ASSERT_EQUAL_64(0xe1db97530eca8643UL, x5); + ASSERT_EQUAL_64(0xf7654322, x6); + ASSERT_EQUAL_64(0x0076e5d4c3b2a191UL, x7); + ASSERT_EQUAL_64(0x01d950c9, x8); + ASSERT_EQUAL_64(0xffffff11, x9); + ASSERT_EQUAL_64(0x0000000000000022UL, x10); + ASSERT_EQUAL_64(0xfffcc844, x11); + ASSERT_EQUAL_64(0x0000000000019088UL, x12); + ASSERT_EQUAL_64(0x65432110, x13); + ASSERT_EQUAL_64(0x0000000765432110UL, x14); + + TEARDOWN(); +} + + +TEST(adc_sbc_shift) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0); + __ Mov(x1, 1); + __ Mov(x2, 0x0123456789abcdefL); + __ Mov(x3, 0xfedcba9876543210L); + __ Mov(x4, 0xffffffffffffffffL); + + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + + __ Adc(x5, x2, Operand(x3)); + __ Adc(x6, x0, Operand(x1, LSL, 60)); + __ Sbc(x7, x4, Operand(x3, LSR, 4)); + __ Adc(x8, x2, Operand(x3, ASR, 4)); + __ Adc(x9, x2, Operand(x3, ROR, 8)); + + __ Adc(w10, w2, Operand(w3)); + __ Adc(w11, w0, Operand(w1, LSL, 30)); + __ Sbc(w12, w4, Operand(w3, LSR, 4)); + __ Adc(w13, w2, Operand(w3, ASR, 4)); + __ Adc(w14, w2, Operand(w3, ROR, 8)); + + // Set the C flag. + __ Cmp(w0, Operand(w0)); + + __ Adc(x18, x2, Operand(x3)); + __ Adc(x19, x0, Operand(x1, LSL, 60)); + __ Sbc(x20, x4, Operand(x3, LSR, 4)); + __ Adc(x21, x2, Operand(x3, ASR, 4)); + __ Adc(x22, x2, Operand(x3, ROR, 8)); + + __ Adc(w23, w2, Operand(w3)); + __ Adc(w24, w0, Operand(w1, LSL, 30)); + __ Sbc(w25, w4, Operand(w3, LSR, 4)); + __ Adc(w26, w2, Operand(w3, ASR, 4)); + __ Adc(w27, w2, Operand(w3, ROR, 8)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xffffffffffffffffL, x5); + ASSERT_EQUAL_64(1L << 60, x6); + ASSERT_EQUAL_64(0xf0123456789abcddL, x7); + ASSERT_EQUAL_64(0x0111111111111110L, x8); + ASSERT_EQUAL_64(0x1222222222222221L, x9); + + ASSERT_EQUAL_32(0xffffffff, w10); + ASSERT_EQUAL_32(1 << 30, w11); + ASSERT_EQUAL_32(0xf89abcdd, w12); + ASSERT_EQUAL_32(0x91111110, w13); + ASSERT_EQUAL_32(0x9a222221, w14); + + ASSERT_EQUAL_64(0xffffffffffffffffL + 1, x18); + ASSERT_EQUAL_64((1L << 60) + 1, x19); + ASSERT_EQUAL_64(0xf0123456789abcddL + 1, x20); + ASSERT_EQUAL_64(0x0111111111111110L + 1, x21); + ASSERT_EQUAL_64(0x1222222222222221L + 1, x22); + + ASSERT_EQUAL_32(0xffffffff + 1, w23); + ASSERT_EQUAL_32((1 << 30) + 1, w24); + ASSERT_EQUAL_32(0xf89abcdd + 1, w25); + ASSERT_EQUAL_32(0x91111110 + 1, w26); + ASSERT_EQUAL_32(0x9a222221 + 1, w27); + + // Check that adc correctly sets the condition flags. + START(); + __ Mov(x0, 1); + __ Mov(x1, 0xffffffffffffffffL); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + __ Adcs(x10, x0, Operand(x1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZCFlag); + ASSERT_EQUAL_64(0, x10); + + START(); + __ Mov(x0, 1); + __ Mov(x1, 0x8000000000000000L); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + __ Adcs(x10, x0, Operand(x1, ASR, 63)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZCFlag); + ASSERT_EQUAL_64(0, x10); + + START(); + __ Mov(x0, 0x10); + __ Mov(x1, 0x07ffffffffffffffL); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + __ Adcs(x10, x0, Operand(x1, LSL, 4)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NVFlag); + ASSERT_EQUAL_64(0x8000000000000000L, x10); + + // Check that sbc correctly sets the condition flags. + START(); + __ Mov(x0, 0); + __ Mov(x1, 0xffffffffffffffffL); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + __ Sbcs(x10, x0, Operand(x1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZFlag); + ASSERT_EQUAL_64(0, x10); + + START(); + __ Mov(x0, 1); + __ Mov(x1, 0xffffffffffffffffL); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + __ Sbcs(x10, x0, Operand(x1, LSR, 1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + ASSERT_EQUAL_64(0x8000000000000001L, x10); + + START(); + __ Mov(x0, 0); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + __ Sbcs(x10, x0, Operand(0xffffffffffffffffL)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZFlag); + ASSERT_EQUAL_64(0, x10); + + START() + __ Mov(w0, 0x7fffffff); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + __ Ngcs(w10, w0); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + ASSERT_EQUAL_64(0x80000000, x10); + + START(); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + __ Ngcs(x10, 0x7fffffffffffffffL); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + ASSERT_EQUAL_64(0x8000000000000000L, x10); + + START() + __ Mov(x0, 0); + // Set the C flag. + __ Cmp(x0, Operand(x0)); + __ Sbcs(x10, x0, Operand(1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + ASSERT_EQUAL_64(0xffffffffffffffffL, x10); + + START() + __ Mov(x0, 0); + // Set the C flag. + __ Cmp(x0, Operand(x0)); + __ Ngcs(x10, 0x7fffffffffffffffL); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + ASSERT_EQUAL_64(0x8000000000000001L, x10); + + TEARDOWN(); +} + + +TEST(adc_sbc_extend) { + INIT_V8(); + SETUP(); + + START(); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + + __ Mov(x0, 0); + __ Mov(x1, 1); + __ Mov(x2, 0x0123456789abcdefL); + + __ Adc(x10, x1, Operand(w2, UXTB, 1)); + __ Adc(x11, x1, Operand(x2, SXTH, 2)); + __ Sbc(x12, x1, Operand(w2, UXTW, 4)); + __ Adc(x13, x1, Operand(x2, UXTX, 4)); + + __ Adc(w14, w1, Operand(w2, UXTB, 1)); + __ Adc(w15, w1, Operand(w2, SXTH, 2)); + __ Adc(w9, w1, Operand(w2, UXTW, 4)); + + // Set the C flag. + __ Cmp(w0, Operand(w0)); + + __ Adc(x20, x1, Operand(w2, UXTB, 1)); + __ Adc(x21, x1, Operand(x2, SXTH, 2)); + __ Sbc(x22, x1, Operand(w2, UXTW, 4)); + __ Adc(x23, x1, Operand(x2, UXTX, 4)); + + __ Adc(w24, w1, Operand(w2, UXTB, 1)); + __ Adc(w25, w1, Operand(w2, SXTH, 2)); + __ Adc(w26, w1, Operand(w2, UXTW, 4)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x1df, x10); + ASSERT_EQUAL_64(0xffffffffffff37bdL, x11); + ASSERT_EQUAL_64(0xfffffff765432110L, x12); + ASSERT_EQUAL_64(0x123456789abcdef1L, x13); + + ASSERT_EQUAL_32(0x1df, w14); + ASSERT_EQUAL_32(0xffff37bd, w15); + ASSERT_EQUAL_32(0x9abcdef1, w9); + + ASSERT_EQUAL_64(0x1df + 1, x20); + ASSERT_EQUAL_64(0xffffffffffff37bdL + 1, x21); + ASSERT_EQUAL_64(0xfffffff765432110L + 1, x22); + ASSERT_EQUAL_64(0x123456789abcdef1L + 1, x23); + + ASSERT_EQUAL_32(0x1df + 1, w24); + ASSERT_EQUAL_32(0xffff37bd + 1, w25); + ASSERT_EQUAL_32(0x9abcdef1 + 1, w26); + + // Check that adc correctly sets the condition flags. + START(); + __ Mov(x0, 0xff); + __ Mov(x1, 0xffffffffffffffffL); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + __ Adcs(x10, x0, Operand(x1, SXTX, 1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(CFlag); + + START(); + __ Mov(x0, 0x7fffffffffffffffL); + __ Mov(x1, 1); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + __ Adcs(x10, x0, Operand(x1, UXTB, 2)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NVFlag); + + START(); + __ Mov(x0, 0x7fffffffffffffffL); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + __ Adcs(x10, x0, Operand(1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NVFlag); + + TEARDOWN(); +} + + +TEST(adc_sbc_wide_imm) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0); + + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + + __ Adc(x7, x0, Operand(0x1234567890abcdefUL)); + __ Adc(w8, w0, Operand(0xffffffff)); + __ Sbc(x9, x0, Operand(0x1234567890abcdefUL)); + __ Sbc(w10, w0, Operand(0xffffffff)); + __ Ngc(x11, Operand(0xffffffff00000000UL)); + __ Ngc(w12, Operand(0xffff0000)); + + // Set the C flag. + __ Cmp(w0, Operand(w0)); + + __ Adc(x18, x0, Operand(0x1234567890abcdefUL)); + __ Adc(w19, w0, Operand(0xffffffff)); + __ Sbc(x20, x0, Operand(0x1234567890abcdefUL)); + __ Sbc(w21, w0, Operand(0xffffffff)); + __ Ngc(x22, Operand(0xffffffff00000000UL)); + __ Ngc(w23, Operand(0xffff0000)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x1234567890abcdefUL, x7); + ASSERT_EQUAL_64(0xffffffff, x8); + ASSERT_EQUAL_64(0xedcba9876f543210UL, x9); + ASSERT_EQUAL_64(0, x10); + ASSERT_EQUAL_64(0xffffffff, x11); + ASSERT_EQUAL_64(0xffff, x12); + + ASSERT_EQUAL_64(0x1234567890abcdefUL + 1, x18); + ASSERT_EQUAL_64(0, x19); + ASSERT_EQUAL_64(0xedcba9876f543211UL, x20); + ASSERT_EQUAL_64(1, x21); + ASSERT_EQUAL_64(0x100000000UL, x22); + ASSERT_EQUAL_64(0x10000, x23); + + TEARDOWN(); +} + + +TEST(flags) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x0, 0); + __ Mov(x1, 0x1111111111111111L); + __ Neg(x10, Operand(x0)); + __ Neg(x11, Operand(x1)); + __ Neg(w12, Operand(w1)); + // Clear the C flag. + __ Adds(x0, x0, Operand(0)); + __ Ngc(x13, Operand(x0)); + // Set the C flag. + __ Cmp(x0, Operand(x0)); + __ Ngc(w14, Operand(w0)); + END(); + + RUN(); + + ASSERT_EQUAL_64(0, x10); + ASSERT_EQUAL_64(-0x1111111111111111L, x11); + ASSERT_EQUAL_32(-0x11111111, w12); + ASSERT_EQUAL_64(-1L, x13); + ASSERT_EQUAL_32(0, w14); + + START(); + __ Mov(x0, 0); + __ Cmp(x0, Operand(x0)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZCFlag); + + START(); + __ Mov(w0, 0); + __ Cmp(w0, Operand(w0)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZCFlag); + + START(); + __ Mov(x0, 0); + __ Mov(x1, 0x1111111111111111L); + __ Cmp(x0, Operand(x1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + + START(); + __ Mov(w0, 0); + __ Mov(w1, 0x11111111); + __ Cmp(w0, Operand(w1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + + START(); + __ Mov(x1, 0x1111111111111111L); + __ Cmp(x1, Operand(0)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(CFlag); + + START(); + __ Mov(w1, 0x11111111); + __ Cmp(w1, Operand(0)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(CFlag); + + START(); + __ Mov(x0, 1); + __ Mov(x1, 0x7fffffffffffffffL); + __ Cmn(x1, Operand(x0)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NVFlag); + + START(); + __ Mov(w0, 1); + __ Mov(w1, 0x7fffffff); + __ Cmn(w1, Operand(w0)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NVFlag); + + START(); + __ Mov(x0, 1); + __ Mov(x1, 0xffffffffffffffffL); + __ Cmn(x1, Operand(x0)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZCFlag); + + START(); + __ Mov(w0, 1); + __ Mov(w1, 0xffffffff); + __ Cmn(w1, Operand(w0)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZCFlag); + + START(); + __ Mov(w0, 0); + __ Mov(w1, 1); + // Clear the C flag. + __ Adds(w0, w0, Operand(0)); + __ Ngcs(w0, Operand(w1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(NFlag); + + START(); + __ Mov(w0, 0); + __ Mov(w1, 0); + // Set the C flag. + __ Cmp(w0, Operand(w0)); + __ Ngcs(w0, Operand(w1)); + END(); + + RUN(); + + ASSERT_EQUAL_NZCV(ZCFlag); + + TEARDOWN(); +} + + +TEST(cmp_shift) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x18, 0xf0000000); + __ Mov(x19, 0xf000000010000000UL); + __ Mov(x20, 0xf0000000f0000000UL); + __ Mov(x21, 0x7800000078000000UL); + __ Mov(x22, 0x3c0000003c000000UL); + __ Mov(x23, 0x8000000780000000UL); + __ Mov(x24, 0x0000000f00000000UL); + __ Mov(x25, 0x00000003c0000000UL); + __ Mov(x26, 0x8000000780000000UL); + __ Mov(x27, 0xc0000003); + + __ Cmp(w20, Operand(w21, LSL, 1)); + __ Mrs(x0, NZCV); + + __ Cmp(x20, Operand(x22, LSL, 2)); + __ Mrs(x1, NZCV); + + __ Cmp(w19, Operand(w23, LSR, 3)); + __ Mrs(x2, NZCV); + + __ Cmp(x18, Operand(x24, LSR, 4)); + __ Mrs(x3, NZCV); + + __ Cmp(w20, Operand(w25, ASR, 2)); + __ Mrs(x4, NZCV); + + __ Cmp(x20, Operand(x26, ASR, 3)); + __ Mrs(x5, NZCV); + + __ Cmp(w27, Operand(w22, ROR, 28)); + __ Mrs(x6, NZCV); + + __ Cmp(x20, Operand(x21, ROR, 31)); + __ Mrs(x7, NZCV); + END(); + + RUN(); + + ASSERT_EQUAL_32(ZCFlag, w0); + ASSERT_EQUAL_32(ZCFlag, w1); + ASSERT_EQUAL_32(ZCFlag, w2); + ASSERT_EQUAL_32(ZCFlag, w3); + ASSERT_EQUAL_32(ZCFlag, w4); + ASSERT_EQUAL_32(ZCFlag, w5); + ASSERT_EQUAL_32(ZCFlag, w6); + ASSERT_EQUAL_32(ZCFlag, w7); + + TEARDOWN(); +} + + +TEST(cmp_extend) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(w20, 0x2); + __ Mov(w21, 0x1); + __ Mov(x22, 0xffffffffffffffffUL); + __ Mov(x23, 0xff); + __ Mov(x24, 0xfffffffffffffffeUL); + __ Mov(x25, 0xffff); + __ Mov(x26, 0xffffffff); + + __ Cmp(w20, Operand(w21, LSL, 1)); + __ Mrs(x0, NZCV); + + __ Cmp(x22, Operand(x23, SXTB, 0)); + __ Mrs(x1, NZCV); + + __ Cmp(x24, Operand(x23, SXTB, 1)); + __ Mrs(x2, NZCV); + + __ Cmp(x24, Operand(x23, UXTB, 1)); + __ Mrs(x3, NZCV); + + __ Cmp(w22, Operand(w25, UXTH)); + __ Mrs(x4, NZCV); + + __ Cmp(x22, Operand(x25, SXTH)); + __ Mrs(x5, NZCV); + + __ Cmp(x22, Operand(x26, UXTW)); + __ Mrs(x6, NZCV); + + __ Cmp(x24, Operand(x26, SXTW, 1)); + __ Mrs(x7, NZCV); + END(); + + RUN(); + + ASSERT_EQUAL_32(ZCFlag, w0); + ASSERT_EQUAL_32(ZCFlag, w1); + ASSERT_EQUAL_32(ZCFlag, w2); + ASSERT_EQUAL_32(NCFlag, w3); + ASSERT_EQUAL_32(NCFlag, w4); + ASSERT_EQUAL_32(ZCFlag, w5); + ASSERT_EQUAL_32(NCFlag, w6); + ASSERT_EQUAL_32(ZCFlag, w7); + + TEARDOWN(); +} + + +TEST(ccmp) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(w16, 0); + __ Mov(w17, 1); + __ Cmp(w16, w16); + __ Ccmp(w16, w17, NCFlag, eq); + __ Mrs(x0, NZCV); + + __ Cmp(w16, w16); + __ Ccmp(w16, w17, NCFlag, ne); + __ Mrs(x1, NZCV); + + __ Cmp(x16, x16); + __ Ccmn(x16, 2, NZCVFlag, eq); + __ Mrs(x2, NZCV); + + __ Cmp(x16, x16); + __ Ccmn(x16, 2, NZCVFlag, ne); + __ Mrs(x3, NZCV); + + __ ccmp(x16, x16, NZCVFlag, al); + __ Mrs(x4, NZCV); + + __ ccmp(x16, x16, NZCVFlag, nv); + __ Mrs(x5, NZCV); + + END(); + + RUN(); + + ASSERT_EQUAL_32(NFlag, w0); + ASSERT_EQUAL_32(NCFlag, w1); + ASSERT_EQUAL_32(NoFlag, w2); + ASSERT_EQUAL_32(NZCVFlag, w3); + ASSERT_EQUAL_32(ZCFlag, w4); + ASSERT_EQUAL_32(ZCFlag, w5); + + TEARDOWN(); +} + + +TEST(ccmp_wide_imm) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(w20, 0); + + __ Cmp(w20, Operand(w20)); + __ Ccmp(w20, Operand(0x12345678), NZCVFlag, eq); + __ Mrs(x0, NZCV); + + __ Cmp(w20, Operand(w20)); + __ Ccmp(x20, Operand(0xffffffffffffffffUL), NZCVFlag, eq); + __ Mrs(x1, NZCV); + END(); + + RUN(); + + ASSERT_EQUAL_32(NFlag, w0); + ASSERT_EQUAL_32(NoFlag, w1); + + TEARDOWN(); +} + + +TEST(ccmp_shift_extend) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(w20, 0x2); + __ Mov(w21, 0x1); + __ Mov(x22, 0xffffffffffffffffUL); + __ Mov(x23, 0xff); + __ Mov(x24, 0xfffffffffffffffeUL); + + __ Cmp(w20, Operand(w20)); + __ Ccmp(w20, Operand(w21, LSL, 1), NZCVFlag, eq); + __ Mrs(x0, NZCV); + + __ Cmp(w20, Operand(w20)); + __ Ccmp(x22, Operand(x23, SXTB, 0), NZCVFlag, eq); + __ Mrs(x1, NZCV); + + __ Cmp(w20, Operand(w20)); + __ Ccmp(x24, Operand(x23, SXTB, 1), NZCVFlag, eq); + __ Mrs(x2, NZCV); + + __ Cmp(w20, Operand(w20)); + __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, eq); + __ Mrs(x3, NZCV); + + __ Cmp(w20, Operand(w20)); + __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, ne); + __ Mrs(x4, NZCV); + END(); + + RUN(); + + ASSERT_EQUAL_32(ZCFlag, w0); + ASSERT_EQUAL_32(ZCFlag, w1); + ASSERT_EQUAL_32(ZCFlag, w2); + ASSERT_EQUAL_32(NCFlag, w3); + ASSERT_EQUAL_32(NZCVFlag, w4); + + TEARDOWN(); +} + + +TEST(csel) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x16, 0); + __ Mov(x24, 0x0000000f0000000fUL); + __ Mov(x25, 0x0000001f0000001fUL); + __ Mov(x26, 0); + __ Mov(x27, 0); + + __ Cmp(w16, 0); + __ Csel(w0, w24, w25, eq); + __ Csel(w1, w24, w25, ne); + __ Csinc(w2, w24, w25, mi); + __ Csinc(w3, w24, w25, pl); + + __ csel(w13, w24, w25, al); + __ csel(x14, x24, x25, nv); + + __ Cmp(x16, 1); + __ Csinv(x4, x24, x25, gt); + __ Csinv(x5, x24, x25, le); + __ Csneg(x6, x24, x25, hs); + __ Csneg(x7, x24, x25, lo); + + __ Cset(w8, ne); + __ Csetm(w9, ne); + __ Cinc(x10, x25, ne); + __ Cinv(x11, x24, ne); + __ Cneg(x12, x24, ne); + + __ csel(w15, w24, w25, al); + __ csel(x18, x24, x25, nv); + + __ CzeroX(x24, ne); + __ CzeroX(x25, eq); + + __ CmovX(x26, x25, ne); + __ CmovX(x27, x25, eq); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x0000000f, x0); + ASSERT_EQUAL_64(0x0000001f, x1); + ASSERT_EQUAL_64(0x00000020, x2); + ASSERT_EQUAL_64(0x0000000f, x3); + ASSERT_EQUAL_64(0xffffffe0ffffffe0UL, x4); + ASSERT_EQUAL_64(0x0000000f0000000fUL, x5); + ASSERT_EQUAL_64(0xffffffe0ffffffe1UL, x6); + ASSERT_EQUAL_64(0x0000000f0000000fUL, x7); + ASSERT_EQUAL_64(0x00000001, x8); + ASSERT_EQUAL_64(0xffffffff, x9); + ASSERT_EQUAL_64(0x0000001f00000020UL, x10); + ASSERT_EQUAL_64(0xfffffff0fffffff0UL, x11); + ASSERT_EQUAL_64(0xfffffff0fffffff1UL, x12); + ASSERT_EQUAL_64(0x0000000f, x13); + ASSERT_EQUAL_64(0x0000000f0000000fUL, x14); + ASSERT_EQUAL_64(0x0000000f, x15); + ASSERT_EQUAL_64(0x0000000f0000000fUL, x18); + ASSERT_EQUAL_64(0, x24); + ASSERT_EQUAL_64(0x0000001f0000001fUL, x25); + ASSERT_EQUAL_64(0x0000001f0000001fUL, x26); + ASSERT_EQUAL_64(0, x27); + + TEARDOWN(); +} + + +TEST(csel_imm) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x18, 0); + __ Mov(x19, 0x80000000); + __ Mov(x20, 0x8000000000000000UL); + + __ Cmp(x18, Operand(0)); + __ Csel(w0, w19, -2, ne); + __ Csel(w1, w19, -1, ne); + __ Csel(w2, w19, 0, ne); + __ Csel(w3, w19, 1, ne); + __ Csel(w4, w19, 2, ne); + __ Csel(w5, w19, Operand(w19, ASR, 31), ne); + __ Csel(w6, w19, Operand(w19, ROR, 1), ne); + __ Csel(w7, w19, 3, eq); + + __ Csel(x8, x20, -2, ne); + __ Csel(x9, x20, -1, ne); + __ Csel(x10, x20, 0, ne); + __ Csel(x11, x20, 1, ne); + __ Csel(x12, x20, 2, ne); + __ Csel(x13, x20, Operand(x20, ASR, 63), ne); + __ Csel(x14, x20, Operand(x20, ROR, 1), ne); + __ Csel(x15, x20, 3, eq); + + END(); + + RUN(); + + ASSERT_EQUAL_32(-2, w0); + ASSERT_EQUAL_32(-1, w1); + ASSERT_EQUAL_32(0, w2); + ASSERT_EQUAL_32(1, w3); + ASSERT_EQUAL_32(2, w4); + ASSERT_EQUAL_32(-1, w5); + ASSERT_EQUAL_32(0x40000000, w6); + ASSERT_EQUAL_32(0x80000000, w7); + + ASSERT_EQUAL_64(-2, x8); + ASSERT_EQUAL_64(-1, x9); + ASSERT_EQUAL_64(0, x10); + ASSERT_EQUAL_64(1, x11); + ASSERT_EQUAL_64(2, x12); + ASSERT_EQUAL_64(-1, x13); + ASSERT_EQUAL_64(0x4000000000000000UL, x14); + ASSERT_EQUAL_64(0x8000000000000000UL, x15); + + TEARDOWN(); +} + + +TEST(lslv) { + INIT_V8(); + SETUP(); + + uint64_t value = 0x0123456789abcdefUL; + int shift[] = {1, 3, 5, 9, 17, 33}; + + START(); + __ Mov(x0, value); + __ Mov(w1, shift[0]); + __ Mov(w2, shift[1]); + __ Mov(w3, shift[2]); + __ Mov(w4, shift[3]); + __ Mov(w5, shift[4]); + __ Mov(w6, shift[5]); + + __ lslv(x0, x0, xzr); + + __ Lsl(x16, x0, x1); + __ Lsl(x17, x0, x2); + __ Lsl(x18, x0, x3); + __ Lsl(x19, x0, x4); + __ Lsl(x20, x0, x5); + __ Lsl(x21, x0, x6); + + __ Lsl(w22, w0, w1); + __ Lsl(w23, w0, w2); + __ Lsl(w24, w0, w3); + __ Lsl(w25, w0, w4); + __ Lsl(w26, w0, w5); + __ Lsl(w27, w0, w6); + END(); + + RUN(); + + ASSERT_EQUAL_64(value, x0); + ASSERT_EQUAL_64(value << (shift[0] & 63), x16); + ASSERT_EQUAL_64(value << (shift[1] & 63), x17); + ASSERT_EQUAL_64(value << (shift[2] & 63), x18); + ASSERT_EQUAL_64(value << (shift[3] & 63), x19); + ASSERT_EQUAL_64(value << (shift[4] & 63), x20); + ASSERT_EQUAL_64(value << (shift[5] & 63), x21); + ASSERT_EQUAL_32(value << (shift[0] & 31), w22); + ASSERT_EQUAL_32(value << (shift[1] & 31), w23); + ASSERT_EQUAL_32(value << (shift[2] & 31), w24); + ASSERT_EQUAL_32(value << (shift[3] & 31), w25); + ASSERT_EQUAL_32(value << (shift[4] & 31), w26); + ASSERT_EQUAL_32(value << (shift[5] & 31), w27); + + TEARDOWN(); +} + + +TEST(lsrv) { + INIT_V8(); + SETUP(); + + uint64_t value = 0x0123456789abcdefUL; + int shift[] = {1, 3, 5, 9, 17, 33}; + + START(); + __ Mov(x0, value); + __ Mov(w1, shift[0]); + __ Mov(w2, shift[1]); + __ Mov(w3, shift[2]); + __ Mov(w4, shift[3]); + __ Mov(w5, shift[4]); + __ Mov(w6, shift[5]); + + __ lsrv(x0, x0, xzr); + + __ Lsr(x16, x0, x1); + __ Lsr(x17, x0, x2); + __ Lsr(x18, x0, x3); + __ Lsr(x19, x0, x4); + __ Lsr(x20, x0, x5); + __ Lsr(x21, x0, x6); + + __ Lsr(w22, w0, w1); + __ Lsr(w23, w0, w2); + __ Lsr(w24, w0, w3); + __ Lsr(w25, w0, w4); + __ Lsr(w26, w0, w5); + __ Lsr(w27, w0, w6); + END(); + + RUN(); + + ASSERT_EQUAL_64(value, x0); + ASSERT_EQUAL_64(value >> (shift[0] & 63), x16); + ASSERT_EQUAL_64(value >> (shift[1] & 63), x17); + ASSERT_EQUAL_64(value >> (shift[2] & 63), x18); + ASSERT_EQUAL_64(value >> (shift[3] & 63), x19); + ASSERT_EQUAL_64(value >> (shift[4] & 63), x20); + ASSERT_EQUAL_64(value >> (shift[5] & 63), x21); + + value &= 0xffffffffUL; + ASSERT_EQUAL_32(value >> (shift[0] & 31), w22); + ASSERT_EQUAL_32(value >> (shift[1] & 31), w23); + ASSERT_EQUAL_32(value >> (shift[2] & 31), w24); + ASSERT_EQUAL_32(value >> (shift[3] & 31), w25); + ASSERT_EQUAL_32(value >> (shift[4] & 31), w26); + ASSERT_EQUAL_32(value >> (shift[5] & 31), w27); + + TEARDOWN(); +} + + +TEST(asrv) { + INIT_V8(); + SETUP(); + + int64_t value = 0xfedcba98fedcba98UL; + int shift[] = {1, 3, 5, 9, 17, 33}; + + START(); + __ Mov(x0, value); + __ Mov(w1, shift[0]); + __ Mov(w2, shift[1]); + __ Mov(w3, shift[2]); + __ Mov(w4, shift[3]); + __ Mov(w5, shift[4]); + __ Mov(w6, shift[5]); + + __ asrv(x0, x0, xzr); + + __ Asr(x16, x0, x1); + __ Asr(x17, x0, x2); + __ Asr(x18, x0, x3); + __ Asr(x19, x0, x4); + __ Asr(x20, x0, x5); + __ Asr(x21, x0, x6); + + __ Asr(w22, w0, w1); + __ Asr(w23, w0, w2); + __ Asr(w24, w0, w3); + __ Asr(w25, w0, w4); + __ Asr(w26, w0, w5); + __ Asr(w27, w0, w6); + END(); + + RUN(); + + ASSERT_EQUAL_64(value, x0); + ASSERT_EQUAL_64(value >> (shift[0] & 63), x16); + ASSERT_EQUAL_64(value >> (shift[1] & 63), x17); + ASSERT_EQUAL_64(value >> (shift[2] & 63), x18); + ASSERT_EQUAL_64(value >> (shift[3] & 63), x19); + ASSERT_EQUAL_64(value >> (shift[4] & 63), x20); + ASSERT_EQUAL_64(value >> (shift[5] & 63), x21); + + int32_t value32 = static_cast<int32_t>(value & 0xffffffffUL); + ASSERT_EQUAL_32(value32 >> (shift[0] & 31), w22); + ASSERT_EQUAL_32(value32 >> (shift[1] & 31), w23); + ASSERT_EQUAL_32(value32 >> (shift[2] & 31), w24); + ASSERT_EQUAL_32(value32 >> (shift[3] & 31), w25); + ASSERT_EQUAL_32(value32 >> (shift[4] & 31), w26); + ASSERT_EQUAL_32(value32 >> (shift[5] & 31), w27); + + TEARDOWN(); +} + + +TEST(rorv) { + INIT_V8(); + SETUP(); + + uint64_t value = 0x0123456789abcdefUL; + int shift[] = {4, 8, 12, 16, 24, 36}; + + START(); + __ Mov(x0, value); + __ Mov(w1, shift[0]); + __ Mov(w2, shift[1]); + __ Mov(w3, shift[2]); + __ Mov(w4, shift[3]); + __ Mov(w5, shift[4]); + __ Mov(w6, shift[5]); + + __ rorv(x0, x0, xzr); + + __ Ror(x16, x0, x1); + __ Ror(x17, x0, x2); + __ Ror(x18, x0, x3); + __ Ror(x19, x0, x4); + __ Ror(x20, x0, x5); + __ Ror(x21, x0, x6); + + __ Ror(w22, w0, w1); + __ Ror(w23, w0, w2); + __ Ror(w24, w0, w3); + __ Ror(w25, w0, w4); + __ Ror(w26, w0, w5); + __ Ror(w27, w0, w6); + END(); + + RUN(); + + ASSERT_EQUAL_64(value, x0); + ASSERT_EQUAL_64(0xf0123456789abcdeUL, x16); + ASSERT_EQUAL_64(0xef0123456789abcdUL, x17); + ASSERT_EQUAL_64(0xdef0123456789abcUL, x18); + ASSERT_EQUAL_64(0xcdef0123456789abUL, x19); + ASSERT_EQUAL_64(0xabcdef0123456789UL, x20); + ASSERT_EQUAL_64(0x789abcdef0123456UL, x21); + ASSERT_EQUAL_32(0xf89abcde, w22); + ASSERT_EQUAL_32(0xef89abcd, w23); + ASSERT_EQUAL_32(0xdef89abc, w24); + ASSERT_EQUAL_32(0xcdef89ab, w25); + ASSERT_EQUAL_32(0xabcdef89, w26); + ASSERT_EQUAL_32(0xf89abcde, w27); + + TEARDOWN(); +} + + +TEST(bfm) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x1, 0x0123456789abcdefL); + + __ Mov(x10, 0x8888888888888888L); + __ Mov(x11, 0x8888888888888888L); + __ Mov(x12, 0x8888888888888888L); + __ Mov(x13, 0x8888888888888888L); + __ Mov(w20, 0x88888888); + __ Mov(w21, 0x88888888); + + __ bfm(x10, x1, 16, 31); + __ bfm(x11, x1, 32, 15); + + __ bfm(w20, w1, 16, 23); + __ bfm(w21, w1, 24, 15); + + // Aliases. + __ Bfi(x12, x1, 16, 8); + __ Bfxil(x13, x1, 16, 8); + END(); + + RUN(); + + + ASSERT_EQUAL_64(0x88888888888889abL, x10); + ASSERT_EQUAL_64(0x8888cdef88888888L, x11); + + ASSERT_EQUAL_32(0x888888ab, w20); + ASSERT_EQUAL_32(0x88cdef88, w21); + + ASSERT_EQUAL_64(0x8888888888ef8888L, x12); + ASSERT_EQUAL_64(0x88888888888888abL, x13); + + TEARDOWN(); +} + + +TEST(sbfm) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x1, 0x0123456789abcdefL); + __ Mov(x2, 0xfedcba9876543210L); + + __ sbfm(x10, x1, 16, 31); + __ sbfm(x11, x1, 32, 15); + __ sbfm(x12, x1, 32, 47); + __ sbfm(x13, x1, 48, 35); + + __ sbfm(w14, w1, 16, 23); + __ sbfm(w15, w1, 24, 15); + __ sbfm(w16, w2, 16, 23); + __ sbfm(w17, w2, 24, 15); + + // Aliases. + __ Asr(x18, x1, 32); + __ Asr(x19, x2, 32); + __ Sbfiz(x20, x1, 8, 16); + __ Sbfiz(x21, x2, 8, 16); + __ Sbfx(x22, x1, 8, 16); + __ Sbfx(x23, x2, 8, 16); + __ Sxtb(x24, w1); + __ Sxtb(x25, x2); + __ Sxth(x26, w1); + __ Sxth(x27, x2); + __ Sxtw(x28, w1); + __ Sxtw(x29, x2); + END(); + + RUN(); + + + ASSERT_EQUAL_64(0xffffffffffff89abL, x10); + ASSERT_EQUAL_64(0xffffcdef00000000L, x11); + ASSERT_EQUAL_64(0x4567L, x12); + ASSERT_EQUAL_64(0x789abcdef0000L, x13); + + ASSERT_EQUAL_32(0xffffffab, w14); + ASSERT_EQUAL_32(0xffcdef00, w15); + ASSERT_EQUAL_32(0x54, w16); + ASSERT_EQUAL_32(0x00321000, w17); + + ASSERT_EQUAL_64(0x01234567L, x18); + ASSERT_EQUAL_64(0xfffffffffedcba98L, x19); + ASSERT_EQUAL_64(0xffffffffffcdef00L, x20); + ASSERT_EQUAL_64(0x321000L, x21); + ASSERT_EQUAL_64(0xffffffffffffabcdL, x22); + ASSERT_EQUAL_64(0x5432L, x23); + ASSERT_EQUAL_64(0xffffffffffffffefL, x24); + ASSERT_EQUAL_64(0x10, x25); + ASSERT_EQUAL_64(0xffffffffffffcdefL, x26); + ASSERT_EQUAL_64(0x3210, x27); + ASSERT_EQUAL_64(0xffffffff89abcdefL, x28); + ASSERT_EQUAL_64(0x76543210, x29); + + TEARDOWN(); +} + + +TEST(ubfm) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x1, 0x0123456789abcdefL); + __ Mov(x2, 0xfedcba9876543210L); + + __ Mov(x10, 0x8888888888888888L); + __ Mov(x11, 0x8888888888888888L); + + __ ubfm(x10, x1, 16, 31); + __ ubfm(x11, x1, 32, 15); + __ ubfm(x12, x1, 32, 47); + __ ubfm(x13, x1, 48, 35); + + __ ubfm(w25, w1, 16, 23); + __ ubfm(w26, w1, 24, 15); + __ ubfm(w27, w2, 16, 23); + __ ubfm(w28, w2, 24, 15); + + // Aliases + __ Lsl(x15, x1, 63); + __ Lsl(x16, x1, 0); + __ Lsr(x17, x1, 32); + __ Ubfiz(x18, x1, 8, 16); + __ Ubfx(x19, x1, 8, 16); + __ Uxtb(x20, x1); + __ Uxth(x21, x1); + __ Uxtw(x22, x1); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x00000000000089abL, x10); + ASSERT_EQUAL_64(0x0000cdef00000000L, x11); + ASSERT_EQUAL_64(0x4567L, x12); + ASSERT_EQUAL_64(0x789abcdef0000L, x13); + + ASSERT_EQUAL_32(0x000000ab, w25); + ASSERT_EQUAL_32(0x00cdef00, w26); + ASSERT_EQUAL_32(0x54, w27); + ASSERT_EQUAL_32(0x00321000, w28); + + ASSERT_EQUAL_64(0x8000000000000000L, x15); + ASSERT_EQUAL_64(0x0123456789abcdefL, x16); + ASSERT_EQUAL_64(0x01234567L, x17); + ASSERT_EQUAL_64(0xcdef00L, x18); + ASSERT_EQUAL_64(0xabcdL, x19); + ASSERT_EQUAL_64(0xefL, x20); + ASSERT_EQUAL_64(0xcdefL, x21); + ASSERT_EQUAL_64(0x89abcdefL, x22); + + TEARDOWN(); +} + + +TEST(extr) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x1, 0x0123456789abcdefL); + __ Mov(x2, 0xfedcba9876543210L); + + __ Extr(w10, w1, w2, 0); + __ Extr(w11, w1, w2, 1); + __ Extr(x12, x2, x1, 2); + + __ Ror(w13, w1, 0); + __ Ror(w14, w2, 17); + __ Ror(w15, w1, 31); + __ Ror(x18, x2, 1); + __ Ror(x19, x1, 63); + END(); + + RUN(); + + ASSERT_EQUAL_64(0x76543210, x10); + ASSERT_EQUAL_64(0xbb2a1908, x11); + ASSERT_EQUAL_64(0x0048d159e26af37bUL, x12); + ASSERT_EQUAL_64(0x89abcdef, x13); + ASSERT_EQUAL_64(0x19083b2a, x14); + ASSERT_EQUAL_64(0x13579bdf, x15); + ASSERT_EQUAL_64(0x7f6e5d4c3b2a1908UL, x18); + ASSERT_EQUAL_64(0x02468acf13579bdeUL, x19); + + TEARDOWN(); +} + + +TEST(fmov_imm) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s11, 1.0); + __ Fmov(d22, -13.0); + __ Fmov(s1, 255.0); + __ Fmov(d2, 12.34567); + __ Fmov(s3, 0.0); + __ Fmov(d4, 0.0); + __ Fmov(s5, kFP32PositiveInfinity); + __ Fmov(d6, kFP64NegativeInfinity); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(1.0, s11); + ASSERT_EQUAL_FP64(-13.0, d22); + ASSERT_EQUAL_FP32(255.0, s1); + ASSERT_EQUAL_FP64(12.34567, d2); + ASSERT_EQUAL_FP32(0.0, s3); + ASSERT_EQUAL_FP64(0.0, d4); + ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5); + ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d6); + + TEARDOWN(); +} + + +TEST(fmov_reg) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s20, 1.0); + __ Fmov(w10, s20); + __ Fmov(s30, w10); + __ Fmov(s5, s20); + __ Fmov(d1, -13.0); + __ Fmov(x1, d1); + __ Fmov(d2, x1); + __ Fmov(d4, d1); + __ Fmov(d6, rawbits_to_double(0x0123456789abcdefL)); + __ Fmov(s6, s6); + END(); + + RUN(); + + ASSERT_EQUAL_32(float_to_rawbits(1.0), w10); + ASSERT_EQUAL_FP32(1.0, s30); + ASSERT_EQUAL_FP32(1.0, s5); + ASSERT_EQUAL_64(double_to_rawbits(-13.0), x1); + ASSERT_EQUAL_FP64(-13.0, d2); + ASSERT_EQUAL_FP64(-13.0, d4); + ASSERT_EQUAL_FP32(rawbits_to_float(0x89abcdef), s6); + + TEARDOWN(); +} + + +TEST(fadd) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s13, -0.0); + __ Fmov(s14, kFP32PositiveInfinity); + __ Fmov(s15, kFP32NegativeInfinity); + __ Fmov(s16, 3.25); + __ Fmov(s17, 1.0); + __ Fmov(s18, 0); + + __ Fmov(d26, -0.0); + __ Fmov(d27, kFP64PositiveInfinity); + __ Fmov(d28, kFP64NegativeInfinity); + __ Fmov(d29, 0); + __ Fmov(d30, -2.0); + __ Fmov(d31, 2.25); + + __ Fadd(s0, s16, s17); + __ Fadd(s1, s17, s18); + __ Fadd(s2, s13, s17); + __ Fadd(s3, s14, s17); + __ Fadd(s4, s15, s17); + + __ Fadd(d5, d30, d31); + __ Fadd(d6, d29, d31); + __ Fadd(d7, d26, d31); + __ Fadd(d8, d27, d31); + __ Fadd(d9, d28, d31); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(4.25, s0); + ASSERT_EQUAL_FP32(1.0, s1); + ASSERT_EQUAL_FP32(1.0, s2); + ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3); + ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4); + ASSERT_EQUAL_FP64(0.25, d5); + ASSERT_EQUAL_FP64(2.25, d6); + ASSERT_EQUAL_FP64(2.25, d7); + ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d8); + ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d9); + + TEARDOWN(); +} + + +TEST(fsub) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s13, -0.0); + __ Fmov(s14, kFP32PositiveInfinity); + __ Fmov(s15, kFP32NegativeInfinity); + __ Fmov(s16, 3.25); + __ Fmov(s17, 1.0); + __ Fmov(s18, 0); + + __ Fmov(d26, -0.0); + __ Fmov(d27, kFP64PositiveInfinity); + __ Fmov(d28, kFP64NegativeInfinity); + __ Fmov(d29, 0); + __ Fmov(d30, -2.0); + __ Fmov(d31, 2.25); + + __ Fsub(s0, s16, s17); + __ Fsub(s1, s17, s18); + __ Fsub(s2, s13, s17); + __ Fsub(s3, s17, s14); + __ Fsub(s4, s17, s15); + + __ Fsub(d5, d30, d31); + __ Fsub(d6, d29, d31); + __ Fsub(d7, d26, d31); + __ Fsub(d8, d31, d27); + __ Fsub(d9, d31, d28); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(2.25, s0); + ASSERT_EQUAL_FP32(1.0, s1); + ASSERT_EQUAL_FP32(-1.0, s2); + ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3); + ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4); + ASSERT_EQUAL_FP64(-4.25, d5); + ASSERT_EQUAL_FP64(-2.25, d6); + ASSERT_EQUAL_FP64(-2.25, d7); + ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8); + ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d9); + + TEARDOWN(); +} + + +TEST(fmul) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s13, -0.0); + __ Fmov(s14, kFP32PositiveInfinity); + __ Fmov(s15, kFP32NegativeInfinity); + __ Fmov(s16, 3.25); + __ Fmov(s17, 2.0); + __ Fmov(s18, 0); + __ Fmov(s19, -2.0); + + __ Fmov(d26, -0.0); + __ Fmov(d27, kFP64PositiveInfinity); + __ Fmov(d28, kFP64NegativeInfinity); + __ Fmov(d29, 0); + __ Fmov(d30, -2.0); + __ Fmov(d31, 2.25); + + __ Fmul(s0, s16, s17); + __ Fmul(s1, s17, s18); + __ Fmul(s2, s13, s13); + __ Fmul(s3, s14, s19); + __ Fmul(s4, s15, s19); + + __ Fmul(d5, d30, d31); + __ Fmul(d6, d29, d31); + __ Fmul(d7, d26, d26); + __ Fmul(d8, d27, d30); + __ Fmul(d9, d28, d30); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(6.5, s0); + ASSERT_EQUAL_FP32(0.0, s1); + ASSERT_EQUAL_FP32(0.0, s2); + ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3); + ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4); + ASSERT_EQUAL_FP64(-4.5, d5); + ASSERT_EQUAL_FP64(0.0, d6); + ASSERT_EQUAL_FP64(0.0, d7); + ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8); + ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d9); + + TEARDOWN(); +} + + +static void FmaddFmsubDoubleHelper(double n, double m, double a, + double fmadd, double fmsub) { + SETUP(); + START(); + + __ Fmov(d0, n); + __ Fmov(d1, m); + __ Fmov(d2, a); + __ Fmadd(d28, d0, d1, d2); + __ Fmsub(d29, d0, d1, d2); + __ Fnmadd(d30, d0, d1, d2); + __ Fnmsub(d31, d0, d1, d2); + + END(); + RUN(); + + ASSERT_EQUAL_FP64(fmadd, d28); + ASSERT_EQUAL_FP64(fmsub, d29); + ASSERT_EQUAL_FP64(-fmadd, d30); + ASSERT_EQUAL_FP64(-fmsub, d31); + + TEARDOWN(); +} + + +TEST(fmadd_fmsub_double) { + INIT_V8(); + double inputs[] = { + // Normal numbers, including -0.0. + DBL_MAX, DBL_MIN, 3.25, 2.0, 0.0, + -DBL_MAX, -DBL_MIN, -3.25, -2.0, -0.0, + // Infinities. + kFP64NegativeInfinity, kFP64PositiveInfinity, + // Subnormal numbers. + rawbits_to_double(0x000fffffffffffff), + rawbits_to_double(0x0000000000000001), + rawbits_to_double(0x000123456789abcd), + -rawbits_to_double(0x000fffffffffffff), + -rawbits_to_double(0x0000000000000001), + -rawbits_to_double(0x000123456789abcd), + // NaN. + kFP64QuietNaN, + -kFP64QuietNaN, + }; + const int count = sizeof(inputs) / sizeof(inputs[0]); + + for (int in = 0; in < count; in++) { + double n = inputs[in]; + for (int im = 0; im < count; im++) { + double m = inputs[im]; + for (int ia = 0; ia < count; ia++) { + double a = inputs[ia]; + double fmadd = fma(n, m, a); + double fmsub = fma(-n, m, a); + + FmaddFmsubDoubleHelper(n, m, a, fmadd, fmsub); + } + } + } +} + + +TEST(fmadd_fmsub_double_rounding) { + INIT_V8(); + // Make sure we run plenty of tests where an intermediate rounding stage would + // produce an incorrect result. + const int limit = 1000; + int count_fmadd = 0; + int count_fmsub = 0; + + uint16_t seed[3] = {42, 43, 44}; + seed48(seed); + + while ((count_fmadd < limit) || (count_fmsub < limit)) { + double n, m, a; + uint32_t r[2]; + ASSERT(sizeof(r) == sizeof(n)); + + r[0] = mrand48(); + r[1] = mrand48(); + memcpy(&n, r, sizeof(r)); + r[0] = mrand48(); + r[1] = mrand48(); + memcpy(&m, r, sizeof(r)); + r[0] = mrand48(); + r[1] = mrand48(); + memcpy(&a, r, sizeof(r)); + + if (!std::isfinite(a) || !std::isfinite(n) || !std::isfinite(m)) { + continue; + } + + // Calculate the expected results. + double fmadd = fma(n, m, a); + double fmsub = fma(-n, m, a); + + bool test_fmadd = (fmadd != (a + n * m)); + bool test_fmsub = (fmsub != (a - n * m)); + + // If rounding would produce a different result, increment the test count. + count_fmadd += test_fmadd; + count_fmsub += test_fmsub; + + if (test_fmadd || test_fmsub) { + FmaddFmsubDoubleHelper(n, m, a, fmadd, fmsub); + } + } +} + + +static void FmaddFmsubFloatHelper(float n, float m, float a, + float fmadd, float fmsub) { + SETUP(); + START(); + + __ Fmov(s0, n); + __ Fmov(s1, m); + __ Fmov(s2, a); + __ Fmadd(s30, s0, s1, s2); + __ Fmsub(s31, s0, s1, s2); + + END(); + RUN(); + + ASSERT_EQUAL_FP32(fmadd, s30); + ASSERT_EQUAL_FP32(fmsub, s31); + + TEARDOWN(); +} + + +TEST(fmadd_fmsub_float) { + INIT_V8(); + float inputs[] = { + // Normal numbers, including -0.0f. + FLT_MAX, FLT_MIN, 3.25f, 2.0f, 0.0f, + -FLT_MAX, -FLT_MIN, -3.25f, -2.0f, -0.0f, + // Infinities. + kFP32NegativeInfinity, kFP32PositiveInfinity, + // Subnormal numbers. + rawbits_to_float(0x07ffffff), + rawbits_to_float(0x00000001), + rawbits_to_float(0x01234567), + -rawbits_to_float(0x07ffffff), + -rawbits_to_float(0x00000001), + -rawbits_to_float(0x01234567), + // NaN. + kFP32QuietNaN, + -kFP32QuietNaN, + }; + const int count = sizeof(inputs) / sizeof(inputs[0]); + + for (int in = 0; in < count; in++) { + float n = inputs[in]; + for (int im = 0; im < count; im++) { + float m = inputs[im]; + for (int ia = 0; ia < count; ia++) { + float a = inputs[ia]; + float fmadd = fmaf(n, m, a); + float fmsub = fmaf(-n, m, a); + + FmaddFmsubFloatHelper(n, m, a, fmadd, fmsub); + } + } + } +} + + +TEST(fmadd_fmsub_float_rounding) { + INIT_V8(); + // Make sure we run plenty of tests where an intermediate rounding stage would + // produce an incorrect result. + const int limit = 1000; + int count_fmadd = 0; + int count_fmsub = 0; + + uint16_t seed[3] = {42, 43, 44}; + seed48(seed); + + while ((count_fmadd < limit) || (count_fmsub < limit)) { + float n, m, a; + uint32_t r; + ASSERT(sizeof(r) == sizeof(n)); + + r = mrand48(); + memcpy(&n, &r, sizeof(r)); + r = mrand48(); + memcpy(&m, &r, sizeof(r)); + r = mrand48(); + memcpy(&a, &r, sizeof(r)); + + if (!std::isfinite(a) || !std::isfinite(n) || !std::isfinite(m)) { + continue; + } + + // Calculate the expected results. + float fmadd = fmaf(n, m, a); + float fmsub = fmaf(-n, m, a); + + bool test_fmadd = (fmadd != (a + n * m)); + bool test_fmsub = (fmsub != (a - n * m)); + + // If rounding would produce a different result, increment the test count. + count_fmadd += test_fmadd; + count_fmsub += test_fmsub; + + if (test_fmadd || test_fmsub) { + FmaddFmsubFloatHelper(n, m, a, fmadd, fmsub); + } + } +} + + +TEST(fdiv) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s13, -0.0); + __ Fmov(s14, kFP32PositiveInfinity); + __ Fmov(s15, kFP32NegativeInfinity); + __ Fmov(s16, 3.25); + __ Fmov(s17, 2.0); + __ Fmov(s18, 2.0); + __ Fmov(s19, -2.0); + + __ Fmov(d26, -0.0); + __ Fmov(d27, kFP64PositiveInfinity); + __ Fmov(d28, kFP64NegativeInfinity); + __ Fmov(d29, 0); + __ Fmov(d30, -2.0); + __ Fmov(d31, 2.25); + + __ Fdiv(s0, s16, s17); + __ Fdiv(s1, s17, s18); + __ Fdiv(s2, s13, s17); + __ Fdiv(s3, s17, s14); + __ Fdiv(s4, s17, s15); + __ Fdiv(d5, d31, d30); + __ Fdiv(d6, d29, d31); + __ Fdiv(d7, d26, d31); + __ Fdiv(d8, d31, d27); + __ Fdiv(d9, d31, d28); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(1.625, s0); + ASSERT_EQUAL_FP32(1.0, s1); + ASSERT_EQUAL_FP32(-0.0, s2); + ASSERT_EQUAL_FP32(0.0, s3); + ASSERT_EQUAL_FP32(-0.0, s4); + ASSERT_EQUAL_FP64(-1.125, d5); + ASSERT_EQUAL_FP64(0.0, d6); + ASSERT_EQUAL_FP64(-0.0, d7); + ASSERT_EQUAL_FP64(0.0, d8); + ASSERT_EQUAL_FP64(-0.0, d9); + + TEARDOWN(); +} + + +static float MinMaxHelper(float n, + float m, + bool min, + float quiet_nan_substitute = 0.0) { + const uint64_t kFP32QuietNaNMask = 0x00400000UL; + uint32_t raw_n = float_to_rawbits(n); + uint32_t raw_m = float_to_rawbits(m); + + if (std::isnan(n) && ((raw_n & kFP32QuietNaNMask) == 0)) { + // n is signalling NaN. + return n; + } else if (std::isnan(m) && ((raw_m & kFP32QuietNaNMask) == 0)) { + // m is signalling NaN. + return m; + } else if (quiet_nan_substitute == 0.0) { + if (std::isnan(n)) { + // n is quiet NaN. + return n; + } else if (std::isnan(m)) { + // m is quiet NaN. + return m; + } + } else { + // Substitute n or m if one is quiet, but not both. + if (std::isnan(n) && !std::isnan(m)) { + // n is quiet NaN: replace with substitute. + n = quiet_nan_substitute; + } else if (!std::isnan(n) && std::isnan(m)) { + // m is quiet NaN: replace with substitute. + m = quiet_nan_substitute; + } + } + + if ((n == 0.0) && (m == 0.0) && + (copysign(1.0, n) != copysign(1.0, m))) { + return min ? -0.0 : 0.0; + } + + return min ? fminf(n, m) : fmaxf(n, m); +} + + +static double MinMaxHelper(double n, + double m, + bool min, + double quiet_nan_substitute = 0.0) { + const uint64_t kFP64QuietNaNMask = 0x0008000000000000UL; + uint64_t raw_n = double_to_rawbits(n); + uint64_t raw_m = double_to_rawbits(m); + + if (std::isnan(n) && ((raw_n & kFP64QuietNaNMask) == 0)) { + // n is signalling NaN. + return n; + } else if (std::isnan(m) && ((raw_m & kFP64QuietNaNMask) == 0)) { + // m is signalling NaN. + return m; + } else if (quiet_nan_substitute == 0.0) { + if (std::isnan(n)) { + // n is quiet NaN. + return n; + } else if (std::isnan(m)) { + // m is quiet NaN. + return m; + } + } else { + // Substitute n or m if one is quiet, but not both. + if (std::isnan(n) && !std::isnan(m)) { + // n is quiet NaN: replace with substitute. + n = quiet_nan_substitute; + } else if (!std::isnan(n) && std::isnan(m)) { + // m is quiet NaN: replace with substitute. + m = quiet_nan_substitute; + } + } + + if ((n == 0.0) && (m == 0.0) && + (copysign(1.0, n) != copysign(1.0, m))) { + return min ? -0.0 : 0.0; + } + + return min ? fmin(n, m) : fmax(n, m); +} + + +static void FminFmaxDoubleHelper(double n, double m, double min, double max, + double minnm, double maxnm) { + SETUP(); + + START(); + __ Fmov(d0, n); + __ Fmov(d1, m); + __ Fmin(d28, d0, d1); + __ Fmax(d29, d0, d1); + __ Fminnm(d30, d0, d1); + __ Fmaxnm(d31, d0, d1); + END(); + + RUN(); + + ASSERT_EQUAL_FP64(min, d28); + ASSERT_EQUAL_FP64(max, d29); + ASSERT_EQUAL_FP64(minnm, d30); + ASSERT_EQUAL_FP64(maxnm, d31); + + TEARDOWN(); +} + + +TEST(fmax_fmin_d) { + INIT_V8(); + // Bootstrap tests. + FminFmaxDoubleHelper(0, 0, 0, 0, 0, 0); + FminFmaxDoubleHelper(0, 1, 0, 1, 0, 1); + FminFmaxDoubleHelper(kFP64PositiveInfinity, kFP64NegativeInfinity, + kFP64NegativeInfinity, kFP64PositiveInfinity, + kFP64NegativeInfinity, kFP64PositiveInfinity); + FminFmaxDoubleHelper(kFP64SignallingNaN, 0, + kFP64SignallingNaN, kFP64SignallingNaN, + kFP64SignallingNaN, kFP64SignallingNaN); + FminFmaxDoubleHelper(kFP64QuietNaN, 0, + kFP64QuietNaN, kFP64QuietNaN, + 0, 0); + FminFmaxDoubleHelper(kFP64QuietNaN, kFP64SignallingNaN, + kFP64SignallingNaN, kFP64SignallingNaN, + kFP64SignallingNaN, kFP64SignallingNaN); + + // Iterate over all combinations of inputs. + double inputs[] = { DBL_MAX, DBL_MIN, 1.0, 0.0, + -DBL_MAX, -DBL_MIN, -1.0, -0.0, + kFP64PositiveInfinity, kFP64NegativeInfinity, + kFP64QuietNaN, kFP64SignallingNaN }; + + const int count = sizeof(inputs) / sizeof(inputs[0]); + + for (int in = 0; in < count; in++) { + double n = inputs[in]; + for (int im = 0; im < count; im++) { + double m = inputs[im]; + FminFmaxDoubleHelper(n, m, + MinMaxHelper(n, m, true), + MinMaxHelper(n, m, false), + MinMaxHelper(n, m, true, kFP64PositiveInfinity), + MinMaxHelper(n, m, false, kFP64NegativeInfinity)); + } + } +} + + +static void FminFmaxFloatHelper(float n, float m, float min, float max, + float minnm, float maxnm) { + SETUP(); + + START(); + // TODO(all): Signalling NaNs are sometimes converted by the C compiler to + // quiet NaNs on implicit casts from float to double. Here, we move the raw + // bits into a W register first, so we get the correct value. Fix Fmov so this + // additional step is no longer needed. + __ Mov(w0, float_to_rawbits(n)); + __ Fmov(s0, w0); + __ Mov(w0, float_to_rawbits(m)); + __ Fmov(s1, w0); + __ Fmin(s28, s0, s1); + __ Fmax(s29, s0, s1); + __ Fminnm(s30, s0, s1); + __ Fmaxnm(s31, s0, s1); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(min, s28); + ASSERT_EQUAL_FP32(max, s29); + ASSERT_EQUAL_FP32(minnm, s30); + ASSERT_EQUAL_FP32(maxnm, s31); + + TEARDOWN(); +} + + +TEST(fmax_fmin_s) { + INIT_V8(); + // Bootstrap tests. + FminFmaxFloatHelper(0, 0, 0, 0, 0, 0); + FminFmaxFloatHelper(0, 1, 0, 1, 0, 1); + FminFmaxFloatHelper(kFP32PositiveInfinity, kFP32NegativeInfinity, + kFP32NegativeInfinity, kFP32PositiveInfinity, + kFP32NegativeInfinity, kFP32PositiveInfinity); + FminFmaxFloatHelper(kFP32SignallingNaN, 0, + kFP32SignallingNaN, kFP32SignallingNaN, + kFP32SignallingNaN, kFP32SignallingNaN); + FminFmaxFloatHelper(kFP32QuietNaN, 0, + kFP32QuietNaN, kFP32QuietNaN, + 0, 0); + FminFmaxFloatHelper(kFP32QuietNaN, kFP32SignallingNaN, + kFP32SignallingNaN, kFP32SignallingNaN, + kFP32SignallingNaN, kFP32SignallingNaN); + + // Iterate over all combinations of inputs. + float inputs[] = { FLT_MAX, FLT_MIN, 1.0, 0.0, + -FLT_MAX, -FLT_MIN, -1.0, -0.0, + kFP32PositiveInfinity, kFP32NegativeInfinity, + kFP32QuietNaN, kFP32SignallingNaN }; + + const int count = sizeof(inputs) / sizeof(inputs[0]); + + for (int in = 0; in < count; in++) { + float n = inputs[in]; + for (int im = 0; im < count; im++) { + float m = inputs[im]; + FminFmaxFloatHelper(n, m, + MinMaxHelper(n, m, true), + MinMaxHelper(n, m, false), + MinMaxHelper(n, m, true, kFP32PositiveInfinity), + MinMaxHelper(n, m, false, kFP32NegativeInfinity)); + } + } +} + + +TEST(fccmp) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s16, 0.0); + __ Fmov(s17, 0.5); + __ Fmov(d18, -0.5); + __ Fmov(d19, -1.0); + __ Mov(x20, 0); + + __ Cmp(x20, 0); + __ Fccmp(s16, s16, NoFlag, eq); + __ Mrs(x0, NZCV); + + __ Cmp(x20, 0); + __ Fccmp(s16, s16, VFlag, ne); + __ Mrs(x1, NZCV); + + __ Cmp(x20, 0); + __ Fccmp(s16, s17, CFlag, ge); + __ Mrs(x2, NZCV); + + __ Cmp(x20, 0); + __ Fccmp(s16, s17, CVFlag, lt); + __ Mrs(x3, NZCV); + + __ Cmp(x20, 0); + __ Fccmp(d18, d18, ZFlag, le); + __ Mrs(x4, NZCV); + + __ Cmp(x20, 0); + __ Fccmp(d18, d18, ZVFlag, gt); + __ Mrs(x5, NZCV); + + __ Cmp(x20, 0); + __ Fccmp(d18, d19, ZCVFlag, ls); + __ Mrs(x6, NZCV); + + __ Cmp(x20, 0); + __ Fccmp(d18, d19, NFlag, hi); + __ Mrs(x7, NZCV); + + __ fccmp(s16, s16, NFlag, al); + __ Mrs(x8, NZCV); + + __ fccmp(d18, d18, NFlag, nv); + __ Mrs(x9, NZCV); + + END(); + + RUN(); + + ASSERT_EQUAL_32(ZCFlag, w0); + ASSERT_EQUAL_32(VFlag, w1); + ASSERT_EQUAL_32(NFlag, w2); + ASSERT_EQUAL_32(CVFlag, w3); + ASSERT_EQUAL_32(ZCFlag, w4); + ASSERT_EQUAL_32(ZVFlag, w5); + ASSERT_EQUAL_32(CFlag, w6); + ASSERT_EQUAL_32(NFlag, w7); + ASSERT_EQUAL_32(ZCFlag, w8); + ASSERT_EQUAL_32(ZCFlag, w9); + + TEARDOWN(); +} + + +TEST(fcmp) { + INIT_V8(); + SETUP(); + + START(); + + // Some of these tests require a floating-point scratch register assigned to + // the macro assembler, but most do not. + __ SetFPScratchRegister(NoFPReg); + + __ Fmov(s8, 0.0); + __ Fmov(s9, 0.5); + __ Mov(w18, 0x7f800001); // Single precision NaN. + __ Fmov(s18, w18); + + __ Fcmp(s8, s8); + __ Mrs(x0, NZCV); + __ Fcmp(s8, s9); + __ Mrs(x1, NZCV); + __ Fcmp(s9, s8); + __ Mrs(x2, NZCV); + __ Fcmp(s8, s18); + __ Mrs(x3, NZCV); + __ Fcmp(s18, s18); + __ Mrs(x4, NZCV); + __ Fcmp(s8, 0.0); + __ Mrs(x5, NZCV); + __ SetFPScratchRegister(d0); + __ Fcmp(s8, 255.0); + __ SetFPScratchRegister(NoFPReg); + __ Mrs(x6, NZCV); + + __ Fmov(d19, 0.0); + __ Fmov(d20, 0.5); + __ Mov(x21, 0x7ff0000000000001UL); // Double precision NaN. + __ Fmov(d21, x21); + + __ Fcmp(d19, d19); + __ Mrs(x10, NZCV); + __ Fcmp(d19, d20); + __ Mrs(x11, NZCV); + __ Fcmp(d20, d19); + __ Mrs(x12, NZCV); + __ Fcmp(d19, d21); + __ Mrs(x13, NZCV); + __ Fcmp(d21, d21); + __ Mrs(x14, NZCV); + __ Fcmp(d19, 0.0); + __ Mrs(x15, NZCV); + __ SetFPScratchRegister(d0); + __ Fcmp(d19, 12.3456); + __ SetFPScratchRegister(NoFPReg); + __ Mrs(x16, NZCV); + END(); + + RUN(); + + ASSERT_EQUAL_32(ZCFlag, w0); + ASSERT_EQUAL_32(NFlag, w1); + ASSERT_EQUAL_32(CFlag, w2); + ASSERT_EQUAL_32(CVFlag, w3); + ASSERT_EQUAL_32(CVFlag, w4); + ASSERT_EQUAL_32(ZCFlag, w5); + ASSERT_EQUAL_32(NFlag, w6); + ASSERT_EQUAL_32(ZCFlag, w10); + ASSERT_EQUAL_32(NFlag, w11); + ASSERT_EQUAL_32(CFlag, w12); + ASSERT_EQUAL_32(CVFlag, w13); + ASSERT_EQUAL_32(CVFlag, w14); + ASSERT_EQUAL_32(ZCFlag, w15); + ASSERT_EQUAL_32(NFlag, w16); + + TEARDOWN(); +} + + +TEST(fcsel) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(x16, 0); + __ Fmov(s16, 1.0); + __ Fmov(s17, 2.0); + __ Fmov(d18, 3.0); + __ Fmov(d19, 4.0); + + __ Cmp(x16, 0); + __ Fcsel(s0, s16, s17, eq); + __ Fcsel(s1, s16, s17, ne); + __ Fcsel(d2, d18, d19, eq); + __ Fcsel(d3, d18, d19, ne); + __ fcsel(s4, s16, s17, al); + __ fcsel(d5, d18, d19, nv); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(1.0, s0); + ASSERT_EQUAL_FP32(2.0, s1); + ASSERT_EQUAL_FP64(3.0, d2); + ASSERT_EQUAL_FP64(4.0, d3); + ASSERT_EQUAL_FP32(1.0, s4); + ASSERT_EQUAL_FP64(3.0, d5); + + TEARDOWN(); +} + + +TEST(fneg) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s16, 1.0); + __ Fmov(s17, 0.0); + __ Fmov(s18, kFP32PositiveInfinity); + __ Fmov(d19, 1.0); + __ Fmov(d20, 0.0); + __ Fmov(d21, kFP64PositiveInfinity); + + __ Fneg(s0, s16); + __ Fneg(s1, s0); + __ Fneg(s2, s17); + __ Fneg(s3, s2); + __ Fneg(s4, s18); + __ Fneg(s5, s4); + __ Fneg(d6, d19); + __ Fneg(d7, d6); + __ Fneg(d8, d20); + __ Fneg(d9, d8); + __ Fneg(d10, d21); + __ Fneg(d11, d10); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(-1.0, s0); + ASSERT_EQUAL_FP32(1.0, s1); + ASSERT_EQUAL_FP32(-0.0, s2); + ASSERT_EQUAL_FP32(0.0, s3); + ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4); + ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5); + ASSERT_EQUAL_FP64(-1.0, d6); + ASSERT_EQUAL_FP64(1.0, d7); + ASSERT_EQUAL_FP64(-0.0, d8); + ASSERT_EQUAL_FP64(0.0, d9); + ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10); + ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11); + + TEARDOWN(); +} + + +TEST(fabs) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s16, -1.0); + __ Fmov(s17, -0.0); + __ Fmov(s18, kFP32NegativeInfinity); + __ Fmov(d19, -1.0); + __ Fmov(d20, -0.0); + __ Fmov(d21, kFP64NegativeInfinity); + + __ Fabs(s0, s16); + __ Fabs(s1, s0); + __ Fabs(s2, s17); + __ Fabs(s3, s18); + __ Fabs(d4, d19); + __ Fabs(d5, d4); + __ Fabs(d6, d20); + __ Fabs(d7, d21); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(1.0, s0); + ASSERT_EQUAL_FP32(1.0, s1); + ASSERT_EQUAL_FP32(0.0, s2); + ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3); + ASSERT_EQUAL_FP64(1.0, d4); + ASSERT_EQUAL_FP64(1.0, d5); + ASSERT_EQUAL_FP64(0.0, d6); + ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7); + + TEARDOWN(); +} + + +TEST(fsqrt) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s16, 0.0); + __ Fmov(s17, 1.0); + __ Fmov(s18, 0.25); + __ Fmov(s19, 65536.0); + __ Fmov(s20, -0.0); + __ Fmov(s21, kFP32PositiveInfinity); + __ Fmov(d22, 0.0); + __ Fmov(d23, 1.0); + __ Fmov(d24, 0.25); + __ Fmov(d25, 4294967296.0); + __ Fmov(d26, -0.0); + __ Fmov(d27, kFP64PositiveInfinity); + + __ Fsqrt(s0, s16); + __ Fsqrt(s1, s17); + __ Fsqrt(s2, s18); + __ Fsqrt(s3, s19); + __ Fsqrt(s4, s20); + __ Fsqrt(s5, s21); + __ Fsqrt(d6, d22); + __ Fsqrt(d7, d23); + __ Fsqrt(d8, d24); + __ Fsqrt(d9, d25); + __ Fsqrt(d10, d26); + __ Fsqrt(d11, d27); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(0.0, s0); + ASSERT_EQUAL_FP32(1.0, s1); + ASSERT_EQUAL_FP32(0.5, s2); + ASSERT_EQUAL_FP32(256.0, s3); + ASSERT_EQUAL_FP32(-0.0, s4); + ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5); + ASSERT_EQUAL_FP64(0.0, d6); + ASSERT_EQUAL_FP64(1.0, d7); + ASSERT_EQUAL_FP64(0.5, d8); + ASSERT_EQUAL_FP64(65536.0, d9); + ASSERT_EQUAL_FP64(-0.0, d10); + ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d11); + + TEARDOWN(); +} + + +TEST(frinta) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s16, 1.0); + __ Fmov(s17, 1.1); + __ Fmov(s18, 1.5); + __ Fmov(s19, 1.9); + __ Fmov(s20, 2.5); + __ Fmov(s21, -1.5); + __ Fmov(s22, -2.5); + __ Fmov(s23, kFP32PositiveInfinity); + __ Fmov(s24, kFP32NegativeInfinity); + __ Fmov(s25, 0.0); + __ Fmov(s26, -0.0); + + __ Frinta(s0, s16); + __ Frinta(s1, s17); + __ Frinta(s2, s18); + __ Frinta(s3, s19); + __ Frinta(s4, s20); + __ Frinta(s5, s21); + __ Frinta(s6, s22); + __ Frinta(s7, s23); + __ Frinta(s8, s24); + __ Frinta(s9, s25); + __ Frinta(s10, s26); + + __ Fmov(d16, 1.0); + __ Fmov(d17, 1.1); + __ Fmov(d18, 1.5); + __ Fmov(d19, 1.9); + __ Fmov(d20, 2.5); + __ Fmov(d21, -1.5); + __ Fmov(d22, -2.5); + __ Fmov(d23, kFP32PositiveInfinity); + __ Fmov(d24, kFP32NegativeInfinity); + __ Fmov(d25, 0.0); + __ Fmov(d26, -0.0); + + __ Frinta(d11, d16); + __ Frinta(d12, d17); + __ Frinta(d13, d18); + __ Frinta(d14, d19); + __ Frinta(d15, d20); + __ Frinta(d16, d21); + __ Frinta(d17, d22); + __ Frinta(d18, d23); + __ Frinta(d19, d24); + __ Frinta(d20, d25); + __ Frinta(d21, d26); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(1.0, s0); + ASSERT_EQUAL_FP32(1.0, s1); + ASSERT_EQUAL_FP32(2.0, s2); + ASSERT_EQUAL_FP32(2.0, s3); + ASSERT_EQUAL_FP32(3.0, s4); + ASSERT_EQUAL_FP32(-2.0, s5); + ASSERT_EQUAL_FP32(-3.0, s6); + ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7); + ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8); + ASSERT_EQUAL_FP32(0.0, s9); + ASSERT_EQUAL_FP32(-0.0, s10); + ASSERT_EQUAL_FP64(1.0, d11); + ASSERT_EQUAL_FP64(1.0, d12); + ASSERT_EQUAL_FP64(2.0, d13); + ASSERT_EQUAL_FP64(2.0, d14); + ASSERT_EQUAL_FP64(3.0, d15); + ASSERT_EQUAL_FP64(-2.0, d16); + ASSERT_EQUAL_FP64(-3.0, d17); + ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18); + ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19); + ASSERT_EQUAL_FP64(0.0, d20); + ASSERT_EQUAL_FP64(-0.0, d21); + + TEARDOWN(); +} + + +TEST(frintn) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s16, 1.0); + __ Fmov(s17, 1.1); + __ Fmov(s18, 1.5); + __ Fmov(s19, 1.9); + __ Fmov(s20, 2.5); + __ Fmov(s21, -1.5); + __ Fmov(s22, -2.5); + __ Fmov(s23, kFP32PositiveInfinity); + __ Fmov(s24, kFP32NegativeInfinity); + __ Fmov(s25, 0.0); + __ Fmov(s26, -0.0); + + __ Frintn(s0, s16); + __ Frintn(s1, s17); + __ Frintn(s2, s18); + __ Frintn(s3, s19); + __ Frintn(s4, s20); + __ Frintn(s5, s21); + __ Frintn(s6, s22); + __ Frintn(s7, s23); + __ Frintn(s8, s24); + __ Frintn(s9, s25); + __ Frintn(s10, s26); + + __ Fmov(d16, 1.0); + __ Fmov(d17, 1.1); + __ Fmov(d18, 1.5); + __ Fmov(d19, 1.9); + __ Fmov(d20, 2.5); + __ Fmov(d21, -1.5); + __ Fmov(d22, -2.5); + __ Fmov(d23, kFP32PositiveInfinity); + __ Fmov(d24, kFP32NegativeInfinity); + __ Fmov(d25, 0.0); + __ Fmov(d26, -0.0); + + __ Frintn(d11, d16); + __ Frintn(d12, d17); + __ Frintn(d13, d18); + __ Frintn(d14, d19); + __ Frintn(d15, d20); + __ Frintn(d16, d21); + __ Frintn(d17, d22); + __ Frintn(d18, d23); + __ Frintn(d19, d24); + __ Frintn(d20, d25); + __ Frintn(d21, d26); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(1.0, s0); + ASSERT_EQUAL_FP32(1.0, s1); + ASSERT_EQUAL_FP32(2.0, s2); + ASSERT_EQUAL_FP32(2.0, s3); + ASSERT_EQUAL_FP32(2.0, s4); + ASSERT_EQUAL_FP32(-2.0, s5); + ASSERT_EQUAL_FP32(-2.0, s6); + ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7); + ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8); + ASSERT_EQUAL_FP32(0.0, s9); + ASSERT_EQUAL_FP32(-0.0, s10); + ASSERT_EQUAL_FP64(1.0, d11); + ASSERT_EQUAL_FP64(1.0, d12); + ASSERT_EQUAL_FP64(2.0, d13); + ASSERT_EQUAL_FP64(2.0, d14); + ASSERT_EQUAL_FP64(2.0, d15); + ASSERT_EQUAL_FP64(-2.0, d16); + ASSERT_EQUAL_FP64(-2.0, d17); + ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18); + ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19); + ASSERT_EQUAL_FP64(0.0, d20); + ASSERT_EQUAL_FP64(-0.0, d21); + + TEARDOWN(); +} + + +TEST(frintz) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s16, 1.0); + __ Fmov(s17, 1.1); + __ Fmov(s18, 1.5); + __ Fmov(s19, 1.9); + __ Fmov(s20, 2.5); + __ Fmov(s21, -1.5); + __ Fmov(s22, -2.5); + __ Fmov(s23, kFP32PositiveInfinity); + __ Fmov(s24, kFP32NegativeInfinity); + __ Fmov(s25, 0.0); + __ Fmov(s26, -0.0); + + __ Frintz(s0, s16); + __ Frintz(s1, s17); + __ Frintz(s2, s18); + __ Frintz(s3, s19); + __ Frintz(s4, s20); + __ Frintz(s5, s21); + __ Frintz(s6, s22); + __ Frintz(s7, s23); + __ Frintz(s8, s24); + __ Frintz(s9, s25); + __ Frintz(s10, s26); + + __ Fmov(d16, 1.0); + __ Fmov(d17, 1.1); + __ Fmov(d18, 1.5); + __ Fmov(d19, 1.9); + __ Fmov(d20, 2.5); + __ Fmov(d21, -1.5); + __ Fmov(d22, -2.5); + __ Fmov(d23, kFP32PositiveInfinity); + __ Fmov(d24, kFP32NegativeInfinity); + __ Fmov(d25, 0.0); + __ Fmov(d26, -0.0); + + __ Frintz(d11, d16); + __ Frintz(d12, d17); + __ Frintz(d13, d18); + __ Frintz(d14, d19); + __ Frintz(d15, d20); + __ Frintz(d16, d21); + __ Frintz(d17, d22); + __ Frintz(d18, d23); + __ Frintz(d19, d24); + __ Frintz(d20, d25); + __ Frintz(d21, d26); + END(); + + RUN(); + + ASSERT_EQUAL_FP32(1.0, s0); + ASSERT_EQUAL_FP32(1.0, s1); + ASSERT_EQUAL_FP32(1.0, s2); + ASSERT_EQUAL_FP32(1.0, s3); + ASSERT_EQUAL_FP32(2.0, s4); + ASSERT_EQUAL_FP32(-1.0, s5); + ASSERT_EQUAL_FP32(-2.0, s6); + ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7); + ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8); + ASSERT_EQUAL_FP32(0.0, s9); + ASSERT_EQUAL_FP32(-0.0, s10); + ASSERT_EQUAL_FP64(1.0, d11); + ASSERT_EQUAL_FP64(1.0, d12); + ASSERT_EQUAL_FP64(1.0, d13); + ASSERT_EQUAL_FP64(1.0, d14); + ASSERT_EQUAL_FP64(2.0, d15); + ASSERT_EQUAL_FP64(-1.0, d16); + ASSERT_EQUAL_FP64(-2.0, d17); + ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18); + ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19); + ASSERT_EQUAL_FP64(0.0, d20); + ASSERT_EQUAL_FP64(-0.0, d21); + + TEARDOWN(); +} + + +TEST(fcvt_ds) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s16, 1.0); + __ Fmov(s17, 1.1); + __ Fmov(s18, 1.5); + __ Fmov(s19, 1.9); + __ Fmov(s20, 2.5); + __ Fmov(s21, -1.5); + __ Fmov(s22, -2.5); + __ Fmov(s23, kFP32PositiveInfinity); + __ Fmov(s24, kFP32NegativeInfinity); + __ Fmov(s25, 0.0); + __ Fmov(s26, -0.0); + __ Fmov(s27, FLT_MAX); + __ Fmov(s28, FLT_MIN); + __ Fmov(s29, rawbits_to_float(0x7fc12345)); // Quiet NaN. + __ Fmov(s30, rawbits_to_float(0x7f812345)); // Signalling NaN. + + __ Fcvt(d0, s16); + __ Fcvt(d1, s17); + __ Fcvt(d2, s18); + __ Fcvt(d3, s19); + __ Fcvt(d4, s20); + __ Fcvt(d5, s21); + __ Fcvt(d6, s22); + __ Fcvt(d7, s23); + __ Fcvt(d8, s24); + __ Fcvt(d9, s25); + __ Fcvt(d10, s26); + __ Fcvt(d11, s27); + __ Fcvt(d12, s28); + __ Fcvt(d13, s29); + __ Fcvt(d14, s30); + END(); + + RUN(); + + ASSERT_EQUAL_FP64(1.0f, d0); + ASSERT_EQUAL_FP64(1.1f, d1); + ASSERT_EQUAL_FP64(1.5f, d2); + ASSERT_EQUAL_FP64(1.9f, d3); + ASSERT_EQUAL_FP64(2.5f, d4); + ASSERT_EQUAL_FP64(-1.5f, d5); + ASSERT_EQUAL_FP64(-2.5f, d6); + ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7); + ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8); + ASSERT_EQUAL_FP64(0.0f, d9); + ASSERT_EQUAL_FP64(-0.0f, d10); + ASSERT_EQUAL_FP64(FLT_MAX, d11); + ASSERT_EQUAL_FP64(FLT_MIN, d12); + + // Check that the NaN payload is preserved according to A64 conversion rules: + // - The sign bit is preserved. + // - The top bit of the mantissa is forced to 1 (making it a quiet NaN). + // - The remaining mantissa bits are copied until they run out. + // - The low-order bits that haven't already been assigned are set to 0. + ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d13); + ASSERT_EQUAL_FP64(rawbits_to_double(0x7ff82468a0000000), d14); + + TEARDOWN(); +} + + +TEST(fcvt_sd) { + INIT_V8(); + // There are a huge number of corner-cases to check, so this test iterates + // through a list. The list is then negated and checked again (since the sign + // is irrelevant in ties-to-even rounding), so the list shouldn't include any + // negative values. + // + // Note that this test only checks ties-to-even rounding, because that is all + // that the simulator supports. + struct {double in; float expected;} test[] = { + // Check some simple conversions. + {0.0, 0.0f}, + {1.0, 1.0f}, + {1.5, 1.5f}, + {2.0, 2.0f}, + {FLT_MAX, FLT_MAX}, + // - The smallest normalized float. + {pow(2.0, -126), powf(2, -126)}, + // - Normal floats that need (ties-to-even) rounding. + // For normalized numbers: + // bit 29 (0x0000000020000000) is the lowest-order bit which will + // fit in the float's mantissa. + {rawbits_to_double(0x3ff0000000000000), rawbits_to_float(0x3f800000)}, + {rawbits_to_double(0x3ff0000000000001), rawbits_to_float(0x3f800000)}, + {rawbits_to_double(0x3ff0000010000000), rawbits_to_float(0x3f800000)}, + {rawbits_to_double(0x3ff0000010000001), rawbits_to_float(0x3f800001)}, + {rawbits_to_double(0x3ff0000020000000), rawbits_to_float(0x3f800001)}, + {rawbits_to_double(0x3ff0000020000001), rawbits_to_float(0x3f800001)}, + {rawbits_to_double(0x3ff0000030000000), rawbits_to_float(0x3f800002)}, + {rawbits_to_double(0x3ff0000030000001), rawbits_to_float(0x3f800002)}, + {rawbits_to_double(0x3ff0000040000000), rawbits_to_float(0x3f800002)}, + {rawbits_to_double(0x3ff0000040000001), rawbits_to_float(0x3f800002)}, + {rawbits_to_double(0x3ff0000050000000), rawbits_to_float(0x3f800002)}, + {rawbits_to_double(0x3ff0000050000001), rawbits_to_float(0x3f800003)}, + {rawbits_to_double(0x3ff0000060000000), rawbits_to_float(0x3f800003)}, + // - A mantissa that overflows into the exponent during rounding. + {rawbits_to_double(0x3feffffff0000000), rawbits_to_float(0x3f800000)}, + // - The largest double that rounds to a normal float. + {rawbits_to_double(0x47efffffefffffff), rawbits_to_float(0x7f7fffff)}, + + // Doubles that are too big for a float. + {kFP64PositiveInfinity, kFP32PositiveInfinity}, + {DBL_MAX, kFP32PositiveInfinity}, + // - The smallest exponent that's too big for a float. + {pow(2.0, 128), kFP32PositiveInfinity}, + // - This exponent is in range, but the value rounds to infinity. + {rawbits_to_double(0x47effffff0000000), kFP32PositiveInfinity}, + + // Doubles that are too small for a float. + // - The smallest (subnormal) double. + {DBL_MIN, 0.0}, + // - The largest double which is too small for a subnormal float. + {rawbits_to_double(0x3690000000000000), rawbits_to_float(0x00000000)}, + + // Normal doubles that become subnormal floats. + // - The largest subnormal float. + {rawbits_to_double(0x380fffffc0000000), rawbits_to_float(0x007fffff)}, + // - The smallest subnormal float. + {rawbits_to_double(0x36a0000000000000), rawbits_to_float(0x00000001)}, + // - Subnormal floats that need (ties-to-even) rounding. + // For these subnormals: + // bit 34 (0x0000000400000000) is the lowest-order bit which will + // fit in the float's mantissa. + {rawbits_to_double(0x37c159e000000000), rawbits_to_float(0x00045678)}, + {rawbits_to_double(0x37c159e000000001), rawbits_to_float(0x00045678)}, + {rawbits_to_double(0x37c159e200000000), rawbits_to_float(0x00045678)}, + {rawbits_to_double(0x37c159e200000001), rawbits_to_float(0x00045679)}, + {rawbits_to_double(0x37c159e400000000), rawbits_to_float(0x00045679)}, + {rawbits_to_double(0x37c159e400000001), rawbits_to_float(0x00045679)}, + {rawbits_to_double(0x37c159e600000000), rawbits_to_float(0x0004567a)}, + {rawbits_to_double(0x37c159e600000001), rawbits_to_float(0x0004567a)}, + {rawbits_to_double(0x37c159e800000000), rawbits_to_float(0x0004567a)}, + {rawbits_to_double(0x37c159e800000001), rawbits_to_float(0x0004567a)}, + {rawbits_to_double(0x37c159ea00000000), rawbits_to_float(0x0004567a)}, + {rawbits_to_double(0x37c159ea00000001), rawbits_to_float(0x0004567b)}, + {rawbits_to_double(0x37c159ec00000000), rawbits_to_float(0x0004567b)}, + // - The smallest double which rounds up to become a subnormal float. + {rawbits_to_double(0x3690000000000001), rawbits_to_float(0x00000001)}, + + // Check NaN payload preservation. + {rawbits_to_double(0x7ff82468a0000000), rawbits_to_float(0x7fc12345)}, + {rawbits_to_double(0x7ff82468bfffffff), rawbits_to_float(0x7fc12345)}, + // - Signalling NaNs become quiet NaNs. + {rawbits_to_double(0x7ff02468a0000000), rawbits_to_float(0x7fc12345)}, + {rawbits_to_double(0x7ff02468bfffffff), rawbits_to_float(0x7fc12345)}, + {rawbits_to_double(0x7ff000001fffffff), rawbits_to_float(0x7fc00000)}, + }; + int count = sizeof(test) / sizeof(test[0]); + + for (int i = 0; i < count; i++) { + double in = test[i].in; + float expected = test[i].expected; + + // We only expect positive input. + ASSERT(std::signbit(in) == 0); + ASSERT(std::signbit(expected) == 0); + + SETUP(); + START(); + + __ Fmov(d10, in); + __ Fcvt(s20, d10); + + __ Fmov(d11, -in); + __ Fcvt(s21, d11); + + END(); + RUN(); + ASSERT_EQUAL_FP32(expected, s20); + ASSERT_EQUAL_FP32(-expected, s21); + TEARDOWN(); + } +} + + +TEST(fcvtas) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s0, 1.0); + __ Fmov(s1, 1.1); + __ Fmov(s2, 2.5); + __ Fmov(s3, -2.5); + __ Fmov(s4, kFP32PositiveInfinity); + __ Fmov(s5, kFP32NegativeInfinity); + __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX. + __ Fneg(s7, s6); // Smallest float > INT32_MIN. + __ Fmov(d8, 1.0); + __ Fmov(d9, 1.1); + __ Fmov(d10, 2.5); + __ Fmov(d11, -2.5); + __ Fmov(d12, kFP64PositiveInfinity); + __ Fmov(d13, kFP64NegativeInfinity); + __ Fmov(d14, kWMaxInt - 1); + __ Fmov(d15, kWMinInt + 1); + __ Fmov(s17, 1.1); + __ Fmov(s18, 2.5); + __ Fmov(s19, -2.5); + __ Fmov(s20, kFP32PositiveInfinity); + __ Fmov(s21, kFP32NegativeInfinity); + __ Fmov(s22, 0x7fffff8000000000UL); // Largest float < INT64_MAX. + __ Fneg(s23, s22); // Smallest float > INT64_MIN. + __ Fmov(d24, 1.1); + __ Fmov(d25, 2.5); + __ Fmov(d26, -2.5); + __ Fmov(d27, kFP64PositiveInfinity); + __ Fmov(d28, kFP64NegativeInfinity); + __ Fmov(d29, 0x7ffffffffffffc00UL); // Largest double < INT64_MAX. + __ Fneg(d30, d29); // Smallest double > INT64_MIN. + + __ Fcvtas(w0, s0); + __ Fcvtas(w1, s1); + __ Fcvtas(w2, s2); + __ Fcvtas(w3, s3); + __ Fcvtas(w4, s4); + __ Fcvtas(w5, s5); + __ Fcvtas(w6, s6); + __ Fcvtas(w7, s7); + __ Fcvtas(w8, d8); + __ Fcvtas(w9, d9); + __ Fcvtas(w10, d10); + __ Fcvtas(w11, d11); + __ Fcvtas(w12, d12); + __ Fcvtas(w13, d13); + __ Fcvtas(w14, d14); + __ Fcvtas(w15, d15); + __ Fcvtas(x17, s17); + __ Fcvtas(x18, s18); + __ Fcvtas(x19, s19); + __ Fcvtas(x20, s20); + __ Fcvtas(x21, s21); + __ Fcvtas(x22, s22); + __ Fcvtas(x23, s23); + __ Fcvtas(x24, d24); + __ Fcvtas(x25, d25); + __ Fcvtas(x26, d26); + __ Fcvtas(x27, d27); + __ Fcvtas(x28, d28); + __ Fcvtas(x29, d29); + __ Fcvtas(x30, d30); + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + ASSERT_EQUAL_64(1, x1); + ASSERT_EQUAL_64(3, x2); + ASSERT_EQUAL_64(0xfffffffd, x3); + ASSERT_EQUAL_64(0x7fffffff, x4); + ASSERT_EQUAL_64(0x80000000, x5); + ASSERT_EQUAL_64(0x7fffff80, x6); + ASSERT_EQUAL_64(0x80000080, x7); + ASSERT_EQUAL_64(1, x8); + ASSERT_EQUAL_64(1, x9); + ASSERT_EQUAL_64(3, x10); + ASSERT_EQUAL_64(0xfffffffd, x11); + ASSERT_EQUAL_64(0x7fffffff, x12); + ASSERT_EQUAL_64(0x80000000, x13); + ASSERT_EQUAL_64(0x7ffffffe, x14); + ASSERT_EQUAL_64(0x80000001, x15); + ASSERT_EQUAL_64(1, x17); + ASSERT_EQUAL_64(3, x18); + ASSERT_EQUAL_64(0xfffffffffffffffdUL, x19); + ASSERT_EQUAL_64(0x7fffffffffffffffUL, x20); + ASSERT_EQUAL_64(0x8000000000000000UL, x21); + ASSERT_EQUAL_64(0x7fffff8000000000UL, x22); + ASSERT_EQUAL_64(0x8000008000000000UL, x23); + ASSERT_EQUAL_64(1, x24); + ASSERT_EQUAL_64(3, x25); + ASSERT_EQUAL_64(0xfffffffffffffffdUL, x26); + ASSERT_EQUAL_64(0x7fffffffffffffffUL, x27); + ASSERT_EQUAL_64(0x8000000000000000UL, x28); + ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29); + ASSERT_EQUAL_64(0x8000000000000400UL, x30); + + TEARDOWN(); +} + + +TEST(fcvtau) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s0, 1.0); + __ Fmov(s1, 1.1); + __ Fmov(s2, 2.5); + __ Fmov(s3, -2.5); + __ Fmov(s4, kFP32PositiveInfinity); + __ Fmov(s5, kFP32NegativeInfinity); + __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX. + __ Fmov(d8, 1.0); + __ Fmov(d9, 1.1); + __ Fmov(d10, 2.5); + __ Fmov(d11, -2.5); + __ Fmov(d12, kFP64PositiveInfinity); + __ Fmov(d13, kFP64NegativeInfinity); + __ Fmov(d14, 0xfffffffe); + __ Fmov(s16, 1.0); + __ Fmov(s17, 1.1); + __ Fmov(s18, 2.5); + __ Fmov(s19, -2.5); + __ Fmov(s20, kFP32PositiveInfinity); + __ Fmov(s21, kFP32NegativeInfinity); + __ Fmov(s22, 0xffffff0000000000UL); // Largest float < UINT64_MAX. + __ Fmov(d24, 1.1); + __ Fmov(d25, 2.5); + __ Fmov(d26, -2.5); + __ Fmov(d27, kFP64PositiveInfinity); + __ Fmov(d28, kFP64NegativeInfinity); + __ Fmov(d29, 0xfffffffffffff800UL); // Largest double < UINT64_MAX. + __ Fmov(s30, 0x100000000UL); + + __ Fcvtau(w0, s0); + __ Fcvtau(w1, s1); + __ Fcvtau(w2, s2); + __ Fcvtau(w3, s3); + __ Fcvtau(w4, s4); + __ Fcvtau(w5, s5); + __ Fcvtau(w6, s6); + __ Fcvtau(w8, d8); + __ Fcvtau(w9, d9); + __ Fcvtau(w10, d10); + __ Fcvtau(w11, d11); + __ Fcvtau(w12, d12); + __ Fcvtau(w13, d13); + __ Fcvtau(w14, d14); + __ Fcvtau(w15, d15); + __ Fcvtau(x16, s16); + __ Fcvtau(x17, s17); + __ Fcvtau(x18, s18); + __ Fcvtau(x19, s19); + __ Fcvtau(x20, s20); + __ Fcvtau(x21, s21); + __ Fcvtau(x22, s22); + __ Fcvtau(x24, d24); + __ Fcvtau(x25, d25); + __ Fcvtau(x26, d26); + __ Fcvtau(x27, d27); + __ Fcvtau(x28, d28); + __ Fcvtau(x29, d29); + __ Fcvtau(w30, s30); + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + ASSERT_EQUAL_64(1, x1); + ASSERT_EQUAL_64(3, x2); + ASSERT_EQUAL_64(0, x3); + ASSERT_EQUAL_64(0xffffffff, x4); + ASSERT_EQUAL_64(0, x5); + ASSERT_EQUAL_64(0xffffff00, x6); + ASSERT_EQUAL_64(1, x8); + ASSERT_EQUAL_64(1, x9); + ASSERT_EQUAL_64(3, x10); + ASSERT_EQUAL_64(0, x11); + ASSERT_EQUAL_64(0xffffffff, x12); + ASSERT_EQUAL_64(0, x13); + ASSERT_EQUAL_64(0xfffffffe, x14); + ASSERT_EQUAL_64(1, x16); + ASSERT_EQUAL_64(1, x17); + ASSERT_EQUAL_64(3, x18); + ASSERT_EQUAL_64(0, x19); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x20); + ASSERT_EQUAL_64(0, x21); + ASSERT_EQUAL_64(0xffffff0000000000UL, x22); + ASSERT_EQUAL_64(1, x24); + ASSERT_EQUAL_64(3, x25); + ASSERT_EQUAL_64(0, x26); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x27); + ASSERT_EQUAL_64(0, x28); + ASSERT_EQUAL_64(0xfffffffffffff800UL, x29); + ASSERT_EQUAL_64(0xffffffff, x30); + + TEARDOWN(); +} + + +TEST(fcvtms) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s0, 1.0); + __ Fmov(s1, 1.1); + __ Fmov(s2, 1.5); + __ Fmov(s3, -1.5); + __ Fmov(s4, kFP32PositiveInfinity); + __ Fmov(s5, kFP32NegativeInfinity); + __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX. + __ Fneg(s7, s6); // Smallest float > INT32_MIN. + __ Fmov(d8, 1.0); + __ Fmov(d9, 1.1); + __ Fmov(d10, 1.5); + __ Fmov(d11, -1.5); + __ Fmov(d12, kFP64PositiveInfinity); + __ Fmov(d13, kFP64NegativeInfinity); + __ Fmov(d14, kWMaxInt - 1); + __ Fmov(d15, kWMinInt + 1); + __ Fmov(s17, 1.1); + __ Fmov(s18, 1.5); + __ Fmov(s19, -1.5); + __ Fmov(s20, kFP32PositiveInfinity); + __ Fmov(s21, kFP32NegativeInfinity); + __ Fmov(s22, 0x7fffff8000000000UL); // Largest float < INT64_MAX. + __ Fneg(s23, s22); // Smallest float > INT64_MIN. + __ Fmov(d24, 1.1); + __ Fmov(d25, 1.5); + __ Fmov(d26, -1.5); + __ Fmov(d27, kFP64PositiveInfinity); + __ Fmov(d28, kFP64NegativeInfinity); + __ Fmov(d29, 0x7ffffffffffffc00UL); // Largest double < INT64_MAX. + __ Fneg(d30, d29); // Smallest double > INT64_MIN. + + __ Fcvtms(w0, s0); + __ Fcvtms(w1, s1); + __ Fcvtms(w2, s2); + __ Fcvtms(w3, s3); + __ Fcvtms(w4, s4); + __ Fcvtms(w5, s5); + __ Fcvtms(w6, s6); + __ Fcvtms(w7, s7); + __ Fcvtms(w8, d8); + __ Fcvtms(w9, d9); + __ Fcvtms(w10, d10); + __ Fcvtms(w11, d11); + __ Fcvtms(w12, d12); + __ Fcvtms(w13, d13); + __ Fcvtms(w14, d14); + __ Fcvtms(w15, d15); + __ Fcvtms(x17, s17); + __ Fcvtms(x18, s18); + __ Fcvtms(x19, s19); + __ Fcvtms(x20, s20); + __ Fcvtms(x21, s21); + __ Fcvtms(x22, s22); + __ Fcvtms(x23, s23); + __ Fcvtms(x24, d24); + __ Fcvtms(x25, d25); + __ Fcvtms(x26, d26); + __ Fcvtms(x27, d27); + __ Fcvtms(x28, d28); + __ Fcvtms(x29, d29); + __ Fcvtms(x30, d30); + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + ASSERT_EQUAL_64(1, x1); + ASSERT_EQUAL_64(1, x2); + ASSERT_EQUAL_64(0xfffffffe, x3); + ASSERT_EQUAL_64(0x7fffffff, x4); + ASSERT_EQUAL_64(0x80000000, x5); + ASSERT_EQUAL_64(0x7fffff80, x6); + ASSERT_EQUAL_64(0x80000080, x7); + ASSERT_EQUAL_64(1, x8); + ASSERT_EQUAL_64(1, x9); + ASSERT_EQUAL_64(1, x10); + ASSERT_EQUAL_64(0xfffffffe, x11); + ASSERT_EQUAL_64(0x7fffffff, x12); + ASSERT_EQUAL_64(0x80000000, x13); + ASSERT_EQUAL_64(0x7ffffffe, x14); + ASSERT_EQUAL_64(0x80000001, x15); + ASSERT_EQUAL_64(1, x17); + ASSERT_EQUAL_64(1, x18); + ASSERT_EQUAL_64(0xfffffffffffffffeUL, x19); + ASSERT_EQUAL_64(0x7fffffffffffffffUL, x20); + ASSERT_EQUAL_64(0x8000000000000000UL, x21); + ASSERT_EQUAL_64(0x7fffff8000000000UL, x22); + ASSERT_EQUAL_64(0x8000008000000000UL, x23); + ASSERT_EQUAL_64(1, x24); + ASSERT_EQUAL_64(1, x25); + ASSERT_EQUAL_64(0xfffffffffffffffeUL, x26); + ASSERT_EQUAL_64(0x7fffffffffffffffUL, x27); + ASSERT_EQUAL_64(0x8000000000000000UL, x28); + ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29); + ASSERT_EQUAL_64(0x8000000000000400UL, x30); + + TEARDOWN(); +} + + +TEST(fcvtmu) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s0, 1.0); + __ Fmov(s1, 1.1); + __ Fmov(s2, 1.5); + __ Fmov(s3, -1.5); + __ Fmov(s4, kFP32PositiveInfinity); + __ Fmov(s5, kFP32NegativeInfinity); + __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX. + __ Fneg(s7, s6); // Smallest float > INT32_MIN. + __ Fmov(d8, 1.0); + __ Fmov(d9, 1.1); + __ Fmov(d10, 1.5); + __ Fmov(d11, -1.5); + __ Fmov(d12, kFP64PositiveInfinity); + __ Fmov(d13, kFP64NegativeInfinity); + __ Fmov(d14, kWMaxInt - 1); + __ Fmov(d15, kWMinInt + 1); + __ Fmov(s17, 1.1); + __ Fmov(s18, 1.5); + __ Fmov(s19, -1.5); + __ Fmov(s20, kFP32PositiveInfinity); + __ Fmov(s21, kFP32NegativeInfinity); + __ Fmov(s22, 0x7fffff8000000000UL); // Largest float < INT64_MAX. + __ Fneg(s23, s22); // Smallest float > INT64_MIN. + __ Fmov(d24, 1.1); + __ Fmov(d25, 1.5); + __ Fmov(d26, -1.5); + __ Fmov(d27, kFP64PositiveInfinity); + __ Fmov(d28, kFP64NegativeInfinity); + __ Fmov(d29, 0x7ffffffffffffc00UL); // Largest double < INT64_MAX. + __ Fneg(d30, d29); // Smallest double > INT64_MIN. + + __ Fcvtmu(w0, s0); + __ Fcvtmu(w1, s1); + __ Fcvtmu(w2, s2); + __ Fcvtmu(w3, s3); + __ Fcvtmu(w4, s4); + __ Fcvtmu(w5, s5); + __ Fcvtmu(w6, s6); + __ Fcvtmu(w7, s7); + __ Fcvtmu(w8, d8); + __ Fcvtmu(w9, d9); + __ Fcvtmu(w10, d10); + __ Fcvtmu(w11, d11); + __ Fcvtmu(w12, d12); + __ Fcvtmu(w13, d13); + __ Fcvtmu(w14, d14); + __ Fcvtmu(x17, s17); + __ Fcvtmu(x18, s18); + __ Fcvtmu(x19, s19); + __ Fcvtmu(x20, s20); + __ Fcvtmu(x21, s21); + __ Fcvtmu(x22, s22); + __ Fcvtmu(x23, s23); + __ Fcvtmu(x24, d24); + __ Fcvtmu(x25, d25); + __ Fcvtmu(x26, d26); + __ Fcvtmu(x27, d27); + __ Fcvtmu(x28, d28); + __ Fcvtmu(x29, d29); + __ Fcvtmu(x30, d30); + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + ASSERT_EQUAL_64(1, x1); + ASSERT_EQUAL_64(1, x2); + ASSERT_EQUAL_64(0, x3); + ASSERT_EQUAL_64(0xffffffff, x4); + ASSERT_EQUAL_64(0, x5); + ASSERT_EQUAL_64(0x7fffff80, x6); + ASSERT_EQUAL_64(0, x7); + ASSERT_EQUAL_64(1, x8); + ASSERT_EQUAL_64(1, x9); + ASSERT_EQUAL_64(1, x10); + ASSERT_EQUAL_64(0, x11); + ASSERT_EQUAL_64(0xffffffff, x12); + ASSERT_EQUAL_64(0, x13); + ASSERT_EQUAL_64(0x7ffffffe, x14); + ASSERT_EQUAL_64(1, x17); + ASSERT_EQUAL_64(1, x18); + ASSERT_EQUAL_64(0x0UL, x19); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x20); + ASSERT_EQUAL_64(0x0UL, x21); + ASSERT_EQUAL_64(0x7fffff8000000000UL, x22); + ASSERT_EQUAL_64(0x0UL, x23); + ASSERT_EQUAL_64(1, x24); + ASSERT_EQUAL_64(1, x25); + ASSERT_EQUAL_64(0x0UL, x26); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x27); + ASSERT_EQUAL_64(0x0UL, x28); + ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29); + ASSERT_EQUAL_64(0x0UL, x30); + + TEARDOWN(); +} + + +TEST(fcvtns) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s0, 1.0); + __ Fmov(s1, 1.1); + __ Fmov(s2, 1.5); + __ Fmov(s3, -1.5); + __ Fmov(s4, kFP32PositiveInfinity); + __ Fmov(s5, kFP32NegativeInfinity); + __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX. + __ Fneg(s7, s6); // Smallest float > INT32_MIN. + __ Fmov(d8, 1.0); + __ Fmov(d9, 1.1); + __ Fmov(d10, 1.5); + __ Fmov(d11, -1.5); + __ Fmov(d12, kFP64PositiveInfinity); + __ Fmov(d13, kFP64NegativeInfinity); + __ Fmov(d14, kWMaxInt - 1); + __ Fmov(d15, kWMinInt + 1); + __ Fmov(s17, 1.1); + __ Fmov(s18, 1.5); + __ Fmov(s19, -1.5); + __ Fmov(s20, kFP32PositiveInfinity); + __ Fmov(s21, kFP32NegativeInfinity); + __ Fmov(s22, 0x7fffff8000000000UL); // Largest float < INT64_MAX. + __ Fneg(s23, s22); // Smallest float > INT64_MIN. + __ Fmov(d24, 1.1); + __ Fmov(d25, 1.5); + __ Fmov(d26, -1.5); + __ Fmov(d27, kFP64PositiveInfinity); + __ Fmov(d28, kFP64NegativeInfinity); + __ Fmov(d29, 0x7ffffffffffffc00UL); // Largest double < INT64_MAX. + __ Fneg(d30, d29); // Smallest double > INT64_MIN. + + __ Fcvtns(w0, s0); + __ Fcvtns(w1, s1); + __ Fcvtns(w2, s2); + __ Fcvtns(w3, s3); + __ Fcvtns(w4, s4); + __ Fcvtns(w5, s5); + __ Fcvtns(w6, s6); + __ Fcvtns(w7, s7); + __ Fcvtns(w8, d8); + __ Fcvtns(w9, d9); + __ Fcvtns(w10, d10); + __ Fcvtns(w11, d11); + __ Fcvtns(w12, d12); + __ Fcvtns(w13, d13); + __ Fcvtns(w14, d14); + __ Fcvtns(w15, d15); + __ Fcvtns(x17, s17); + __ Fcvtns(x18, s18); + __ Fcvtns(x19, s19); + __ Fcvtns(x20, s20); + __ Fcvtns(x21, s21); + __ Fcvtns(x22, s22); + __ Fcvtns(x23, s23); + __ Fcvtns(x24, d24); + __ Fcvtns(x25, d25); + __ Fcvtns(x26, d26); + __ Fcvtns(x27, d27); +// __ Fcvtns(x28, d28); + __ Fcvtns(x29, d29); + __ Fcvtns(x30, d30); + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + ASSERT_EQUAL_64(1, x1); + ASSERT_EQUAL_64(2, x2); + ASSERT_EQUAL_64(0xfffffffe, x3); + ASSERT_EQUAL_64(0x7fffffff, x4); + ASSERT_EQUAL_64(0x80000000, x5); + ASSERT_EQUAL_64(0x7fffff80, x6); + ASSERT_EQUAL_64(0x80000080, x7); + ASSERT_EQUAL_64(1, x8); + ASSERT_EQUAL_64(1, x9); + ASSERT_EQUAL_64(2, x10); + ASSERT_EQUAL_64(0xfffffffe, x11); + ASSERT_EQUAL_64(0x7fffffff, x12); + ASSERT_EQUAL_64(0x80000000, x13); + ASSERT_EQUAL_64(0x7ffffffe, x14); + ASSERT_EQUAL_64(0x80000001, x15); + ASSERT_EQUAL_64(1, x17); + ASSERT_EQUAL_64(2, x18); + ASSERT_EQUAL_64(0xfffffffffffffffeUL, x19); + ASSERT_EQUAL_64(0x7fffffffffffffffUL, x20); + ASSERT_EQUAL_64(0x8000000000000000UL, x21); + ASSERT_EQUAL_64(0x7fffff8000000000UL, x22); + ASSERT_EQUAL_64(0x8000008000000000UL, x23); + ASSERT_EQUAL_64(1, x24); + ASSERT_EQUAL_64(2, x25); + ASSERT_EQUAL_64(0xfffffffffffffffeUL, x26); + ASSERT_EQUAL_64(0x7fffffffffffffffUL, x27); +// ASSERT_EQUAL_64(0x8000000000000000UL, x28); + ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29); + ASSERT_EQUAL_64(0x8000000000000400UL, x30); + + TEARDOWN(); +} + + +TEST(fcvtnu) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s0, 1.0); + __ Fmov(s1, 1.1); + __ Fmov(s2, 1.5); + __ Fmov(s3, -1.5); + __ Fmov(s4, kFP32PositiveInfinity); + __ Fmov(s5, kFP32NegativeInfinity); + __ Fmov(s6, 0xffffff00); // Largest float < UINT32_MAX. + __ Fmov(d8, 1.0); + __ Fmov(d9, 1.1); + __ Fmov(d10, 1.5); + __ Fmov(d11, -1.5); + __ Fmov(d12, kFP64PositiveInfinity); + __ Fmov(d13, kFP64NegativeInfinity); + __ Fmov(d14, 0xfffffffe); + __ Fmov(s16, 1.0); + __ Fmov(s17, 1.1); + __ Fmov(s18, 1.5); + __ Fmov(s19, -1.5); + __ Fmov(s20, kFP32PositiveInfinity); + __ Fmov(s21, kFP32NegativeInfinity); + __ Fmov(s22, 0xffffff0000000000UL); // Largest float < UINT64_MAX. + __ Fmov(d24, 1.1); + __ Fmov(d25, 1.5); + __ Fmov(d26, -1.5); + __ Fmov(d27, kFP64PositiveInfinity); + __ Fmov(d28, kFP64NegativeInfinity); + __ Fmov(d29, 0xfffffffffffff800UL); // Largest double < UINT64_MAX. + __ Fmov(s30, 0x100000000UL); + + __ Fcvtnu(w0, s0); + __ Fcvtnu(w1, s1); + __ Fcvtnu(w2, s2); + __ Fcvtnu(w3, s3); + __ Fcvtnu(w4, s4); + __ Fcvtnu(w5, s5); + __ Fcvtnu(w6, s6); + __ Fcvtnu(w8, d8); + __ Fcvtnu(w9, d9); + __ Fcvtnu(w10, d10); + __ Fcvtnu(w11, d11); + __ Fcvtnu(w12, d12); + __ Fcvtnu(w13, d13); + __ Fcvtnu(w14, d14); + __ Fcvtnu(w15, d15); + __ Fcvtnu(x16, s16); + __ Fcvtnu(x17, s17); + __ Fcvtnu(x18, s18); + __ Fcvtnu(x19, s19); + __ Fcvtnu(x20, s20); + __ Fcvtnu(x21, s21); + __ Fcvtnu(x22, s22); + __ Fcvtnu(x24, d24); + __ Fcvtnu(x25, d25); + __ Fcvtnu(x26, d26); + __ Fcvtnu(x27, d27); +// __ Fcvtnu(x28, d28); + __ Fcvtnu(x29, d29); + __ Fcvtnu(w30, s30); + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + ASSERT_EQUAL_64(1, x1); + ASSERT_EQUAL_64(2, x2); + ASSERT_EQUAL_64(0, x3); + ASSERT_EQUAL_64(0xffffffff, x4); + ASSERT_EQUAL_64(0, x5); + ASSERT_EQUAL_64(0xffffff00, x6); + ASSERT_EQUAL_64(1, x8); + ASSERT_EQUAL_64(1, x9); + ASSERT_EQUAL_64(2, x10); + ASSERT_EQUAL_64(0, x11); + ASSERT_EQUAL_64(0xffffffff, x12); + ASSERT_EQUAL_64(0, x13); + ASSERT_EQUAL_64(0xfffffffe, x14); + ASSERT_EQUAL_64(1, x16); + ASSERT_EQUAL_64(1, x17); + ASSERT_EQUAL_64(2, x18); + ASSERT_EQUAL_64(0, x19); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x20); + ASSERT_EQUAL_64(0, x21); + ASSERT_EQUAL_64(0xffffff0000000000UL, x22); + ASSERT_EQUAL_64(1, x24); + ASSERT_EQUAL_64(2, x25); + ASSERT_EQUAL_64(0, x26); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x27); +// ASSERT_EQUAL_64(0, x28); + ASSERT_EQUAL_64(0xfffffffffffff800UL, x29); + ASSERT_EQUAL_64(0xffffffff, x30); + + TEARDOWN(); +} + + +TEST(fcvtzs) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s0, 1.0); + __ Fmov(s1, 1.1); + __ Fmov(s2, 1.5); + __ Fmov(s3, -1.5); + __ Fmov(s4, kFP32PositiveInfinity); + __ Fmov(s5, kFP32NegativeInfinity); + __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX. + __ Fneg(s7, s6); // Smallest float > INT32_MIN. + __ Fmov(d8, 1.0); + __ Fmov(d9, 1.1); + __ Fmov(d10, 1.5); + __ Fmov(d11, -1.5); + __ Fmov(d12, kFP64PositiveInfinity); + __ Fmov(d13, kFP64NegativeInfinity); + __ Fmov(d14, kWMaxInt - 1); + __ Fmov(d15, kWMinInt + 1); + __ Fmov(s17, 1.1); + __ Fmov(s18, 1.5); + __ Fmov(s19, -1.5); + __ Fmov(s20, kFP32PositiveInfinity); + __ Fmov(s21, kFP32NegativeInfinity); + __ Fmov(s22, 0x7fffff8000000000UL); // Largest float < INT64_MAX. + __ Fneg(s23, s22); // Smallest float > INT64_MIN. + __ Fmov(d24, 1.1); + __ Fmov(d25, 1.5); + __ Fmov(d26, -1.5); + __ Fmov(d27, kFP64PositiveInfinity); + __ Fmov(d28, kFP64NegativeInfinity); + __ Fmov(d29, 0x7ffffffffffffc00UL); // Largest double < INT64_MAX. + __ Fneg(d30, d29); // Smallest double > INT64_MIN. + + __ Fcvtzs(w0, s0); + __ Fcvtzs(w1, s1); + __ Fcvtzs(w2, s2); + __ Fcvtzs(w3, s3); + __ Fcvtzs(w4, s4); + __ Fcvtzs(w5, s5); + __ Fcvtzs(w6, s6); + __ Fcvtzs(w7, s7); + __ Fcvtzs(w8, d8); + __ Fcvtzs(w9, d9); + __ Fcvtzs(w10, d10); + __ Fcvtzs(w11, d11); + __ Fcvtzs(w12, d12); + __ Fcvtzs(w13, d13); + __ Fcvtzs(w14, d14); + __ Fcvtzs(w15, d15); + __ Fcvtzs(x17, s17); + __ Fcvtzs(x18, s18); + __ Fcvtzs(x19, s19); + __ Fcvtzs(x20, s20); + __ Fcvtzs(x21, s21); + __ Fcvtzs(x22, s22); + __ Fcvtzs(x23, s23); + __ Fcvtzs(x24, d24); + __ Fcvtzs(x25, d25); + __ Fcvtzs(x26, d26); + __ Fcvtzs(x27, d27); + __ Fcvtzs(x28, d28); + __ Fcvtzs(x29, d29); + __ Fcvtzs(x30, d30); + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + ASSERT_EQUAL_64(1, x1); + ASSERT_EQUAL_64(1, x2); + ASSERT_EQUAL_64(0xffffffff, x3); + ASSERT_EQUAL_64(0x7fffffff, x4); + ASSERT_EQUAL_64(0x80000000, x5); + ASSERT_EQUAL_64(0x7fffff80, x6); + ASSERT_EQUAL_64(0x80000080, x7); + ASSERT_EQUAL_64(1, x8); + ASSERT_EQUAL_64(1, x9); + ASSERT_EQUAL_64(1, x10); + ASSERT_EQUAL_64(0xffffffff, x11); + ASSERT_EQUAL_64(0x7fffffff, x12); + ASSERT_EQUAL_64(0x80000000, x13); + ASSERT_EQUAL_64(0x7ffffffe, x14); + ASSERT_EQUAL_64(0x80000001, x15); + ASSERT_EQUAL_64(1, x17); + ASSERT_EQUAL_64(1, x18); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x19); + ASSERT_EQUAL_64(0x7fffffffffffffffUL, x20); + ASSERT_EQUAL_64(0x8000000000000000UL, x21); + ASSERT_EQUAL_64(0x7fffff8000000000UL, x22); + ASSERT_EQUAL_64(0x8000008000000000UL, x23); + ASSERT_EQUAL_64(1, x24); + ASSERT_EQUAL_64(1, x25); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x26); + ASSERT_EQUAL_64(0x7fffffffffffffffUL, x27); + ASSERT_EQUAL_64(0x8000000000000000UL, x28); + ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29); + ASSERT_EQUAL_64(0x8000000000000400UL, x30); + + TEARDOWN(); +} + + +TEST(fcvtzu) { + INIT_V8(); + SETUP(); + + START(); + __ Fmov(s0, 1.0); + __ Fmov(s1, 1.1); + __ Fmov(s2, 1.5); + __ Fmov(s3, -1.5); + __ Fmov(s4, kFP32PositiveInfinity); + __ Fmov(s5, kFP32NegativeInfinity); + __ Fmov(s6, 0x7fffff80); // Largest float < INT32_MAX. + __ Fneg(s7, s6); // Smallest float > INT32_MIN. + __ Fmov(d8, 1.0); + __ Fmov(d9, 1.1); + __ Fmov(d10, 1.5); + __ Fmov(d11, -1.5); + __ Fmov(d12, kFP64PositiveInfinity); + __ Fmov(d13, kFP64NegativeInfinity); + __ Fmov(d14, kWMaxInt - 1); + __ Fmov(d15, kWMinInt + 1); + __ Fmov(s17, 1.1); + __ Fmov(s18, 1.5); + __ Fmov(s19, -1.5); + __ Fmov(s20, kFP32PositiveInfinity); + __ Fmov(s21, kFP32NegativeInfinity); + __ Fmov(s22, 0x7fffff8000000000UL); // Largest float < INT64_MAX. + __ Fneg(s23, s22); // Smallest float > INT64_MIN. + __ Fmov(d24, 1.1); + __ Fmov(d25, 1.5); + __ Fmov(d26, -1.5); + __ Fmov(d27, kFP64PositiveInfinity); + __ Fmov(d28, kFP64NegativeInfinity); + __ Fmov(d29, 0x7ffffffffffffc00UL); // Largest double < INT64_MAX. + __ Fneg(d30, d29); // Smallest double > INT64_MIN. + + __ Fcvtzu(w0, s0); + __ Fcvtzu(w1, s1); + __ Fcvtzu(w2, s2); + __ Fcvtzu(w3, s3); + __ Fcvtzu(w4, s4); + __ Fcvtzu(w5, s5); + __ Fcvtzu(w6, s6); + __ Fcvtzu(w7, s7); + __ Fcvtzu(w8, d8); + __ Fcvtzu(w9, d9); + __ Fcvtzu(w10, d10); + __ Fcvtzu(w11, d11); + __ Fcvtzu(w12, d12); + __ Fcvtzu(w13, d13); + __ Fcvtzu(w14, d14); + __ Fcvtzu(x17, s17); + __ Fcvtzu(x18, s18); + __ Fcvtzu(x19, s19); + __ Fcvtzu(x20, s20); + __ Fcvtzu(x21, s21); + __ Fcvtzu(x22, s22); + __ Fcvtzu(x23, s23); + __ Fcvtzu(x24, d24); + __ Fcvtzu(x25, d25); + __ Fcvtzu(x26, d26); + __ Fcvtzu(x27, d27); + __ Fcvtzu(x28, d28); + __ Fcvtzu(x29, d29); + __ Fcvtzu(x30, d30); + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + ASSERT_EQUAL_64(1, x1); + ASSERT_EQUAL_64(1, x2); + ASSERT_EQUAL_64(0, x3); + ASSERT_EQUAL_64(0xffffffff, x4); + ASSERT_EQUAL_64(0, x5); + ASSERT_EQUAL_64(0x7fffff80, x6); + ASSERT_EQUAL_64(0, x7); + ASSERT_EQUAL_64(1, x8); + ASSERT_EQUAL_64(1, x9); + ASSERT_EQUAL_64(1, x10); + ASSERT_EQUAL_64(0, x11); + ASSERT_EQUAL_64(0xffffffff, x12); + ASSERT_EQUAL_64(0, x13); + ASSERT_EQUAL_64(0x7ffffffe, x14); + ASSERT_EQUAL_64(1, x17); + ASSERT_EQUAL_64(1, x18); + ASSERT_EQUAL_64(0x0UL, x19); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x20); + ASSERT_EQUAL_64(0x0UL, x21); + ASSERT_EQUAL_64(0x7fffff8000000000UL, x22); + ASSERT_EQUAL_64(0x0UL, x23); + ASSERT_EQUAL_64(1, x24); + ASSERT_EQUAL_64(1, x25); + ASSERT_EQUAL_64(0x0UL, x26); + ASSERT_EQUAL_64(0xffffffffffffffffUL, x27); + ASSERT_EQUAL_64(0x0UL, x28); + ASSERT_EQUAL_64(0x7ffffffffffffc00UL, x29); + ASSERT_EQUAL_64(0x0UL, x30); + + TEARDOWN(); +} + + +// Test that scvtf and ucvtf can convert the 64-bit input into the expected +// value. All possible values of 'fbits' are tested. The expected value is +// modified accordingly in each case. +// +// The expected value is specified as the bit encoding of the expected double +// produced by scvtf (expected_scvtf_bits) as well as ucvtf +// (expected_ucvtf_bits). +// +// Where the input value is representable by int32_t or uint32_t, conversions +// from W registers will also be tested. +static void TestUScvtfHelper(uint64_t in, + uint64_t expected_scvtf_bits, + uint64_t expected_ucvtf_bits) { + uint64_t u64 = in; + uint32_t u32 = u64 & 0xffffffff; + int64_t s64 = static_cast<int64_t>(in); + int32_t s32 = s64 & 0x7fffffff; + + bool cvtf_s32 = (s64 == s32); + bool cvtf_u32 = (u64 == u32); + + double results_scvtf_x[65]; + double results_ucvtf_x[65]; + double results_scvtf_w[33]; + double results_ucvtf_w[33]; + + SETUP(); + START(); + + __ Mov(x0, reinterpret_cast<int64_t>(results_scvtf_x)); + __ Mov(x1, reinterpret_cast<int64_t>(results_ucvtf_x)); + __ Mov(x2, reinterpret_cast<int64_t>(results_scvtf_w)); + __ Mov(x3, reinterpret_cast<int64_t>(results_ucvtf_w)); + + __ Mov(x10, s64); + + // Corrupt the top word, in case it is accidentally used during W-register + // conversions. + __ Mov(x11, 0x5555555555555555); + __ Bfi(x11, x10, 0, kWRegSize); + + // Test integer conversions. + __ Scvtf(d0, x10); + __ Ucvtf(d1, x10); + __ Scvtf(d2, w11); + __ Ucvtf(d3, w11); + __ Str(d0, MemOperand(x0)); + __ Str(d1, MemOperand(x1)); + __ Str(d2, MemOperand(x2)); + __ Str(d3, MemOperand(x3)); + + // Test all possible values of fbits. + for (int fbits = 1; fbits <= 32; fbits++) { + __ Scvtf(d0, x10, fbits); + __ Ucvtf(d1, x10, fbits); + __ Scvtf(d2, w11, fbits); + __ Ucvtf(d3, w11, fbits); + __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes)); + __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes)); + __ Str(d2, MemOperand(x2, fbits * kDRegSizeInBytes)); + __ Str(d3, MemOperand(x3, fbits * kDRegSizeInBytes)); + } + + // Conversions from W registers can only handle fbits values <= 32, so just + // test conversions from X registers for 32 < fbits <= 64. + for (int fbits = 33; fbits <= 64; fbits++) { + __ Scvtf(d0, x10, fbits); + __ Ucvtf(d1, x10, fbits); + __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes)); + __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes)); + } + + END(); + RUN(); + + // Check the results. + double expected_scvtf_base = rawbits_to_double(expected_scvtf_bits); + double expected_ucvtf_base = rawbits_to_double(expected_ucvtf_bits); + + for (int fbits = 0; fbits <= 32; fbits++) { + double expected_scvtf = expected_scvtf_base / pow(2.0, fbits); + double expected_ucvtf = expected_ucvtf_base / pow(2.0, fbits); + ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]); + ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]); + if (cvtf_s32) ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_w[fbits]); + if (cvtf_u32) ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_w[fbits]); + } + for (int fbits = 33; fbits <= 64; fbits++) { + double expected_scvtf = expected_scvtf_base / pow(2.0, fbits); + double expected_ucvtf = expected_ucvtf_base / pow(2.0, fbits); + ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]); + ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]); + } + + TEARDOWN(); +} + + +TEST(scvtf_ucvtf_double) { + INIT_V8(); + // Simple conversions of positive numbers which require no rounding; the + // results should not depened on the rounding mode, and ucvtf and scvtf should + // produce the same result. + TestUScvtfHelper(0x0000000000000000, 0x0000000000000000, 0x0000000000000000); + TestUScvtfHelper(0x0000000000000001, 0x3ff0000000000000, 0x3ff0000000000000); + TestUScvtfHelper(0x0000000040000000, 0x41d0000000000000, 0x41d0000000000000); + TestUScvtfHelper(0x0000000100000000, 0x41f0000000000000, 0x41f0000000000000); + TestUScvtfHelper(0x4000000000000000, 0x43d0000000000000, 0x43d0000000000000); + // Test mantissa extremities. + TestUScvtfHelper(0x4000000000000400, 0x43d0000000000001, 0x43d0000000000001); + // The largest int32_t that fits in a double. + TestUScvtfHelper(0x000000007fffffff, 0x41dfffffffc00000, 0x41dfffffffc00000); + // Values that would be negative if treated as an int32_t. + TestUScvtfHelper(0x00000000ffffffff, 0x41efffffffe00000, 0x41efffffffe00000); + TestUScvtfHelper(0x0000000080000000, 0x41e0000000000000, 0x41e0000000000000); + TestUScvtfHelper(0x0000000080000001, 0x41e0000000200000, 0x41e0000000200000); + // The largest int64_t that fits in a double. + TestUScvtfHelper(0x7ffffffffffffc00, 0x43dfffffffffffff, 0x43dfffffffffffff); + // Check for bit pattern reproduction. + TestUScvtfHelper(0x0123456789abcde0, 0x43723456789abcde, 0x43723456789abcde); + TestUScvtfHelper(0x0000000012345678, 0x41b2345678000000, 0x41b2345678000000); + + // Simple conversions of negative int64_t values. These require no rounding, + // and the results should not depend on the rounding mode. + TestUScvtfHelper(0xffffffffc0000000, 0xc1d0000000000000, 0x43effffffff80000); + TestUScvtfHelper(0xffffffff00000000, 0xc1f0000000000000, 0x43efffffffe00000); + TestUScvtfHelper(0xc000000000000000, 0xc3d0000000000000, 0x43e8000000000000); + + // Conversions which require rounding. + TestUScvtfHelper(0x1000000000000000, 0x43b0000000000000, 0x43b0000000000000); + TestUScvtfHelper(0x1000000000000001, 0x43b0000000000000, 0x43b0000000000000); + TestUScvtfHelper(0x1000000000000080, 0x43b0000000000000, 0x43b0000000000000); + TestUScvtfHelper(0x1000000000000081, 0x43b0000000000001, 0x43b0000000000001); + TestUScvtfHelper(0x1000000000000100, 0x43b0000000000001, 0x43b0000000000001); + TestUScvtfHelper(0x1000000000000101, 0x43b0000000000001, 0x43b0000000000001); + TestUScvtfHelper(0x1000000000000180, 0x43b0000000000002, 0x43b0000000000002); + TestUScvtfHelper(0x1000000000000181, 0x43b0000000000002, 0x43b0000000000002); + TestUScvtfHelper(0x1000000000000200, 0x43b0000000000002, 0x43b0000000000002); + TestUScvtfHelper(0x1000000000000201, 0x43b0000000000002, 0x43b0000000000002); + TestUScvtfHelper(0x1000000000000280, 0x43b0000000000002, 0x43b0000000000002); + TestUScvtfHelper(0x1000000000000281, 0x43b0000000000003, 0x43b0000000000003); + TestUScvtfHelper(0x1000000000000300, 0x43b0000000000003, 0x43b0000000000003); + // Check rounding of negative int64_t values (and large uint64_t values). + TestUScvtfHelper(0x8000000000000000, 0xc3e0000000000000, 0x43e0000000000000); + TestUScvtfHelper(0x8000000000000001, 0xc3e0000000000000, 0x43e0000000000000); + TestUScvtfHelper(0x8000000000000200, 0xc3e0000000000000, 0x43e0000000000000); + TestUScvtfHelper(0x8000000000000201, 0xc3dfffffffffffff, 0x43e0000000000000); + TestUScvtfHelper(0x8000000000000400, 0xc3dfffffffffffff, 0x43e0000000000000); + TestUScvtfHelper(0x8000000000000401, 0xc3dfffffffffffff, 0x43e0000000000001); + TestUScvtfHelper(0x8000000000000600, 0xc3dffffffffffffe, 0x43e0000000000001); + TestUScvtfHelper(0x8000000000000601, 0xc3dffffffffffffe, 0x43e0000000000001); + TestUScvtfHelper(0x8000000000000800, 0xc3dffffffffffffe, 0x43e0000000000001); + TestUScvtfHelper(0x8000000000000801, 0xc3dffffffffffffe, 0x43e0000000000001); + TestUScvtfHelper(0x8000000000000a00, 0xc3dffffffffffffe, 0x43e0000000000001); + TestUScvtfHelper(0x8000000000000a01, 0xc3dffffffffffffd, 0x43e0000000000001); + TestUScvtfHelper(0x8000000000000c00, 0xc3dffffffffffffd, 0x43e0000000000002); + // Round up to produce a result that's too big for the input to represent. + TestUScvtfHelper(0x7ffffffffffffe00, 0x43e0000000000000, 0x43e0000000000000); + TestUScvtfHelper(0x7fffffffffffffff, 0x43e0000000000000, 0x43e0000000000000); + TestUScvtfHelper(0xfffffffffffffc00, 0xc090000000000000, 0x43f0000000000000); + TestUScvtfHelper(0xffffffffffffffff, 0xbff0000000000000, 0x43f0000000000000); +} + + +// The same as TestUScvtfHelper, but convert to floats. +static void TestUScvtf32Helper(uint64_t in, + uint32_t expected_scvtf_bits, + uint32_t expected_ucvtf_bits) { + uint64_t u64 = in; + uint32_t u32 = u64 & 0xffffffff; + int64_t s64 = static_cast<int64_t>(in); + int32_t s32 = s64 & 0x7fffffff; + + bool cvtf_s32 = (s64 == s32); + bool cvtf_u32 = (u64 == u32); + + float results_scvtf_x[65]; + float results_ucvtf_x[65]; + float results_scvtf_w[33]; + float results_ucvtf_w[33]; + + SETUP(); + START(); + + __ Mov(x0, reinterpret_cast<int64_t>(results_scvtf_x)); + __ Mov(x1, reinterpret_cast<int64_t>(results_ucvtf_x)); + __ Mov(x2, reinterpret_cast<int64_t>(results_scvtf_w)); + __ Mov(x3, reinterpret_cast<int64_t>(results_ucvtf_w)); + + __ Mov(x10, s64); + + // Corrupt the top word, in case it is accidentally used during W-register + // conversions. + __ Mov(x11, 0x5555555555555555); + __ Bfi(x11, x10, 0, kWRegSize); + + // Test integer conversions. + __ Scvtf(s0, x10); + __ Ucvtf(s1, x10); + __ Scvtf(s2, w11); + __ Ucvtf(s3, w11); + __ Str(s0, MemOperand(x0)); + __ Str(s1, MemOperand(x1)); + __ Str(s2, MemOperand(x2)); + __ Str(s3, MemOperand(x3)); + + // Test all possible values of fbits. + for (int fbits = 1; fbits <= 32; fbits++) { + __ Scvtf(s0, x10, fbits); + __ Ucvtf(s1, x10, fbits); + __ Scvtf(s2, w11, fbits); + __ Ucvtf(s3, w11, fbits); + __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes)); + __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes)); + __ Str(s2, MemOperand(x2, fbits * kSRegSizeInBytes)); + __ Str(s3, MemOperand(x3, fbits * kSRegSizeInBytes)); + } + + // Conversions from W registers can only handle fbits values <= 32, so just + // test conversions from X registers for 32 < fbits <= 64. + for (int fbits = 33; fbits <= 64; fbits++) { + __ Scvtf(s0, x10, fbits); + __ Ucvtf(s1, x10, fbits); + __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes)); + __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes)); + } + + END(); + RUN(); + + // Check the results. + float expected_scvtf_base = rawbits_to_float(expected_scvtf_bits); + float expected_ucvtf_base = rawbits_to_float(expected_ucvtf_bits); + + for (int fbits = 0; fbits <= 32; fbits++) { + float expected_scvtf = expected_scvtf_base / powf(2, fbits); + float expected_ucvtf = expected_ucvtf_base / powf(2, fbits); + ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]); + ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]); + if (cvtf_s32) ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_w[fbits]); + if (cvtf_u32) ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_w[fbits]); + break; + } + for (int fbits = 33; fbits <= 64; fbits++) { + break; + float expected_scvtf = expected_scvtf_base / powf(2, fbits); + float expected_ucvtf = expected_ucvtf_base / powf(2, fbits); + ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]); + ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]); + } + + TEARDOWN(); +} + + +TEST(scvtf_ucvtf_float) { + INIT_V8(); + // Simple conversions of positive numbers which require no rounding; the + // results should not depened on the rounding mode, and ucvtf and scvtf should + // produce the same result. + TestUScvtf32Helper(0x0000000000000000, 0x00000000, 0x00000000); + TestUScvtf32Helper(0x0000000000000001, 0x3f800000, 0x3f800000); + TestUScvtf32Helper(0x0000000040000000, 0x4e800000, 0x4e800000); + TestUScvtf32Helper(0x0000000100000000, 0x4f800000, 0x4f800000); + TestUScvtf32Helper(0x4000000000000000, 0x5e800000, 0x5e800000); + // Test mantissa extremities. + TestUScvtf32Helper(0x0000000000800001, 0x4b000001, 0x4b000001); + TestUScvtf32Helper(0x4000008000000000, 0x5e800001, 0x5e800001); + // The largest int32_t that fits in a float. + TestUScvtf32Helper(0x000000007fffff80, 0x4effffff, 0x4effffff); + // Values that would be negative if treated as an int32_t. + TestUScvtf32Helper(0x00000000ffffff00, 0x4f7fffff, 0x4f7fffff); + TestUScvtf32Helper(0x0000000080000000, 0x4f000000, 0x4f000000); + TestUScvtf32Helper(0x0000000080000100, 0x4f000001, 0x4f000001); + // The largest int64_t that fits in a float. + TestUScvtf32Helper(0x7fffff8000000000, 0x5effffff, 0x5effffff); + // Check for bit pattern reproduction. + TestUScvtf32Helper(0x0000000000876543, 0x4b076543, 0x4b076543); + + // Simple conversions of negative int64_t values. These require no rounding, + // and the results should not depend on the rounding mode. + TestUScvtf32Helper(0xfffffc0000000000, 0xd4800000, 0x5f7ffffc); + TestUScvtf32Helper(0xc000000000000000, 0xde800000, 0x5f400000); + + // Conversions which require rounding. + TestUScvtf32Helper(0x0000800000000000, 0x57000000, 0x57000000); + TestUScvtf32Helper(0x0000800000000001, 0x57000000, 0x57000000); + TestUScvtf32Helper(0x0000800000800000, 0x57000000, 0x57000000); + TestUScvtf32Helper(0x0000800000800001, 0x57000001, 0x57000001); + TestUScvtf32Helper(0x0000800001000000, 0x57000001, 0x57000001); + TestUScvtf32Helper(0x0000800001000001, 0x57000001, 0x57000001); + TestUScvtf32Helper(0x0000800001800000, 0x57000002, 0x57000002); + TestUScvtf32Helper(0x0000800001800001, 0x57000002, 0x57000002); + TestUScvtf32Helper(0x0000800002000000, 0x57000002, 0x57000002); + TestUScvtf32Helper(0x0000800002000001, 0x57000002, 0x57000002); + TestUScvtf32Helper(0x0000800002800000, 0x57000002, 0x57000002); + TestUScvtf32Helper(0x0000800002800001, 0x57000003, 0x57000003); + TestUScvtf32Helper(0x0000800003000000, 0x57000003, 0x57000003); + // Check rounding of negative int64_t values (and large uint64_t values). + TestUScvtf32Helper(0x8000000000000000, 0xdf000000, 0x5f000000); + TestUScvtf32Helper(0x8000000000000001, 0xdf000000, 0x5f000000); + TestUScvtf32Helper(0x8000004000000000, 0xdf000000, 0x5f000000); + TestUScvtf32Helper(0x8000004000000001, 0xdeffffff, 0x5f000000); + TestUScvtf32Helper(0x8000008000000000, 0xdeffffff, 0x5f000000); + TestUScvtf32Helper(0x8000008000000001, 0xdeffffff, 0x5f000001); + TestUScvtf32Helper(0x800000c000000000, 0xdefffffe, 0x5f000001); + TestUScvtf32Helper(0x800000c000000001, 0xdefffffe, 0x5f000001); + TestUScvtf32Helper(0x8000010000000000, 0xdefffffe, 0x5f000001); + TestUScvtf32Helper(0x8000010000000001, 0xdefffffe, 0x5f000001); + TestUScvtf32Helper(0x8000014000000000, 0xdefffffe, 0x5f000001); + TestUScvtf32Helper(0x8000014000000001, 0xdefffffd, 0x5f000001); + TestUScvtf32Helper(0x8000018000000000, 0xdefffffd, 0x5f000002); + // Round up to produce a result that's too big for the input to represent. + TestUScvtf32Helper(0x000000007fffffc0, 0x4f000000, 0x4f000000); + TestUScvtf32Helper(0x000000007fffffff, 0x4f000000, 0x4f000000); + TestUScvtf32Helper(0x00000000ffffff80, 0x4f800000, 0x4f800000); + TestUScvtf32Helper(0x00000000ffffffff, 0x4f800000, 0x4f800000); + TestUScvtf32Helper(0x7fffffc000000000, 0x5f000000, 0x5f000000); + TestUScvtf32Helper(0x7fffffffffffffff, 0x5f000000, 0x5f000000); + TestUScvtf32Helper(0xffffff8000000000, 0xd3000000, 0x5f800000); + TestUScvtf32Helper(0xffffffffffffffff, 0xbf800000, 0x5f800000); +} + + +TEST(system_mrs) { + INIT_V8(); + SETUP(); + + START(); + __ Mov(w0, 0); + __ Mov(w1, 1); + __ Mov(w2, 0x80000000); + + // Set the Z and C flags. + __ Cmp(w0, w0); + __ Mrs(x3, NZCV); + + // Set the N flag. + __ Cmp(w0, w1); + __ Mrs(x4, NZCV); + + // Set the Z, C and V flags. + __ Adds(w0, w2, w2); + __ Mrs(x5, NZCV); + + // Read the default FPCR. + __ Mrs(x6, FPCR); + END(); + + RUN(); + + // NZCV + ASSERT_EQUAL_32(ZCFlag, w3); + ASSERT_EQUAL_32(NFlag, w4); + ASSERT_EQUAL_32(ZCVFlag, w5); + + // FPCR + // The default FPCR on Linux-based platforms is 0. + ASSERT_EQUAL_32(0, w6); + + TEARDOWN(); +} + + +TEST(system_msr) { + INIT_V8(); + // All FPCR fields that must be implemented: AHP, DN, FZ, RMode + const uint64_t fpcr_core = 0x07c00000; + + // All FPCR fields (including fields which may be read-as-zero): + // Stride, Len + // IDE, IXE, UFE, OFE, DZE, IOE + const uint64_t fpcr_all = fpcr_core | 0x00379f00; + + SETUP(); + + START(); + __ Mov(w0, 0); + __ Mov(w1, 0x7fffffff); + + __ Mov(x7, 0); + + __ Mov(x10, NVFlag); + __ Cmp(w0, w0); // Set Z and C. + __ Msr(NZCV, x10); // Set N and V. + // The Msr should have overwritten every flag set by the Cmp. + __ Cinc(x7, x7, mi); // N + __ Cinc(x7, x7, ne); // !Z + __ Cinc(x7, x7, lo); // !C + __ Cinc(x7, x7, vs); // V + + __ Mov(x10, ZCFlag); + __ Cmn(w1, w1); // Set N and V. + __ Msr(NZCV, x10); // Set Z and C. + // The Msr should have overwritten every flag set by the Cmn. + __ Cinc(x7, x7, pl); // !N + __ Cinc(x7, x7, eq); // Z + __ Cinc(x7, x7, hs); // C + __ Cinc(x7, x7, vc); // !V + + // All core FPCR fields must be writable. + __ Mov(x8, fpcr_core); + __ Msr(FPCR, x8); + __ Mrs(x8, FPCR); + + // All FPCR fields, including optional ones. This part of the test doesn't + // achieve much other than ensuring that supported fields can be cleared by + // the next test. + __ Mov(x9, fpcr_all); + __ Msr(FPCR, x9); + __ Mrs(x9, FPCR); + __ And(x9, x9, fpcr_core); + + // The undefined bits must ignore writes. + // It's conceivable that a future version of the architecture could use these + // fields (making this test fail), but in the meantime this is a useful test + // for the simulator. + __ Mov(x10, ~fpcr_all); + __ Msr(FPCR, x10); + __ Mrs(x10, FPCR); + + END(); + + RUN(); + + // We should have incremented x7 (from 0) exactly 8 times. + ASSERT_EQUAL_64(8, x7); + + ASSERT_EQUAL_64(fpcr_core, x8); + ASSERT_EQUAL_64(fpcr_core, x9); + ASSERT_EQUAL_64(0, x10); + + TEARDOWN(); +} + + +TEST(system_nop) { + INIT_V8(); + SETUP(); + RegisterDump before; + + START(); + before.Dump(&masm); + __ Nop(); + END(); + + RUN(); + + ASSERT_EQUAL_REGISTERS(before); + ASSERT_EQUAL_NZCV(before.flags_nzcv()); + + TEARDOWN(); +} + + +TEST(zero_dest) { + INIT_V8(); + SETUP(); + RegisterDump before; + + START(); + // Preserve the system stack pointer, in case we clobber it. + __ Mov(x30, csp); + // Initialize the other registers used in this test. + uint64_t literal_base = 0x0100001000100101UL; + __ Mov(x0, 0); + __ Mov(x1, literal_base); + for (unsigned i = 2; i < x30.code(); i++) { + __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1); + } + before.Dump(&masm); + + // All of these instructions should be NOPs in these forms, but have + // alternate forms which can write into the stack pointer. + __ add(xzr, x0, x1); + __ add(xzr, x1, xzr); + __ add(xzr, xzr, x1); + + __ and_(xzr, x0, x2); + __ and_(xzr, x2, xzr); + __ and_(xzr, xzr, x2); + + __ bic(xzr, x0, x3); + __ bic(xzr, x3, xzr); + __ bic(xzr, xzr, x3); + + __ eon(xzr, x0, x4); + __ eon(xzr, x4, xzr); + __ eon(xzr, xzr, x4); + + __ eor(xzr, x0, x5); + __ eor(xzr, x5, xzr); + __ eor(xzr, xzr, x5); + + __ orr(xzr, x0, x6); + __ orr(xzr, x6, xzr); + __ orr(xzr, xzr, x6); + + __ sub(xzr, x0, x7); + __ sub(xzr, x7, xzr); + __ sub(xzr, xzr, x7); + + // Swap the saved system stack pointer with the real one. If csp was written + // during the test, it will show up in x30. This is done because the test + // framework assumes that csp will be valid at the end of the test. + __ Mov(x29, x30); + __ Mov(x30, csp); + __ Mov(csp, x29); + // We used x29 as a scratch register, so reset it to make sure it doesn't + // trigger a test failure. + __ Add(x29, x28, x1); + END(); + + RUN(); + + ASSERT_EQUAL_REGISTERS(before); + ASSERT_EQUAL_NZCV(before.flags_nzcv()); + + TEARDOWN(); +} + + +TEST(zero_dest_setflags) { + INIT_V8(); + SETUP(); + RegisterDump before; + + START(); + // Preserve the system stack pointer, in case we clobber it. + __ Mov(x30, csp); + // Initialize the other registers used in this test. + uint64_t literal_base = 0x0100001000100101UL; + __ Mov(x0, 0); + __ Mov(x1, literal_base); + for (int i = 2; i < 30; i++) { + __ Add(Register::XRegFromCode(i), Register::XRegFromCode(i-1), x1); + } + before.Dump(&masm); + + // All of these instructions should only write to the flags in these forms, + // but have alternate forms which can write into the stack pointer. + __ adds(xzr, x0, Operand(x1, UXTX)); + __ adds(xzr, x1, Operand(xzr, UXTX)); + __ adds(xzr, x1, 1234); + __ adds(xzr, x0, x1); + __ adds(xzr, x1, xzr); + __ adds(xzr, xzr, x1); + + __ ands(xzr, x2, ~0xf); + __ ands(xzr, xzr, ~0xf); + __ ands(xzr, x0, x2); + __ ands(xzr, x2, xzr); + __ ands(xzr, xzr, x2); + + __ bics(xzr, x3, ~0xf); + __ bics(xzr, xzr, ~0xf); + __ bics(xzr, x0, x3); + __ bics(xzr, x3, xzr); + __ bics(xzr, xzr, x3); + + __ subs(xzr, x0, Operand(x3, UXTX)); + __ subs(xzr, x3, Operand(xzr, UXTX)); + __ subs(xzr, x3, 1234); + __ subs(xzr, x0, x3); + __ subs(xzr, x3, xzr); + __ subs(xzr, xzr, x3); + + // Swap the saved system stack pointer with the real one. If csp was written + // during the test, it will show up in x30. This is done because the test + // framework assumes that csp will be valid at the end of the test. + __ Mov(x29, x30); + __ Mov(x30, csp); + __ Mov(csp, x29); + // We used x29 as a scratch register, so reset it to make sure it doesn't + // trigger a test failure. + __ Add(x29, x28, x1); + END(); + + RUN(); + + ASSERT_EQUAL_REGISTERS(before); + + TEARDOWN(); +} + + +TEST(register_bit) { + // No code generation takes place in this test, so no need to setup and + // teardown. + + // Simple tests. + CHECK(x0.Bit() == (1UL << 0)); + CHECK(x1.Bit() == (1UL << 1)); + CHECK(x10.Bit() == (1UL << 10)); + + // AAPCS64 definitions. + CHECK(fp.Bit() == (1UL << kFramePointerRegCode)); + CHECK(lr.Bit() == (1UL << kLinkRegCode)); + + // Fixed (hardware) definitions. + CHECK(xzr.Bit() == (1UL << kZeroRegCode)); + + // Internal ABI definitions. + CHECK(jssp.Bit() == (1UL << kJSSPCode)); + CHECK(csp.Bit() == (1UL << kSPRegInternalCode)); + CHECK(csp.Bit() != xzr.Bit()); + + // xn.Bit() == wn.Bit() at all times, for the same n. + CHECK(x0.Bit() == w0.Bit()); + CHECK(x1.Bit() == w1.Bit()); + CHECK(x10.Bit() == w10.Bit()); + CHECK(jssp.Bit() == wjssp.Bit()); + CHECK(xzr.Bit() == wzr.Bit()); + CHECK(csp.Bit() == wcsp.Bit()); +} + + +TEST(stack_pointer_override) { + // This test generates some stack maintenance code, but the test only checks + // the reported state. + INIT_V8(); + SETUP(); + START(); + + // The default stack pointer in V8 is jssp, but for compatibility with W16, + // the test framework sets it to csp before calling the test. + CHECK(csp.Is(__ StackPointer())); + __ SetStackPointer(x0); + CHECK(x0.Is(__ StackPointer())); + __ SetStackPointer(jssp); + CHECK(jssp.Is(__ StackPointer())); + __ SetStackPointer(csp); + CHECK(csp.Is(__ StackPointer())); + + END(); + RUN(); + TEARDOWN(); +} + + +TEST(peek_poke_simple) { + INIT_V8(); + SETUP(); + START(); + + static const RegList x0_to_x3 = x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit(); + static const RegList x10_to_x13 = x10.Bit() | x11.Bit() | + x12.Bit() | x13.Bit(); + + // The literal base is chosen to have two useful properties: + // * When multiplied by small values (such as a register index), this value + // is clearly readable in the result. + // * The value is not formed from repeating fixed-size smaller values, so it + // can be used to detect endianness-related errors. + uint64_t literal_base = 0x0100001000100101UL; + + // Initialize the registers. + __ Mov(x0, literal_base); + __ Add(x1, x0, x0); + __ Add(x2, x1, x0); + __ Add(x3, x2, x0); + + __ Claim(4); + + // Simple exchange. + // After this test: + // x0-x3 should be unchanged. + // w10-w13 should contain the lower words of x0-x3. + __ Poke(x0, 0); + __ Poke(x1, 8); + __ Poke(x2, 16); + __ Poke(x3, 24); + Clobber(&masm, x0_to_x3); + __ Peek(x0, 0); + __ Peek(x1, 8); + __ Peek(x2, 16); + __ Peek(x3, 24); + + __ Poke(w0, 0); + __ Poke(w1, 4); + __ Poke(w2, 8); + __ Poke(w3, 12); + Clobber(&masm, x10_to_x13); + __ Peek(w10, 0); + __ Peek(w11, 4); + __ Peek(w12, 8); + __ Peek(w13, 12); + + __ Drop(4); + + END(); + RUN(); + + ASSERT_EQUAL_64(literal_base * 1, x0); + ASSERT_EQUAL_64(literal_base * 2, x1); + ASSERT_EQUAL_64(literal_base * 3, x2); + ASSERT_EQUAL_64(literal_base * 4, x3); + + ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10); + ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11); + ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12); + ASSERT_EQUAL_64((literal_base * 4) & 0xffffffff, x13); + + TEARDOWN(); +} + + +TEST(peek_poke_unaligned) { + INIT_V8(); + SETUP(); + START(); + + // The literal base is chosen to have two useful properties: + // * When multiplied by small values (such as a register index), this value + // is clearly readable in the result. + // * The value is not formed from repeating fixed-size smaller values, so it + // can be used to detect endianness-related errors. + uint64_t literal_base = 0x0100001000100101UL; + + // Initialize the registers. + __ Mov(x0, literal_base); + __ Add(x1, x0, x0); + __ Add(x2, x1, x0); + __ Add(x3, x2, x0); + __ Add(x4, x3, x0); + __ Add(x5, x4, x0); + __ Add(x6, x5, x0); + + __ Claim(4); + + // Unaligned exchanges. + // After this test: + // x0-x6 should be unchanged. + // w10-w12 should contain the lower words of x0-x2. + __ Poke(x0, 1); + Clobber(&masm, x0.Bit()); + __ Peek(x0, 1); + __ Poke(x1, 2); + Clobber(&masm, x1.Bit()); + __ Peek(x1, 2); + __ Poke(x2, 3); + Clobber(&masm, x2.Bit()); + __ Peek(x2, 3); + __ Poke(x3, 4); + Clobber(&masm, x3.Bit()); + __ Peek(x3, 4); + __ Poke(x4, 5); + Clobber(&masm, x4.Bit()); + __ Peek(x4, 5); + __ Poke(x5, 6); + Clobber(&masm, x5.Bit()); + __ Peek(x5, 6); + __ Poke(x6, 7); + Clobber(&masm, x6.Bit()); + __ Peek(x6, 7); + + __ Poke(w0, 1); + Clobber(&masm, w10.Bit()); + __ Peek(w10, 1); + __ Poke(w1, 2); + Clobber(&masm, w11.Bit()); + __ Peek(w11, 2); + __ Poke(w2, 3); + Clobber(&masm, w12.Bit()); + __ Peek(w12, 3); + + __ Drop(4); + + END(); + RUN(); + + ASSERT_EQUAL_64(literal_base * 1, x0); + ASSERT_EQUAL_64(literal_base * 2, x1); + ASSERT_EQUAL_64(literal_base * 3, x2); + ASSERT_EQUAL_64(literal_base * 4, x3); + ASSERT_EQUAL_64(literal_base * 5, x4); + ASSERT_EQUAL_64(literal_base * 6, x5); + ASSERT_EQUAL_64(literal_base * 7, x6); + + ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10); + ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11); + ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12); + + TEARDOWN(); +} + + +TEST(peek_poke_endianness) { + INIT_V8(); + SETUP(); + START(); + + // The literal base is chosen to have two useful properties: + // * When multiplied by small values (such as a register index), this value + // is clearly readable in the result. + // * The value is not formed from repeating fixed-size smaller values, so it + // can be used to detect endianness-related errors. + uint64_t literal_base = 0x0100001000100101UL; + + // Initialize the registers. + __ Mov(x0, literal_base); + __ Add(x1, x0, x0); + + __ Claim(4); + + // Endianness tests. + // After this section: + // x4 should match x0[31:0]:x0[63:32] + // w5 should match w1[15:0]:w1[31:16] + __ Poke(x0, 0); + __ Poke(x0, 8); + __ Peek(x4, 4); + + __ Poke(w1, 0); + __ Poke(w1, 4); + __ Peek(w5, 2); + + __ Drop(4); + + END(); + RUN(); + + uint64_t x0_expected = literal_base * 1; + uint64_t x1_expected = literal_base * 2; + uint64_t x4_expected = (x0_expected << 32) | (x0_expected >> 32); + uint64_t x5_expected = ((x1_expected << 16) & 0xffff0000) | + ((x1_expected >> 16) & 0x0000ffff); + + ASSERT_EQUAL_64(x0_expected, x0); + ASSERT_EQUAL_64(x1_expected, x1); + ASSERT_EQUAL_64(x4_expected, x4); + ASSERT_EQUAL_64(x5_expected, x5); + + TEARDOWN(); +} + + +TEST(peek_poke_mixed) { + INIT_V8(); + SETUP(); + START(); + + // The literal base is chosen to have two useful properties: + // * When multiplied by small values (such as a register index), this value + // is clearly readable in the result. + // * The value is not formed from repeating fixed-size smaller values, so it + // can be used to detect endianness-related errors. + uint64_t literal_base = 0x0100001000100101UL; + + // Initialize the registers. + __ Mov(x0, literal_base); + __ Add(x1, x0, x0); + __ Add(x2, x1, x0); + __ Add(x3, x2, x0); + + __ Claim(4); + + // Mix with other stack operations. + // After this section: + // x0-x3 should be unchanged. + // x6 should match x1[31:0]:x0[63:32] + // w7 should match x1[15:0]:x0[63:48] + __ Poke(x1, 8); + __ Poke(x0, 0); + { + ASSERT(__ StackPointer().Is(csp)); + __ Mov(x4, __ StackPointer()); + __ SetStackPointer(x4); + + __ Poke(wzr, 0); // Clobber the space we're about to drop. + __ Drop(1, kWRegSizeInBytes); + __ Peek(x6, 0); + __ Claim(1); + __ Peek(w7, 10); + __ Poke(x3, 28); + __ Poke(xzr, 0); // Clobber the space we're about to drop. + __ Drop(1); + __ Poke(x2, 12); + __ Push(w0); + + __ Mov(csp, __ StackPointer()); + __ SetStackPointer(csp); + } + + __ Pop(x0, x1, x2, x3); + + END(); + RUN(); + + uint64_t x0_expected = literal_base * 1; + uint64_t x1_expected = literal_base * 2; + uint64_t x2_expected = literal_base * 3; + uint64_t x3_expected = literal_base * 4; + uint64_t x6_expected = (x1_expected << 32) | (x0_expected >> 32); + uint64_t x7_expected = ((x1_expected << 16) & 0xffff0000) | + ((x0_expected >> 48) & 0x0000ffff); + + ASSERT_EQUAL_64(x0_expected, x0); + ASSERT_EQUAL_64(x1_expected, x1); + ASSERT_EQUAL_64(x2_expected, x2); + ASSERT_EQUAL_64(x3_expected, x3); + ASSERT_EQUAL_64(x6_expected, x6); + ASSERT_EQUAL_64(x7_expected, x7); + + TEARDOWN(); +} + + +// This enum is used only as an argument to the push-pop test helpers. +enum PushPopMethod { + // Push or Pop using the Push and Pop methods, with blocks of up to four + // registers. (Smaller blocks will be used if necessary.) + PushPopByFour, + + // Use Push<Size>RegList and Pop<Size>RegList to transfer the registers. + PushPopRegList +}; + + +// The maximum number of registers that can be used by the PushPopJssp* tests, +// where a reg_count field is provided. +static int const kPushPopJsspMaxRegCount = -1; + +// Test a simple push-pop pattern: +// * Claim <claim> bytes to set the stack alignment. +// * Push <reg_count> registers with size <reg_size>. +// * Clobber the register contents. +// * Pop <reg_count> registers to restore the original contents. +// * Drop <claim> bytes to restore the original stack pointer. +// +// Different push and pop methods can be specified independently to test for +// proper word-endian behaviour. +static void PushPopJsspSimpleHelper(int reg_count, + int claim, + int reg_size, + PushPopMethod push_method, + PushPopMethod pop_method) { + SETUP(); + + START(); + + // Registers x8 and x9 are used by the macro assembler for debug code (for + // example in 'Pop'), so we can't use them here. We can't use jssp because it + // will be the stack pointer for this test. + static RegList const allowed = ~(x8.Bit() | x9.Bit() | jssp.Bit()); + if (reg_count == kPushPopJsspMaxRegCount) { + reg_count = CountSetBits(allowed, kNumberOfRegisters); + } + // Work out which registers to use, based on reg_size. + Register r[kNumberOfRegisters]; + Register x[kNumberOfRegisters]; + RegList list = PopulateRegisterArray(NULL, x, r, reg_size, reg_count, + allowed); + + // The literal base is chosen to have two useful properties: + // * When multiplied by small values (such as a register index), this value + // is clearly readable in the result. + // * The value is not formed from repeating fixed-size smaller values, so it + // can be used to detect endianness-related errors. + uint64_t literal_base = 0x0100001000100101UL; + + { + ASSERT(__ StackPointer().Is(csp)); + __ Mov(jssp, __ StackPointer()); + __ SetStackPointer(jssp); + + int i; + + // Initialize the registers. + for (i = 0; i < reg_count; i++) { + // Always write into the X register, to ensure that the upper word is + // properly ignored by Push when testing W registers. + if (!x[i].IsZero()) { + __ Mov(x[i], literal_base * i); + } + } + + // Claim memory first, as requested. + __ Claim(claim, kByteSizeInBytes); + + switch (push_method) { + case PushPopByFour: + // Push high-numbered registers first (to the highest addresses). + for (i = reg_count; i >= 4; i -= 4) { + __ Push(r[i-1], r[i-2], r[i-3], r[i-4]); + } + // Finish off the leftovers. + switch (i) { + case 3: __ Push(r[2], r[1], r[0]); break; + case 2: __ Push(r[1], r[0]); break; + case 1: __ Push(r[0]); break; + default: ASSERT(i == 0); break; + } + break; + case PushPopRegList: + __ PushSizeRegList(list, reg_size); + break; + } + + // Clobber all the registers, to ensure that they get repopulated by Pop. + Clobber(&masm, list); + + switch (pop_method) { + case PushPopByFour: + // Pop low-numbered registers first (from the lowest addresses). + for (i = 0; i <= (reg_count-4); i += 4) { + __ Pop(r[i], r[i+1], r[i+2], r[i+3]); + } + // Finish off the leftovers. + switch (reg_count - i) { + case 3: __ Pop(r[i], r[i+1], r[i+2]); break; + case 2: __ Pop(r[i], r[i+1]); break; + case 1: __ Pop(r[i]); break; + default: ASSERT(i == reg_count); break; + } + break; + case PushPopRegList: + __ PopSizeRegList(list, reg_size); + break; + } + + // Drop memory to restore jssp. + __ Drop(claim, kByteSizeInBytes); + + __ Mov(csp, __ StackPointer()); + __ SetStackPointer(csp); + } + + END(); + + RUN(); + + // Check that the register contents were preserved. + // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test + // that the upper word was properly cleared by Pop. + literal_base &= (0xffffffffffffffffUL >> (64-reg_size)); + for (int i = 0; i < reg_count; i++) { + if (x[i].IsZero()) { + ASSERT_EQUAL_64(0, x[i]); + } else { + ASSERT_EQUAL_64(literal_base * i, x[i]); + } + } + + TEARDOWN(); +} + + +TEST(push_pop_jssp_simple_32) { + INIT_V8(); + for (int claim = 0; claim <= 8; claim++) { + for (int count = 0; count <= 8; count++) { + PushPopJsspSimpleHelper(count, claim, kWRegSize, + PushPopByFour, PushPopByFour); + PushPopJsspSimpleHelper(count, claim, kWRegSize, + PushPopByFour, PushPopRegList); + PushPopJsspSimpleHelper(count, claim, kWRegSize, + PushPopRegList, PushPopByFour); + PushPopJsspSimpleHelper(count, claim, kWRegSize, + PushPopRegList, PushPopRegList); + } + // Test with the maximum number of registers. + PushPopJsspSimpleHelper(kPushPopJsspMaxRegCount, claim, kWRegSize, + PushPopByFour, PushPopByFour); + PushPopJsspSimpleHelper(kPushPopJsspMaxRegCount, claim, kWRegSize, + PushPopByFour, PushPopRegList); + PushPopJsspSimpleHelper(kPushPopJsspMaxRegCount, claim, kWRegSize, + PushPopRegList, PushPopByFour); + PushPopJsspSimpleHelper(kPushPopJsspMaxRegCount, claim, kWRegSize, + PushPopRegList, PushPopRegList); + } +} + + +TEST(push_pop_jssp_simple_64) { + INIT_V8(); + for (int claim = 0; claim <= 8; claim++) { + for (int count = 0; count <= 8; count++) { + PushPopJsspSimpleHelper(count, claim, kXRegSize, + PushPopByFour, PushPopByFour); + PushPopJsspSimpleHelper(count, claim, kXRegSize, + PushPopByFour, PushPopRegList); + PushPopJsspSimpleHelper(count, claim, kXRegSize, + PushPopRegList, PushPopByFour); + PushPopJsspSimpleHelper(count, claim, kXRegSize, + PushPopRegList, PushPopRegList); + } + // Test with the maximum number of registers. + PushPopJsspSimpleHelper(kPushPopJsspMaxRegCount, claim, kXRegSize, + PushPopByFour, PushPopByFour); + PushPopJsspSimpleHelper(kPushPopJsspMaxRegCount, claim, kXRegSize, + PushPopByFour, PushPopRegList); + PushPopJsspSimpleHelper(kPushPopJsspMaxRegCount, claim, kXRegSize, + PushPopRegList, PushPopByFour); + PushPopJsspSimpleHelper(kPushPopJsspMaxRegCount, claim, kXRegSize, + PushPopRegList, PushPopRegList); + } +} + + +// The maximum number of registers that can be used by the PushPopFPJssp* tests, +// where a reg_count field is provided. +static int const kPushPopFPJsspMaxRegCount = -1; + +// Test a simple push-pop pattern: +// * Claim <claim> bytes to set the stack alignment. +// * Push <reg_count> FP registers with size <reg_size>. +// * Clobber the register contents. +// * Pop <reg_count> FP registers to restore the original contents. +// * Drop <claim> bytes to restore the original stack pointer. +// +// Different push and pop methods can be specified independently to test for +// proper word-endian behaviour. +static void PushPopFPJsspSimpleHelper(int reg_count, + int claim, + int reg_size, + PushPopMethod push_method, + PushPopMethod pop_method) { + SETUP(); + + START(); + + // We can use any floating-point register. None of them are reserved for + // debug code, for example. + static RegList const allowed = ~0; + if (reg_count == kPushPopFPJsspMaxRegCount) { + reg_count = CountSetBits(allowed, kNumberOfFPRegisters); + } + // Work out which registers to use, based on reg_size. + FPRegister v[kNumberOfRegisters]; + FPRegister d[kNumberOfRegisters]; + RegList list = PopulateFPRegisterArray(NULL, d, v, reg_size, reg_count, + allowed); + + // The literal base is chosen to have two useful properties: + // * When multiplied (using an integer) by small values (such as a register + // index), this value is clearly readable in the result. + // * The value is not formed from repeating fixed-size smaller values, so it + // can be used to detect endianness-related errors. + // * It is never a floating-point NaN, and will therefore always compare + // equal to itself. + uint64_t literal_base = 0x0100001000100101UL; + + { + ASSERT(__ StackPointer().Is(csp)); + __ Mov(jssp, __ StackPointer()); + __ SetStackPointer(jssp); + + int i; + + // Initialize the registers, using X registers to load the literal. + __ Mov(x0, 0); + __ Mov(x1, literal_base); + for (i = 0; i < reg_count; i++) { + // Always write into the D register, to ensure that the upper word is + // properly ignored by Push when testing S registers. + __ Fmov(d[i], x0); + // Calculate the next literal. + __ Add(x0, x0, x1); + } + + // Claim memory first, as requested. + __ Claim(claim, kByteSizeInBytes); + + switch (push_method) { + case PushPopByFour: + // Push high-numbered registers first (to the highest addresses). + for (i = reg_count; i >= 4; i -= 4) { + __ Push(v[i-1], v[i-2], v[i-3], v[i-4]); + } + // Finish off the leftovers. + switch (i) { + case 3: __ Push(v[2], v[1], v[0]); break; + case 2: __ Push(v[1], v[0]); break; + case 1: __ Push(v[0]); break; + default: ASSERT(i == 0); break; + } + break; + case PushPopRegList: + __ PushSizeRegList(list, reg_size, CPURegister::kFPRegister); + break; + } + + // Clobber all the registers, to ensure that they get repopulated by Pop. + ClobberFP(&masm, list); + + switch (pop_method) { + case PushPopByFour: + // Pop low-numbered registers first (from the lowest addresses). + for (i = 0; i <= (reg_count-4); i += 4) { + __ Pop(v[i], v[i+1], v[i+2], v[i+3]); + } + // Finish off the leftovers. + switch (reg_count - i) { + case 3: __ Pop(v[i], v[i+1], v[i+2]); break; + case 2: __ Pop(v[i], v[i+1]); break; + case 1: __ Pop(v[i]); break; + default: ASSERT(i == reg_count); break; + } + break; + case PushPopRegList: + __ PopSizeRegList(list, reg_size, CPURegister::kFPRegister); + break; + } + + // Drop memory to restore jssp. + __ Drop(claim, kByteSizeInBytes); + + __ Mov(csp, __ StackPointer()); + __ SetStackPointer(csp); + } + + END(); + + RUN(); + + // Check that the register contents were preserved. + // Always use ASSERT_EQUAL_FP64, even when testing S registers, so we can + // test that the upper word was properly cleared by Pop. + literal_base &= (0xffffffffffffffffUL >> (64-reg_size)); + for (int i = 0; i < reg_count; i++) { + uint64_t literal = literal_base * i; + double expected; + memcpy(&expected, &literal, sizeof(expected)); + ASSERT_EQUAL_FP64(expected, d[i]); + } + + TEARDOWN(); +} + + +TEST(push_pop_fp_jssp_simple_32) { + INIT_V8(); + for (int claim = 0; claim <= 8; claim++) { + for (int count = 0; count <= 8; count++) { + PushPopFPJsspSimpleHelper(count, claim, kSRegSize, + PushPopByFour, PushPopByFour); + PushPopFPJsspSimpleHelper(count, claim, kSRegSize, + PushPopByFour, PushPopRegList); + PushPopFPJsspSimpleHelper(count, claim, kSRegSize, + PushPopRegList, PushPopByFour); + PushPopFPJsspSimpleHelper(count, claim, kSRegSize, + PushPopRegList, PushPopRegList); + } + // Test with the maximum number of registers. + PushPopFPJsspSimpleHelper(kPushPopFPJsspMaxRegCount, claim, kSRegSize, + PushPopByFour, PushPopByFour); + PushPopFPJsspSimpleHelper(kPushPopFPJsspMaxRegCount, claim, kSRegSize, + PushPopByFour, PushPopRegList); + PushPopFPJsspSimpleHelper(kPushPopFPJsspMaxRegCount, claim, kSRegSize, + PushPopRegList, PushPopByFour); + PushPopFPJsspSimpleHelper(kPushPopFPJsspMaxRegCount, claim, kSRegSize, + PushPopRegList, PushPopRegList); + } +} + + +TEST(push_pop_fp_jssp_simple_64) { + INIT_V8(); + for (int claim = 0; claim <= 8; claim++) { + for (int count = 0; count <= 8; count++) { + PushPopFPJsspSimpleHelper(count, claim, kDRegSize, + PushPopByFour, PushPopByFour); + PushPopFPJsspSimpleHelper(count, claim, kDRegSize, + PushPopByFour, PushPopRegList); + PushPopFPJsspSimpleHelper(count, claim, kDRegSize, + PushPopRegList, PushPopByFour); + PushPopFPJsspSimpleHelper(count, claim, kDRegSize, + PushPopRegList, PushPopRegList); + } + // Test with the maximum number of registers. + PushPopFPJsspSimpleHelper(kPushPopFPJsspMaxRegCount, claim, kDRegSize, + PushPopByFour, PushPopByFour); + PushPopFPJsspSimpleHelper(kPushPopFPJsspMaxRegCount, claim, kDRegSize, + PushPopByFour, PushPopRegList); + PushPopFPJsspSimpleHelper(kPushPopFPJsspMaxRegCount, claim, kDRegSize, + PushPopRegList, PushPopByFour); + PushPopFPJsspSimpleHelper(kPushPopFPJsspMaxRegCount, claim, kDRegSize, + PushPopRegList, PushPopRegList); + } +} + + +// Push and pop data using an overlapping combination of Push/Pop and +// RegList-based methods. +static void PushPopJsspMixedMethodsHelper(int claim, int reg_size) { + SETUP(); + + // Registers x8 and x9 are used by the macro assembler for debug code (for + // example in 'Pop'), so we can't use them here. We can't use jssp because it + // will be the stack pointer for this test. + static RegList const allowed = + ~(x8.Bit() | x9.Bit() | jssp.Bit() | xzr.Bit()); + // Work out which registers to use, based on reg_size. + Register r[10]; + Register x[10]; + PopulateRegisterArray(NULL, x, r, reg_size, 10, allowed); + + // Calculate some handy register lists. + RegList r0_to_r3 = 0; + for (int i = 0; i <= 3; i++) { + r0_to_r3 |= x[i].Bit(); + } + RegList r4_to_r5 = 0; + for (int i = 4; i <= 5; i++) { + r4_to_r5 |= x[i].Bit(); + } + RegList r6_to_r9 = 0; + for (int i = 6; i <= 9; i++) { + r6_to_r9 |= x[i].Bit(); + } + + // The literal base is chosen to have two useful properties: + // * When multiplied by small values (such as a register index), this value + // is clearly readable in the result. + // * The value is not formed from repeating fixed-size smaller values, so it + // can be used to detect endianness-related errors. + uint64_t literal_base = 0x0100001000100101UL; + + START(); + { + ASSERT(__ StackPointer().Is(csp)); + __ Mov(jssp, __ StackPointer()); + __ SetStackPointer(jssp); + + // Claim memory first, as requested. + __ Claim(claim, kByteSizeInBytes); + + __ Mov(x[3], literal_base * 3); + __ Mov(x[2], literal_base * 2); + __ Mov(x[1], literal_base * 1); + __ Mov(x[0], literal_base * 0); + + __ PushSizeRegList(r0_to_r3, reg_size); + __ Push(r[3], r[2]); + + Clobber(&masm, r0_to_r3); + __ PopSizeRegList(r0_to_r3, reg_size); + + __ Push(r[2], r[1], r[3], r[0]); + + Clobber(&masm, r4_to_r5); + __ Pop(r[4], r[5]); + Clobber(&masm, r6_to_r9); + __ Pop(r[6], r[7], r[8], r[9]); + + // Drop memory to restore jssp. + __ Drop(claim, kByteSizeInBytes); + + __ Mov(csp, __ StackPointer()); + __ SetStackPointer(csp); + } + + END(); + + RUN(); + + // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test + // that the upper word was properly cleared by Pop. + literal_base &= (0xffffffffffffffffUL >> (64-reg_size)); + + ASSERT_EQUAL_64(literal_base * 3, x[9]); + ASSERT_EQUAL_64(literal_base * 2, x[8]); + ASSERT_EQUAL_64(literal_base * 0, x[7]); + ASSERT_EQUAL_64(literal_base * 3, x[6]); + ASSERT_EQUAL_64(literal_base * 1, x[5]); + ASSERT_EQUAL_64(literal_base * 2, x[4]); + + TEARDOWN(); +} + + +TEST(push_pop_jssp_mixed_methods_64) { + INIT_V8(); + for (int claim = 0; claim <= 8; claim++) { + PushPopJsspMixedMethodsHelper(claim, kXRegSize); + } +} + + +TEST(push_pop_jssp_mixed_methods_32) { + INIT_V8(); + for (int claim = 0; claim <= 8; claim++) { + PushPopJsspMixedMethodsHelper(claim, kWRegSize); + } +} + + +// Push and pop data using overlapping X- and W-sized quantities. +static void PushPopJsspWXOverlapHelper(int reg_count, int claim) { + // This test emits rather a lot of code. + SETUP_SIZE(BUF_SIZE * 2); + + // Work out which registers to use, based on reg_size. + static RegList const allowed = ~(x8.Bit() | x9.Bit() | jssp.Bit()); + if (reg_count == kPushPopJsspMaxRegCount) { + reg_count = CountSetBits(allowed, kNumberOfRegisters); + } + Register w[kNumberOfRegisters]; + Register x[kNumberOfRegisters]; + RegList list = PopulateRegisterArray(w, x, NULL, 0, reg_count, allowed); + + // The number of W-sized slots we expect to pop. When we pop, we alternate + // between W and X registers, so we need reg_count*1.5 W-sized slots. + int const requested_w_slots = reg_count + reg_count / 2; + + // Track what _should_ be on the stack, using W-sized slots. + static int const kMaxWSlots = kNumberOfRegisters + kNumberOfRegisters / 2; + uint32_t stack[kMaxWSlots]; + for (int i = 0; i < kMaxWSlots; i++) { + stack[i] = 0xdeadbeef; + } + + // The literal base is chosen to have two useful properties: + // * When multiplied by small values (such as a register index), this value + // is clearly readable in the result. + // * The value is not formed from repeating fixed-size smaller values, so it + // can be used to detect endianness-related errors. + static uint64_t const literal_base = 0x0100001000100101UL; + static uint64_t const literal_base_hi = literal_base >> 32; + static uint64_t const literal_base_lo = literal_base & 0xffffffff; + static uint64_t const literal_base_w = literal_base & 0xffffffff; + + START(); + { + ASSERT(__ StackPointer().Is(csp)); + __ Mov(jssp, __ StackPointer()); + __ SetStackPointer(jssp); + + // Initialize the registers. + for (int i = 0; i < reg_count; i++) { + // Always write into the X register, to ensure that the upper word is + // properly ignored by Push when testing W registers. + if (!x[i].IsZero()) { + __ Mov(x[i], literal_base * i); + } + } + + // Claim memory first, as requested. + __ Claim(claim, kByteSizeInBytes); + + // The push-pop pattern is as follows: + // Push: Pop: + // x[0](hi) -> w[0] + // x[0](lo) -> x[1](hi) + // w[1] -> x[1](lo) + // w[1] -> w[2] + // x[2](hi) -> x[2](hi) + // x[2](lo) -> x[2](lo) + // x[2](hi) -> w[3] + // x[2](lo) -> x[4](hi) + // x[2](hi) -> x[4](lo) + // x[2](lo) -> w[5] + // w[3] -> x[5](hi) + // w[3] -> x[6](lo) + // w[3] -> w[7] + // w[3] -> x[8](hi) + // x[4](hi) -> x[8](lo) + // x[4](lo) -> w[9] + // ... pattern continues ... + // + // That is, registers are pushed starting with the lower numbers, + // alternating between x and w registers, and pushing i%4+1 copies of each, + // where i is the register number. + // Registers are popped starting with the higher numbers one-by-one, + // alternating between x and w registers, but only popping one at a time. + // + // This pattern provides a wide variety of alignment effects and overlaps. + + // ---- Push ---- + + int active_w_slots = 0; + for (int i = 0; active_w_slots < requested_w_slots; i++) { + ASSERT(i < reg_count); + // In order to test various arguments to PushMultipleTimes, and to try to + // exercise different alignment and overlap effects, we push each + // register a different number of times. + int times = i % 4 + 1; + if (i & 1) { + // Push odd-numbered registers as W registers. + __ PushMultipleTimes(times, w[i]); + // Fill in the expected stack slots. + for (int j = 0; j < times; j++) { + if (w[i].Is(wzr)) { + // The zero register always writes zeroes. + stack[active_w_slots++] = 0; + } else { + stack[active_w_slots++] = literal_base_w * i; + } + } + } else { + // Push even-numbered registers as X registers. + __ PushMultipleTimes(times, x[i]); + // Fill in the expected stack slots. + for (int j = 0; j < times; j++) { + if (x[i].IsZero()) { + // The zero register always writes zeroes. + stack[active_w_slots++] = 0; + stack[active_w_slots++] = 0; + } else { + stack[active_w_slots++] = literal_base_hi * i; + stack[active_w_slots++] = literal_base_lo * i; + } + } + } + } + // Because we were pushing several registers at a time, we probably pushed + // more than we needed to. + if (active_w_slots > requested_w_slots) { + __ Drop(active_w_slots - requested_w_slots, kWRegSizeInBytes); + // Bump the number of active W-sized slots back to where it should be, + // and fill the empty space with a dummy value. + do { + stack[active_w_slots--] = 0xdeadbeef; + } while (active_w_slots > requested_w_slots); + } + + // ---- Pop ---- + + Clobber(&masm, list); + + // If popping an even number of registers, the first one will be X-sized. + // Otherwise, the first one will be W-sized. + bool next_is_64 = !(reg_count & 1); + for (int i = reg_count-1; i >= 0; i--) { + if (next_is_64) { + __ Pop(x[i]); + active_w_slots -= 2; + } else { + __ Pop(w[i]); + active_w_slots -= 1; + } + next_is_64 = !next_is_64; + } + ASSERT(active_w_slots == 0); + + // Drop memory to restore jssp. + __ Drop(claim, kByteSizeInBytes); + + __ Mov(csp, __ StackPointer()); + __ SetStackPointer(csp); + } + + END(); + + RUN(); + + int slot = 0; + for (int i = 0; i < reg_count; i++) { + // Even-numbered registers were written as W registers. + // Odd-numbered registers were written as X registers. + bool expect_64 = (i & 1); + uint64_t expected; + + if (expect_64) { + uint64_t hi = stack[slot++]; + uint64_t lo = stack[slot++]; + expected = (hi << 32) | lo; + } else { + expected = stack[slot++]; + } + + // Always use ASSERT_EQUAL_64, even when testing W registers, so we can + // test that the upper word was properly cleared by Pop. + if (x[i].IsZero()) { + ASSERT_EQUAL_64(0, x[i]); + } else { + ASSERT_EQUAL_64(expected, x[i]); + } + } + ASSERT(slot == requested_w_slots); + + TEARDOWN(); +} + + +TEST(push_pop_jssp_wx_overlap) { + INIT_V8(); + for (int claim = 0; claim <= 8; claim++) { + for (int count = 1; count <= 8; count++) { + PushPopJsspWXOverlapHelper(count, claim); + PushPopJsspWXOverlapHelper(count, claim); + PushPopJsspWXOverlapHelper(count, claim); + PushPopJsspWXOverlapHelper(count, claim); + } + // Test with the maximum number of registers. + PushPopJsspWXOverlapHelper(kPushPopJsspMaxRegCount, claim); + PushPopJsspWXOverlapHelper(kPushPopJsspMaxRegCount, claim); + PushPopJsspWXOverlapHelper(kPushPopJsspMaxRegCount, claim); + PushPopJsspWXOverlapHelper(kPushPopJsspMaxRegCount, claim); + } +} + + +TEST(push_pop_csp) { + INIT_V8(); + SETUP(); + + START(); + + ASSERT(csp.Is(__ StackPointer())); + + __ Mov(x3, 0x3333333333333333UL); + __ Mov(x2, 0x2222222222222222UL); + __ Mov(x1, 0x1111111111111111UL); + __ Mov(x0, 0x0000000000000000UL); + __ Claim(2); + __ PushXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit()); + __ Push(x3, x2); + __ PopXRegList(x0.Bit() | x1.Bit() | x2.Bit() | x3.Bit()); + __ Push(x2, x1, x3, x0); + __ Pop(x4, x5); + __ Pop(x6, x7, x8, x9); + + __ Claim(2); + __ PushWRegList(w0.Bit() | w1.Bit() | w2.Bit() | w3.Bit()); + __ Push(w3, w1, w2, w0); + __ PopWRegList(w10.Bit() | w11.Bit() | w12.Bit() | w13.Bit()); + __ Pop(w14, w15, w16, w17); + + __ Claim(2); + __ Push(w2, w2, w1, w1); + __ Push(x3, x3); + __ Pop(w18, w19, w20, w21); + __ Pop(x22, x23); + + __ Claim(2); + __ PushXRegList(x1.Bit() | x22.Bit()); + __ PopXRegList(x24.Bit() | x26.Bit()); + + __ Claim(2); + __ PushWRegList(w1.Bit() | w2.Bit() | w4.Bit() | w22.Bit()); + __ PopWRegList(w25.Bit() | w27.Bit() | w28.Bit() | w29.Bit()); + + __ Claim(2); + __ PushXRegList(0); + __ PopXRegList(0); + __ PushXRegList(0xffffffff); + __ PopXRegList(0xffffffff); + __ Drop(12); + + END(); + + RUN(); + + ASSERT_EQUAL_64(0x1111111111111111UL, x3); + ASSERT_EQUAL_64(0x0000000000000000UL, x2); + ASSERT_EQUAL_64(0x3333333333333333UL, x1); + ASSERT_EQUAL_64(0x2222222222222222UL, x0); + ASSERT_EQUAL_64(0x3333333333333333UL, x9); + ASSERT_EQUAL_64(0x2222222222222222UL, x8); + ASSERT_EQUAL_64(0x0000000000000000UL, x7); + ASSERT_EQUAL_64(0x3333333333333333UL, x6); + ASSERT_EQUAL_64(0x1111111111111111UL, x5); + ASSERT_EQUAL_64(0x2222222222222222UL, x4); + + ASSERT_EQUAL_32(0x11111111U, w13); + ASSERT_EQUAL_32(0x33333333U, w12); + ASSERT_EQUAL_32(0x00000000U, w11); + ASSERT_EQUAL_32(0x22222222U, w10); + ASSERT_EQUAL_32(0x11111111U, w17); + ASSERT_EQUAL_32(0x00000000U, w16); + ASSERT_EQUAL_32(0x33333333U, w15); + ASSERT_EQUAL_32(0x22222222U, w14); + + ASSERT_EQUAL_32(0x11111111U, w18); + ASSERT_EQUAL_32(0x11111111U, w19); + ASSERT_EQUAL_32(0x11111111U, w20); + ASSERT_EQUAL_32(0x11111111U, w21); + ASSERT_EQUAL_64(0x3333333333333333UL, x22); + ASSERT_EQUAL_64(0x0000000000000000UL, x23); + + ASSERT_EQUAL_64(0x3333333333333333UL, x24); + ASSERT_EQUAL_64(0x3333333333333333UL, x26); + + ASSERT_EQUAL_32(0x33333333U, w25); + ASSERT_EQUAL_32(0x00000000U, w27); + ASSERT_EQUAL_32(0x22222222U, w28); + ASSERT_EQUAL_32(0x33333333U, w29); + TEARDOWN(); +} + + +TEST(jump_both_smi) { + INIT_V8(); + SETUP(); + + Label cond_pass_00, cond_pass_01, cond_pass_10, cond_pass_11; + Label cond_fail_00, cond_fail_01, cond_fail_10, cond_fail_11; + Label return1, return2, return3, done; + + START(); + + __ Mov(x0, 0x5555555500000001UL); // A pointer. + __ Mov(x1, 0xaaaaaaaa00000001UL); // A pointer. + __ Mov(x2, 0x1234567800000000UL); // A smi. + __ Mov(x3, 0x8765432100000000UL); // A smi. + __ Mov(x4, 0xdead); + __ Mov(x5, 0xdead); + __ Mov(x6, 0xdead); + __ Mov(x7, 0xdead); + + __ JumpIfBothSmi(x0, x1, &cond_pass_00, &cond_fail_00); + __ Bind(&return1); + __ JumpIfBothSmi(x0, x2, &cond_pass_01, &cond_fail_01); + __ Bind(&return2); + __ JumpIfBothSmi(x2, x1, &cond_pass_10, &cond_fail_10); + __ Bind(&return3); + __ JumpIfBothSmi(x2, x3, &cond_pass_11, &cond_fail_11); + + __ Bind(&cond_fail_00); + __ Mov(x4, 0); + __ B(&return1); + __ Bind(&cond_pass_00); + __ Mov(x4, 1); + __ B(&return1); + + __ Bind(&cond_fail_01); + __ Mov(x5, 0); + __ B(&return2); + __ Bind(&cond_pass_01); + __ Mov(x5, 1); + __ B(&return2); + + __ Bind(&cond_fail_10); + __ Mov(x6, 0); + __ B(&return3); + __ Bind(&cond_pass_10); + __ Mov(x6, 1); + __ B(&return3); + + __ Bind(&cond_fail_11); + __ Mov(x7, 0); + __ B(&done); + __ Bind(&cond_pass_11); + __ Mov(x7, 1); + + __ Bind(&done); + + END(); + + RUN(); + + ASSERT_EQUAL_64(0x5555555500000001UL, x0); + ASSERT_EQUAL_64(0xaaaaaaaa00000001UL, x1); + ASSERT_EQUAL_64(0x1234567800000000UL, x2); + ASSERT_EQUAL_64(0x8765432100000000UL, x3); + ASSERT_EQUAL_64(0, x4); + ASSERT_EQUAL_64(0, x5); + ASSERT_EQUAL_64(0, x6); + ASSERT_EQUAL_64(1, x7); + + TEARDOWN(); +} + + +TEST(jump_either_smi) { + INIT_V8(); + SETUP(); + + Label cond_pass_00, cond_pass_01, cond_pass_10, cond_pass_11; + Label cond_fail_00, cond_fail_01, cond_fail_10, cond_fail_11; + Label return1, return2, return3, done; + + START(); + + __ Mov(x0, 0x5555555500000001UL); // A pointer. + __ Mov(x1, 0xaaaaaaaa00000001UL); // A pointer. + __ Mov(x2, 0x1234567800000000UL); // A smi. + __ Mov(x3, 0x8765432100000000UL); // A smi. + __ Mov(x4, 0xdead); + __ Mov(x5, 0xdead); + __ Mov(x6, 0xdead); + __ Mov(x7, 0xdead); + + __ JumpIfEitherSmi(x0, x1, &cond_pass_00, &cond_fail_00); + __ Bind(&return1); + __ JumpIfEitherSmi(x0, x2, &cond_pass_01, &cond_fail_01); + __ Bind(&return2); + __ JumpIfEitherSmi(x2, x1, &cond_pass_10, &cond_fail_10); + __ Bind(&return3); + __ JumpIfEitherSmi(x2, x3, &cond_pass_11, &cond_fail_11); + + __ Bind(&cond_fail_00); + __ Mov(x4, 0); + __ B(&return1); + __ Bind(&cond_pass_00); + __ Mov(x4, 1); + __ B(&return1); + + __ Bind(&cond_fail_01); + __ Mov(x5, 0); + __ B(&return2); + __ Bind(&cond_pass_01); + __ Mov(x5, 1); + __ B(&return2); + + __ Bind(&cond_fail_10); + __ Mov(x6, 0); + __ B(&return3); + __ Bind(&cond_pass_10); + __ Mov(x6, 1); + __ B(&return3); + + __ Bind(&cond_fail_11); + __ Mov(x7, 0); + __ B(&done); + __ Bind(&cond_pass_11); + __ Mov(x7, 1); + + __ Bind(&done); + + END(); + + RUN(); + + ASSERT_EQUAL_64(0x5555555500000001UL, x0); + ASSERT_EQUAL_64(0xaaaaaaaa00000001UL, x1); + ASSERT_EQUAL_64(0x1234567800000000UL, x2); + ASSERT_EQUAL_64(0x8765432100000000UL, x3); + ASSERT_EQUAL_64(0, x4); + ASSERT_EQUAL_64(1, x5); + ASSERT_EQUAL_64(1, x6); + ASSERT_EQUAL_64(1, x7); + + TEARDOWN(); +} + + +TEST(noreg) { + // This test doesn't generate any code, but it verifies some invariants + // related to NoReg. + CHECK(NoReg.Is(NoFPReg)); + CHECK(NoFPReg.Is(NoReg)); + CHECK(NoReg.Is(NoCPUReg)); + CHECK(NoCPUReg.Is(NoReg)); + CHECK(NoFPReg.Is(NoCPUReg)); + CHECK(NoCPUReg.Is(NoFPReg)); + + CHECK(NoReg.IsNone()); + CHECK(NoFPReg.IsNone()); + CHECK(NoCPUReg.IsNone()); +} + + +TEST(isvalid) { + // This test doesn't generate any code, but it verifies some invariants + // related to IsValid(). + CHECK(!NoReg.IsValid()); + CHECK(!NoFPReg.IsValid()); + CHECK(!NoCPUReg.IsValid()); + + CHECK(x0.IsValid()); + CHECK(w0.IsValid()); + CHECK(x30.IsValid()); + CHECK(w30.IsValid()); + CHECK(xzr.IsValid()); + CHECK(wzr.IsValid()); + + CHECK(csp.IsValid()); + CHECK(wcsp.IsValid()); + + CHECK(d0.IsValid()); + CHECK(s0.IsValid()); + CHECK(d31.IsValid()); + CHECK(s31.IsValid()); + + CHECK(x0.IsValidRegister()); + CHECK(w0.IsValidRegister()); + CHECK(xzr.IsValidRegister()); + CHECK(wzr.IsValidRegister()); + CHECK(csp.IsValidRegister()); + CHECK(wcsp.IsValidRegister()); + CHECK(!x0.IsValidFPRegister()); + CHECK(!w0.IsValidFPRegister()); + CHECK(!xzr.IsValidFPRegister()); + CHECK(!wzr.IsValidFPRegister()); + CHECK(!csp.IsValidFPRegister()); + CHECK(!wcsp.IsValidFPRegister()); + + CHECK(d0.IsValidFPRegister()); + CHECK(s0.IsValidFPRegister()); + CHECK(!d0.IsValidRegister()); + CHECK(!s0.IsValidRegister()); + + // Test the same as before, but using CPURegister types. This shouldn't make + // any difference. + CHECK(static_cast<CPURegister>(x0).IsValid()); + CHECK(static_cast<CPURegister>(w0).IsValid()); + CHECK(static_cast<CPURegister>(x30).IsValid()); + CHECK(static_cast<CPURegister>(w30).IsValid()); + CHECK(static_cast<CPURegister>(xzr).IsValid()); + CHECK(static_cast<CPURegister>(wzr).IsValid()); + + CHECK(static_cast<CPURegister>(csp).IsValid()); + CHECK(static_cast<CPURegister>(wcsp).IsValid()); + + CHECK(static_cast<CPURegister>(d0).IsValid()); + CHECK(static_cast<CPURegister>(s0).IsValid()); + CHECK(static_cast<CPURegister>(d31).IsValid()); + CHECK(static_cast<CPURegister>(s31).IsValid()); + + CHECK(static_cast<CPURegister>(x0).IsValidRegister()); + CHECK(static_cast<CPURegister>(w0).IsValidRegister()); + CHECK(static_cast<CPURegister>(xzr).IsValidRegister()); + CHECK(static_cast<CPURegister>(wzr).IsValidRegister()); + CHECK(static_cast<CPURegister>(csp).IsValidRegister()); + CHECK(static_cast<CPURegister>(wcsp).IsValidRegister()); + CHECK(!static_cast<CPURegister>(x0).IsValidFPRegister()); + CHECK(!static_cast<CPURegister>(w0).IsValidFPRegister()); + CHECK(!static_cast<CPURegister>(xzr).IsValidFPRegister()); + CHECK(!static_cast<CPURegister>(wzr).IsValidFPRegister()); + CHECK(!static_cast<CPURegister>(csp).IsValidFPRegister()); + CHECK(!static_cast<CPURegister>(wcsp).IsValidFPRegister()); + + CHECK(static_cast<CPURegister>(d0).IsValidFPRegister()); + CHECK(static_cast<CPURegister>(s0).IsValidFPRegister()); + CHECK(!static_cast<CPURegister>(d0).IsValidRegister()); + CHECK(!static_cast<CPURegister>(s0).IsValidRegister()); +} + + +TEST(cpureglist_utils_x) { + // This test doesn't generate any code, but it verifies the behaviour of + // the CPURegList utility methods. + + // Test a list of X registers. + CPURegList test(x0, x1, x2, x3); + + CHECK(test.IncludesAliasOf(x0)); + CHECK(test.IncludesAliasOf(x1)); + CHECK(test.IncludesAliasOf(x2)); + CHECK(test.IncludesAliasOf(x3)); + CHECK(test.IncludesAliasOf(w0)); + CHECK(test.IncludesAliasOf(w1)); + CHECK(test.IncludesAliasOf(w2)); + CHECK(test.IncludesAliasOf(w3)); + + CHECK(!test.IncludesAliasOf(x4)); + CHECK(!test.IncludesAliasOf(x30)); + CHECK(!test.IncludesAliasOf(xzr)); + CHECK(!test.IncludesAliasOf(csp)); + CHECK(!test.IncludesAliasOf(w4)); + CHECK(!test.IncludesAliasOf(w30)); + CHECK(!test.IncludesAliasOf(wzr)); + CHECK(!test.IncludesAliasOf(wcsp)); + + CHECK(!test.IncludesAliasOf(d0)); + CHECK(!test.IncludesAliasOf(d1)); + CHECK(!test.IncludesAliasOf(d2)); + CHECK(!test.IncludesAliasOf(d3)); + CHECK(!test.IncludesAliasOf(s0)); + CHECK(!test.IncludesAliasOf(s1)); + CHECK(!test.IncludesAliasOf(s2)); + CHECK(!test.IncludesAliasOf(s3)); + + CHECK(!test.IsEmpty()); + + CHECK(test.type() == x0.type()); + + CHECK(test.PopHighestIndex().Is(x3)); + CHECK(test.PopLowestIndex().Is(x0)); + + CHECK(test.IncludesAliasOf(x1)); + CHECK(test.IncludesAliasOf(x2)); + CHECK(test.IncludesAliasOf(w1)); + CHECK(test.IncludesAliasOf(w2)); + CHECK(!test.IncludesAliasOf(x0)); + CHECK(!test.IncludesAliasOf(x3)); + CHECK(!test.IncludesAliasOf(w0)); + CHECK(!test.IncludesAliasOf(w3)); + + CHECK(test.PopHighestIndex().Is(x2)); + CHECK(test.PopLowestIndex().Is(x1)); + + CHECK(!test.IncludesAliasOf(x1)); + CHECK(!test.IncludesAliasOf(x2)); + CHECK(!test.IncludesAliasOf(w1)); + CHECK(!test.IncludesAliasOf(w2)); + + CHECK(test.IsEmpty()); +} + + +TEST(cpureglist_utils_w) { + // This test doesn't generate any code, but it verifies the behaviour of + // the CPURegList utility methods. + + // Test a list of W registers. + CPURegList test(w10, w11, w12, w13); + + CHECK(test.IncludesAliasOf(x10)); + CHECK(test.IncludesAliasOf(x11)); + CHECK(test.IncludesAliasOf(x12)); + CHECK(test.IncludesAliasOf(x13)); + CHECK(test.IncludesAliasOf(w10)); + CHECK(test.IncludesAliasOf(w11)); + CHECK(test.IncludesAliasOf(w12)); + CHECK(test.IncludesAliasOf(w13)); + + CHECK(!test.IncludesAliasOf(x0)); + CHECK(!test.IncludesAliasOf(x9)); + CHECK(!test.IncludesAliasOf(x14)); + CHECK(!test.IncludesAliasOf(x30)); + CHECK(!test.IncludesAliasOf(xzr)); + CHECK(!test.IncludesAliasOf(csp)); + CHECK(!test.IncludesAliasOf(w0)); + CHECK(!test.IncludesAliasOf(w9)); + CHECK(!test.IncludesAliasOf(w14)); + CHECK(!test.IncludesAliasOf(w30)); + CHECK(!test.IncludesAliasOf(wzr)); + CHECK(!test.IncludesAliasOf(wcsp)); + + CHECK(!test.IncludesAliasOf(d10)); + CHECK(!test.IncludesAliasOf(d11)); + CHECK(!test.IncludesAliasOf(d12)); + CHECK(!test.IncludesAliasOf(d13)); + CHECK(!test.IncludesAliasOf(s10)); + CHECK(!test.IncludesAliasOf(s11)); + CHECK(!test.IncludesAliasOf(s12)); + CHECK(!test.IncludesAliasOf(s13)); + + CHECK(!test.IsEmpty()); + + CHECK(test.type() == w10.type()); + + CHECK(test.PopHighestIndex().Is(w13)); + CHECK(test.PopLowestIndex().Is(w10)); + + CHECK(test.IncludesAliasOf(x11)); + CHECK(test.IncludesAliasOf(x12)); + CHECK(test.IncludesAliasOf(w11)); + CHECK(test.IncludesAliasOf(w12)); + CHECK(!test.IncludesAliasOf(x10)); + CHECK(!test.IncludesAliasOf(x13)); + CHECK(!test.IncludesAliasOf(w10)); + CHECK(!test.IncludesAliasOf(w13)); + + CHECK(test.PopHighestIndex().Is(w12)); + CHECK(test.PopLowestIndex().Is(w11)); + + CHECK(!test.IncludesAliasOf(x11)); + CHECK(!test.IncludesAliasOf(x12)); + CHECK(!test.IncludesAliasOf(w11)); + CHECK(!test.IncludesAliasOf(w12)); + + CHECK(test.IsEmpty()); +} + + +TEST(cpureglist_utils_d) { + // This test doesn't generate any code, but it verifies the behaviour of + // the CPURegList utility methods. + + // Test a list of D registers. + CPURegList test(d20, d21, d22, d23); + + CHECK(test.IncludesAliasOf(d20)); + CHECK(test.IncludesAliasOf(d21)); + CHECK(test.IncludesAliasOf(d22)); + CHECK(test.IncludesAliasOf(d23)); + CHECK(test.IncludesAliasOf(s20)); + CHECK(test.IncludesAliasOf(s21)); + CHECK(test.IncludesAliasOf(s22)); + CHECK(test.IncludesAliasOf(s23)); + + CHECK(!test.IncludesAliasOf(d0)); + CHECK(!test.IncludesAliasOf(d19)); + CHECK(!test.IncludesAliasOf(d24)); + CHECK(!test.IncludesAliasOf(d31)); + CHECK(!test.IncludesAliasOf(s0)); + CHECK(!test.IncludesAliasOf(s19)); + CHECK(!test.IncludesAliasOf(s24)); + CHECK(!test.IncludesAliasOf(s31)); + + CHECK(!test.IncludesAliasOf(x20)); + CHECK(!test.IncludesAliasOf(x21)); + CHECK(!test.IncludesAliasOf(x22)); + CHECK(!test.IncludesAliasOf(x23)); + CHECK(!test.IncludesAliasOf(w20)); + CHECK(!test.IncludesAliasOf(w21)); + CHECK(!test.IncludesAliasOf(w22)); + CHECK(!test.IncludesAliasOf(w23)); + + CHECK(!test.IncludesAliasOf(xzr)); + CHECK(!test.IncludesAliasOf(wzr)); + CHECK(!test.IncludesAliasOf(csp)); + CHECK(!test.IncludesAliasOf(wcsp)); + + CHECK(!test.IsEmpty()); + + CHECK(test.type() == d20.type()); + + CHECK(test.PopHighestIndex().Is(d23)); + CHECK(test.PopLowestIndex().Is(d20)); + + CHECK(test.IncludesAliasOf(d21)); + CHECK(test.IncludesAliasOf(d22)); + CHECK(test.IncludesAliasOf(s21)); + CHECK(test.IncludesAliasOf(s22)); + CHECK(!test.IncludesAliasOf(d20)); + CHECK(!test.IncludesAliasOf(d23)); + CHECK(!test.IncludesAliasOf(s20)); + CHECK(!test.IncludesAliasOf(s23)); + + CHECK(test.PopHighestIndex().Is(d22)); + CHECK(test.PopLowestIndex().Is(d21)); + + CHECK(!test.IncludesAliasOf(d21)); + CHECK(!test.IncludesAliasOf(d22)); + CHECK(!test.IncludesAliasOf(s21)); + CHECK(!test.IncludesAliasOf(s22)); + + CHECK(test.IsEmpty()); +} + + +TEST(cpureglist_utils_s) { + // This test doesn't generate any code, but it verifies the behaviour of + // the CPURegList utility methods. + + // Test a list of S registers. + CPURegList test(s20, s21, s22, s23); + + // The type and size mechanisms are already covered, so here we just test + // that lists of S registers alias individual D registers. + + CHECK(test.IncludesAliasOf(d20)); + CHECK(test.IncludesAliasOf(d21)); + CHECK(test.IncludesAliasOf(d22)); + CHECK(test.IncludesAliasOf(d23)); + CHECK(test.IncludesAliasOf(s20)); + CHECK(test.IncludesAliasOf(s21)); + CHECK(test.IncludesAliasOf(s22)); + CHECK(test.IncludesAliasOf(s23)); +} + + +TEST(cpureglist_utils_empty) { + // This test doesn't generate any code, but it verifies the behaviour of + // the CPURegList utility methods. + + // Test an empty list. + // Empty lists can have type and size properties. Check that we can create + // them, and that they are empty. + CPURegList reg32(CPURegister::kRegister, kWRegSize, 0); + CPURegList reg64(CPURegister::kRegister, kXRegSize, 0); + CPURegList fpreg32(CPURegister::kFPRegister, kSRegSize, 0); + CPURegList fpreg64(CPURegister::kFPRegister, kDRegSize, 0); + + CHECK(reg32.IsEmpty()); + CHECK(reg64.IsEmpty()); + CHECK(fpreg32.IsEmpty()); + CHECK(fpreg64.IsEmpty()); + + CHECK(reg32.PopLowestIndex().IsNone()); + CHECK(reg64.PopLowestIndex().IsNone()); + CHECK(fpreg32.PopLowestIndex().IsNone()); + CHECK(fpreg64.PopLowestIndex().IsNone()); + + CHECK(reg32.PopHighestIndex().IsNone()); + CHECK(reg64.PopHighestIndex().IsNone()); + CHECK(fpreg32.PopHighestIndex().IsNone()); + CHECK(fpreg64.PopHighestIndex().IsNone()); + + CHECK(reg32.IsEmpty()); + CHECK(reg64.IsEmpty()); + CHECK(fpreg32.IsEmpty()); + CHECK(fpreg64.IsEmpty()); +} + + +TEST(printf) { + INIT_V8(); + SETUP(); + START(); + + char const * test_plain_string = "Printf with no arguments.\n"; + char const * test_substring = "'This is a substring.'"; + RegisterDump before; + + // Initialize x29 to the value of the stack pointer. We will use x29 as a + // temporary stack pointer later, and initializing it in this way allows the + // RegisterDump check to pass. + __ Mov(x29, __ StackPointer()); + + // Test simple integer arguments. + __ Mov(x0, 1234); + __ Mov(x1, 0x1234); + + // Test simple floating-point arguments. + __ Fmov(d0, 1.234); + + // Test pointer (string) arguments. + __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring)); + + // Test the maximum number of arguments, and sign extension. + __ Mov(w3, 0xffffffff); + __ Mov(w4, 0xffffffff); + __ Mov(x5, 0xffffffffffffffff); + __ Mov(x6, 0xffffffffffffffff); + __ Fmov(s1, 1.234); + __ Fmov(s2, 2.345); + __ Fmov(d3, 3.456); + __ Fmov(d4, 4.567); + + // Test printing callee-saved registers. + __ Mov(x28, 0x123456789abcdef); + __ Fmov(d10, 42.0); + + // Test with three arguments. + __ Mov(x10, 3); + __ Mov(x11, 40); + __ Mov(x12, 500); + + // x8 and x9 are used by debug code in part of the macro assembler. However, + // Printf guarantees to preserve them (so we can use Printf in debug code), + // and we need to test that they are properly preserved. The above code + // shouldn't need to use them, but we initialize x8 and x9 last to be on the + // safe side. This test still assumes that none of the code from + // before->Dump() to the end of the test can clobber x8 or x9, so where + // possible we use the Assembler directly to be safe. + __ orr(x8, xzr, 0x8888888888888888); + __ orr(x9, xzr, 0x9999999999999999); + + // Check that we don't clobber any registers, except those that we explicitly + // write results into. + before.Dump(&masm); + + __ Printf(test_plain_string); // NOLINT(runtime/printf) + __ Printf("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1); + __ Printf("d0: %f\n", d0); + __ Printf("Test %%s: %s\n", x2); + __ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n" + "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n", + w3, w4, x5, x6); + __ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4); + __ Printf("0x%08" PRIx32 ", 0x%016" PRIx64 "\n", x28, x28); + __ Printf("%g\n", d10); + + // Test with a different stack pointer. + const Register old_stack_pointer = __ StackPointer(); + __ mov(x29, old_stack_pointer); + __ SetStackPointer(x29); + __ Printf("old_stack_pointer: 0x%016" PRIx64 "\n", old_stack_pointer); + __ mov(old_stack_pointer, __ StackPointer()); + __ SetStackPointer(old_stack_pointer); + + __ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12); + + END(); + RUN(); + + // We cannot easily test the output of the Printf sequences, and because + // Printf preserves all registers by default, we can't look at the number of + // bytes that were printed. However, the printf_no_preserve test should check + // that, and here we just test that we didn't clobber any registers. + ASSERT_EQUAL_REGISTERS(before); + + TEARDOWN(); +} + + +TEST(printf_no_preserve) { + INIT_V8(); + SETUP(); + START(); + + char const * test_plain_string = "Printf with no arguments.\n"; + char const * test_substring = "'This is a substring.'"; + + __ PrintfNoPreserve(test_plain_string); // NOLINT(runtime/printf) + __ Mov(x19, x0); + + // Test simple integer arguments. + __ Mov(x0, 1234); + __ Mov(x1, 0x1234); + __ PrintfNoPreserve("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1); + __ Mov(x20, x0); + + // Test simple floating-point arguments. + __ Fmov(d0, 1.234); + __ PrintfNoPreserve("d0: %f\n", d0); + __ Mov(x21, x0); + + // Test pointer (string) arguments. + __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring)); + __ PrintfNoPreserve("Test %%s: %s\n", x2); + __ Mov(x22, x0); + + // Test the maximum number of arguments, and sign extension. + __ Mov(w3, 0xffffffff); + __ Mov(w4, 0xffffffff); + __ Mov(x5, 0xffffffffffffffff); + __ Mov(x6, 0xffffffffffffffff); + __ PrintfNoPreserve("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n" + "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n", + w3, w4, x5, x6); + __ Mov(x23, x0); + + __ Fmov(s1, 1.234); + __ Fmov(s2, 2.345); + __ Fmov(d3, 3.456); + __ Fmov(d4, 4.567); + __ PrintfNoPreserve("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4); + __ Mov(x24, x0); + + // Test printing callee-saved registers. + __ Mov(x28, 0x123456789abcdef); + __ PrintfNoPreserve("0x%08" PRIx32 ", 0x%016" PRIx64 "\n", x28, x28); + __ Mov(x25, x0); + + __ Fmov(d10, 42.0); + __ PrintfNoPreserve("%g\n", d10); + __ Mov(x26, x0); + + // Test with a different stack pointer. + const Register old_stack_pointer = __ StackPointer(); + __ Mov(x29, old_stack_pointer); + __ SetStackPointer(x29); + + __ PrintfNoPreserve("old_stack_pointer: 0x%016" PRIx64 "\n", + old_stack_pointer); + __ Mov(x27, x0); + + __ Mov(old_stack_pointer, __ StackPointer()); + __ SetStackPointer(old_stack_pointer); + + // Test with three arguments. + __ Mov(x3, 3); + __ Mov(x4, 40); + __ Mov(x5, 500); + __ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5); + __ Mov(x28, x0); + + END(); + RUN(); + + // We cannot easily test the exact output of the Printf sequences, but we can + // use the return code to check that the string length was correct. + + // Printf with no arguments. + ASSERT_EQUAL_64(strlen(test_plain_string), x19); + // x0: 1234, x1: 0x00001234 + ASSERT_EQUAL_64(25, x20); + // d0: 1.234000 + ASSERT_EQUAL_64(13, x21); + // Test %s: 'This is a substring.' + ASSERT_EQUAL_64(32, x22); + // w3(uint32): 4294967295 + // w4(int32): -1 + // x5(uint64): 18446744073709551615 + // x6(int64): -1 + ASSERT_EQUAL_64(23 + 14 + 33 + 14, x23); + // %f: 1.234000 + // %g: 2.345 + // %e: 3.456000e+00 + // %E: 4.567000E+00 + ASSERT_EQUAL_64(13 + 10 + 17 + 17, x24); + // 0x89abcdef, 0x0123456789abcdef + ASSERT_EQUAL_64(31, x25); + // 42 + ASSERT_EQUAL_64(3, x26); + // old_stack_pointer: 0x00007fb037ae2370 + // Note: This is an example value, but the field width is fixed here so the + // string length is still predictable. + ASSERT_EQUAL_64(38, x27); + // 3=3, 4=40, 5=500 + ASSERT_EQUAL_64(17, x28); + + TEARDOWN(); +} + + +// This is a V8-specific test. +static void CopyFieldsHelper(CPURegList temps) { + static const uint64_t kLiteralBase = 0x0100001000100101UL; + static const uint64_t src[] = {kLiteralBase * 1, + kLiteralBase * 2, + kLiteralBase * 3, + kLiteralBase * 4, + kLiteralBase * 5, + kLiteralBase * 6, + kLiteralBase * 7, + kLiteralBase * 8, + kLiteralBase * 9, + kLiteralBase * 10, + kLiteralBase * 11}; + static const uint64_t src_tagged = + reinterpret_cast<uint64_t>(src) + kHeapObjectTag; + + static const unsigned kTestCount = sizeof(src) / sizeof(src[0]) + 1; + uint64_t* dst[kTestCount]; + uint64_t dst_tagged[kTestCount]; + + // The first test will be to copy 0 fields. The destination (and source) + // should not be accessed in any way. + dst[0] = NULL; + dst_tagged[0] = kHeapObjectTag; + + // Allocate memory for each other test. Each test <n> will have <n> fields. + // This is intended to exercise as many paths in CopyFields as possible. + for (unsigned i = 1; i < kTestCount; i++) { + dst[i] = new uint64_t[i]; + memset(dst[i], 0, i * sizeof(kLiteralBase)); + dst_tagged[i] = reinterpret_cast<uint64_t>(dst[i]) + kHeapObjectTag; + } + + SETUP(); + START(); + + __ Mov(x0, dst_tagged[0]); + __ Mov(x1, 0); + __ CopyFields(x0, x1, temps, 0); + for (unsigned i = 1; i < kTestCount; i++) { + __ Mov(x0, dst_tagged[i]); + __ Mov(x1, src_tagged); + __ CopyFields(x0, x1, temps, i); + } + + END(); + RUN(); + TEARDOWN(); + + for (unsigned i = 1; i < kTestCount; i++) { + for (unsigned j = 0; j < i; j++) { + CHECK(src[j] == dst[i][j]); + } + delete [] dst[i]; + } +} + + +// This is a V8-specific test. +TEST(copyfields) { + INIT_V8(); + CopyFieldsHelper(CPURegList(x10)); + CopyFieldsHelper(CPURegList(x10, x11)); + CopyFieldsHelper(CPURegList(x10, x11, x12)); + CopyFieldsHelper(CPURegList(x10, x11, x12, x13)); +} + + +static void DoSmiAbsTest(int32_t value, bool must_fail = false) { + SETUP(); + + START(); + Label end, slow; + __ Mov(x2, 0xc001c0de); + __ Mov(x1, value); + __ SmiTag(x1); + __ SmiAbs(x1, &slow); + __ SmiUntag(x1); + __ B(&end); + + __ Bind(&slow); + __ Mov(x2, 0xbad); + + __ Bind(&end); + END(); + + RUN(); + + if (must_fail) { + // We tested an invalid conversion. The code must have jump on slow. + ASSERT_EQUAL_64(0xbad, x2); + } else { + // The conversion is valid, check the result. + int32_t result = (value >= 0) ? value : -value; + ASSERT_EQUAL_64(result, x1); + + // Check that we didn't jump on slow. + ASSERT_EQUAL_64(0xc001c0de, x2); + } + + TEARDOWN(); +} + + +TEST(smi_abs) { + INIT_V8(); + // Simple and edge cases. + DoSmiAbsTest(0); + DoSmiAbsTest(0x12345); + DoSmiAbsTest(0x40000000); + DoSmiAbsTest(0x7fffffff); + DoSmiAbsTest(-1); + DoSmiAbsTest(-12345); + DoSmiAbsTest(0x80000001); + + // Check that the most negative SMI is detected. + DoSmiAbsTest(0x80000000, true); +} + + +TEST(blr_lr) { + // A simple test to check that the simulator correcty handle "blr lr". + INIT_V8(); + SETUP(); + + START(); + Label target; + Label end; + + __ Mov(x0, 0x0); + __ Adr(lr, &target); + + __ Blr(lr); + __ Mov(x0, 0xdeadbeef); + __ B(&end); + + __ Bind(&target); + __ Mov(x0, 0xc001c0de); + + __ Bind(&end); + END(); + + RUN(); + + ASSERT_EQUAL_64(0xc001c0de, x0); + + TEARDOWN(); +} + + +TEST(barriers) { + // Generate all supported barriers, this is just a smoke test + INIT_V8(); + SETUP(); + + START(); + + // DMB + __ Dmb(FullSystem, BarrierAll); + __ Dmb(FullSystem, BarrierReads); + __ Dmb(FullSystem, BarrierWrites); + __ Dmb(FullSystem, BarrierOther); + + __ Dmb(InnerShareable, BarrierAll); + __ Dmb(InnerShareable, BarrierReads); + __ Dmb(InnerShareable, BarrierWrites); + __ Dmb(InnerShareable, BarrierOther); + + __ Dmb(NonShareable, BarrierAll); + __ Dmb(NonShareable, BarrierReads); + __ Dmb(NonShareable, BarrierWrites); + __ Dmb(NonShareable, BarrierOther); + + __ Dmb(OuterShareable, BarrierAll); + __ Dmb(OuterShareable, BarrierReads); + __ Dmb(OuterShareable, BarrierWrites); + __ Dmb(OuterShareable, BarrierOther); + + // DSB + __ Dsb(FullSystem, BarrierAll); + __ Dsb(FullSystem, BarrierReads); + __ Dsb(FullSystem, BarrierWrites); + __ Dsb(FullSystem, BarrierOther); + + __ Dsb(InnerShareable, BarrierAll); + __ Dsb(InnerShareable, BarrierReads); + __ Dsb(InnerShareable, BarrierWrites); + __ Dsb(InnerShareable, BarrierOther); + + __ Dsb(NonShareable, BarrierAll); + __ Dsb(NonShareable, BarrierReads); + __ Dsb(NonShareable, BarrierWrites); + __ Dsb(NonShareable, BarrierOther); + + __ Dsb(OuterShareable, BarrierAll); + __ Dsb(OuterShareable, BarrierReads); + __ Dsb(OuterShareable, BarrierWrites); + __ Dsb(OuterShareable, BarrierOther); + + // ISB + __ Isb(); + + END(); + + RUN(); + + TEARDOWN(); +} + + +TEST(call_no_relocation) { + Address call_start; + Address return_address; + + INIT_V8(); + SETUP(); + + START(); + + Label function; + Label test; + + __ B(&test); + + __ Bind(&function); + __ Mov(x0, 0x1); + __ Ret(); + + __ Bind(&test); + __ Mov(x0, 0x0); + __ Push(lr, xzr); + { + Assembler::BlockConstPoolScope scope(&masm); + call_start = buf + __ pc_offset(); + __ Call(buf + function.pos(), RelocInfo::NONE64); + return_address = buf + __ pc_offset(); + } + __ Pop(xzr, lr); + END(); + + RUN(); + + ASSERT_EQUAL_64(1, x0); + + // The return_address_from_call_start function doesn't currently encounter any + // non-relocatable sequences, so we check it here to make sure it works. + // TODO(jbramley): Once Crankshaft is complete, decide if we need to support + // non-relocatable calls at all. + CHECK(return_address == + Assembler::return_address_from_call_start(call_start)); + + TEARDOWN(); +} + + +static void AbsHelperX(int64_t value) { + int64_t expected; + + SETUP(); + START(); + + Label fail; + Label done; + + __ Mov(x0, 0); + __ Mov(x1, value); + + if (value != kXMinInt) { + expected = labs(value); + + Label next; + // The result is representable. + __ Abs(x10, x1); + __ Abs(x11, x1, &fail); + __ Abs(x12, x1, &fail, &next); + __ Bind(&next); + __ Abs(x13, x1, NULL, &done); + } else { + // labs is undefined for kXMinInt but our implementation in the + // MacroAssembler will return kXMinInt in such a case. + expected = kXMinInt; + + Label next; + // The result is not representable. + __ Abs(x10, x1); + __ Abs(x11, x1, NULL, &fail); + __ Abs(x12, x1, &next, &fail); + __ Bind(&next); + __ Abs(x13, x1, &done); + } + + __ Bind(&fail); + __ Mov(x0, -1); + + __ Bind(&done); + + END(); + RUN(); + + ASSERT_EQUAL_64(0, x0); + ASSERT_EQUAL_64(value, x1); + ASSERT_EQUAL_64(expected, x10); + ASSERT_EQUAL_64(expected, x11); + ASSERT_EQUAL_64(expected, x12); + ASSERT_EQUAL_64(expected, x13); + + TEARDOWN(); +} + + +static void AbsHelperW(int32_t value) { + int32_t expected; + + SETUP(); + START(); + + Label fail; + Label done; + + __ Mov(w0, 0); + // TODO(jbramley): The cast is needed to avoid a sign-extension bug in VIXL. + // Once it is fixed, we should remove the cast. + __ Mov(w1, static_cast<uint32_t>(value)); + + if (value != kWMinInt) { + expected = abs(value); + + Label next; + // The result is representable. + __ Abs(w10, w1); + __ Abs(w11, w1, &fail); + __ Abs(w12, w1, &fail, &next); + __ Bind(&next); + __ Abs(w13, w1, NULL, &done); + } else { + // abs is undefined for kWMinInt but our implementation in the + // MacroAssembler will return kWMinInt in such a case. + expected = kWMinInt; + + Label next; + // The result is not representable. + __ Abs(w10, w1); + __ Abs(w11, w1, NULL, &fail); + __ Abs(w12, w1, &next, &fail); + __ Bind(&next); + __ Abs(w13, w1, &done); + } + + __ Bind(&fail); + __ Mov(w0, -1); + + __ Bind(&done); + + END(); + RUN(); + + ASSERT_EQUAL_32(0, w0); + ASSERT_EQUAL_32(value, w1); + ASSERT_EQUAL_32(expected, w10); + ASSERT_EQUAL_32(expected, w11); + ASSERT_EQUAL_32(expected, w12); + ASSERT_EQUAL_32(expected, w13); + + TEARDOWN(); +} + + +TEST(abs) { + INIT_V8(); + AbsHelperX(0); + AbsHelperX(42); + AbsHelperX(-42); + AbsHelperX(kXMinInt); + AbsHelperX(kXMaxInt); + + AbsHelperW(0); + AbsHelperW(42); + AbsHelperW(-42); + AbsHelperW(kWMinInt); + AbsHelperW(kWMaxInt); +} diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc index 69ea6f4742..b21dc34dc4 100644 --- a/deps/v8/test/cctest/test-assembler-arm.cc +++ b/deps/v8/test/cctest/test-assembler-arm.cc @@ -1439,6 +1439,72 @@ TEST(17) { } +#define TEST_SDIV(expected_, dividend_, divisor_) \ + t.dividend = dividend_; \ + t.divisor = divisor_; \ + t.result = 0; \ + dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); \ + CHECK_EQ(expected_, t.result); + + +TEST(18) { + // Test the sdiv. + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + typedef struct { + uint32_t dividend; + uint32_t divisor; + uint32_t result; + } T; + T t; + + Assembler assm(isolate, NULL, 0); + + if (CpuFeatures::IsSupported(SUDIV)) { + CpuFeatureScope scope(&assm, SUDIV); + + __ mov(r3, Operand(r0)); + + __ ldr(r0, MemOperand(r3, OFFSET_OF(T, dividend))); + __ ldr(r1, MemOperand(r3, OFFSET_OF(T, divisor))); + + __ sdiv(r2, r0, r1); + __ str(r2, MemOperand(r3, OFFSET_OF(T, result))); + + __ bx(lr); + + CodeDesc desc; + assm.GetCode(&desc); + Object* code = isolate->heap()->CreateCode( + desc, + Code::ComputeFlags(Code::STUB), + Handle<Code>())->ToObjectChecked(); + CHECK(code->IsCode()); +#ifdef DEBUG + Code::cast(code)->Print(); +#endif + F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry()); + Object* dummy; + TEST_SDIV(1073741824, kMinInt, -2); + TEST_SDIV(kMinInt, kMinInt, -1); + TEST_SDIV(5, 10, 2); + TEST_SDIV(3, 10, 3); + TEST_SDIV(-5, 10, -2); + TEST_SDIV(-3, 10, -3); + TEST_SDIV(-5, -10, 2); + TEST_SDIV(-3, -10, 3); + TEST_SDIV(5, -10, -2); + TEST_SDIV(3, -10, -3); + USE(dummy); + } +} + + +#undef TEST_SDIV + + TEST(code_relative_offset) { // Test extracting the offset of a label from the beginning of the code // in a register. diff --git a/deps/v8/test/cctest/test-assembler-ia32.cc b/deps/v8/test/cctest/test-assembler-ia32.cc index d40156841e..db28231d63 100644 --- a/deps/v8/test/cctest/test-assembler-ia32.cc +++ b/deps/v8/test/cctest/test-assembler-ia32.cc @@ -522,7 +522,7 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { F0 f = FUNCTION_CAST<F0>(Code::cast(code)->entry()); int res = f(); - args.GetReturnValue().Set(v8::Integer::New(res)); + args.GetReturnValue().Set(v8::Integer::New(CcTest::isolate(), res)); } @@ -534,8 +534,10 @@ TEST(StackAlignmentForSSE2) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); - global_template->Set(v8_str("do_sse2"), v8::FunctionTemplate::New(DoSSE2)); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); + global_template->Set(v8_str("do_sse2"), + v8::FunctionTemplate::New(isolate, DoSSE2)); LocalContext env(NULL, global_template); CompileRun( @@ -548,7 +550,7 @@ TEST(StackAlignmentForSSE2) { v8::Local<v8::Function>::Cast(global_object->Get(v8_str("foo"))); int32_t vec[ELEMENT_COUNT] = { -1, 1, 1, 1 }; - v8::Local<v8::Array> v8_vec = v8::Array::New(ELEMENT_COUNT); + v8::Local<v8::Array> v8_vec = v8::Array::New(isolate, ELEMENT_COUNT); for (int i = 0; i < ELEMENT_COUNT; i++) { v8_vec->Set(i, v8_num(vec[i])); } @@ -599,4 +601,44 @@ TEST(AssemblerIa32Extractps) { } +typedef int (*F8)(float x, float y); +TEST(AssemblerIa32SSE) { + CcTest::InitializeVM(); + if (!CpuFeatures::IsSupported(SSE2)) return; + + Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); + HandleScope scope(isolate); + v8::internal::byte buffer[256]; + MacroAssembler assm(isolate, buffer, sizeof buffer); + { + CpuFeatureScope fscope(&assm, SSE2); + __ movss(xmm0, Operand(esp, kPointerSize)); + __ movss(xmm1, Operand(esp, 2 * kPointerSize)); + __ shufps(xmm0, xmm0, 0x0); + __ shufps(xmm1, xmm1, 0x0); + __ movaps(xmm2, xmm1); + __ addps(xmm2, xmm0); + __ mulps(xmm2, xmm1); + __ subps(xmm2, xmm0); + __ divps(xmm2, xmm1); + __ cvttss2si(eax, xmm2); + __ ret(0); + } + + CodeDesc desc; + assm.GetCode(&desc); + Code* code = Code::cast(isolate->heap()->CreateCode( + desc, + Code::ComputeFlags(Code::STUB), + Handle<Code>())->ToObjectChecked()); + CHECK(code->IsCode()); +#ifdef OBJECT_PRINT + Code::cast(code)->Print(); +#endif + + F8 f = FUNCTION_CAST<F8>(Code::cast(code)->entry()); + CHECK_EQ(2, f(1.0, 2.0)); +} + + #undef __ diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc index e8e724c052..534c4cf0ae 100644 --- a/deps/v8/test/cctest/test-assembler-mips.cc +++ b/deps/v8/test/cctest/test-assembler-mips.cc @@ -765,10 +765,8 @@ TEST(MIPS10) { double b; int32_t dbl_mant; int32_t dbl_exp; - int32_t long_hi; - int32_t long_lo; - int32_t b_long_hi; - int32_t b_long_lo; + int32_t word; + int32_t b_word; } T; T t; @@ -786,18 +784,14 @@ TEST(MIPS10) { __ sw(t1, MemOperand(a0, OFFSET_OF(T, dbl_exp))); // Convert double in f0 to long, save hi/lo parts. - __ cvt_l_d(f0, f0); - __ mfc1(t0, f0); // f0 has LS 32 bits of long. - __ mfc1(t1, f1); // f1 has MS 32 bits of long. - __ sw(t0, MemOperand(a0, OFFSET_OF(T, long_lo))); - __ sw(t1, MemOperand(a0, OFFSET_OF(T, long_hi))); + __ cvt_w_d(f0, f0); + __ mfc1(t0, f0); // f0 has a 32-bits word. + __ sw(t0, MemOperand(a0, OFFSET_OF(T, word))); // Convert the b long integers to double b. - __ lw(t0, MemOperand(a0, OFFSET_OF(T, b_long_lo))); - __ lw(t1, MemOperand(a0, OFFSET_OF(T, b_long_hi))); - __ mtc1(t0, f8); // f8 has LS 32-bits. - __ mtc1(t1, f9); // f9 has MS 32-bits. - __ cvt_d_l(f10, f8); + __ lw(t0, MemOperand(a0, OFFSET_OF(T, b_word))); + __ mtc1(t0, f8); // f8 has a 32-bits word. + __ cvt_d_w(f10, f8); __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, b))); __ jr(ra); @@ -811,18 +805,16 @@ TEST(MIPS10) { Handle<Code>())->ToObjectChecked(); CHECK(code->IsCode()); F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry()); - t.a = 2.147483647e9; // 0x7fffffff -> 0x41DFFFFFFFC00000 as double. - t.b_long_hi = 0x000000ff; // 0xFF00FF00FF -> 0x426FE01FE01FE000 as double. - t.b_long_lo = 0x00ff00ff; + t.a = 2.147483646e+09; // 0x7FFFFFFE -> 0xFF80000041DFFFFF as double. + t.b_word = 0x0ff00ff0; // 0x0FF00FF0 -> 0x as double. Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(0x41DFFFFF, t.dbl_exp); - CHECK_EQ(0xFFC00000, t.dbl_mant); - CHECK_EQ(0, t.long_hi); - CHECK_EQ(0x7fffffff, t.long_lo); - // 0xFF00FF00FF -> 1.095233372415e12. - CHECK_EQ(1.095233372415e12, t.b); + CHECK_EQ(0xFF800000, t.dbl_mant); + CHECK_EQ(0X7FFFFFFE, t.word); + // 0x0FF00FF0 -> 2.6739096+e08 + CHECK_EQ(2.6739096e08, t.b); } } diff --git a/deps/v8/test/cctest/test-assembler-x64.cc b/deps/v8/test/cctest/test-assembler-x64.cc index cd1ed2823b..4fa5ffecb4 100644 --- a/deps/v8/test/cctest/test-assembler-x64.cc +++ b/deps/v8/test/cctest/test-assembler-x64.cc @@ -179,10 +179,10 @@ TEST(AssemblerX64XchglOperations) { Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); __ movq(rax, Operand(arg1, 0)); - __ movq(rbx, Operand(arg2, 0)); - __ xchgl(rax, rbx); + __ movq(r11, Operand(arg2, 0)); + __ xchgl(rax, r11); __ movq(Operand(arg1, 0), rax); - __ movq(Operand(arg2, 0), rbx); + __ movq(Operand(arg2, 0), r11); __ ret(0); CodeDesc desc; @@ -279,8 +279,8 @@ TEST(AssemblerX64TestlOperations) { // Set rax with the ZF flag of the testl instruction. Label done; __ movq(rax, Immediate(1)); - __ movq(rbx, Operand(arg2, 0)); - __ testl(Operand(arg1, 0), rbx); + __ movq(r11, Operand(arg2, 0)); + __ testl(Operand(arg1, 0), r11); __ j(zero, &done, Label::kNear); __ movq(rax, Immediate(0)); __ bind(&done); @@ -604,7 +604,7 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { F0 f = FUNCTION_CAST<F0>(code->entry()); int res = f(); - args.GetReturnValue().Set(v8::Integer::New(res)); + args.GetReturnValue().Set(v8::Integer::New(CcTest::isolate(), res)); } @@ -614,8 +614,10 @@ TEST(StackAlignmentForSSE2) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); - global_template->Set(v8_str("do_sse2"), v8::FunctionTemplate::New(DoSSE2)); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); + global_template->Set(v8_str("do_sse2"), + v8::FunctionTemplate::New(isolate, DoSSE2)); LocalContext env(NULL, global_template); CompileRun( @@ -628,7 +630,7 @@ TEST(StackAlignmentForSSE2) { v8::Local<v8::Function>::Cast(global_object->Get(v8_str("foo"))); int32_t vec[ELEMENT_COUNT] = { -1, 1, 1, 1 }; - v8::Local<v8::Array> v8_vec = v8::Array::New(ELEMENT_COUNT); + v8::Local<v8::Array> v8_vec = v8::Array::New(isolate, ELEMENT_COUNT); for (int i = 0; i < ELEMENT_COUNT; i++) { v8_vec->Set(i, v8_num(vec[i])); } @@ -676,4 +678,38 @@ TEST(AssemblerX64Extractps) { } +typedef int (*F6)(float x, float y); +TEST(AssemblerX64SSE) { + CcTest::InitializeVM(); + + Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); + HandleScope scope(isolate); + v8::internal::byte buffer[256]; + MacroAssembler assm(isolate, buffer, sizeof buffer); + { + __ shufps(xmm0, xmm0, 0x0); // brocast first argument + __ shufps(xmm1, xmm1, 0x0); // brocast second argument + __ movaps(xmm2, xmm1); + __ addps(xmm2, xmm0); + __ mulps(xmm2, xmm1); + __ subps(xmm2, xmm0); + __ divps(xmm2, xmm1); + __ cvttss2si(rax, xmm2); + __ ret(0); + } + + CodeDesc desc; + assm.GetCode(&desc); + Code* code = Code::cast(isolate->heap()->CreateCode( + desc, + Code::ComputeFlags(Code::STUB), + Handle<Code>())->ToObjectChecked()); + CHECK(code->IsCode()); +#ifdef OBJECT_PRINT + Code::cast(code)->Print(); +#endif + + F6 f = FUNCTION_CAST<F6>(Code::cast(code)->entry()); + CHECK_EQ(2, f(1.0, 2.0)); +} #undef __ diff --git a/deps/v8/test/cctest/test-ast.cc b/deps/v8/test/cctest/test-ast.cc index 299f2a8960..d6431371aa 100644 --- a/deps/v8/test/cctest/test-ast.cc +++ b/deps/v8/test/cctest/test-ast.cc @@ -41,7 +41,7 @@ TEST(List) { Isolate* isolate = CcTest::i_isolate(); Zone zone(isolate); - AstNodeFactory<AstNullVisitor> factory(isolate, &zone); + AstNodeFactory<AstNullVisitor> factory(&zone); AstNode* node = factory.NewEmptyStatement(RelocInfo::kNoPosition); list->Add(node); CHECK_EQ(1, list->length()); diff --git a/deps/v8/test/cctest/test-code-stubs-a64.cc b/deps/v8/test/cctest/test-code-stubs-a64.cc new file mode 100644 index 0000000000..9416b19dda --- /dev/null +++ b/deps/v8/test/cctest/test-code-stubs-a64.cc @@ -0,0 +1,188 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Rrdistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Rrdistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Rrdistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <stdlib.h> + +#include "v8.h" + +#include "cctest.h" +#include "code-stubs.h" +#include "test-code-stubs.h" +#include "factory.h" +#include "macro-assembler.h" +#include "platform.h" +#include "simulator.h" + +using namespace v8::internal; + +#define __ masm. + +ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, + Register source_reg, + Register destination_reg, + bool inline_fastpath) { + // Allocate an executable page of memory. + size_t actual_size = 2 * Assembler::kMinimalBufferSize; + byte* buffer = static_cast<byte*>(OS::Allocate(actual_size, + &actual_size, + true)); + CHECK(buffer); + HandleScope handles(isolate); + MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size)); + DoubleToIStub stub(source_reg, destination_reg, 0, true, inline_fastpath); + + byte* start = stub.GetCode(isolate)->instruction_start(); + Label done; + + __ SetStackPointer(csp); + __ PushCalleeSavedRegisters(); + __ Mov(jssp, csp); + __ SetStackPointer(jssp); + + // Push the double argument. + __ Push(d0); + if (!source_reg.is(jssp)) { + __ Mov(source_reg, jssp); + } + + // Save registers make sure they don't get clobbered. + int source_reg_offset = kDoubleSize; + int reg_num = 0; + for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) { + Register reg = Register::from_code(reg_num); + if (!reg.is(destination_reg)) { + __ Push(reg); + source_reg_offset += kPointerSize; + } + } + + // Re-push the double argument. + __ Push(d0); + + // Call through to the actual stub + if (inline_fastpath) { + __ Ldr(d0, MemOperand(source_reg)); + __ TryInlineTruncateDoubleToI(destination_reg, d0, &done); + if (destination_reg.is(source_reg)) { + // Restore clobbered source_reg. + __ add(source_reg, jssp, Operand(source_reg_offset)); + } + } + __ Call(start, RelocInfo::EXTERNAL_REFERENCE); + __ bind(&done); + + __ Drop(1, kDoubleSize); + + // // Make sure no registers have been unexpectedly clobbered + for (--reg_num; reg_num >= 0; --reg_num) { + Register reg = Register::from_code(reg_num); + if (!reg.is(destination_reg)) { + __ Pop(ip0); + __ cmp(reg, ip0); + __ Assert(eq, kRegisterWasClobbered); + } + } + + __ Drop(1, kDoubleSize); + + if (!destination_reg.is(x0)) + __ Mov(x0, destination_reg); + + // Restore callee save registers. + __ Mov(csp, jssp); + __ SetStackPointer(csp); + __ PopCalleeSavedRegisters(); + + __ Ret(); + + CodeDesc desc; + masm.GetCode(&desc); + CPU::FlushICache(buffer, actual_size); + return (reinterpret_cast<ConvertDToIFunc>( + reinterpret_cast<intptr_t>(buffer))); +} + +#undef __ + + +static Isolate* GetIsolateFrom(LocalContext* context) { + return reinterpret_cast<Isolate*>((*context)->GetIsolate()); +} + + +int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func, + double from) { +#ifdef USE_SIMULATOR + Simulator::CallArgument args[] = { + Simulator::CallArgument(from), + Simulator::CallArgument::End() + }; + return Simulator::current(Isolate::Current())->CallInt64( + FUNCTION_ADDR(func), args); +#else + return (*func)(from); +#endif +} + + +TEST(ConvertDToI) { + CcTest::InitializeVM(); + LocalContext context; + Isolate* isolate = GetIsolateFrom(&context); + HandleScope scope(isolate); + +#if DEBUG + // Verify that the tests actually work with the C version. In the release + // code, the compiler optimizes it away because it's all constant, but does it + // wrong, triggering an assert on gcc. + RunAllTruncationTests(&ConvertDToICVersion); +#endif + + Register source_registers[] = {jssp, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, + x10, x11, x12, x13, x14, x15, x18, x19, x20, + x21, x22, x23, x24}; + Register dest_registers[] = {x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, + x12, x13, x14, x15, x18, x19, x20, x21, x22, x23, + x24}; + + for (size_t s = 0; s < sizeof(source_registers) / sizeof(Register); s++) { + for (size_t d = 0; d < sizeof(dest_registers) / sizeof(Register); d++) { + RunAllTruncationTests( + RunGeneratedCodeCallWrapper, + MakeConvertDToIFuncTrampoline(isolate, + source_registers[s], + dest_registers[d], + false)); + RunAllTruncationTests( + RunGeneratedCodeCallWrapper, + MakeConvertDToIFuncTrampoline(isolate, + source_registers[s], + dest_registers[d], + true)); + } + } +} diff --git a/deps/v8/test/cctest/test-code-stubs-arm.cc b/deps/v8/test/cctest/test-code-stubs-arm.cc index 54eaa58318..53cdd16130 100644 --- a/deps/v8/test/cctest/test-code-stubs-arm.cc +++ b/deps/v8/test/cctest/test-code-stubs-arm.cc @@ -53,7 +53,6 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, CHECK(buffer); HandleScope handles(isolate); MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size)); - masm.set_allow_stub_calls(false); DoubleToIStub stub(source_reg, destination_reg, 0, true, inline_fastpath); byte* start = stub.GetCode(isolate)->instruction_start(); diff --git a/deps/v8/test/cctest/test-code-stubs-ia32.cc b/deps/v8/test/cctest/test-code-stubs-ia32.cc index 3f621758e3..c206a0102a 100644 --- a/deps/v8/test/cctest/test-code-stubs-ia32.cc +++ b/deps/v8/test/cctest/test-code-stubs-ia32.cc @@ -53,7 +53,6 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, CHECK(buffer); HandleScope handles(isolate); MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size)); - assm.set_allow_stub_calls(false); int offset = source_reg.is(esp) ? 0 : (HeapNumber::kValueOffset - kSmiTagSize); DoubleToIStub stub(source_reg, destination_reg, offset, true); @@ -73,7 +72,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, // Save registers make sure they don't get clobbered. int reg_num = 0; for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) { - Register reg = Register::from_code(reg_num); + Register reg = Register::FromAllocationIndex(reg_num); if (!reg.is(esp) && !reg.is(ebp) && !reg.is(destination_reg)) { __ push(reg); param_offset += kPointerSize; @@ -91,7 +90,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, // Make sure no registers have been unexpectedly clobbered for (--reg_num; reg_num >= 0; --reg_num) { - Register reg = Register::from_code(reg_num); + Register reg = Register::FromAllocationIndex(reg_num); if (!reg.is(esp) && !reg.is(ebp) && !reg.is(destination_reg)) { __ cmp(reg, MemOperand(esp, 0)); __ Assert(equal, kRegisterWasClobbered); diff --git a/deps/v8/test/cctest/test-code-stubs-mips.cc b/deps/v8/test/cctest/test-code-stubs-mips.cc new file mode 100644 index 0000000000..8dce89694e --- /dev/null +++ b/deps/v8/test/cctest/test-code-stubs-mips.cc @@ -0,0 +1,188 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Rrdistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Rrdistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Rrdistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <stdlib.h> + +#include "v8.h" + +#include "cctest.h" +#include "code-stubs.h" +#include "test-code-stubs.h" +#include "mips/constants-mips.h" +#include "factory.h" +#include "macro-assembler.h" +#include "platform.h" +#include "simulator.h" + +using namespace v8::internal; + +#define __ masm. + +ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, + Register source_reg, + Register destination_reg, + bool inline_fastpath) { + // Allocate an executable page of memory. + size_t actual_size; + byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + &actual_size, + true)); + CHECK(buffer); + HandleScope handles(isolate); + MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size)); + DoubleToIStub stub(source_reg, destination_reg, 0, true, inline_fastpath); + + byte* start = stub.GetCode(isolate)->instruction_start(); + Label done; + + // Save callee save registers. + __ MultiPush(kCalleeSaved | ra.bit()); + + // For softfp, move the input value into f12. + if (IsMipsSoftFloatABI) { + __ Move(f12, a0, a1); + } + // Push the double argument. + __ Subu(sp, sp, Operand(kDoubleSize)); + __ sdc1(f12, MemOperand(sp)); + __ Move(source_reg, sp); + + // Save registers make sure they don't get clobbered. + int source_reg_offset = kDoubleSize; + int reg_num = 2; + for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) { + Register reg = Register::from_code(reg_num); + if (!reg.is(destination_reg)) { + __ push(reg); + source_reg_offset += kPointerSize; + } + } + + // Re-push the double argument. + __ Subu(sp, sp, Operand(kDoubleSize)); + __ sdc1(f12, MemOperand(sp)); + + // Call through to the actual stub + if (inline_fastpath) { + __ ldc1(f12, MemOperand(source_reg)); + __ TryInlineTruncateDoubleToI(destination_reg, f12, &done); + if (destination_reg.is(source_reg) && !source_reg.is(sp)) { + // Restore clobbered source_reg. + __ Addu(source_reg, sp, Operand(source_reg_offset)); + } + } + __ Call(start, RelocInfo::EXTERNAL_REFERENCE); + __ bind(&done); + + __ Addu(sp, sp, Operand(kDoubleSize)); + + // Make sure no registers have been unexpectedly clobbered + for (--reg_num; reg_num >= 2; --reg_num) { + Register reg = Register::from_code(reg_num); + if (!reg.is(destination_reg)) { + __ lw(at, MemOperand(sp, 0)); + __ Assert(eq, kRegisterWasClobbered, reg, Operand(at)); + __ Addu(sp, sp, Operand(kPointerSize)); + } + } + + __ Addu(sp, sp, Operand(kDoubleSize)); + + __ Move(v0, destination_reg); + Label ok; + __ Branch(&ok, eq, v0, Operand(zero_reg)); + __ bind(&ok); + + // Restore callee save registers. + __ MultiPop(kCalleeSaved | ra.bit()); + + Label ok1; + __ Branch(&ok1, eq, v0, Operand(zero_reg)); + __ bind(&ok1); + __ Ret(); + + CodeDesc desc; + masm.GetCode(&desc); + CPU::FlushICache(buffer, actual_size); + return (reinterpret_cast<ConvertDToIFunc>( + reinterpret_cast<intptr_t>(buffer))); +} + +#undef __ + + +static Isolate* GetIsolateFrom(LocalContext* context) { + return reinterpret_cast<Isolate*>((*context)->GetIsolate()); +} + + +int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func, + double from) { +#ifdef USE_SIMULATOR + Simulator::current(Isolate::Current())->CallFP(FUNCTION_ADDR(func), from, 0.); + return Simulator::current(Isolate::Current())->get_register(v0.code()); +#else + return (*func)(from); +#endif +} + + +TEST(ConvertDToI) { + CcTest::InitializeVM(); + LocalContext context; + Isolate* isolate = GetIsolateFrom(&context); + HandleScope scope(isolate); + +#if DEBUG + // Verify that the tests actually work with the C version. In the release + // code, the compiler optimizes it away because it's all constant, but does it + // wrong, triggering an assert on gcc. + RunAllTruncationTests(&ConvertDToICVersion); +#endif + + Register source_registers[] = { + sp, v0, v1, a0, a1, a2, a3, t0, t1, t2, t3, t4, t5}; + Register dest_registers[] = { + v0, v1, a0, a1, a2, a3, t0, t1, t2, t3, t4, t5}; + + for (size_t s = 0; s < sizeof(source_registers) / sizeof(Register); s++) { + for (size_t d = 0; d < sizeof(dest_registers) / sizeof(Register); d++) { + RunAllTruncationTests( + RunGeneratedCodeCallWrapper, + MakeConvertDToIFuncTrampoline(isolate, + source_registers[s], + dest_registers[d], + false)); + RunAllTruncationTests( + RunGeneratedCodeCallWrapper, + MakeConvertDToIFuncTrampoline(isolate, + source_registers[s], + dest_registers[d], + true)); + } + } +} diff --git a/deps/v8/test/cctest/test-code-stubs-x64.cc b/deps/v8/test/cctest/test-code-stubs-x64.cc index 4af5b45d7c..6b3a12ccc8 100644 --- a/deps/v8/test/cctest/test-code-stubs-x64.cc +++ b/deps/v8/test/cctest/test-code-stubs-x64.cc @@ -52,7 +52,6 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, CHECK(buffer); HandleScope handles(isolate); MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size)); - assm.set_allow_stub_calls(false); int offset = source_reg.is(rsp) ? 0 : (HeapNumber::kValueOffset - kSmiTagSize); DoubleToIStub stub(source_reg, destination_reg, offset, true); @@ -65,21 +64,25 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, __ push(rdi); if (!source_reg.is(rsp)) { - __ lea(source_reg, MemOperand(rsp, -8 * kPointerSize - offset)); + // The argument we pass to the stub is not a heap number, but instead + // stack-allocated and offset-wise made to look like a heap number for + // the stub. We create that "heap number" after pushing all allocatable + // registers. + int double_argument_slot = + (Register::NumAllocatableRegisters() - 1) * kPointerSize + kDoubleSize; + __ lea(source_reg, MemOperand(rsp, -double_argument_slot - offset)); } - int param_offset = 7 * kPointerSize; // Save registers make sure they don't get clobbered. int reg_num = 0; for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) { - Register reg = Register::from_code(reg_num); + Register reg = Register::FromAllocationIndex(reg_num); if (!reg.is(rsp) && !reg.is(rbp) && !reg.is(destination_reg)) { __ push(reg); - param_offset += kPointerSize; } } - // Re-push the double argument + // Put the double argument into the designated double argument slot. __ subq(rsp, Immediate(kDoubleSize)); __ movsd(MemOperand(rsp, 0), xmm0); @@ -90,7 +93,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, // Make sure no registers have been unexpectedly clobbered for (--reg_num; reg_num >= 0; --reg_num) { - Register reg = Register::from_code(reg_num); + Register reg = Register::FromAllocationIndex(reg_num); if (!reg.is(rsp) && !reg.is(rbp) && !reg.is(destination_reg)) { __ cmpq(reg, MemOperand(rsp, 0)); __ Assert(equal, kRegisterWasClobbered); diff --git a/deps/v8/test/cctest/test-code-stubs.cc b/deps/v8/test/cctest/test-code-stubs.cc index db00e9ac5a..999febf777 100644 --- a/deps/v8/test/cctest/test-code-stubs.cc +++ b/deps/v8/test/cctest/test-code-stubs.cc @@ -49,6 +49,9 @@ int STDCALL ConvertDToICVersion(double d) { int32_t exponent = (((exponent_bits & shifted_mask) >> (Double::kPhysicalSignificandSize - 32)) - HeapNumber::kExponentBias); + if (exponent < 0) { + return 0; + } uint32_t unsigned_exponent = static_cast<uint32_t>(exponent); int result = 0; uint32_t max_exponent = @@ -113,10 +116,27 @@ void RunAllTruncationTests(ConvertDToICallWrapper callWrapper, RunOneTruncationTest(Infinity, 0); RunOneTruncationTest(-NaN, 0); RunOneTruncationTest(-Infinity, 0); - - RunOneTruncationTest(4.5036e+15, 0x1635E000); + RunOneTruncationTest(4.94065645841e-324, 0); + RunOneTruncationTest(-4.94065645841e-324, 0); + + RunOneTruncationTest(0.9999999999999999, 0); + RunOneTruncationTest(-0.9999999999999999, 0); + RunOneTruncationTest(4294967296.0, 0); + RunOneTruncationTest(-4294967296.0, 0); + RunOneTruncationTest(9223372036854775000.0, 4294966272.0); + RunOneTruncationTest(-9223372036854775000.0, -4294966272.0); + RunOneTruncationTest(4.5036e+15, 372629504); RunOneTruncationTest(-4.5036e+15, -372629504); + RunOneTruncationTest(287524199.5377777, 0x11234567); + RunOneTruncationTest(-287524199.5377777, -0x11234567); + RunOneTruncationTest(2300193596.302222, 2300193596.0); + RunOneTruncationTest(-2300193596.302222, -2300193596.0); + RunOneTruncationTest(4600387192.604444, 305419896); + RunOneTruncationTest(-4600387192.604444, -305419896); + RunOneTruncationTest(4823855600872397.0, 1737075661); + RunOneTruncationTest(-4823855600872397.0, -1737075661); + RunOneTruncationTest(4503603922337791.0, -1); RunOneTruncationTest(-4503603922337791.0, 1); RunOneTruncationTest(4503601774854143.0, 2147483647); @@ -134,10 +154,19 @@ void RunAllTruncationTests(ConvertDToICallWrapper callWrapper, RunOneTruncationTest(4.8357078901445341e+24, -1073741824); RunOneTruncationTest(-4.8357078901445341e+24, 1073741824); + RunOneTruncationTest(2147483647.0, 2147483647.0); + RunOneTruncationTest(-2147483648.0, -2147483648.0); RunOneTruncationTest(9.6714111686030497e+24, -2147483648.0); RunOneTruncationTest(-9.6714111686030497e+24, -2147483648.0); RunOneTruncationTest(9.6714157802890681e+24, -2147483648.0); RunOneTruncationTest(-9.6714157802890681e+24, -2147483648.0); + RunOneTruncationTest(1.9342813113834065e+25, 2147483648.0); + RunOneTruncationTest(-1.9342813113834065e+25, 2147483648.0); + + RunOneTruncationTest(3.868562622766813e+25, 0); + RunOneTruncationTest(-3.868562622766813e+25, 0); + RunOneTruncationTest(1.7976931348623157e+308, 0); + RunOneTruncationTest(-1.7976931348623157e+308, 0); } #undef NaN diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc index 9fd68e5222..ae414d7843 100644 --- a/deps/v8/test/cctest/test-compiler.cc +++ b/deps/v8/test/cctest/test-compiler.cc @@ -32,52 +32,10 @@ #include "compiler.h" #include "disasm.h" -#include "disassembler.h" -#include "execution.h" -#include "factory.h" -#include "platform.h" #include "cctest.h" using namespace v8::internal; -// --- P r i n t E x t e n s i o n --- - -class PrintExtension : public v8::Extension { - public: - PrintExtension() : v8::Extension("v8/print", kSource) { } - virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( - v8::Handle<v8::String> name); - static void Print(const v8::FunctionCallbackInfo<v8::Value>& args); - private: - static const char* kSource; -}; - - -const char* PrintExtension::kSource = "native function print();"; - - -v8::Handle<v8::FunctionTemplate> PrintExtension::GetNativeFunction( - v8::Handle<v8::String> str) { - return v8::FunctionTemplate::New(PrintExtension::Print); -} - - -void PrintExtension::Print(const v8::FunctionCallbackInfo<v8::Value>& args) { - for (int i = 0; i < args.Length(); i++) { - if (i != 0) printf(" "); - v8::HandleScope scope(args.GetIsolate()); - v8::String::Utf8Value str(args[i]); - if (*str == NULL) return; - printf("%s", *str); - } - printf("\n"); -} - - -static PrintExtension kPrintExtension; -v8::DeclareExtension kPrintExtensionDeclaration(&kPrintExtension); - - static MaybeObject* GetGlobalProperty(const char* name) { Isolate* isolate = CcTest::i_isolate(); Handle<String> internalized_name = @@ -92,7 +50,8 @@ static void SetGlobalProperty(const char* name, Object* value) { Handle<String> internalized_name = isolate->factory()->InternalizeUtf8String(name); Handle<JSObject> global(isolate->context()->global_object()); - SetProperty(isolate, global, internalized_name, object, NONE, kNonStrictMode); + Runtime::SetObjectProperty(isolate, global, internalized_name, object, NONE, + kNonStrictMode); } @@ -101,16 +60,15 @@ static Handle<JSFunction> Compile(const char* source) { Handle<String> source_code( isolate->factory()->NewStringFromUtf8(CStrVector(source))); Handle<SharedFunctionInfo> shared_function = - Compiler::Compile(source_code, - Handle<String>(), - 0, - 0, - false, - Handle<Context>(isolate->native_context()), - NULL, - NULL, - Handle<String>::null(), - NOT_NATIVES_CODE); + Compiler::CompileScript(source_code, + Handle<String>(), + 0, + 0, + false, + Handle<Context>(isolate->native_context()), + NULL, NULL, + Handle<String>::null(), + NOT_NATIVES_CODE); return isolate->factory()->NewFunctionFromSharedFunctionInfo( shared_function, isolate->native_context()); } @@ -274,6 +232,7 @@ TEST(UncaughtThrow) { // | JS | // | C-to-JS | TEST(C2JSFrames) { + FLAG_expose_gc = true; v8::HandleScope scope(CcTest::isolate()); v8::Local<v8::Context> context = CcTest::NewContext(PRINT_EXTENSION | GC_EXTENSION); @@ -330,7 +289,8 @@ TEST(Regression236) { TEST(GetScriptLineNumber) { LocalContext context; v8::HandleScope scope(CcTest::isolate()); - v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); + v8::ScriptOrigin origin = + v8::ScriptOrigin(v8::String::NewFromUtf8(CcTest::isolate(), "test")); const char function_f[] = "function f() {}"; const int max_rows = 1000; const int buffer_size = max_rows + sizeof(function_f); @@ -342,10 +302,12 @@ TEST(GetScriptLineNumber) { if (i > 0) buffer[i - 1] = '\n'; OS::MemCopy(&buffer[i], function_f, sizeof(function_f) - 1); - v8::Handle<v8::String> script_body = v8::String::New(buffer.start()); + v8::Handle<v8::String> script_body = + v8::String::NewFromUtf8(CcTest::isolate(), buffer.start()); v8::Script::Compile(script_body, &origin)->Run(); - v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - context->Global()->Get(v8::String::New("f"))); + v8::Local<v8::Function> f = + v8::Local<v8::Function>::Cast(context->Global()->Get( + v8::String::NewFromUtf8(CcTest::isolate(), "f"))); CHECK_EQ(i, f->GetScriptLineNumber()); } } @@ -363,7 +325,8 @@ TEST(OptimizedCodeSharing) { v8::HandleScope scope(CcTest::isolate()); for (int i = 0; i < 10; i++) { LocalContext env; - env->Global()->Set(v8::String::New("x"), v8::Integer::New(i)); + env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), + v8::Integer::New(CcTest::isolate(), i)); CompileRun("function MakeClosure() {" " return function() { return x; };" "}" diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc index 9ef307c6f4..3bba514391 100644 --- a/deps/v8/test/cctest/test-cpu-profiler.cc +++ b/deps/v8/test/cctest/test-cpu-profiler.cc @@ -31,6 +31,7 @@ #include "cpu-profiler-inl.h" #include "cctest.h" #include "platform.h" +#include "profiler-extension.h" #include "smart-pointers.h" #include "utils.h" #include "../include/v8-profiler.h" @@ -59,10 +60,6 @@ TEST(StartStop) { } -static inline i::Address ToAddress(int n) { - return reinterpret_cast<i::Address>(n); -} - static void EnqueueTickSampleEvent(ProfilerEventsProcessor* proc, i::Address frame1, i::Address frame2 = NULL, @@ -142,12 +139,12 @@ TEST(CodeEvents) { i::Code* args4_code = CreateCode(&env); CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap()); - profiles->StartProfiling("", 1, false); + profiles->StartProfiling("", false); ProfileGenerator generator(profiles); SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor( &generator, NULL, TimeDelta::FromMicroseconds(100))); processor->Start(); - CpuProfiler profiler(isolate, profiles, &generator, *processor); + CpuProfiler profiler(isolate, profiles, &generator, processor.get()); // Enqueue code creation events. const char* aaa_str = "aaa"; @@ -162,7 +159,7 @@ TEST(CodeEvents) { profiler.CodeCreateEvent(i::Logger::STUB_TAG, args4_code, 4); // Enqueue a tick event to enable code events processing. - EnqueueTickSampleEvent(*processor, aaa_code->address()); + EnqueueTickSampleEvent(processor.get(), aaa_code->address()); processor->StopSynchronously(); @@ -204,24 +201,24 @@ TEST(TickEvents) { i::Code* frame3_code = CreateCode(&env); CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap()); - profiles->StartProfiling("", 1, false); + profiles->StartProfiling("", false); ProfileGenerator generator(profiles); SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor( &generator, NULL, TimeDelta::FromMicroseconds(100))); processor->Start(); - CpuProfiler profiler(isolate, profiles, &generator, *processor); + CpuProfiler profiler(isolate, profiles, &generator, processor.get()); profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame1_code, "bbb"); profiler.CodeCreateEvent(i::Logger::STUB_TAG, frame2_code, 5); profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame3_code, "ddd"); - EnqueueTickSampleEvent(*processor, frame1_code->instruction_start()); + EnqueueTickSampleEvent(processor.get(), frame1_code->instruction_start()); EnqueueTickSampleEvent( - *processor, + processor.get(), frame2_code->instruction_start() + frame2_code->ExecutableSize() / 2, frame1_code->instruction_start() + frame2_code->ExecutableSize() / 2); EnqueueTickSampleEvent( - *processor, + processor.get(), frame3_code->instruction_end() - 1, frame2_code->instruction_end() - 1, frame1_code->instruction_end() - 1); @@ -273,12 +270,12 @@ TEST(Issue1398) { i::Code* code = CreateCode(&env); CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap()); - profiles->StartProfiling("", 1, false); + profiles->StartProfiling("", false); ProfileGenerator generator(profiles); SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor( &generator, NULL, TimeDelta::FromMicroseconds(100))); processor->Start(); - CpuProfiler profiler(isolate, profiles, &generator, *processor); + CpuProfiler profiler(isolate, profiles, &generator, processor.get()); profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, code, "bbb"); @@ -336,16 +333,17 @@ TEST(DeleteAllCpuProfiles) { } -static const v8::CpuProfile* FindCpuProfile(v8::CpuProfiler* profiler, - unsigned uid) { - int length = profiler->GetProfileCount(); +static bool FindCpuProfile(v8::CpuProfiler* v8profiler, + const v8::CpuProfile* v8profile) { + i::CpuProfiler* profiler = reinterpret_cast<i::CpuProfiler*>(v8profiler); + const i::CpuProfile* profile = + reinterpret_cast<const i::CpuProfile*>(v8profile); + int length = profiler->GetProfilesCount(); for (int i = 0; i < length; i++) { - const v8::CpuProfile* profile = profiler->GetCpuProfile(i); - if (profile->GetUid() == uid) { - return profile; - } + if (profile == profiler->GetProfile(i)) + return true; } - return NULL; + return false; } @@ -353,46 +351,38 @@ TEST(DeleteCpuProfile) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); + i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(cpu_profiler); - CHECK_EQ(0, cpu_profiler->GetProfileCount()); - v8::Local<v8::String> name1 = v8::String::New("1"); + CHECK_EQ(0, iprofiler->GetProfilesCount()); + v8::Local<v8::String> name1 = v8::String::NewFromUtf8(env->GetIsolate(), "1"); cpu_profiler->StartCpuProfiling(name1); const v8::CpuProfile* p1 = cpu_profiler->StopCpuProfiling(name1); CHECK_NE(NULL, p1); - CHECK_EQ(1, cpu_profiler->GetProfileCount()); - unsigned uid1 = p1->GetUid(); - CHECK_EQ(p1, FindCpuProfile(cpu_profiler, uid1)); + CHECK_EQ(1, iprofiler->GetProfilesCount()); + CHECK(FindCpuProfile(cpu_profiler, p1)); const_cast<v8::CpuProfile*>(p1)->Delete(); - CHECK_EQ(0, cpu_profiler->GetProfileCount()); - CHECK_EQ(NULL, FindCpuProfile(cpu_profiler, uid1)); + CHECK_EQ(0, iprofiler->GetProfilesCount()); - v8::Local<v8::String> name2 = v8::String::New("2"); + v8::Local<v8::String> name2 = v8::String::NewFromUtf8(env->GetIsolate(), "2"); cpu_profiler->StartCpuProfiling(name2); const v8::CpuProfile* p2 = cpu_profiler->StopCpuProfiling(name2); CHECK_NE(NULL, p2); - CHECK_EQ(1, cpu_profiler->GetProfileCount()); - unsigned uid2 = p2->GetUid(); - CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2)); - CHECK_EQ(p2, FindCpuProfile(cpu_profiler, uid2)); - CHECK_EQ(NULL, FindCpuProfile(cpu_profiler, uid1)); - v8::Local<v8::String> name3 = v8::String::New("3"); + CHECK_EQ(1, iprofiler->GetProfilesCount()); + CHECK(FindCpuProfile(cpu_profiler, p2)); + v8::Local<v8::String> name3 = v8::String::NewFromUtf8(env->GetIsolate(), "3"); cpu_profiler->StartCpuProfiling(name3); const v8::CpuProfile* p3 = cpu_profiler->StopCpuProfiling(name3); CHECK_NE(NULL, p3); - CHECK_EQ(2, cpu_profiler->GetProfileCount()); - unsigned uid3 = p3->GetUid(); - CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3)); - CHECK_EQ(p3, FindCpuProfile(cpu_profiler, uid3)); - CHECK_EQ(NULL, FindCpuProfile(cpu_profiler, uid1)); + CHECK_EQ(2, iprofiler->GetProfilesCount()); + CHECK_NE(p2, p3); + CHECK(FindCpuProfile(cpu_profiler, p3)); + CHECK(FindCpuProfile(cpu_profiler, p2)); const_cast<v8::CpuProfile*>(p2)->Delete(); - CHECK_EQ(1, cpu_profiler->GetProfileCount()); - CHECK_EQ(NULL, FindCpuProfile(cpu_profiler, uid2)); - CHECK_EQ(p3, FindCpuProfile(cpu_profiler, uid3)); + CHECK_EQ(1, iprofiler->GetProfilesCount()); + CHECK(!FindCpuProfile(cpu_profiler, p2)); + CHECK(FindCpuProfile(cpu_profiler, p3)); const_cast<v8::CpuProfile*>(p3)->Delete(); - CHECK_EQ(0, cpu_profiler->GetProfileCount()); - CHECK_EQ(NULL, FindCpuProfile(cpu_profiler, uid3)); - CHECK_EQ(NULL, FindCpuProfile(cpu_profiler, uid2)); - CHECK_EQ(NULL, FindCpuProfile(cpu_profiler, uid1)); + CHECK_EQ(0, iprofiler->GetProfilesCount()); } @@ -401,7 +391,8 @@ TEST(ProfileStartEndTime) { v8::HandleScope scope(env->GetIsolate()); v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - v8::Local<v8::String> profile_name = v8::String::New("test"); + v8::Local<v8::String> profile_name = + v8::String::NewFromUtf8(env->GetIsolate(), "test"); cpu_profiler->StartCpuProfiling(profile_name); const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name); CHECK(profile->GetStartTime() <= profile->GetEndTime()); @@ -409,11 +400,12 @@ TEST(ProfileStartEndTime) { static const v8::CpuProfile* RunProfiler( - LocalContext& env, v8::Handle<v8::Function> function, + v8::Handle<v8::Context> env, v8::Handle<v8::Function> function, v8::Handle<v8::Value> argv[], int argc, unsigned min_js_samples) { v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - v8::Local<v8::String> profile_name = v8::String::New("my_profile"); + v8::Local<v8::String> profile_name = + v8::String::NewFromUtf8(env->GetIsolate(), "my_profile"); cpu_profiler->StartCpuProfiling(profile_name); @@ -460,10 +452,11 @@ static void CheckChildrenNames(const v8::CpuProfileNode* node, } -static const v8::CpuProfileNode* FindChild(const v8::CpuProfileNode* node, +static const v8::CpuProfileNode* FindChild(v8::Isolate* isolate, + const v8::CpuProfileNode* node, const char* name) { int count = node->GetChildrenCount(); - v8::Handle<v8::String> nameHandle = v8::String::New(name); + v8::Handle<v8::String> nameHandle = v8::String::NewFromUtf8(isolate, name); for (int i = 0; i < count; i++) { const v8::CpuProfileNode* child = node->GetChild(i); if (nameHandle->Equals(child->GetFunctionName())) return child; @@ -472,9 +465,10 @@ static const v8::CpuProfileNode* FindChild(const v8::CpuProfileNode* node, } -static const v8::CpuProfileNode* GetChild(const v8::CpuProfileNode* node, +static const v8::CpuProfileNode* GetChild(v8::Isolate* isolate, + const v8::CpuProfileNode* node, const char* name) { - const v8::CpuProfileNode* result = FindChild(node, name); + const v8::CpuProfileNode* result = FindChild(isolate, node, name); if (!result) { char buffer[100]; i::OS::SNPrintF(Vector<char>(buffer, ARRAY_SIZE(buffer)), @@ -485,11 +479,12 @@ static const v8::CpuProfileNode* GetChild(const v8::CpuProfileNode* node, } -static void CheckSimpleBranch(const v8::CpuProfileNode* node, +static void CheckSimpleBranch(v8::Isolate* isolate, + const v8::CpuProfileNode* node, const char* names[], int length) { for (int i = 0; i < length; i++) { const char* name = names[i]; - node = GetChild(node, name); + node = GetChild(isolate, node, name); int expectedChildrenCount = (i == length - 1) ? 0 : 1; CHECK_EQ(expectedChildrenCount, node->GetChildrenCount()); } @@ -549,39 +544,48 @@ TEST(CollectCpuProfile) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Script::Compile(v8::String::New(cpu_profiler_test_source))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + cpu_profiler_test_source))->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("start"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start"))); int32_t profiling_interval_ms = 200; - v8::Handle<v8::Value> args[] = { v8::Integer::New(profiling_interval_ms) }; + v8::Handle<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), profiling_interval_ms) + }; const v8::CpuProfile* profile = - RunProfiler(env, function, args, ARRAY_SIZE(args), 200); + RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 200); function->Call(env->Global(), ARRAY_SIZE(args), args); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); ScopedVector<v8::Handle<v8::String> > names(3); - names[0] = v8::String::New(ProfileGenerator::kGarbageCollectorEntryName); - names[1] = v8::String::New(ProfileGenerator::kProgramEntryName); - names[2] = v8::String::New("start"); + names[0] = v8::String::NewFromUtf8( + env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName); + names[1] = v8::String::NewFromUtf8(env->GetIsolate(), + ProfileGenerator::kProgramEntryName); + names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start"); CheckChildrenNames(root, names); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); + const v8::CpuProfileNode* startNode = + GetChild(env->GetIsolate(), root, "start"); CHECK_EQ(1, startNode->GetChildrenCount()); - const v8::CpuProfileNode* fooNode = GetChild(startNode, "foo"); + const v8::CpuProfileNode* fooNode = + GetChild(env->GetIsolate(), startNode, "foo"); CHECK_EQ(3, fooNode->GetChildrenCount()); const char* barBranch[] = { "bar", "delay", "loop" }; - CheckSimpleBranch(fooNode, barBranch, ARRAY_SIZE(barBranch)); + CheckSimpleBranch(env->GetIsolate(), fooNode, barBranch, + ARRAY_SIZE(barBranch)); const char* bazBranch[] = { "baz", "delay", "loop" }; - CheckSimpleBranch(fooNode, bazBranch, ARRAY_SIZE(bazBranch)); + CheckSimpleBranch(env->GetIsolate(), fooNode, bazBranch, + ARRAY_SIZE(bazBranch)); const char* delayBranch[] = { "delay", "loop" }; - CheckSimpleBranch(fooNode, delayBranch, ARRAY_SIZE(delayBranch)); + CheckSimpleBranch(env->GetIsolate(), fooNode, delayBranch, + ARRAY_SIZE(delayBranch)); - v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } @@ -610,41 +614,47 @@ TEST(SampleWhenFrameIsNotSetup) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Script::Compile(v8::String::New(cpu_profiler_test_source2))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8( + env->GetIsolate(), cpu_profiler_test_source2))->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("start"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start"))); int32_t repeat_count = 100; #if defined(USE_SIMULATOR) // Simulators are much slower. repeat_count = 1; #endif - v8::Handle<v8::Value> args[] = { v8::Integer::New(repeat_count) }; + v8::Handle<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), repeat_count) + }; const v8::CpuProfile* profile = - RunProfiler(env, function, args, ARRAY_SIZE(args), 100); + RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); ScopedVector<v8::Handle<v8::String> > names(3); - names[0] = v8::String::New(ProfileGenerator::kGarbageCollectorEntryName); - names[1] = v8::String::New(ProfileGenerator::kProgramEntryName); - names[2] = v8::String::New("start"); + names[0] = v8::String::NewFromUtf8( + env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName); + names[1] = v8::String::NewFromUtf8(env->GetIsolate(), + ProfileGenerator::kProgramEntryName); + names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start"); CheckChildrenNames(root, names); - const v8::CpuProfileNode* startNode = FindChild(root, "start"); + const v8::CpuProfileNode* startNode = + FindChild(env->GetIsolate(), root, "start"); // On slow machines there may be no meaningfull samples at all, skip the // check there. if (startNode && startNode->GetChildrenCount() > 0) { CHECK_EQ(1, startNode->GetChildrenCount()); - const v8::CpuProfileNode* delayNode = GetChild(startNode, "delay"); + const v8::CpuProfileNode* delayNode = + GetChild(env->GetIsolate(), startNode, "delay"); if (delayNode->GetChildrenCount() > 0) { CHECK_EQ(1, delayNode->GetChildrenCount()); - GetChild(delayNode, "loop"); + GetChild(env->GetIsolate(), delayNode, "loop"); } } - v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } @@ -710,38 +720,43 @@ class TestApiCallbacks { // code. TEST(NativeAccessorUninitializedIC) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - - v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New(); + v8::Local<v8::FunctionTemplate> func_template = + v8::FunctionTemplate::New(isolate); v8::Local<v8::ObjectTemplate> instance_template = func_template->InstanceTemplate(); TestApiCallbacks accessors(100); - v8::Local<v8::External> data = v8::External::New(&accessors); + v8::Local<v8::External> data = + v8::External::New(isolate, &accessors); instance_template->SetAccessor( - v8::String::New("foo"), &TestApiCallbacks::Getter, - &TestApiCallbacks::Setter, data); + v8::String::NewFromUtf8(isolate, "foo"), + &TestApiCallbacks::Getter, &TestApiCallbacks::Setter, data); v8::Local<v8::Function> func = func_template->GetFunction(); v8::Local<v8::Object> instance = func->NewInstance(); - env->Global()->Set(v8::String::New("instance"), instance); + env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"), + instance); - v8::Script::Compile(v8::String::New(native_accessor_test_source))->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(isolate, native_accessor_test_source)) + ->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("start"))); + env->Global()->Get(v8::String::NewFromUtf8(isolate, "start"))); int32_t repeat_count = 1; - v8::Handle<v8::Value> args[] = { v8::Integer::New(repeat_count) }; + v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) }; const v8::CpuProfile* profile = - RunProfiler(env, function, args, ARRAY_SIZE(args), 180); + RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 180); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); - GetChild(startNode, "get foo"); - GetChild(startNode, "set foo"); + const v8::CpuProfileNode* startNode = + GetChild(isolate, root, "start"); + GetChild(isolate, startNode, "get foo"); + GetChild(isolate, startNode, "set foo"); - v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } @@ -750,48 +765,55 @@ TEST(NativeAccessorUninitializedIC) { // hot and to trigger optimizations. TEST(NativeAccessorMonomorphicIC) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); - - v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New(); + v8::Local<v8::FunctionTemplate> func_template = + v8::FunctionTemplate::New(isolate); v8::Local<v8::ObjectTemplate> instance_template = func_template->InstanceTemplate(); TestApiCallbacks accessors(1); - v8::Local<v8::External> data = v8::External::New(&accessors); + v8::Local<v8::External> data = + v8::External::New(isolate, &accessors); instance_template->SetAccessor( - v8::String::New("foo"), &TestApiCallbacks::Getter, - &TestApiCallbacks::Setter, data); + v8::String::NewFromUtf8(isolate, "foo"), + &TestApiCallbacks::Getter, &TestApiCallbacks::Setter, data); v8::Local<v8::Function> func = func_template->GetFunction(); v8::Local<v8::Object> instance = func->NewInstance(); - env->Global()->Set(v8::String::New("instance"), instance); + env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"), + instance); - v8::Script::Compile(v8::String::New(native_accessor_test_source))->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(isolate, native_accessor_test_source)) + ->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("start"))); + env->Global()->Get(v8::String::NewFromUtf8(isolate, "start"))); { // Make sure accessors ICs are in monomorphic state before starting // profiling. accessors.set_warming_up(true); int32_t warm_up_iterations = 3; - v8::Handle<v8::Value> args[] = { v8::Integer::New(warm_up_iterations) }; + v8::Handle<v8::Value> args[] = { + v8::Integer::New(isolate, warm_up_iterations) + }; function->Call(env->Global(), ARRAY_SIZE(args), args); accessors.set_warming_up(false); } int32_t repeat_count = 100; - v8::Handle<v8::Value> args[] = { v8::Integer::New(repeat_count) }; + v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) }; const v8::CpuProfile* profile = - RunProfiler(env, function, args, ARRAY_SIZE(args), 200); + RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 200); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); - GetChild(startNode, "get foo"); - GetChild(startNode, "set foo"); + const v8::CpuProfileNode* startNode = + GetChild(isolate, root, "start"); + GetChild(isolate, startNode, "get foo"); + GetChild(isolate, startNode, "set foo"); - v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } @@ -804,85 +826,105 @@ static const char* native_method_test_source = "function start(count) {\n" TEST(NativeMethodUninitializedIC) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); TestApiCallbacks callbacks(100); - v8::Local<v8::External> data = v8::External::New(&callbacks); + v8::Local<v8::External> data = + v8::External::New(isolate, &callbacks); - v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New(); - func_template->SetClassName(v8::String::New("Test_InstanceCostructor")); + v8::Local<v8::FunctionTemplate> func_template = + v8::FunctionTemplate::New(isolate); + func_template->SetClassName( + v8::String::NewFromUtf8(isolate, "Test_InstanceCostructor")); v8::Local<v8::ObjectTemplate> proto_template = func_template->PrototypeTemplate(); - v8::Local<v8::Signature> signature = v8::Signature::New(func_template); - proto_template->Set(v8::String::New("fooMethod"), v8::FunctionTemplate::New( - &TestApiCallbacks::Callback, data, signature, 0)); + v8::Local<v8::Signature> signature = + v8::Signature::New(isolate, func_template); + proto_template->Set(v8::String::NewFromUtf8(isolate, "fooMethod"), + v8::FunctionTemplate::New(isolate, + &TestApiCallbacks::Callback, + data, signature, 0)); v8::Local<v8::Function> func = func_template->GetFunction(); v8::Local<v8::Object> instance = func->NewInstance(); - env->Global()->Set(v8::String::New("instance"), instance); + env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"), + instance); - v8::Script::Compile(v8::String::New(native_method_test_source))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8( + isolate, native_method_test_source))->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("start"))); + env->Global()->Get(v8::String::NewFromUtf8(isolate, "start"))); int32_t repeat_count = 1; - v8::Handle<v8::Value> args[] = { v8::Integer::New(repeat_count) }; + v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) }; const v8::CpuProfile* profile = - RunProfiler(env, function, args, ARRAY_SIZE(args), 100); + RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); - GetChild(startNode, "fooMethod"); + const v8::CpuProfileNode* startNode = + GetChild(isolate, root, "start"); + GetChild(isolate, startNode, "fooMethod"); - v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } TEST(NativeMethodMonomorphicIC) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); TestApiCallbacks callbacks(1); - v8::Local<v8::External> data = v8::External::New(&callbacks); + v8::Local<v8::External> data = + v8::External::New(isolate, &callbacks); - v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New(); - func_template->SetClassName(v8::String::New("Test_InstanceCostructor")); + v8::Local<v8::FunctionTemplate> func_template = + v8::FunctionTemplate::New(isolate); + func_template->SetClassName( + v8::String::NewFromUtf8(isolate, "Test_InstanceCostructor")); v8::Local<v8::ObjectTemplate> proto_template = func_template->PrototypeTemplate(); - v8::Local<v8::Signature> signature = v8::Signature::New(func_template); - proto_template->Set(v8::String::New("fooMethod"), v8::FunctionTemplate::New( - &TestApiCallbacks::Callback, data, signature, 0)); + v8::Local<v8::Signature> signature = + v8::Signature::New(isolate, func_template); + proto_template->Set(v8::String::NewFromUtf8(isolate, "fooMethod"), + v8::FunctionTemplate::New(isolate, + &TestApiCallbacks::Callback, + data, signature, 0)); v8::Local<v8::Function> func = func_template->GetFunction(); v8::Local<v8::Object> instance = func->NewInstance(); - env->Global()->Set(v8::String::New("instance"), instance); + env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"), + instance); - v8::Script::Compile(v8::String::New(native_method_test_source))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8( + isolate, native_method_test_source))->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("start"))); + env->Global()->Get(v8::String::NewFromUtf8(isolate, "start"))); { // Make sure method ICs are in monomorphic state before starting // profiling. callbacks.set_warming_up(true); int32_t warm_up_iterations = 3; - v8::Handle<v8::Value> args[] = { v8::Integer::New(warm_up_iterations) }; + v8::Handle<v8::Value> args[] = { + v8::Integer::New(isolate, warm_up_iterations) + }; function->Call(env->Global(), ARRAY_SIZE(args), args); callbacks.set_warming_up(false); } int32_t repeat_count = 100; - v8::Handle<v8::Value> args[] = { v8::Integer::New(repeat_count) }; + v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) }; const v8::CpuProfile* profile = - RunProfiler(env, function, args, ARRAY_SIZE(args), 100); + RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - GetChild(root, "start"); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); - GetChild(startNode, "fooMethod"); + GetChild(isolate, root, "start"); + const v8::CpuProfileNode* startNode = + GetChild(isolate, root, "start"); + GetChild(isolate, startNode, "fooMethod"); - v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } @@ -904,28 +946,34 @@ TEST(BoundFunctionCall) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Script::Compile(v8::String::New(bound_function_test_source))->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), bound_function_test_source)) + ->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("start"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start"))); int32_t duration_ms = 100; - v8::Handle<v8::Value> args[] = { v8::Integer::New(duration_ms) }; + v8::Handle<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), duration_ms) + }; const v8::CpuProfile* profile = - RunProfiler(env, function, args, ARRAY_SIZE(args), 100); + RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); ScopedVector<v8::Handle<v8::String> > names(3); - names[0] = v8::String::New(ProfileGenerator::kGarbageCollectorEntryName); - names[1] = v8::String::New(ProfileGenerator::kProgramEntryName); - names[2] = v8::String::New("start"); + names[0] = v8::String::NewFromUtf8( + env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName); + names[1] = v8::String::NewFromUtf8(env->GetIsolate(), + ProfileGenerator::kProgramEntryName); + names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start"); // Don't allow |foo| node to be at the top level. CheckChildrenNames(root, names); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); - GetChild(startNode, "foo"); + const v8::CpuProfileNode* startNode = + GetChild(env->GetIsolate(), root, "start"); + GetChild(env->GetIsolate(), startNode, "foo"); - v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } @@ -960,22 +1008,28 @@ TEST(FunctionCallSample) { // Collect garbage that might have be generated while installing extensions. CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); - v8::Script::Compile(v8::String::New(call_function_test_source))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8( + env->GetIsolate(), call_function_test_source))->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("start"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start"))); int32_t duration_ms = 100; - v8::Handle<v8::Value> args[] = { v8::Integer::New(duration_ms) }; + v8::Handle<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), duration_ms) + }; const v8::CpuProfile* profile = - RunProfiler(env, function, args, ARRAY_SIZE(args), 100); + RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); { ScopedVector<v8::Handle<v8::String> > names(4); - names[0] = v8::String::New(ProfileGenerator::kGarbageCollectorEntryName); - names[1] = v8::String::New(ProfileGenerator::kProgramEntryName); - names[2] = v8::String::New("start"); - names[3] = v8::String::New(i::ProfileGenerator::kUnresolvedFunctionName); + names[0] = v8::String::NewFromUtf8( + env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName); + names[1] = v8::String::NewFromUtf8(env->GetIsolate(), + ProfileGenerator::kProgramEntryName); + names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start"); + names[3] = v8::String::NewFromUtf8( + env->GetIsolate(), i::ProfileGenerator::kUnresolvedFunctionName); // Don't allow |bar| and |call| nodes to be at the top level. CheckChildrenNames(root, names); } @@ -984,25 +1038,25 @@ TEST(FunctionCallSample) { // won't be |start| node in the profiles. bool is_gc_stress_testing = (i::FLAG_gc_interval != -1) || i::FLAG_stress_compaction; - const v8::CpuProfileNode* startNode = FindChild(root, "start"); + const v8::CpuProfileNode* startNode = + FindChild(env->GetIsolate(), root, "start"); CHECK(is_gc_stress_testing || startNode); if (startNode) { ScopedVector<v8::Handle<v8::String> > names(2); - names[0] = v8::String::New("bar"); - names[1] = v8::String::New("call"); + names[0] = v8::String::NewFromUtf8(env->GetIsolate(), "bar"); + names[1] = v8::String::NewFromUtf8(env->GetIsolate(), "call"); CheckChildrenNames(startNode, names); } - const v8::CpuProfileNode* unresolvedNode = - FindChild(root, i::ProfileGenerator::kUnresolvedFunctionName); + const v8::CpuProfileNode* unresolvedNode = FindChild( + env->GetIsolate(), root, i::ProfileGenerator::kUnresolvedFunctionName); if (unresolvedNode) { ScopedVector<v8::Handle<v8::String> > names(1); - names[0] = v8::String::New("call"); + names[0] = v8::String::NewFromUtf8(env->GetIsolate(), "call"); CheckChildrenNames(unresolvedNode, names); } - v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } @@ -1035,54 +1089,63 @@ TEST(FunctionApplySample) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Script::Compile(v8::String::New(function_apply_test_source))->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), function_apply_test_source)) + ->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("start"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start"))); int32_t duration_ms = 100; - v8::Handle<v8::Value> args[] = { v8::Integer::New(duration_ms) }; + v8::Handle<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), duration_ms) + }; const v8::CpuProfile* profile = - RunProfiler(env, function, args, ARRAY_SIZE(args), 100); + RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); { ScopedVector<v8::Handle<v8::String> > names(3); - names[0] = v8::String::New(ProfileGenerator::kGarbageCollectorEntryName); - names[1] = v8::String::New(ProfileGenerator::kProgramEntryName); - names[2] = v8::String::New("start"); + names[0] = v8::String::NewFromUtf8( + env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName); + names[1] = v8::String::NewFromUtf8(env->GetIsolate(), + ProfileGenerator::kProgramEntryName); + names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start"); // Don't allow |test|, |bar| and |apply| nodes to be at the top level. CheckChildrenNames(root, names); } - const v8::CpuProfileNode* startNode = FindChild(root, "start"); + const v8::CpuProfileNode* startNode = + FindChild(env->GetIsolate(), root, "start"); if (startNode) { { ScopedVector<v8::Handle<v8::String> > names(2); - names[0] = v8::String::New("test"); - names[1] = v8::String::New(ProfileGenerator::kUnresolvedFunctionName); + names[0] = v8::String::NewFromUtf8(env->GetIsolate(), "test"); + names[1] = v8::String::NewFromUtf8( + env->GetIsolate(), ProfileGenerator::kUnresolvedFunctionName); CheckChildrenNames(startNode, names); } - const v8::CpuProfileNode* testNode = FindChild(startNode, "test"); + const v8::CpuProfileNode* testNode = + FindChild(env->GetIsolate(), startNode, "test"); if (testNode) { ScopedVector<v8::Handle<v8::String> > names(2); - names[0] = v8::String::New("bar"); - names[1] = v8::String::New("apply"); + names[0] = v8::String::NewFromUtf8(env->GetIsolate(), "bar"); + names[1] = v8::String::NewFromUtf8(env->GetIsolate(), "apply"); CheckChildrenNames(testNode, names); } if (const v8::CpuProfileNode* unresolvedNode = - FindChild(startNode, ProfileGenerator::kUnresolvedFunctionName)) { + FindChild(env->GetIsolate(), startNode, + ProfileGenerator::kUnresolvedFunctionName)) { ScopedVector<v8::Handle<v8::String> > names(1); - names[0] = v8::String::New("apply"); + names[0] = v8::String::NewFromUtf8(env->GetIsolate(), "apply"); CheckChildrenNames(unresolvedNode, names); - GetChild(unresolvedNode, "apply"); + GetChild(env->GetIsolate(), unresolvedNode, "apply"); } } - v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } @@ -1124,48 +1187,54 @@ static void CallJsFunction(const v8::FunctionCallbackInfo<v8::Value>& info) { // 55 1 bar #16 5 // 54 54 foo #16 6 TEST(JsNativeJsSample) { - const char* extensions[] = { "v8/profiler" }; - v8::ExtensionConfiguration config(1, extensions); - LocalContext env(&config); - v8::HandleScope scope(env->GetIsolate()); + v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); + v8::Context::Scope context_scope(env); v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New( - CallJsFunction); + env->GetIsolate(), CallJsFunction); v8::Local<v8::Function> func = func_template->GetFunction(); - func->SetName(v8::String::New("CallJsFunction")); - env->Global()->Set(v8::String::New("CallJsFunction"), func); + func->SetName(v8::String::NewFromUtf8(env->GetIsolate(), "CallJsFunction")); + env->Global()->Set( + v8::String::NewFromUtf8(env->GetIsolate(), "CallJsFunction"), func); - v8::Script::Compile(v8::String::New(js_native_js_test_source))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + js_native_js_test_source))->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("start"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start"))); int32_t duration_ms = 20; - v8::Handle<v8::Value> args[] = { v8::Integer::New(duration_ms) }; + v8::Handle<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), duration_ms) + }; const v8::CpuProfile* profile = RunProfiler(env, function, args, ARRAY_SIZE(args), 10); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); { ScopedVector<v8::Handle<v8::String> > names(3); - names[0] = v8::String::New(ProfileGenerator::kGarbageCollectorEntryName); - names[1] = v8::String::New(ProfileGenerator::kProgramEntryName); - names[2] = v8::String::New("start"); + names[0] = v8::String::NewFromUtf8( + env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName); + names[1] = v8::String::NewFromUtf8(env->GetIsolate(), + ProfileGenerator::kProgramEntryName); + names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start"); CheckChildrenNames(root, names); } - const v8::CpuProfileNode* startNode = GetChild(root, "start"); + const v8::CpuProfileNode* startNode = + GetChild(env->GetIsolate(), root, "start"); CHECK_EQ(1, startNode->GetChildrenCount()); const v8::CpuProfileNode* nativeFunctionNode = - GetChild(startNode, "CallJsFunction"); + GetChild(env->GetIsolate(), startNode, "CallJsFunction"); CHECK_EQ(1, nativeFunctionNode->GetChildrenCount()); - const v8::CpuProfileNode* barNode = GetChild(nativeFunctionNode, "bar"); + const v8::CpuProfileNode* barNode = + GetChild(env->GetIsolate(), nativeFunctionNode, "bar"); CHECK_EQ(1, barNode->GetChildrenCount()); - GetChild(barNode, "foo"); + GetChild(env->GetIsolate(), barNode, "foo"); - v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } @@ -1202,47 +1271,53 @@ static const char* js_native_js_runtime_js_test_source = // 51 51 foo #16 6 // 2 2 (program) #0 2 TEST(JsNativeJsRuntimeJsSample) { - const char* extensions[] = { "v8/profiler" }; - v8::ExtensionConfiguration config(1, extensions); - LocalContext env(&config); - v8::HandleScope scope(env->GetIsolate()); + v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); + v8::Context::Scope context_scope(env); v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New( - CallJsFunction); + env->GetIsolate(), CallJsFunction); v8::Local<v8::Function> func = func_template->GetFunction(); - func->SetName(v8::String::New("CallJsFunction")); - env->Global()->Set(v8::String::New("CallJsFunction"), func); + func->SetName(v8::String::NewFromUtf8(env->GetIsolate(), "CallJsFunction")); + env->Global()->Set( + v8::String::NewFromUtf8(env->GetIsolate(), "CallJsFunction"), func); - v8::Script::Compile(v8::String::New(js_native_js_runtime_js_test_source))-> - Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), + js_native_js_runtime_js_test_source))->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("start"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start"))); int32_t duration_ms = 20; - v8::Handle<v8::Value> args[] = { v8::Integer::New(duration_ms) }; + v8::Handle<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), duration_ms) + }; const v8::CpuProfile* profile = RunProfiler(env, function, args, ARRAY_SIZE(args), 10); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); ScopedVector<v8::Handle<v8::String> > names(3); - names[0] = v8::String::New(ProfileGenerator::kGarbageCollectorEntryName); - names[1] = v8::String::New(ProfileGenerator::kProgramEntryName); - names[2] = v8::String::New("start"); + names[0] = v8::String::NewFromUtf8( + env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName); + names[1] = v8::String::NewFromUtf8(env->GetIsolate(), + ProfileGenerator::kProgramEntryName); + names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start"); CheckChildrenNames(root, names); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); + const v8::CpuProfileNode* startNode = + GetChild(env->GetIsolate(), root, "start"); CHECK_EQ(1, startNode->GetChildrenCount()); const v8::CpuProfileNode* nativeFunctionNode = - GetChild(startNode, "CallJsFunction"); + GetChild(env->GetIsolate(), startNode, "CallJsFunction"); CHECK_EQ(1, nativeFunctionNode->GetChildrenCount()); - const v8::CpuProfileNode* barNode = GetChild(nativeFunctionNode, "bar"); + const v8::CpuProfileNode* barNode = + GetChild(env->GetIsolate(), nativeFunctionNode, "bar"); CHECK_EQ(1, barNode->GetChildrenCount()); - GetChild(barNode, "foo"); + GetChild(env->GetIsolate(), barNode, "foo"); - v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } @@ -1284,55 +1359,63 @@ static const char* js_native1_js_native2_js_test_source = // 54 54 foo #16 7 // 2 2 (program) #0 2 TEST(JsNative1JsNative2JsSample) { - const char* extensions[] = { "v8/profiler" }; - v8::ExtensionConfiguration config(1, extensions); - LocalContext env(&config); - v8::HandleScope scope(env->GetIsolate()); + v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); + v8::Context::Scope context_scope(env); v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New( - CallJsFunction); + env->GetIsolate(), CallJsFunction); v8::Local<v8::Function> func1 = func_template->GetFunction(); - func1->SetName(v8::String::New("CallJsFunction1")); - env->Global()->Set(v8::String::New("CallJsFunction1"), func1); + func1->SetName(v8::String::NewFromUtf8(env->GetIsolate(), "CallJsFunction1")); + env->Global()->Set( + v8::String::NewFromUtf8(env->GetIsolate(), "CallJsFunction1"), func1); v8::Local<v8::Function> func2 = v8::FunctionTemplate::New( - CallJsFunction2)->GetFunction(); - func2->SetName(v8::String::New("CallJsFunction2")); - env->Global()->Set(v8::String::New("CallJsFunction2"), func2); - - v8::Script::Compile(v8::String::New(js_native1_js_native2_js_test_source))-> - Run(); + env->GetIsolate(), CallJsFunction2)->GetFunction(); + func2->SetName(v8::String::NewFromUtf8(env->GetIsolate(), "CallJsFunction2")); + env->Global()->Set( + v8::String::NewFromUtf8(env->GetIsolate(), "CallJsFunction2"), func2); + + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), + js_native1_js_native2_js_test_source))->Run(); v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("start"))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start"))); int32_t duration_ms = 20; - v8::Handle<v8::Value> args[] = { v8::Integer::New(duration_ms) }; + v8::Handle<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), duration_ms) + }; const v8::CpuProfile* profile = RunProfiler(env, function, args, ARRAY_SIZE(args), 10); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); ScopedVector<v8::Handle<v8::String> > names(3); - names[0] = v8::String::New(ProfileGenerator::kGarbageCollectorEntryName); - names[1] = v8::String::New(ProfileGenerator::kProgramEntryName); - names[2] = v8::String::New("start"); + names[0] = v8::String::NewFromUtf8( + env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName); + names[1] = v8::String::NewFromUtf8(env->GetIsolate(), + ProfileGenerator::kProgramEntryName); + names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start"); CheckChildrenNames(root, names); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); + const v8::CpuProfileNode* startNode = + GetChild(env->GetIsolate(), root, "start"); CHECK_EQ(1, startNode->GetChildrenCount()); const v8::CpuProfileNode* nativeNode1 = - GetChild(startNode, "CallJsFunction1"); + GetChild(env->GetIsolate(), startNode, "CallJsFunction1"); CHECK_EQ(1, nativeNode1->GetChildrenCount()); - const v8::CpuProfileNode* barNode = GetChild(nativeNode1, "bar"); + const v8::CpuProfileNode* barNode = + GetChild(env->GetIsolate(), nativeNode1, "bar"); CHECK_EQ(1, barNode->GetChildrenCount()); - const v8::CpuProfileNode* nativeNode2 = GetChild(barNode, "CallJsFunction2"); + const v8::CpuProfileNode* nativeNode2 = + GetChild(env->GetIsolate(), barNode, "CallJsFunction2"); CHECK_EQ(1, nativeNode2->GetChildrenCount()); - GetChild(nativeNode2, "foo"); + GetChild(env->GetIsolate(), nativeNode2, "foo"); - v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } @@ -1345,7 +1428,8 @@ TEST(IdleTime) { v8::HandleScope scope(env->GetIsolate()); v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); - v8::Local<v8::String> profile_name = v8::String::New("my_profile"); + v8::Local<v8::String> profile_name = + v8::String::NewFromUtf8(env->GetIsolate(), "my_profile"); cpu_profiler->StartCpuProfiling(profile_name); i::Isolate* isolate = CcTest::i_isolate(); @@ -1370,30 +1454,36 @@ TEST(IdleTime) { const v8::CpuProfileNode* root = profile->GetTopDownRoot(); ScopedVector<v8::Handle<v8::String> > names(3); - names[0] = v8::String::New(ProfileGenerator::kGarbageCollectorEntryName); - names[1] = v8::String::New(ProfileGenerator::kProgramEntryName); - names[2] = v8::String::New(ProfileGenerator::kIdleEntryName); + names[0] = v8::String::NewFromUtf8( + env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName); + names[1] = v8::String::NewFromUtf8(env->GetIsolate(), + ProfileGenerator::kProgramEntryName); + names[2] = v8::String::NewFromUtf8(env->GetIsolate(), + ProfileGenerator::kIdleEntryName); CheckChildrenNames(root, names); const v8::CpuProfileNode* programNode = - GetChild(root, ProfileGenerator::kProgramEntryName); + GetChild(env->GetIsolate(), root, ProfileGenerator::kProgramEntryName); CHECK_EQ(0, programNode->GetChildrenCount()); CHECK_GE(programNode->GetHitCount(), 3); const v8::CpuProfileNode* idleNode = - GetChild(root, ProfileGenerator::kIdleEntryName); + GetChild(env->GetIsolate(), root, ProfileGenerator::kIdleEntryName); CHECK_EQ(0, idleNode->GetChildrenCount()); CHECK_GE(idleNode->GetHitCount(), 3); - cpu_profiler->DeleteAllCpuProfiles(); + const_cast<v8::CpuProfile*>(profile)->Delete(); } -static void CheckFunctionDetails(const v8::CpuProfileNode* node, - const char* name, const char* script_name, int script_id, - int line, int column) { - CHECK_EQ(v8::String::New(name), node->GetFunctionName()); - CHECK_EQ(v8::String::New(script_name), node->GetScriptResourceName()); +static void CheckFunctionDetails(v8::Isolate* isolate, + const v8::CpuProfileNode* node, + const char* name, const char* script_name, + int script_id, int line, int column) { + CHECK_EQ(v8::String::NewFromUtf8(isolate, name), + node->GetFunctionName()); + CHECK_EQ(v8::String::NewFromUtf8(isolate, script_name), + node->GetScriptResourceName()); CHECK_EQ(script_id, node->GetScriptId()); CHECK_EQ(line, node->GetLineNumber()); CHECK_EQ(column, node->GetColumnNumber()); @@ -1401,24 +1491,26 @@ static void CheckFunctionDetails(const v8::CpuProfileNode* node, TEST(FunctionDetails) { - const char* extensions[] = { "v8/profiler" }; - v8::ExtensionConfiguration config(1, extensions); - LocalContext env(&config); - v8::HandleScope handleScope(env->GetIsolate()); - - v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler(); - CHECK_EQ(0, profiler->GetProfileCount()); - v8::Handle<v8::Script> script_a = v8::Script::Compile(v8::String::New( - " function foo\n() { try { bar(); } catch(e) {} }\n" - " function bar() { startProfiling(); }\n"), v8::String::New("script_a")); + v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); + v8::Context::Scope context_scope(env); + + v8::Handle<v8::Script> script_a = v8::Script::Compile( + v8::String::NewFromUtf8( + env->GetIsolate(), + " function foo\n() { try { bar(); } catch(e) {} }\n" + " function bar() { startProfiling(); }\n"), + v8::String::NewFromUtf8(env->GetIsolate(), "script_a")); script_a->Run(); - v8::Handle<v8::Script> script_b = v8::Script::Compile(v8::String::New( - "\n\n function baz() { try { foo(); } catch(e) {} }\n" - "\n\nbaz();\n" - "stopProfiling();\n"), v8::String::New("script_b")); + v8::Handle<v8::Script> script_b = v8::Script::Compile( + v8::String::NewFromUtf8( + env->GetIsolate(), + "\n\n function baz() { try { foo(); } catch(e) {} }\n" + "\n\nbaz();\n" + "stopProfiling();\n"), + v8::String::NewFromUtf8(env->GetIsolate(), "script_b")); script_b->Run(); - CHECK_EQ(1, profiler->GetProfileCount()); - const v8::CpuProfile* profile = profiler->GetCpuProfile(0); + const v8::CpuProfile* profile = i::ProfilerExtension::last_profile; const v8::CpuProfileNode* current = profile->GetTopDownRoot(); reinterpret_cast<ProfileNode*>( const_cast<v8::CpuProfileNode*>(current))->Print(0); @@ -1429,14 +1521,52 @@ TEST(FunctionDetails) { // 0 foo 18 #4 TryCatchStatement script_a:2 // 1 bar 18 #5 no reason script_a:3 const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - const v8::CpuProfileNode* script = GetChild(root, + const v8::CpuProfileNode* script = GetChild(env->GetIsolate(), root, ProfileGenerator::kAnonymousFunctionName); - CheckFunctionDetails(script, ProfileGenerator::kAnonymousFunctionName, - "script_b", script_b->GetId(), 1, 1); - const v8::CpuProfileNode* baz = GetChild(script, "baz"); - CheckFunctionDetails(baz, "baz", "script_b", script_b->GetId(), 3, 16); - const v8::CpuProfileNode* foo = GetChild(baz, "foo"); - CheckFunctionDetails(foo, "foo", "script_a", script_a->GetId(), 2, 1); - const v8::CpuProfileNode* bar = GetChild(foo, "bar"); - CheckFunctionDetails(bar, "bar", "script_a", script_a->GetId(), 3, 14); + CheckFunctionDetails(env->GetIsolate(), script, + ProfileGenerator::kAnonymousFunctionName, "script_b", + script_b->GetId(), 1, 1); + const v8::CpuProfileNode* baz = GetChild(env->GetIsolate(), script, "baz"); + CheckFunctionDetails(env->GetIsolate(), baz, "baz", "script_b", + script_b->GetId(), 3, 16); + const v8::CpuProfileNode* foo = GetChild(env->GetIsolate(), baz, "foo"); + CheckFunctionDetails(env->GetIsolate(), foo, "foo", "script_a", + script_a->GetId(), 2, 1); + const v8::CpuProfileNode* bar = GetChild(env->GetIsolate(), foo, "bar"); + CheckFunctionDetails(env->GetIsolate(), bar, "bar", "script_a", + script_a->GetId(), 3, 14); +} + + +TEST(DontStopOnFinishedProfileDelete) { + v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); + v8::Context::Scope context_scope(env); + v8::Isolate* isolate = env->GetIsolate(); + + v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler(); + i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler); + + CHECK_EQ(0, iprofiler->GetProfilesCount()); + v8::Handle<v8::String> outer = v8::String::NewFromUtf8(isolate, "outer"); + profiler->StartCpuProfiling(outer); + CHECK_EQ(0, iprofiler->GetProfilesCount()); + + v8::Handle<v8::String> inner = v8::String::NewFromUtf8(isolate, "inner"); + profiler->StartCpuProfiling(inner); + CHECK_EQ(0, iprofiler->GetProfilesCount()); + + const v8::CpuProfile* inner_profile = profiler->StopCpuProfiling(inner); + CHECK(inner_profile); + CHECK_EQ(1, iprofiler->GetProfilesCount()); + const_cast<v8::CpuProfile*>(inner_profile)->Delete(); + inner_profile = NULL; + CHECK_EQ(0, iprofiler->GetProfilesCount()); + + const v8::CpuProfile* outer_profile = profiler->StopCpuProfiling(outer); + CHECK(outer_profile); + CHECK_EQ(1, iprofiler->GetProfilesCount()); + const_cast<v8::CpuProfile*>(outer_profile)->Delete(); + outer_profile = NULL; + CHECK_EQ(0, iprofiler->GetProfilesCount()); } diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc index 1bd1dc3a0d..67ef88516a 100644 --- a/deps/v8/test/cctest/test-debug.cc +++ b/deps/v8/test/cctest/test-debug.cc @@ -70,65 +70,6 @@ using ::v8::internal::StrLength; // Size of temp buffer for formatting small strings. #define SMALL_STRING_BUFFER_SIZE 80 -// --- A d d i t i o n a l C h e c k H e l p e r s - - -// Helper function used by the CHECK_EQ function when given Address -// arguments. Should not be called directly. -static inline void CheckEqualsHelper(const char* file, int line, - const char* expected_source, - ::v8::internal::Address expected, - const char* value_source, - ::v8::internal::Address value) { - if (expected != value) { - V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n# " - "Expected: %i\n# Found: %i", - expected_source, value_source, expected, value); - } -} - - -// Helper function used by the CHECK_NE function when given Address -// arguments. Should not be called directly. -static inline void CheckNonEqualsHelper(const char* file, int line, - const char* unexpected_source, - ::v8::internal::Address unexpected, - const char* value_source, - ::v8::internal::Address value) { - if (unexpected == value) { - V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %i", - unexpected_source, value_source, value); - } -} - - -// Helper function used by the CHECK function when given code -// arguments. Should not be called directly. -static inline void CheckEqualsHelper(const char* file, int line, - const char* expected_source, - const Code* expected, - const char* value_source, - const Code* value) { - if (expected != value) { - V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n# " - "Expected: %p\n# Found: %p", - expected_source, value_source, expected, value); - } -} - - -static inline void CheckNonEqualsHelper(const char* file, int line, - const char* expected_source, - const Code* expected, - const char* value_source, - const Code* value) { - if (expected == value) { - V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %p", - expected_source, value_source, value); - } -} - - // --- H e l p e r C l a s s e s @@ -154,6 +95,7 @@ class DebugLocalContext { inline v8::Local<v8::Context> context() { return context_; } inline v8::Context* operator->() { return *context_; } inline v8::Context* operator*() { return *context_; } + inline v8::Isolate* GetIsolate() { return context_->GetIsolate(); } inline bool IsReady() { return !context_.IsEmpty(); } void ExposeDebug() { v8::internal::Isolate* isolate = @@ -169,10 +111,10 @@ class DebugLocalContext { v8::Utils::OpenHandle(*context_->Global()))); Handle<v8::internal::String> debug_string = factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("debug")); - SetProperty(isolate, global, debug_string, - Handle<Object>(debug->debug_context()->global_proxy(), isolate), - DONT_ENUM, - ::v8::internal::kNonStrictMode); + v8::internal::Runtime::SetObjectProperty(isolate, global, debug_string, + Handle<Object>(debug->debug_context()->global_proxy(), isolate), + DONT_ENUM, + ::v8::internal::kNonStrictMode); } private: @@ -188,20 +130,22 @@ class DebugLocalContext { static v8::Local<v8::Function> CompileFunction(DebugLocalContext* env, const char* source, const char* function_name) { - v8::Script::Compile(v8::String::New(source))->Run(); - return v8::Local<v8::Function>::Cast( - (*env)->Global()->Get(v8::String::New(function_name))); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source)) + ->Run(); + return v8::Local<v8::Function>::Cast((*env)->Global()->Get( + v8::String::NewFromUtf8(env->GetIsolate(), function_name))); } // Compile and run the supplied source and return the requested function. -static v8::Local<v8::Function> CompileFunction(const char* source, +static v8::Local<v8::Function> CompileFunction(v8::Isolate* isolate, + const char* source, const char* function_name) { - v8::Script::Compile(v8::String::New(source))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, source))->Run(); v8::Local<v8::Object> global = CcTest::isolate()->GetCurrentContext()->Global(); return v8::Local<v8::Function>::Cast( - global->Get(v8::String::New(function_name))); + global->Get(v8::String::NewFromUtf8(isolate, function_name))); } @@ -236,20 +180,22 @@ static int SetBreakPoint(v8::Handle<v8::Function> fun, int position) { // Set a break point in a function using the Debug object and return the // associated break point number. -static int SetBreakPointFromJS(const char* function_name, +static int SetBreakPointFromJS(v8::Isolate* isolate, + const char* function_name, int line, int position) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; OS::SNPrintF(buffer, "debug.Debug.setBreakPoint(%s,%d,%d)", function_name, line, position); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; - v8::Handle<v8::String> str = v8::String::New(buffer.start()); + v8::Handle<v8::String> str = v8::String::NewFromUtf8(isolate, buffer.start()); return v8::Script::Compile(str)->Run()->Int32Value(); } // Set a break point in a script identified by id using the global Debug object. -static int SetScriptBreakPointByIdFromJS(int script_id, int line, int column) { +static int SetScriptBreakPointByIdFromJS(v8::Isolate* isolate, int script_id, + int line, int column) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; if (column >= 0) { // Column specified set script break point on precise location. @@ -265,7 +211,8 @@ static int SetScriptBreakPointByIdFromJS(int script_id, int line, int column) { buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; { v8::TryCatch try_catch; - v8::Handle<v8::String> str = v8::String::New(buffer.start()); + v8::Handle<v8::String> str = + v8::String::NewFromUtf8(isolate, buffer.start()); v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run(); CHECK(!try_catch.HasCaught()); return value->Int32Value(); @@ -275,8 +222,9 @@ static int SetScriptBreakPointByIdFromJS(int script_id, int line, int column) { // Set a break point in a script identified by name using the global Debug // object. -static int SetScriptBreakPointByNameFromJS(const char* script_name, - int line, int column) { +static int SetScriptBreakPointByNameFromJS(v8::Isolate* isolate, + const char* script_name, int line, + int column) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; if (column >= 0) { // Column specified set script break point on precise location. @@ -292,7 +240,8 @@ static int SetScriptBreakPointByNameFromJS(const char* script_name, buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; { v8::TryCatch try_catch; - v8::Handle<v8::String> str = v8::String::New(buffer.start()); + v8::Handle<v8::String> str = + v8::String::NewFromUtf8(isolate, buffer.start()); v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run(); CHECK(!try_catch.HasCaught()); return value->Int32Value(); @@ -310,55 +259,60 @@ static void ClearBreakPoint(int break_point) { // Clear a break point using the global Debug object. -static void ClearBreakPointFromJS(int break_point_number) { +static void ClearBreakPointFromJS(v8::Isolate* isolate, + int break_point_number) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; OS::SNPrintF(buffer, "debug.Debug.clearBreakPoint(%d)", break_point_number); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; - v8::Script::Compile(v8::String::New(buffer.start()))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); } -static void EnableScriptBreakPointFromJS(int break_point_number) { +static void EnableScriptBreakPointFromJS(v8::Isolate* isolate, + int break_point_number) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; OS::SNPrintF(buffer, "debug.Debug.enableScriptBreakPoint(%d)", break_point_number); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; - v8::Script::Compile(v8::String::New(buffer.start()))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); } -static void DisableScriptBreakPointFromJS(int break_point_number) { +static void DisableScriptBreakPointFromJS(v8::Isolate* isolate, + int break_point_number) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; OS::SNPrintF(buffer, "debug.Debug.disableScriptBreakPoint(%d)", break_point_number); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; - v8::Script::Compile(v8::String::New(buffer.start()))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); } -static void ChangeScriptBreakPointConditionFromJS(int break_point_number, +static void ChangeScriptBreakPointConditionFromJS(v8::Isolate* isolate, + int break_point_number, const char* condition) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; OS::SNPrintF(buffer, "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")", break_point_number, condition); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; - v8::Script::Compile(v8::String::New(buffer.start()))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); } -static void ChangeScriptBreakPointIgnoreCountFromJS(int break_point_number, +static void ChangeScriptBreakPointIgnoreCountFromJS(v8::Isolate* isolate, + int break_point_number, int ignoreCount) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; OS::SNPrintF(buffer, "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)", break_point_number, ignoreCount); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; - v8::Script::Compile(v8::String::New(buffer.start()))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); } @@ -371,20 +325,25 @@ static void ChangeBreakOnException(bool caught, bool uncaught) { // Change break on exception using the global Debug object. -static void ChangeBreakOnExceptionFromJS(bool caught, bool uncaught) { +static void ChangeBreakOnExceptionFromJS(v8::Isolate* isolate, bool caught, + bool uncaught) { if (caught) { v8::Script::Compile( - v8::String::New("debug.Debug.setBreakOnException()"))->Run(); + v8::String::NewFromUtf8(isolate, "debug.Debug.setBreakOnException()")) + ->Run(); } else { v8::Script::Compile( - v8::String::New("debug.Debug.clearBreakOnException()"))->Run(); + v8::String::NewFromUtf8(isolate, "debug.Debug.clearBreakOnException()")) + ->Run(); } if (uncaught) { v8::Script::Compile( - v8::String::New("debug.Debug.setBreakOnUncaughtException()"))->Run(); + v8::String::NewFromUtf8( + isolate, "debug.Debug.setBreakOnUncaughtException()"))->Run(); } else { v8::Script::Compile( - v8::String::New("debug.Debug.clearBreakOnUncaughtException()"))->Run(); + v8::String::NewFromUtf8( + isolate, "debug.Debug.clearBreakOnUncaughtException()"))->Run(); } } @@ -429,12 +388,6 @@ Handle<FixedArray> GetDebuggedFunctions() { } -static Handle<Code> ComputeCallDebugBreak(int argc) { - return CcTest::i_isolate()->stub_cache()->ComputeCallDebugBreak(argc, - Code::CALL_IC); -} - - // Check that the debugger has been fully unloaded. void CheckDebuggerUnloaded(bool check_functions) { // Check that the debugger context is cleared and that there is no debug @@ -685,7 +638,9 @@ static void DebugEventBreakPointHitCount( if (!frame_function_name.IsEmpty()) { // Get the name of the function. const int argc = 2; - v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; + v8::Handle<v8::Value> argv[argc] = { + exec_state, v8::Integer::New(CcTest::isolate(), 0) + }; v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, argc, argv); if (result->IsUndefined()) { @@ -799,7 +754,8 @@ static void DebugEventCounter( exception_hit_count++; // Check whether the exception was uncaught. - v8::Local<v8::String> fun_name = v8::String::New("uncaught"); + v8::Local<v8::String> fun_name = + v8::String::NewFromUtf8(CcTest::isolate(), "uncaught"); v8::Local<v8::Function> fun = v8::Local<v8::Function>::Cast(event_data->Get(fun_name)); v8::Local<v8::Value> result = fun->Call(event_data, 0, NULL); @@ -856,9 +812,10 @@ static void DebugEventEvaluate( if (event == v8::Break) { for (int i = 0; checks[i].expr != NULL; i++) { const int argc = 3; - v8::Handle<v8::Value> argv[argc] = { exec_state, - v8::String::New(checks[i].expr), - checks[i].expected }; + v8::Handle<v8::Value> argv[argc] = { + exec_state, + v8::String::NewFromUtf8(CcTest::isolate(), checks[i].expr), + checks[i].expected}; v8::Handle<v8::Value> result = evaluate_check_function->Call(exec_state, argc, argv); if (!result->IsTrue()) { @@ -930,7 +887,9 @@ static void DebugEventStepSequence( CHECK(break_point_hit_count < StrLength(expected_step_sequence)); const int argc = 2; - v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; + v8::Handle<v8::Value> argv[argc] = { + exec_state, v8::Integer::New(CcTest::isolate(), 0) + }; v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, argc, argv); CHECK(result->IsString()); @@ -1075,13 +1034,13 @@ TEST(DebugStub) { CheckDebugBreakFunction(&env, "function f2(){x=1;}", "f2", 0, - v8::internal::RelocInfo::CODE_TARGET_CONTEXT, + v8::internal::RelocInfo::CODE_TARGET, CcTest::i_isolate()->builtins()->builtin( Builtins::kStoreIC_DebugBreak)); CheckDebugBreakFunction(&env, "function f3(){var a=x;}", "f3", 0, - v8::internal::RelocInfo::CODE_TARGET_CONTEXT, + v8::internal::RelocInfo::CODE_TARGET, CcTest::i_isolate()->builtins()->builtin( Builtins::kLoadIC_DebugBreak)); @@ -1119,27 +1078,28 @@ TEST(DebugStub) { // Check the debug break code stubs for call ICs with different number of // parameters. - Handle<Code> debug_break_0 = v8::internal::ComputeCallDebugBreak(0); - Handle<Code> debug_break_1 = v8::internal::ComputeCallDebugBreak(1); - Handle<Code> debug_break_4 = v8::internal::ComputeCallDebugBreak(4); + // TODO(verwaest): XXX update test. + // Handle<Code> debug_break_0 = v8::internal::ComputeCallDebugBreak(0); + // Handle<Code> debug_break_1 = v8::internal::ComputeCallDebugBreak(1); + // Handle<Code> debug_break_4 = v8::internal::ComputeCallDebugBreak(4); - CheckDebugBreakFunction(&env, - "function f4_0(){x();}", "f4_0", - 0, - v8::internal::RelocInfo::CODE_TARGET_CONTEXT, - *debug_break_0); + // CheckDebugBreakFunction(&env, + // "function f4_0(){x();}", "f4_0", + // 0, + // v8::internal::RelocInfo::CODE_TARGET, + // *debug_break_0); - CheckDebugBreakFunction(&env, - "function f4_1(){x(1);}", "f4_1", - 0, - v8::internal::RelocInfo::CODE_TARGET_CONTEXT, - *debug_break_1); + // CheckDebugBreakFunction(&env, + // "function f4_1(){x(1);}", "f4_1", + // 0, + // v8::internal::RelocInfo::CODE_TARGET, + // *debug_break_1); - CheckDebugBreakFunction(&env, - "function f4_4(){x(1,2,3,4);}", "f4_4", - 0, - v8::internal::RelocInfo::CODE_TARGET_CONTEXT, - *debug_break_4); + // CheckDebugBreakFunction(&env, + // "function f4_4(){x(1,2,3,4);}", "f4_4", + // 0, + // v8::internal::RelocInfo::CODE_TARGET, + // *debug_break_4); } @@ -1187,9 +1147,10 @@ TEST(BreakPointICStore) { v8::HandleScope scope(env->GetIsolate()); v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Script::Compile(v8::String::New("function foo(){bar=0;}"))->Run(); - v8::Local<v8::Function> foo = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + "function foo(){bar=0;}"))->Run(); + v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); // Run without breakpoints. foo->Call(env->Global(), 0, NULL); @@ -1218,10 +1179,13 @@ TEST(BreakPointICLoad) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Script::Compile(v8::String::New("bar=1"))->Run(); - v8::Script::Compile(v8::String::New("function foo(){var x=bar;}"))->Run(); - v8::Local<v8::Function> foo = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "bar=1")) + ->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){var x=bar;}")) + ->Run(); + v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); // Run without breakpoints. foo->Call(env->Global(), 0, NULL); @@ -1250,10 +1214,12 @@ TEST(BreakPointICCall) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Script::Compile(v8::String::New("function bar(){}"))->Run(); - v8::Script::Compile(v8::String::New("function foo(){bar();}"))->Run(); - v8::Local<v8::Function> foo = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){}"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + "function foo(){bar();}"))->Run(); + v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); // Run without breakpoints. foo->Call(env->Global(), 0, NULL); @@ -1282,10 +1248,14 @@ TEST(BreakPointICCallWithGC) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage); - v8::Script::Compile(v8::String::New("function bar(){return 1;}"))->Run(); - v8::Script::Compile(v8::String::New("function foo(){return bar();}"))->Run(); - v8::Local<v8::Function> foo = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){return 1;}")) + ->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + "function foo(){return bar();}")) + ->Run(); + v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); // Run without breakpoints. CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); @@ -1314,11 +1284,14 @@ TEST(BreakPointConstructCallWithGC) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage); - v8::Script::Compile(v8::String::New("function bar(){ this.x = 1;}"))->Run(); - v8::Script::Compile(v8::String::New( - "function foo(){return new bar(1).x;}"))->Run(); - v8::Local<v8::Function> foo = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + "function bar(){ this.x = 1;}")) + ->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), + "function foo(){return new bar(1).x;}"))->Run(); + v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); // Run without breakpoints. CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); @@ -1358,9 +1331,10 @@ TEST(BreakPointReturn) { v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Script::Compile(v8::String::New("function foo(){}"))->Run(); - v8::Local<v8::Function> foo = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){}"))->Run(); + v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); // Run without breakpoints. foo->Call(env->Global(), 0, NULL); @@ -1527,40 +1501,44 @@ TEST(BreakPointThroughJavaScript) { env.ExposeDebug(); v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Script::Compile(v8::String::New("function bar(){}"))->Run(); - v8::Script::Compile(v8::String::New("function foo(){bar();bar();}"))->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){}"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + "function foo(){bar();bar();}")) + ->Run(); // 012345678901234567890 // 1 2 // Break points are set at position 3 and 9 - v8::Local<v8::Script> foo = v8::Script::Compile(v8::String::New("foo()")); + v8::Local<v8::Script> foo = + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "foo()")); // Run without breakpoints. foo->Run(); CHECK_EQ(0, break_point_hit_count); // Run with one breakpoint - int bp1 = SetBreakPointFromJS("foo", 0, 3); + int bp1 = SetBreakPointFromJS(env->GetIsolate(), "foo", 0, 3); foo->Run(); CHECK_EQ(1, break_point_hit_count); foo->Run(); CHECK_EQ(2, break_point_hit_count); // Run with two breakpoints - int bp2 = SetBreakPointFromJS("foo", 0, 9); + int bp2 = SetBreakPointFromJS(env->GetIsolate(), "foo", 0, 9); foo->Run(); CHECK_EQ(4, break_point_hit_count); foo->Run(); CHECK_EQ(6, break_point_hit_count); // Run with one breakpoint - ClearBreakPointFromJS(bp2); + ClearBreakPointFromJS(env->GetIsolate(), bp2); foo->Run(); CHECK_EQ(7, break_point_hit_count); foo->Run(); CHECK_EQ(8, break_point_hit_count); // Run without breakpoints. - ClearBreakPointFromJS(bp1); + ClearBreakPointFromJS(env->GetIsolate(), bp1); foo->Run(); CHECK_EQ(8, break_point_hit_count); @@ -1583,7 +1561,8 @@ TEST(ScriptBreakPointByNameThroughJavaScript) { v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Local<v8::String> script = v8::String::New( + v8::Local<v8::String> script = v8::String::NewFromUtf8( + env->GetIsolate(), "function f() {\n" " function h() {\n" " a = 0; // line 2\n" @@ -1604,12 +1583,12 @@ TEST(ScriptBreakPointByNameThroughJavaScript) { // Compile the script and get the two functions. v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::New("test")); + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); v8::Script::Compile(script, &origin)->Run(); - v8::Local<v8::Function> f = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); - v8::Local<v8::Function> g = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); + v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); // Call f and g without break points. break_point_hit_count = 0; @@ -1619,7 +1598,7 @@ TEST(ScriptBreakPointByNameThroughJavaScript) { CHECK_EQ(0, break_point_hit_count); // Call f and g with break point on line 12. - int sbp1 = SetScriptBreakPointByNameFromJS("test", 12, 0); + int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 12, 0); break_point_hit_count = 0; f->Call(env->Global(), 0, NULL); CHECK_EQ(0, break_point_hit_count); @@ -1628,14 +1607,14 @@ TEST(ScriptBreakPointByNameThroughJavaScript) { // Remove the break point again. break_point_hit_count = 0; - ClearBreakPointFromJS(sbp1); + ClearBreakPointFromJS(env->GetIsolate(), sbp1); f->Call(env->Global(), 0, NULL); CHECK_EQ(0, break_point_hit_count); g->Call(env->Global(), 0, NULL); CHECK_EQ(0, break_point_hit_count); // Call f and g with break point on line 2. - int sbp2 = SetScriptBreakPointByNameFromJS("test", 2, 0); + int sbp2 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 2, 0); break_point_hit_count = 0; f->Call(env->Global(), 0, NULL); CHECK_EQ(1, break_point_hit_count); @@ -1643,10 +1622,10 @@ TEST(ScriptBreakPointByNameThroughJavaScript) { CHECK_EQ(2, break_point_hit_count); // Call f and g with break point on line 2, 4, 12, 14 and 15. - int sbp3 = SetScriptBreakPointByNameFromJS("test", 4, 0); - int sbp4 = SetScriptBreakPointByNameFromJS("test", 12, 0); - int sbp5 = SetScriptBreakPointByNameFromJS("test", 14, 0); - int sbp6 = SetScriptBreakPointByNameFromJS("test", 15, 0); + int sbp3 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 4, 0); + int sbp4 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 12, 0); + int sbp5 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 14, 0); + int sbp6 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 15, 0); break_point_hit_count = 0; f->Call(env->Global(), 0, NULL); CHECK_EQ(2, break_point_hit_count); @@ -1655,11 +1634,11 @@ TEST(ScriptBreakPointByNameThroughJavaScript) { // Remove all the break points again. break_point_hit_count = 0; - ClearBreakPointFromJS(sbp2); - ClearBreakPointFromJS(sbp3); - ClearBreakPointFromJS(sbp4); - ClearBreakPointFromJS(sbp5); - ClearBreakPointFromJS(sbp6); + ClearBreakPointFromJS(env->GetIsolate(), sbp2); + ClearBreakPointFromJS(env->GetIsolate(), sbp3); + ClearBreakPointFromJS(env->GetIsolate(), sbp4); + ClearBreakPointFromJS(env->GetIsolate(), sbp5); + ClearBreakPointFromJS(env->GetIsolate(), sbp6); f->Call(env->Global(), 0, NULL); CHECK_EQ(0, break_point_hit_count); g->Call(env->Global(), 0, NULL); @@ -1686,7 +1665,8 @@ TEST(ScriptBreakPointByIdThroughJavaScript) { v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Local<v8::String> source = v8::String::New( + v8::Local<v8::String> source = v8::String::NewFromUtf8( + env->GetIsolate(), "function f() {\n" " function h() {\n" " a = 0; // line 2\n" @@ -1707,16 +1687,16 @@ TEST(ScriptBreakPointByIdThroughJavaScript) { // Compile the script and get the two functions. v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::New("test")); + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); v8::Local<v8::Script> script = v8::Script::Compile(source, &origin); script->Run(); - v8::Local<v8::Function> f = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); - v8::Local<v8::Function> g = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); + v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); // Get the script id knowing that internally it is a 32 integer. - uint32_t script_id = script->Id()->Uint32Value(); + int script_id = script->GetId(); // Call f and g without break points. break_point_hit_count = 0; @@ -1726,7 +1706,7 @@ TEST(ScriptBreakPointByIdThroughJavaScript) { CHECK_EQ(0, break_point_hit_count); // Call f and g with break point on line 12. - int sbp1 = SetScriptBreakPointByIdFromJS(script_id, 12, 0); + int sbp1 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0); break_point_hit_count = 0; f->Call(env->Global(), 0, NULL); CHECK_EQ(0, break_point_hit_count); @@ -1735,14 +1715,14 @@ TEST(ScriptBreakPointByIdThroughJavaScript) { // Remove the break point again. break_point_hit_count = 0; - ClearBreakPointFromJS(sbp1); + ClearBreakPointFromJS(env->GetIsolate(), sbp1); f->Call(env->Global(), 0, NULL); CHECK_EQ(0, break_point_hit_count); g->Call(env->Global(), 0, NULL); CHECK_EQ(0, break_point_hit_count); // Call f and g with break point on line 2. - int sbp2 = SetScriptBreakPointByIdFromJS(script_id, 2, 0); + int sbp2 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 2, 0); break_point_hit_count = 0; f->Call(env->Global(), 0, NULL); CHECK_EQ(1, break_point_hit_count); @@ -1750,10 +1730,10 @@ TEST(ScriptBreakPointByIdThroughJavaScript) { CHECK_EQ(2, break_point_hit_count); // Call f and g with break point on line 2, 4, 12, 14 and 15. - int sbp3 = SetScriptBreakPointByIdFromJS(script_id, 4, 0); - int sbp4 = SetScriptBreakPointByIdFromJS(script_id, 12, 0); - int sbp5 = SetScriptBreakPointByIdFromJS(script_id, 14, 0); - int sbp6 = SetScriptBreakPointByIdFromJS(script_id, 15, 0); + int sbp3 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 4, 0); + int sbp4 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0); + int sbp5 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 14, 0); + int sbp6 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 15, 0); break_point_hit_count = 0; f->Call(env->Global(), 0, NULL); CHECK_EQ(2, break_point_hit_count); @@ -1762,11 +1742,11 @@ TEST(ScriptBreakPointByIdThroughJavaScript) { // Remove all the break points again. break_point_hit_count = 0; - ClearBreakPointFromJS(sbp2); - ClearBreakPointFromJS(sbp3); - ClearBreakPointFromJS(sbp4); - ClearBreakPointFromJS(sbp5); - ClearBreakPointFromJS(sbp6); + ClearBreakPointFromJS(env->GetIsolate(), sbp2); + ClearBreakPointFromJS(env->GetIsolate(), sbp3); + ClearBreakPointFromJS(env->GetIsolate(), sbp4); + ClearBreakPointFromJS(env->GetIsolate(), sbp5); + ClearBreakPointFromJS(env->GetIsolate(), sbp6); f->Call(env->Global(), 0, NULL); CHECK_EQ(0, break_point_hit_count); g->Call(env->Global(), 0, NULL); @@ -1794,45 +1774,47 @@ TEST(EnableDisableScriptBreakPoint) { v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Local<v8::String> script = v8::String::New( + v8::Local<v8::String> script = v8::String::NewFromUtf8( + env->GetIsolate(), "function f() {\n" " a = 0; // line 1\n" "};"); // Compile the script and get function f. v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::New("test")); + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); v8::Script::Compile(script, &origin)->Run(); - v8::Local<v8::Function> f = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); // Set script break point on line 1 (in function f). - int sbp = SetScriptBreakPointByNameFromJS("test", 1, 0); + int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); // Call f while enabeling and disabling the script break point. break_point_hit_count = 0; f->Call(env->Global(), 0, NULL); CHECK_EQ(1, break_point_hit_count); - DisableScriptBreakPointFromJS(sbp); + DisableScriptBreakPointFromJS(env->GetIsolate(), sbp); f->Call(env->Global(), 0, NULL); CHECK_EQ(1, break_point_hit_count); - EnableScriptBreakPointFromJS(sbp); + EnableScriptBreakPointFromJS(env->GetIsolate(), sbp); f->Call(env->Global(), 0, NULL); CHECK_EQ(2, break_point_hit_count); - DisableScriptBreakPointFromJS(sbp); + DisableScriptBreakPointFromJS(env->GetIsolate(), sbp); f->Call(env->Global(), 0, NULL); CHECK_EQ(2, break_point_hit_count); // Reload the script and get f again checking that the disabeling survives. v8::Script::Compile(script, &origin)->Run(); - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); f->Call(env->Global(), 0, NULL); CHECK_EQ(2, break_point_hit_count); - EnableScriptBreakPointFromJS(sbp); + EnableScriptBreakPointFromJS(env->GetIsolate(), sbp); f->Call(env->Global(), 0, NULL); CHECK_EQ(3, break_point_hit_count); @@ -1850,7 +1832,8 @@ TEST(ConditionalScriptBreakPoint) { v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Local<v8::String> script = v8::String::New( + v8::Local<v8::String> script = v8::String::NewFromUtf8( + env->GetIsolate(), "count = 0;\n" "function f() {\n" " g(count++); // line 2\n" @@ -1861,26 +1844,26 @@ TEST(ConditionalScriptBreakPoint) { // Compile the script and get function f. v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::New("test")); + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); v8::Script::Compile(script, &origin)->Run(); - v8::Local<v8::Function> f = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); // Set script break point on line 5 (in function g). - int sbp1 = SetScriptBreakPointByNameFromJS("test", 5, 0); + int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 5, 0); // Call f with different conditions on the script break point. break_point_hit_count = 0; - ChangeScriptBreakPointConditionFromJS(sbp1, "false"); + ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "false"); f->Call(env->Global(), 0, NULL); CHECK_EQ(0, break_point_hit_count); - ChangeScriptBreakPointConditionFromJS(sbp1, "true"); + ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "true"); break_point_hit_count = 0; f->Call(env->Global(), 0, NULL); CHECK_EQ(1, break_point_hit_count); - ChangeScriptBreakPointConditionFromJS(sbp1, "x % 2 == 0"); + ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "x % 2 == 0"); break_point_hit_count = 0; for (int i = 0; i < 10; i++) { f->Call(env->Global(), 0, NULL); @@ -1889,7 +1872,8 @@ TEST(ConditionalScriptBreakPoint) { // Reload the script and get f again checking that the condition survives. v8::Script::Compile(script, &origin)->Run(); - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); break_point_hit_count = 0; for (int i = 0; i < 10; i++) { @@ -1911,30 +1895,31 @@ TEST(ScriptBreakPointIgnoreCount) { v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Local<v8::String> script = v8::String::New( + v8::Local<v8::String> script = v8::String::NewFromUtf8( + env->GetIsolate(), "function f() {\n" " a = 0; // line 1\n" "};"); // Compile the script and get function f. v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::New("test")); + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); v8::Script::Compile(script, &origin)->Run(); - v8::Local<v8::Function> f = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); // Set script break point on line 1 (in function f). - int sbp = SetScriptBreakPointByNameFromJS("test", 1, 0); + int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); // Call f with different ignores on the script break point. break_point_hit_count = 0; - ChangeScriptBreakPointIgnoreCountFromJS(sbp, 1); + ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 1); f->Call(env->Global(), 0, NULL); CHECK_EQ(0, break_point_hit_count); f->Call(env->Global(), 0, NULL); CHECK_EQ(1, break_point_hit_count); - ChangeScriptBreakPointIgnoreCountFromJS(sbp, 5); + ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 5); break_point_hit_count = 0; for (int i = 0; i < 10; i++) { f->Call(env->Global(), 0, NULL); @@ -1943,7 +1928,8 @@ TEST(ScriptBreakPointIgnoreCount) { // Reload the script and get f again checking that the ignore survives. v8::Script::Compile(script, &origin)->Run(); - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); break_point_hit_count = 0; for (int i = 0; i < 10; i++) { @@ -1966,7 +1952,8 @@ TEST(ScriptBreakPointReload) { v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); v8::Local<v8::Function> f; - v8::Local<v8::String> script = v8::String::New( + v8::Local<v8::String> script = v8::String::NewFromUtf8( + env->GetIsolate(), "function f() {\n" " function h() {\n" " a = 0; // line 2\n" @@ -1975,15 +1962,18 @@ TEST(ScriptBreakPointReload) { " return h();\n" "}"); - v8::ScriptOrigin origin_1 = v8::ScriptOrigin(v8::String::New("1")); - v8::ScriptOrigin origin_2 = v8::ScriptOrigin(v8::String::New("2")); + v8::ScriptOrigin origin_1 = + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "1")); + v8::ScriptOrigin origin_2 = + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "2")); // Set a script break point before the script is loaded. - SetScriptBreakPointByNameFromJS("1", 2, 0); + SetScriptBreakPointByNameFromJS(env->GetIsolate(), "1", 2, 0); // Compile the script and get the function. v8::Script::Compile(script, &origin_1)->Run(); - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); // Call f and check that the script break point is active. break_point_hit_count = 0; @@ -1993,7 +1983,8 @@ TEST(ScriptBreakPointReload) { // Compile the script again with a different script data and get the // function. v8::Script::Compile(script, &origin_2)->Run(); - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); // Call f and check that no break points are set. break_point_hit_count = 0; @@ -2002,7 +1993,8 @@ TEST(ScriptBreakPointReload) { // Compile the script again and get the function. v8::Script::Compile(script, &origin_1)->Run(); - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); // Call f and check that the script break point is active. break_point_hit_count = 0; @@ -2024,28 +2016,32 @@ TEST(ScriptBreakPointMultiple) { v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); v8::Local<v8::Function> f; - v8::Local<v8::String> script_f = v8::String::New( - "function f() {\n" - " a = 0; // line 1\n" - "}"); + v8::Local<v8::String> script_f = + v8::String::NewFromUtf8(env->GetIsolate(), + "function f() {\n" + " a = 0; // line 1\n" + "}"); v8::Local<v8::Function> g; - v8::Local<v8::String> script_g = v8::String::New( - "function g() {\n" - " b = 0; // line 1\n" - "}"); + v8::Local<v8::String> script_g = + v8::String::NewFromUtf8(env->GetIsolate(), + "function g() {\n" + " b = 0; // line 1\n" + "}"); v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::New("test")); + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); // Set a script break point before the scripts are loaded. - int sbp = SetScriptBreakPointByNameFromJS("test", 1, 0); + int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); // Compile the scripts with same script data and get the functions. v8::Script::Compile(script_f, &origin)->Run(); - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); v8::Script::Compile(script_g, &origin)->Run(); - g = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); + g = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); // Call f and g and check that the script break point is active. break_point_hit_count = 0; @@ -2055,7 +2051,7 @@ TEST(ScriptBreakPointMultiple) { CHECK_EQ(2, break_point_hit_count); // Clear the script break point. - ClearBreakPointFromJS(sbp); + ClearBreakPointFromJS(env->GetIsolate(), sbp); // Call f and g and check that the script break point is no longer active. break_point_hit_count = 0; @@ -2065,7 +2061,7 @@ TEST(ScriptBreakPointMultiple) { CHECK_EQ(0, break_point_hit_count); // Set script break point with the scripts loaded. - sbp = SetScriptBreakPointByNameFromJS("test", 1, 0); + sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); // Call f and g and check that the script break point is active. break_point_hit_count = 0; @@ -2089,23 +2085,28 @@ TEST(ScriptBreakPointLineOffset) { v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); v8::Local<v8::Function> f; - v8::Local<v8::String> script = v8::String::New( - "function f() {\n" - " a = 0; // line 8 as this script has line offset 7\n" - " b = 0; // line 9 as this script has line offset 7\n" - "}"); + v8::Local<v8::String> script = v8::String::NewFromUtf8( + env->GetIsolate(), + "function f() {\n" + " a = 0; // line 8 as this script has line offset 7\n" + " b = 0; // line 9 as this script has line offset 7\n" + "}"); // Create script origin both name and line offset. - v8::ScriptOrigin origin(v8::String::New("test.html"), - v8::Integer::New(7)); + v8::ScriptOrigin origin( + v8::String::NewFromUtf8(env->GetIsolate(), "test.html"), + v8::Integer::New(env->GetIsolate(), 7)); // Set two script break points before the script is loaded. - int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 8, 0); - int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 9, 0); + int sbp1 = + SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 8, 0); + int sbp2 = + SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0); // Compile the script and get the function. v8::Script::Compile(script, &origin)->Run(); - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); // Call f and check that the script break point is active. break_point_hit_count = 0; @@ -2113,8 +2114,8 @@ TEST(ScriptBreakPointLineOffset) { CHECK_EQ(2, break_point_hit_count); // Clear the script break points. - ClearBreakPointFromJS(sbp1); - ClearBreakPointFromJS(sbp2); + ClearBreakPointFromJS(env->GetIsolate(), sbp1); + ClearBreakPointFromJS(env->GetIsolate(), sbp2); // Call f and check that no script break points are active. break_point_hit_count = 0; @@ -2122,7 +2123,7 @@ TEST(ScriptBreakPointLineOffset) { CHECK_EQ(0, break_point_hit_count); // Set a script break point with the script loaded. - sbp1 = SetScriptBreakPointByNameFromJS("test.html", 9, 0); + sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0); // Call f and check that the script break point is active. break_point_hit_count = 0; @@ -2149,32 +2150,40 @@ TEST(ScriptBreakPointLine) { v8::Local<v8::Function> f; v8::Local<v8::Function> g; - v8::Local<v8::String> script = v8::String::New( - "a = 0 // line 0\n" - "function f() {\n" - " a = 1; // line 2\n" - "}\n" - " a = 2; // line 4\n" - " /* xx */ function g() { // line 5\n" - " function h() { // line 6\n" - " a = 3; // line 7\n" - " }\n" - " h(); // line 9\n" - " a = 4; // line 10\n" - " }\n" - " a=5; // line 12"); + v8::Local<v8::String> script = + v8::String::NewFromUtf8(env->GetIsolate(), + "a = 0 // line 0\n" + "function f() {\n" + " a = 1; // line 2\n" + "}\n" + " a = 2; // line 4\n" + " /* xx */ function g() { // line 5\n" + " function h() { // line 6\n" + " a = 3; // line 7\n" + " }\n" + " h(); // line 9\n" + " a = 4; // line 10\n" + " }\n" + " a=5; // line 12"); // Set a couple script break point before the script is loaded. - int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 0, -1); - int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 1, -1); - int sbp3 = SetScriptBreakPointByNameFromJS("test.html", 5, -1); + int sbp1 = + SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 0, -1); + int sbp2 = + SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 1, -1); + int sbp3 = + SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 5, -1); // Compile the script and get the function. break_point_hit_count = 0; - v8::ScriptOrigin origin(v8::String::New("test.html"), v8::Integer::New(0)); + v8::ScriptOrigin origin( + v8::String::NewFromUtf8(env->GetIsolate(), "test.html"), + v8::Integer::New(env->GetIsolate(), 0)); v8::Script::Compile(script, &origin)->Run(); - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); - g = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + g = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); // Check that a break point was hit when the script was run. CHECK_EQ(1, break_point_hit_count); @@ -2191,8 +2200,9 @@ TEST(ScriptBreakPointLine) { CHECK_EQ("g", last_function_hit); // Clear the script break point on g and set one on h. - ClearBreakPointFromJS(sbp3); - int sbp4 = SetScriptBreakPointByNameFromJS("test.html", 6, -1); + ClearBreakPointFromJS(env->GetIsolate(), sbp3); + int sbp4 = + SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 6, -1); // Call g and check that the script break point in h is hit. g->Call(env->Global(), 0, NULL); @@ -2202,9 +2212,10 @@ TEST(ScriptBreakPointLine) { // Clear break points in f and h. Set a new one in the script between // functions f and g and test that there is no break points in f and g any // more. - ClearBreakPointFromJS(sbp2); - ClearBreakPointFromJS(sbp4); - int sbp5 = SetScriptBreakPointByNameFromJS("test.html", 4, -1); + ClearBreakPointFromJS(env->GetIsolate(), sbp2); + ClearBreakPointFromJS(env->GetIsolate(), sbp4); + int sbp5 = + SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 4, -1); break_point_hit_count = 0; f->Call(env->Global(), 0, NULL); g->Call(env->Global(), 0, NULL); @@ -2217,7 +2228,8 @@ TEST(ScriptBreakPointLine) { CHECK_EQ(0, StrLength(last_function_hit)); // Set a break point in the code after the last function decleration. - int sbp6 = SetScriptBreakPointByNameFromJS("test.html", 12, -1); + int sbp6 = + SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 12, -1); // Reload the script which should hit three break points. break_point_hit_count = 0; @@ -2227,9 +2239,9 @@ TEST(ScriptBreakPointLine) { // Clear the last break points, and reload the script which should not hit any // break points. - ClearBreakPointFromJS(sbp1); - ClearBreakPointFromJS(sbp5); - ClearBreakPointFromJS(sbp6); + ClearBreakPointFromJS(env->GetIsolate(), sbp1); + ClearBreakPointFromJS(env->GetIsolate(), sbp5); + ClearBreakPointFromJS(env->GetIsolate(), sbp6); break_point_hit_count = 0; v8::Script::Compile(script, &origin)->Run(); CHECK_EQ(0, break_point_hit_count); @@ -2247,21 +2259,24 @@ TEST(ScriptBreakPointLineTopLevel) { v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Local<v8::String> script = v8::String::New( - "function f() {\n" - " a = 1; // line 1\n" - "}\n" - "a = 2; // line 3\n"); + v8::Local<v8::String> script = + v8::String::NewFromUtf8(env->GetIsolate(), + "function f() {\n" + " a = 1; // line 1\n" + "}\n" + "a = 2; // line 3\n"); v8::Local<v8::Function> f; { v8::HandleScope scope(env->GetIsolate()); - v8::Script::Compile(script, v8::String::New("test.html"))->Run(); + v8::Script::Compile( + script, v8::String::NewFromUtf8(env->GetIsolate(), "test.html"))->Run(); } - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); - SetScriptBreakPointByNameFromJS("test.html", 3, -1); + SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); // Call f and check that there was no break points. break_point_hit_count = 0; @@ -2270,12 +2285,14 @@ TEST(ScriptBreakPointLineTopLevel) { // Recompile and run script and check that break point was hit. break_point_hit_count = 0; - v8::Script::Compile(script, v8::String::New("test.html"))->Run(); + v8::Script::Compile( + script, v8::String::NewFromUtf8(env->GetIsolate(), "test.html"))->Run(); CHECK_EQ(1, break_point_hit_count); // Call f and check that there are still no break points. break_point_hit_count = 0; - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); CHECK_EQ(0, break_point_hit_count); v8::Debug::SetDebugEventListener2(NULL); @@ -2292,23 +2309,28 @@ TEST(ScriptBreakPointTopLevelCrash) { v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Local<v8::String> script_source = v8::String::New( - "function f() {\n" - " return 0;\n" - "}\n" - "f()"); + v8::Local<v8::String> script_source = + v8::String::NewFromUtf8(env->GetIsolate(), + "function f() {\n" + " return 0;\n" + "}\n" + "f()"); - int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 3, -1); + int sbp1 = + SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); { v8::HandleScope scope(env->GetIsolate()); break_point_hit_count = 0; - v8::Script::Compile(script_source, v8::String::New("test.html"))->Run(); + v8::Script::Compile(script_source, + v8::String::NewFromUtf8(env->GetIsolate(), "test.html")) + ->Run(); CHECK_EQ(1, break_point_hit_count); } - int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 3, -1); - ClearBreakPointFromJS(sbp1); - ClearBreakPointFromJS(sbp2); + int sbp2 = + SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); + ClearBreakPointFromJS(env->GetIsolate(), sbp1); + ClearBreakPointFromJS(env->GetIsolate(), sbp2); v8::Debug::SetDebugEventListener2(NULL); CheckDebuggerUnloaded(); @@ -2347,13 +2369,16 @@ TEST(DebuggerStatement) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Script::Compile(v8::String::New("function bar(){debugger}"))->Run(); - v8::Script::Compile(v8::String::New( - "function foo(){debugger;debugger;}"))->Run(); - v8::Local<v8::Function> foo = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); - v8::Local<v8::Function> bar = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("bar"))); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){debugger}")) + ->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), + "function foo(){debugger;debugger;}"))->Run(); + v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); + v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "bar"))); // Run function with debugger statement bar->Call(env->Global(), 0, NULL); @@ -2374,9 +2399,11 @@ TEST(DebuggerStatementBreakpoint) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); - v8::Script::Compile(v8::String::New("function foo(){debugger;}"))->Run(); - v8::Local<v8::Function> foo = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){debugger;}")) + ->Run(); + v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); // The debugger statement triggers breakpint hit foo->Call(env->Global(), 0, NULL); @@ -2417,13 +2444,13 @@ TEST(DebugEvaluate) { {NULL, v8::Handle<v8::Value>()} }; struct EvaluateCheck checks_hu[] = { - {"x", v8::String::New("Hello, world!")}, + {"x", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}, {"a", v8::Undefined(isolate)}, {NULL, v8::Handle<v8::Value>()} }; struct EvaluateCheck checks_hh[] = { - {"x", v8::String::New("Hello, world!")}, - {"a", v8::String::New("Hello, world!")}, + {"x", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}, + {"a", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}, {NULL, v8::Handle<v8::Value>()} }; @@ -2443,7 +2470,8 @@ TEST(DebugEvaluate) { const int foo_break_position_2 = 29; // Arguments with one parameter "Hello, world!" - v8::Handle<v8::Value> argv_foo[1] = { v8::String::New("Hello, world!") }; + v8::Handle<v8::Value> argv_foo[1] = { + v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}; // Call foo with breakpoint set before a=x and undefined as parameter. int bp = SetBreakPoint(foo, foo_break_position_1); @@ -2485,7 +2513,7 @@ TEST(DebugEvaluate) { checks = checks_uu; v8::Handle<v8::Value> argv_bar_1[2] = { v8::Undefined(isolate), - v8::Number::New(barbar_break_position) + v8::Number::New(isolate, barbar_break_position) }; bar->Call(env->Global(), 2, argv_bar_1); @@ -2493,8 +2521,8 @@ TEST(DebugEvaluate) { // "Hello, world!". checks = checks_hu; v8::Handle<v8::Value> argv_bar_2[2] = { - v8::String::New("Hello, world!"), - v8::Number::New(barbar_break_position) + v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!"), + v8::Number::New(env->GetIsolate(), barbar_break_position) }; bar->Call(env->Global(), 2, argv_bar_2); @@ -2502,8 +2530,8 @@ TEST(DebugEvaluate) { // "Hello, world!". checks = checks_hh; v8::Handle<v8::Value> argv_bar_3[2] = { - v8::String::New("Hello, world!"), - v8::Number::New(barbar_break_position + 1) + v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!"), + v8::Number::New(env->GetIsolate(), barbar_break_position + 1) }; bar->Call(env->Global(), 2, argv_bar_3); @@ -2690,10 +2718,10 @@ DebugProcessDebugMessagesData process_debug_messages_data; static void DebugProcessDebugMessagesHandler( const v8::Debug::Message& message) { v8::Handle<v8::String> json = message.GetJSON(); - v8::String::AsciiValue ascii(json); + v8::String::Utf8Value utf8(json); EvaluateResult* array_item = process_debug_messages_data.current(); - bool res = GetEvaluateStringResult(*ascii, + bool res = GetEvaluateStringResult(*utf8, array_item->buffer, EvaluateResult::kBufferSize); if (res) { @@ -2713,7 +2741,8 @@ TEST(DebugEvaluateWithoutStack) { const char* source = "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }"; - v8::Script::Compile(v8::String::New(source))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source)) + ->Run(); v8::Debug::ProcessDebugMessages(); @@ -2833,9 +2862,10 @@ TEST(DebugStepKeyedLoadLoop) { "foo"); // Create array [0,1,2,3,4,5,6,7,8,9] - v8::Local<v8::Array> a = v8::Array::New(10); + v8::Local<v8::Array> a = v8::Array::New(env->GetIsolate(), 10); for (int i = 0; i < 10; i++) { - a->Set(v8::Number::New(i), v8::Number::New(i)); + a->Set(v8::Number::New(env->GetIsolate(), i), + v8::Number::New(env->GetIsolate(), i)); } // Call function without any break points to ensure inlining is in place. @@ -2880,9 +2910,10 @@ TEST(DebugStepKeyedStoreLoop) { "foo"); // Create array [0,1,2,3,4,5,6,7,8,9] - v8::Local<v8::Array> a = v8::Array::New(10); + v8::Local<v8::Array> a = v8::Array::New(env->GetIsolate(), 10); for (int i = 0; i < 10; i++) { - a->Set(v8::Number::New(i), v8::Number::New(i)); + a->Set(v8::Number::New(env->GetIsolate(), i), + v8::Number::New(env->GetIsolate(), i)); } // Call function without any break points to ensure inlining is in place. @@ -3148,7 +3179,8 @@ TEST(DebugStepIf) { TEST(DebugStepSwitch) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. v8::Debug::SetDebugEventListener2(DebugEventStep); @@ -3178,21 +3210,21 @@ TEST(DebugStepSwitch) { // One case with fall-through. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_1[argc] = { v8::Number::New(1) }; + v8::Handle<v8::Value> argv_1[argc] = { v8::Number::New(isolate, 1) }; foo->Call(env->Global(), argc, argv_1); CHECK_EQ(6, break_point_hit_count); // Another case. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_2[argc] = { v8::Number::New(2) }; + v8::Handle<v8::Value> argv_2[argc] = { v8::Number::New(isolate, 2) }; foo->Call(env->Global(), argc, argv_2); CHECK_EQ(5, break_point_hit_count); // Last case. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_3[argc] = { v8::Number::New(3) }; + v8::Handle<v8::Value> argv_3[argc] = { v8::Number::New(isolate, 3) }; foo->Call(env->Global(), argc, argv_3); CHECK_EQ(7, break_point_hit_count); @@ -3204,7 +3236,8 @@ TEST(DebugStepSwitch) { TEST(DebugStepWhile) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. v8::Debug::SetDebugEventListener2(DebugEventStep); @@ -3225,14 +3258,14 @@ TEST(DebugStepWhile) { // Looping 10 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; + v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; foo->Call(env->Global(), argc, argv_10); CHECK_EQ(22, break_point_hit_count); // Looping 100 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; + v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; foo->Call(env->Global(), argc, argv_100); CHECK_EQ(202, break_point_hit_count); @@ -3244,7 +3277,8 @@ TEST(DebugStepWhile) { TEST(DebugStepDoWhile) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. v8::Debug::SetDebugEventListener2(DebugEventStep); @@ -3265,14 +3299,14 @@ TEST(DebugStepDoWhile) { // Looping 10 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; + v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; foo->Call(env->Global(), argc, argv_10); CHECK_EQ(22, break_point_hit_count); // Looping 100 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; + v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; foo->Call(env->Global(), argc, argv_100); CHECK_EQ(202, break_point_hit_count); @@ -3284,7 +3318,8 @@ TEST(DebugStepDoWhile) { TEST(DebugStepFor) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. v8::Debug::SetDebugEventListener2(DebugEventStep); @@ -3306,14 +3341,14 @@ TEST(DebugStepFor) { // Looping 10 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; + v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; foo->Call(env->Global(), argc, argv_10); CHECK_EQ(23, break_point_hit_count); // Looping 100 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; + v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; foo->Call(env->Global(), argc, argv_100); CHECK_EQ(203, break_point_hit_count); @@ -3325,7 +3360,8 @@ TEST(DebugStepFor) { TEST(DebugStepForContinue) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. v8::Debug::SetDebugEventListener2(DebugEventStep); @@ -3355,7 +3391,7 @@ TEST(DebugStepForContinue) { // Looping 10 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; + v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; result = foo->Call(env->Global(), argc, argv_10); CHECK_EQ(5, result->Int32Value()); CHECK_EQ(52, break_point_hit_count); @@ -3363,7 +3399,7 @@ TEST(DebugStepForContinue) { // Looping 100 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; + v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; result = foo->Call(env->Global(), argc, argv_100); CHECK_EQ(50, result->Int32Value()); CHECK_EQ(457, break_point_hit_count); @@ -3376,7 +3412,8 @@ TEST(DebugStepForContinue) { TEST(DebugStepForBreak) { DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. v8::Debug::SetDebugEventListener2(DebugEventStep); @@ -3407,7 +3444,7 @@ TEST(DebugStepForBreak) { // Looping 10 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; + v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; result = foo->Call(env->Global(), argc, argv_10); CHECK_EQ(9, result->Int32Value()); CHECK_EQ(55, break_point_hit_count); @@ -3415,7 +3452,7 @@ TEST(DebugStepForBreak) { // Looping 100 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; + v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; result = foo->Call(env->Global(), argc, argv_100); CHECK_EQ(99, result->Int32Value()); CHECK_EQ(505, break_point_hit_count); @@ -3489,7 +3526,8 @@ TEST(DebugStepWith) { " with (b) {}" "}" "foo()"; - env->Global()->Set(v8::String::New("b"), v8::Object::New()); + env->Global()->Set(v8::String::NewFromUtf8(env->GetIsolate(), "b"), + v8::Object::New(env->GetIsolate())); v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); v8::Handle<v8::Value> result; SetBreakPoint(foo, 8); // "var a = {};" @@ -3823,12 +3861,14 @@ TEST(PauseInScript) { const char* script_name = "StepInHandlerTest"; // Set breakpoint in the script. - SetScriptBreakPointByNameFromJS(script_name, 0, -1); + SetScriptBreakPointByNameFromJS(env->GetIsolate(), script_name, 0, -1); break_point_hit_count = 0; - v8::ScriptOrigin origin(v8::String::New(script_name), v8::Integer::New(0)); - v8::Handle<v8::Script> script = v8::Script::Compile(v8::String::New(src), - &origin); + v8::ScriptOrigin origin( + v8::String::NewFromUtf8(env->GetIsolate(), script_name), + v8::Integer::New(env->GetIsolate(), 0)); + v8::Handle<v8::Script> script = v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), src), &origin); v8::Local<v8::Value> r = script->Run(); CHECK(r->IsFunction()); @@ -3851,8 +3891,6 @@ TEST(BreakOnException) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); - CcTest::i_isolate()->TraceException(false); - // Create functions for testing break on exception. CompileFunction(&env, "function throws(){throw 1;}", "throws"); v8::Local<v8::Function> caught = @@ -3932,7 +3970,7 @@ TEST(BreakOnException) { // No break on exception using JavaScript DebugEventCounterClear(); MessageCallbackCountClear(); - ChangeBreakOnExceptionFromJS(false, false); + ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, false); caught->Call(env->Global(), 0, NULL); CHECK_EQ(0, exception_hit_count); CHECK_EQ(0, uncaught_exception_hit_count); @@ -3945,7 +3983,7 @@ TEST(BreakOnException) { // Break on uncaught exception using JavaScript DebugEventCounterClear(); MessageCallbackCountClear(); - ChangeBreakOnExceptionFromJS(false, true); + ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, true); caught->Call(env->Global(), 0, NULL); CHECK_EQ(0, exception_hit_count); CHECK_EQ(0, uncaught_exception_hit_count); @@ -3958,7 +3996,7 @@ TEST(BreakOnException) { // Break on exception and uncaught exception using JavaScript DebugEventCounterClear(); MessageCallbackCountClear(); - ChangeBreakOnExceptionFromJS(true, true); + ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, true); caught->Call(env->Global(), 0, NULL); CHECK_EQ(1, exception_hit_count); CHECK_EQ(0, message_callback_count); @@ -3971,7 +4009,7 @@ TEST(BreakOnException) { // Break on exception using JavaScript DebugEventCounterClear(); MessageCallbackCountClear(); - ChangeBreakOnExceptionFromJS(true, false); + ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, false); caught->Call(env->Global(), 0, NULL); CHECK_EQ(1, exception_hit_count); CHECK_EQ(0, uncaught_exception_hit_count); @@ -3997,8 +4035,6 @@ TEST(BreakOnCompileException) { // For this test, we want to break on uncaught exceptions: ChangeBreakOnException(false, true); - CcTest::i_isolate()->TraceException(false); - // Create a function for checking the function when hitting a break point. frame_count = CompileFunction(&env, frame_count_source, "frame_count"); @@ -4015,28 +4051,30 @@ TEST(BreakOnCompileException) { CHECK_EQ(-1, last_js_stack_height); // Throws SyntaxError: Unexpected end of input - v8::Script::Compile(v8::String::New("+++")); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "+++")); CHECK_EQ(1, exception_hit_count); CHECK_EQ(1, uncaught_exception_hit_count); CHECK_EQ(1, message_callback_count); CHECK_EQ(0, last_js_stack_height); // No JavaScript stack. // Throws SyntaxError: Unexpected identifier - v8::Script::Compile(v8::String::New("x x")); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "x x")); CHECK_EQ(2, exception_hit_count); CHECK_EQ(2, uncaught_exception_hit_count); CHECK_EQ(2, message_callback_count); CHECK_EQ(0, last_js_stack_height); // No JavaScript stack. // Throws SyntaxError: Unexpected end of input - v8::Script::Compile(v8::String::New("eval('+++')"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "eval('+++')")) + ->Run(); CHECK_EQ(3, exception_hit_count); CHECK_EQ(3, uncaught_exception_hit_count); CHECK_EQ(3, message_callback_count); CHECK_EQ(1, last_js_stack_height); // Throws SyntaxError: Unexpected identifier - v8::Script::Compile(v8::String::New("eval('x x')"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "eval('x x')")) + ->Run(); CHECK_EQ(4, exception_hit_count); CHECK_EQ(4, uncaught_exception_hit_count); CHECK_EQ(4, message_callback_count); @@ -4140,7 +4178,8 @@ TEST(DebugBreak) { i::FLAG_verify_heap = true; #endif DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Register a debug event listener which sets the break flag and counts. v8::Debug::SetDebugEventListener2(DebugEventBreak); @@ -4156,10 +4195,10 @@ TEST(DebugBreak) { v8::Local<v8::Function> f3 = CompileFunction(&env, src, "f3"); // Call the function to make sure it is compiled. - v8::Handle<v8::Value> argv[] = { v8::Number::New(1), - v8::Number::New(1), - v8::Number::New(1), - v8::Number::New(1) }; + v8::Handle<v8::Value> argv[] = { v8::Number::New(isolate, 1), + v8::Number::New(isolate, 1), + v8::Number::New(isolate, 1), + v8::Number::New(isolate, 1) }; // Call all functions to make sure that they are compiled. f0->Call(env->Global(), 0, NULL); @@ -4262,18 +4301,22 @@ TEST(NoBreakWhenBootstrapping) { static void NamedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { - v8::Handle<v8::Array> result = v8::Array::New(3); - result->Set(v8::Integer::New(0), v8::String::New("a")); - result->Set(v8::Integer::New(1), v8::String::New("b")); - result->Set(v8::Integer::New(2), v8::String::New("c")); + v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 3); + result->Set(v8::Integer::New(info.GetIsolate(), 0), + v8::String::NewFromUtf8(info.GetIsolate(), "a")); + result->Set(v8::Integer::New(info.GetIsolate(), 1), + v8::String::NewFromUtf8(info.GetIsolate(), "b")); + result->Set(v8::Integer::New(info.GetIsolate(), 2), + v8::String::NewFromUtf8(info.GetIsolate(), "c")); info.GetReturnValue().Set(result); } static void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { - v8::Handle<v8::Array> result = v8::Array::New(2); - result->Set(v8::Integer::New(0), v8::Number::New(1)); - result->Set(v8::Integer::New(1), v8::Number::New(10)); + v8::Isolate* isolate = info.GetIsolate(); + v8::Handle<v8::Array> result = v8::Array::New(isolate, 2); + result->Set(v8::Integer::New(isolate, 0), v8::Number::New(isolate, 1)); + result->Set(v8::Integer::New(isolate, 1), v8::Number::New(isolate, 10)); info.GetReturnValue().Set(result); } @@ -4282,13 +4325,13 @@ static void NamedGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { v8::String::Utf8Value n(name); if (strcmp(*n, "a") == 0) { - info.GetReturnValue().Set(v8::String::New("AA")); + info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "AA")); return; } else if (strcmp(*n, "b") == 0) { - info.GetReturnValue().Set(v8::String::New("BB")); + info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "BB")); return; } else if (strcmp(*n, "c") == 0) { - info.GetReturnValue().Set(v8::String::New("CC")); + info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "CC")); return; } else { info.GetReturnValue().SetUndefined(); @@ -4307,30 +4350,35 @@ static void IndexedGetter(uint32_t index, TEST(InterceptorPropertyMirror) { // Create a V8 environment with debug access. DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); env.ExposeDebug(); // Create object with named interceptor. - v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); named->SetNamedPropertyHandler(NamedGetter, NULL, NULL, NULL, NamedEnum); - env->Global()->Set(v8::String::New("intercepted_named"), - named->NewInstance()); + env->Global()->Set( + v8::String::NewFromUtf8(isolate, "intercepted_named"), + named->NewInstance()); // Create object with indexed interceptor. - v8::Handle<v8::ObjectTemplate> indexed = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> indexed = v8::ObjectTemplate::New(isolate); indexed->SetIndexedPropertyHandler(IndexedGetter, NULL, NULL, NULL, IndexedEnum); - env->Global()->Set(v8::String::New("intercepted_indexed"), - indexed->NewInstance()); + env->Global()->Set( + v8::String::NewFromUtf8(isolate, "intercepted_indexed"), + indexed->NewInstance()); // Create object with both named and indexed interceptor. - v8::Handle<v8::ObjectTemplate> both = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> both = v8::ObjectTemplate::New(isolate); both->SetNamedPropertyHandler(NamedGetter, NULL, NULL, NULL, NamedEnum); both->SetIndexedPropertyHandler(IndexedGetter, NULL, NULL, NULL, IndexedEnum); - env->Global()->Set(v8::String::New("intercepted_both"), both->NewInstance()); + env->Global()->Set( + v8::String::NewFromUtf8(isolate, "intercepted_both"), + both->NewInstance()); // Get mirrors for the three objects with interceptor. CompileRun( @@ -4438,29 +4486,34 @@ TEST(InterceptorPropertyMirror) { TEST(HiddenPrototypePropertyMirror) { // Create a V8 environment with debug access. DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); env.ExposeDebug(); - v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(); - t0->InstanceTemplate()->Set(v8::String::New("x"), v8::Number::New(0)); - v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(); + v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); + t0->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "x"), + v8::Number::New(isolate, 0)); + v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); t1->SetHiddenPrototype(true); - t1->InstanceTemplate()->Set(v8::String::New("y"), v8::Number::New(1)); - v8::Handle<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(); + t1->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "y"), + v8::Number::New(isolate, 1)); + v8::Handle<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate); t2->SetHiddenPrototype(true); - t2->InstanceTemplate()->Set(v8::String::New("z"), v8::Number::New(2)); - v8::Handle<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(); - t3->InstanceTemplate()->Set(v8::String::New("u"), v8::Number::New(3)); + t2->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "z"), + v8::Number::New(isolate, 2)); + v8::Handle<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate); + t3->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "u"), + v8::Number::New(isolate, 3)); // Create object and set them on the global object. v8::Handle<v8::Object> o0 = t0->GetFunction()->NewInstance(); - env->Global()->Set(v8::String::New("o0"), o0); + env->Global()->Set(v8::String::NewFromUtf8(isolate, "o0"), o0); v8::Handle<v8::Object> o1 = t1->GetFunction()->NewInstance(); - env->Global()->Set(v8::String::New("o1"), o1); + env->Global()->Set(v8::String::NewFromUtf8(isolate, "o1"), o1); v8::Handle<v8::Object> o2 = t2->GetFunction()->NewInstance(); - env->Global()->Set(v8::String::New("o2"), o2); + env->Global()->Set(v8::String::NewFromUtf8(isolate, "o2"), o2); v8::Handle<v8::Object> o3 = t3->GetFunction()->NewInstance(); - env->Global()->Set(v8::String::New("o3"), o3); + env->Global()->Set(v8::String::NewFromUtf8(isolate, "o3"), o3); // Get mirrors for the four objects. CompileRun( @@ -4485,7 +4538,7 @@ TEST(HiddenPrototypePropertyMirror) { // Set o1 as prototype for o0. o1 has the hidden prototype flag so all // properties on o1 should be seen on o0. - o0->Set(v8::String::New("__proto__"), o1); + o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o1); CHECK_EQ(2, CompileRun( "o0_mirror.propertyNames().length")->Int32Value()); CHECK_EQ(0, CompileRun( @@ -4496,7 +4549,7 @@ TEST(HiddenPrototypePropertyMirror) { // Set o2 as prototype for o0 (it will end up after o1 as o1 has the hidden // prototype flag. o2 also has the hidden prototype flag so all properties // on o2 should be seen on o0 as well as properties on o1. - o0->Set(v8::String::New("__proto__"), o2); + o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o2); CHECK_EQ(3, CompileRun( "o0_mirror.propertyNames().length")->Int32Value()); CHECK_EQ(0, CompileRun( @@ -4512,7 +4565,7 @@ TEST(HiddenPrototypePropertyMirror) { // from o1 and o2 should still be seen on o0. // Final prototype chain: o0 -> o1 -> o2 -> o3 // Hidden prototypes: ^^ ^^ - o0->Set(v8::String::New("__proto__"), o3); + o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o3); CHECK_EQ(3, CompileRun( "o0_mirror.propertyNames().length")->Int32Value()); CHECK_EQ(1, CompileRun( @@ -4540,17 +4593,19 @@ static void ProtperyXNativeGetter( TEST(NativeGetterPropertyMirror) { // Create a V8 environment with debug access. DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); env.ExposeDebug(); - v8::Handle<v8::String> name = v8::String::New("x"); + v8::Handle<v8::String> name = v8::String::NewFromUtf8(isolate, "x"); // Create object with named accessor. - v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); named->SetAccessor(name, &ProtperyXNativeGetter, NULL, v8::Handle<v8::Value>(), v8::DEFAULT, v8::None); // Create object with named property getter. - env->Global()->Set(v8::String::New("instance"), named->NewInstance()); + env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"), + named->NewInstance()); CHECK_EQ(10, CompileRun("instance.x")->Int32Value()); // Get mirror for the object with property getter. @@ -4578,17 +4633,19 @@ static void ProtperyXNativeGetterThrowingError( TEST(NativeGetterThrowingErrorPropertyMirror) { // Create a V8 environment with debug access. DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); env.ExposeDebug(); - v8::Handle<v8::String> name = v8::String::New("x"); + v8::Handle<v8::String> name = v8::String::NewFromUtf8(isolate, "x"); // Create object with named accessor. - v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); named->SetAccessor(name, &ProtperyXNativeGetterThrowingError, NULL, v8::Handle<v8::Value>(), v8::DEFAULT, v8::None); // Create object with named property getter. - env->Global()->Set(v8::String::New("instance"), named->NewInstance()); + env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"), + named->NewInstance()); // Get mirror for the object with property getter. CompileRun("var instance_mirror = debug.MakeMirror(instance);"); @@ -4613,17 +4670,20 @@ TEST(NativeGetterThrowingErrorPropertyMirror) { TEST(NoHiddenProperties) { // Create a V8 environment with debug access. DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); env.ExposeDebug(); // Create an object in the global scope. const char* source = "var obj = {a: 1};"; - v8::Script::Compile(v8::String::New(source))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, source)) + ->Run(); v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast( - env->Global()->Get(v8::String::New("obj"))); + env->Global()->Get(v8::String::NewFromUtf8(isolate, "obj"))); // Set a hidden property on the object. - obj->SetHiddenValue(v8::String::New("v8::test-debug::a"), - v8::Int32::New(11)); + obj->SetHiddenValue( + v8::String::NewFromUtf8(isolate, "v8::test-debug::a"), + v8::Int32::New(isolate, 11)); // Get mirror for the object with property getter. CompileRun("var obj_mirror = debug.MakeMirror(obj);"); @@ -4639,26 +4699,34 @@ TEST(NoHiddenProperties) { "obj_mirror.property('a').value().value() == 1")->BooleanValue()); // Object created by t0 will become hidden prototype of object 'obj'. - v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(); - t0->InstanceTemplate()->Set(v8::String::New("b"), v8::Number::New(2)); + v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); + t0->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "b"), + v8::Number::New(isolate, 2)); t0->SetHiddenPrototype(true); - v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(); - t1->InstanceTemplate()->Set(v8::String::New("c"), v8::Number::New(3)); + v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); + t1->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "c"), + v8::Number::New(isolate, 3)); // Create proto objects, add hidden properties to them and set them on // the global object. v8::Handle<v8::Object> protoObj = t0->GetFunction()->NewInstance(); - protoObj->SetHiddenValue(v8::String::New("v8::test-debug::b"), - v8::Int32::New(12)); - env->Global()->Set(v8::String::New("protoObj"), protoObj); + protoObj->SetHiddenValue( + v8::String::NewFromUtf8(isolate, "v8::test-debug::b"), + v8::Int32::New(isolate, 12)); + env->Global()->Set(v8::String::NewFromUtf8(isolate, "protoObj"), + protoObj); v8::Handle<v8::Object> grandProtoObj = t1->GetFunction()->NewInstance(); - grandProtoObj->SetHiddenValue(v8::String::New("v8::test-debug::c"), - v8::Int32::New(13)); - env->Global()->Set(v8::String::New("grandProtoObj"), grandProtoObj); + grandProtoObj->SetHiddenValue( + v8::String::NewFromUtf8(isolate, "v8::test-debug::c"), + v8::Int32::New(isolate, 13)); + env->Global()->Set( + v8::String::NewFromUtf8(isolate, "grandProtoObj"), + grandProtoObj); // Setting prototypes: obj->protoObj->grandProtoObj - protoObj->Set(v8::String::New("__proto__"), grandProtoObj); - obj->Set(v8::String::New("__proto__"), protoObj); + protoObj->Set(v8::String::NewFromUtf8(isolate, "__proto__"), + grandProtoObj); + obj->Set(v8::String::NewFromUtf8(isolate, "__proto__"), protoObj); // Get mirror for the object with property getter. CompileRun("var obj_mirror = debug.MakeMirror(obj);"); @@ -4844,8 +4912,8 @@ class MessageQueueDebuggerThread : public v8::internal::Thread { static void MessageHandler(const v8::Debug::Message& message) { v8::Handle<v8::String> json = message.GetJSON(); - v8::String::AsciiValue ascii(json); - if (IsBreakEventMessage(*ascii)) { + v8::String::Utf8Value utf8(json); + if (IsBreakEventMessage(*utf8)) { // Lets test script wait until break occurs to send commands. // Signals when a break is reported. message_queue_barriers.semaphore_2.Signal(); @@ -5146,14 +5214,17 @@ void V8Thread::Run() { "\n" "foo();\n"; - v8::Isolate::Scope isolate_scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + v8::Isolate::Scope isolate_scope(isolate); DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); v8::Debug::SetMessageHandler2(&ThreadedMessageHandler); - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); - global_template->Set(v8::String::New("ThreadedAtBarrier1"), - v8::FunctionTemplate::New(ThreadedAtBarrier1)); - v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate(), + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(env->GetIsolate()); + global_template->Set( + v8::String::NewFromUtf8(env->GetIsolate(), "ThreadedAtBarrier1"), + v8::FunctionTemplate::New(isolate, ThreadedAtBarrier1)); + v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global_template); v8::Context::Scope context_scope(context); @@ -5484,7 +5555,8 @@ static void CheckSourceLine(const v8::FunctionCallbackInfo<v8::Value>& args) { // can throw exceptions. static void CheckDataParameter( const v8::FunctionCallbackInfo<v8::Value>& args) { - v8::Handle<v8::String> data = v8::String::New("Test"); + v8::Handle<v8::String> data = + v8::String::NewFromUtf8(args.GetIsolate(), "Test"); CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString()); CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty()); @@ -5508,75 +5580,97 @@ static void CheckClosure(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(CallFunctionInDebugger) { // Create and enter a context with the functions CheckFrameCount, // CheckSourceLine and CheckDataParameter installed. - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); - global_template->Set(v8::String::New("CheckFrameCount"), - v8::FunctionTemplate::New(CheckFrameCount)); - global_template->Set(v8::String::New("CheckSourceLine"), - v8::FunctionTemplate::New(CheckSourceLine)); - global_template->Set(v8::String::New("CheckDataParameter"), - v8::FunctionTemplate::New(CheckDataParameter)); - global_template->Set(v8::String::New("CheckClosure"), - v8::FunctionTemplate::New(CheckClosure)); - v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate(), + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); + global_template->Set( + v8::String::NewFromUtf8(isolate, "CheckFrameCount"), + v8::FunctionTemplate::New(isolate, CheckFrameCount)); + global_template->Set( + v8::String::NewFromUtf8(isolate, "CheckSourceLine"), + v8::FunctionTemplate::New(isolate, CheckSourceLine)); + global_template->Set( + v8::String::NewFromUtf8(isolate, "CheckDataParameter"), + v8::FunctionTemplate::New(isolate, CheckDataParameter)); + global_template->Set( + v8::String::NewFromUtf8(isolate, "CheckClosure"), + v8::FunctionTemplate::New(isolate, CheckClosure)); + v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global_template); v8::Context::Scope context_scope(context); // Compile a function for checking the number of JavaScript frames. - v8::Script::Compile(v8::String::New(frame_count_source))->Run(); - frame_count = v8::Local<v8::Function>::Cast( - context->Global()->Get(v8::String::New("frame_count"))); + v8::Script::Compile( + v8::String::NewFromUtf8(isolate, frame_count_source))->Run(); + frame_count = v8::Local<v8::Function>::Cast(context->Global()->Get( + v8::String::NewFromUtf8(isolate, "frame_count"))); // Compile a function for returning the source line for the top frame. - v8::Script::Compile(v8::String::New(frame_source_line_source))->Run(); - frame_source_line = v8::Local<v8::Function>::Cast( - context->Global()->Get(v8::String::New("frame_source_line"))); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, + frame_source_line_source))->Run(); + frame_source_line = v8::Local<v8::Function>::Cast(context->Global()->Get( + v8::String::NewFromUtf8(isolate, "frame_source_line"))); // Compile a function returning the data parameter. - v8::Script::Compile(v8::String::New(debugger_call_with_data_source))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, + debugger_call_with_data_source)) + ->Run(); debugger_call_with_data = v8::Local<v8::Function>::Cast( - context->Global()->Get(v8::String::New("debugger_call_with_data"))); + context->Global()->Get(v8::String::NewFromUtf8( + isolate, "debugger_call_with_data"))); // Compile a function capturing closure. - debugger_call_with_closure = v8::Local<v8::Function>::Cast( - v8::Script::Compile( - v8::String::New(debugger_call_with_closure_source))->Run()); + debugger_call_with_closure = + v8::Local<v8::Function>::Cast(v8::Script::Compile( + v8::String::NewFromUtf8(isolate, + debugger_call_with_closure_source))->Run()); // Calling a function through the debugger returns 0 frames if there are // no JavaScript frames. - CHECK_EQ(v8::Integer::New(0), v8::Debug::Call(frame_count)); + CHECK_EQ(v8::Integer::New(isolate, 0), + v8::Debug::Call(frame_count)); // Test that the number of frames can be retrieved. - v8::Script::Compile(v8::String::New("CheckFrameCount(1)"))->Run(); - v8::Script::Compile(v8::String::New("function f() {" - " CheckFrameCount(2);" - "}; f()"))->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(isolate, "CheckFrameCount(1)"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, + "function f() {" + " CheckFrameCount(2);" + "}; f()"))->Run(); // Test that the source line can be retrieved. - v8::Script::Compile(v8::String::New("CheckSourceLine(0)"))->Run(); - v8::Script::Compile(v8::String::New("function f() {\n" - " CheckSourceLine(1)\n" - " CheckSourceLine(2)\n" - " CheckSourceLine(3)\n" - "}; f()"))->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(isolate, "CheckSourceLine(0)"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, + "function f() {\n" + " CheckSourceLine(1)\n" + " CheckSourceLine(2)\n" + " CheckSourceLine(3)\n" + "}; f()"))->Run(); // Test that a parameter can be passed to a function called in the debugger. - v8::Script::Compile(v8::String::New("CheckDataParameter()"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, + "CheckDataParameter()"))->Run(); // Test that a function with closure can be run in the debugger. - v8::Script::Compile(v8::String::New("CheckClosure()"))->Run(); - + v8::Script::Compile( + v8::String::NewFromUtf8(isolate, "CheckClosure()"))->Run(); // Test that the source line is correct when there is a line offset. - v8::ScriptOrigin origin(v8::String::New("test"), - v8::Integer::New(7)); - v8::Script::Compile(v8::String::New("CheckSourceLine(7)"), &origin)->Run(); - v8::Script::Compile(v8::String::New("function f() {\n" - " CheckSourceLine(8)\n" - " CheckSourceLine(9)\n" - " CheckSourceLine(10)\n" - "}; f()"), &origin)->Run(); + v8::ScriptOrigin origin(v8::String::NewFromUtf8(isolate, "test"), + v8::Integer::New(isolate, 7)); + v8::Script::Compile( + v8::String::NewFromUtf8(isolate, "CheckSourceLine(7)"), &origin) + ->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, + "function f() {\n" + " CheckSourceLine(8)\n" + " CheckSourceLine(9)\n" + " CheckSourceLine(10)\n" + "}; f()"), + &origin)->Run(); } @@ -5639,7 +5733,7 @@ TEST(DebuggerUnload) { // Get the test functions again. v8::Local<v8::Function> foo(v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::New("foo")))); + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")))); foo->Call(env->Global(), 0, NULL); CHECK_EQ(0, break_point_hit_count); @@ -5989,7 +6083,7 @@ class DebuggerAgentProtocolServerThread : public i::Thread { void Run(); void WaitForListening() { listening_.Wait(); } - char* body() { return *body_; } + char* body() { return body_.get(); } private: int port_; @@ -6113,7 +6207,8 @@ TEST(DebugGetLoadedScripts) { env.ExposeDebug(); EmptyExternalStringResource source_ext_str; - v8::Local<v8::String> source = v8::String::NewExternal(&source_ext_str); + v8::Local<v8::String> source = + v8::String::NewExternal(env->GetIsolate(), &source_ext_str); v8::Handle<v8::Script> evil_script(v8::Script::Compile(source)); // "use" evil_script to make the compiler happy. (void) evil_script; @@ -6135,7 +6230,11 @@ TEST(DebugGetLoadedScripts) { i::FLAG_allow_natives_syntax = allow_natives_syntax; // Some scripts are retrieved - at least the number of native scripts. - CHECK_GT((*env)->Global()->Get(v8::String::New("count"))->Int32Value(), 8); + CHECK_GT((*env) + ->Global() + ->Get(v8::String::NewFromUtf8(env->GetIsolate(), "count")) + ->Int32Value(), + 8); } @@ -6160,17 +6259,19 @@ TEST(ScriptNameAndData) { v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount); // Test function source. - v8::Local<v8::String> script = v8::String::New( - "function f() {\n" - " debugger;\n" - "}\n"); + v8::Local<v8::String> script = v8::String::NewFromUtf8(env->GetIsolate(), + "function f() {\n" + " debugger;\n" + "}\n"); - v8::ScriptOrigin origin1 = v8::ScriptOrigin(v8::String::New("name")); + v8::ScriptOrigin origin1 = + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "name")); v8::Handle<v8::Script> script1 = v8::Script::Compile(script, &origin1); - script1->SetData(v8::String::New("data")); + script1->SetData(v8::String::NewFromUtf8(env->GetIsolate(), "data")); script1->Run(); v8::Local<v8::Function> f; - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); f->Call(env->Global(), 0, NULL); CHECK_EQ(1, break_point_hit_count); @@ -6180,34 +6281,39 @@ TEST(ScriptNameAndData) { // Compile the same script again without setting data. As the compilation // cache is disabled when debugging expect the data to be missing. v8::Script::Compile(script, &origin1)->Run(); - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); f->Call(env->Global(), 0, NULL); CHECK_EQ(2, break_point_hit_count); CHECK_EQ("name", last_script_name_hit); CHECK_EQ("", last_script_data_hit); // Undefined results in empty string. - v8::Local<v8::String> data_obj_source = v8::String::New( - "({ a: 'abc',\n" - " b: 123,\n" - " toString: function() { return this.a + ' ' + this.b; }\n" - "})\n"); + v8::Local<v8::String> data_obj_source = v8::String::NewFromUtf8( + env->GetIsolate(), + "({ a: 'abc',\n" + " b: 123,\n" + " toString: function() { return this.a + ' ' + this.b; }\n" + "})\n"); v8::Local<v8::Value> data_obj = v8::Script::Compile(data_obj_source)->Run(); - v8::ScriptOrigin origin2 = v8::ScriptOrigin(v8::String::New("new name")); + v8::ScriptOrigin origin2 = + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "new name")); v8::Handle<v8::Script> script2 = v8::Script::Compile(script, &origin2); script2->Run(); script2->SetData(data_obj->ToString()); - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); f->Call(env->Global(), 0, NULL); CHECK_EQ(3, break_point_hit_count); CHECK_EQ("new name", last_script_name_hit); CHECK_EQ("abc 123", last_script_data_hit); - v8::Handle<v8::Script> script3 = - v8::Script::Compile(script, &origin2, NULL, - v8::String::New("in compile")); + v8::Handle<v8::Script> script3 = v8::Script::Compile( + script, &origin2, NULL, + v8::String::NewFromUtf8(env->GetIsolate(), "in compile")); CHECK_EQ("in compile", last_script_data_hit); script3->Run(); - f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); f->Call(env->Global(), 0, NULL); CHECK_EQ(4, break_point_hit_count); CHECK_EQ("in compile", last_script_data_hit); @@ -6259,8 +6365,8 @@ TEST(ContextData) { CHECK(context_2->GetEmbedderData(0)->IsUndefined()); // Set and check different data values. - v8::Handle<v8::String> data_1 = v8::String::New("1"); - v8::Handle<v8::String> data_2 = v8::String::New("2"); + v8::Handle<v8::String> data_1 = v8::String::NewFromUtf8(isolate, "1"); + v8::Handle<v8::String> data_2 = v8::String::NewFromUtf8(isolate, "2"); context_1->SetEmbedderData(0, data_1); context_2->SetEmbedderData(0, data_2); CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1)); @@ -6274,7 +6380,7 @@ TEST(ContextData) { v8::Context::Scope context_scope(context_1); expected_context = context_1; expected_context_data = data_1; - v8::Local<v8::Function> f = CompileFunction(source, "f"); + v8::Local<v8::Function> f = CompileFunction(isolate, source, "f"); f->Call(context_1->Global(), 0, NULL); } @@ -6284,7 +6390,7 @@ TEST(ContextData) { v8::Context::Scope context_scope(context_2); expected_context = context_2; expected_context_data = data_2; - v8::Local<v8::Function> f = CompileFunction(source, "f"); + v8::Local<v8::Function> f = CompileFunction(isolate, source, "f"); f->Call(context_2->Global(), 0, NULL); } @@ -6325,10 +6431,10 @@ TEST(DebugBreakInMessageHandler) { // Test functions. const char* script = "function f() { debugger; g(); } function g() { }"; CompileRun(script); - v8::Local<v8::Function> f = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); - v8::Local<v8::Function> g = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); + v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); // Call f then g. The debugger statement in f will casue a break which will // cause another break. @@ -6355,7 +6461,9 @@ static void DebugEventDebugBreak( if (!frame_function_name.IsEmpty()) { // Get the name of the function. const int argc = 2; - v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; + v8::Handle<v8::Value> argv[argc] = { + exec_state, v8::Integer::New(CcTest::isolate(), 0) + }; v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, argc, argv); if (result->IsUndefined()) { @@ -6391,9 +6499,10 @@ TEST(RegExpDebugBreak) { "var sourceLineBeginningSkip = /^(?:[ \\v\\h]*(?:\\/\\*.*?\\*\\/)*)*/;\n" "function f(s) { return s.match(sourceLineBeginningSkip)[0].length; }"; - v8::Local<v8::Function> f = CompileFunction(script, "f"); + v8::Local<v8::Function> f = CompileFunction(env->GetIsolate(), script, "f"); const int argc = 1; - v8::Handle<v8::Value> argv[argc] = { v8::String::New(" /* xxx */ a=0;") }; + v8::Handle<v8::Value> argv[argc] = { + v8::String::NewFromUtf8(env->GetIsolate(), " /* xxx */ a=0;")}; v8::Local<v8::Value> result = f->Call(env->Global(), argc, argv); CHECK_EQ(12, result->Int32Value()); @@ -6425,7 +6534,8 @@ static void ExecuteScriptForContextCheck( CHECK(context_1->GetEmbedderData(0)->IsUndefined()); // Set and check a data value. - v8::Handle<v8::String> data_1 = v8::String::New("1"); + v8::Handle<v8::String> data_1 = + v8::String::NewFromUtf8(CcTest::isolate(), "1"); context_1->SetEmbedderData(0, data_1); CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1)); @@ -6437,7 +6547,7 @@ static void ExecuteScriptForContextCheck( v8::Context::Scope context_scope(context_1); expected_context = context_1; expected_context_data = data_1; - v8::Local<v8::Function> f = CompileFunction(source, "f"); + v8::Local<v8::Function> f = CompileFunction(CcTest::isolate(), source, "f"); f->Call(context_1->Global(), 0, NULL); } @@ -6558,8 +6668,10 @@ TEST(ScriptCollectedEvent) { script_collected_count = 0; v8::Debug::SetDebugEventListener2(DebugEventScriptCollectedEvent); { - v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); - v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), "eval('a=1')"))->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(env->GetIsolate(), "eval('a=2')"))->Run(); } // Do garbage collection to collect the script above which is no longer @@ -6618,8 +6730,8 @@ TEST(ScriptCollectedEventContext) { CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler); - v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); - v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, "eval('a=1')"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(isolate, "eval('a=2')"))->Run(); // Leave context { @@ -6628,7 +6740,7 @@ TEST(ScriptCollectedEventContext) { v8::Local<v8::Context>::New(isolate, context); local_context->Exit(); } - context.Dispose(); + context.Reset(); // Do garbage collection to collect the script above which is no longer // referenced. @@ -6663,12 +6775,14 @@ TEST(AfterCompileMessageWhenMessageHandlerIsReset) { const char* script = "var a=1"; v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); - v8::Script::Compile(v8::String::New(script))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) + ->Run(); v8::Debug::SetMessageHandler2(NULL); v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); v8::Debug::DebugBreak(env->GetIsolate()); - v8::Script::Compile(v8::String::New(script))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) + ->Run(); // Setting listener to NULL should cause debugger unload. v8::Debug::SetMessageHandler2(NULL); @@ -6687,13 +6801,14 @@ TEST(BreakMessageWhenMessageHandlerIsReset) { const char* script = "function f() {};"; v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); - v8::Script::Compile(v8::String::New(script))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) + ->Run(); v8::Debug::SetMessageHandler2(NULL); v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); v8::Debug::DebugBreak(env->GetIsolate()); - v8::Local<v8::Function> f = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); f->Call(env->Global(), 0, NULL); // Setting message handler to NULL should cause debugger unload. @@ -6726,12 +6841,13 @@ TEST(ExceptionMessageWhenMessageHandlerIsReset) { const char* script = "function f() {throw new Error()};"; v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); - v8::Script::Compile(v8::String::New(script))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) + ->Run(); v8::Debug::SetMessageHandler2(NULL); v8::Debug::SetMessageHandler2(ExceptionMessageHandler); - v8::Local<v8::Function> f = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); f->Call(env->Global(), 0, NULL); // Setting message handler to NULL should cause debugger unload. @@ -6753,28 +6869,30 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) { // Set a couple of provisional breakpoint on lines out of the script lines // range. - int sbp1 = SetScriptBreakPointByNameFromJS(resource_name, 3, - -1 /* no column */); - int sbp2 = SetScriptBreakPointByNameFromJS(resource_name, 5, 5); + int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, + 3, -1 /* no column */); + int sbp2 = + SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, 5, 5); after_compile_message_count = 0; v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); v8::ScriptOrigin origin( - v8::String::New(resource_name), - v8::Integer::New(10), - v8::Integer::New(1)); + v8::String::NewFromUtf8(env->GetIsolate(), resource_name), + v8::Integer::New(env->GetIsolate(), 10), + v8::Integer::New(env->GetIsolate(), 1)); // Compile a script whose first line number is greater than the breakpoints' // lines. - v8::Script::Compile(v8::String::New(script), &origin)->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script), + &origin)->Run(); // If the script is compiled successfully there is exactly one after compile // event. In case of an exception in debugger code after compile event is not // sent. CHECK_EQ(1, after_compile_message_count); - ClearBreakPointFromJS(sbp1); - ClearBreakPointFromJS(sbp2); + ClearBreakPointFromJS(env->GetIsolate(), sbp1); + ClearBreakPointFromJS(env->GetIsolate(), sbp2); v8::Debug::SetMessageHandler2(NULL); } @@ -6932,7 +7050,8 @@ TEST(Backtrace) { v8::Debug::ProcessDebugMessages(); CHECK_EQ(BacktraceData::frame_counter, 0); - v8::Handle<v8::String> void0 = v8::String::New("void(0)"); + v8::Handle<v8::String> void0 = + v8::String::NewFromUtf8(env->GetIsolate(), "void(0)"); v8::Handle<v8::Script> script = v8::Script::Compile(void0, void0); // Check backtrace from "void(0)" script. @@ -6954,10 +7073,12 @@ TEST(Backtrace) { TEST(GetMirror) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Handle<v8::Value> obj = v8::Debug::GetMirror(v8::String::New("hodja")); - v8::Handle<v8::Function> run_test = v8::Handle<v8::Function>::Cast( - v8::Script::New( - v8::String::New( + v8::Handle<v8::Value> obj = + v8::Debug::GetMirror(v8::String::NewFromUtf8(env->GetIsolate(), "hodja")); + v8::Handle<v8::Function> run_test = + v8::Handle<v8::Function>::Cast(v8::Script::New( + v8::String::NewFromUtf8( + env->GetIsolate(), "function runTest(mirror) {" " return mirror.isString() && (mirror.length() == 5);" "}" @@ -7048,7 +7169,8 @@ TEST(CallingContextIsNotDebugContext) { v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // Create and enter a debugee context. DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); env.ExposeDebug(); // Save handles to the debugger and debugee contexts to be used in @@ -7057,10 +7179,10 @@ TEST(CallingContextIsNotDebugContext) { debugger_context = v8::Utils::ToLocal(debug->debug_context()); // Create object with 'a' property accessor. - v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(); - named->SetAccessor(v8::String::New("a"), + v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); + named->SetAccessor(v8::String::NewFromUtf8(isolate, "a"), NamedGetterWithCallingContextCheck); - env->Global()->Set(v8::String::New("obj"), + env->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), named->NewInstance()); // Register the debug event listener @@ -7103,12 +7225,13 @@ static void DebugEventContextChecker(const v8::Debug::EventDetails& details) { TEST(DebugEventContext) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - expected_callback_data = v8::Int32::New(2010); expected_context = v8::Context::New(isolate); + expected_callback_data = v8::Int32::New(isolate, 2010); v8::Debug::SetDebugEventListener2(DebugEventContextChecker, expected_callback_data); v8::Context::Scope context_scope(expected_context); - v8::Script::Compile(v8::String::New("(function(){debugger;})();"))->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(isolate, "(function(){debugger;})();"))->Run(); expected_context.Clear(); v8::Debug::SetDebugEventListener2(NULL); expected_context_data = v8::Handle<v8::Value>(); @@ -7143,7 +7266,9 @@ TEST(DebugEventBreakData) { was_debug_event_called = false; was_debug_break_called = false; v8::Debug::DebugBreakForCommand(NULL, isolate); - v8::Script::Compile(v8::String::New("(function(x){return x;})(1);"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + "(function(x){return x;})(1);")) + ->Run(); CHECK(was_debug_event_called); CHECK(!was_debug_break_called); @@ -7152,7 +7277,9 @@ TEST(DebugEventBreakData) { was_debug_event_called = false; was_debug_break_called = false; v8::Debug::DebugBreakForCommand(data1, isolate); - v8::Script::Compile(v8::String::New("(function(x){return x+1;})(1);"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + "(function(x){return x+1;})(1);")) + ->Run(); CHECK(was_debug_event_called); CHECK(!was_debug_break_called); @@ -7160,7 +7287,9 @@ TEST(DebugEventBreakData) { was_debug_event_called = false; was_debug_break_called = false; v8::Debug::DebugBreak(isolate); - v8::Script::Compile(v8::String::New("(function(x){return x+2;})(1);"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + "(function(x){return x+2;})(1);")) + ->Run(); CHECK(!was_debug_event_called); CHECK(was_debug_break_called); @@ -7170,7 +7299,9 @@ TEST(DebugEventBreakData) { was_debug_break_called = false; v8::Debug::DebugBreak(isolate); v8::Debug::DebugBreakForCommand(data2, isolate); - v8::Script::Compile(v8::String::New("(function(x){return x+3;})(1);"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + "(function(x){return x+3;})(1);")) + ->Run(); CHECK(was_debug_event_called); CHECK(was_debug_break_called); @@ -7192,7 +7323,9 @@ static void DebugEventBreakDeoptimize( if (!frame_function_name.IsEmpty()) { // Get the name of the function. const int argc = 2; - v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; + v8::Handle<v8::Value> argv[argc] = { + exec_state, v8::Integer::New(CcTest::isolate(), 0) + }; v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, argc, argv); if (!result->IsUndefined()) { @@ -7233,11 +7366,13 @@ TEST(DeoptimizeDuringDebugBreak) { v8::Debug::SetDebugEventListener2(DebugEventBreakDeoptimize); // Compile and run function bar which will optimize it for some flag settings. - v8::Script::Compile(v8::String::New("function bar(){}; bar()"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8( + env->GetIsolate(), "function bar(){}; bar()"))->Run(); // Set debug break and call bar again. v8::Debug::DebugBreak(env->GetIsolate()); - v8::Script::Compile(v8::String::New("bar()"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "bar()")) + ->Run(); CHECK(debug_event_break_deoptimize_done); @@ -7247,24 +7382,27 @@ TEST(DeoptimizeDuringDebugBreak) { static void DebugEventBreakWithOptimizedStack( const v8::Debug::EventDetails& event_details) { + v8::Isolate* isolate = event_details.GetEventContext()->GetIsolate(); v8::DebugEvent event = event_details.GetEvent(); v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); if (event == v8::Break) { if (!frame_function_name.IsEmpty()) { for (int i = 0; i < 2; i++) { const int argc = 2; - v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(i) }; + v8::Handle<v8::Value> argv[argc] = { + exec_state, v8::Integer::New(isolate, i) + }; // Get the name of the function in frame i. v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, argc, argv); CHECK(result->IsString()); v8::Handle<v8::String> function_name(result->ToString()); - CHECK(function_name->Equals(v8::String::New("loop"))); + CHECK(function_name->Equals(v8::String::NewFromUtf8(isolate, "loop"))); // Get the name of the first argument in frame i. result = frame_argument_name->Call(exec_state, argc, argv); CHECK(result->IsString()); v8::Handle<v8::String> argument_name(result->ToString()); - CHECK(argument_name->Equals(v8::String::New("count"))); + CHECK(argument_name->Equals(v8::String::NewFromUtf8(isolate, "count"))); // Get the value of the first argument in frame i. If the // funtion is optimized the value will be undefined, otherwise // the value will be '1 - i'. @@ -7277,7 +7415,7 @@ static void DebugEventBreakWithOptimizedStack( result = frame_local_name->Call(exec_state, argc, argv); CHECK(result->IsString()); v8::Handle<v8::String> local_name(result->ToString()); - CHECK(local_name->Equals(v8::String::New("local"))); + CHECK(local_name->Equals(v8::String::NewFromUtf8(isolate, "local"))); // Get the value of the first local variable. If the function // is optimized the value will be undefined, otherwise it will // be 42. @@ -7315,7 +7453,7 @@ TEST(DebugBreakStackInspection) { CompileFunction(&env, frame_local_value_source, "frame_local_value"); v8::Handle<v8::FunctionTemplate> schedule_break_template = - v8::FunctionTemplate::New(ScheduleBreak); + v8::FunctionTemplate::New(env->GetIsolate(), ScheduleBreak); v8::Handle<v8::Function> schedule_break = schedule_break_template->GetFunction(); env->Global()->Set(v8_str("scheduleBreak"), schedule_break); @@ -7326,7 +7464,7 @@ TEST(DebugBreakStackInspection) { " if (count < 1) { scheduleBreak(); loop(count + 1); }" "}" "loop(0);"; - v8::Script::Compile(v8::String::New(src))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), src))->Run(); } @@ -7340,9 +7478,9 @@ static void TestDebugBreakInLoop(const char* loop_head, for (int i = 0; loop_bodies[i] != NULL; i++) { // Perform a lazy deoptimization after various numbers of breaks // have been hit. - for (int j = 0; j < 11; j++) { + for (int j = 0; j < 7; j++) { break_point_hit_count_deoptimize = j; - if (j == 10) { + if (j == 6) { break_point_hit_count_deoptimize = kBreaksPerTest; } @@ -7470,7 +7608,8 @@ TEST(DebugBreakInline) { "%OptimizeFunctionOnNextCall(g); \n" "g(true);"; v8::Debug::SetDebugEventListener2(DebugBreakInlineListener); - inline_script = v8::Script::Compile(v8::String::New(source)); + inline_script = + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source)); inline_script->Run(); } @@ -7556,7 +7695,7 @@ TEST(LiveEditDisabled) { v8::internal::FLAG_allow_natives_syntax = true; LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetLiveEditEnabled(false), env->GetIsolate(); + v8::Debug::SetLiveEditEnabled(false, env->GetIsolate()); CompileRun("%LiveEditCompareStrings('', '')"); } diff --git a/deps/v8/test/cctest/test-declarative-accessors.cc b/deps/v8/test/cctest/test-declarative-accessors.cc index fb22ccdbab..f2169a9fb8 100644 --- a/deps/v8/test/cctest/test-declarative-accessors.cc +++ b/deps/v8/test/cctest/test-declarative-accessors.cc @@ -42,8 +42,7 @@ class HandleArray : public Malloced { void Reset() { for (unsigned i = 0; i < kArraySize; i++) { if (handles_[i].IsEmpty()) continue; - handles_[i].Dispose(); - handles_[i].Clear(); + handles_[i].Reset(); } } v8::Persistent<v8::Value> handles_[kArraySize]; @@ -96,7 +95,8 @@ static v8::Local<v8::ObjectTemplate> CreateConstructor( const char* descriptor_name = NULL, v8::Handle<v8::DeclaredAccessorDescriptor> descriptor = v8::Handle<v8::DeclaredAccessorDescriptor>()) { - v8::Local<v8::FunctionTemplate> constructor = v8::FunctionTemplate::New(); + v8::Local<v8::FunctionTemplate> constructor = + v8::FunctionTemplate::New(context->GetIsolate()); v8::Local<v8::ObjectTemplate> obj_template = constructor->InstanceTemplate(); // Setup object template. if (descriptor_name != NULL && !descriptor.IsEmpty()) { @@ -147,17 +147,17 @@ static void VerifyRead(v8::Handle<v8::DeclaredAccessorDescriptor> descriptor, static v8::Handle<v8::Value> Convert(int32_t value, v8::Isolate* isolate) { - return v8::Integer::New(value, isolate); + return v8::Integer::New(isolate, value); } -static v8::Handle<v8::Value> Convert(float value, v8::Isolate*) { - return v8::Number::New(value); +static v8::Handle<v8::Value> Convert(float value, v8::Isolate* isolate) { + return v8::Number::New(isolate, value); } -static v8::Handle<v8::Value> Convert(double value, v8::Isolate*) { - return v8::Number::New(value); +static v8::Handle<v8::Value> Convert(double value, v8::Isolate* isolate) { + return v8::Number::New(isolate, value); } @@ -178,7 +178,7 @@ static void TestPrimitiveValue( v8::Handle<v8::Value> expected = Convert(value, helper->isolate_); helper->array_->Reset(); helper->array_->As<T*>()[index] = value; - VerifyRead(descriptor, internal_field, *helper->array_, expected); + VerifyRead(descriptor, internal_field, helper->array_.get(), expected); } @@ -224,7 +224,7 @@ static void TestBitmaskCompare(T bitmask, CHECK(false); break; } - AlignedArray* array = *helper->array_; + AlignedArray* array = helper->array_.get(); array->Reset(); VerifyRead(descriptor, internal_field, array, v8::False(helper->isolate_)); array->As<T*>()[index] = compare_value; @@ -252,7 +252,7 @@ TEST(PointerCompareRead) { OOD::NewInternalFieldDereference(helper.isolate_, internal_field) ->NewRawShift(helper.isolate_, static_cast<uint16_t>(index*sizeof(ptr))) ->NewPointerCompare(helper.isolate_, ptr); - AlignedArray* array = *helper.array_; + AlignedArray* array = helper.array_.get(); VerifyRead(descriptor, internal_field, array, v8::False(helper.isolate_)); array->As<uintptr_t*>()[index] = reinterpret_cast<uintptr_t>(ptr); VerifyRead(descriptor, internal_field, array, v8::True(helper.isolate_)); @@ -274,13 +274,15 @@ TEST(PointerDereferenceRead) { ->NewRawShift(helper.isolate_, static_cast<uint16_t>(second_index*sizeof(int16_t))) ->NewPrimitiveValue(helper.isolate_, v8::kDescriptorInt16Type, 0); - AlignedArray* array = *helper.array_; + AlignedArray* array = helper.array_.get(); array->As<uintptr_t**>()[first_index] = &array->As<uintptr_t*>()[pointed_to_index]; - VerifyRead(descriptor, internal_field, array, v8::Integer::New(0)); + VerifyRead(descriptor, internal_field, array, + v8::Integer::New(helper.isolate_, 0)); second_index += pointed_to_index*sizeof(uintptr_t)/sizeof(uint16_t); array->As<uint16_t*>()[second_index] = expected; - VerifyRead(descriptor, internal_field, array, v8::Integer::New(expected)); + VerifyRead(descriptor, internal_field, array, + v8::Integer::New(helper.isolate_, expected)); } @@ -293,7 +295,7 @@ TEST(HandleDereferenceRead) { OOD::NewInternalFieldDereference(helper.isolate_, internal_field) ->NewRawShift(helper.isolate_, index*kPointerSize) ->NewHandleDereference(helper.isolate_); - HandleArray* array = *helper.handle_array_; + HandleArray* array = helper.handle_array_.get(); v8::Handle<v8::String> expected = v8_str("whatever"); array->handles_[index].Reset(helper.isolate_, expected); VerifyRead(descriptor, internal_field, array, expected); diff --git a/deps/v8/test/cctest/test-decls.cc b/deps/v8/test/cctest/test-decls.cc index de27286dac..1f22c9ff3a 100644 --- a/deps/v8/test/cctest/test-decls.cc +++ b/deps/v8/test/cctest/test-decls.cc @@ -56,7 +56,7 @@ class DeclarationContext { HandleScope scope(isolate); Local<Context> context = Local<Context>::New(isolate, context_); context->Exit(); - context_.Dispose(); + context_.Reset(); } } @@ -96,6 +96,8 @@ class DeclarationContext { static void HandleQuery(Local<String> key, const v8::PropertyCallbackInfo<v8::Integer>& info); + v8::Isolate* isolate() const { return CcTest::isolate(); } + private: bool is_initialized_; Persistent<Context> context_; @@ -118,8 +120,8 @@ void DeclarationContext::InitializeIfNeeded() { if (is_initialized_) return; Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); - Local<FunctionTemplate> function = FunctionTemplate::New(); - Local<Value> data = External::New(this); + Local<FunctionTemplate> function = FunctionTemplate::New(isolate); + Local<Value> data = External::New(CcTest::isolate(), this); GetHolder(function)->SetNamedPropertyHandler(&HandleGet, &HandleSet, &HandleQuery, @@ -147,7 +149,8 @@ void DeclarationContext::Check(const char* source, HandleScope scope(CcTest::isolate()); TryCatch catcher; catcher.SetVerbose(true); - Local<Script> script = Script::Compile(String::New(source)); + Local<Script> script = + Script::Compile(String::NewFromUtf8(CcTest::isolate(), source)); if (expectations == EXPECT_ERROR) { CHECK(script.IsEmpty()); return; @@ -243,7 +246,7 @@ TEST(Unknown) { 1, // access 2, // declaration + initialization 2, // declaration + initialization - EXPECT_RESULT, Number::New(0)); + EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); } { DeclarationContext context; @@ -277,7 +280,7 @@ TEST(Unknown) { class PresentPropertyContext: public DeclarationContext { protected: virtual v8::Handle<Integer> Query(Local<String> key) { - return Integer::New(v8::None); + return Integer::New(isolate(), v8::None); } }; @@ -299,7 +302,7 @@ TEST(Present) { 1, // access 1, // initialization 2, // declaration + initialization - EXPECT_RESULT, Number::New(0)); + EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); } { PresentPropertyContext context; @@ -323,7 +326,7 @@ TEST(Present) { 1, // access 1, // initialization 1, // (re-)declaration - EXPECT_RESULT, Number::New(0)); + EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); } } @@ -355,7 +358,7 @@ TEST(Absent) { 1, // access 2, // declaration + initialization 2, // declaration + initialization - EXPECT_RESULT, Number::New(0)); + EXPECT_RESULT, Number::New(isolate, 0)); } { AbsentPropertyContext context; @@ -415,7 +418,7 @@ class AppearingPropertyContext: public DeclarationContext { // Return that the property is present so we only get the // setter called when initializing with a value. state_ = UNKNOWN; - return Integer::New(v8::None); + return Integer::New(isolate(), v8::None); default: CHECK(state_ == UNKNOWN); break; @@ -446,7 +449,7 @@ TEST(Appearing) { 1, // access 2, // declaration + initialization 2, // declaration + initialization - EXPECT_RESULT, Number::New(0)); + EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); } { AppearingPropertyContext context; @@ -501,7 +504,7 @@ class ReappearingPropertyContext: public DeclarationContext { // Ignore the second declaration by returning // that the property is already there. state_ = INITIALIZE; - return Integer::New(v8::None); + return Integer::New(isolate(), v8::None); case INITIALIZE: // Force an initialization by returning that // the property is absent. This will make sure @@ -538,10 +541,12 @@ TEST(Reappearing) { class ExistsInPrototypeContext: public DeclarationContext { + public: + ExistsInPrototypeContext() { InitializeIfNeeded(); } protected: virtual v8::Handle<Integer> Query(Local<String> key) { // Let it seem that the property exists in the prototype object. - return Integer::New(v8::None); + return Integer::New(isolate(), v8::None); } // Use the prototype as the holder for the interceptors. @@ -562,7 +567,7 @@ TEST(ExistsInPrototype) { 0, 0, 0, - EXPECT_RESULT, Number::New(87)); + EXPECT_RESULT, Number::New(CcTest::isolate(), 87)); } { ExistsInPrototypeContext context; @@ -578,7 +583,7 @@ TEST(ExistsInPrototype) { 0, 0, 0, - EXPECT_RESULT, Number::New(0)); + EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); } { ExistsInPrototypeContext context; @@ -594,7 +599,7 @@ TEST(ExistsInPrototype) { 0, 0, 0, - EXPECT_RESULT, Number::New(0)); + EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); } } @@ -633,23 +638,23 @@ TEST(AbsentInPrototype) { class ExistsInHiddenPrototypeContext: public DeclarationContext { public: ExistsInHiddenPrototypeContext() { - hidden_proto_ = FunctionTemplate::New(); + hidden_proto_ = FunctionTemplate::New(CcTest::isolate()); hidden_proto_->SetHiddenPrototype(true); } protected: virtual v8::Handle<Integer> Query(Local<String> key) { // Let it seem that the property exists in the hidden prototype object. - return Integer::New(v8::None); + return Integer::New(isolate(), v8::None); } // Install the hidden prototype after the global object has been created. virtual void PostInitializeContext(Handle<Context> context) { Local<Object> global_object = context->Global(); Local<Object> hidden_proto = hidden_proto_->GetFunction()->NewInstance(); - context->DetachGlobal(); - context->Global()->SetPrototype(hidden_proto); - context->ReattachGlobal(global_object); + Local<Object> inner_global = + Local<Object>::Cast(global_object->GetPrototype()); + inner_global->SetPrototype(hidden_proto); } // Use the hidden prototype as the holder for the interceptors. @@ -679,7 +684,7 @@ TEST(ExistsInHiddenPrototype) { 1, // access 1, // initialization 2, // declaration + initialization - EXPECT_RESULT, Number::New(0)); + EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); } { ExistsInHiddenPrototypeContext context; @@ -705,7 +710,7 @@ TEST(ExistsInHiddenPrototype) { 0, 0, 1, // (re-)declaration - EXPECT_RESULT, Number::New(0)); + EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); } } @@ -729,7 +734,8 @@ class SimpleContext { HandleScope scope(context_->GetIsolate()); TryCatch catcher; catcher.SetVerbose(true); - Local<Script> script = Script::Compile(String::New(source)); + Local<Script> script = + Script::Compile(String::NewFromUtf8(context_->GetIsolate(), source)); if (expectations == EXPECT_ERROR) { CHECK(script.IsEmpty()); return; @@ -757,40 +763,41 @@ class SimpleContext { TEST(CrossScriptReferences) { - HandleScope scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); { SimpleContext context; context.Check("var x = 1; x", - EXPECT_RESULT, Number::New(1)); + EXPECT_RESULT, Number::New(isolate, 1)); context.Check("var x = 2; x", - EXPECT_RESULT, Number::New(2)); + EXPECT_RESULT, Number::New(isolate, 2)); context.Check("const x = 3; x", - EXPECT_RESULT, Number::New(3)); + EXPECT_RESULT, Number::New(isolate, 3)); context.Check("const x = 4; x", - EXPECT_RESULT, Number::New(4)); + EXPECT_RESULT, Number::New(isolate, 4)); context.Check("x = 5; x", - EXPECT_RESULT, Number::New(5)); + EXPECT_RESULT, Number::New(isolate, 5)); context.Check("var x = 6; x", - EXPECT_RESULT, Number::New(6)); + EXPECT_RESULT, Number::New(isolate, 6)); context.Check("this.x", - EXPECT_RESULT, Number::New(6)); + EXPECT_RESULT, Number::New(isolate, 6)); context.Check("function x() { return 7 }; x()", - EXPECT_RESULT, Number::New(7)); + EXPECT_RESULT, Number::New(isolate, 7)); } { SimpleContext context; context.Check("const x = 1; x", - EXPECT_RESULT, Number::New(1)); + EXPECT_RESULT, Number::New(isolate, 1)); context.Check("var x = 2; x", // assignment ignored - EXPECT_RESULT, Number::New(1)); + EXPECT_RESULT, Number::New(isolate, 1)); context.Check("const x = 3; x", - EXPECT_RESULT, Number::New(1)); + EXPECT_RESULT, Number::New(isolate, 1)); context.Check("x = 4; x", // assignment ignored - EXPECT_RESULT, Number::New(1)); + EXPECT_RESULT, Number::New(isolate, 1)); context.Check("var x = 5; x", // assignment ignored - EXPECT_RESULT, Number::New(1)); + EXPECT_RESULT, Number::New(isolate, 1)); context.Check("this.x", - EXPECT_RESULT, Number::New(1)); + EXPECT_RESULT, Number::New(isolate, 1)); context.Check("function x() { return 7 }; x", EXPECT_EXCEPTION); } @@ -802,7 +809,8 @@ TEST(CrossScriptReferencesHarmony) { i::FLAG_harmony_scoping = true; i::FLAG_harmony_modules = true; - HandleScope scope(CcTest::isolate()); + v8::Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); const char* decs[] = { "var x = 1; x", "x", "this.x", @@ -815,12 +823,14 @@ TEST(CrossScriptReferencesHarmony) { for (int i = 0; decs[i] != NULL; i += 3) { SimpleContext context; - context.Check(decs[i], EXPECT_RESULT, Number::New(1)); - context.Check(decs[i+1], EXPECT_RESULT, Number::New(1)); + context.Check(decs[i], EXPECT_RESULT, Number::New(isolate, 1)); + context.Check(decs[i+1], EXPECT_RESULT, Number::New(isolate, 1)); // TODO(rossberg): The current ES6 draft spec does not reflect lexical // bindings on the global object. However, this will probably change, in // which case we reactivate the following test. - if (i/3 < 2) context.Check(decs[i+2], EXPECT_RESULT, Number::New(1)); + if (i/3 < 2) { + context.Check(decs[i+2], EXPECT_RESULT, Number::New(isolate, 1)); + } } } @@ -852,12 +862,14 @@ TEST(CrossScriptConflicts) { for (int i = 0; firsts[i] != NULL; ++i) { for (int j = 0; seconds[j] != NULL; ++j) { SimpleContext context; - context.Check(firsts[i], EXPECT_RESULT, Number::New(1)); + context.Check(firsts[i], EXPECT_RESULT, + Number::New(CcTest::isolate(), 1)); // TODO(rossberg): All tests should actually be errors in Harmony, // but we currently do not detect the cases where the first declaration // is not lexical. context.Check(seconds[j], - i < 2 ? EXPECT_RESULT : EXPECT_ERROR, Number::New(2)); + i < 2 ? EXPECT_RESULT : EXPECT_ERROR, + Number::New(CcTest::isolate(), 2)); } } } diff --git a/deps/v8/test/cctest/test-deoptimization.cc b/deps/v8/test/cctest/test-deoptimization.cc index 765b1ce55f..dbbb3edb09 100644 --- a/deps/v8/test/cctest/test-deoptimization.cc +++ b/deps/v8/test/cctest/test-deoptimization.cc @@ -77,27 +77,23 @@ class AlwaysOptimizeAllowNativesSyntaxNoInlining { // Utility class to set --allow-natives-syntax and --nouse-inlining when // constructed and return to their default state when destroyed. -class AllowNativesSyntaxNoInliningNoConcurrent { +class AllowNativesSyntaxNoInlining { public: - AllowNativesSyntaxNoInliningNoConcurrent() + AllowNativesSyntaxNoInlining() : allow_natives_syntax_(i::FLAG_allow_natives_syntax), - use_inlining_(i::FLAG_use_inlining), - concurrent_recompilation_(i::FLAG_concurrent_recompilation) { + use_inlining_(i::FLAG_use_inlining) { i::FLAG_allow_natives_syntax = true; i::FLAG_use_inlining = false; - i::FLAG_concurrent_recompilation = false; } - ~AllowNativesSyntaxNoInliningNoConcurrent() { + ~AllowNativesSyntaxNoInlining() { i::FLAG_allow_natives_syntax = allow_natives_syntax_; i::FLAG_use_inlining = use_inlining_; - i::FLAG_concurrent_recompilation = concurrent_recompilation_; } private: bool allow_natives_syntax_; bool use_inlining_; - bool concurrent_recompilation_; }; @@ -239,8 +235,8 @@ TEST(DeoptimizeRecursive) { CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); - v8::Local<v8::Function> fun = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); + v8::Local<v8::Function> fun = v8::Local<v8::Function>::Cast( + env->Global()->Get(v8::String::NewFromUtf8(CcTest::isolate(), "f"))); CHECK(!fun.IsEmpty()); } @@ -341,13 +337,14 @@ TEST(DeoptimizeConstructorMultiple) { TEST(DeoptimizeBinaryOperationADDString) { + i::FLAG_concurrent_recompilation = false; + AllowNativesSyntaxNoInlining options; LocalContext env; v8::HandleScope scope(env->GetIsolate()); const char* f_source = "function f(x, y) { return x + y; };"; { - AllowNativesSyntaxNoInliningNoConcurrent options; // Compile function f and collect to type feedback to insert binary op stub // call in the optimized code. i::FLAG_prepare_always_opt = true; @@ -405,7 +402,7 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env, binary_op); char* f_source = f_source_buffer.start(); - AllowNativesSyntaxNoInliningNoConcurrent options; + AllowNativesSyntaxNoInlining options; // Compile function f and collect to type feedback to insert binary op stub // call in the optimized code. i::FLAG_prepare_always_opt = true; @@ -431,6 +428,7 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env, TEST(DeoptimizeBinaryOperationADD) { + i::FLAG_concurrent_recompilation = false; LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -443,6 +441,7 @@ TEST(DeoptimizeBinaryOperationADD) { TEST(DeoptimizeBinaryOperationSUB) { + i::FLAG_concurrent_recompilation = false; LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -455,6 +454,7 @@ TEST(DeoptimizeBinaryOperationSUB) { TEST(DeoptimizeBinaryOperationMUL) { + i::FLAG_concurrent_recompilation = false; LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -467,6 +467,7 @@ TEST(DeoptimizeBinaryOperationMUL) { TEST(DeoptimizeBinaryOperationDIV) { + i::FLAG_concurrent_recompilation = false; LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -479,6 +480,7 @@ TEST(DeoptimizeBinaryOperationDIV) { TEST(DeoptimizeBinaryOperationMOD) { + i::FLAG_concurrent_recompilation = false; LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -491,13 +493,14 @@ TEST(DeoptimizeBinaryOperationMOD) { TEST(DeoptimizeCompare) { + i::FLAG_concurrent_recompilation = false; LocalContext env; v8::HandleScope scope(env->GetIsolate()); const char* f_source = "function f(x, y) { return x < y; };"; { - AllowNativesSyntaxNoInliningNoConcurrent options; + AllowNativesSyntaxNoInlining options; // Compile function f and collect to type feedback to insert compare ic // call in the optimized code. i::FLAG_prepare_always_opt = true; @@ -534,6 +537,7 @@ TEST(DeoptimizeCompare) { TEST(DeoptimizeLoadICStoreIC) { + i::FLAG_concurrent_recompilation = false; LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -544,7 +548,7 @@ TEST(DeoptimizeLoadICStoreIC) { const char* g2_source = "function g2(x, y) { x[y] = 1; };"; { - AllowNativesSyntaxNoInliningNoConcurrent options; + AllowNativesSyntaxNoInlining options; // Compile functions and collect to type feedback to insert ic // calls in the optimized code. i::FLAG_prepare_always_opt = true; @@ -609,11 +613,11 @@ TEST(DeoptimizeLoadICStoreIC) { CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } TEST(DeoptimizeLoadICStoreICNested) { + i::FLAG_concurrent_recompilation = false; LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -624,7 +628,7 @@ TEST(DeoptimizeLoadICStoreICNested) { const char* g2_source = "function g2(x, y) { x[y] = 1; };"; { - AllowNativesSyntaxNoInliningNoConcurrent options; + AllowNativesSyntaxNoInlining options; // Compile functions and collect to type feedback to insert ic // calls in the optimized code. i::FLAG_prepare_always_opt = true; @@ -690,5 +694,4 @@ TEST(DeoptimizeLoadICStoreICNested) { CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } diff --git a/deps/v8/test/cctest/test-dictionary.cc b/deps/v8/test/cctest/test-dictionary.cc index 44f64f7881..6e62a2243c 100644 --- a/deps/v8/test/cctest/test-dictionary.cc +++ b/deps/v8/test/cctest/test-dictionary.cc @@ -47,7 +47,7 @@ TEST(ObjectHashTable) { Handle<ObjectHashTable> table = factory->NewObjectHashTable(23); Handle<JSObject> a = factory->NewJSArray(7); Handle<JSObject> b = factory->NewJSArray(11); - table = PutIntoObjectHashTable(table, a, b); + table = ObjectHashTable::Put(table, a, b); CHECK_EQ(table->NumberOfElements(), 1); CHECK_EQ(table->Lookup(*a), *b); CHECK_EQ(table->Lookup(*b), CcTest::heap()->the_hole_value()); @@ -59,12 +59,12 @@ TEST(ObjectHashTable) { CHECK_EQ(table->Lookup(*b), CcTest::heap()->the_hole_value()); // Keys that are overwritten should not change number of elements. - table = PutIntoObjectHashTable(table, a, factory->NewJSArray(13)); + table = ObjectHashTable::Put(table, a, factory->NewJSArray(13)); CHECK_EQ(table->NumberOfElements(), 1); CHECK_NE(table->Lookup(*a), *b); // Keys mapped to the hole should be removed permanently. - table = PutIntoObjectHashTable(table, a, factory->the_hole_value()); + table = ObjectHashTable::Put(table, a, factory->the_hole_value()); CHECK_EQ(table->NumberOfElements(), 0); CHECK_EQ(table->NumberOfDeletedElements(), 1); CHECK_EQ(table->Lookup(*a), CcTest::heap()->the_hole_value()); @@ -74,21 +74,21 @@ TEST(ObjectHashTable) { for (int i = 0; i < 100; i++) { Handle<JSReceiver> key = factory->NewJSArray(7); Handle<JSObject> value = factory->NewJSArray(11); - table = PutIntoObjectHashTable(table, key, value); + table = ObjectHashTable::Put(table, key, value); CHECK_EQ(table->NumberOfElements(), i + 1); CHECK_NE(table->FindEntry(*key), ObjectHashTable::kNotFound); CHECK_EQ(table->Lookup(*key), *value); - CHECK(key->GetIdentityHash(OMIT_CREATION)->ToObjectChecked()->IsSmi()); + CHECK(key->GetIdentityHash()->IsSmi()); } // Keys never added to the map which already have an identity hash // code should not be found. for (int i = 0; i < 100; i++) { Handle<JSReceiver> key = factory->NewJSArray(7); - CHECK(key->GetIdentityHash(ALLOW_CREATION)->ToObjectChecked()->IsSmi()); + CHECK(JSReceiver::GetOrCreateIdentityHash(key)->IsSmi()); CHECK_EQ(table->FindEntry(*key), ObjectHashTable::kNotFound); CHECK_EQ(table->Lookup(*key), CcTest::heap()->the_hole_value()); - CHECK(key->GetIdentityHash(OMIT_CREATION)->ToObjectChecked()->IsSmi()); + CHECK(key->GetIdentityHash()->IsSmi()); } // Keys that don't have an identity hash should not be found and also @@ -96,7 +96,7 @@ TEST(ObjectHashTable) { for (int i = 0; i < 100; i++) { Handle<JSReceiver> key = factory->NewJSArray(7); CHECK_EQ(table->Lookup(*key), CcTest::heap()->the_hole_value()); - CHECK_EQ(key->GetIdentityHash(OMIT_CREATION), + CHECK_EQ(key->GetIdentityHash(), CcTest::heap()->undefined_value()); } } @@ -175,13 +175,17 @@ TEST(ObjectHashSetCausesGC) { SimulateFullSpace(CcTest::heap()->old_pointer_space()); // Calling Contains() should not cause GC ever. + int gc_count = isolate->heap()->gc_count(); CHECK(!table->Contains(*key)); + CHECK(gc_count == isolate->heap()->gc_count()); - // Calling Remove() should not cause GC ever. - CHECK(!table->Remove(*key)->IsFailure()); + // Calling Remove() will not cause GC in this case. + table = ObjectHashSet::Remove(table, key); + CHECK(gc_count == isolate->heap()->gc_count()); - // Calling Add() should request GC by returning a failure. - CHECK(table->Add(*key)->IsRetryAfterGC()); + // Calling Add() should cause GC. + table = ObjectHashSet::Add(table, key); + CHECK(gc_count < isolate->heap()->gc_count()); } #endif @@ -211,6 +215,8 @@ TEST(ObjectHashTableCausesGC) { CHECK(table->Lookup(*key)->IsTheHole()); // Calling Put() should request GC by returning a failure. - CHECK(table->Put(*key, *key)->IsRetryAfterGC()); + int gc_count = isolate->heap()->gc_count(); + ObjectHashTable::Put(table, key, key); + CHECK(gc_count < isolate->heap()->gc_count()); } #endif diff --git a/deps/v8/test/cctest/test-disasm-a64.cc b/deps/v8/test/cctest/test-disasm-a64.cc new file mode 100644 index 0000000000..0ada0b1a56 --- /dev/null +++ b/deps/v8/test/cctest/test-disasm-a64.cc @@ -0,0 +1,1761 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <stdio.h> +#include <cstring> +#include "cctest.h" + +#include "v8.h" + +#include "macro-assembler.h" +#include "a64/assembler-a64.h" +#include "a64/macro-assembler-a64.h" +#include "a64/disasm-a64.h" +#include "a64/utils-a64.h" + +using namespace v8::internal; + +#define TEST_(name) TEST(DISASM_##name) + +#define EXP_SIZE (256) +#define INSTR_SIZE (1024) +#define SET_UP_CLASS(ASMCLASS) \ + InitializeVM(); \ + Isolate* isolate = Isolate::Current(); \ + HandleScope scope(isolate); \ + byte* buf = static_cast<byte*>(malloc(INSTR_SIZE)); \ + uint32_t encoding = 0; \ + ASMCLASS* assm = new ASMCLASS(isolate, buf, INSTR_SIZE); \ + Decoder* decoder = new Decoder(); \ + Disassembler* disasm = new Disassembler(); \ + decoder->AppendVisitor(disasm) + +#define SET_UP() SET_UP_CLASS(Assembler) + +#define COMPARE(ASM, EXP) \ + assm->Reset(); \ + assm->ASM; \ + assm->GetCode(NULL); \ + decoder->Decode(reinterpret_cast<Instruction*>(buf)); \ + encoding = *reinterpret_cast<uint32_t*>(buf); \ + if (strcmp(disasm->GetOutput(), EXP) != 0) { \ + printf("%u : Encoding: %08" PRIx32 "\nExpected: %s\nFound: %s\n", \ + __LINE__, encoding, EXP, disasm->GetOutput()); \ + abort(); \ + } + +#define COMPARE_PREFIX(ASM, EXP) \ + assm->Reset(); \ + assm->ASM; \ + assm->GetCode(NULL); \ + decoder->Decode(reinterpret_cast<Instruction*>(buf)); \ + encoding = *reinterpret_cast<uint32_t*>(buf); \ + if (strncmp(disasm->GetOutput(), EXP, strlen(EXP)) != 0) { \ + printf("%u : Encoding: %08" PRIx32 "\nExpected: %s\nFound: %s\n", \ + __LINE__, encoding, EXP, disasm->GetOutput()); \ + abort(); \ + } + +#define CLEANUP() \ + delete disasm; \ + delete decoder; \ + delete assm + + +static bool vm_initialized = false; + + +static void InitializeVM() { + if (!vm_initialized) { + CcTest::InitializeVM(); + vm_initialized = true; + } +} + + +TEST_(bootstrap) { + SET_UP(); + + // Instructions generated by C compiler, disassembled by objdump, and + // reformatted to suit our disassembly style. + COMPARE(dci(0xa9ba7bfd), "stp fp, lr, [csp, #-96]!"); + COMPARE(dci(0x910003fd), "mov fp, csp"); + COMPARE(dci(0x9100e3a0), "add x0, fp, #0x38 (56)"); + COMPARE(dci(0xb900001f), "str wzr, [x0]"); + COMPARE(dci(0x528000e1), "movz w1, #0x7"); + COMPARE(dci(0xb9001c01), "str w1, [x0, #28]"); + COMPARE(dci(0x390043a0), "strb w0, [fp, #16]"); + COMPARE(dci(0x790027a0), "strh w0, [fp, #18]"); + COMPARE(dci(0xb9400400), "ldr w0, [x0, #4]"); + COMPARE(dci(0x0b000021), "add w1, w1, w0"); + COMPARE(dci(0x531b6800), "lsl w0, w0, #5"); + COMPARE(dci(0x521e0400), "eor w0, w0, #0xc"); + COMPARE(dci(0x72af0f00), "movk w0, #0x7878, lsl #16"); + COMPARE(dci(0xd360fc00), "lsr x0, x0, #32"); + COMPARE(dci(0x13037c01), "asr w1, w0, #3"); + COMPARE(dci(0x4b000021), "sub w1, w1, w0"); + COMPARE(dci(0x2a0103e0), "mov w0, w1"); + COMPARE(dci(0x93407c00), "sxtw x0, w0"); + COMPARE(dci(0x2a000020), "orr w0, w1, w0"); + COMPARE(dci(0xa8c67bfd), "ldp fp, lr, [csp], #96"); + + CLEANUP(); +} + + +TEST_(mov_mvn) { + SET_UP_CLASS(MacroAssembler); + + COMPARE(Mov(w0, Operand(0x1234)), "movz w0, #0x1234"); + COMPARE(Mov(x1, Operand(0x1234)), "movz x1, #0x1234"); + COMPARE(Mov(w2, Operand(w3)), "mov w2, w3"); + COMPARE(Mov(x4, Operand(x5)), "mov x4, x5"); + COMPARE(Mov(w6, Operand(w7, LSL, 5)), "lsl w6, w7, #5"); + COMPARE(Mov(x8, Operand(x9, ASR, 42)), "asr x8, x9, #42"); + COMPARE(Mov(w10, Operand(w11, UXTB)), "uxtb w10, w11"); + COMPARE(Mov(x12, Operand(x13, UXTB, 1)), "ubfiz x12, x13, #1, #8"); + COMPARE(Mov(w14, Operand(w15, SXTH, 2)), "sbfiz w14, w15, #2, #16"); + COMPARE(Mov(x16, Operand(x20, SXTW, 3)), "sbfiz x16, x20, #3, #32"); + + COMPARE(Mov(x0, csp), "mov x0, csp"); + COMPARE(Mov(w0, wcsp), "mov w0, wcsp"); + COMPARE(Mov(x0, xzr), "mov x0, xzr"); + COMPARE(Mov(w0, wzr), "mov w0, wzr"); + COMPARE(mov(x0, csp), "mov x0, csp"); + COMPARE(mov(w0, wcsp), "mov w0, wcsp"); + COMPARE(mov(x0, xzr), "mov x0, xzr"); + COMPARE(mov(w0, wzr), "mov w0, wzr"); + + COMPARE(Mvn(w0, Operand(0x1)), "movn w0, #0x1"); + COMPARE(Mvn(x1, Operand(0xfff)), "movn x1, #0xfff"); + COMPARE(Mvn(w2, Operand(w3)), "mvn w2, w3"); + COMPARE(Mvn(x4, Operand(x5)), "mvn x4, x5"); + COMPARE(Mvn(w6, Operand(w7, LSL, 12)), "mvn w6, w7, lsl #12"); + COMPARE(Mvn(x8, Operand(x9, ASR, 63)), "mvn x8, x9, asr #63"); + + CLEANUP(); +} + + +TEST_(move_immediate) { + SET_UP(); + + COMPARE(movz(w0, 0x1234), "movz w0, #0x1234"); + COMPARE(movz(x1, 0xabcd0000), "movz x1, #0xabcd0000"); + COMPARE(movz(x2, 0x555500000000), "movz x2, #0x555500000000"); + COMPARE(movz(x3, 0xaaaa000000000000), "movz x3, #0xaaaa000000000000"); + COMPARE(movz(x4, 0xabcd, 16), "movz x4, #0xabcd0000"); + COMPARE(movz(x5, 0x5555, 32), "movz x5, #0x555500000000"); + COMPARE(movz(x6, 0xaaaa, 48), "movz x6, #0xaaaa000000000000"); + + COMPARE(movk(w7, 0x1234), "movk w7, #0x1234"); + COMPARE(movk(x8, 0xabcd0000), "movk x8, #0xabcd, lsl #16"); + COMPARE(movk(x9, 0x555500000000), "movk x9, #0x5555, lsl #32"); + COMPARE(movk(x10, 0xaaaa000000000000), "movk x10, #0xaaaa, lsl #48"); + COMPARE(movk(w11, 0xabcd, 16), "movk w11, #0xabcd, lsl #16"); + COMPARE(movk(x12, 0x5555, 32), "movk x12, #0x5555, lsl #32"); + COMPARE(movk(x13, 0xaaaa, 48), "movk x13, #0xaaaa, lsl #48"); + + COMPARE(movn(w14, 0x1234), "movn w14, #0x1234"); + COMPARE(movn(x15, 0xabcd0000), "movn x15, #0xabcd0000"); + COMPARE(movn(x16, 0x555500000000), "movn x16, #0x555500000000"); + COMPARE(movn(x17, 0xaaaa000000000000), "movn x17, #0xaaaa000000000000"); + COMPARE(movn(w18, 0xabcd, 16), "movn w18, #0xabcd0000"); + COMPARE(movn(x19, 0x5555, 32), "movn x19, #0x555500000000"); + COMPARE(movn(x20, 0xaaaa, 48), "movn x20, #0xaaaa000000000000"); + + COMPARE(movk(w21, 0), "movk w21, #0x0"); + COMPARE(movk(x22, 0, 0), "movk x22, #0x0"); + COMPARE(movk(w23, 0, 16), "movk w23, #0x0, lsl #16"); + COMPARE(movk(x24, 0, 32), "movk x24, #0x0, lsl #32"); + COMPARE(movk(x25, 0, 48), "movk x25, #0x0, lsl #48"); + + CLEANUP(); +} + + +TEST(move_immediate_2) { + SET_UP_CLASS(MacroAssembler); + + // Move instructions expected for certain immediates. This is really a macro + // assembler test, to ensure it generates immediates efficiently. + COMPARE(Mov(w0, 0), "movz w0, #0x0"); + COMPARE(Mov(w0, 0x0000ffff), "movz w0, #0xffff"); + COMPARE(Mov(w0, 0x00010000), "movz w0, #0x10000"); + COMPARE(Mov(w0, 0xffff0000), "movz w0, #0xffff0000"); + COMPARE(Mov(w0, 0x0001ffff), "movn w0, #0xfffe0000"); + COMPARE(Mov(w0, 0xffff8000), "movn w0, #0x7fff"); + COMPARE(Mov(w0, 0xfffffffe), "movn w0, #0x1"); + COMPARE(Mov(w0, 0xffffffff), "movn w0, #0x0"); + COMPARE(Mov(w0, 0x00ffff00), "mov w0, #0xffff00"); + COMPARE(Mov(w0, 0xfffe7fff), "mov w0, #0xfffe7fff"); + COMPARE(Mov(w0, 0xfffeffff), "movn w0, #0x10000"); + COMPARE(Mov(w0, 0xffff7fff), "movn w0, #0x8000"); + + COMPARE(Mov(x0, 0), "movz x0, #0x0"); + COMPARE(Mov(x0, 0x0000ffff), "movz x0, #0xffff"); + COMPARE(Mov(x0, 0x00010000), "movz x0, #0x10000"); + COMPARE(Mov(x0, 0xffff0000), "movz x0, #0xffff0000"); + COMPARE(Mov(x0, 0x0001ffff), "mov x0, #0x1ffff"); + COMPARE(Mov(x0, 0xffff8000), "mov x0, #0xffff8000"); + COMPARE(Mov(x0, 0xfffffffe), "mov x0, #0xfffffffe"); + COMPARE(Mov(x0, 0xffffffff), "mov x0, #0xffffffff"); + COMPARE(Mov(x0, 0x00ffff00), "mov x0, #0xffff00"); + COMPARE(Mov(x0, 0xffff000000000000), "movz x0, #0xffff000000000000"); + COMPARE(Mov(x0, 0x0000ffff00000000), "movz x0, #0xffff00000000"); + COMPARE(Mov(x0, 0x00000000ffff0000), "movz x0, #0xffff0000"); + COMPARE(Mov(x0, 0xffffffffffff0000), "movn x0, #0xffff"); + COMPARE(Mov(x0, 0xffffffff0000ffff), "movn x0, #0xffff0000"); + COMPARE(Mov(x0, 0xffff0000ffffffff), "movn x0, #0xffff00000000"); + COMPARE(Mov(x0, 0x0000ffffffffffff), "movn x0, #0xffff000000000000"); + COMPARE(Mov(x0, 0xfffe7fffffffffff), "mov x0, #0xfffe7fffffffffff"); + COMPARE(Mov(x0, 0xfffeffffffffffff), "movn x0, #0x1000000000000"); + COMPARE(Mov(x0, 0xffff7fffffffffff), "movn x0, #0x800000000000"); + COMPARE(Mov(x0, 0xfffffffe7fffffff), "mov x0, #0xfffffffe7fffffff"); + COMPARE(Mov(x0, 0xfffffffeffffffff), "movn x0, #0x100000000"); + COMPARE(Mov(x0, 0xffffffff7fffffff), "movn x0, #0x80000000"); + COMPARE(Mov(x0, 0xfffffffffffe7fff), "mov x0, #0xfffffffffffe7fff"); + COMPARE(Mov(x0, 0xfffffffffffeffff), "movn x0, #0x10000"); + COMPARE(Mov(x0, 0xffffffffffff7fff), "movn x0, #0x8000"); + COMPARE(Mov(x0, 0xffffffffffffffff), "movn x0, #0x0"); + + COMPARE(Movk(w0, 0x1234, 0), "movk w0, #0x1234"); + COMPARE(Movk(x1, 0x2345, 0), "movk x1, #0x2345"); + COMPARE(Movk(w2, 0x3456, 16), "movk w2, #0x3456, lsl #16"); + COMPARE(Movk(x3, 0x4567, 16), "movk x3, #0x4567, lsl #16"); + COMPARE(Movk(x4, 0x5678, 32), "movk x4, #0x5678, lsl #32"); + COMPARE(Movk(x5, 0x6789, 48), "movk x5, #0x6789, lsl #48"); + + CLEANUP(); +} + + +TEST_(add_immediate) { + SET_UP(); + + COMPARE(add(w0, w1, Operand(0xff)), "add w0, w1, #0xff (255)"); + COMPARE(add(x2, x3, Operand(0x3ff)), "add x2, x3, #0x3ff (1023)"); + COMPARE(add(w4, w5, Operand(0xfff)), "add w4, w5, #0xfff (4095)"); + COMPARE(add(x6, x7, Operand(0x1000)), "add x6, x7, #0x1000 (4096)"); + COMPARE(add(w8, w9, Operand(0xff000)), "add w8, w9, #0xff000 (1044480)"); + COMPARE(add(x10, x11, Operand(0x3ff000)), + "add x10, x11, #0x3ff000 (4190208)"); + COMPARE(add(w12, w13, Operand(0xfff000)), + "add w12, w13, #0xfff000 (16773120)"); + COMPARE(adds(w14, w15, Operand(0xff)), "adds w14, w15, #0xff (255)"); + COMPARE(adds(x16, x17, Operand(0xaa000)), + "adds x16, x17, #0xaa000 (696320)"); + COMPARE(cmn(w18, Operand(0xff)), "cmn w18, #0xff (255)"); + COMPARE(cmn(x19, Operand(0xff000)), "cmn x19, #0xff000 (1044480)"); + COMPARE(add(w0, wcsp, Operand(0)), "mov w0, wcsp"); + COMPARE(add(csp, x0, Operand(0)), "mov csp, x0"); + + COMPARE(add(w1, wcsp, Operand(8)), "add w1, wcsp, #0x8 (8)"); + COMPARE(add(x2, csp, Operand(16)), "add x2, csp, #0x10 (16)"); + COMPARE(add(wcsp, wcsp, Operand(42)), "add wcsp, wcsp, #0x2a (42)"); + COMPARE(cmn(csp, Operand(24)), "cmn csp, #0x18 (24)"); + COMPARE(adds(wzr, wcsp, Operand(9)), "cmn wcsp, #0x9 (9)"); + + CLEANUP(); +} + + +TEST_(sub_immediate) { + SET_UP(); + + COMPARE(sub(w0, w1, Operand(0xff)), "sub w0, w1, #0xff (255)"); + COMPARE(sub(x2, x3, Operand(0x3ff)), "sub x2, x3, #0x3ff (1023)"); + COMPARE(sub(w4, w5, Operand(0xfff)), "sub w4, w5, #0xfff (4095)"); + COMPARE(sub(x6, x7, Operand(0x1000)), "sub x6, x7, #0x1000 (4096)"); + COMPARE(sub(w8, w9, Operand(0xff000)), "sub w8, w9, #0xff000 (1044480)"); + COMPARE(sub(x10, x11, Operand(0x3ff000)), + "sub x10, x11, #0x3ff000 (4190208)"); + COMPARE(sub(w12, w13, Operand(0xfff000)), + "sub w12, w13, #0xfff000 (16773120)"); + COMPARE(subs(w14, w15, Operand(0xff)), "subs w14, w15, #0xff (255)"); + COMPARE(subs(x16, x17, Operand(0xaa000)), + "subs x16, x17, #0xaa000 (696320)"); + COMPARE(cmp(w18, Operand(0xff)), "cmp w18, #0xff (255)"); + COMPARE(cmp(x19, Operand(0xff000)), "cmp x19, #0xff000 (1044480)"); + + COMPARE(add(w1, wcsp, Operand(8)), "add w1, wcsp, #0x8 (8)"); + COMPARE(add(x2, csp, Operand(16)), "add x2, csp, #0x10 (16)"); + COMPARE(add(wcsp, wcsp, Operand(42)), "add wcsp, wcsp, #0x2a (42)"); + COMPARE(cmn(csp, Operand(24)), "cmn csp, #0x18 (24)"); + COMPARE(adds(wzr, wcsp, Operand(9)), "cmn wcsp, #0x9 (9)"); + + CLEANUP(); +} + + +TEST_(add_shifted) { + SET_UP(); + + COMPARE(add(w0, w1, Operand(w2)), "add w0, w1, w2"); + COMPARE(add(x3, x4, Operand(x5)), "add x3, x4, x5"); + COMPARE(add(w6, w7, Operand(w8, LSL, 1)), "add w6, w7, w8, lsl #1"); + COMPARE(add(x9, x10, Operand(x11, LSL, 2)), "add x9, x10, x11, lsl #2"); + COMPARE(add(w12, w13, Operand(w14, LSR, 3)), "add w12, w13, w14, lsr #3"); + COMPARE(add(x15, x16, Operand(x17, LSR, 4)), "add x15, x16, x17, lsr #4"); + COMPARE(add(w18, w19, Operand(w20, ASR, 5)), "add w18, w19, w20, asr #5"); + COMPARE(add(x21, x22, Operand(x23, ASR, 6)), "add x21, x22, x23, asr #6"); + COMPARE(cmn(w24, Operand(w25)), "cmn w24, w25"); + COMPARE(cmn(x26, Operand(cp, LSL, 63)), "cmn x26, cp, lsl #63"); + + COMPARE(add(x0, csp, Operand(x1)), "add x0, csp, x1"); + COMPARE(add(w2, wcsp, Operand(w3)), "add w2, wcsp, w3"); + COMPARE(add(x4, csp, Operand(x5, LSL, 1)), "add x4, csp, x5, lsl #1"); + COMPARE(add(x4, xzr, Operand(x5, LSL, 1)), "add x4, xzr, x5, lsl #1"); + COMPARE(add(w6, wcsp, Operand(w7, LSL, 3)), "add w6, wcsp, w7, lsl #3"); + COMPARE(adds(xzr, csp, Operand(x8, LSL, 4)), "cmn csp, x8, lsl #4"); + COMPARE(adds(xzr, xzr, Operand(x8, LSL, 5)), "cmn xzr, x8, lsl #5"); + + CLEANUP(); +} + + +TEST_(sub_shifted) { + SET_UP(); + + COMPARE(sub(w0, w1, Operand(w2)), "sub w0, w1, w2"); + COMPARE(sub(x3, x4, Operand(x5)), "sub x3, x4, x5"); + COMPARE(sub(w6, w7, Operand(w8, LSL, 1)), "sub w6, w7, w8, lsl #1"); + COMPARE(sub(x9, x10, Operand(x11, LSL, 2)), "sub x9, x10, x11, lsl #2"); + COMPARE(sub(w12, w13, Operand(w14, LSR, 3)), "sub w12, w13, w14, lsr #3"); + COMPARE(sub(x15, x16, Operand(x17, LSR, 4)), "sub x15, x16, x17, lsr #4"); + COMPARE(sub(w18, w19, Operand(w20, ASR, 5)), "sub w18, w19, w20, asr #5"); + COMPARE(sub(x21, x22, Operand(x23, ASR, 6)), "sub x21, x22, x23, asr #6"); + COMPARE(cmp(w24, Operand(w25)), "cmp w24, w25"); + COMPARE(cmp(x26, Operand(cp, LSL, 63)), "cmp x26, cp, lsl #63"); + COMPARE(neg(w28, Operand(w29)), "neg w28, w29"); + COMPARE(neg(lr, Operand(x0, LSR, 62)), "neg lr, x0, lsr #62"); + COMPARE(negs(w1, Operand(w2)), "negs w1, w2"); + COMPARE(negs(x3, Operand(x4, ASR, 61)), "negs x3, x4, asr #61"); + + COMPARE(sub(x0, csp, Operand(x1)), "sub x0, csp, x1"); + COMPARE(sub(w2, wcsp, Operand(w3)), "sub w2, wcsp, w3"); + COMPARE(sub(x4, csp, Operand(x5, LSL, 1)), "sub x4, csp, x5, lsl #1"); + COMPARE(sub(x4, xzr, Operand(x5, LSL, 1)), "neg x4, x5, lsl #1"); + COMPARE(sub(w6, wcsp, Operand(w7, LSL, 3)), "sub w6, wcsp, w7, lsl #3"); + COMPARE(subs(xzr, csp, Operand(x8, LSL, 4)), "cmp csp, x8, lsl #4"); + COMPARE(subs(xzr, xzr, Operand(x8, LSL, 5)), "cmp xzr, x8, lsl #5"); + + CLEANUP(); +} + + +TEST_(add_extended) { + SET_UP(); + + COMPARE(add(w0, w1, Operand(w2, UXTB)), "add w0, w1, w2, uxtb"); + COMPARE(adds(x3, x4, Operand(w5, UXTB, 1)), "adds x3, x4, w5, uxtb #1"); + COMPARE(add(w6, w7, Operand(w8, UXTH, 2)), "add w6, w7, w8, uxth #2"); + COMPARE(adds(x9, x10, Operand(x11, UXTW, 3)), "adds x9, x10, w11, uxtw #3"); + COMPARE(add(x12, x13, Operand(x14, UXTX, 4)), "add x12, x13, x14, uxtx #4"); + COMPARE(adds(w15, w16, Operand(w17, SXTB, 4)), "adds w15, w16, w17, sxtb #4"); + COMPARE(add(x18, x19, Operand(x20, SXTB, 3)), "add x18, x19, w20, sxtb #3"); + COMPARE(adds(w21, w22, Operand(w23, SXTH, 2)), "adds w21, w22, w23, sxth #2"); + COMPARE(add(x24, x25, Operand(x26, SXTW, 1)), "add x24, x25, w26, sxtw #1"); + COMPARE(adds(cp, jssp, Operand(fp, SXTX)), "adds cp, jssp, fp, sxtx"); + COMPARE(cmn(w0, Operand(w1, UXTB, 2)), "cmn w0, w1, uxtb #2"); + COMPARE(cmn(x2, Operand(x3, SXTH, 4)), "cmn x2, w3, sxth #4"); + + COMPARE(add(w0, wcsp, Operand(w1, UXTB)), "add w0, wcsp, w1, uxtb"); + COMPARE(add(x2, csp, Operand(x3, UXTH, 1)), "add x2, csp, w3, uxth #1"); + COMPARE(add(wcsp, wcsp, Operand(w4, UXTW, 2)), "add wcsp, wcsp, w4, lsl #2"); + COMPARE(cmn(csp, Operand(xzr, UXTX, 3)), "cmn csp, xzr, lsl #3"); + COMPARE(cmn(csp, Operand(xzr, LSL, 4)), "cmn csp, xzr, lsl #4"); + + CLEANUP(); +} + + +TEST_(sub_extended) { + SET_UP(); + + COMPARE(sub(w0, w1, Operand(w2, UXTB)), "sub w0, w1, w2, uxtb"); + COMPARE(subs(x3, x4, Operand(w5, UXTB, 1)), "subs x3, x4, w5, uxtb #1"); + COMPARE(sub(w6, w7, Operand(w8, UXTH, 2)), "sub w6, w7, w8, uxth #2"); + COMPARE(subs(x9, x10, Operand(x11, UXTW, 3)), "subs x9, x10, w11, uxtw #3"); + COMPARE(sub(x12, x13, Operand(x14, UXTX, 4)), "sub x12, x13, x14, uxtx #4"); + COMPARE(subs(w15, w16, Operand(w17, SXTB, 4)), "subs w15, w16, w17, sxtb #4"); + COMPARE(sub(x18, x19, Operand(x20, SXTB, 3)), "sub x18, x19, w20, sxtb #3"); + COMPARE(subs(w21, w22, Operand(w23, SXTH, 2)), "subs w21, w22, w23, sxth #2"); + COMPARE(sub(x24, x25, Operand(x26, SXTW, 1)), "sub x24, x25, w26, sxtw #1"); + COMPARE(subs(cp, jssp, Operand(fp, SXTX)), "subs cp, jssp, fp, sxtx"); + COMPARE(cmp(w0, Operand(w1, SXTB, 1)), "cmp w0, w1, sxtb #1"); + COMPARE(cmp(x2, Operand(x3, UXTH, 3)), "cmp x2, w3, uxth #3"); + + COMPARE(sub(w0, wcsp, Operand(w1, UXTB)), "sub w0, wcsp, w1, uxtb"); + COMPARE(sub(x2, csp, Operand(x3, UXTH, 1)), "sub x2, csp, w3, uxth #1"); + COMPARE(sub(wcsp, wcsp, Operand(w4, UXTW, 2)), "sub wcsp, wcsp, w4, lsl #2"); + COMPARE(cmp(csp, Operand(xzr, UXTX, 3)), "cmp csp, xzr, lsl #3"); + COMPARE(cmp(csp, Operand(xzr, LSL, 4)), "cmp csp, xzr, lsl #4"); + + CLEANUP(); +} + + +TEST_(adc_subc_ngc) { + SET_UP(); + + COMPARE(adc(w0, w1, Operand(w2)), "adc w0, w1, w2"); + COMPARE(adc(x3, x4, Operand(x5)), "adc x3, x4, x5"); + COMPARE(adcs(w6, w7, Operand(w8)), "adcs w6, w7, w8"); + COMPARE(adcs(x9, x10, Operand(x11)), "adcs x9, x10, x11"); + COMPARE(sbc(w12, w13, Operand(w14)), "sbc w12, w13, w14"); + COMPARE(sbc(x15, x16, Operand(x17)), "sbc x15, x16, x17"); + COMPARE(sbcs(w18, w19, Operand(w20)), "sbcs w18, w19, w20"); + COMPARE(sbcs(x21, x22, Operand(x23)), "sbcs x21, x22, x23"); + COMPARE(ngc(w24, Operand(w25)), "ngc w24, w25"); + COMPARE(ngc(x26, Operand(cp)), "ngc x26, cp"); + COMPARE(ngcs(w28, Operand(w29)), "ngcs w28, w29"); + COMPARE(ngcs(lr, Operand(x0)), "ngcs lr, x0"); + + CLEANUP(); +} + + +TEST_(mul_and_div) { + SET_UP(); + + COMPARE(mul(w0, w1, w2), "mul w0, w1, w2"); + COMPARE(mul(x3, x4, x5), "mul x3, x4, x5"); + COMPARE(mul(w30, w0, w1), "mul w30, w0, w1"); + COMPARE(mul(lr, x0, x1), "mul lr, x0, x1"); + COMPARE(mneg(w0, w1, w2), "mneg w0, w1, w2"); + COMPARE(mneg(x3, x4, x5), "mneg x3, x4, x5"); + COMPARE(mneg(w30, w0, w1), "mneg w30, w0, w1"); + COMPARE(mneg(lr, x0, x1), "mneg lr, x0, x1"); + COMPARE(smull(x0, w0, w1), "smull x0, w0, w1"); + COMPARE(smull(lr, w30, w0), "smull lr, w30, w0"); + COMPARE(smulh(x0, x1, x2), "smulh x0, x1, x2"); + + COMPARE(madd(w0, w1, w2, w3), "madd w0, w1, w2, w3"); + COMPARE(madd(x4, x5, x6, x7), "madd x4, x5, x6, x7"); + COMPARE(madd(w8, w9, w10, wzr), "mul w8, w9, w10"); + COMPARE(madd(x11, x12, x13, xzr), "mul x11, x12, x13"); + COMPARE(msub(w14, w15, w16, w17), "msub w14, w15, w16, w17"); + COMPARE(msub(x18, x19, x20, x21), "msub x18, x19, x20, x21"); + COMPARE(msub(w22, w23, w24, wzr), "mneg w22, w23, w24"); + COMPARE(msub(x25, x26, x0, xzr), "mneg x25, x26, x0"); + + COMPARE(sdiv(w0, w1, w2), "sdiv w0, w1, w2"); + COMPARE(sdiv(x3, x4, x5), "sdiv x3, x4, x5"); + COMPARE(udiv(w6, w7, w8), "udiv w6, w7, w8"); + COMPARE(udiv(x9, x10, x11), "udiv x9, x10, x11"); + + CLEANUP(); +} + + +TEST(maddl_msubl) { + SET_UP(); + + COMPARE(smaddl(x0, w1, w2, x3), "smaddl x0, w1, w2, x3"); + COMPARE(smaddl(x25, w21, w22, x16), "smaddl x25, w21, w22, x16"); + COMPARE(umaddl(x0, w1, w2, x3), "umaddl x0, w1, w2, x3"); + COMPARE(umaddl(x25, w21, w22, x16), "umaddl x25, w21, w22, x16"); + + COMPARE(smsubl(x0, w1, w2, x3), "smsubl x0, w1, w2, x3"); + COMPARE(smsubl(x25, w21, w22, x16), "smsubl x25, w21, w22, x16"); + COMPARE(umsubl(x0, w1, w2, x3), "umsubl x0, w1, w2, x3"); + COMPARE(umsubl(x25, w21, w22, x16), "umsubl x25, w21, w22, x16"); + + CLEANUP(); +} + + +TEST_(dp_1_source) { + SET_UP(); + + COMPARE(rbit(w0, w1), "rbit w0, w1"); + COMPARE(rbit(x2, x3), "rbit x2, x3"); + COMPARE(rev16(w4, w5), "rev16 w4, w5"); + COMPARE(rev16(x6, x7), "rev16 x6, x7"); + COMPARE(rev32(x8, x9), "rev32 x8, x9"); + COMPARE(rev(w10, w11), "rev w10, w11"); + COMPARE(rev(x12, x13), "rev x12, x13"); + COMPARE(clz(w14, w15), "clz w14, w15"); + COMPARE(clz(x16, x17), "clz x16, x17"); + COMPARE(cls(w18, w19), "cls w18, w19"); + COMPARE(cls(x20, x21), "cls x20, x21"); + + CLEANUP(); +} + + +TEST_(bitfield) { + SET_UP(); + + COMPARE(sxtb(w0, w1), "sxtb w0, w1"); + COMPARE(sxtb(x2, x3), "sxtb x2, w3"); + COMPARE(sxth(w4, w5), "sxth w4, w5"); + COMPARE(sxth(x6, x7), "sxth x6, w7"); + COMPARE(sxtw(x8, x9), "sxtw x8, w9"); + COMPARE(sxtb(x0, w1), "sxtb x0, w1"); + COMPARE(sxth(x2, w3), "sxth x2, w3"); + COMPARE(sxtw(x4, w5), "sxtw x4, w5"); + + COMPARE(uxtb(w10, w11), "uxtb w10, w11"); + COMPARE(uxtb(x12, x13), "uxtb x12, w13"); + COMPARE(uxth(w14, w15), "uxth w14, w15"); + COMPARE(uxth(x16, x17), "uxth x16, w17"); + COMPARE(uxtw(x18, x19), "ubfx x18, x19, #0, #32"); + + COMPARE(asr(w20, w21, 10), "asr w20, w21, #10"); + COMPARE(asr(x22, x23, 20), "asr x22, x23, #20"); + COMPARE(lsr(w24, w25, 10), "lsr w24, w25, #10"); + COMPARE(lsr(x26, cp, 20), "lsr x26, cp, #20"); + COMPARE(lsl(w28, w29, 10), "lsl w28, w29, #10"); + COMPARE(lsl(lr, x0, 20), "lsl lr, x0, #20"); + + COMPARE(sbfiz(w1, w2, 1, 20), "sbfiz w1, w2, #1, #20"); + COMPARE(sbfiz(x3, x4, 2, 19), "sbfiz x3, x4, #2, #19"); + COMPARE(sbfx(w5, w6, 3, 18), "sbfx w5, w6, #3, #18"); + COMPARE(sbfx(x7, x8, 4, 17), "sbfx x7, x8, #4, #17"); + COMPARE(bfi(w9, w10, 5, 16), "bfi w9, w10, #5, #16"); + COMPARE(bfi(x11, x12, 6, 15), "bfi x11, x12, #6, #15"); + COMPARE(bfxil(w13, w14, 7, 14), "bfxil w13, w14, #7, #14"); + COMPARE(bfxil(x15, x16, 8, 13), "bfxil x15, x16, #8, #13"); + COMPARE(ubfiz(w17, w18, 9, 12), "ubfiz w17, w18, #9, #12"); + COMPARE(ubfiz(x19, x20, 10, 11), "ubfiz x19, x20, #10, #11"); + COMPARE(ubfx(w21, w22, 11, 10), "ubfx w21, w22, #11, #10"); + COMPARE(ubfx(x23, x24, 12, 9), "ubfx x23, x24, #12, #9"); + + CLEANUP(); +} + + +TEST_(extract) { + SET_UP(); + + COMPARE(extr(w0, w1, w2, 0), "extr w0, w1, w2, #0"); + COMPARE(extr(x3, x4, x5, 1), "extr x3, x4, x5, #1"); + COMPARE(extr(w6, w7, w8, 31), "extr w6, w7, w8, #31"); + COMPARE(extr(x9, x10, x11, 63), "extr x9, x10, x11, #63"); + COMPARE(extr(w12, w13, w13, 10), "ror w12, w13, #10"); + COMPARE(extr(x14, x15, x15, 42), "ror x14, x15, #42"); + + CLEANUP(); +} + + +TEST_(logical_immediate) { + SET_UP(); + #define RESULT_SIZE (256) + + char result[RESULT_SIZE]; + + // Test immediate encoding - 64-bit destination. + // 64-bit patterns. + uint64_t value = 0x7fffffff; + for (int i = 0; i < 64; i++) { + snprintf(result, RESULT_SIZE, "and x0, x0, #0x%" PRIx64, value); + COMPARE(and_(x0, x0, Operand(value)), result); + value = ((value & 1) << 63) | (value >> 1); // Rotate right 1 bit. + } + + // 32-bit patterns. + value = 0x00003fff00003fffL; + for (int i = 0; i < 32; i++) { + snprintf(result, RESULT_SIZE, "and x0, x0, #0x%" PRIx64, value); + COMPARE(and_(x0, x0, Operand(value)), result); + value = ((value & 1) << 63) | (value >> 1); // Rotate right 1 bit. + } + + // 16-bit patterns. + value = 0x001f001f001f001fL; + for (int i = 0; i < 16; i++) { + snprintf(result, RESULT_SIZE, "and x0, x0, #0x%" PRIx64, value); + COMPARE(and_(x0, x0, Operand(value)), result); + value = ((value & 1) << 63) | (value >> 1); // Rotate right 1 bit. + } + + // 8-bit patterns. + value = 0x0e0e0e0e0e0e0e0eL; + for (int i = 0; i < 8; i++) { + snprintf(result, RESULT_SIZE, "and x0, x0, #0x%" PRIx64, value); + COMPARE(and_(x0, x0, Operand(value)), result); + value = ((value & 1) << 63) | (value >> 1); // Rotate right 1 bit. + } + + // 4-bit patterns. + value = 0x6666666666666666L; + for (int i = 0; i < 4; i++) { + snprintf(result, RESULT_SIZE, "and x0, x0, #0x%" PRIx64, value); + COMPARE(and_(x0, x0, Operand(value)), result); + value = ((value & 1) << 63) | (value >> 1); // Rotate right 1 bit. + } + + // 2-bit patterns. + COMPARE(and_(x0, x0, Operand(0x5555555555555555L)), + "and x0, x0, #0x5555555555555555"); + COMPARE(and_(x0, x0, Operand(0xaaaaaaaaaaaaaaaaL)), + "and x0, x0, #0xaaaaaaaaaaaaaaaa"); + + // Test immediate encoding - 32-bit destination. + COMPARE(and_(w0, w0, Operand(0xff8007ff)), + "and w0, w0, #0xff8007ff"); // 32-bit pattern. + COMPARE(and_(w0, w0, Operand(0xf87ff87f)), + "and w0, w0, #0xf87ff87f"); // 16-bit pattern. + COMPARE(and_(w0, w0, Operand(0x87878787)), + "and w0, w0, #0x87878787"); // 8-bit pattern. + COMPARE(and_(w0, w0, Operand(0x66666666)), + "and w0, w0, #0x66666666"); // 4-bit pattern. + COMPARE(and_(w0, w0, Operand(0x55555555)), + "and w0, w0, #0x55555555"); // 2-bit pattern. + + // Test other instructions. + COMPARE(tst(w1, Operand(0x11111111)), + "tst w1, #0x11111111"); + COMPARE(tst(x2, Operand(0x8888888888888888L)), + "tst x2, #0x8888888888888888"); + COMPARE(orr(w7, w8, Operand(0xaaaaaaaa)), + "orr w7, w8, #0xaaaaaaaa"); + COMPARE(orr(x9, x10, Operand(0x5555555555555555L)), + "orr x9, x10, #0x5555555555555555"); + COMPARE(eor(w15, w16, Operand(0x00000001)), + "eor w15, w16, #0x1"); + COMPARE(eor(x17, x18, Operand(0x0000000000000003L)), + "eor x17, x18, #0x3"); + COMPARE(ands(w23, w24, Operand(0x0000000f)), "ands w23, w24, #0xf"); + COMPARE(ands(x25, x26, Operand(0x800000000000000fL)), + "ands x25, x26, #0x800000000000000f"); + + // Test inverse. + COMPARE(bic(w3, w4, Operand(0x20202020)), + "and w3, w4, #0xdfdfdfdf"); + COMPARE(bic(x5, x6, Operand(0x4040404040404040L)), + "and x5, x6, #0xbfbfbfbfbfbfbfbf"); + COMPARE(orn(w11, w12, Operand(0x40004000)), + "orr w11, w12, #0xbfffbfff"); + COMPARE(orn(x13, x14, Operand(0x8181818181818181L)), + "orr x13, x14, #0x7e7e7e7e7e7e7e7e"); + COMPARE(eon(w19, w20, Operand(0x80000001)), + "eor w19, w20, #0x7ffffffe"); + COMPARE(eon(x21, x22, Operand(0xc000000000000003L)), + "eor x21, x22, #0x3ffffffffffffffc"); + COMPARE(bics(w27, w28, Operand(0xfffffff7)), "ands w27, w28, #0x8"); + COMPARE(bics(fp, x0, Operand(0xfffffffeffffffffL)), + "ands fp, x0, #0x100000000"); + + // Test stack pointer. + COMPARE(and_(wcsp, wzr, Operand(7)), "and wcsp, wzr, #0x7"); + COMPARE(ands(xzr, xzr, Operand(7)), "tst xzr, #0x7"); + COMPARE(orr(csp, xzr, Operand(15)), "orr csp, xzr, #0xf"); + COMPARE(eor(wcsp, w0, Operand(31)), "eor wcsp, w0, #0x1f"); + + // Test move aliases. + COMPARE(orr(w0, wzr, Operand(0x00000780)), "orr w0, wzr, #0x780"); + COMPARE(orr(w1, wzr, Operand(0x00007800)), "orr w1, wzr, #0x7800"); + COMPARE(orr(w2, wzr, Operand(0x00078000)), "mov w2, #0x78000"); + COMPARE(orr(w3, wzr, Operand(0x00780000)), "orr w3, wzr, #0x780000"); + COMPARE(orr(w4, wzr, Operand(0x07800000)), "orr w4, wzr, #0x7800000"); + COMPARE(orr(x5, xzr, Operand(0xffffffffffffc001UL)), + "orr x5, xzr, #0xffffffffffffc001"); + COMPARE(orr(x6, xzr, Operand(0xfffffffffffc001fUL)), + "mov x6, #0xfffffffffffc001f"); + COMPARE(orr(x7, xzr, Operand(0xffffffffffc001ffUL)), + "mov x7, #0xffffffffffc001ff"); + COMPARE(orr(x8, xzr, Operand(0xfffffffffc001fffUL)), + "mov x8, #0xfffffffffc001fff"); + COMPARE(orr(x9, xzr, Operand(0xffffffffc001ffffUL)), + "orr x9, xzr, #0xffffffffc001ffff"); + + CLEANUP(); +} + + +TEST_(logical_shifted) { + SET_UP(); + + COMPARE(and_(w0, w1, Operand(w2)), "and w0, w1, w2"); + COMPARE(and_(x3, x4, Operand(x5, LSL, 1)), "and x3, x4, x5, lsl #1"); + COMPARE(and_(w6, w7, Operand(w8, LSR, 2)), "and w6, w7, w8, lsr #2"); + COMPARE(and_(x9, x10, Operand(x11, ASR, 3)), "and x9, x10, x11, asr #3"); + COMPARE(and_(w12, w13, Operand(w14, ROR, 4)), "and w12, w13, w14, ror #4"); + + COMPARE(bic(w15, w16, Operand(w17)), "bic w15, w16, w17"); + COMPARE(bic(x18, x19, Operand(x20, LSL, 5)), "bic x18, x19, x20, lsl #5"); + COMPARE(bic(w21, w22, Operand(w23, LSR, 6)), "bic w21, w22, w23, lsr #6"); + COMPARE(bic(x24, x25, Operand(x26, ASR, 7)), "bic x24, x25, x26, asr #7"); + COMPARE(bic(w27, w28, Operand(w29, ROR, 8)), "bic w27, w28, w29, ror #8"); + + COMPARE(orr(w0, w1, Operand(w2)), "orr w0, w1, w2"); + COMPARE(orr(x3, x4, Operand(x5, LSL, 9)), "orr x3, x4, x5, lsl #9"); + COMPARE(orr(w6, w7, Operand(w8, LSR, 10)), "orr w6, w7, w8, lsr #10"); + COMPARE(orr(x9, x10, Operand(x11, ASR, 11)), "orr x9, x10, x11, asr #11"); + COMPARE(orr(w12, w13, Operand(w14, ROR, 12)), "orr w12, w13, w14, ror #12"); + + COMPARE(orn(w15, w16, Operand(w17)), "orn w15, w16, w17"); + COMPARE(orn(x18, x19, Operand(x20, LSL, 13)), "orn x18, x19, x20, lsl #13"); + COMPARE(orn(w21, w22, Operand(w23, LSR, 14)), "orn w21, w22, w23, lsr #14"); + COMPARE(orn(x24, x25, Operand(x26, ASR, 15)), "orn x24, x25, x26, asr #15"); + COMPARE(orn(w27, w28, Operand(w29, ROR, 16)), "orn w27, w28, w29, ror #16"); + + COMPARE(eor(w0, w1, Operand(w2)), "eor w0, w1, w2"); + COMPARE(eor(x3, x4, Operand(x5, LSL, 17)), "eor x3, x4, x5, lsl #17"); + COMPARE(eor(w6, w7, Operand(w8, LSR, 18)), "eor w6, w7, w8, lsr #18"); + COMPARE(eor(x9, x10, Operand(x11, ASR, 19)), "eor x9, x10, x11, asr #19"); + COMPARE(eor(w12, w13, Operand(w14, ROR, 20)), "eor w12, w13, w14, ror #20"); + + COMPARE(eon(w15, w16, Operand(w17)), "eon w15, w16, w17"); + COMPARE(eon(x18, x19, Operand(x20, LSL, 21)), "eon x18, x19, x20, lsl #21"); + COMPARE(eon(w21, w22, Operand(w23, LSR, 22)), "eon w21, w22, w23, lsr #22"); + COMPARE(eon(x24, x25, Operand(x26, ASR, 23)), "eon x24, x25, x26, asr #23"); + COMPARE(eon(w27, w28, Operand(w29, ROR, 24)), "eon w27, w28, w29, ror #24"); + + COMPARE(ands(w0, w1, Operand(w2)), "ands w0, w1, w2"); + COMPARE(ands(x3, x4, Operand(x5, LSL, 1)), "ands x3, x4, x5, lsl #1"); + COMPARE(ands(w6, w7, Operand(w8, LSR, 2)), "ands w6, w7, w8, lsr #2"); + COMPARE(ands(x9, x10, Operand(x11, ASR, 3)), "ands x9, x10, x11, asr #3"); + COMPARE(ands(w12, w13, Operand(w14, ROR, 4)), "ands w12, w13, w14, ror #4"); + + COMPARE(bics(w15, w16, Operand(w17)), "bics w15, w16, w17"); + COMPARE(bics(x18, x19, Operand(x20, LSL, 5)), "bics x18, x19, x20, lsl #5"); + COMPARE(bics(w21, w22, Operand(w23, LSR, 6)), "bics w21, w22, w23, lsr #6"); + COMPARE(bics(x24, x25, Operand(x26, ASR, 7)), "bics x24, x25, x26, asr #7"); + COMPARE(bics(w27, w28, Operand(w29, ROR, 8)), "bics w27, w28, w29, ror #8"); + + COMPARE(tst(w0, Operand(w1)), "tst w0, w1"); + COMPARE(tst(w2, Operand(w3, ROR, 10)), "tst w2, w3, ror #10"); + COMPARE(tst(x0, Operand(x1)), "tst x0, x1"); + COMPARE(tst(x2, Operand(x3, ROR, 42)), "tst x2, x3, ror #42"); + + COMPARE(orn(w0, wzr, Operand(w1)), "mvn w0, w1"); + COMPARE(orn(w2, wzr, Operand(w3, ASR, 5)), "mvn w2, w3, asr #5"); + COMPARE(orn(x0, xzr, Operand(x1)), "mvn x0, x1"); + COMPARE(orn(x2, xzr, Operand(x3, ASR, 42)), "mvn x2, x3, asr #42"); + + COMPARE(orr(w0, wzr, Operand(w1)), "mov w0, w1"); + COMPARE(orr(x0, xzr, Operand(x1)), "mov x0, x1"); + COMPARE(orr(w16, wzr, Operand(w17, LSL, 1)), "orr w16, wzr, w17, lsl #1"); + COMPARE(orr(x16, xzr, Operand(x17, ASR, 2)), "orr x16, xzr, x17, asr #2"); + + CLEANUP(); +} + + +TEST_(dp_2_source) { + SET_UP(); + + COMPARE(lslv(w0, w1, w2), "lsl w0, w1, w2"); + COMPARE(lslv(x3, x4, x5), "lsl x3, x4, x5"); + COMPARE(lsrv(w6, w7, w8), "lsr w6, w7, w8"); + COMPARE(lsrv(x9, x10, x11), "lsr x9, x10, x11"); + COMPARE(asrv(w12, w13, w14), "asr w12, w13, w14"); + COMPARE(asrv(x15, x16, x17), "asr x15, x16, x17"); + COMPARE(rorv(w18, w19, w20), "ror w18, w19, w20"); + COMPARE(rorv(x21, x22, x23), "ror x21, x22, x23"); + + CLEANUP(); +} + + +TEST_(adr) { + SET_UP(); + + COMPARE(adr(x0, 0), "adr x0, #+0x0"); + COMPARE(adr(x1, 1), "adr x1, #+0x1"); + COMPARE(adr(x2, -1), "adr x2, #-0x1"); + COMPARE(adr(x3, 4), "adr x3, #+0x4"); + COMPARE(adr(x4, -4), "adr x4, #-0x4"); + COMPARE(adr(x5, 0x000fffff), "adr x5, #+0xfffff"); + COMPARE(adr(x6, -0x00100000), "adr x6, #-0x100000"); + COMPARE(adr(xzr, 0), "adr xzr, #+0x0"); + + CLEANUP(); +} + + +TEST_(branch) { + SET_UP(); + + #define INST_OFF(x) ((x) >> kInstructionSizeLog2) + COMPARE(b(INST_OFF(0x4)), "b #+0x4"); + COMPARE(b(INST_OFF(-0x4)), "b #-0x4"); + COMPARE(b(INST_OFF(0x7fffffc)), "b #+0x7fffffc"); + COMPARE(b(INST_OFF(-0x8000000)), "b #-0x8000000"); + COMPARE(b(INST_OFF(0xffffc), eq), "b.eq #+0xffffc"); + COMPARE(b(INST_OFF(-0x100000), mi), "b.mi #-0x100000"); + COMPARE(bl(INST_OFF(0x4)), "bl #+0x4"); + COMPARE(bl(INST_OFF(-0x4)), "bl #-0x4"); + COMPARE(bl(INST_OFF(0xffffc)), "bl #+0xffffc"); + COMPARE(bl(INST_OFF(-0x100000)), "bl #-0x100000"); + COMPARE(cbz(w0, INST_OFF(0xffffc)), "cbz w0, #+0xffffc"); + COMPARE(cbz(x1, INST_OFF(-0x100000)), "cbz x1, #-0x100000"); + COMPARE(cbnz(w2, INST_OFF(0xffffc)), "cbnz w2, #+0xffffc"); + COMPARE(cbnz(x3, INST_OFF(-0x100000)), "cbnz x3, #-0x100000"); + COMPARE(tbz(w4, 0, INST_OFF(0x7ffc)), "tbz w4, #0, #+0x7ffc"); + COMPARE(tbz(x5, 63, INST_OFF(-0x8000)), "tbz x5, #63, #-0x8000"); + COMPARE(tbz(w6, 31, INST_OFF(0)), "tbz w6, #31, #+0x0"); + COMPARE(tbz(x7, 31, INST_OFF(0x4)), "tbz w7, #31, #+0x4"); + COMPARE(tbz(x8, 32, INST_OFF(0x8)), "tbz x8, #32, #+0x8"); + COMPARE(tbnz(w8, 0, INST_OFF(0x7ffc)), "tbnz w8, #0, #+0x7ffc"); + COMPARE(tbnz(x9, 63, INST_OFF(-0x8000)), "tbnz x9, #63, #-0x8000"); + COMPARE(tbnz(w10, 31, INST_OFF(0)), "tbnz w10, #31, #+0x0"); + COMPARE(tbnz(x11, 31, INST_OFF(0x4)), "tbnz w11, #31, #+0x4"); + COMPARE(tbnz(x12, 32, INST_OFF(0x8)), "tbnz x12, #32, #+0x8"); + COMPARE(br(x0), "br x0"); + COMPARE(blr(x1), "blr x1"); + COMPARE(ret(x2), "ret x2"); + COMPARE(ret(lr), "ret") + + CLEANUP(); +} + + +TEST_(load_store) { + SET_UP(); + + COMPARE(ldr(w0, MemOperand(x1)), "ldr w0, [x1]"); + COMPARE(ldr(w2, MemOperand(x3, 4)), "ldr w2, [x3, #4]"); + COMPARE(ldr(w4, MemOperand(x5, 16380)), "ldr w4, [x5, #16380]"); + COMPARE(ldr(x6, MemOperand(x7)), "ldr x6, [x7]"); + COMPARE(ldr(x8, MemOperand(x9, 8)), "ldr x8, [x9, #8]"); + COMPARE(ldr(x10, MemOperand(x11, 32760)), "ldr x10, [x11, #32760]"); + COMPARE(str(w12, MemOperand(x13)), "str w12, [x13]"); + COMPARE(str(w14, MemOperand(x15, 4)), "str w14, [x15, #4]"); + COMPARE(str(w16, MemOperand(x17, 16380)), "str w16, [x17, #16380]"); + COMPARE(str(x18, MemOperand(x19)), "str x18, [x19]"); + COMPARE(str(x20, MemOperand(x21, 8)), "str x20, [x21, #8]"); + COMPARE(str(x22, MemOperand(x23, 32760)), "str x22, [x23, #32760]"); + + COMPARE(ldr(w0, MemOperand(x1, 4, PreIndex)), "ldr w0, [x1, #4]!"); + COMPARE(ldr(w2, MemOperand(x3, 255, PreIndex)), "ldr w2, [x3, #255]!"); + COMPARE(ldr(w4, MemOperand(x5, -256, PreIndex)), "ldr w4, [x5, #-256]!"); + COMPARE(ldr(x6, MemOperand(x7, 8, PreIndex)), "ldr x6, [x7, #8]!"); + COMPARE(ldr(x8, MemOperand(x9, 255, PreIndex)), "ldr x8, [x9, #255]!"); + COMPARE(ldr(x10, MemOperand(x11, -256, PreIndex)), "ldr x10, [x11, #-256]!"); + COMPARE(str(w12, MemOperand(x13, 4, PreIndex)), "str w12, [x13, #4]!"); + COMPARE(str(w14, MemOperand(x15, 255, PreIndex)), "str w14, [x15, #255]!"); + COMPARE(str(w16, MemOperand(x17, -256, PreIndex)), "str w16, [x17, #-256]!"); + COMPARE(str(x18, MemOperand(x19, 8, PreIndex)), "str x18, [x19, #8]!"); + COMPARE(str(x20, MemOperand(x21, 255, PreIndex)), "str x20, [x21, #255]!"); + COMPARE(str(x22, MemOperand(x23, -256, PreIndex)), "str x22, [x23, #-256]!"); + + COMPARE(ldr(w0, MemOperand(x1, 4, PostIndex)), "ldr w0, [x1], #4"); + COMPARE(ldr(w2, MemOperand(x3, 255, PostIndex)), "ldr w2, [x3], #255"); + COMPARE(ldr(w4, MemOperand(x5, -256, PostIndex)), "ldr w4, [x5], #-256"); + COMPARE(ldr(x6, MemOperand(x7, 8, PostIndex)), "ldr x6, [x7], #8"); + COMPARE(ldr(x8, MemOperand(x9, 255, PostIndex)), "ldr x8, [x9], #255"); + COMPARE(ldr(x10, MemOperand(x11, -256, PostIndex)), "ldr x10, [x11], #-256"); + COMPARE(str(w12, MemOperand(x13, 4, PostIndex)), "str w12, [x13], #4"); + COMPARE(str(w14, MemOperand(x15, 255, PostIndex)), "str w14, [x15], #255"); + COMPARE(str(w16, MemOperand(x17, -256, PostIndex)), "str w16, [x17], #-256"); + COMPARE(str(x18, MemOperand(x19, 8, PostIndex)), "str x18, [x19], #8"); + COMPARE(str(x20, MemOperand(x21, 255, PostIndex)), "str x20, [x21], #255"); + COMPARE(str(x22, MemOperand(x23, -256, PostIndex)), "str x22, [x23], #-256"); + + // TODO(all): Fix this for jssp. + COMPARE(ldr(w24, MemOperand(jssp)), "ldr w24, [jssp]"); + COMPARE(ldr(x25, MemOperand(jssp, 8)), "ldr x25, [jssp, #8]"); + COMPARE(str(w26, MemOperand(jssp, 4, PreIndex)), "str w26, [jssp, #4]!"); + COMPARE(str(cp, MemOperand(jssp, -8, PostIndex)), "str cp, [jssp], #-8"); + + COMPARE(ldrsw(x0, MemOperand(x1)), "ldrsw x0, [x1]"); + COMPARE(ldrsw(x2, MemOperand(x3, 8)), "ldrsw x2, [x3, #8]"); + COMPARE(ldrsw(x4, MemOperand(x5, 42, PreIndex)), "ldrsw x4, [x5, #42]!"); + COMPARE(ldrsw(x6, MemOperand(x7, -11, PostIndex)), "ldrsw x6, [x7], #-11"); + + CLEANUP(); +} + + +TEST_(load_store_regoffset) { + SET_UP(); + + COMPARE(ldr(w0, MemOperand(x1, w2, UXTW)), "ldr w0, [x1, w2, uxtw]"); + COMPARE(ldr(w3, MemOperand(x4, w5, UXTW, 2)), "ldr w3, [x4, w5, uxtw #2]"); + COMPARE(ldr(w6, MemOperand(x7, x8)), "ldr w6, [x7, x8]"); + COMPARE(ldr(w9, MemOperand(x10, x11, LSL, 2)), "ldr w9, [x10, x11, lsl #2]"); + COMPARE(ldr(w12, MemOperand(x13, w14, SXTW)), "ldr w12, [x13, w14, sxtw]"); + COMPARE(ldr(w15, MemOperand(x16, w17, SXTW, 2)), + "ldr w15, [x16, w17, sxtw #2]"); + COMPARE(ldr(w18, MemOperand(x19, x20, SXTX)), "ldr w18, [x19, x20, sxtx]"); + COMPARE(ldr(w21, MemOperand(x22, x23, SXTX, 2)), + "ldr w21, [x22, x23, sxtx #2]"); + COMPARE(ldr(x0, MemOperand(x1, w2, UXTW)), "ldr x0, [x1, w2, uxtw]"); + COMPARE(ldr(x3, MemOperand(x4, w5, UXTW, 3)), "ldr x3, [x4, w5, uxtw #3]"); + COMPARE(ldr(x6, MemOperand(x7, x8)), "ldr x6, [x7, x8]"); + COMPARE(ldr(x9, MemOperand(x10, x11, LSL, 3)), "ldr x9, [x10, x11, lsl #3]"); + COMPARE(ldr(x12, MemOperand(x13, w14, SXTW)), "ldr x12, [x13, w14, sxtw]"); + COMPARE(ldr(x15, MemOperand(x16, w17, SXTW, 3)), + "ldr x15, [x16, w17, sxtw #3]"); + COMPARE(ldr(x18, MemOperand(x19, x20, SXTX)), "ldr x18, [x19, x20, sxtx]"); + COMPARE(ldr(x21, MemOperand(x22, x23, SXTX, 3)), + "ldr x21, [x22, x23, sxtx #3]"); + + COMPARE(str(w0, MemOperand(x1, w2, UXTW)), "str w0, [x1, w2, uxtw]"); + COMPARE(str(w3, MemOperand(x4, w5, UXTW, 2)), "str w3, [x4, w5, uxtw #2]"); + COMPARE(str(w6, MemOperand(x7, x8)), "str w6, [x7, x8]"); + COMPARE(str(w9, MemOperand(x10, x11, LSL, 2)), "str w9, [x10, x11, lsl #2]"); + COMPARE(str(w12, MemOperand(x13, w14, SXTW)), "str w12, [x13, w14, sxtw]"); + COMPARE(str(w15, MemOperand(x16, w17, SXTW, 2)), + "str w15, [x16, w17, sxtw #2]"); + COMPARE(str(w18, MemOperand(x19, x20, SXTX)), "str w18, [x19, x20, sxtx]"); + COMPARE(str(w21, MemOperand(x22, x23, SXTX, 2)), + "str w21, [x22, x23, sxtx #2]"); + COMPARE(str(x0, MemOperand(x1, w2, UXTW)), "str x0, [x1, w2, uxtw]"); + COMPARE(str(x3, MemOperand(x4, w5, UXTW, 3)), "str x3, [x4, w5, uxtw #3]"); + COMPARE(str(x6, MemOperand(x7, x8)), "str x6, [x7, x8]"); + COMPARE(str(x9, MemOperand(x10, x11, LSL, 3)), "str x9, [x10, x11, lsl #3]"); + COMPARE(str(x12, MemOperand(x13, w14, SXTW)), "str x12, [x13, w14, sxtw]"); + COMPARE(str(x15, MemOperand(x16, w17, SXTW, 3)), + "str x15, [x16, w17, sxtw #3]"); + COMPARE(str(x18, MemOperand(x19, x20, SXTX)), "str x18, [x19, x20, sxtx]"); + COMPARE(str(x21, MemOperand(x22, x23, SXTX, 3)), + "str x21, [x22, x23, sxtx #3]"); + + COMPARE(ldrb(w0, MemOperand(x1, w2, UXTW)), "ldrb w0, [x1, w2, uxtw]"); + COMPARE(ldrb(w6, MemOperand(x7, x8)), "ldrb w6, [x7, x8]"); + COMPARE(ldrb(w12, MemOperand(x13, w14, SXTW)), "ldrb w12, [x13, w14, sxtw]"); + COMPARE(ldrb(w18, MemOperand(x19, x20, SXTX)), "ldrb w18, [x19, x20, sxtx]"); + COMPARE(strb(w0, MemOperand(x1, w2, UXTW)), "strb w0, [x1, w2, uxtw]"); + COMPARE(strb(w6, MemOperand(x7, x8)), "strb w6, [x7, x8]"); + COMPARE(strb(w12, MemOperand(x13, w14, SXTW)), "strb w12, [x13, w14, sxtw]"); + COMPARE(strb(w18, MemOperand(x19, x20, SXTX)), "strb w18, [x19, x20, sxtx]"); + + COMPARE(ldrh(w0, MemOperand(x1, w2, UXTW)), "ldrh w0, [x1, w2, uxtw]"); + COMPARE(ldrh(w3, MemOperand(x4, w5, UXTW, 1)), "ldrh w3, [x4, w5, uxtw #1]"); + COMPARE(ldrh(w6, MemOperand(x7, x8)), "ldrh w6, [x7, x8]"); + COMPARE(ldrh(w9, MemOperand(x10, x11, LSL, 1)), + "ldrh w9, [x10, x11, lsl #1]"); + COMPARE(ldrh(w12, MemOperand(x13, w14, SXTW)), "ldrh w12, [x13, w14, sxtw]"); + COMPARE(ldrh(w15, MemOperand(x16, w17, SXTW, 1)), + "ldrh w15, [x16, w17, sxtw #1]"); + COMPARE(ldrh(w18, MemOperand(x19, x20, SXTX)), "ldrh w18, [x19, x20, sxtx]"); + COMPARE(ldrh(w21, MemOperand(x22, x23, SXTX, 1)), + "ldrh w21, [x22, x23, sxtx #1]"); + COMPARE(strh(w0, MemOperand(x1, w2, UXTW)), "strh w0, [x1, w2, uxtw]"); + COMPARE(strh(w3, MemOperand(x4, w5, UXTW, 1)), "strh w3, [x4, w5, uxtw #1]"); + COMPARE(strh(w6, MemOperand(x7, x8)), "strh w6, [x7, x8]"); + COMPARE(strh(w9, MemOperand(x10, x11, LSL, 1)), + "strh w9, [x10, x11, lsl #1]"); + COMPARE(strh(w12, MemOperand(x13, w14, SXTW)), "strh w12, [x13, w14, sxtw]"); + COMPARE(strh(w15, MemOperand(x16, w17, SXTW, 1)), + "strh w15, [x16, w17, sxtw #1]"); + COMPARE(strh(w18, MemOperand(x19, x20, SXTX)), "strh w18, [x19, x20, sxtx]"); + COMPARE(strh(w21, MemOperand(x22, x23, SXTX, 1)), + "strh w21, [x22, x23, sxtx #1]"); + + // TODO(all): Fix this for jssp. + COMPARE(ldr(x0, MemOperand(jssp, wzr, SXTW)), "ldr x0, [jssp, wzr, sxtw]"); + COMPARE(str(x1, MemOperand(jssp, xzr)), "str x1, [jssp, xzr]"); + + CLEANUP(); +} + + +TEST_(load_store_byte) { + SET_UP(); + + COMPARE(ldrb(w0, MemOperand(x1)), "ldrb w0, [x1]"); + COMPARE(ldrb(x2, MemOperand(x3)), "ldrb w2, [x3]"); + COMPARE(ldrb(w4, MemOperand(x5, 4095)), "ldrb w4, [x5, #4095]"); + COMPARE(ldrb(w6, MemOperand(x7, 255, PreIndex)), "ldrb w6, [x7, #255]!"); + COMPARE(ldrb(w8, MemOperand(x9, -256, PreIndex)), "ldrb w8, [x9, #-256]!"); + COMPARE(ldrb(w10, MemOperand(x11, 255, PostIndex)), "ldrb w10, [x11], #255"); + COMPARE(ldrb(w12, MemOperand(x13, -256, PostIndex)), + "ldrb w12, [x13], #-256"); + COMPARE(strb(w14, MemOperand(x15)), "strb w14, [x15]"); + COMPARE(strb(x16, MemOperand(x17)), "strb w16, [x17]"); + COMPARE(strb(w18, MemOperand(x19, 4095)), "strb w18, [x19, #4095]"); + COMPARE(strb(w20, MemOperand(x21, 255, PreIndex)), "strb w20, [x21, #255]!"); + COMPARE(strb(w22, MemOperand(x23, -256, PreIndex)), + "strb w22, [x23, #-256]!"); + COMPARE(strb(w24, MemOperand(x25, 255, PostIndex)), "strb w24, [x25], #255"); + COMPARE(strb(w26, MemOperand(cp, -256, PostIndex)), + "strb w26, [cp], #-256"); + // TODO(all): Fix this for jssp. + COMPARE(ldrb(w28, MemOperand(jssp, 3, PostIndex)), "ldrb w28, [jssp], #3"); + COMPARE(strb(fp, MemOperand(jssp, -42, PreIndex)), "strb w29, [jssp, #-42]!"); + COMPARE(ldrsb(w0, MemOperand(x1)), "ldrsb w0, [x1]"); + COMPARE(ldrsb(x2, MemOperand(x3, 8)), "ldrsb x2, [x3, #8]"); + COMPARE(ldrsb(w4, MemOperand(x5, 42, PreIndex)), "ldrsb w4, [x5, #42]!"); + COMPARE(ldrsb(x6, MemOperand(x7, -11, PostIndex)), "ldrsb x6, [x7], #-11"); + + CLEANUP(); +} + + +TEST_(load_store_half) { + SET_UP(); + + COMPARE(ldrh(w0, MemOperand(x1)), "ldrh w0, [x1]"); + COMPARE(ldrh(x2, MemOperand(x3)), "ldrh w2, [x3]"); + COMPARE(ldrh(w4, MemOperand(x5, 8190)), "ldrh w4, [x5, #8190]"); + COMPARE(ldrh(w6, MemOperand(x7, 255, PreIndex)), "ldrh w6, [x7, #255]!"); + COMPARE(ldrh(w8, MemOperand(x9, -256, PreIndex)), "ldrh w8, [x9, #-256]!"); + COMPARE(ldrh(w10, MemOperand(x11, 255, PostIndex)), "ldrh w10, [x11], #255"); + COMPARE(ldrh(w12, MemOperand(x13, -256, PostIndex)), + "ldrh w12, [x13], #-256"); + COMPARE(strh(w14, MemOperand(x15)), "strh w14, [x15]"); + COMPARE(strh(x16, MemOperand(x17)), "strh w16, [x17]"); + COMPARE(strh(w18, MemOperand(x19, 8190)), "strh w18, [x19, #8190]"); + COMPARE(strh(w20, MemOperand(x21, 255, PreIndex)), "strh w20, [x21, #255]!"); + COMPARE(strh(w22, MemOperand(x23, -256, PreIndex)), + "strh w22, [x23, #-256]!"); + COMPARE(strh(w24, MemOperand(x25, 255, PostIndex)), "strh w24, [x25], #255"); + COMPARE(strh(w26, MemOperand(cp, -256, PostIndex)), + "strh w26, [cp], #-256"); + // TODO(all): Fix this for jssp. + COMPARE(ldrh(w28, MemOperand(jssp, 3, PostIndex)), "ldrh w28, [jssp], #3"); + COMPARE(strh(fp, MemOperand(jssp, -42, PreIndex)), "strh w29, [jssp, #-42]!"); + COMPARE(ldrh(w30, MemOperand(x0, 255)), "ldurh w30, [x0, #255]"); + COMPARE(ldrh(x1, MemOperand(x2, -256)), "ldurh w1, [x2, #-256]"); + COMPARE(strh(w3, MemOperand(x4, 255)), "sturh w3, [x4, #255]"); + COMPARE(strh(x5, MemOperand(x6, -256)), "sturh w5, [x6, #-256]"); + COMPARE(ldrsh(w0, MemOperand(x1)), "ldrsh w0, [x1]"); + COMPARE(ldrsh(w2, MemOperand(x3, 8)), "ldrsh w2, [x3, #8]"); + COMPARE(ldrsh(w4, MemOperand(x5, 42, PreIndex)), "ldrsh w4, [x5, #42]!"); + COMPARE(ldrsh(x6, MemOperand(x7, -11, PostIndex)), "ldrsh x6, [x7], #-11"); + + CLEANUP(); +} + + +TEST_(load_store_fp) { + SET_UP(); + + COMPARE(ldr(s0, MemOperand(x1)), "ldr s0, [x1]"); + COMPARE(ldr(s2, MemOperand(x3, 4)), "ldr s2, [x3, #4]"); + COMPARE(ldr(s4, MemOperand(x5, 16380)), "ldr s4, [x5, #16380]"); + COMPARE(ldr(d6, MemOperand(x7)), "ldr d6, [x7]"); + COMPARE(ldr(d8, MemOperand(x9, 8)), "ldr d8, [x9, #8]"); + COMPARE(ldr(d10, MemOperand(x11, 32760)), "ldr d10, [x11, #32760]"); + COMPARE(str(s12, MemOperand(x13)), "str s12, [x13]"); + COMPARE(str(s14, MemOperand(x15, 4)), "str s14, [x15, #4]"); + COMPARE(str(s16, MemOperand(x17, 16380)), "str s16, [x17, #16380]"); + COMPARE(str(d18, MemOperand(x19)), "str d18, [x19]"); + COMPARE(str(d20, MemOperand(x21, 8)), "str d20, [x21, #8]"); + COMPARE(str(d22, MemOperand(x23, 32760)), "str d22, [x23, #32760]"); + + COMPARE(ldr(s0, MemOperand(x1, 4, PreIndex)), "ldr s0, [x1, #4]!"); + COMPARE(ldr(s2, MemOperand(x3, 255, PreIndex)), "ldr s2, [x3, #255]!"); + COMPARE(ldr(s4, MemOperand(x5, -256, PreIndex)), "ldr s4, [x5, #-256]!"); + COMPARE(ldr(d6, MemOperand(x7, 8, PreIndex)), "ldr d6, [x7, #8]!"); + COMPARE(ldr(d8, MemOperand(x9, 255, PreIndex)), "ldr d8, [x9, #255]!"); + COMPARE(ldr(d10, MemOperand(x11, -256, PreIndex)), "ldr d10, [x11, #-256]!"); + COMPARE(str(s12, MemOperand(x13, 4, PreIndex)), "str s12, [x13, #4]!"); + COMPARE(str(s14, MemOperand(x15, 255, PreIndex)), "str s14, [x15, #255]!"); + COMPARE(str(s16, MemOperand(x17, -256, PreIndex)), "str s16, [x17, #-256]!"); + COMPARE(str(d18, MemOperand(x19, 8, PreIndex)), "str d18, [x19, #8]!"); + COMPARE(str(d20, MemOperand(x21, 255, PreIndex)), "str d20, [x21, #255]!"); + COMPARE(str(d22, MemOperand(x23, -256, PreIndex)), "str d22, [x23, #-256]!"); + + COMPARE(ldr(s0, MemOperand(x1, 4, PostIndex)), "ldr s0, [x1], #4"); + COMPARE(ldr(s2, MemOperand(x3, 255, PostIndex)), "ldr s2, [x3], #255"); + COMPARE(ldr(s4, MemOperand(x5, -256, PostIndex)), "ldr s4, [x5], #-256"); + COMPARE(ldr(d6, MemOperand(x7, 8, PostIndex)), "ldr d6, [x7], #8"); + COMPARE(ldr(d8, MemOperand(x9, 255, PostIndex)), "ldr d8, [x9], #255"); + COMPARE(ldr(d10, MemOperand(x11, -256, PostIndex)), "ldr d10, [x11], #-256"); + COMPARE(str(s12, MemOperand(x13, 4, PostIndex)), "str s12, [x13], #4"); + COMPARE(str(s14, MemOperand(x15, 255, PostIndex)), "str s14, [x15], #255"); + COMPARE(str(s16, MemOperand(x17, -256, PostIndex)), "str s16, [x17], #-256"); + COMPARE(str(d18, MemOperand(x19, 8, PostIndex)), "str d18, [x19], #8"); + COMPARE(str(d20, MemOperand(x21, 255, PostIndex)), "str d20, [x21], #255"); + COMPARE(str(d22, MemOperand(x23, -256, PostIndex)), "str d22, [x23], #-256"); + + // TODO(all): Fix this for jssp. + COMPARE(ldr(s24, MemOperand(jssp)), "ldr s24, [jssp]"); + COMPARE(ldr(d25, MemOperand(jssp, 8)), "ldr d25, [jssp, #8]"); + COMPARE(str(s26, MemOperand(jssp, 4, PreIndex)), "str s26, [jssp, #4]!"); + COMPARE(str(d27, MemOperand(jssp, -8, PostIndex)), "str d27, [jssp], #-8"); + + CLEANUP(); +} + + +TEST_(load_store_unscaled) { + SET_UP(); + + COMPARE(ldr(w0, MemOperand(x1, 1)), "ldur w0, [x1, #1]"); + COMPARE(ldr(w2, MemOperand(x3, -1)), "ldur w2, [x3, #-1]"); + COMPARE(ldr(w4, MemOperand(x5, 255)), "ldur w4, [x5, #255]"); + COMPARE(ldr(w6, MemOperand(x7, -256)), "ldur w6, [x7, #-256]"); + COMPARE(ldr(x8, MemOperand(x9, 1)), "ldur x8, [x9, #1]"); + COMPARE(ldr(x10, MemOperand(x11, -1)), "ldur x10, [x11, #-1]"); + COMPARE(ldr(x12, MemOperand(x13, 255)), "ldur x12, [x13, #255]"); + COMPARE(ldr(x14, MemOperand(x15, -256)), "ldur x14, [x15, #-256]"); + COMPARE(str(w16, MemOperand(x17, 1)), "stur w16, [x17, #1]"); + COMPARE(str(w18, MemOperand(x19, -1)), "stur w18, [x19, #-1]"); + COMPARE(str(w20, MemOperand(x21, 255)), "stur w20, [x21, #255]"); + COMPARE(str(w22, MemOperand(x23, -256)), "stur w22, [x23, #-256]"); + COMPARE(str(x24, MemOperand(x25, 1)), "stur x24, [x25, #1]"); + COMPARE(str(x26, MemOperand(cp, -1)), "stur x26, [cp, #-1]"); + COMPARE(str(jssp, MemOperand(fp, 255)), "stur jssp, [fp, #255]"); + COMPARE(str(lr, MemOperand(x0, -256)), "stur lr, [x0, #-256]"); + COMPARE(ldr(w0, MemOperand(csp, 1)), "ldur w0, [csp, #1]"); + COMPARE(str(x1, MemOperand(csp, -1)), "stur x1, [csp, #-1]"); + COMPARE(ldrb(w2, MemOperand(x3, -2)), "ldurb w2, [x3, #-2]"); + COMPARE(ldrsb(w4, MemOperand(x5, -3)), "ldursb w4, [x5, #-3]"); + COMPARE(ldrsb(x6, MemOperand(x7, -4)), "ldursb x6, [x7, #-4]"); + COMPARE(ldrh(w8, MemOperand(x9, -5)), "ldurh w8, [x9, #-5]"); + COMPARE(ldrsh(w10, MemOperand(x11, -6)), "ldursh w10, [x11, #-6]"); + COMPARE(ldrsh(x12, MemOperand(x13, -7)), "ldursh x12, [x13, #-7]"); + COMPARE(ldrsw(x14, MemOperand(x15, -8)), "ldursw x14, [x15, #-8]"); + + CLEANUP(); +} + + +TEST_(load_store_pair) { + SET_UP(); + + COMPARE(ldp(w0, w1, MemOperand(x2)), "ldp w0, w1, [x2]"); + COMPARE(ldp(x3, x4, MemOperand(x5)), "ldp x3, x4, [x5]"); + COMPARE(ldp(w6, w7, MemOperand(x8, 4)), "ldp w6, w7, [x8, #4]"); + COMPARE(ldp(x9, x10, MemOperand(x11, 8)), "ldp x9, x10, [x11, #8]"); + COMPARE(ldp(w12, w13, MemOperand(x14, 252)), "ldp w12, w13, [x14, #252]"); + COMPARE(ldp(x15, x16, MemOperand(x17, 504)), "ldp x15, x16, [x17, #504]"); + COMPARE(ldp(w18, w19, MemOperand(x20, -256)), "ldp w18, w19, [x20, #-256]"); + COMPARE(ldp(x21, x22, MemOperand(x23, -512)), "ldp x21, x22, [x23, #-512]"); + COMPARE(ldp(w24, w25, MemOperand(x26, 252, PreIndex)), + "ldp w24, w25, [x26, #252]!"); + COMPARE(ldp(cp, jssp, MemOperand(fp, 504, PreIndex)), + "ldp cp, jssp, [fp, #504]!"); + COMPARE(ldp(w30, w0, MemOperand(x1, -256, PreIndex)), + "ldp w30, w0, [x1, #-256]!"); + COMPARE(ldp(x2, x3, MemOperand(x4, -512, PreIndex)), + "ldp x2, x3, [x4, #-512]!"); + COMPARE(ldp(w5, w6, MemOperand(x7, 252, PostIndex)), + "ldp w5, w6, [x7], #252"); + COMPARE(ldp(x8, x9, MemOperand(x10, 504, PostIndex)), + "ldp x8, x9, [x10], #504"); + COMPARE(ldp(w11, w12, MemOperand(x13, -256, PostIndex)), + "ldp w11, w12, [x13], #-256"); + COMPARE(ldp(x14, x15, MemOperand(x16, -512, PostIndex)), + "ldp x14, x15, [x16], #-512"); + + COMPARE(ldp(s17, s18, MemOperand(x19)), "ldp s17, s18, [x19]"); + COMPARE(ldp(s20, s21, MemOperand(x22, 252)), "ldp s20, s21, [x22, #252]"); + COMPARE(ldp(s23, s24, MemOperand(x25, -256)), "ldp s23, s24, [x25, #-256]"); + COMPARE(ldp(s26, s27, MemOperand(jssp, 252, PreIndex)), + "ldp s26, s27, [jssp, #252]!"); + COMPARE(ldp(s29, s30, MemOperand(fp, -256, PreIndex)), + "ldp s29, s30, [fp, #-256]!"); + COMPARE(ldp(s31, s0, MemOperand(x1, 252, PostIndex)), + "ldp s31, s0, [x1], #252"); + COMPARE(ldp(s2, s3, MemOperand(x4, -256, PostIndex)), + "ldp s2, s3, [x4], #-256"); + COMPARE(ldp(d17, d18, MemOperand(x19)), "ldp d17, d18, [x19]"); + COMPARE(ldp(d20, d21, MemOperand(x22, 504)), "ldp d20, d21, [x22, #504]"); + COMPARE(ldp(d23, d24, MemOperand(x25, -512)), "ldp d23, d24, [x25, #-512]"); + COMPARE(ldp(d26, d27, MemOperand(jssp, 504, PreIndex)), + "ldp d26, d27, [jssp, #504]!"); + COMPARE(ldp(d29, d30, MemOperand(fp, -512, PreIndex)), + "ldp d29, d30, [fp, #-512]!"); + COMPARE(ldp(d31, d0, MemOperand(x1, 504, PostIndex)), + "ldp d31, d0, [x1], #504"); + COMPARE(ldp(d2, d3, MemOperand(x4, -512, PostIndex)), + "ldp d2, d3, [x4], #-512"); + + COMPARE(stp(w0, w1, MemOperand(x2)), "stp w0, w1, [x2]"); + COMPARE(stp(x3, x4, MemOperand(x5)), "stp x3, x4, [x5]"); + COMPARE(stp(w6, w7, MemOperand(x8, 4)), "stp w6, w7, [x8, #4]"); + COMPARE(stp(x9, x10, MemOperand(x11, 8)), "stp x9, x10, [x11, #8]"); + COMPARE(stp(w12, w13, MemOperand(x14, 252)), "stp w12, w13, [x14, #252]"); + COMPARE(stp(x15, x16, MemOperand(x17, 504)), "stp x15, x16, [x17, #504]"); + COMPARE(stp(w18, w19, MemOperand(x20, -256)), "stp w18, w19, [x20, #-256]"); + COMPARE(stp(x21, x22, MemOperand(x23, -512)), "stp x21, x22, [x23, #-512]"); + COMPARE(stp(w24, w25, MemOperand(x26, 252, PreIndex)), + "stp w24, w25, [x26, #252]!"); + COMPARE(stp(cp, jssp, MemOperand(fp, 504, PreIndex)), + "stp cp, jssp, [fp, #504]!"); + COMPARE(stp(w30, w0, MemOperand(x1, -256, PreIndex)), + "stp w30, w0, [x1, #-256]!"); + COMPARE(stp(x2, x3, MemOperand(x4, -512, PreIndex)), + "stp x2, x3, [x4, #-512]!"); + COMPARE(stp(w5, w6, MemOperand(x7, 252, PostIndex)), + "stp w5, w6, [x7], #252"); + COMPARE(stp(x8, x9, MemOperand(x10, 504, PostIndex)), + "stp x8, x9, [x10], #504"); + COMPARE(stp(w11, w12, MemOperand(x13, -256, PostIndex)), + "stp w11, w12, [x13], #-256"); + COMPARE(stp(x14, x15, MemOperand(x16, -512, PostIndex)), + "stp x14, x15, [x16], #-512"); + + COMPARE(stp(s17, s18, MemOperand(x19)), "stp s17, s18, [x19]"); + COMPARE(stp(s20, s21, MemOperand(x22, 252)), "stp s20, s21, [x22, #252]"); + COMPARE(stp(s23, s24, MemOperand(x25, -256)), "stp s23, s24, [x25, #-256]"); + COMPARE(stp(s26, s27, MemOperand(jssp, 252, PreIndex)), + "stp s26, s27, [jssp, #252]!"); + COMPARE(stp(s29, s30, MemOperand(fp, -256, PreIndex)), + "stp s29, s30, [fp, #-256]!"); + COMPARE(stp(s31, s0, MemOperand(x1, 252, PostIndex)), + "stp s31, s0, [x1], #252"); + COMPARE(stp(s2, s3, MemOperand(x4, -256, PostIndex)), + "stp s2, s3, [x4], #-256"); + COMPARE(stp(d17, d18, MemOperand(x19)), "stp d17, d18, [x19]"); + COMPARE(stp(d20, d21, MemOperand(x22, 504)), "stp d20, d21, [x22, #504]"); + COMPARE(stp(d23, d24, MemOperand(x25, -512)), "stp d23, d24, [x25, #-512]"); + COMPARE(stp(d26, d27, MemOperand(jssp, 504, PreIndex)), + "stp d26, d27, [jssp, #504]!"); + COMPARE(stp(d29, d30, MemOperand(fp, -512, PreIndex)), + "stp d29, d30, [fp, #-512]!"); + COMPARE(stp(d31, d0, MemOperand(x1, 504, PostIndex)), + "stp d31, d0, [x1], #504"); + COMPARE(stp(d2, d3, MemOperand(x4, -512, PostIndex)), + "stp d2, d3, [x4], #-512"); + + // TODO(all): Update / Restore this test. + COMPARE(ldp(w16, w17, MemOperand(jssp, 4, PostIndex)), + "ldp w16, w17, [jssp], #4"); + COMPARE(stp(x18, x19, MemOperand(jssp, -8, PreIndex)), + "stp x18, x19, [jssp, #-8]!"); + COMPARE(ldp(s30, s31, MemOperand(jssp, 12, PostIndex)), + "ldp s30, s31, [jssp], #12"); + COMPARE(stp(d30, d31, MemOperand(jssp, -16)), + "stp d30, d31, [jssp, #-16]"); + + COMPARE(ldpsw(x0, x1, MemOperand(x2)), "ldpsw x0, x1, [x2]"); + COMPARE(ldpsw(x3, x4, MemOperand(x5, 16)), "ldpsw x3, x4, [x5, #16]"); + COMPARE(ldpsw(x6, x7, MemOperand(x8, -32, PreIndex)), + "ldpsw x6, x7, [x8, #-32]!"); + COMPARE(ldpsw(x9, x10, MemOperand(x11, 128, PostIndex)), + "ldpsw x9, x10, [x11], #128"); + + CLEANUP(); +} + + +TEST_(load_store_pair_nontemp) { + SET_UP(); + + COMPARE(ldnp(w0, w1, MemOperand(x2)), "ldnp w0, w1, [x2]"); + COMPARE(stnp(w3, w4, MemOperand(x5, 252)), "stnp w3, w4, [x5, #252]"); + COMPARE(ldnp(w6, w7, MemOperand(x8, -256)), "ldnp w6, w7, [x8, #-256]"); + COMPARE(stnp(x9, x10, MemOperand(x11)), "stnp x9, x10, [x11]"); + COMPARE(ldnp(x12, x13, MemOperand(x14, 504)), "ldnp x12, x13, [x14, #504]"); + COMPARE(stnp(x15, x16, MemOperand(x17, -512)), "stnp x15, x16, [x17, #-512]"); + COMPARE(ldnp(s18, s19, MemOperand(x20)), "ldnp s18, s19, [x20]"); + COMPARE(stnp(s21, s22, MemOperand(x23, 252)), "stnp s21, s22, [x23, #252]"); + COMPARE(ldnp(s24, s25, MemOperand(x26, -256)), "ldnp s24, s25, [x26, #-256]"); + COMPARE(stnp(d27, d28, MemOperand(fp)), "stnp d27, d28, [fp]"); + COMPARE(ldnp(d30, d31, MemOperand(x0, 504)), "ldnp d30, d31, [x0, #504]"); + COMPARE(stnp(d1, d2, MemOperand(x3, -512)), "stnp d1, d2, [x3, #-512]"); + + CLEANUP(); +} + +#if 0 // TODO(all): enable. +TEST_(load_literal) { + SET_UP(); + + COMPARE_PREFIX(ldr(x10, 0x1234567890abcdefUL), "ldr x10, pc+8"); + COMPARE_PREFIX(ldr(w20, 0xfedcba09), "ldr w20, pc+8"); + COMPARE_PREFIX(ldr(d11, 1.234), "ldr d11, pc+8"); + COMPARE_PREFIX(ldr(s22, 2.5), "ldr s22, pc+8"); + + CLEANUP(); +} +#endif + +TEST_(cond_select) { + SET_UP(); + + COMPARE(csel(w0, w1, w2, eq), "csel w0, w1, w2, eq"); + COMPARE(csel(x3, x4, x5, ne), "csel x3, x4, x5, ne"); + COMPARE(csinc(w6, w7, w8, hs), "csinc w6, w7, w8, hs"); + COMPARE(csinc(x9, x10, x11, lo), "csinc x9, x10, x11, lo"); + COMPARE(csinv(w12, w13, w14, mi), "csinv w12, w13, w14, mi"); + COMPARE(csinv(x15, x16, x17, pl), "csinv x15, x16, x17, pl"); + COMPARE(csneg(w18, w19, w20, vs), "csneg w18, w19, w20, vs"); + COMPARE(csneg(x21, x22, x23, vc), "csneg x21, x22, x23, vc"); + COMPARE(cset(w24, hi), "cset w24, hi"); + COMPARE(cset(x25, ls), "cset x25, ls"); + COMPARE(csetm(w26, ge), "csetm w26, ge"); + COMPARE(csetm(cp, lt), "csetm cp, lt"); + COMPARE(cinc(w28, w29, gt), "cinc w28, w29, gt"); + COMPARE(cinc(lr, x0, le), "cinc lr, x0, le"); + COMPARE(cinv(w1, w2, eq), "cinv w1, w2, eq"); + COMPARE(cinv(x3, x4, ne), "cinv x3, x4, ne"); + COMPARE(cneg(w5, w6, hs), "cneg w5, w6, hs"); + COMPARE(cneg(x7, x8, lo), "cneg x7, x8, lo"); + + COMPARE(csel(x0, x1, x2, al), "csel x0, x1, x2, al"); + COMPARE(csel(x1, x2, x3, nv), "csel x1, x2, x3, nv"); + COMPARE(csinc(x2, x3, x4, al), "csinc x2, x3, x4, al"); + COMPARE(csinc(x3, x4, x5, nv), "csinc x3, x4, x5, nv"); + COMPARE(csinv(x4, x5, x6, al), "csinv x4, x5, x6, al"); + COMPARE(csinv(x5, x6, x7, nv), "csinv x5, x6, x7, nv"); + COMPARE(csneg(x6, x7, x8, al), "csneg x6, x7, x8, al"); + COMPARE(csneg(x7, x8, x9, nv), "csneg x7, x8, x9, nv"); + + CLEANUP(); +} + + +TEST(cond_select_macro) { + SET_UP_CLASS(MacroAssembler); + + COMPARE(Csel(w0, w1, -1, eq), "csinv w0, w1, wzr, eq"); + COMPARE(Csel(w2, w3, 0, ne), "csel w2, w3, wzr, ne"); + COMPARE(Csel(w4, w5, 1, hs), "csinc w4, w5, wzr, hs"); + COMPARE(Csel(x6, x7, -1, lo), "csinv x6, x7, xzr, lo"); + COMPARE(Csel(x8, x9, 0, mi), "csel x8, x9, xzr, mi"); + COMPARE(Csel(x10, x11, 1, pl), "csinc x10, x11, xzr, pl"); + + CLEANUP(); +} + + +TEST_(cond_cmp) { + SET_UP(); + + COMPARE(ccmn(w0, w1, NZCVFlag, eq), "ccmn w0, w1, #NZCV, eq"); + COMPARE(ccmn(x2, x3, NZCFlag, ne), "ccmn x2, x3, #NZCv, ne"); + COMPARE(ccmp(w4, w5, NZVFlag, hs), "ccmp w4, w5, #NZcV, hs"); + COMPARE(ccmp(x6, x7, NZFlag, lo), "ccmp x6, x7, #NZcv, lo"); + COMPARE(ccmn(w8, 31, NFlag, mi), "ccmn w8, #31, #Nzcv, mi"); + COMPARE(ccmn(x9, 30, NCFlag, pl), "ccmn x9, #30, #NzCv, pl"); + COMPARE(ccmp(w10, 29, NVFlag, vs), "ccmp w10, #29, #NzcV, vs"); + COMPARE(ccmp(x11, 28, NFlag, vc), "ccmp x11, #28, #Nzcv, vc"); + COMPARE(ccmn(w12, w13, NoFlag, al), "ccmn w12, w13, #nzcv, al"); + COMPARE(ccmp(x14, 27, ZVFlag, nv), "ccmp x14, #27, #nZcV, nv"); + + CLEANUP(); +} + + +TEST_(cond_cmp_macro) { + SET_UP_CLASS(MacroAssembler); + + COMPARE(Ccmp(w0, -1, VFlag, hi), "ccmn w0, #1, #nzcV, hi"); + COMPARE(Ccmp(x1, -31, CFlag, ge), "ccmn x1, #31, #nzCv, ge"); + COMPARE(Ccmn(w2, -1, CVFlag, gt), "ccmp w2, #1, #nzCV, gt"); + COMPARE(Ccmn(x3, -31, ZCVFlag, ls), "ccmp x3, #31, #nZCV, ls"); + + CLEANUP(); +} + + +TEST_(fmov_imm) { + SET_UP(); + + COMPARE(fmov(s0, 1.0), "fmov s0, #0x70 (1.0000)"); + COMPARE(fmov(s31, -13.0), "fmov s31, #0xaa (-13.0000)"); + COMPARE(fmov(d1, 1.0), "fmov d1, #0x70 (1.0000)"); + COMPARE(fmov(d29, -13.0), "fmov d29, #0xaa (-13.0000)"); + + CLEANUP(); +} + + +TEST_(fmov_reg) { + SET_UP(); + + COMPARE(fmov(w3, s13), "fmov w3, s13"); + COMPARE(fmov(x6, d26), "fmov x6, d26"); + COMPARE(fmov(s11, w30), "fmov s11, w30"); + COMPARE(fmov(d31, x2), "fmov d31, x2"); + COMPARE(fmov(s12, s13), "fmov s12, s13"); + COMPARE(fmov(d22, d23), "fmov d22, d23"); + + CLEANUP(); +} + + +TEST_(fp_dp1) { + SET_UP(); + + COMPARE(fabs(s0, s1), "fabs s0, s1"); + COMPARE(fabs(s31, s30), "fabs s31, s30"); + COMPARE(fabs(d2, d3), "fabs d2, d3"); + COMPARE(fabs(d31, d30), "fabs d31, d30"); + COMPARE(fneg(s4, s5), "fneg s4, s5"); + COMPARE(fneg(s31, s30), "fneg s31, s30"); + COMPARE(fneg(d6, d7), "fneg d6, d7"); + COMPARE(fneg(d31, d30), "fneg d31, d30"); + COMPARE(fsqrt(s8, s9), "fsqrt s8, s9"); + COMPARE(fsqrt(s31, s30), "fsqrt s31, s30"); + COMPARE(fsqrt(d10, d11), "fsqrt d10, d11"); + COMPARE(fsqrt(d31, d30), "fsqrt d31, d30"); + COMPARE(frinta(s10, s11), "frinta s10, s11"); + COMPARE(frinta(s31, s30), "frinta s31, s30"); + COMPARE(frinta(d12, d13), "frinta d12, d13"); + COMPARE(frinta(d31, d30), "frinta d31, d30"); + COMPARE(frintn(s10, s11), "frintn s10, s11"); + COMPARE(frintn(s31, s30), "frintn s31, s30"); + COMPARE(frintn(d12, d13), "frintn d12, d13"); + COMPARE(frintn(d31, d30), "frintn d31, d30"); + COMPARE(frintz(s10, s11), "frintz s10, s11"); + COMPARE(frintz(s31, s30), "frintz s31, s30"); + COMPARE(frintz(d12, d13), "frintz d12, d13"); + COMPARE(frintz(d31, d30), "frintz d31, d30"); + COMPARE(fcvt(d14, s15), "fcvt d14, s15"); + COMPARE(fcvt(d31, s31), "fcvt d31, s31"); + + CLEANUP(); +} + + +TEST_(fp_dp2) { + SET_UP(); + + COMPARE(fadd(s0, s1, s2), "fadd s0, s1, s2"); + COMPARE(fadd(d3, d4, d5), "fadd d3, d4, d5"); + COMPARE(fsub(s31, s30, s29), "fsub s31, s30, s29"); + COMPARE(fsub(d31, d30, d29), "fsub d31, d30, d29"); + COMPARE(fmul(s7, s8, s9), "fmul s7, s8, s9"); + COMPARE(fmul(d10, d11, d12), "fmul d10, d11, d12"); + COMPARE(fdiv(s13, s14, s15), "fdiv s13, s14, s15"); + COMPARE(fdiv(d16, d17, d18), "fdiv d16, d17, d18"); + COMPARE(fmax(s19, s20, s21), "fmax s19, s20, s21"); + COMPARE(fmax(d22, d23, d24), "fmax d22, d23, d24"); + COMPARE(fmin(s25, s26, s27), "fmin s25, s26, s27"); + COMPARE(fmin(d28, d29, d30), "fmin d28, d29, d30"); + COMPARE(fmaxnm(s31, s0, s1), "fmaxnm s31, s0, s1"); + COMPARE(fmaxnm(d2, d3, d4), "fmaxnm d2, d3, d4"); + COMPARE(fminnm(s5, s6, s7), "fminnm s5, s6, s7"); + COMPARE(fminnm(d8, d9, d10), "fminnm d8, d9, d10"); + + CLEANUP(); +} + + +TEST(fp_dp3) { + SET_UP(); + + COMPARE(fmadd(s7, s8, s9, s10), "fmadd s7, s8, s9, s10"); + COMPARE(fmadd(d10, d11, d12, d10), "fmadd d10, d11, d12, d10"); + COMPARE(fmsub(s7, s8, s9, s10), "fmsub s7, s8, s9, s10"); + COMPARE(fmsub(d10, d11, d12, d10), "fmsub d10, d11, d12, d10"); + + COMPARE(fnmadd(s7, s8, s9, s10), "fnmadd s7, s8, s9, s10"); + COMPARE(fnmadd(d10, d11, d12, d10), "fnmadd d10, d11, d12, d10"); + COMPARE(fnmsub(s7, s8, s9, s10), "fnmsub s7, s8, s9, s10"); + COMPARE(fnmsub(d10, d11, d12, d10), "fnmsub d10, d11, d12, d10"); + + CLEANUP(); +} + + +TEST_(fp_compare) { + SET_UP(); + + COMPARE(fcmp(s0, s1), "fcmp s0, s1"); + COMPARE(fcmp(s31, s30), "fcmp s31, s30"); + COMPARE(fcmp(d0, d1), "fcmp d0, d1"); + COMPARE(fcmp(d31, d30), "fcmp d31, d30"); + COMPARE(fcmp(s12, 0), "fcmp s12, #0.0"); + COMPARE(fcmp(d12, 0), "fcmp d12, #0.0"); + + CLEANUP(); +} + + +TEST_(fp_cond_compare) { + SET_UP(); + + COMPARE(fccmp(s0, s1, NoFlag, eq), "fccmp s0, s1, #nzcv, eq"); + COMPARE(fccmp(s2, s3, ZVFlag, ne), "fccmp s2, s3, #nZcV, ne"); + COMPARE(fccmp(s30, s16, NCFlag, pl), "fccmp s30, s16, #NzCv, pl"); + COMPARE(fccmp(s31, s31, NZCVFlag, le), "fccmp s31, s31, #NZCV, le"); + COMPARE(fccmp(d4, d5, VFlag, gt), "fccmp d4, d5, #nzcV, gt"); + COMPARE(fccmp(d6, d7, NFlag, vs), "fccmp d6, d7, #Nzcv, vs"); + COMPARE(fccmp(d30, d0, NZFlag, vc), "fccmp d30, d0, #NZcv, vc"); + COMPARE(fccmp(d31, d31, ZFlag, hs), "fccmp d31, d31, #nZcv, hs"); + COMPARE(fccmp(s14, s15, CVFlag, al), "fccmp s14, s15, #nzCV, al"); + COMPARE(fccmp(d16, d17, CFlag, nv), "fccmp d16, d17, #nzCv, nv"); + + CLEANUP(); +} + + +TEST_(fp_select) { + SET_UP(); + + COMPARE(fcsel(s0, s1, s2, eq), "fcsel s0, s1, s2, eq") + COMPARE(fcsel(s31, s31, s30, ne), "fcsel s31, s31, s30, ne"); + COMPARE(fcsel(d0, d1, d2, mi), "fcsel d0, d1, d2, mi"); + COMPARE(fcsel(d31, d30, d31, pl), "fcsel d31, d30, d31, pl"); + COMPARE(fcsel(s14, s15, s16, al), "fcsel s14, s15, s16, al"); + COMPARE(fcsel(d17, d18, d19, nv), "fcsel d17, d18, d19, nv"); + + CLEANUP(); +} + + +TEST_(fcvt_scvtf_ucvtf) { + SET_UP(); + + COMPARE(fcvtas(w0, s1), "fcvtas w0, s1"); + COMPARE(fcvtas(x2, s3), "fcvtas x2, s3"); + COMPARE(fcvtas(w4, d5), "fcvtas w4, d5"); + COMPARE(fcvtas(x6, d7), "fcvtas x6, d7"); + COMPARE(fcvtau(w8, s9), "fcvtau w8, s9"); + COMPARE(fcvtau(x10, s11), "fcvtau x10, s11"); + COMPARE(fcvtau(w12, d13), "fcvtau w12, d13"); + COMPARE(fcvtau(x14, d15), "fcvtau x14, d15"); + COMPARE(fcvtns(w0, s1), "fcvtns w0, s1"); + COMPARE(fcvtns(x2, s3), "fcvtns x2, s3"); + COMPARE(fcvtns(w4, d5), "fcvtns w4, d5"); + COMPARE(fcvtns(x6, d7), "fcvtns x6, d7"); + COMPARE(fcvtnu(w8, s9), "fcvtnu w8, s9"); + COMPARE(fcvtnu(x10, s11), "fcvtnu x10, s11"); + COMPARE(fcvtnu(w12, d13), "fcvtnu w12, d13"); + COMPARE(fcvtnu(x14, d15), "fcvtnu x14, d15"); + COMPARE(fcvtzu(x16, d17), "fcvtzu x16, d17"); + COMPARE(fcvtzu(w18, d19), "fcvtzu w18, d19"); + COMPARE(fcvtzs(x20, d21), "fcvtzs x20, d21"); + COMPARE(fcvtzs(w22, d23), "fcvtzs w22, d23"); + COMPARE(fcvtzu(x16, s17), "fcvtzu x16, s17"); + COMPARE(fcvtzu(w18, s19), "fcvtzu w18, s19"); + COMPARE(fcvtzs(x20, s21), "fcvtzs x20, s21"); + COMPARE(fcvtzs(w22, s23), "fcvtzs w22, s23"); + COMPARE(scvtf(d24, w25), "scvtf d24, w25"); + COMPARE(scvtf(s24, w25), "scvtf s24, w25"); + COMPARE(scvtf(d26, x0), "scvtf d26, x0"); + COMPARE(scvtf(s26, x0), "scvtf s26, x0"); + COMPARE(ucvtf(d28, w29), "ucvtf d28, w29"); + COMPARE(ucvtf(s28, w29), "ucvtf s28, w29"); + COMPARE(ucvtf(d0, x1), "ucvtf d0, x1"); + COMPARE(ucvtf(s0, x1), "ucvtf s0, x1"); + COMPARE(ucvtf(d0, x1, 0), "ucvtf d0, x1"); + COMPARE(ucvtf(s0, x1, 0), "ucvtf s0, x1"); + COMPARE(scvtf(d1, x2, 1), "scvtf d1, x2, #1"); + COMPARE(scvtf(s1, x2, 1), "scvtf s1, x2, #1"); + COMPARE(scvtf(d3, x4, 15), "scvtf d3, x4, #15"); + COMPARE(scvtf(s3, x4, 15), "scvtf s3, x4, #15"); + COMPARE(scvtf(d5, x6, 32), "scvtf d5, x6, #32"); + COMPARE(scvtf(s5, x6, 32), "scvtf s5, x6, #32"); + COMPARE(ucvtf(d7, x8, 2), "ucvtf d7, x8, #2"); + COMPARE(ucvtf(s7, x8, 2), "ucvtf s7, x8, #2"); + COMPARE(ucvtf(d9, x10, 16), "ucvtf d9, x10, #16"); + COMPARE(ucvtf(s9, x10, 16), "ucvtf s9, x10, #16"); + COMPARE(ucvtf(d11, x12, 33), "ucvtf d11, x12, #33"); + COMPARE(ucvtf(s11, x12, 33), "ucvtf s11, x12, #33"); + COMPARE(fcvtms(w0, s1), "fcvtms w0, s1"); + COMPARE(fcvtms(x2, s3), "fcvtms x2, s3"); + COMPARE(fcvtms(w4, d5), "fcvtms w4, d5"); + COMPARE(fcvtms(x6, d7), "fcvtms x6, d7"); + COMPARE(fcvtmu(w8, s9), "fcvtmu w8, s9"); + COMPARE(fcvtmu(x10, s11), "fcvtmu x10, s11"); + COMPARE(fcvtmu(w12, d13), "fcvtmu w12, d13"); + COMPARE(fcvtmu(x14, d15), "fcvtmu x14, d15"); + + CLEANUP(); +} + + +TEST_(system_mrs) { + SET_UP(); + + COMPARE(mrs(x0, NZCV), "mrs x0, nzcv"); + COMPARE(mrs(lr, NZCV), "mrs lr, nzcv"); + COMPARE(mrs(x15, FPCR), "mrs x15, fpcr"); + + CLEANUP(); +} + + +TEST_(system_msr) { + SET_UP(); + + COMPARE(msr(NZCV, x0), "msr nzcv, x0"); + COMPARE(msr(NZCV, x30), "msr nzcv, lr"); + COMPARE(msr(FPCR, x15), "msr fpcr, x15"); + + CLEANUP(); +} + + +TEST_(system_nop) { + SET_UP(); + + COMPARE(nop(), "nop"); + + CLEANUP(); +} + + +TEST_(debug) { + SET_UP(); + + ASSERT(kImmExceptionIsDebug == 0xdeb0); + + // All debug codes should produce the same instruction, and the debug code + // can be any uint32_t. + COMPARE(debug("message", 0, NO_PARAM), "hlt #0xdeb0"); + COMPARE(debug("message", 1, NO_PARAM), "hlt #0xdeb0"); + COMPARE(debug("message", 0xffff, NO_PARAM), "hlt #0xdeb0"); + COMPARE(debug("message", 0x10000, NO_PARAM), "hlt #0xdeb0"); + COMPARE(debug("message", 0x7fffffff, NO_PARAM), "hlt #0xdeb0"); + COMPARE(debug("message", 0x80000000u, NO_PARAM), "hlt #0xdeb0"); + COMPARE(debug("message", 0xffffffffu, NO_PARAM), "hlt #0xdeb0"); + + CLEANUP(); +} + + +TEST_(hlt) { + SET_UP(); + + COMPARE(hlt(0), "hlt #0x0"); + COMPARE(hlt(1), "hlt #0x1"); + COMPARE(hlt(65535), "hlt #0xffff"); + + CLEANUP(); +} + + +TEST_(brk) { + SET_UP(); + + COMPARE(brk(0), "brk #0x0"); + COMPARE(brk(1), "brk #0x1"); + COMPARE(brk(65535), "brk #0xffff"); + + CLEANUP(); +} + + +TEST_(add_sub_negative) { + SET_UP_CLASS(MacroAssembler); + + COMPARE(Add(x10, x0, -42), "sub x10, x0, #0x2a (42)"); + COMPARE(Add(x11, x1, -687), "sub x11, x1, #0x2af (687)"); + COMPARE(Add(x12, x2, -0x88), "sub x12, x2, #0x88 (136)"); + + COMPARE(Sub(x13, x0, -600), "add x13, x0, #0x258 (600)"); + COMPARE(Sub(x14, x1, -313), "add x14, x1, #0x139 (313)"); + COMPARE(Sub(x15, x2, -0x555), "add x15, x2, #0x555 (1365)"); + + COMPARE(Add(w19, w3, -0x344), "sub w19, w3, #0x344 (836)"); + COMPARE(Add(w20, w4, -2000), "sub w20, w4, #0x7d0 (2000)"); + + COMPARE(Sub(w21, w3, -0xbc), "add w21, w3, #0xbc (188)"); + COMPARE(Sub(w22, w4, -2000), "add w22, w4, #0x7d0 (2000)"); + + COMPARE(Cmp(w0, -1), "cmn w0, #0x1 (1)"); + COMPARE(Cmp(x1, -1), "cmn x1, #0x1 (1)"); + COMPARE(Cmp(w2, -4095), "cmn w2, #0xfff (4095)"); + COMPARE(Cmp(x3, -4095), "cmn x3, #0xfff (4095)"); + + COMPARE(Cmn(w0, -1), "cmp w0, #0x1 (1)"); + COMPARE(Cmn(x1, -1), "cmp x1, #0x1 (1)"); + COMPARE(Cmn(w2, -4095), "cmp w2, #0xfff (4095)"); + COMPARE(Cmn(x3, -4095), "cmp x3, #0xfff (4095)"); + + CLEANUP(); +} + + +TEST_(logical_immediate_move) { + SET_UP_CLASS(MacroAssembler); + + COMPARE(And(w0, w1, 0), "movz w0, #0x0"); + COMPARE(And(x0, x1, 0), "movz x0, #0x0"); + COMPARE(Orr(w2, w3, 0), "mov w2, w3"); + COMPARE(Orr(x2, x3, 0), "mov x2, x3"); + COMPARE(Eor(w4, w5, 0), "mov w4, w5"); + COMPARE(Eor(x4, x5, 0), "mov x4, x5"); + COMPARE(Bic(w6, w7, 0), "mov w6, w7"); + COMPARE(Bic(x6, x7, 0), "mov x6, x7"); + COMPARE(Orn(w8, w9, 0), "movn w8, #0x0"); + COMPARE(Orn(x8, x9, 0), "movn x8, #0x0"); + COMPARE(Eon(w10, w11, 0), "mvn w10, w11"); + COMPARE(Eon(x10, x11, 0), "mvn x10, x11"); + + COMPARE(And(w12, w13, 0xffffffff), "mov w12, w13"); + COMPARE(And(x12, x13, 0xffffffff), "and x12, x13, #0xffffffff"); + COMPARE(And(x12, x13, 0xffffffffffffffff), "mov x12, x13"); + COMPARE(Orr(w14, w15, 0xffffffff), "movn w14, #0x0"); + COMPARE(Orr(x14, x15, 0xffffffff), "orr x14, x15, #0xffffffff"); + COMPARE(Orr(x14, x15, 0xffffffffffffffff), "movn x14, #0x0"); + COMPARE(Eor(w16, w17, 0xffffffff), "mvn w16, w17"); + COMPARE(Eor(x16, x17, 0xffffffff), "eor x16, x17, #0xffffffff"); + COMPARE(Eor(x16, x17, 0xffffffffffffffff), "mvn x16, x17"); + COMPARE(Bic(w18, w19, 0xffffffff), "movz w18, #0x0"); + COMPARE(Bic(x18, x19, 0xffffffff), "and x18, x19, #0xffffffff00000000"); + COMPARE(Bic(x18, x19, 0xffffffffffffffff), "movz x18, #0x0"); + COMPARE(Orn(w20, w21, 0xffffffff), "mov w20, w21"); + COMPARE(Orn(x20, x21, 0xffffffff), "orr x20, x21, #0xffffffff00000000"); + COMPARE(Orn(x20, x21, 0xffffffffffffffff), "mov x20, x21"); + COMPARE(Eon(w22, w23, 0xffffffff), "mov w22, w23"); + COMPARE(Eon(x22, x23, 0xffffffff), "eor x22, x23, #0xffffffff00000000"); + COMPARE(Eon(x22, x23, 0xffffffffffffffff), "mov x22, x23"); + + CLEANUP(); +} + + +TEST_(barriers) { + SET_UP_CLASS(MacroAssembler); + + // DMB + COMPARE(Dmb(FullSystem, BarrierAll), "dmb sy"); + COMPARE(Dmb(FullSystem, BarrierReads), "dmb ld"); + COMPARE(Dmb(FullSystem, BarrierWrites), "dmb st"); + + COMPARE(Dmb(InnerShareable, BarrierAll), "dmb ish"); + COMPARE(Dmb(InnerShareable, BarrierReads), "dmb ishld"); + COMPARE(Dmb(InnerShareable, BarrierWrites), "dmb ishst"); + + COMPARE(Dmb(NonShareable, BarrierAll), "dmb nsh"); + COMPARE(Dmb(NonShareable, BarrierReads), "dmb nshld"); + COMPARE(Dmb(NonShareable, BarrierWrites), "dmb nshst"); + + COMPARE(Dmb(OuterShareable, BarrierAll), "dmb osh"); + COMPARE(Dmb(OuterShareable, BarrierReads), "dmb oshld"); + COMPARE(Dmb(OuterShareable, BarrierWrites), "dmb oshst"); + + COMPARE(Dmb(FullSystem, BarrierOther), "dmb sy (0b1100)"); + COMPARE(Dmb(InnerShareable, BarrierOther), "dmb sy (0b1000)"); + COMPARE(Dmb(NonShareable, BarrierOther), "dmb sy (0b0100)"); + COMPARE(Dmb(OuterShareable, BarrierOther), "dmb sy (0b0000)"); + + // DSB + COMPARE(Dsb(FullSystem, BarrierAll), "dsb sy"); + COMPARE(Dsb(FullSystem, BarrierReads), "dsb ld"); + COMPARE(Dsb(FullSystem, BarrierWrites), "dsb st"); + + COMPARE(Dsb(InnerShareable, BarrierAll), "dsb ish"); + COMPARE(Dsb(InnerShareable, BarrierReads), "dsb ishld"); + COMPARE(Dsb(InnerShareable, BarrierWrites), "dsb ishst"); + + COMPARE(Dsb(NonShareable, BarrierAll), "dsb nsh"); + COMPARE(Dsb(NonShareable, BarrierReads), "dsb nshld"); + COMPARE(Dsb(NonShareable, BarrierWrites), "dsb nshst"); + + COMPARE(Dsb(OuterShareable, BarrierAll), "dsb osh"); + COMPARE(Dsb(OuterShareable, BarrierReads), "dsb oshld"); + COMPARE(Dsb(OuterShareable, BarrierWrites), "dsb oshst"); + + COMPARE(Dsb(FullSystem, BarrierOther), "dsb sy (0b1100)"); + COMPARE(Dsb(InnerShareable, BarrierOther), "dsb sy (0b1000)"); + COMPARE(Dsb(NonShareable, BarrierOther), "dsb sy (0b0100)"); + COMPARE(Dsb(OuterShareable, BarrierOther), "dsb sy (0b0000)"); + + // ISB + COMPARE(Isb(), "isb"); + + CLEANUP(); +} diff --git a/deps/v8/test/cctest/test-disasm-ia32.cc b/deps/v8/test/cctest/test-disasm-ia32.cc index 301545c6c4..f32a69c4a3 100644 --- a/deps/v8/test/cctest/test-disasm-ia32.cc +++ b/deps/v8/test/cctest/test-disasm-ia32.cc @@ -28,6 +28,7 @@ #include <stdlib.h> #include "v8.h" +#include "stub-cache.h" #include "debug.h" #include "disasm.h" @@ -254,7 +255,7 @@ TEST(DisasmIa320) { __ bind(&L2); __ call(Operand(ebx, ecx, times_4, 10000)); __ nop(); - Handle<Code> ic(isolate->builtins()->builtin(Builtins::kLoadIC_Initialize)); + Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL)); __ call(ic, RelocInfo::CODE_TARGET); __ nop(); __ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY); @@ -348,7 +349,37 @@ TEST(DisasmIa320) { __ fdivp(3); __ fcompp(); __ fwait(); + __ frndint(); + __ fninit(); __ nop(); + + // SSE instruction + { + if (CpuFeatures::IsSupported(SSE2)) { + CpuFeatureScope fscope(&assm, SSE2); + // Move operation + __ movaps(xmm0, xmm1); + __ shufps(xmm0, xmm0, 0x0); + + // logic operation + __ andps(xmm0, xmm1); + __ andps(xmm0, Operand(ebx, ecx, times_4, 10000)); + __ orps(xmm0, xmm1); + __ orps(xmm0, Operand(ebx, ecx, times_4, 10000)); + __ xorps(xmm0, xmm1); + __ xorps(xmm0, Operand(ebx, ecx, times_4, 10000)); + + // Arithmetic operation + __ addps(xmm1, xmm0); + __ addps(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ subps(xmm1, xmm0); + __ subps(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ mulps(xmm1, xmm0); + __ mulps(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ divps(xmm1, xmm0); + __ divps(xmm1, Operand(ebx, ecx, times_4, 10000)); + } + } { if (CpuFeatures::IsSupported(SSE2)) { CpuFeatureScope fscope(&assm, SSE2); @@ -356,7 +387,6 @@ TEST(DisasmIa320) { __ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000)); __ movsd(xmm1, Operand(ebx, ecx, times_4, 10000)); __ movsd(Operand(ebx, ecx, times_4, 10000), xmm1); - __ movaps(xmm0, xmm1); // 128 bit move instructions. __ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000)); __ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0); @@ -370,7 +400,6 @@ TEST(DisasmIa320) { __ ucomisd(xmm0, xmm1); __ cmpltsd(xmm0, xmm1); - __ andps(xmm0, xmm1); __ andpd(xmm0, xmm1); __ psllq(xmm0, 17); __ psllq(xmm0, xmm1); diff --git a/deps/v8/test/cctest/test-disasm-x64.cc b/deps/v8/test/cctest/test-disasm-x64.cc index 8fd036956f..9fce25fae4 100644 --- a/deps/v8/test/cctest/test-disasm-x64.cc +++ b/deps/v8/test/cctest/test-disasm-x64.cc @@ -90,11 +90,7 @@ TEST(DisasmX64) { __ or_(rdx, Immediate(3)); __ xor_(rdx, Immediate(3)); __ nop(); - { - CHECK(CpuFeatures::IsSupported(CPUID)); - CpuFeatures::Scope fscope(CPUID); - __ cpuid(); - } + __ cpuid(); __ movsxbq(rdx, Operand(rcx, 0)); __ movsxwq(rdx, Operand(rcx, 0)); __ movzxbl(rdx, Operand(rcx, 0)); @@ -334,15 +330,34 @@ TEST(DisasmX64) { __ fdivp(3); __ fcompp(); __ fwait(); + __ frndint(); + __ fninit(); __ nop(); // SSE instruction { + // Move operation __ cvttss2si(rdx, Operand(rbx, rcx, times_4, 10000)); __ cvttss2si(rdx, xmm1); __ movaps(xmm0, xmm1); + // logic operation __ andps(xmm0, xmm1); + __ andps(xmm0, Operand(rbx, rcx, times_4, 10000)); + __ orps(xmm0, xmm1); + __ ordps(xmm0, Operand(rbx, rcx, times_4, 10000)); + __ xorps(xmm0, xmm1); + __ xordps(xmm0, Operand(rbx, rcx, times_4, 10000)); + + // Arithmetic operation + __ addps(xmm1, xmm0); + __ addps(xmm1, Operand(rbx, rcx, times_4, 10000)); + __ subps(xmm1, xmm0); + __ subps(xmm1, Operand(rbx, rcx, times_4, 10000)); + __ mulps(xmm1, xmm0); + __ mulps(xmm1, Operand(rbx, ecx, times_4, 10000)); + __ divps(xmm1, xmm0); + __ divps(xmm1, Operand(rbx, rcx, times_4, 10000)); } // SSE 2 instructions { diff --git a/deps/v8/test/cctest/test-func-name-inference.cc b/deps/v8/test/cctest/test-func-name-inference.cc index 1a000afba2..d7c5083050 100644 --- a/deps/v8/test/cctest/test-func-name-inference.cc +++ b/deps/v8/test/cctest/test-func-name-inference.cc @@ -89,13 +89,13 @@ static void CheckFunctionName(v8::Handle<v8::Script> script, // Verify inferred function name. SmartArrayPointer<char> inferred_name = shared_func_info->inferred_name()->ToCString(); - CHECK_EQ(ref_inferred_name, *inferred_name); + CHECK_EQ(ref_inferred_name, inferred_name.get()); #endif // ENABLE_DEBUGGER_SUPPORT } -static v8::Handle<v8::Script> Compile(const char* src) { - return v8::Script::Compile(v8::String::New(src)); +static v8::Handle<v8::Script> Compile(v8::Isolate* isolate, const char* src) { + return v8::Script::Compile(v8::String::NewFromUtf8(isolate, src)); } @@ -104,6 +104,7 @@ TEST(GlobalProperty) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "fun1 = function() { return 1; }\n" "fun2 = function() { return 2; }\n"); CheckFunctionName(script, "return 1", "fun1"); @@ -116,6 +117,7 @@ TEST(GlobalVar) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "var fun1 = function() { return 1; }\n" "var fun2 = function() { return 2; }\n"); CheckFunctionName(script, "return 1", "fun1"); @@ -128,6 +130,7 @@ TEST(LocalVar) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function outer() {\n" " var fun1 = function() { return 1; }\n" " var fun2 = function() { return 2; }\n" @@ -142,6 +145,7 @@ TEST(InConstructor) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function MyClass() {\n" " this.method1 = function() { return 1; }\n" " this.method2 = function() { return 2; }\n" @@ -156,6 +160,7 @@ TEST(Factory) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function createMyObj() {\n" " var obj = {};\n" " obj.method1 = function() { return 1; }\n" @@ -172,6 +177,7 @@ TEST(Static) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function MyClass() {}\n" "MyClass.static1 = function() { return 1; }\n" "MyClass.static2 = function() { return 2; }\n" @@ -190,6 +196,7 @@ TEST(Prototype) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function MyClass() {}\n" "MyClass.prototype.method1 = function() { return 1; }\n" "MyClass.prototype.method2 = function() { return 2; }\n" @@ -208,6 +215,7 @@ TEST(ObjectLiteral) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function MyClass() {}\n" "MyClass.prototype = {\n" " method1: function() { return 1; },\n" @@ -222,6 +230,7 @@ TEST(AsParameter) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function f1(a) { return a(); }\n" "function f2(a, b) { return a() + b(); }\n" "var result1 = f1(function() { return 1; })\n" @@ -238,6 +247,7 @@ TEST(MultipleFuncsConditional) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "fun1 = 0 ?\n" " function() { return 1; } :\n" " function() { return 2; }"); @@ -251,6 +261,7 @@ TEST(MultipleFuncsInLiteral) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function MyClass() {}\n" "MyClass.prototype = {\n" " method1: 0 ? function() { return 1; } :\n" @@ -265,6 +276,7 @@ TEST(AnonymousInAnonymousClosure1) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "(function() {\n" " (function() {\n" " var a = 1;\n" @@ -284,6 +296,7 @@ TEST(AnonymousInAnonymousClosure2) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "(function() {\n" " (function() {\n" " var a = 1;\n" @@ -300,6 +313,7 @@ TEST(NamedInAnonymousClosure) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "var foo = function() {\n" " (function named() {\n" " var a = 1;\n" @@ -317,6 +331,7 @@ TEST(Issue380) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function a() {\n" "var result = function(p,a,c,k,e,d)" "{return p}(\"if blah blah\",62,1976,\'a|b\'.split(\'|\'),0,{})\n" @@ -330,6 +345,7 @@ TEST(MultipleAssignments) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "var fun1 = fun2 = function () { return 1; }\n" "var bar1 = bar2 = bar3 = function () { return 2; }\n" "foo1 = foo2 = function () { return 3; }\n" @@ -346,6 +362,7 @@ TEST(AsConstructorParameter) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function Foo() {}\n" "var foo = new Foo(function() { return 1; })\n" "var bar = new Foo(function() { return 2; }, function() { return 3; })"); @@ -360,6 +377,7 @@ TEST(FactoryHashmap) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function createMyObj() {\n" " var obj = {};\n" " obj[\"method1\"] = function() { return 1; }\n" @@ -376,6 +394,7 @@ TEST(FactoryHashmapVariable) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function createMyObj() {\n" " var obj = {};\n" " var methodName = \"method1\";\n" @@ -395,6 +414,7 @@ TEST(FactoryHashmapConditional) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "function createMyObj() {\n" " var obj = {};\n" " obj[0 ? \"method1\" : \"method2\"] = function() { return 1; }\n" @@ -410,6 +430,7 @@ TEST(GlobalAssignmentAndCall) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "var Foo = function() {\n" " return 1;\n" "}();\n" @@ -428,6 +449,7 @@ TEST(AssignmentAndCall) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "(function Enclosing() {\n" " var Foo;\n" " Foo = function() {\n" @@ -451,6 +473,7 @@ TEST(MethodAssignmentInAnonymousFunctionCall) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "(function () {\n" " var EventSource = function () { };\n" " EventSource.prototype.addListener = function () {\n" @@ -467,6 +490,7 @@ TEST(ReturnAnonymousFunction) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::Script> script = Compile( + CcTest::isolate(), "(function() {\n" " function wrapCode() {\n" " return function () {\n" diff --git a/deps/v8/test/cctest/test-fuzz-a64.cc b/deps/v8/test/cctest/test-fuzz-a64.cc new file mode 100644 index 0000000000..3f091d7586 --- /dev/null +++ b/deps/v8/test/cctest/test-fuzz-a64.cc @@ -0,0 +1,70 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of ARM Limited nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <stdlib.h> +#include "cctest.h" + +#include "a64/decoder-a64.h" +#include "a64/disasm-a64.h" + +using namespace v8::internal; + +TEST(FUZZ_decoder) { + // Feed noise into the decoder to check that it doesn't crash. + // 43 million = ~1% of the instruction space. + static const int instruction_count = 43 * 1024 * 1024; + + uint16_t seed[3] = {1, 2, 3}; + seed48(seed); + + Decoder decoder; + Instruction buffer[kInstructionSize]; + + for (int i = 0; i < instruction_count; i++) { + uint32_t instr = mrand48(); + buffer->SetInstructionBits(instr); + decoder.Decode(buffer); + } +} + + +TEST(FUZZ_disasm) { + // Feed noise into the disassembler to check that it doesn't crash. + // 9 million = ~0.2% of the instruction space. + static const int instruction_count = 9 * 1024 * 1024; + + uint16_t seed[3] = {42, 43, 44}; + seed48(seed); + + Decoder decoder; + Disassembler disasm; + Instruction buffer[kInstructionSize]; + + decoder.AppendVisitor(&disasm); + for (int i = 0; i < instruction_count; i++) { + uint32_t instr = mrand48(); + buffer->SetInstructionBits(instr); + decoder.Decode(buffer); + } +} diff --git a/deps/v8/test/cctest/test-global-handles.cc b/deps/v8/test/cctest/test-global-handles.cc index d0b80d1c8f..48b6655bbc 100644 --- a/deps/v8/test/cctest/test-global-handles.cc +++ b/deps/v8/test/cctest/test-global-handles.cc @@ -316,6 +316,8 @@ TEST(ImplicitReferences) { reinterpret_cast<HeapObject**>(g2s1.location())); ASSERT(implicit_refs->at(1)->length == 1); ASSERT(implicit_refs->at(1)->children[0] == g2c1.location()); + global_handles->RemoveObjectGroups(); + global_handles->RemoveImplicitRefGroups(); } @@ -334,8 +336,8 @@ TEST(EternalHandles) { for (int i = 0; i < kArrayLength; i++) { indices[i] = -1; HandleScope scope(isolate); - v8::Local<v8::Object> object = v8::Object::New(); - object->Set(i, v8::Integer::New(i, v8_isolate)); + v8::Local<v8::Object> object = v8::Object::New(v8_isolate); + object->Set(i, v8::Integer::New(v8_isolate, i)); // Create with internal api eternal_handles->Create( isolate, *v8::Utils::OpenHandle(*object), &indices[i]); @@ -370,7 +372,7 @@ TEST(EternalHandles) { // Create an eternal via the constructor { HandleScope scope(isolate); - v8::Local<v8::Object> object = v8::Object::New(); + v8::Local<v8::Object> object = v8::Object::New(v8_isolate); v8::Eternal<v8::Object> eternal(v8_isolate, object); CHECK(!eternal.IsEmpty()); CHECK(object == eternal.Get(v8_isolate)); diff --git a/deps/v8/test/cctest/test-global-object.cc b/deps/v8/test/cctest/test-global-object.cc index 5fe77c2adf..bbec9df775 100644 --- a/deps/v8/test/cctest/test-global-object.cc +++ b/deps/v8/test/cctest/test-global-object.cc @@ -39,7 +39,7 @@ TEST(StrictUndeclaredGlobalVariable) { LocalContext context; v8::TryCatch try_catch; v8::Local<v8::Script> script = v8_compile("\"use strict\"; x = 42;"); - v8::Handle<v8::Object> proto = v8::Object::New(); + v8::Handle<v8::Object> proto = v8::Object::New(CcTest::isolate()); v8::Handle<v8::Object> global = context->Global()->GetPrototype().As<v8::Object>(); proto->Set(var_name, v8_num(100)); diff --git a/deps/v8/test/cctest/test-hashing.cc b/deps/v8/test/cctest/test-hashing.cc index 3ec844e9c7..a29d3d16cb 100644 --- a/deps/v8/test/cctest/test-hashing.cc +++ b/deps/v8/test/cctest/test-hashing.cc @@ -96,6 +96,24 @@ void generate(MacroAssembler* masm, i::Vector<const uint8_t> string) { StringHelper::GenerateHashGetHash(masm, r0); __ pop(kRootRegister); __ mov(pc, Operand(lr)); +#elif V8_TARGET_ARCH_A64 + // The A64 assembler usually uses jssp (x28) as a stack pointer, but only csp + // is initialized by the calling (C++) code. + Register old_stack_pointer = __ StackPointer(); + __ SetStackPointer(csp); + __ Push(root, xzr); + __ InitializeRootRegister(); + __ Mov(x0, 0); + __ Mov(x10, Operand(string.at(0))); + StringHelper::GenerateHashInit(masm, x0, x10); + for (int i = 1; i < string.length(); i++) { + __ Mov(x10, Operand(string.at(i))); + StringHelper::GenerateHashAddCharacter(masm, x0, x10); + } + StringHelper::GenerateHashGetHash(masm, x0, x10); + __ Pop(xzr, root); + __ Ret(); + __ SetStackPointer(old_stack_pointer); #elif V8_TARGET_ARCH_MIPS __ push(kRootRegister); __ InitializeRootRegister(); @@ -111,6 +129,8 @@ void generate(MacroAssembler* masm, i::Vector<const uint8_t> string) { __ pop(kRootRegister); __ jr(ra); __ nop(); +#else +#error Unsupported architecture. #endif } @@ -138,6 +158,18 @@ void generate(MacroAssembler* masm, uint32_t key) { __ GetNumberHash(r0, ip); __ pop(kRootRegister); __ mov(pc, Operand(lr)); +#elif V8_TARGET_ARCH_A64 + // The A64 assembler usually uses jssp (x28) as a stack pointer, but only csp + // is initialized by the calling (C++) code. + Register old_stack_pointer = __ StackPointer(); + __ SetStackPointer(csp); + __ Push(root, xzr); + __ InitializeRootRegister(); + __ Mov(x0, key); + __ GetNumberHash(x0, x10); + __ Pop(xzr, root); + __ Ret(); + __ SetStackPointer(old_stack_pointer); #elif V8_TARGET_ARCH_MIPS __ push(kRootRegister); __ InitializeRootRegister(); @@ -146,6 +178,8 @@ void generate(MacroAssembler* masm, uint32_t key) { __ pop(kRootRegister); __ jr(ra); __ nop(); +#else +#error Unsupported architecture. #endif } @@ -172,8 +206,8 @@ void check(i::Vector<const uint8_t> string) { Handle<String> v8_string = factory->NewStringFromOneByte(string); v8_string->set_hash_field(String::kEmptyHashField); #ifdef USE_SIMULATOR - uint32_t codegen_hash = - reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(hash, 0, 0, 0, 0, 0)); + uint32_t codegen_hash = static_cast<uint32_t>( + reinterpret_cast<uintptr_t>(CALL_GENERATED_CODE(hash, 0, 0, 0, 0, 0))); #else uint32_t codegen_hash = hash(); #endif @@ -207,8 +241,8 @@ void check(uint32_t key) { HASH_FUNCTION hash = FUNCTION_CAST<HASH_FUNCTION>(code->entry()); #ifdef USE_SIMULATOR - uint32_t codegen_hash = - reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(hash, 0, 0, 0, 0, 0)); + uint32_t codegen_hash = static_cast<uint32_t>( + reinterpret_cast<uintptr_t>(CALL_GENERATED_CODE(hash, 0, 0, 0, 0, 0))); #else uint32_t codegen_hash = hash(); #endif diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index db2243a3f0..c04ed9de13 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -234,9 +234,9 @@ TEST(HeapSnapshotObjectSizes) { CHECK_NE(NULL, x2); // Test sizes. - CHECK_NE(0, x->GetSelfSize()); - CHECK_NE(0, x1->GetSelfSize()); - CHECK_NE(0, x2->GetSelfSize()); + CHECK_NE(0, static_cast<int>(x->GetShallowSize())); + CHECK_NE(0, static_cast<int>(x1->GetShallowSize())); + CHECK_NE(0, static_cast<int>(x2->GetShallowSize())); } @@ -255,7 +255,8 @@ TEST(BoundFunctionInSnapshot) { const v8::HeapGraphNode* f = GetProperty(global, v8::HeapGraphEdge::kProperty, "boundFunction"); CHECK(f); - CHECK_EQ(v8::String::New("native_bind"), f->GetName()); + CHECK_EQ(v8::String::NewFromUtf8(env->GetIsolate(), "native_bind"), + f->GetName()); const v8::HeapGraphNode* bindings = GetProperty(f, v8::HeapGraphEdge::kInternal, "bindings"); CHECK_NE(NULL, bindings); @@ -343,6 +344,15 @@ TEST(HeapSnapshotCodeObjects) { GetProperty(lazy, v8::HeapGraphEdge::kInternal, "shared"); CHECK_NE(NULL, lazy_code); + // Check that there's no strong next_code_link. There might be a weak one + // but might be not, so we can't check that fact. + const v8::HeapGraphNode* code = + GetProperty(compiled_code, v8::HeapGraphEdge::kInternal, "code"); + CHECK_NE(NULL, code); + const v8::HeapGraphNode* next_code_link = + GetProperty(code, v8::HeapGraphEdge::kInternal, "code"); + CHECK_EQ(NULL, next_code_link); + // Verify that non-compiled code doesn't contain references to "x" // literal, while compiled code does. The scope info is stored in FixedArray // objects attached to the SharedFunctionInfo. @@ -422,7 +432,8 @@ TEST(HeapSnapshotSlicedString) { TEST(HeapSnapshotConsString) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Local<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); global_template->SetInternalFieldCount(1); LocalContext env(NULL, global_template); v8::Handle<v8::Object> global_proxy = env->Global(); @@ -465,13 +476,14 @@ TEST(HeapSnapshotConsString) { TEST(HeapSnapshotInternalReferences) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Local<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); global_template->SetInternalFieldCount(2); LocalContext env(NULL, global_template); v8::Handle<v8::Object> global_proxy = env->Global(); v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); CHECK_EQ(2, global->InternalFieldCount()); - v8::Local<v8::Object> obj = v8::Object::New(); + v8::Local<v8::Object> obj = v8::Object::New(isolate); global->SetInternalField(0, v8_num(17)); global->SetInternalField(1, obj); v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); @@ -734,8 +746,9 @@ TEST(HeapSnapshotJSONSerialization) { stream.WriteTo(json); // Verify that snapshot string is valid JSON. - AsciiResource json_res(json); - v8::Local<v8::String> json_string = v8::String::NewExternal(&json_res); + AsciiResource* json_res = new AsciiResource(json); + v8::Local<v8::String> json_string = + v8::String::NewExternal(env->GetIsolate(), json_res); env->Global()->Set(v8_str("json_snapshot"), json_string); v8::Local<v8::Value> snapshot_parse_result = CompileRun( "var parsed = JSON.parse(json_snapshot); true;"); @@ -1003,7 +1016,7 @@ TEST(HeapSnapshotObjectsStats) { CHECK_EQ(2, stats_update.first_interval_index()); } - v8::Local<v8::Array> array = v8::Array::New(); + v8::Local<v8::Array> array = v8::Array::New(env->GetIsolate()); CHECK_EQ(0, array->Length()); // Force array's buffer allocation. array->Set(2, v8_num(7)); @@ -1039,6 +1052,49 @@ TEST(HeapSnapshotObjectsStats) { } +TEST(HeapObjectIds) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); + + const int kLength = 10; + v8::Handle<v8::Object> objects[kLength]; + v8::SnapshotObjectId ids[kLength]; + + heap_profiler->StartTrackingHeapObjects(false); + + for (int i = 0; i < kLength; i++) { + objects[i] = v8::Object::New(isolate); + } + GetHeapStatsUpdate(heap_profiler); + + for (int i = 0; i < kLength; i++) { + v8::SnapshotObjectId id = heap_profiler->GetObjectId(objects[i]); + CHECK_NE(v8::HeapProfiler::kUnknownObjectId, static_cast<int>(id)); + ids[i] = id; + } + + heap_profiler->StopTrackingHeapObjects(); + CcTest::heap()->CollectAllAvailableGarbage(); + + for (int i = 0; i < kLength; i++) { + v8::SnapshotObjectId id = heap_profiler->GetObjectId(objects[i]); + CHECK_EQ(static_cast<int>(ids[i]), static_cast<int>(id)); + v8::Handle<v8::Value> obj = heap_profiler->FindObjectById(ids[i]); + CHECK_EQ(objects[i], obj); + } + + heap_profiler->ClearObjectIds(); + for (int i = 0; i < kLength; i++) { + v8::SnapshotObjectId id = heap_profiler->GetObjectId(objects[i]); + CHECK_EQ(v8::HeapProfiler::kUnknownObjectId, static_cast<int>(id)); + v8::Handle<v8::Value> obj = heap_profiler->FindObjectById(ids[i]); + CHECK(obj.IsEmpty()); + } +} + + static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, const v8::HeapGraphNode* node, int level, int max_level) { @@ -1083,8 +1139,8 @@ TEST(HeapSnapshotGetSnapshotObjectId) { GetProperty(global, v8::HeapGraphEdge::kProperty, "globalObject"); CHECK(global_object); - v8::Local<v8::Value> globalObjectHandle = - env->Global()->Get(v8::String::New("globalObject")); + v8::Local<v8::Value> globalObjectHandle = env->Global()->Get( + v8::String::NewFromUtf8(env->GetIsolate(), "globalObject")); CHECK(!globalObjectHandle.IsEmpty()); CHECK(globalObjectHandle->IsObject()); @@ -1309,7 +1365,7 @@ class GraphWithImplicitRefs { instance_ = this; isolate_ = (*env)->GetIsolate(); for (int i = 0; i < kObjectsCount; i++) { - objects_[i].Reset(isolate_, v8::Object::New()); + objects_[i].Reset(isolate_, v8::Object::New(isolate_)); } (*env)->Global()->Set(v8_str("root_object"), v8::Local<v8::Value>::New(isolate_, objects_[0])); @@ -1481,6 +1537,30 @@ TEST(GlobalObjectName) { } +TEST(GlobalObjectFields) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); + CompileRun("obj = {};"); + const v8::HeapSnapshot* snapshot = + heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); + CHECK(ValidateSnapshot(snapshot)); + const v8::HeapGraphNode* global = GetGlobalObject(snapshot); + const v8::HeapGraphNode* builtins = + GetProperty(global, v8::HeapGraphEdge::kInternal, "builtins"); + CHECK_NE(NULL, builtins); + const v8::HeapGraphNode* native_context = + GetProperty(global, v8::HeapGraphEdge::kInternal, "native_context"); + CHECK_NE(NULL, native_context); + const v8::HeapGraphNode* global_context = + GetProperty(global, v8::HeapGraphEdge::kInternal, "global_context"); + CHECK_NE(NULL, global_context); + const v8::HeapGraphNode* global_receiver = + GetProperty(global, v8::HeapGraphEdge::kInternal, "global_receiver"); + CHECK_NE(NULL, global_receiver); +} + + TEST(NoHandleLeaks) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -1517,7 +1597,7 @@ TEST(NodesIteration) { } -TEST(GetHeapValue) { +TEST(GetHeapValueForNode) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); @@ -1527,25 +1607,26 @@ TEST(GetHeapValue) { heap_profiler->TakeHeapSnapshot(v8_str("value")); CHECK(ValidateSnapshot(snapshot)); const v8::HeapGraphNode* global = GetGlobalObject(snapshot); - CHECK(global->GetHeapValue()->IsObject()); + CHECK(heap_profiler->FindObjectById(global->GetId())->IsObject()); v8::Local<v8::Object> js_global = env->Global()->GetPrototype().As<v8::Object>(); - CHECK(js_global == global->GetHeapValue()); + CHECK(js_global == heap_profiler->FindObjectById(global->GetId())); const v8::HeapGraphNode* obj = GetProperty( global, v8::HeapGraphEdge::kProperty, "a"); - CHECK(obj->GetHeapValue()->IsObject()); + CHECK(heap_profiler->FindObjectById(obj->GetId())->IsObject()); v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); - CHECK(js_obj == obj->GetHeapValue()); + CHECK(js_obj == heap_profiler->FindObjectById(obj->GetId())); const v8::HeapGraphNode* s_prop = GetProperty(obj, v8::HeapGraphEdge::kProperty, "s_prop"); v8::Local<v8::String> js_s_prop = js_obj->Get(v8_str("s_prop")).As<v8::String>(); - CHECK(js_s_prop == s_prop->GetHeapValue()); + CHECK(js_s_prop == heap_profiler->FindObjectById(s_prop->GetId())); const v8::HeapGraphNode* n_prop = GetProperty(obj, v8::HeapGraphEdge::kProperty, "n_prop"); v8::Local<v8::Number> js_n_prop = js_obj->Get(v8_str("n_prop")).As<v8::Number>(); - CHECK(js_n_prop->NumberValue() == n_prop->GetHeapValue()->NumberValue()); + CHECK(js_n_prop->NumberValue() == + heap_profiler->FindObjectById(n_prop->GetId())->NumberValue()); } @@ -1570,18 +1651,18 @@ TEST(GetHeapValueForDeletedObject) { // Perform the check inside a nested local scope to avoid creating a // reference to the object we are deleting. v8::HandleScope scope(env->GetIsolate()); - CHECK(prop->GetHeapValue()->IsObject()); + CHECK(heap_profiler->FindObjectById(prop->GetId())->IsObject()); } CompileRun("delete a.p;"); - CHECK(prop->GetHeapValue()->IsUndefined()); + CHECK(heap_profiler->FindObjectById(prop->GetId()).IsEmpty()); } static int StringCmp(const char* ref, i::String* act) { i::SmartArrayPointer<char> s_act = act->ToCString(); - int result = strcmp(ref, *s_act); + int result = strcmp(ref, s_act.get()); if (result != 0) - fprintf(stderr, "Expected: \"%s\", Actual: \"%s\"\n", ref, *s_act); + fprintf(stderr, "Expected: \"%s\", Actual: \"%s\"\n", ref, s_act.get()); return result; } @@ -1719,7 +1800,8 @@ TEST(HiddenPropertiesFastCase) { GetProperty(c, v8::HeapGraphEdge::kInternal, "hidden_properties"); CHECK_EQ(NULL, hidden_props); - v8::Handle<v8::Value> cHandle = env->Global()->Get(v8::String::New("c")); + v8::Handle<v8::Value> cHandle = + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "c")); CHECK(!cHandle.IsEmpty() && cHandle->IsObject()); cHandle->ToObject()->SetHiddenValue(v8_str("key"), v8_str("val")); @@ -1760,10 +1842,10 @@ bool HasWeakGlobalHandle() { } -static void PersistentHandleCallback(v8::Isolate* isolate, - v8::Persistent<v8::Value>* handle, - void*) { - handle->Dispose(); +static void PersistentHandleCallback( + const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) { + data.GetParameter()->Reset(); + delete data.GetParameter(); } @@ -1773,8 +1855,9 @@ TEST(WeakGlobalHandle) { CHECK(!HasWeakGlobalHandle()); - v8::Persistent<v8::Object> handle(env->GetIsolate(), v8::Object::New()); - handle.MakeWeak<v8::Value, void>(NULL, PersistentHandleCallback); + v8::Persistent<v8::Object> handle(env->GetIsolate(), + v8::Object::New(env->GetIsolate())); + handle.SetWeak(&handle, PersistentHandleCallback); CHECK(HasWeakGlobalHandle()); } @@ -1934,8 +2017,8 @@ TEST(ManyLocalsInSharedContext) { CHECK_EQ(v8::internal::Context::MIN_CONTEXT_SLOTS + num_objects - 1, context_object->GetChildrenCount()); // Check all the objects have got their names. - // ... well check just every 8th because otherwise it's too slow in debug. - for (int i = 0; i < num_objects - 1; i += 8) { + // ... well check just every 15th because otherwise it's too slow in debug. + for (int i = 0; i < num_objects - 1; i += 15) { i::EmbeddedVector<char, 100> var_name; i::OS::SNPrintF(var_name, "f_%d", i); const v8::HeapGraphNode* f_object = GetProperty( @@ -1947,8 +2030,9 @@ TEST(ManyLocalsInSharedContext) { TEST(AllocationSitesAreVisible) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); CompileRun( "fun = function () { var a = [3, 2, 1]; return a; }\n" "fun();"); @@ -1983,16 +2067,21 @@ TEST(AllocationSitesAreVisible) { "elements"); CHECK_NE(NULL, elements); CHECK_EQ(v8::HeapGraphNode::kArray, elements->GetType()); - CHECK_EQ(v8::internal::FixedArray::SizeFor(3), elements->GetSelfSize()); + CHECK_EQ(v8::internal::FixedArray::SizeFor(3), + static_cast<int>(elements->GetShallowSize())); - CHECK(transition_info->GetHeapValue()->IsArray()); - v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast( - transition_info->GetHeapValue()); + v8::Handle<v8::Value> array_val = + heap_profiler->FindObjectById(transition_info->GetId()); + CHECK(array_val->IsArray()); + v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(array_val); // Verify the array is "a" in the code above. CHECK_EQ(3, array->Length()); - CHECK_EQ(v8::Integer::New(3), array->Get(v8::Integer::New(0))); - CHECK_EQ(v8::Integer::New(2), array->Get(v8::Integer::New(1))); - CHECK_EQ(v8::Integer::New(1), array->Get(v8::Integer::New(2))); + CHECK_EQ(v8::Integer::New(isolate, 3), + array->Get(v8::Integer::New(isolate, 0))); + CHECK_EQ(v8::Integer::New(isolate, 2), + array->Get(v8::Integer::New(isolate, 1))); + CHECK_EQ(v8::Integer::New(isolate, 1), + array->Get(v8::Integer::New(isolate, 2))); } @@ -2014,70 +2103,66 @@ TEST(JSFunctionHasCodeLink) { } - -class HeapProfilerExtension : public v8::Extension { - public: - static const char* kName; - HeapProfilerExtension() : v8::Extension(kName, kSource) { } - virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( - v8::Handle<v8::String> name); - static void FindUntrackedObjects( - const v8::FunctionCallbackInfo<v8::Value>& args); - private: - static const char* kSource; -}; - -const char* HeapProfilerExtension::kName = "v8/heap-profiler"; - - -const char* HeapProfilerExtension::kSource = - "native function findUntrackedObjects();"; - - -v8::Handle<v8::FunctionTemplate> HeapProfilerExtension::GetNativeFunction( - v8::Handle<v8::String> name) { - if (name->Equals(v8::String::New("findUntrackedObjects"))) { - return v8::FunctionTemplate::New( - HeapProfilerExtension::FindUntrackedObjects); - } else { - CHECK(false); - return v8::Handle<v8::FunctionTemplate>(); +static const v8::HeapGraphNode* GetNodeByPath(const v8::HeapSnapshot* snapshot, + const char* path[], + int depth) { + const v8::HeapGraphNode* node = snapshot->GetRoot(); + for (int current_depth = 0; current_depth < depth; ++current_depth) { + int i, count = node->GetChildrenCount(); + for (i = 0; i < count; ++i) { + const v8::HeapGraphEdge* edge = node->GetChild(i); + const v8::HeapGraphNode* to_node = edge->GetToNode(); + v8::String::Utf8Value edge_name(edge->GetName()); + v8::String::Utf8Value node_name(to_node->GetName()); + i::EmbeddedVector<char, 100> name; + i::OS::SNPrintF(name, "%s::%s", *edge_name, *node_name); + if (strstr(name.start(), path[current_depth])) { + node = to_node; + break; + } + } + if (i == count) return NULL; } + return node; } -void HeapProfilerExtension::FindUntrackedObjects( - const v8::FunctionCallbackInfo<v8::Value>& args) { - i::HeapProfiler* heap_profiler = - reinterpret_cast<i::HeapProfiler*>(args.GetIsolate()->GetHeapProfiler()); - int untracked_objects = heap_profiler->FindUntrackedObjects(); - args.GetReturnValue().Set(untracked_objects); - CHECK_EQ(0, untracked_objects); -} - +TEST(CheckCodeNames) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); + CompileRun("var a = 1.1;"); + const v8::HeapSnapshot* snapshot = + heap_profiler->TakeHeapSnapshot(v8_str("CheckCodeNames")); + CHECK(ValidateSnapshot(snapshot)); -static HeapProfilerExtension kHeapProfilerExtension; -v8::DeclareExtension kHeapProfilerExtensionDeclaration( - &kHeapProfilerExtension); + const char* stub_path[] = { + "::(GC roots)", + "::(Strong roots)", + "code_stubs::", + "::(ArraySingleArgumentConstructorStub code)" + }; + const v8::HeapGraphNode* node = GetNodeByPath(snapshot, + stub_path, ARRAY_SIZE(stub_path)); + CHECK_NE(NULL, node); + const char* builtin_path1[] = { + "::(GC roots)", + "::(Builtins)", + "::(KeyedLoadIC_Generic builtin)" + }; + node = GetNodeByPath(snapshot, builtin_path1, ARRAY_SIZE(builtin_path1)); + CHECK_NE(NULL, node); -// This is an example of using checking of JS allocations tracking in a test. -TEST(HeapObjectsTracker) { - const char* extensions[] = { HeapProfilerExtension::kName }; - v8::ExtensionConfiguration config(1, extensions); - LocalContext env(&config); - v8::HandleScope scope(env->GetIsolate()); - HeapObjectsTracker tracker; - CompileRun("var a = 1.2"); - CompileRun("var a = 1.2; var b = 1.0; var c = 1.0;"); - CompileRun( - "var a = [];\n" - "for (var i = 0; i < 5; ++i)\n" - " a[i] = i;\n" - "findUntrackedObjects();\n" - "for (var i = 0; i < 3; ++i)\n" - " a.shift();\n" - "findUntrackedObjects();\n"); + const char* builtin_path2[] = { + "::(GC roots)", + "::(Builtins)", + "::(CompileUnoptimized builtin)" + }; + node = GetNodeByPath(snapshot, builtin_path2, ARRAY_SIZE(builtin_path2)); + CHECK_NE(NULL, node); + v8::String::Utf8Value node_name(node->GetName()); + CHECK_EQ("(CompileUnoptimized builtin)", *node_name); } @@ -2123,12 +2208,6 @@ static const char* record_trace_tree_source = "for (var i = 0; i < 100; i++) start();\n"; -static i::HeapSnapshot* ToInternal(const v8::HeapSnapshot* snapshot) { - return const_cast<i::HeapSnapshot*>( - reinterpret_cast<const i::HeapSnapshot*>(snapshot)); -} - - static AllocationTraceNode* FindNode( AllocationTracker* tracker, const Vector<const char*>& names) { AllocationTraceNode* node = tracker->trace_tree()->root(); @@ -2149,19 +2228,48 @@ static AllocationTraceNode* FindNode( } +TEST(ArrayGrowLeftTrim) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); + heap_profiler->StartTrackingHeapObjects(true); + + CompileRun( + "var a = [];\n" + "for (var i = 0; i < 5; ++i)\n" + " a[i] = i;\n" + "for (var i = 0; i < 3; ++i)\n" + " a.shift();\n"); + + const char* names[] = { "(anonymous function)" }; + AllocationTracker* tracker = + reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker(); + CHECK_NE(NULL, tracker); + // Resolve all function locations. + tracker->PrepareForSerialization(); + // Print for better diagnostics in case of failure. + tracker->trace_tree()->Print(tracker); + + AllocationTraceNode* node = + FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names))); + CHECK_NE(NULL, node); + CHECK_GE(node->allocation_count(), 2); + CHECK_GE(node->allocation_size(), 4 * 5); + heap_profiler->StopTrackingHeapObjects(); +} + + TEST(TrackHeapAllocations) { v8::HandleScope scope(v8::Isolate::GetCurrent()); LocalContext env; v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); - heap_profiler->StartRecordingHeapAllocations(); + heap_profiler->StartTrackingHeapObjects(true); CompileRun(record_trace_tree_source); - const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot( - v8::String::New("Test")); - i::HeapSnapshotsCollection* collection = ToInternal(snapshot)->collection(); - AllocationTracker* tracker = collection->allocation_tracker(); + AllocationTracker* tracker = + reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker(); CHECK_NE(NULL, tracker); // Resolve all function locations. tracker->PrepareForSerialization(); @@ -2175,5 +2283,197 @@ TEST(TrackHeapAllocations) { CHECK_NE(NULL, node); CHECK_GE(node->allocation_count(), 100); CHECK_GE(node->allocation_size(), 4 * node->allocation_count()); - heap_profiler->StopRecordingHeapAllocations(); + heap_profiler->StopTrackingHeapObjects(); +} + + +static const char* inline_heap_allocation_source = +"function f_0(x) {\n" +" return f_1(x+1);\n" +"}\n" +"%NeverOptimizeFunction(f_0);\n" +"function f_1(x) {\n" +" return new f_2(x+1);\n" +"}\n" +"function f_2(x) {\n" +" this.foo = x;\n" +"}\n" +"var instances = [];\n" +"function start() {\n" +" instances.push(f_0(0));\n" +"}\n" +"\n" +"for (var i = 0; i < 100; i++) start();\n"; + + +TEST(TrackBumpPointerAllocations) { + i::FLAG_allow_natives_syntax = true; + v8::HandleScope scope(v8::Isolate::GetCurrent()); + LocalContext env; + + v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); + const char* names[] = { "(anonymous function)", "start", "f_0", "f_1" }; + // First check that normally all allocations are recorded. + { + heap_profiler->StartTrackingHeapObjects(true); + + CompileRun(inline_heap_allocation_source); + + AllocationTracker* tracker = + reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker(); + CHECK_NE(NULL, tracker); + // Resolve all function locations. + tracker->PrepareForSerialization(); + // Print for better diagnostics in case of failure. + tracker->trace_tree()->Print(tracker); + + AllocationTraceNode* node = + FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names))); + CHECK_NE(NULL, node); + CHECK_GE(node->allocation_count(), 100); + CHECK_GE(node->allocation_size(), 4 * node->allocation_count()); + heap_profiler->StopTrackingHeapObjects(); + } + + { + heap_profiler->StartTrackingHeapObjects(true); + + // Now check that not all allocations are tracked if we manually reenable + // inline allocations. + CHECK(CcTest::heap()->inline_allocation_disabled()); + CcTest::heap()->EnableInlineAllocation(); + + CompileRun(inline_heap_allocation_source); + + AllocationTracker* tracker = + reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker(); + CHECK_NE(NULL, tracker); + // Resolve all function locations. + tracker->PrepareForSerialization(); + // Print for better diagnostics in case of failure. + tracker->trace_tree()->Print(tracker); + + AllocationTraceNode* node = + FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names))); + CHECK_NE(NULL, node); + CHECK_LT(node->allocation_count(), 100); + + CcTest::heap()->DisableInlineAllocation(); + heap_profiler->StopTrackingHeapObjects(); + } +} + + +TEST(ArrayBufferAndArrayBufferView) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); + CompileRun("arr1 = new Uint32Array(100);\n"); + const v8::HeapSnapshot* snapshot = + heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); + CHECK(ValidateSnapshot(snapshot)); + const v8::HeapGraphNode* global = GetGlobalObject(snapshot); + const v8::HeapGraphNode* arr1_obj = + GetProperty(global, v8::HeapGraphEdge::kProperty, "arr1"); + CHECK_NE(NULL, arr1_obj); + const v8::HeapGraphNode* arr1_buffer = + GetProperty(arr1_obj, v8::HeapGraphEdge::kInternal, "buffer"); + CHECK_NE(NULL, arr1_buffer); + const v8::HeapGraphNode* first_view = + GetProperty(arr1_buffer, v8::HeapGraphEdge::kWeak, "weak_first_view"); + CHECK_NE(NULL, first_view); + const v8::HeapGraphNode* backing_store = + GetProperty(arr1_buffer, v8::HeapGraphEdge::kInternal, "backing_store"); + CHECK_NE(NULL, backing_store); + CHECK_EQ(400, static_cast<int>(backing_store->GetShallowSize())); +} + + +static int GetRetainersCount(const v8::HeapSnapshot* snapshot, + const v8::HeapGraphNode* node) { + int count = 0; + for (int i = 0, l = snapshot->GetNodesCount(); i < l; ++i) { + const v8::HeapGraphNode* parent = snapshot->GetNode(i); + for (int j = 0, l2 = parent->GetChildrenCount(); j < l2; ++j) { + if (parent->GetChild(j)->GetToNode() == node) { + ++count; + } + } + } + return count; +} + + +TEST(ArrayBufferSharedBackingStore) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope handle_scope(isolate); + v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); + + v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 1024); + CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); + CHECK(!ab->IsExternal()); + v8::ArrayBuffer::Contents ab_contents = ab->Externalize(); + CHECK(ab->IsExternal()); + + CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); + void* data = ab_contents.Data(); + ASSERT(data != NULL); + v8::Local<v8::ArrayBuffer> ab2 = + v8::ArrayBuffer::New(isolate, data, ab_contents.ByteLength()); + CHECK(ab2->IsExternal()); + env->Global()->Set(v8_str("ab1"), ab); + env->Global()->Set(v8_str("ab2"), ab2); + + v8::Handle<v8::Value> result = CompileRun("ab2.byteLength"); + CHECK_EQ(1024, result->Int32Value()); + + const v8::HeapSnapshot* snapshot = + heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); + CHECK(ValidateSnapshot(snapshot)); + const v8::HeapGraphNode* global = GetGlobalObject(snapshot); + const v8::HeapGraphNode* ab1_node = + GetProperty(global, v8::HeapGraphEdge::kProperty, "ab1"); + CHECK_NE(NULL, ab1_node); + const v8::HeapGraphNode* ab1_data = + GetProperty(ab1_node, v8::HeapGraphEdge::kInternal, "backing_store"); + CHECK_NE(NULL, ab1_data); + const v8::HeapGraphNode* ab2_node = + GetProperty(global, v8::HeapGraphEdge::kProperty, "ab2"); + CHECK_NE(NULL, ab2_node); + const v8::HeapGraphNode* ab2_data = + GetProperty(ab2_node, v8::HeapGraphEdge::kInternal, "backing_store"); + CHECK_NE(NULL, ab2_data); + CHECK_EQ(ab1_data, ab2_data); + CHECK_EQ(2, GetRetainersCount(snapshot, ab1_data)); + free(data); +} + + +TEST(BoxObject) { + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + LocalContext env; + v8::Handle<v8::Object> global_proxy = env->Global(); + v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); + + i::Factory* factory = CcTest::i_isolate()->factory(); + i::Handle<i::String> string = + factory->NewStringFromAscii(i::CStrVector("string")); + i::Handle<i::Object> box = factory->NewBox(string); + global->Set(0, v8::ToApiHandle<v8::Object>(box)); + + v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); + const v8::HeapSnapshot* snapshot = + heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); + CHECK(ValidateSnapshot(snapshot)); + const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot); + const v8::HeapGraphNode* box_node = + GetProperty(global_node, v8::HeapGraphEdge::kElement, "0"); + CHECK_NE(NULL, box_node); + v8::String::Utf8Value box_node_name(box_node->GetName()); + CHECK_EQ("system / Box", *box_node_name); + const v8::HeapGraphNode* box_value = + GetProperty(box_node, v8::HeapGraphEdge::kInternal, "value"); + CHECK_NE(NULL, box_value); } diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc index 74c2b75811..0efbbfd776 100644 --- a/deps/v8/test/cctest/test-heap.cc +++ b/deps/v8/test/cctest/test-heap.cc @@ -26,6 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdlib.h> +#include <utility> #include "v8.h" @@ -179,7 +180,7 @@ TEST(HeapObjects) { CHECK(value->IsNumber()); CHECK_EQ(Smi::kMaxValue, Smi::cast(value)->value()); -#ifndef V8_TARGET_ARCH_X64 +#if !defined(V8_TARGET_ARCH_X64) && !defined(V8_TARGET_ARCH_A64) // TODO(lrn): We need a NumberFromIntptr function in order to test this. value = heap->NumberFromInt32(Smi::kMinValue - 1)->ToObjectChecked(); CHECK(value->IsHeapNumber()); @@ -382,22 +383,24 @@ TEST(GlobalHandles) { CHECK((*h4)->IsHeapNumber()); CHECK_EQ(*h3, *h1); - global_handles->Destroy(h1.location()); - global_handles->Destroy(h3.location()); + GlobalHandles::Destroy(h1.location()); + GlobalHandles::Destroy(h3.location()); CHECK_EQ(*h4, *h2); - global_handles->Destroy(h2.location()); - global_handles->Destroy(h4.location()); + GlobalHandles::Destroy(h2.location()); + GlobalHandles::Destroy(h4.location()); } static bool WeakPointerCleared = false; -static void TestWeakGlobalHandleCallback(v8::Isolate* isolate, - v8::Persistent<v8::Value>* handle, - void* id) { - if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true; - handle->Dispose(); +static void TestWeakGlobalHandleCallback( + const v8::WeakCallbackData<v8::Value, void>& data) { + std::pair<v8::Persistent<v8::Value>*, int>* p = + reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>( + data.GetParameter()); + if (p->second == 1234) WeakPointerCleared = true; + p->first->Reset(); } @@ -424,12 +427,13 @@ TEST(WeakGlobalHandlesScavenge) { h2 = global_handles->Create(*u); } - global_handles->MakeWeak(h2.location(), - reinterpret_cast<void*>(1234), - &TestWeakGlobalHandleCallback); + std::pair<Handle<Object>*, int> handle_and_id(&h2, 1234); + GlobalHandles::MakeWeak(h2.location(), + reinterpret_cast<void*>(&handle_and_id), + &TestWeakGlobalHandleCallback); // Scavenge treats weak pointers as normal roots. - heap->PerformScavenge(); + heap->CollectGarbage(NEW_SPACE); CHECK((*h1)->IsString()); CHECK((*h2)->IsHeapNumber()); @@ -438,8 +442,8 @@ TEST(WeakGlobalHandlesScavenge) { CHECK(!global_handles->IsNearDeath(h2.location())); CHECK(!global_handles->IsNearDeath(h1.location())); - global_handles->Destroy(h1.location()); - global_handles->Destroy(h2.location()); + GlobalHandles::Destroy(h1.location()); + GlobalHandles::Destroy(h2.location()); } @@ -470,9 +474,10 @@ TEST(WeakGlobalHandlesMark) { heap->CollectGarbage(NEW_SPACE); CHECK(!heap->InNewSpace(*h1) && !heap->InNewSpace(*h2)); - global_handles->MakeWeak(h2.location(), - reinterpret_cast<void*>(1234), - &TestWeakGlobalHandleCallback); + std::pair<Handle<Object>*, int> handle_and_id(&h2, 1234); + GlobalHandles::MakeWeak(h2.location(), + reinterpret_cast<void*>(&handle_and_id), + &TestWeakGlobalHandleCallback); CHECK(!GlobalHandles::IsNearDeath(h1.location())); CHECK(!GlobalHandles::IsNearDeath(h2.location())); @@ -484,7 +489,7 @@ TEST(WeakGlobalHandlesMark) { CHECK(WeakPointerCleared); CHECK(!GlobalHandles::IsNearDeath(h1.location())); - global_handles->Destroy(h1.location()); + GlobalHandles::Destroy(h1.location()); } @@ -507,12 +512,13 @@ TEST(DeleteWeakGlobalHandle) { h = global_handles->Create(*i); } - global_handles->MakeWeak(h.location(), - reinterpret_cast<void*>(1234), - &TestWeakGlobalHandleCallback); + std::pair<Handle<Object>*, int> handle_and_id(&h, 1234); + GlobalHandles::MakeWeak(h.location(), + reinterpret_cast<void*>(&handle_and_id), + &TestWeakGlobalHandleCallback); // Scanvenge does not recognize weak reference. - heap->PerformScavenge(); + heap->CollectGarbage(NEW_SPACE); CHECK(!WeakPointerCleared); @@ -760,7 +766,7 @@ TEST(JSArray) { CHECK(array->HasFastSmiOrObjectElements()); // array[length] = name. - array->SetElement(0, *name, NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetElement(array, 0, name, NONE, kNonStrictMode); CHECK_EQ(Smi::FromInt(1), array->length()); CHECK_EQ(array->GetElement(isolate, 0), *name); @@ -775,7 +781,7 @@ TEST(JSArray) { CHECK(array->HasDictionaryElements()); // Must be in slow mode. // array[length] = name. - array->SetElement(int_length, *name, NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetElement(array, int_length, name, NONE, kNonStrictMode); uint32_t new_int_length = 0; CHECK(array->length()->ToArrayIndex(&new_int_length)); CHECK_EQ(static_cast<double>(int_length), new_int_length - 1); @@ -805,8 +811,8 @@ TEST(JSObjectCopy) { JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode); JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode); - obj->SetElement(0, *first, NONE, kNonStrictMode)->ToObjectChecked(); - obj->SetElement(1, *second, NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetElement(obj, 0, first, NONE, kNonStrictMode); + JSReceiver::SetElement(obj, 1, second, NONE, kNonStrictMode); // Make the clone. Handle<JSObject> clone = JSObject::Copy(obj); @@ -822,8 +828,8 @@ TEST(JSObjectCopy) { JSReceiver::SetProperty(clone, first, two, NONE, kNonStrictMode); JSReceiver::SetProperty(clone, second, one, NONE, kNonStrictMode); - clone->SetElement(0, *second, NONE, kNonStrictMode)->ToObjectChecked(); - clone->SetElement(1, *first, NONE, kNonStrictMode)->ToObjectChecked(); + JSReceiver::SetElement(clone, 0, second, NONE, kNonStrictMode); + JSReceiver::SetElement(clone, 1, first, NONE, kNonStrictMode); CHECK_EQ(obj->GetElement(isolate, 1), clone->GetElement(isolate, 0)); CHECK_EQ(obj->GetElement(isolate, 0), clone->GetElement(isolate, 1)); @@ -912,7 +918,7 @@ TEST(Iteration) { factory->NewStringFromAscii(CStrVector("abcdefghij"), TENURED); // Allocate a large string (for large object space). - int large_size = Page::kMaxNonCodeHeapObjectSize + 1; + int large_size = Page::kMaxRegularHeapObjectSize + 1; char* str = new char[large_size]; for (int i = 0; i < large_size - 1; ++i) str[i] = 'a'; str[large_size - 1] = '\0'; @@ -935,7 +941,7 @@ TEST(EmptyHandleEscapeFrom) { Handle<JSObject> runaway; { - v8::HandleScope nested(CcTest::isolate()); + v8::EscapableHandleScope nested(CcTest::isolate()); Handle<JSObject> empty; runaway = empty.EscapeFrom(&nested); } @@ -981,7 +987,7 @@ TEST(Regression39128) { // just enough room to allocate JSObject and thus fill the newspace. int allocation_amount = Min(FixedArray::kMaxSize, - Page::kMaxNonCodeHeapObjectSize + kPointerSize); + Page::kMaxRegularHeapObjectSize + kPointerSize); int allocation_len = LenFromSize(allocation_amount); NewSpace* new_space = heap->new_space(); Address* top_addr = new_space->allocation_top_address(); @@ -1430,7 +1436,7 @@ TEST(TestInternalWeakLists) { // Scavenge treats these references as strong. for (int j = 0; j < 10; j++) { - CcTest::heap()->PerformScavenge(); + CcTest::heap()->CollectGarbage(NEW_SPACE); CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); } @@ -1442,14 +1448,14 @@ TEST(TestInternalWeakLists) { // Get rid of f3 and f5 in the same way. CompileRun("f3=null"); for (int j = 0; j < 10; j++) { - CcTest::heap()->PerformScavenge(); + CcTest::heap()->CollectGarbage(NEW_SPACE); CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); } CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); CompileRun("f5=null"); for (int j = 0; j < 10; j++) { - CcTest::heap()->PerformScavenge(); + CcTest::heap()->CollectGarbage(NEW_SPACE); CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); } CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); @@ -1471,7 +1477,7 @@ TEST(TestInternalWeakLists) { // Scavenge treats these references as strong. for (int j = 0; j < 10; j++) { - CcTest::heap()->PerformScavenge(); + CcTest::heap()->CollectGarbage(i::NEW_SPACE); CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); } @@ -1784,15 +1790,15 @@ TEST(LeakNativeContextViaMap) { "%OptimizeFunctionOnNextCall(f);" "f();"); CHECK_EQ(42, res->Int32Value()); - ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); + ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); ctx2->Exit(); v8::Local<v8::Context>::New(isolate, ctx1)->Exit(); - ctx1p.Dispose(); + ctx1p.Reset(); v8::V8::ContextDisposedNotification(); } CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(2, NumberOfGlobalObjects()); - ctx2p.Dispose(); + ctx2p.Reset(); CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, NumberOfGlobalObjects()); } @@ -1830,15 +1836,15 @@ TEST(LeakNativeContextViaFunction) { "%OptimizeFunctionOnNextCall(f);" "f(o);"); CHECK_EQ(42, res->Int32Value()); - ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); + ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); ctx2->Exit(); ctx1->Exit(); - ctx1p.Dispose(); + ctx1p.Reset(); v8::V8::ContextDisposedNotification(); } CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(2, NumberOfGlobalObjects()); - ctx2p.Dispose(); + ctx2p.Reset(); CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, NumberOfGlobalObjects()); } @@ -1874,15 +1880,15 @@ TEST(LeakNativeContextViaMapKeyed) { "%OptimizeFunctionOnNextCall(f);" "f();"); CHECK_EQ(42, res->Int32Value()); - ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); + ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); ctx2->Exit(); ctx1->Exit(); - ctx1p.Dispose(); + ctx1p.Reset(); v8::V8::ContextDisposedNotification(); } CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(2, NumberOfGlobalObjects()); - ctx2p.Dispose(); + ctx2p.Reset(); CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, NumberOfGlobalObjects()); } @@ -1922,15 +1928,15 @@ TEST(LeakNativeContextViaMapProto) { "%OptimizeFunctionOnNextCall(f);" "f();"); CHECK_EQ(42, res->Int32Value()); - ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); + ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); ctx2->Exit(); ctx1->Exit(); - ctx1p.Dispose(); + ctx1p.Reset(); v8::V8::ContextDisposedNotification(); } CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(2, NumberOfGlobalObjects()); - ctx2p.Dispose(); + ctx2p.Reset(); CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, NumberOfGlobalObjects()); } @@ -2184,6 +2190,8 @@ TEST(OptimizedAllocationAlwaysInNewSpace) { TEST(OptimizedPretenuringAllocationFolding) { i::FLAG_allow_natives_syntax = true; + i::FLAG_max_new_space_size = 2048; + i::FLAG_allocation_site_pretenuring = false; CcTest::InitializeVM(); if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; @@ -2199,8 +2207,13 @@ TEST(OptimizedPretenuringAllocationFolding) { " this.e = 1.3;" " this.f = [{}];" "}" + "var number_elements = 20000;" + "var elements = new Array();" "function f() {" - " return new DataObject();" + " for (var i = 0; i < number_elements; i++) {" + " elements[i] = new DataObject();" + " }" + " return elements[number_elements-1]" "};" "f(); f(); f();" "%OptimizeFunctionOnNextCall(f);" @@ -2220,6 +2233,8 @@ TEST(OptimizedPretenuringAllocationFolding) { TEST(OptimizedPretenuringAllocationFoldingBlocks) { i::FLAG_allow_natives_syntax = true; + i::FLAG_max_new_space_size = 2048; + i::FLAG_allocation_site_pretenuring = false; CcTest::InitializeVM(); if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; @@ -2227,6 +2242,8 @@ TEST(OptimizedPretenuringAllocationFoldingBlocks) { CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( + "var number_elements = 30000;" + "var elements = new Array(number_elements);" "function DataObject() {" " this.a = [{}];" " this.b = [{}];" @@ -2236,7 +2253,10 @@ TEST(OptimizedPretenuringAllocationFoldingBlocks) { " this.f = 1.3;" "}" "function f() {" - " return new DataObject();" + " for (var i = 0; i < number_elements; i++) {" + " elements[i] = new DataObject();" + " }" + " return elements[number_elements - 1];" "};" "f(); f(); f();" "%OptimizeFunctionOnNextCall(f);" @@ -2256,16 +2276,20 @@ TEST(OptimizedPretenuringAllocationFoldingBlocks) { TEST(OptimizedPretenuringObjectArrayLiterals) { i::FLAG_allow_natives_syntax = true; + i::FLAG_max_new_space_size = 2048; CcTest::InitializeVM(); if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( + "var number_elements = 20000;" + "var elements = new Array(number_elements);" "function f() {" - " var numbers = [{}, {}, {}];" - " return numbers;" + " for (var i = 0; i < number_elements; i++) {" + " elements[i] = [{}, {}, {}];" + " }" + " return elements[number_elements - 1];" "};" "f(); f(); f();" "%OptimizeFunctionOnNextCall(f);" @@ -2281,16 +2305,20 @@ TEST(OptimizedPretenuringObjectArrayLiterals) { TEST(OptimizedPretenuringMixedInObjectProperties) { i::FLAG_allow_natives_syntax = true; + i::FLAG_max_new_space_size = 2048; CcTest::InitializeVM(); if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( + "var number_elements = 20000;" + "var elements = new Array(number_elements);" "function f() {" - " var numbers = {a: {c: 2.2, d: {}}, b: 1.1};" - " return numbers;" + " for (var i = 0; i < number_elements; i++) {" + " elements[i] = {a: {c: 2.2, d: {}}, b: 1.1};" + " }" + " return elements[number_elements - 1];" "};" "f(); f(); f();" "%OptimizeFunctionOnNextCall(f);" @@ -2312,16 +2340,20 @@ TEST(OptimizedPretenuringMixedInObjectProperties) { TEST(OptimizedPretenuringDoubleArrayProperties) { i::FLAG_allow_natives_syntax = true; + i::FLAG_max_new_space_size = 2048; CcTest::InitializeVM(); if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( + "var number_elements = 30000;" + "var elements = new Array(number_elements);" "function f() {" - " var numbers = {a: 1.1, b: 2.2};" - " return numbers;" + " for (var i = 0; i < number_elements; i++) {" + " elements[i] = {a: 1.1, b: 2.2};" + " }" + " return elements[i - 1];" "};" "f(); f(); f();" "%OptimizeFunctionOnNextCall(f);" @@ -2337,16 +2369,20 @@ TEST(OptimizedPretenuringDoubleArrayProperties) { TEST(OptimizedPretenuringdoubleArrayLiterals) { i::FLAG_allow_natives_syntax = true; + i::FLAG_max_new_space_size = 2048; CcTest::InitializeVM(); if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( + "var number_elements = 30000;" + "var elements = new Array(number_elements);" "function f() {" - " var numbers = [1.1, 2.2, 3.3];" - " return numbers;" + " for (var i = 0; i < number_elements; i++) {" + " elements[i] = [1.1, 2.2, 3.3];" + " }" + " return elements[number_elements - 1];" "};" "f(); f(); f();" "%OptimizeFunctionOnNextCall(f);" @@ -2362,16 +2398,20 @@ TEST(OptimizedPretenuringdoubleArrayLiterals) { TEST(OptimizedPretenuringNestedMixedArrayLiterals) { i::FLAG_allow_natives_syntax = true; + i::FLAG_max_new_space_size = 2048; CcTest::InitializeVM(); if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( + "var number_elements = 20000;" + "var elements = new Array(number_elements);" "function f() {" - " var numbers = [[{}, {}, {}],[1.1, 2.2, 3.3]];" - " return numbers;" + " for (var i = 0; i < number_elements; i++) {" + " elements[i] = [[{}, {}, {}], [1.1, 2.2, 3.3]];" + " }" + " return elements[number_elements - 1];" "};" "f(); f(); f();" "%OptimizeFunctionOnNextCall(f);" @@ -2396,16 +2436,20 @@ TEST(OptimizedPretenuringNestedMixedArrayLiterals) { TEST(OptimizedPretenuringNestedObjectLiterals) { i::FLAG_allow_natives_syntax = true; + i::FLAG_max_new_space_size = 2048; CcTest::InitializeVM(); if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( + "var number_elements = 20000;" + "var elements = new Array(number_elements);" "function f() {" - " var numbers = [[{}, {}, {}],[{}, {}, {}]];" - " return numbers;" + " for (var i = 0; i < number_elements; i++) {" + " elements[i] = [[{}, {}, {}],[{}, {}, {}]];" + " }" + " return elements[number_elements - 1];" "};" "f(); f(); f();" "%OptimizeFunctionOnNextCall(f);" @@ -2430,16 +2474,20 @@ TEST(OptimizedPretenuringNestedObjectLiterals) { TEST(OptimizedPretenuringNestedDoubleLiterals) { i::FLAG_allow_natives_syntax = true; + i::FLAG_max_new_space_size = 2048; CcTest::InitializeVM(); if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; v8::HandleScope scope(CcTest::isolate()); - CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); v8::Local<v8::Value> res = CompileRun( + "var number_elements = 20000;" + "var elements = new Array(number_elements);" "function f() {" - " var numbers = [[1.1, 1.2, 1.3],[2.1, 2.2, 2.3]];" - " return numbers;" + " for (var i = 0; i < number_elements; i++) {" + " elements[i] = [[1.1, 1.2, 1.3],[2.1, 2.2, 2.3]];" + " }" + " return elements[number_elements - 1];" "};" "f(); f(); f();" "%OptimizeFunctionOnNextCall(f);" @@ -2493,6 +2541,7 @@ TEST(OptimizedAllocationArrayLiterals) { TEST(OptimizedPretenuringCallNew) { i::FLAG_allow_natives_syntax = true; + i::FLAG_allocation_site_pretenuring = false; i::FLAG_pretenuring_call_new = true; CcTest::InitializeVM(); if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; @@ -2752,14 +2801,14 @@ TEST(Regress2211) { for (int i = 0; i < 2; i++) { // Store identity hash first and common hidden property second. - v8::Handle<v8::Object> obj = v8::Object::New(); + v8::Handle<v8::Object> obj = v8::Object::New(CcTest::isolate()); Handle<JSObject> internal_obj = v8::Utils::OpenHandle(*obj); CHECK(internal_obj->HasFastProperties()); // In the first iteration, set hidden value first and identity hash second. // In the second iteration, reverse the order. if (i == 0) obj->SetHiddenValue(v8_str("key string"), value); - JSObject::SetIdentityHash(internal_obj, hash); + JSObject::SetIdentityHash(internal_obj, handle(hash, CcTest::i_isolate())); if (i == 1) obj->SetHiddenValue(v8_str("key string"), value); // Check values. @@ -2777,7 +2826,7 @@ TEST(Regress2211) { } -TEST(IncrementalMarkingClearsTypeFeedbackCells) { +TEST(IncrementalMarkingClearsTypeFeedbackInfo) { if (i::FLAG_always_opt) return; CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); @@ -2799,32 +2848,35 @@ TEST(IncrementalMarkingClearsTypeFeedbackCells) { // originating from two different native contexts. CcTest::global()->Set(v8_str("fun1"), fun1); CcTest::global()->Set(v8_str("fun2"), fun2); - CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);"); + CompileRun("function f(a, b) { a(); b(); }" + "f(fun1, fun2);" // Run twice to skip premonomorphic state. + "f(fun1, fun2)"); + Handle<JSFunction> f = v8::Utils::OpenHandle( *v8::Handle<v8::Function>::Cast( CcTest::global()->Get(v8_str("f")))); - Handle<TypeFeedbackCells> cells(TypeFeedbackInfo::cast( - f->shared()->code()->type_feedback_info())->type_feedback_cells()); - CHECK_EQ(2, cells->CellCount()); - CHECK(cells->GetCell(0)->value()->IsJSFunction()); - CHECK(cells->GetCell(1)->value()->IsJSFunction()); + Handle<FixedArray> feedback_vector(TypeFeedbackInfo::cast( + f->shared()->code()->type_feedback_info())->feedback_vector()); + + CHECK_EQ(2, feedback_vector->length()); + CHECK(feedback_vector->get(0)->IsJSFunction()); + CHECK(feedback_vector->get(1)->IsJSFunction()); SimulateIncrementalMarking(); CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); - CHECK_EQ(2, cells->CellCount()); - CHECK(cells->GetCell(0)->value()->IsTheHole()); - CHECK(cells->GetCell(1)->value()->IsTheHole()); + CHECK_EQ(2, feedback_vector->length()); + CHECK(feedback_vector->get(0)->IsTheHole()); + CHECK(feedback_vector->get(1)->IsTheHole()); } static Code* FindFirstIC(Code* code, Code::Kind kind) { int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | - RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) | - RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT); + RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); for (RelocIterator it(code, mask); !it.done(); it.next()) { RelocInfo* info = it.rinfo(); Code* target = Code::GetCodeFromTargetAddress(info->target_address()); @@ -2836,7 +2888,7 @@ static Code* FindFirstIC(Code* code, Code::Kind kind) { } -TEST(IncrementalMarkingPreservesMonomorhpicIC) { +TEST(IncrementalMarkingPreservesMonomorphicIC) { if (i::FLAG_always_opt) return; CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); @@ -2861,7 +2913,7 @@ TEST(IncrementalMarkingPreservesMonomorhpicIC) { } -TEST(IncrementalMarkingClearsMonomorhpicIC) { +TEST(IncrementalMarkingClearsMonomorphicIC) { if (i::FLAG_always_opt) return; CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); @@ -2895,7 +2947,7 @@ TEST(IncrementalMarkingClearsMonomorhpicIC) { } -TEST(IncrementalMarkingClearsPolymorhpicIC) { +TEST(IncrementalMarkingClearsPolymorphicIC) { if (i::FLAG_always_opt) return; CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); @@ -2963,13 +3015,12 @@ void ReleaseStackTraceDataTest(const char* source, const char* accessor) { // after the first time the accessor is fired. We use external string // to check whether the data is being released since the external string // resource's callback is fired when the external string is GC'ed. - FLAG_use_ic = false; // ICs retain objects. - FLAG_concurrent_recompilation = false; v8::HandleScope scope(CcTest::isolate()); SourceResource* resource = new SourceResource(i::StrDup(source)); { v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::String> source_string = v8::String::NewExternal(resource); + v8::Handle<v8::String> source_string = + v8::String::NewExternal(CcTest::isolate(), resource); CcTest::heap()->CollectAllAvailableGarbage(); v8::Script::Compile(source_string)->Run(); CHECK(!resource->IsDisposed()); @@ -2987,6 +3038,8 @@ void ReleaseStackTraceDataTest(const char* source, const char* accessor) { TEST(ReleaseStackTraceData) { + FLAG_use_ic = false; // ICs retain objects. + FLAG_concurrent_recompilation = false; CcTest::InitializeVM(); static const char* source1 = "var error = null; " /* Normal Error */ "try { " @@ -3030,69 +3083,6 @@ TEST(ReleaseStackTraceData) { } -TEST(Regression144230) { - i::FLAG_stress_compaction = false; - CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - Heap* heap = isolate->heap(); - HandleScope scope(isolate); - - // First make sure that the uninitialized CallIC stub is on a single page - // that will later be selected as an evacuation candidate. - { - HandleScope inner_scope(isolate); - AlwaysAllocateScope always_allocate; - SimulateFullSpace(heap->code_space()); - isolate->stub_cache()->ComputeCallInitialize(9, RelocInfo::CODE_TARGET); - } - - // Second compile a CallIC and execute it once so that it gets patched to - // the pre-monomorphic stub. These code objects are on yet another page. - { - HandleScope inner_scope(isolate); - AlwaysAllocateScope always_allocate; - SimulateFullSpace(heap->code_space()); - CompileRun("var o = { f:function(a,b,c,d,e,f,g,h,i) {}};" - "function call() { o.f(1,2,3,4,5,6,7,8,9); };" - "call();"); - } - - // Third we fill up the last page of the code space so that it does not get - // chosen as an evacuation candidate. - { - HandleScope inner_scope(isolate); - AlwaysAllocateScope always_allocate; - CompileRun("for (var i = 0; i < 2000; i++) {" - " eval('function f' + i + '() { return ' + i +'; };' +" - " 'f' + i + '();');" - "}"); - } - heap->CollectAllGarbage(Heap::kNoGCFlags); - - // Fourth is the tricky part. Make sure the code containing the CallIC is - // visited first without clearing the IC. The shared function info is then - // visited later, causing the CallIC to be cleared. - Handle<String> name = isolate->factory()->InternalizeUtf8String("call"); - Handle<GlobalObject> global(isolate->context()->global_object()); - Handle<Smi> zero(Smi::FromInt(0), isolate); - MaybeObject* maybe_call = global->GetProperty(*name); - JSFunction* call = JSFunction::cast(maybe_call->ToObjectChecked()); - JSReceiver::SetProperty(global, name, zero, NONE, kNonStrictMode); - isolate->compilation_cache()->Clear(); - call->shared()->set_ic_age(heap->global_ic_age() + 1); - Handle<Object> call_code(call->code(), isolate); - Handle<Object> call_function(call, isolate); - - // Now we are ready to mess up the heap. - heap->CollectAllGarbage(Heap::kReduceMemoryFootprintMask); - - // Either heap verification caught the problem already or we go kaboom once - // the CallIC is executed the next time. - JSReceiver::SetProperty(global, name, call_function, NONE, kNonStrictMode); - CompileRun("call();"); -} - - TEST(Regress159140) { i::FLAG_allow_natives_syntax = true; i::FLAG_flush_code_incrementally = true; @@ -3320,7 +3310,7 @@ TEST(Regress169928) { v8_str("fastliteralcase(mote, 2.5);"); v8::Local<v8::String> array_name = v8_str("mote"); - CcTest::global()->Set(array_name, v8::Int32::New(0)); + CcTest::global()->Set(array_name, v8::Int32::New(CcTest::isolate(), 0)); // First make sure we flip spaces CcTest::heap()->CollectGarbage(NEW_SPACE); @@ -3485,8 +3475,7 @@ TEST(DeferredHandles) { Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate)); - v8::ImplementationUtilities::HandleScopeData* data = - isolate->handle_scope_data(); + HandleScopeData* data = isolate->handle_scope_data(); Handle<Object> init(heap->empty_string(), isolate); while (data->next < data->limit) { Handle<Object> obj(heap->empty_string(), isolate); @@ -3498,7 +3487,7 @@ TEST(DeferredHandles) { DeferredHandleScope deferred(isolate); DummyVisitor visitor; isolate->handle_scope_implementer()->Iterate(&visitor); - deferred.Detach(); + delete deferred.Detach(); } @@ -3516,3 +3505,188 @@ TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) { marking->Step(100 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); ASSERT(marking->IsComplete()); } + + +TEST(DisableInlineAllocation) { + i::FLAG_allow_natives_syntax = true; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + CompileRun("function test() {" + " var x = [];" + " for (var i = 0; i < 10; i++) {" + " x[i] = [ {}, [1,2,3], [1,x,3] ];" + " }" + "}" + "function run() {" + " %OptimizeFunctionOnNextCall(test);" + " test();" + " %DeoptimizeFunction(test);" + "}"); + + // Warm-up with inline allocation enabled. + CompileRun("test(); test(); run();"); + + // Run test with inline allocation disabled. + CcTest::heap()->DisableInlineAllocation(); + CompileRun("run()"); + + // Run test with inline allocation disabled and pretenuring. + CcTest::heap()->SetNewSpaceHighPromotionModeActive(true); + CompileRun("run()"); + + // Run test with inline allocation re-enabled. + CcTest::heap()->EnableInlineAllocation(); + CompileRun("run()"); +} + + +static int AllocationSitesCount(Heap* heap) { + int count = 0; + for (Object* site = heap->allocation_sites_list(); + !(site->IsUndefined()); + site = AllocationSite::cast(site)->weak_next()) { + count++; + } + return count; +} + + +TEST(EnsureAllocationSiteDependentCodesProcessed) { + if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; + i::FLAG_allow_natives_syntax = true; + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + v8::internal::Heap* heap = CcTest::heap(); + GlobalHandles* global_handles = isolate->global_handles(); + + if (!isolate->use_crankshaft()) return; + + // The allocation site at the head of the list is ours. + Handle<AllocationSite> site; + { + LocalContext context; + v8::HandleScope scope(context->GetIsolate()); + + int count = AllocationSitesCount(heap); + CompileRun("var bar = function() { return (new Array()); };" + "var a = bar();" + "bar();" + "bar();"); + + // One allocation site should have been created. + int new_count = AllocationSitesCount(heap); + CHECK_EQ(new_count, (count + 1)); + site = Handle<AllocationSite>::cast( + global_handles->Create( + AllocationSite::cast(heap->allocation_sites_list()))); + + CompileRun("%OptimizeFunctionOnNextCall(bar); bar();"); + + DependentCode::GroupStartIndexes starts(site->dependent_code()); + CHECK_GE(starts.number_of_entries(), 1); + int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); + CHECK(site->dependent_code()->is_code_at(index)); + Code* function_bar = site->dependent_code()->code_at(index); + Handle<JSFunction> bar_handle = + v8::Utils::OpenHandle( + *v8::Handle<v8::Function>::Cast( + CcTest::global()->Get(v8_str("bar")))); + CHECK_EQ(bar_handle->code(), function_bar); + } + + // Now make sure that a gc should get rid of the function, even though we + // still have the allocation site alive. + for (int i = 0; i < 4; i++) { + heap->CollectAllGarbage(false); + } + + // The site still exists because of our global handle, but the code is no + // longer referred to by dependent_code(). + DependentCode::GroupStartIndexes starts(site->dependent_code()); + int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); + CHECK(!(site->dependent_code()->is_code_at(index))); +} + + +TEST(CellsInOptimizedCodeAreWeak) { + if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; + i::FLAG_weak_embedded_objects_in_optimized_code = true; + i::FLAG_allow_natives_syntax = true; + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + v8::internal::Heap* heap = CcTest::heap(); + + if (!isolate->use_crankshaft()) return; + HandleScope outer_scope(heap->isolate()); + Handle<Code> code; + { + LocalContext context; + HandleScope scope(heap->isolate()); + + CompileRun("bar = (function() {" + " function bar() {" + " return foo(1);" + " };" + " var foo = function(x) { with (x) { return 1 + x; } };" + " bar(foo);" + " bar(foo);" + " bar(foo);" + " %OptimizeFunctionOnNextCall(bar);" + " bar(foo);" + " return bar;})();"); + + Handle<JSFunction> bar = + v8::Utils::OpenHandle( + *v8::Handle<v8::Function>::Cast( + CcTest::global()->Get(v8_str("bar")))); + code = scope.CloseAndEscape(Handle<Code>(bar->code())); + } + + // Now make sure that a gc should get rid of the function + for (int i = 0; i < 4; i++) { + heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + } + + ASSERT(code->marked_for_deoptimization()); +} + + +TEST(ObjectsInOptimizedCodeAreWeak) { + if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; + i::FLAG_weak_embedded_objects_in_optimized_code = true; + i::FLAG_allow_natives_syntax = true; + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + v8::internal::Heap* heap = CcTest::heap(); + + if (!isolate->use_crankshaft()) return; + HandleScope outer_scope(heap->isolate()); + Handle<Code> code; + { + LocalContext context; + HandleScope scope(heap->isolate()); + + CompileRun("function bar() {" + " return foo(1);" + "};" + "function foo(x) { with (x) { return 1 + x; } };" + "bar();" + "bar();" + "bar();" + "%OptimizeFunctionOnNextCall(bar);" + "bar();"); + + Handle<JSFunction> bar = + v8::Utils::OpenHandle( + *v8::Handle<v8::Function>::Cast( + CcTest::global()->Get(v8_str("bar")))); + code = scope.CloseAndEscape(Handle<Code>(bar->code())); + } + + // Now make sure that a gc should get rid of the function + for (int i = 0; i < 4; i++) { + heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + } + + ASSERT(code->marked_for_deoptimization()); +} diff --git a/deps/v8/test/cctest/test-javascript-a64.cc b/deps/v8/test/cctest/test-javascript-a64.cc new file mode 100644 index 0000000000..bd7a2b2851 --- /dev/null +++ b/deps/v8/test/cctest/test-javascript-a64.cc @@ -0,0 +1,266 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <limits.h> + +#include "v8.h" + +#include "api.h" +#include "isolate.h" +#include "compilation-cache.h" +#include "execution.h" +#include "snapshot.h" +#include "platform.h" +#include "utils.h" +#include "cctest.h" +#include "parser.h" +#include "unicode-inl.h" + +using ::v8::Context; +using ::v8::Extension; +using ::v8::Function; +using ::v8::FunctionTemplate; +using ::v8::Handle; +using ::v8::HandleScope; +using ::v8::Local; +using ::v8::Message; +using ::v8::MessageCallback; +using ::v8::Object; +using ::v8::ObjectTemplate; +using ::v8::Persistent; +using ::v8::Script; +using ::v8::StackTrace; +using ::v8::String; +using ::v8::TryCatch; +using ::v8::Undefined; +using ::v8::V8; +using ::v8::Value; + +static void ExpectBoolean(bool expected, Local<Value> result) { + CHECK(result->IsBoolean()); + CHECK_EQ(expected, result->BooleanValue()); +} + + +static void ExpectInt32(int32_t expected, Local<Value> result) { + CHECK(result->IsInt32()); + CHECK_EQ(expected, result->Int32Value()); +} + + +static void ExpectNumber(double expected, Local<Value> result) { + CHECK(result->IsNumber()); + CHECK_EQ(expected, result->NumberValue()); +} + + +static void ExpectUndefined(Local<Value> result) { + CHECK(result->IsUndefined()); +} + + +// Tests are sorted by order of implementation. + +TEST(simple_value) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result = CompileRun("0x271828;"); + ExpectInt32(0x271828, result); +} + + +TEST(global_variable) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result = CompileRun("var my_global_var = 0x123; my_global_var;"); + ExpectInt32(0x123, result); +} + + +TEST(simple_function_call) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result = CompileRun( + "function foo() { return 0x314; }" + "foo();"); + ExpectInt32(0x314, result); +} + + +TEST(binary_op) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result = CompileRun( + "function foo() {" + " var a = 0x1200;" + " var b = 0x0035;" + " return 2 * (a + b - 1);" + "}" + "foo();"); + ExpectInt32(0x2468, result); +} + +static void if_comparison_testcontext_helper( + char const * op, + char const * lhs, + char const * rhs, + int expect) { + char buffer[256]; + snprintf(buffer, sizeof(buffer), + "var lhs = %s;" + "var rhs = %s;" + "if ( lhs %s rhs ) { 1; }" + "else { 0; }", + lhs, rhs, op); + Local<Value> result = CompileRun(buffer); + ExpectInt32(expect, result); +} + +static void if_comparison_effectcontext_helper( + char const * op, + char const * lhs, + char const * rhs, + int expect) { + char buffer[256]; + snprintf(buffer, sizeof(buffer), + "var lhs = %s;" + "var rhs = %s;" + "var test = lhs %s rhs;" + "if ( test ) { 1; }" + "else { 0; }", + lhs, rhs, op); + Local<Value> result = CompileRun(buffer); + ExpectInt32(expect, result); +} + +static void if_comparison_helper( + char const * op, + int expect_when_lt, + int expect_when_eq, + int expect_when_gt) { + // TODO(all): Non-SMI tests. + + if_comparison_testcontext_helper(op, "1", "3", expect_when_lt); + if_comparison_testcontext_helper(op, "5", "5", expect_when_eq); + if_comparison_testcontext_helper(op, "9", "7", expect_when_gt); + + if_comparison_effectcontext_helper(op, "1", "3", expect_when_lt); + if_comparison_effectcontext_helper(op, "5", "5", expect_when_eq); + if_comparison_effectcontext_helper(op, "9", "7", expect_when_gt); +} + + +TEST(if_comparison) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + + if_comparison_helper("<", 1, 0, 0); + if_comparison_helper("<=", 1, 1, 0); + if_comparison_helper("==", 0, 1, 0); + if_comparison_helper("===", 0, 1, 0); + if_comparison_helper(">=", 0, 1, 1); + if_comparison_helper(">", 0, 0, 1); + if_comparison_helper("!=", 1, 0, 1); + if_comparison_helper("!==", 1, 0, 1); +} + + +TEST(unary_plus) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result; + // SMI + result = CompileRun("var a = 1234; +a"); + ExpectInt32(1234, result); + // Number + result = CompileRun("var a = 1234.5; +a"); + ExpectNumber(1234.5, result); + // String (SMI) + result = CompileRun("var a = '1234'; +a"); + ExpectInt32(1234, result); + // String (Number) + result = CompileRun("var a = '1234.5'; +a"); + ExpectNumber(1234.5, result); + // Check side effects. + result = CompileRun("var a = 1234; +(a = 4321); a"); + ExpectInt32(4321, result); +} + + +TEST(unary_minus) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result; + result = CompileRun("var a = 1234; -a"); + ExpectInt32(-1234, result); + result = CompileRun("var a = 1234.5; -a"); + ExpectNumber(-1234.5, result); + result = CompileRun("var a = 1234; -(a = 4321); a"); + ExpectInt32(4321, result); + result = CompileRun("var a = '1234'; -a"); + ExpectInt32(-1234, result); + result = CompileRun("var a = '1234.5'; -a"); + ExpectNumber(-1234.5, result); +} + + +TEST(unary_void) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result; + result = CompileRun("var a = 1234; void (a);"); + ExpectUndefined(result); + result = CompileRun("var a = 0; void (a = 42); a"); + ExpectInt32(42, result); + result = CompileRun("var a = 0; void (a = 42);"); + ExpectUndefined(result); +} + + +TEST(unary_not) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result; + result = CompileRun("var a = 1234; !a"); + ExpectBoolean(false, result); + result = CompileRun("var a = 0; !a"); + ExpectBoolean(true, result); + result = CompileRun("var a = 0; !(a = 1234); a"); + ExpectInt32(1234, result); + result = CompileRun("var a = '1234'; !a"); + ExpectBoolean(false, result); + result = CompileRun("var a = ''; !a"); + ExpectBoolean(true, result); + result = CompileRun("var a = 1234; !!a"); + ExpectBoolean(true, result); + result = CompileRun("var a = 0; !!a"); + ExpectBoolean(false, result); + result = CompileRun("var a = 0; if ( !a ) { 1; } else { 0; }"); + ExpectInt32(1, result); + result = CompileRun("var a = 1; if ( !a ) { 1; } else { 0; }"); + ExpectInt32(0, result); +} diff --git a/deps/v8/test/cctest/test-js-a64-variables.cc b/deps/v8/test/cctest/test-js-a64-variables.cc new file mode 100644 index 0000000000..df3f4a8295 --- /dev/null +++ b/deps/v8/test/cctest/test-js-a64-variables.cc @@ -0,0 +1,143 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Adapted from test/mjsunit/compiler/variables.js + +#include <limits.h> + +#include "v8.h" + +#include "api.h" +#include "isolate.h" +#include "compilation-cache.h" +#include "execution.h" +#include "snapshot.h" +#include "platform.h" +#include "utils.h" +#include "cctest.h" +#include "parser.h" +#include "unicode-inl.h" + +using ::v8::Context; +using ::v8::Extension; +using ::v8::Function; +using ::v8::FunctionTemplate; +using ::v8::Handle; +using ::v8::HandleScope; +using ::v8::Local; +using ::v8::Message; +using ::v8::MessageCallback; +using ::v8::Object; +using ::v8::ObjectTemplate; +using ::v8::Persistent; +using ::v8::Script; +using ::v8::StackTrace; +using ::v8::String; +using ::v8::TryCatch; +using ::v8::Undefined; +using ::v8::V8; +using ::v8::Value; + +static void ExpectInt32(int32_t expected, Local<Value> result) { + CHECK(result->IsInt32()); + CHECK_EQ(expected, result->Int32Value()); +} + + +// Global variables. +TEST(global_variables) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result = CompileRun( +"var x = 0;" +"function f0() { return x; }" +"f0();"); + ExpectInt32(0, result); +} + + +// Parameters. +TEST(parameters) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result = CompileRun( +"function f1(x) { return x; }" +"f1(1);"); + ExpectInt32(1, result); +} + + +// Stack-allocated locals. +TEST(stack_allocated_locals) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result = CompileRun( +"function f2() { var x = 2; return x; }" +"f2();"); + ExpectInt32(2, result); +} + + +// Context-allocated locals. Local function forces x into f3's context. +TEST(context_allocated_locals) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result = CompileRun( +"function f3(x) {" +" function g() { return x; }" +" return x;" +"}" +"f3(3);"); + ExpectInt32(3, result); +} + + +// Local function reads x from an outer context. +TEST(read_from_outer_context) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result = CompileRun( +"function f4(x) {" +" function g() { return x; }" +" return g();" +"}" +"f4(4);"); + ExpectInt32(4, result); +} + + +// Local function reads x from an outer context. +TEST(lookup_slots) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + Local<Value> result = CompileRun( +"function f5(x) {" +" with ({}) return x;" +"}" +"f5(5);"); + ExpectInt32(5, result); +} diff --git a/deps/v8/test/cctest/test-libplatform-task-queue.cc b/deps/v8/test/cctest/test-libplatform-task-queue.cc new file mode 100644 index 0000000000..4765515763 --- /dev/null +++ b/deps/v8/test/cctest/test-libplatform-task-queue.cc @@ -0,0 +1,95 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "v8.h" + +#include "cctest.h" +#include "libplatform/task-queue.h" +#include "test-libplatform.h" + +using namespace v8::internal; + + +TEST(TaskQueueBasic) { + TaskCounter task_counter; + + TaskQueue queue; + + TestTask* task = new TestTask(&task_counter); + queue.Append(task); + CHECK_EQ(1, task_counter.GetCount()); + CHECK_EQ(task, queue.GetNext()); + delete task; + CHECK_EQ(0, task_counter.GetCount()); + + queue.Terminate(); + CHECK_EQ(NULL, queue.GetNext()); +} + + +class ReadQueueTask : public TestTask { + public: + ReadQueueTask(TaskCounter* task_counter, TaskQueue* queue) + : TestTask(task_counter, true), queue_(queue) {} + virtual ~ReadQueueTask() {} + + virtual void Run() V8_OVERRIDE { + TestTask::Run(); + CHECK_EQ(NULL, queue_->GetNext()); + } + + private: + TaskQueue* queue_; + + DISALLOW_COPY_AND_ASSIGN(ReadQueueTask); +}; + + +TEST(TaskQueueTerminateMultipleReaders) { + TaskQueue queue; + TaskCounter task_counter; + ReadQueueTask* read1 = new ReadQueueTask(&task_counter, &queue); + ReadQueueTask* read2 = new ReadQueueTask(&task_counter, &queue); + + TestWorkerThread thread1(read1); + TestWorkerThread thread2(read2); + + thread1.Start(); + thread2.Start(); + + CHECK_EQ(2, task_counter.GetCount()); + + thread1.Signal(); + thread2.Signal(); + + queue.Terminate(); + + thread1.Join(); + thread2.Join(); + + CHECK_EQ(0, task_counter.GetCount()); +} diff --git a/deps/v8/test/mjsunit/proto-poison.js b/deps/v8/test/cctest/test-libplatform-worker-thread.cc index ca3b5d6d06..090d6e1a18 100644 --- a/deps/v8/test/mjsunit/proto-poison.js +++ b/deps/v8/test/cctest/test-libplatform-worker-thread.cc @@ -25,21 +25,40 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Check that the __proto__ accessor is properly poisoned when extracted -// from Object.prototype using the property descriptor. -var desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__"); -assertEquals("function", typeof desc.get); -assertEquals("function", typeof desc.set); -assertDoesNotThrow("desc.get.call({})"); -assertThrows("desc.set.call({})", TypeError); - -// Check that any redefinition of the __proto__ accessor causes poising -// to cease and the accessor to be extracted normally. -Object.defineProperty(Object.prototype, "__proto__", { get:function(){} }); -desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__"); -assertDoesNotThrow("desc.get.call({})"); -assertThrows("desc.set.call({})", TypeError); -Object.defineProperty(Object.prototype, "__proto__", { set:function(x){} }); -desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__"); -assertDoesNotThrow("desc.get.call({})"); -assertDoesNotThrow("desc.set.call({})"); +#include "v8.h" + +#include "cctest.h" +#include "libplatform/task-queue.h" +#include "libplatform/worker-thread.h" +#include "test-libplatform.h" + +using namespace v8::internal; + + +TEST(WorkerThread) { + TaskQueue queue; + TaskCounter task_counter; + + TestTask* task1 = new TestTask(&task_counter, true); + TestTask* task2 = new TestTask(&task_counter, true); + TestTask* task3 = new TestTask(&task_counter, true); + TestTask* task4 = new TestTask(&task_counter, true); + + WorkerThread* thread1 = new WorkerThread(&queue); + WorkerThread* thread2 = new WorkerThread(&queue); + + CHECK_EQ(4, task_counter.GetCount()); + + queue.Append(task1); + queue.Append(task2); + queue.Append(task3); + queue.Append(task4); + + // TaskQueue ASSERTs that it is empty in its destructor. + queue.Terminate(); + + delete thread1; + delete thread2; + + CHECK_EQ(0, task_counter.GetCount()); +} diff --git a/deps/v8/test/cctest/test-libplatform.h b/deps/v8/test/cctest/test-libplatform.h new file mode 100644 index 0000000000..e32770eeda --- /dev/null +++ b/deps/v8/test/cctest/test-libplatform.h @@ -0,0 +1,120 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef TEST_LIBPLATFORM_H_ +#define TEST_LIBPLATFORM_H_ + +#include "v8.h" + +#include "cctest.h" + +using namespace v8::internal; + +class TaskCounter { + public: + TaskCounter() : counter_(0) {} + ~TaskCounter() { CHECK_EQ(0, counter_); } + + int GetCount() const { + LockGuard<Mutex> guard(&lock_); + return counter_; + } + + void Inc() { + LockGuard<Mutex> guard(&lock_); + ++counter_; + } + + void Dec() { + LockGuard<Mutex> guard(&lock_); + --counter_; + } + + private: + mutable Mutex lock_; + int counter_; + + DISALLOW_COPY_AND_ASSIGN(TaskCounter); +}; + + +class TestTask : public v8::Task { + public: + TestTask(TaskCounter* task_counter, bool expected_to_run) + : task_counter_(task_counter), + expected_to_run_(expected_to_run), + executed_(false) { + task_counter_->Inc(); + } + + explicit TestTask(TaskCounter* task_counter) + : task_counter_(task_counter), expected_to_run_(false), executed_(false) { + task_counter_->Inc(); + } + + virtual ~TestTask() { + CHECK_EQ(expected_to_run_, executed_); + task_counter_->Dec(); + } + + // v8::Task implementation. + virtual void Run() V8_OVERRIDE { executed_ = true; } + + private: + TaskCounter* task_counter_; + bool expected_to_run_; + bool executed_; + + DISALLOW_COPY_AND_ASSIGN(TestTask); +}; + + +class TestWorkerThread : public Thread { + public: + explicit TestWorkerThread(v8::Task* task) + : Thread("libplatform TestWorkerThread"), semaphore_(0), task_(task) {} + virtual ~TestWorkerThread() {} + + void Signal() { semaphore_.Signal(); } + + // Thread implementation. + virtual void Run() V8_OVERRIDE { + semaphore_.Wait(); + if (task_) { + task_->Run(); + delete task_; + } + } + + private: + Semaphore semaphore_; + v8::Task* task_; + + DISALLOW_COPY_AND_ASSIGN(TestWorkerThread); +}; + +#endif // TEST_LIBPLATFORM_H_ diff --git a/deps/v8/test/cctest/test-lockers.cc b/deps/v8/test/cctest/test-lockers.cc index 1094512276..12b35a5c4d 100644 --- a/deps/v8/test/cctest/test-lockers.cc +++ b/deps/v8/test/cctest/test-lockers.cc @@ -667,7 +667,7 @@ TEST(Regress1433) { v8::HandleScope handle_scope(isolate); v8::Handle<Context> context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); - v8::Handle<String> source = v8::String::New("1+1"); + v8::Handle<String> source = v8::String::NewFromUtf8(isolate, "1+1"); v8::Handle<Script> script = v8::Script::Compile(source); v8::Handle<Value> result = script->Run(); v8::String::Utf8Value utf8(result); diff --git a/deps/v8/test/cctest/test-log-stack-tracer.cc b/deps/v8/test/cctest/test-log-stack-tracer.cc index 4a0717d09d..5b6858e553 100644 --- a/deps/v8/test/cctest/test-log-stack-tracer.cc +++ b/deps/v8/test/cctest/test-log-stack-tracer.cc @@ -38,6 +38,7 @@ #include "isolate.h" #include "log.h" #include "sampler.h" +#include "trace-extension.h" #include "vm-state-inl.h" using v8::Function; @@ -52,135 +53,9 @@ using v8::internal::Address; using v8::internal::Handle; using v8::internal::Isolate; using v8::internal::JSFunction; -using v8::internal::RegisterState; using v8::internal::TickSample; -static struct { - TickSample* sample; -} trace_env = { NULL }; - - -static void InitTraceEnv(TickSample* sample) { - trace_env.sample = sample; -} - - -static void DoTrace(Address fp) { - RegisterState regs; - regs.fp = fp; - // sp is only used to define stack high bound - regs.sp = - reinterpret_cast<Address>(trace_env.sample) - 10240; - trace_env.sample->Init(CcTest::i_isolate(), regs); -} - - -// Hide c_entry_fp to emulate situation when sampling is done while -// pure JS code is being executed -static void DoTraceHideCEntryFPAddress(Address fp) { - v8::internal::Address saved_c_frame_fp = - *(CcTest::i_isolate()->c_entry_fp_address()); - CHECK(saved_c_frame_fp); - *(CcTest::i_isolate()->c_entry_fp_address()) = 0; - DoTrace(fp); - *(CcTest::i_isolate()->c_entry_fp_address()) = saved_c_frame_fp; -} - - -// --- T r a c e E x t e n s i o n --- - -class TraceExtension : public v8::Extension { - public: - TraceExtension() : v8::Extension("v8/trace", kSource) { } - virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( - v8::Handle<String> name); - static void Trace(const v8::FunctionCallbackInfo<v8::Value>& args); - static void JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args); - static void JSEntrySP(const v8::FunctionCallbackInfo<v8::Value>& args); - static void JSEntrySPLevel2(const v8::FunctionCallbackInfo<v8::Value>& args); - private: - static Address GetFP(const v8::FunctionCallbackInfo<v8::Value>& args); - static const char* kSource; -}; - - -const char* TraceExtension::kSource = - "native function trace();" - "native function js_trace();" - "native function js_entry_sp();" - "native function js_entry_sp_level2();"; - -v8::Handle<v8::FunctionTemplate> TraceExtension::GetNativeFunction( - v8::Handle<String> name) { - if (name->Equals(String::New("trace"))) { - return v8::FunctionTemplate::New(TraceExtension::Trace); - } else if (name->Equals(String::New("js_trace"))) { - return v8::FunctionTemplate::New(TraceExtension::JSTrace); - } else if (name->Equals(String::New("js_entry_sp"))) { - return v8::FunctionTemplate::New(TraceExtension::JSEntrySP); - } else if (name->Equals(String::New("js_entry_sp_level2"))) { - return v8::FunctionTemplate::New(TraceExtension::JSEntrySPLevel2); - } else { - CHECK(false); - return v8::Handle<v8::FunctionTemplate>(); - } -} - - -Address TraceExtension::GetFP(const v8::FunctionCallbackInfo<v8::Value>& args) { - // Convert frame pointer from encoding as smis in the arguments to a pointer. - CHECK_EQ(2, args.Length()); // Ignore second argument on 32-bit platform. -#if defined(V8_HOST_ARCH_32_BIT) - Address fp = *reinterpret_cast<Address*>(*args[0]); -#elif defined(V8_HOST_ARCH_64_BIT) - int64_t low_bits = *reinterpret_cast<uint64_t*>(*args[0]) >> 32; - int64_t high_bits = *reinterpret_cast<uint64_t*>(*args[1]); - Address fp = reinterpret_cast<Address>(high_bits | low_bits); -#else -#error Host architecture is neither 32-bit nor 64-bit. -#endif - printf("Trace: %p\n", fp); - return fp; -} - - -void TraceExtension::Trace(const v8::FunctionCallbackInfo<v8::Value>& args) { - DoTrace(GetFP(args)); -} - - -void TraceExtension::JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args) { - DoTraceHideCEntryFPAddress(GetFP(args)); -} - - -static Address GetJsEntrySp() { - CHECK_NE(NULL, CcTest::i_isolate()->thread_local_top()); - return CcTest::i_isolate()->js_entry_sp(); -} - - -void TraceExtension::JSEntrySP( - const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK_NE(0, GetJsEntrySp()); -} - - -void TraceExtension::JSEntrySPLevel2( - const v8::FunctionCallbackInfo<v8::Value>& args) { - v8::HandleScope scope(args.GetIsolate()); - const Address js_entry_sp = GetJsEntrySp(); - CHECK_NE(0, js_entry_sp); - CompileRun("js_entry_sp();"); - CHECK_EQ(js_entry_sp, GetJsEntrySp()); -} - - -static TraceExtension kTraceExtension; -v8::DeclareExtension kTraceExtensionDeclaration(&kTraceExtension); - - static bool IsAddressWithinFuncCode(JSFunction* function, Address addr) { i::Code* code = function->code(); return code->contains(addr); @@ -230,7 +105,7 @@ static void construct_call(const v8::FunctionCallbackInfo<v8::Value>& args) { void CreateFramePointerGrabberConstructor(v8::Local<v8::Context> context, const char* constructor_name) { Local<v8::FunctionTemplate> constructor_template = - v8::FunctionTemplate::New(construct_call); + v8::FunctionTemplate::New(context->GetIsolate(), construct_call); constructor_template->SetClassName(v8_str("FPGrabber")); Local<Function> fun = constructor_template->GetFunction(); context->Global()->Set(v8_str(constructor_name), fun); @@ -269,7 +144,7 @@ TEST(CFromJSStackTrace) { i::FLAG_use_inlining = false; TickSample sample; - InitTraceEnv(&sample); + i::TraceExtension::InitTraceEnv(&sample); v8::HandleScope scope(CcTest::isolate()); v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION); @@ -294,7 +169,7 @@ TEST(CFromJSStackTrace) { // TickSample::Trace CHECK(sample.has_external_callback); - CHECK_EQ(FUNCTION_ADDR(TraceExtension::Trace), sample.external_callback); + CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::Trace), sample.external_callback); // Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace" int base = 0; @@ -317,7 +192,7 @@ TEST(PureJSStackTrace) { i::FLAG_use_inlining = false; TickSample sample; - InitTraceEnv(&sample); + i::TraceExtension::InitTraceEnv(&sample); v8::HandleScope scope(CcTest::isolate()); v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION); @@ -347,7 +222,7 @@ TEST(PureJSStackTrace) { // CHECK(sample.has_external_callback); - CHECK_EQ(FUNCTION_ADDR(TraceExtension::JSTrace), sample.external_callback); + CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::JSTrace), sample.external_callback); // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace" int base = 0; @@ -369,7 +244,7 @@ static void CFuncDoTrace(byte dummy_parameter) { #else #error Unexpected platform. #endif - DoTrace(fp); + i::TraceExtension::DoTrace(fp); } @@ -388,7 +263,7 @@ static int CFunc(int depth) { // get any meaningful info here. TEST(PureCStackTrace) { TickSample sample; - InitTraceEnv(&sample); + i::TraceExtension::InitTraceEnv(&sample); v8::HandleScope scope(CcTest::isolate()); v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION); v8::Context::Scope context_scope(context); @@ -401,11 +276,11 @@ TEST(JsEntrySp) { v8::HandleScope scope(CcTest::isolate()); v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION); v8::Context::Scope context_scope(context); - CHECK_EQ(0, GetJsEntrySp()); + CHECK_EQ(0, i::TraceExtension::GetJsEntrySp()); CompileRun("a = 1; b = a + 1;"); - CHECK_EQ(0, GetJsEntrySp()); + CHECK_EQ(0, i::TraceExtension::GetJsEntrySp()); CompileRun("js_entry_sp();"); - CHECK_EQ(0, GetJsEntrySp()); + CHECK_EQ(0, i::TraceExtension::GetJsEntrySp()); CompileRun("js_entry_sp_level2();"); - CHECK_EQ(0, GetJsEntrySp()); + CHECK_EQ(0, i::TraceExtension::GetJsEntrySp()); } diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc index 2cf2a77445..65310369cb 100644 --- a/deps/v8/test/cctest/test-log.cc +++ b/deps/v8/test/cctest/test-log.cc @@ -203,7 +203,7 @@ class LoopingNonJsThread : public LoopingThread { double i = 10; SignalRunning(); while (IsRunning()) { - i = sin(i); + i = std::sin(i); i::OS::Sleep(1); } } @@ -305,9 +305,11 @@ TEST(Issue23768) { env->Enter(); SimpleExternalString source_ext_str("(function ext() {})();"); - v8::Local<v8::String> source = v8::String::NewExternal(&source_ext_str); + v8::Local<v8::String> source = + v8::String::NewExternal(CcTest::isolate(), &source_ext_str); // Script needs to have a name in order to trigger InitLineEnds execution. - v8::Handle<v8::String> origin = v8::String::New("issue-23768-test"); + v8::Handle<v8::String> origin = + v8::String::NewFromUtf8(CcTest::isolate(), "issue-23768-test"); v8::Handle<v8::Script> evil_script = v8::Script::Compile(source, origin); CHECK(!evil_script.IsEmpty()); CHECK(!evil_script->Run().IsEmpty()); @@ -327,17 +329,20 @@ static void ObjMethod1(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(LogCallbacks) { + v8::Isolate* isolate = CcTest::isolate(); ScopedLoggerInitializer initialize_logger; Logger* logger = initialize_logger.logger(); v8::Local<v8::FunctionTemplate> obj = - v8::Local<v8::FunctionTemplate>::New(CcTest::isolate(), - v8::FunctionTemplate::New()); + v8::Local<v8::FunctionTemplate>::New(isolate, + v8::FunctionTemplate::New(isolate)); obj->SetClassName(v8_str("Obj")); v8::Handle<v8::ObjectTemplate> proto = obj->PrototypeTemplate(); - v8::Local<v8::Signature> signature = v8::Signature::New(obj); + v8::Local<v8::Signature> signature = + v8::Signature::New(isolate, obj); proto->Set(v8_str("method1"), - v8::FunctionTemplate::New(ObjMethod1, + v8::FunctionTemplate::New(isolate, + ObjMethod1, v8::Handle<v8::Value>(), signature), static_cast<v8::PropertyAttribute>(v8::DontDelete)); @@ -358,6 +363,7 @@ TEST(LogCallbacks) { ObjMethod1); CHECK_NE(NULL, StrNStr(log.start(), ref_data.start(), log.length())); + log.Dispose(); } @@ -376,12 +382,13 @@ static void Prop2Getter(v8::Local<v8::String> property, TEST(LogAccessorCallbacks) { + v8::Isolate* isolate = CcTest::isolate(); ScopedLoggerInitializer initialize_logger; Logger* logger = initialize_logger.logger(); v8::Local<v8::FunctionTemplate> obj = - v8::Local<v8::FunctionTemplate>::New(CcTest::isolate(), - v8::FunctionTemplate::New()); + v8::Local<v8::FunctionTemplate>::New(isolate, + v8::FunctionTemplate::New(isolate)); obj->SetClassName(v8_str("Obj")); v8::Handle<v8::ObjectTemplate> inst = obj->InstanceTemplate(); inst->SetAccessor(v8_str("prop1"), Prop1Getter, Prop1Setter); @@ -414,6 +421,7 @@ TEST(LogAccessorCallbacks) { Prop2Getter); CHECK_NE(NULL, StrNStr(log.start(), prop2_getter_record.start(), log.length())); + log.Dispose(); } @@ -451,12 +459,14 @@ TEST(EquivalenceOfLoggingAndTraversal) { i::Vector<const char> log( i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true)); CHECK(exists); - v8::Handle<v8::String> log_str = v8::String::New(log.start(), log.length()); + v8::Handle<v8::String> log_str = v8::String::NewFromUtf8( + CcTest::isolate(), log.start(), v8::String::kNormalString, log.length()); initialize_logger.env()->Global()->Set(v8_str("_log"), log_str); i::Vector<const unsigned char> source = TestSources::GetScriptsSource(); - v8::Handle<v8::String> source_str = v8::String::New( - reinterpret_cast<const char*>(source.start()), source.length()); + v8::Handle<v8::String> source_str = v8::String::NewFromUtf8( + CcTest::isolate(), reinterpret_cast<const char*>(source.start()), + v8::String::kNormalString, source.length()); v8::TryCatch try_catch; v8::Handle<v8::Script> script = v8::Script::Compile(source_str, v8_str("")); if (script.IsEmpty()) { diff --git a/deps/v8/test/cctest/test-macro-assembler-arm.cc b/deps/v8/test/cctest/test-macro-assembler-arm.cc index 77f7abbd44..d40b8a50c0 100644 --- a/deps/v8/test/cctest/test-macro-assembler-arm.cc +++ b/deps/v8/test/cctest/test-macro-assembler-arm.cc @@ -132,5 +132,101 @@ TEST(CopyBytes) { } +typedef int (*F5)(void*, void*, void*, void*, void*); + + +TEST(LoadAndStoreWithRepresentation) { + v8::internal::V8::Initialize(NULL); + + // Allocate an executable page of memory. + size_t actual_size; + byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + &actual_size, + true)); + CHECK(buffer); + Isolate* isolate = CcTest::i_isolate(); + HandleScope handles(isolate); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. + __ sub(sp, sp, Operand(1 * kPointerSize)); + Label exit; + + // Test 1. + __ mov(r0, Operand(1)); // Test number. + __ mov(r1, Operand(0)); + __ str(r1, MemOperand(sp, 0 * kPointerSize)); + __ mov(r2, Operand(-1)); + __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::UInteger8()); + __ ldr(r3, MemOperand(sp, 0 * kPointerSize)); + __ mov(r2, Operand(255)); + __ cmp(r3, r2); + __ b(ne, &exit); + __ mov(r2, Operand(255)); + __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::UInteger8()); + __ cmp(r3, r2); + __ b(ne, &exit); + + // Test 2. + __ mov(r0, Operand(2)); // Test number. + __ mov(r1, Operand(0)); + __ str(r1, MemOperand(sp, 0 * kPointerSize)); + __ mov(r2, Operand(-1)); + __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::Integer8()); + __ ldr(r3, MemOperand(sp, 0 * kPointerSize)); + __ mov(r2, Operand(255)); + __ cmp(r3, r2); + __ b(ne, &exit); + __ mov(r2, Operand(-1)); + __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::Integer8()); + __ cmp(r3, r2); + __ b(ne, &exit); + + // Test 3. + __ mov(r0, Operand(3)); // Test number. + __ mov(r1, Operand(0)); + __ str(r1, MemOperand(sp, 0 * kPointerSize)); + __ mov(r2, Operand(-1)); + __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::UInteger16()); + __ ldr(r3, MemOperand(sp, 0 * kPointerSize)); + __ mov(r2, Operand(65535)); + __ cmp(r3, r2); + __ b(ne, &exit); + __ mov(r2, Operand(65535)); + __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::UInteger16()); + __ cmp(r3, r2); + __ b(ne, &exit); + + // Test 4. + __ mov(r0, Operand(4)); // Test number. + __ mov(r1, Operand(0)); + __ str(r1, MemOperand(sp, 0 * kPointerSize)); + __ mov(r2, Operand(-1)); + __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::Integer16()); + __ ldr(r3, MemOperand(sp, 0 * kPointerSize)); + __ mov(r2, Operand(65535)); + __ cmp(r3, r2); + __ b(ne, &exit); + __ mov(r2, Operand(-1)); + __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::Integer16()); + __ cmp(r3, r2); + __ b(ne, &exit); + + __ mov(r0, Operand(0)); // Success. + __ bind(&exit); + __ add(sp, sp, Operand(1 * kPointerSize)); + __ bx(lr); + + CodeDesc desc; + masm->GetCode(&desc); + Object* code = isolate->heap()->CreateCode( + desc, + Code::ComputeFlags(Code::STUB), + Handle<Code>())->ToObjectChecked(); + CHECK(code->IsCode()); + + // Call the function from C++. + F5 f = FUNCTION_CAST<F5>(Code::cast(code)->entry()); + CHECK_EQ(0, CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); +} #undef __ diff --git a/deps/v8/test/cctest/test-macro-assembler-ia32.cc b/deps/v8/test/cctest/test-macro-assembler-ia32.cc new file mode 100644 index 0000000000..38c738f1d0 --- /dev/null +++ b/deps/v8/test/cctest/test-macro-assembler-ia32.cc @@ -0,0 +1,139 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <stdlib.h> + +#include "v8.h" + +#include "macro-assembler.h" +#include "factory.h" +#include "platform.h" +#include "serialize.h" +#include "cctest.h" + +using namespace v8::internal; + +#if __GNUC__ +#define STDCALL __attribute__((stdcall)) +#else +#define STDCALL __stdcall +#endif + +typedef int STDCALL F0Type(); +typedef F0Type* F0; + +#define __ masm-> + + +TEST(LoadAndStoreWithRepresentation) { + v8::internal::V8::Initialize(NULL); + + // Allocate an executable page of memory. + size_t actual_size; + byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + &actual_size, + true)); + CHECK(buffer); + Isolate* isolate = CcTest::i_isolate(); + HandleScope handles(isolate); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. + __ push(ebx); + __ push(edx); + __ sub(esp, Immediate(1 * kPointerSize)); + Label exit; + + // Test 1. + __ mov(eax, Immediate(1)); // Test number. + __ mov(Operand(esp, 0 * kPointerSize), Immediate(0)); + __ mov(ebx, Immediate(-1)); + __ Store(ebx, Operand(esp, 0 * kPointerSize), Representation::UInteger8()); + __ mov(ebx, Operand(esp, 0 * kPointerSize)); + __ mov(edx, Immediate(255)); + __ cmp(ebx, edx); + __ j(not_equal, &exit); + __ Load(ebx, Operand(esp, 0 * kPointerSize), Representation::UInteger8()); + __ cmp(ebx, edx); + __ j(not_equal, &exit); + + + // Test 2. + __ mov(eax, Immediate(2)); // Test number. + __ mov(Operand(esp, 0 * kPointerSize), Immediate(0)); + __ mov(ebx, Immediate(-1)); + __ Store(ebx, Operand(esp, 0 * kPointerSize), Representation::Integer8()); + __ mov(ebx, Operand(esp, 0 * kPointerSize)); + __ mov(edx, Immediate(255)); + __ cmp(ebx, edx); + __ j(not_equal, &exit); + __ Load(ebx, Operand(esp, 0 * kPointerSize), Representation::Integer8()); + __ mov(edx, Immediate(-1)); + __ cmp(ebx, edx); + __ j(not_equal, &exit); + + // Test 3. + __ mov(eax, Immediate(3)); // Test number. + __ mov(Operand(esp, 0 * kPointerSize), Immediate(0)); + __ mov(ebx, Immediate(-1)); + __ Store(ebx, Operand(esp, 0 * kPointerSize), Representation::Integer16()); + __ mov(ebx, Operand(esp, 0 * kPointerSize)); + __ mov(edx, Immediate(65535)); + __ cmp(ebx, edx); + __ j(not_equal, &exit); + __ Load(edx, Operand(esp, 0 * kPointerSize), Representation::Integer16()); + __ mov(ebx, Immediate(-1)); + __ cmp(ebx, edx); + __ j(not_equal, &exit); + + // Test 4. + __ mov(eax, Immediate(4)); // Test number. + __ mov(Operand(esp, 0 * kPointerSize), Immediate(0)); + __ mov(ebx, Immediate(-1)); + __ Store(ebx, Operand(esp, 0 * kPointerSize), Representation::UInteger16()); + __ mov(ebx, Operand(esp, 0 * kPointerSize)); + __ mov(edx, Immediate(65535)); + __ cmp(ebx, edx); + __ j(not_equal, &exit); + __ Load(edx, Operand(esp, 0 * kPointerSize), Representation::UInteger16()); + __ cmp(ebx, edx); + __ j(not_equal, &exit); + + __ xor_(eax, eax); // Success. + __ bind(&exit); + __ add(esp, Immediate(1 * kPointerSize)); + __ pop(edx); + __ pop(ebx); + __ ret(0); + + CodeDesc desc; + masm->GetCode(&desc); + // Call the function from C++. + int result = FUNCTION_CAST<F0>(buffer)(); + CHECK_EQ(0, result); +} + +#undef __ diff --git a/deps/v8/test/cctest/test-macro-assembler-mips.cc b/deps/v8/test/cctest/test-macro-assembler-mips.cc index b200949679..3154aac596 100644 --- a/deps/v8/test/cctest/test-macro-assembler-mips.cc +++ b/deps/v8/test/cctest/test-macro-assembler-mips.cc @@ -132,5 +132,47 @@ TEST(CopyBytes) { } +static void TestNaN(const char *code) { + // NaN value is different on MIPS and x86 architectures, and TEST(NaNx) + // tests checks the case where a x86 NaN value is serialized into the + // snapshot on the simulator during cross compilation. + v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> context = CcTest::NewContext(PRINT_EXTENSION); + v8::Context::Scope context_scope(context); + + v8::Local<v8::Script> script = v8::Script::Compile(v8_str(code)); + v8::Local<v8::Object> result = v8::Local<v8::Object>::Cast(script->Run()); + // Have to populate the handle manually, as it's not Cast-able. + i::Handle<i::JSObject> o = + v8::Utils::OpenHandle<v8::Object, i::JSObject>(result); + i::Handle<i::JSArray> array1(reinterpret_cast<i::JSArray*>(*o)); + i::FixedDoubleArray* a = i::FixedDoubleArray::cast(array1->elements()); + double value = a->get_scalar(0); + CHECK(std::isnan(value) && + i::BitCast<uint64_t>(value) == + i::BitCast<uint64_t>( + i::FixedDoubleArray::canonical_not_the_hole_nan_as_double())); +} + + +TEST(NaN0) { + TestNaN( + "var result;" + "for (var i = 0; i < 2; i++) {" + " result = new Array(Number.NaN, Number.POSITIVE_INFINITY);" + "}" + "result;"); +} + + +TEST(NaN1) { + TestNaN( + "var result;" + "for (var i = 0; i < 2; i++) {" + " result = [NaN];" + "}" + "result;"); +} + #undef __ diff --git a/deps/v8/test/cctest/test-macro-assembler-x64.cc b/deps/v8/test/cctest/test-macro-assembler-x64.cc index 61914b58c3..3daed5b456 100644 --- a/deps/v8/test/cctest/test-macro-assembler-x64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-x64.cc @@ -35,50 +35,53 @@ #include "serialize.h" #include "cctest.h" -using v8::internal::Assembler; -using v8::internal::CodeDesc; -using v8::internal::Condition; -using v8::internal::FUNCTION_CAST; -using v8::internal::HandleScope; -using v8::internal::Immediate; -using v8::internal::Isolate; -using v8::internal::Label; -using v8::internal::MacroAssembler; -using v8::internal::OS; -using v8::internal::Operand; -using v8::internal::RelocInfo; -using v8::internal::Representation; -using v8::internal::Smi; -using v8::internal::SmiIndex; -using v8::internal::byte; -using v8::internal::carry; -using v8::internal::greater; -using v8::internal::greater_equal; -using v8::internal::kIntSize; -using v8::internal::kPointerSize; -using v8::internal::kSmiTagMask; -using v8::internal::kSmiValueSize; -using v8::internal::less_equal; -using v8::internal::negative; -using v8::internal::not_carry; -using v8::internal::not_equal; -using v8::internal::not_zero; -using v8::internal::positive; -using v8::internal::r11; -using v8::internal::r13; -using v8::internal::r14; -using v8::internal::r15; -using v8::internal::r8; -using v8::internal::r9; -using v8::internal::rax; -using v8::internal::rbp; -using v8::internal::rbx; -using v8::internal::rcx; -using v8::internal::rdi; -using v8::internal::rdx; -using v8::internal::rsi; -using v8::internal::rsp; -using v8::internal::times_pointer_size; +namespace i = v8::internal; +using i::Address; +using i::Assembler; +using i::CodeDesc; +using i::Condition; +using i::FUNCTION_CAST; +using i::HandleScope; +using i::Immediate; +using i::Isolate; +using i::Label; +using i::MacroAssembler; +using i::OS; +using i::Operand; +using i::RelocInfo; +using i::Representation; +using i::Smi; +using i::SmiIndex; +using i::byte; +using i::carry; +using i::greater; +using i::greater_equal; +using i::kIntSize; +using i::kPointerSize; +using i::kSmiTagMask; +using i::kSmiValueSize; +using i::less_equal; +using i::negative; +using i::not_carry; +using i::not_equal; +using i::equal; +using i::not_zero; +using i::positive; +using i::r11; +using i::r13; +using i::r14; +using i::r15; +using i::r8; +using i::r9; +using i::rax; +using i::rbp; +using i::rbx; +using i::rcx; +using i::rdi; +using i::rdx; +using i::rsi; +using i::rsp; +using i::times_pointer_size; // Test the x64 assembler by compiling some simple functions into // a buffer and executing them. These tests do not initialize the @@ -96,8 +99,8 @@ typedef int (*F0)(); static void EntryCode(MacroAssembler* masm) { // Smi constant register is callee save. - __ push(v8::internal::kSmiConstantRegister); - __ push(v8::internal::kRootRegister); + __ push(i::kSmiConstantRegister); + __ push(i::kRootRegister); __ InitializeSmiConstantRegister(); __ InitializeRootRegister(); } @@ -106,11 +109,11 @@ static void EntryCode(MacroAssembler* masm) { static void ExitCode(MacroAssembler* masm) { // Return -1 if kSmiConstantRegister was clobbered during the test. __ Move(rdx, Smi::FromInt(1)); - __ cmpq(rdx, v8::internal::kSmiConstantRegister); + __ cmpq(rdx, i::kSmiConstantRegister); __ movq(rdx, Immediate(-1)); __ cmovq(not_equal, rax, rdx); - __ pop(v8::internal::kRootRegister); - __ pop(v8::internal::kSmiConstantRegister); + __ pop(i::kRootRegister); + __ pop(i::kSmiConstantRegister); } @@ -151,7 +154,7 @@ static void TestMoveSmi(MacroAssembler* masm, Label* exit, int id, Smi* value) { // Test that we can move a Smi value literally into a register. TEST(SmiMove) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, @@ -162,7 +165,6 @@ TEST(SmiMove) { HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -239,7 +241,7 @@ void TestSmiCompare(MacroAssembler* masm, Label* exit, int id, int x, int y) { // Test that we can compare smis for equality (and more). TEST(SmiCompare) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = @@ -252,7 +254,6 @@ TEST(SmiCompare) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -291,7 +292,7 @@ TEST(SmiCompare) { TEST(Integer32ToSmi) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, @@ -303,7 +304,6 @@ TEST(Integer32ToSmi) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -402,7 +402,7 @@ void TestI64PlusConstantToSmi(MacroAssembler* masm, ASSERT(Smi::IsValid(result)); __ movl(rax, Immediate(id)); __ Move(r8, Smi::FromInt(static_cast<int>(result))); - __ movq(rcx, x, RelocInfo::NONE64); + __ movq(rcx, x); __ movq(r11, rcx); __ Integer64PlusConstantToSmi(rdx, rcx, y); __ cmpq(rdx, r8); @@ -420,7 +420,7 @@ void TestI64PlusConstantToSmi(MacroAssembler* masm, TEST(Integer64PlusConstantToSmi) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, @@ -432,7 +432,6 @@ TEST(Integer64PlusConstantToSmi) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -465,7 +464,7 @@ TEST(Integer64PlusConstantToSmi) { TEST(SmiCheck) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, @@ -477,7 +476,6 @@ TEST(SmiCheck) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; Condition cond; @@ -713,7 +711,7 @@ void TestSmiNeg(MacroAssembler* masm, Label* exit, int id, int x) { TEST(SmiNeg) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = @@ -726,7 +724,6 @@ TEST(SmiNeg) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -770,7 +767,7 @@ static void SmiAddTest(MacroAssembler* masm, __ j(not_equal, exit); __ incq(rax); - __ SmiAdd(rcx, rcx, rdx, exit); \ + __ SmiAdd(rcx, rcx, rdx, exit); __ cmpq(rcx, r8); __ j(not_equal, exit); @@ -789,13 +786,30 @@ static void SmiAddTest(MacroAssembler* masm, __ movl(rcx, Immediate(first)); __ Integer32ToSmi(rcx, rcx); + i::SmiOperationExecutionMode mode; + mode.Add(i::PRESERVE_SOURCE_REGISTER); + mode.Add(i::BAILOUT_ON_OVERFLOW); __ incq(rax); - __ SmiAddConstant(r9, rcx, Smi::FromInt(second), exit); + __ SmiAddConstant(r9, rcx, Smi::FromInt(second), mode, exit); __ cmpq(r9, r8); __ j(not_equal, exit); __ incq(rax); - __ SmiAddConstant(rcx, rcx, Smi::FromInt(second), exit); + __ SmiAddConstant(rcx, rcx, Smi::FromInt(second), mode, exit); + __ cmpq(rcx, r8); + __ j(not_equal, exit); + + __ movl(rcx, Immediate(first)); + __ Integer32ToSmi(rcx, rcx); + + mode.RemoveAll(); + mode.Add(i::PRESERVE_SOURCE_REGISTER); + mode.Add(i::BAILOUT_ON_NO_OVERFLOW); + Label done; + __ incq(rax); + __ SmiAddConstant(rcx, rcx, Smi::FromInt(second), mode, &done); + __ jmp(exit); + __ bind(&done); __ cmpq(rcx, r8); __ j(not_equal, exit); } @@ -835,11 +849,14 @@ static void SmiAddOverflowTest(MacroAssembler* masm, __ j(not_equal, exit); } + i::SmiOperationExecutionMode mode; + mode.Add(i::PRESERVE_SOURCE_REGISTER); + mode.Add(i::BAILOUT_ON_OVERFLOW); __ movq(rcx, r11); { Label overflow_ok; __ incq(rax); - __ SmiAddConstant(r9, rcx, Smi::FromInt(y_min), &overflow_ok); + __ SmiAddConstant(r9, rcx, Smi::FromInt(y_min), mode, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -850,7 +867,7 @@ static void SmiAddOverflowTest(MacroAssembler* masm, { Label overflow_ok; __ incq(rax); - __ SmiAddConstant(rcx, rcx, Smi::FromInt(y_min), &overflow_ok); + __ SmiAddConstant(rcx, rcx, Smi::FromInt(y_min), mode, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -886,7 +903,7 @@ static void SmiAddOverflowTest(MacroAssembler* masm, { Label overflow_ok; __ incq(rax); - __ SmiAddConstant(r9, rcx, Smi::FromInt(y_max), &overflow_ok); + __ SmiAddConstant(r9, rcx, Smi::FromInt(y_max), mode, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -894,25 +911,27 @@ static void SmiAddOverflowTest(MacroAssembler* masm, __ j(not_equal, exit); } + mode.RemoveAll(); + mode.Add(i::BAILOUT_ON_OVERFLOW); { Label overflow_ok; __ incq(rax); - __ SmiAddConstant(rcx, rcx, Smi::FromInt(y_max), &overflow_ok); + __ SmiAddConstant(rcx, rcx, Smi::FromInt(y_max), mode, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); __ cmpq(rcx, r11); - __ j(not_equal, exit); + __ j(equal, exit); } } TEST(SmiAdd) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = - static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, + static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 3, &actual_size, true)); CHECK(buffer); @@ -921,7 +940,6 @@ TEST(SmiAdd) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -987,15 +1005,30 @@ static void SmiSubTest(MacroAssembler* masm, __ cmpq(rcx, r8); __ j(not_equal, exit); + i::SmiOperationExecutionMode mode; + mode.Add(i::PRESERVE_SOURCE_REGISTER); + mode.Add(i::BAILOUT_ON_OVERFLOW); __ Move(rcx, Smi::FromInt(first)); - __ incq(rax); // Test 4. - __ SmiSubConstant(r9, rcx, Smi::FromInt(second), exit); - __ cmpq(r9, r8); + __ SmiSubConstant(rcx, rcx, Smi::FromInt(second), mode, exit); + __ cmpq(rcx, r8); __ j(not_equal, exit); + __ Move(rcx, Smi::FromInt(first)); __ incq(rax); // Test 5. - __ SmiSubConstant(rcx, rcx, Smi::FromInt(second), exit); + __ SmiSubConstant(r9, rcx, Smi::FromInt(second), mode, exit); + __ cmpq(r9, r8); + __ j(not_equal, exit); + + mode.RemoveAll(); + mode.Add(i::PRESERVE_SOURCE_REGISTER); + mode.Add(i::BAILOUT_ON_NO_OVERFLOW); + __ Move(rcx, Smi::FromInt(first)); + Label done; + __ incq(rax); // Test 6. + __ SmiSubConstant(rcx, rcx, Smi::FromInt(second), mode, &done); + __ jmp(exit); + __ bind(&done); __ cmpq(rcx, r8); __ j(not_equal, exit); } @@ -1035,11 +1068,15 @@ static void SmiSubOverflowTest(MacroAssembler* masm, __ j(not_equal, exit); } + i::SmiOperationExecutionMode mode; + mode.Add(i::PRESERVE_SOURCE_REGISTER); + mode.Add(i::BAILOUT_ON_OVERFLOW); + __ movq(rcx, r11); { Label overflow_ok; __ incq(rax); - __ SmiSubConstant(r9, rcx, Smi::FromInt(y_min), &overflow_ok); + __ SmiSubConstant(r9, rcx, Smi::FromInt(y_min), mode, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -1050,7 +1087,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm, { Label overflow_ok; __ incq(rax); - __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_min), &overflow_ok); + __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_min), mode, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -1086,7 +1123,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm, { Label overflow_ok; __ incq(rax); - __ SmiSubConstant(r9, rcx, Smi::FromInt(y_max), &overflow_ok); + __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_max), mode, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -1094,25 +1131,28 @@ static void SmiSubOverflowTest(MacroAssembler* masm, __ j(not_equal, exit); } + mode.RemoveAll(); + mode.Add(i::BAILOUT_ON_OVERFLOW); + __ movq(rcx, r11); { Label overflow_ok; __ incq(rax); - __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_max), &overflow_ok); + __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_max), mode, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); __ cmpq(rcx, r11); - __ j(not_equal, exit); + __ j(equal, exit); } } TEST(SmiSub) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = - static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, + static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 4, &actual_size, true)); CHECK(buffer); @@ -1121,7 +1161,6 @@ TEST(SmiSub) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -1200,7 +1239,7 @@ void TestSmiMul(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiMul) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, @@ -1212,7 +1251,6 @@ TEST(SmiMul) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -1306,7 +1344,7 @@ void TestSmiDiv(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiDiv) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = @@ -1319,7 +1357,6 @@ TEST(SmiDiv) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -1417,7 +1454,7 @@ void TestSmiMod(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiMod) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = @@ -1430,7 +1467,6 @@ TEST(SmiMod) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -1515,11 +1551,11 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) { TEST(SmiIndex) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = - static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 3, + static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 5, &actual_size, true)); CHECK(buffer); @@ -1528,7 +1564,6 @@ TEST(SmiIndex) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -1585,11 +1620,11 @@ void TestSelectNonSmi(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiSelectNonSmi) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = - static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, &actual_size, true)); CHECK(buffer); @@ -1598,7 +1633,6 @@ TEST(SmiSelectNonSmi) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); // Avoid inline checks. EntryCode(masm); Label exit; @@ -1665,11 +1699,11 @@ void TestSmiAnd(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiAnd) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = - static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, &actual_size, true)); CHECK(buffer); @@ -1678,7 +1712,6 @@ TEST(SmiAnd) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -1747,11 +1780,11 @@ void TestSmiOr(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiOr) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = - static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, &actual_size, true)); CHECK(buffer); @@ -1760,7 +1793,6 @@ TEST(SmiOr) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -1831,11 +1863,11 @@ void TestSmiXor(MacroAssembler* masm, Label* exit, int id, int x, int y) { TEST(SmiXor) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = - static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, + static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, &actual_size, true)); CHECK(buffer); @@ -1844,7 +1876,6 @@ TEST(SmiXor) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -1899,7 +1930,7 @@ void TestSmiNot(MacroAssembler* masm, Label* exit, int id, int x) { TEST(SmiNot) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = @@ -1912,7 +1943,6 @@ TEST(SmiNot) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -1996,11 +2026,11 @@ void TestSmiShiftLeft(MacroAssembler* masm, Label* exit, int id, int x) { TEST(SmiShiftLeft) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = - static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 4, + static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 7, &actual_size, true)); CHECK(buffer); @@ -2009,7 +2039,6 @@ TEST(SmiShiftLeft) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -2103,11 +2132,11 @@ void TestSmiShiftLogicalRight(MacroAssembler* masm, TEST(SmiShiftLogicalRight) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = - static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 3, + static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 5, &actual_size, true)); CHECK(buffer); @@ -2116,7 +2145,6 @@ TEST(SmiShiftLogicalRight) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -2173,11 +2201,11 @@ void TestSmiShiftArithmeticRight(MacroAssembler* masm, TEST(SmiShiftArithmeticRight) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = - static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, + static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 3, &actual_size, true)); CHECK(buffer); @@ -2186,7 +2214,6 @@ TEST(SmiShiftArithmeticRight) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -2238,7 +2265,7 @@ void TestPositiveSmiPowerUp(MacroAssembler* masm, Label* exit, int id, int x) { TEST(PositiveSmiTimesPowerOfTwoToInteger64) { - v8::internal::V8::Initialize(NULL); + i::V8::Initialize(NULL); // Allocate an executable page of memory. size_t actual_size; byte* buffer = @@ -2251,7 +2278,6 @@ TEST(PositiveSmiTimesPowerOfTwoToInteger64) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); EntryCode(masm); Label exit; @@ -2279,9 +2305,9 @@ TEST(PositiveSmiTimesPowerOfTwoToInteger64) { TEST(OperandOffset) { - v8::internal::V8::Initialize(NULL); - int data[256]; - for (int i = 0; i < 256; i++) { data[i] = i * 0x01010101; } + i::V8::Initialize(NULL); + uint32_t data[256]; + for (uint32_t i = 0; i < 256; i++) { data[i] = i * 0x01010101; } // Allocate an executable page of memory. size_t actual_size; @@ -2295,7 +2321,6 @@ TEST(OperandOffset) { MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; - masm->set_allow_stub_calls(false); Label exit; EntryCode(masm); @@ -2322,7 +2347,7 @@ TEST(OperandOffset) { __ lea(r13, Operand(rbp, -3 * kPointerSize)); __ lea(rbx, Operand(rbp, -5 * kPointerSize)); __ movl(rcx, Immediate(2)); - __ movq(r8, reinterpret_cast<uintptr_t>(&data[128]), RelocInfo::NONE64); + __ Move(r8, reinterpret_cast<Address>(&data[128]), RelocInfo::NONE64); __ movl(rax, Immediate(1)); Operand sp0 = Operand(rsp, 0); @@ -2648,7 +2673,6 @@ TEST(LoadAndStoreWithRepresentation) { HandleScope handles(isolate); MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. - masm->set_allow_stub_calls(false); EntryCode(masm); __ subq(rsp, Immediate(1 * kPointerSize)); Label exit; @@ -2657,12 +2681,12 @@ TEST(LoadAndStoreWithRepresentation) { __ movq(rax, Immediate(1)); // Test number. __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); __ movq(rcx, Immediate(-1)); - __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Byte()); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::UInteger8()); __ movq(rcx, Operand(rsp, 0 * kPointerSize)); __ movl(rdx, Immediate(255)); __ cmpq(rcx, rdx); __ j(not_equal, &exit); - __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Byte()); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::UInteger8()); __ cmpq(rcx, rdx); __ j(not_equal, &exit); @@ -2731,6 +2755,47 @@ TEST(LoadAndStoreWithRepresentation) { __ cmpq(rcx, rdx); __ j(not_equal, &exit); + // Test 7. + __ movq(rax, Immediate(7)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ movq(rcx, Immediate(-1)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Integer8()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ movl(rdx, Immediate(255)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Integer8()); + __ movq(rcx, Immediate(-1)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + // Test 8. + __ movq(rax, Immediate(8)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ movq(rcx, Immediate(-1)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Integer16()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ movl(rdx, Immediate(65535)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Integer16()); + __ movq(rcx, Immediate(-1)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + // Test 9. + __ movq(rax, Immediate(9)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ movq(rcx, Immediate(-1)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::UInteger16()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ movl(rdx, Immediate(65535)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::UInteger16()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ xor_(rax, rax); // Success. __ bind(&exit); __ addq(rsp, Immediate(1 * kPointerSize)); diff --git a/deps/v8/test/cctest/test-mark-compact.cc b/deps/v8/test/cctest/test-mark-compact.cc index e62bdeb074..9e09051305 100644 --- a/deps/v8/test/cctest/test-mark-compact.cc +++ b/deps/v8/test/cctest/test-mark-compact.cc @@ -35,6 +35,7 @@ #include <errno.h> #endif +#include <utility> #include "v8.h" @@ -81,7 +82,7 @@ TEST(Promotion) { // Allocate a fixed array in the new space. int array_length = - (Page::kMaxNonCodeHeapObjectSize - FixedArray::kHeaderSize) / + (Page::kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) / (4 * kPointerSize); Object* obj = heap->AllocateFixedArray(array_length)->ToObjectChecked(); Handle<FixedArray> array(FixedArray::cast(obj)); @@ -106,7 +107,7 @@ TEST(NoPromotion) { // Allocate a big fixed array in the new space. int array_length = - (Page::kMaxNonCodeHeapObjectSize - FixedArray::kHeaderSize) / + (Page::kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) / (2 * kPointerSize); Object* obj = heap->AllocateFixedArray(array_length)->ToObjectChecked(); Handle<FixedArray> array(FixedArray::cast(obj)); @@ -245,12 +246,14 @@ TEST(MapCompact) { static int NumberOfWeakCalls = 0; -static void WeakPointerCallback(v8::Isolate* isolate, - v8::Persistent<v8::Value>* handle, - void* id) { - ASSERT(id == reinterpret_cast<void*>(1234)); +static void WeakPointerCallback( + const v8::WeakCallbackData<v8::Value, void>& data) { + std::pair<v8::Persistent<v8::Value>*, int>* p = + reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>( + data.GetParameter()); + ASSERT_EQ(1234, p->second); NumberOfWeakCalls++; - handle->Dispose(); + p->first->Reset(); } @@ -268,15 +271,18 @@ TEST(ObjectGroups) { global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g1c1 = global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); - global_handles->MakeWeak(g1s1.location(), - reinterpret_cast<void*>(1234), - &WeakPointerCallback); - global_handles->MakeWeak(g1s2.location(), - reinterpret_cast<void*>(1234), - &WeakPointerCallback); - global_handles->MakeWeak(g1c1.location(), - reinterpret_cast<void*>(1234), - &WeakPointerCallback); + std::pair<Handle<Object>*, int> g1s1_and_id(&g1s1, 1234); + GlobalHandles::MakeWeak(g1s1.location(), + reinterpret_cast<void*>(&g1s1_and_id), + &WeakPointerCallback); + std::pair<Handle<Object>*, int> g1s2_and_id(&g1s2, 1234); + GlobalHandles::MakeWeak(g1s2.location(), + reinterpret_cast<void*>(&g1s2_and_id), + &WeakPointerCallback); + std::pair<Handle<Object>*, int> g1c1_and_id(&g1c1, 1234); + GlobalHandles::MakeWeak(g1c1.location(), + reinterpret_cast<void*>(&g1c1_and_id), + &WeakPointerCallback); Handle<Object> g2s1 = global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); @@ -284,15 +290,18 @@ TEST(ObjectGroups) { global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); Handle<Object> g2c1 = global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); - global_handles->MakeWeak(g2s1.location(), - reinterpret_cast<void*>(1234), - &WeakPointerCallback); - global_handles->MakeWeak(g2s2.location(), - reinterpret_cast<void*>(1234), - &WeakPointerCallback); - global_handles->MakeWeak(g2c1.location(), - reinterpret_cast<void*>(1234), - &WeakPointerCallback); + std::pair<Handle<Object>*, int> g2s1_and_id(&g2s1, 1234); + GlobalHandles::MakeWeak(g2s1.location(), + reinterpret_cast<void*>(&g2s1_and_id), + &WeakPointerCallback); + std::pair<Handle<Object>*, int> g2s2_and_id(&g2s2, 1234); + GlobalHandles::MakeWeak(g2s2.location(), + reinterpret_cast<void*>(&g2s2_and_id), + &WeakPointerCallback); + std::pair<Handle<Object>*, int> g2c1_and_id(&g2c1, 1234); + GlobalHandles::MakeWeak(g2c1.location(), + reinterpret_cast<void*>(&g2c1_and_id), + &WeakPointerCallback); Handle<Object> root = global_handles->Create(*g1s1); // make a root. @@ -319,9 +328,10 @@ TEST(ObjectGroups) { CHECK_EQ(0, NumberOfWeakCalls); // Weaken the root. - global_handles->MakeWeak(root.location(), - reinterpret_cast<void*>(1234), - &WeakPointerCallback); + std::pair<Handle<Object>*, int> root_and_id(&root, 1234); + GlobalHandles::MakeWeak(root.location(), + reinterpret_cast<void*>(&root_and_id), + &WeakPointerCallback); // But make children strong roots---all the objects (except for children) // should be collectable now. global_handles->ClearWeakness(g1c1.location()); @@ -347,12 +357,12 @@ TEST(ObjectGroups) { CHECK_EQ(5, NumberOfWeakCalls); // And now make children weak again and collect them. - global_handles->MakeWeak(g1c1.location(), - reinterpret_cast<void*>(1234), - &WeakPointerCallback); - global_handles->MakeWeak(g2c1.location(), - reinterpret_cast<void*>(1234), - &WeakPointerCallback); + GlobalHandles::MakeWeak(g1c1.location(), + reinterpret_cast<void*>(&g1c1_and_id), + &WeakPointerCallback); + GlobalHandles::MakeWeak(g2c1.location(), + reinterpret_cast<void*>(&g2c1_and_id), + &WeakPointerCallback); heap->CollectGarbage(OLD_POINTER_SPACE); CHECK_EQ(7, NumberOfWeakCalls); @@ -486,6 +496,7 @@ TEST(BootUpMemoryUse) { intptr_t initial_memory = MemoryInUse(); // Avoid flakiness. FLAG_crankshaft = false; + FLAG_concurrent_osr = false; FLAG_concurrent_recompilation = false; // Only Linux has the proc filesystem and only if it is mapped. If it's not diff --git a/deps/v8/test/cctest/test-mementos.cc b/deps/v8/test/cctest/test-mementos.cc new file mode 100644 index 0000000000..9662effa50 --- /dev/null +++ b/deps/v8/test/cctest/test-mementos.cc @@ -0,0 +1,79 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "cctest.h" + +using namespace v8::internal; + + +static void SetUpNewSpaceWithPoisonedMementoAtTop() { + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + NewSpace* new_space = heap->new_space(); + + // Make sure we can allocate some objects without causing a GC later. + heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + + // Allocate a string, the GC may suspect a memento behind the string. + Handle<SeqOneByteString> string = isolate->factory()->NewRawOneByteString(12); + CHECK(*string); + + // Create an allocation memento behind the string with a garbage allocation + // site pointer. + AllocationMemento* memento = + reinterpret_cast<AllocationMemento*>(new_space->top() + kHeapObjectTag); + memento->set_map_no_write_barrier(heap->allocation_memento_map()); + memento->set_allocation_site( + reinterpret_cast<AllocationSite*>(kHeapObjectTag), SKIP_WRITE_BARRIER); +} + + +TEST(Regress340063) { + CcTest::InitializeVM(); + if (!i::FLAG_allocation_site_pretenuring) return; + v8::HandleScope scope(CcTest::isolate()); + + + SetUpNewSpaceWithPoisonedMementoAtTop(); + + // Call GC to see if we can handle a poisonous memento right after the + // current new space top pointer. + CcTest::i_isolate()->heap()->CollectAllGarbage( + Heap::kAbortIncrementalMarkingMask); +} + + +TEST(BadMementoAfterTopForceScavenge) { + CcTest::InitializeVM(); + if (!i::FLAG_allocation_site_pretenuring) return; + v8::HandleScope scope(CcTest::isolate()); + + SetUpNewSpaceWithPoisonedMementoAtTop(); + + // Force GC to test the poisoned memento handling + CcTest::i_isolate()->heap()->CollectGarbage(i::NEW_SPACE); +} diff --git a/deps/v8/test/cctest/test-microtask-delivery.cc b/deps/v8/test/cctest/test-microtask-delivery.cc new file mode 100644 index 0000000000..4db760dd39 --- /dev/null +++ b/deps/v8/test/cctest/test-microtask-delivery.cc @@ -0,0 +1,137 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "v8.h" + +#include "cctest.h" + +using namespace v8; +namespace i = v8::internal; + +namespace { +class HarmonyIsolate { + public: + HarmonyIsolate() { + i::FLAG_harmony_observation = true; + i::FLAG_harmony_promises = true; + isolate_ = Isolate::New(); + isolate_->Enter(); + } + + ~HarmonyIsolate() { + isolate_->Exit(); + isolate_->Dispose(); + } + + Isolate* GetIsolate() const { return isolate_; } + + private: + Isolate* isolate_; +}; +} + + +TEST(MicrotaskDeliverySimple) { + HarmonyIsolate isolate; + HandleScope scope(isolate.GetIsolate()); + LocalContext context(isolate.GetIsolate()); + CompileRun( + "var ordering = [];" + "var resolver = {};" + "function handler(resolve) { resolver.resolve = resolve; }" + "var obj = {};" + "var observeOrders = [1, 4];" + "function observer() {" + "ordering.push(observeOrders.shift());" + "resolver.resolve();" + "}" + "var p = new Promise(handler);" + "p.then(function() {" + "ordering.push(2);" + "}).then(function() {" + "ordering.push(3);" + "obj.id++;" + "return new Promise(handler);" + "}).then(function() {" + "ordering.push(5);" + "}).then(function() {" + "ordering.push(6);" + "});" + "Object.observe(obj, observer);" + "obj.id = 1;"); + CHECK_EQ(6, CompileRun("ordering.length")->Int32Value()); + CHECK_EQ(1, CompileRun("ordering[0]")->Int32Value()); + CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); + CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value()); + CHECK_EQ(4, CompileRun("ordering[3]")->Int32Value()); + CHECK_EQ(5, CompileRun("ordering[4]")->Int32Value()); + CHECK_EQ(6, CompileRun("ordering[5]")->Int32Value()); +} + + +TEST(MicrotaskPerIsolateState) { + HarmonyIsolate isolate; + HandleScope scope(isolate.GetIsolate()); + LocalContext context1(isolate.GetIsolate()); + V8::SetAutorunMicrotasks(isolate.GetIsolate(), false); + CompileRun( + "var obj = { calls: 0 };"); + Handle<Value> obj = CompileRun("obj"); + { + LocalContext context2(isolate.GetIsolate()); + context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), + obj); + CompileRun( + "var resolver = {};" + "new Promise(function(resolve) {" + "resolver.resolve = resolve;" + "}).then(function() {" + "obj.calls++;" + "});" + "(function() {" + "resolver.resolve();" + "})();"); + } + { + LocalContext context3(isolate.GetIsolate()); + context3->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), + obj); + CompileRun( + "var foo = { id: 1 };" + "Object.observe(foo, function() {" + "obj.calls++;" + "});" + "foo.id++;"); + } + { + LocalContext context4(isolate.GetIsolate()); + context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), + obj); + V8::RunMicrotasks(isolate.GetIsolate()); + CHECK_EQ(2, CompileRun("obj.calls")->Int32Value()); + } +} diff --git a/deps/v8/test/cctest/test-object-observe.cc b/deps/v8/test/cctest/test-object-observe.cc index b4488a603a..0a30d4e275 100644 --- a/deps/v8/test/cctest/test-object-observe.cc +++ b/deps/v8/test/cctest/test-object-observe.cc @@ -72,23 +72,29 @@ TEST(PerIsolateState) { Handle<Value> notify_fun2; { LocalContext context2(isolate.GetIsolate()); - context2->Global()->Set(String::New("obj"), obj); + context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), + obj); notify_fun2 = CompileRun( "(function() { obj.foo = 'baz'; })"); } Handle<Value> notify_fun3; { LocalContext context3(isolate.GetIsolate()); - context3->Global()->Set(String::New("obj"), obj); + context3->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), + obj); notify_fun3 = CompileRun( "(function() { obj.foo = 'bat'; })"); } { LocalContext context4(isolate.GetIsolate()); - context4->Global()->Set(String::New("observer"), observer); - context4->Global()->Set(String::New("fun1"), notify_fun1); - context4->Global()->Set(String::New("fun2"), notify_fun2); - context4->Global()->Set(String::New("fun3"), notify_fun3); + context4->Global()->Set( + String::NewFromUtf8(isolate.GetIsolate(), "observer"), observer); + context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "fun1"), + notify_fun1); + context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "fun2"), + notify_fun2); + context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "fun3"), + notify_fun3); CompileRun("fun1(); fun2(); fun3(); Object.deliverChangeRecords(observer)"); } CHECK_EQ(1, CompileRun("calls")->Int32Value()); @@ -211,8 +217,10 @@ TEST(ObjectHashTableGrowth) { { // As does initializing this context. LocalContext context2(isolate.GetIsolate()); - context2->Global()->Set(String::New("obj"), obj); - context2->Global()->Set(String::New("observer"), observer); + context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), + obj); + context2->Global()->Set( + String::NewFromUtf8(isolate.GetIsolate(), "observer"), observer); CompileRun( "var objArr = [];" // 100 objects should be enough to make the hash table grow @@ -234,7 +242,6 @@ TEST(GlobalObjectObservation) { LocalContext context(isolate.GetIsolate()); HandleScope scope(isolate.GetIsolate()); Handle<Object> global_proxy = context->Global(); - Handle<Object> inner_global = global_proxy->GetPrototype().As<Object>(); CompileRun( "var records = [];" "var global = this;" @@ -247,33 +254,26 @@ TEST(GlobalObjectObservation) { context->DetachGlobal(); CompileRun("global.bar = 'goodbye';"); CHECK_EQ(1, CompileRun("records.length")->Int32Value()); - - // Mutating the global object directly still has an effect... - CompileRun("this.bar = 'goodbye';"); - CHECK_EQ(2, CompileRun("records.length")->Int32Value()); - CHECK(inner_global->StrictEquals(CompileRun("records[1].object"))); - - // Reattached, back to global proxy. - context->ReattachGlobal(global_proxy); - CompileRun("global.baz = 'again';"); - CHECK_EQ(3, CompileRun("records.length")->Int32Value()); - CHECK(global_proxy->StrictEquals(CompileRun("records[2].object"))); + CompileRun("this.baz = 'goodbye';"); + CHECK_EQ(1, CompileRun("records.length")->Int32Value()); // Attached to a different context, should not leak mutations // to the old context. context->DetachGlobal(); { LocalContext context2(isolate.GetIsolate()); - context2->DetachGlobal(); - context2->ReattachGlobal(global_proxy); CompileRun( "var records2 = [];" + "var global = this;" "Object.observe(this, function(r) { [].push.apply(records2, r) });" - "this.bat = 'context2';"); + "this.v1 = 'context2';"); + context2->DetachGlobal(); + CompileRun( + "global.v2 = 'context2';" + "this.v3 = 'context2';"); CHECK_EQ(1, CompileRun("records2.length")->Int32Value()); - CHECK(global_proxy->StrictEquals(CompileRun("records2[0].object"))); } - CHECK_EQ(3, CompileRun("records.length")->Int32Value()); + CHECK_EQ(1, CompileRun("records.length")->Int32Value()); // Attaching by passing to Context::New { @@ -287,7 +287,7 @@ TEST(GlobalObjectObservation) { CHECK_EQ(1, CompileRun("records3.length")->Int32Value()); CHECK(global_proxy->StrictEquals(CompileRun("records3[0].object"))); } - CHECK_EQ(3, CompileRun("records.length")->Int32Value()); + CHECK_EQ(1, CompileRun("records.length")->Int32Value()); } @@ -300,7 +300,8 @@ struct RecordExpectation { // TODO(adamk): Use this helper elsewhere in this file. -static void ExpectRecords(Handle<Value> records, +static void ExpectRecords(v8::Isolate* isolate, + Handle<Value> records, const RecordExpectation expectations[], int num) { CHECK(records->IsArray()); @@ -311,62 +312,67 @@ static void ExpectRecords(Handle<Value> records, CHECK(record->IsObject()); Handle<Object> recordObj = record.As<Object>(); CHECK(expectations[i].object->StrictEquals( - recordObj->Get(String::New("object")))); - CHECK(String::New(expectations[i].type)->Equals( - recordObj->Get(String::New("type")))); + recordObj->Get(String::NewFromUtf8(isolate, "object")))); + CHECK(String::NewFromUtf8(isolate, expectations[i].type)->Equals( + recordObj->Get(String::NewFromUtf8(isolate, "type")))); if (strcmp("splice", expectations[i].type) != 0) { - CHECK(String::New(expectations[i].name)->Equals( - recordObj->Get(String::New("name")))); + CHECK(String::NewFromUtf8(isolate, expectations[i].name)->Equals( + recordObj->Get(String::NewFromUtf8(isolate, "name")))); if (!expectations[i].old_value.IsEmpty()) { CHECK(expectations[i].old_value->Equals( - recordObj->Get(String::New("oldValue")))); + recordObj->Get(String::NewFromUtf8(isolate, "oldValue")))); } } } } -#define EXPECT_RECORDS(records, expectations) \ - ExpectRecords(records, expectations, ARRAY_SIZE(expectations)) +#define EXPECT_RECORDS(records, expectations) \ + ExpectRecords(isolate.GetIsolate(), records, expectations, \ + ARRAY_SIZE(expectations)) TEST(APITestBasicMutation) { HarmonyIsolate isolate; - HandleScope scope(isolate.GetIsolate()); - LocalContext context(isolate.GetIsolate()); + v8::Isolate* v8_isolate = isolate.GetIsolate(); + HandleScope scope(v8_isolate); + LocalContext context(v8_isolate); Handle<Object> obj = Handle<Object>::Cast(CompileRun( "var records = [];" "var obj = {};" "function observer(r) { [].push.apply(records, r); };" "Object.observe(obj, observer);" "obj")); - obj->Set(String::New("foo"), Number::New(7)); - obj->Set(1, Number::New(2)); + obj->Set(String::NewFromUtf8(v8_isolate, "foo"), + Number::New(v8_isolate, 7)); + obj->Set(1, Number::New(v8_isolate, 2)); // ForceSet should work just as well as Set - obj->ForceSet(String::New("foo"), Number::New(3)); - obj->ForceSet(Number::New(1), Number::New(4)); + obj->ForceSet(String::NewFromUtf8(v8_isolate, "foo"), + Number::New(v8_isolate, 3)); + obj->ForceSet(Number::New(v8_isolate, 1), Number::New(v8_isolate, 4)); // Setting an indexed element via the property setting method - obj->Set(Number::New(1), Number::New(5)); + obj->Set(Number::New(v8_isolate, 1), Number::New(v8_isolate, 5)); // Setting with a non-String, non-uint32 key - obj->Set(Number::New(1.1), Number::New(6), DontDelete); - obj->Delete(String::New("foo")); + obj->Set(Number::New(v8_isolate, 1.1), + Number::New(v8_isolate, 6), DontDelete); + obj->Delete(String::NewFromUtf8(v8_isolate, "foo")); obj->Delete(1); - obj->ForceDelete(Number::New(1.1)); + obj->ForceDelete(Number::New(v8_isolate, 1.1)); // Force delivery // TODO(adamk): Should the above set methods trigger delivery themselves? CompileRun("void 0"); CHECK_EQ(9, CompileRun("records.length")->Int32Value()); const RecordExpectation expected_records[] = { - { obj, "new", "foo", Handle<Value>() }, - { obj, "new", "1", Handle<Value>() }, + { obj, "add", "foo", Handle<Value>() }, + { obj, "add", "1", Handle<Value>() }, // Note: use 7 not 1 below, as the latter triggers a nifty VS10 compiler bug // where instead of 1.0, a garbage value would be passed into Number::New. - { obj, "updated", "foo", Number::New(7) }, - { obj, "updated", "1", Number::New(2) }, - { obj, "updated", "1", Number::New(4) }, - { obj, "new", "1.1", Handle<Value>() }, - { obj, "deleted", "foo", Number::New(3) }, - { obj, "deleted", "1", Number::New(5) }, - { obj, "deleted", "1.1", Number::New(6) } + { obj, "update", "foo", Number::New(v8_isolate, 7) }, + { obj, "update", "1", Number::New(v8_isolate, 2) }, + { obj, "update", "1", Number::New(v8_isolate, 4) }, + { obj, "add", "1.1", Handle<Value>() }, + { obj, "delete", "foo", Number::New(v8_isolate, 3) }, + { obj, "delete", "1", Number::New(v8_isolate, 5) }, + { obj, "delete", "1.1", Number::New(v8_isolate, 6) } }; EXPECT_RECORDS(CompileRun("records"), expected_records); } @@ -374,16 +380,19 @@ TEST(APITestBasicMutation) { TEST(HiddenPrototypeObservation) { HarmonyIsolate isolate; - HandleScope scope(isolate.GetIsolate()); - LocalContext context(isolate.GetIsolate()); - Handle<FunctionTemplate> tmpl = FunctionTemplate::New(); + v8::Isolate* v8_isolate = isolate.GetIsolate(); + HandleScope scope(v8_isolate); + LocalContext context(v8_isolate); + Handle<FunctionTemplate> tmpl = FunctionTemplate::New(v8_isolate); tmpl->SetHiddenPrototype(true); - tmpl->InstanceTemplate()->Set(String::New("foo"), Number::New(75)); + tmpl->InstanceTemplate()->Set( + String::NewFromUtf8(v8_isolate, "foo"), Number::New(v8_isolate, 75)); Handle<Object> proto = tmpl->GetFunction()->NewInstance(); - Handle<Object> obj = Object::New(); + Handle<Object> obj = Object::New(v8_isolate); obj->SetPrototype(proto); - context->Global()->Set(String::New("obj"), obj); - context->Global()->Set(String::New("proto"), proto); + context->Global()->Set(String::NewFromUtf8(v8_isolate, "obj"), obj); + context->Global()->Set(String::NewFromUtf8(v8_isolate, "proto"), + proto); CompileRun( "var records;" "function observer(r) { records = r; };" @@ -391,13 +400,13 @@ TEST(HiddenPrototypeObservation) { "obj.foo = 41;" // triggers a notification "proto.foo = 42;"); // does not trigger a notification const RecordExpectation expected_records[] = { - { obj, "updated", "foo", Number::New(75) } + { obj, "update", "foo", Number::New(v8_isolate, 75) } }; EXPECT_RECORDS(CompileRun("records"), expected_records); - obj->SetPrototype(Null(isolate.GetIsolate())); + obj->SetPrototype(Null(v8_isolate)); CompileRun("obj.foo = 43"); const RecordExpectation expected_records2[] = { - { obj, "new", "foo", Handle<Value>() } + { obj, "add", "foo", Handle<Value>() } }; EXPECT_RECORDS(CompileRun("records"), expected_records2); obj->SetPrototype(proto); @@ -407,10 +416,10 @@ TEST(HiddenPrototypeObservation) { "Object.unobserve(obj, observer);" "obj.foo = 44;"); const RecordExpectation expected_records3[] = { - { proto, "new", "bar", Handle<Value>() } + { proto, "add", "bar", Handle<Value>() } // TODO(adamk): The below record should be emitted since proto is observed // and has been modified. Not clear if this happens in practice. - // { proto, "updated", "foo", Number::New(43) } + // { proto, "update", "foo", Number::New(43) } }; EXPECT_RECORDS(CompileRun("records"), expected_records3); } @@ -504,15 +513,16 @@ static bool BlockAccessKeys(Local<Object> host, Local<Value> key, static Handle<Object> CreateAccessCheckedObject( + v8::Isolate* isolate, NamedSecurityCallback namedCallback, IndexedSecurityCallback indexedCallback, Handle<Value> data = Handle<Value>()) { - Handle<ObjectTemplate> tmpl = ObjectTemplate::New(); + Handle<ObjectTemplate> tmpl = ObjectTemplate::New(isolate); tmpl->SetAccessCheckCallbacks(namedCallback, indexedCallback, data); Handle<Object> instance = tmpl->NewInstance(); Handle<Object> global = instance->CreationContext()->Global(); - global->Set(String::New("obj"), instance); - global->Set(kBlockedContextIndex, v8::True()); + global->Set(String::NewFromUtf8(isolate, "obj"), instance); + global->Set(kBlockedContextIndex, v8::True(isolate)); return instance; } @@ -525,9 +535,10 @@ TEST(NamedAccessCheck) { LocalContext context(isolate.GetIsolate()); g_access_block_type = types[i]; Handle<Object> instance = CreateAccessCheckedObject( + isolate.GetIsolate(), NamedAccessAllowUnlessBlocked, IndexedAccessAlwaysAllowed, - String::New("foo")); + String::NewFromUtf8(isolate.GetIsolate(), "foo")); CompileRun("var records = null;" "var objNoCheck = {};" "var observer = function(r) { records = r };" @@ -536,8 +547,11 @@ TEST(NamedAccessCheck) { Handle<Value> obj_no_check = CompileRun("objNoCheck"); { LocalContext context2(isolate.GetIsolate()); - context2->Global()->Set(String::New("obj"), instance); - context2->Global()->Set(String::New("objNoCheck"), obj_no_check); + context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), + instance); + context2->Global()->Set( + String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"), + obj_no_check); CompileRun("var records2 = null;" "var observer2 = function(r) { records2 = r };" "Object.observe(obj, observer2);" @@ -548,17 +562,19 @@ TEST(NamedAccessCheck) { "obj.bar = 'baz';" "objNoCheck.baz = 'quux'"); const RecordExpectation expected_records2[] = { - { instance, "new", "foo", Handle<Value>() }, - { instance, "updated", "foo", String::New("bar") }, - { instance, "reconfigured", "foo", Number::New(5) }, - { instance, "new", "bar", Handle<Value>() }, - { obj_no_check, "new", "baz", Handle<Value>() }, + { instance, "add", "foo", Handle<Value>() }, + { instance, "update", "foo", + String::NewFromUtf8(isolate.GetIsolate(), "bar") }, + { instance, "reconfigure", "foo", + Number::New(isolate.GetIsolate(), 5) }, + { instance, "add", "bar", Handle<Value>() }, + { obj_no_check, "add", "baz", Handle<Value>() }, }; EXPECT_RECORDS(CompileRun("records2"), expected_records2); } const RecordExpectation expected_records[] = { - { instance, "new", "bar", Handle<Value>() }, - { obj_no_check, "new", "baz", Handle<Value>() } + { instance, "add", "bar", Handle<Value>() }, + { obj_no_check, "add", "baz", Handle<Value>() } }; EXPECT_RECORDS(CompileRun("records"), expected_records); } @@ -573,8 +589,8 @@ TEST(IndexedAccessCheck) { LocalContext context(isolate.GetIsolate()); g_access_block_type = types[i]; Handle<Object> instance = CreateAccessCheckedObject( - NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked, - Number::New(7)); + isolate.GetIsolate(), NamedAccessAlwaysAllowed, + IndexedAccessAllowUnlessBlocked, Number::New(isolate.GetIsolate(), 7)); CompileRun("var records = null;" "var objNoCheck = {};" "var observer = function(r) { records = r };" @@ -583,8 +599,11 @@ TEST(IndexedAccessCheck) { Handle<Value> obj_no_check = CompileRun("objNoCheck"); { LocalContext context2(isolate.GetIsolate()); - context2->Global()->Set(String::New("obj"), instance); - context2->Global()->Set(String::New("objNoCheck"), obj_no_check); + context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), + instance); + context2->Global()->Set( + String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"), + obj_no_check); CompileRun("var records2 = null;" "var observer2 = function(r) { records2 = r };" "Object.observe(obj, observer2);" @@ -595,17 +614,18 @@ TEST(IndexedAccessCheck) { "obj[8] = 'bar';" "objNoCheck[42] = 'quux'"); const RecordExpectation expected_records2[] = { - { instance, "new", "7", Handle<Value>() }, - { instance, "updated", "7", String::New("foo") }, - { instance, "reconfigured", "7", Number::New(5) }, - { instance, "new", "8", Handle<Value>() }, - { obj_no_check, "new", "42", Handle<Value>() } + { instance, "add", "7", Handle<Value>() }, + { instance, "update", "7", + String::NewFromUtf8(isolate.GetIsolate(), "foo") }, + { instance, "reconfigure", "7", Number::New(isolate.GetIsolate(), 5) }, + { instance, "add", "8", Handle<Value>() }, + { obj_no_check, "add", "42", Handle<Value>() } }; EXPECT_RECORDS(CompileRun("records2"), expected_records2); } const RecordExpectation expected_records[] = { - { instance, "new", "8", Handle<Value>() }, - { obj_no_check, "new", "42", Handle<Value>() } + { instance, "add", "8", Handle<Value>() }, + { obj_no_check, "add", "42", Handle<Value>() } }; EXPECT_RECORDS(CompileRun("records"), expected_records); } @@ -618,8 +638,8 @@ TEST(SpliceAccessCheck) { LocalContext context(isolate.GetIsolate()); g_access_block_type = ACCESS_GET; Handle<Object> instance = CreateAccessCheckedObject( - NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked, - Number::New(1)); + isolate.GetIsolate(), NamedAccessAlwaysAllowed, + IndexedAccessAllowUnlessBlocked, Number::New(isolate.GetIsolate(), 1)); CompileRun("var records = null;" "obj[1] = 'foo';" "obj.length = 2;" @@ -630,8 +650,10 @@ TEST(SpliceAccessCheck) { Handle<Value> obj_no_check = CompileRun("objNoCheck"); { LocalContext context2(isolate.GetIsolate()); - context2->Global()->Set(String::New("obj"), instance); - context2->Global()->Set(String::New("objNoCheck"), obj_no_check); + context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), + instance); + context2->Global()->Set( + String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"), obj_no_check); CompileRun("var records2 = null;" "var observer2 = function(r) { records2 = r };" "Array.observe(obj, observer2);" @@ -662,7 +684,7 @@ TEST(DisallowAllForAccessKeys) { HandleScope scope(isolate.GetIsolate()); LocalContext context(isolate.GetIsolate()); Handle<Object> instance = CreateAccessCheckedObject( - BlockAccessKeys, IndexedAccessAlwaysAllowed); + isolate.GetIsolate(), BlockAccessKeys, IndexedAccessAlwaysAllowed); CompileRun("var records = null;" "var objNoCheck = {};" "var observer = function(r) { records = r };" @@ -671,8 +693,10 @@ TEST(DisallowAllForAccessKeys) { Handle<Value> obj_no_check = CompileRun("objNoCheck"); { LocalContext context2(isolate.GetIsolate()); - context2->Global()->Set(String::New("obj"), instance); - context2->Global()->Set(String::New("objNoCheck"), obj_no_check); + context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), + instance); + context2->Global()->Set( + String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"), obj_no_check); CompileRun("var records2 = null;" "var observer2 = function(r) { records2 = r };" "Object.observe(obj, observer2);" @@ -681,14 +705,14 @@ TEST(DisallowAllForAccessKeys) { "obj[5] = 'baz';" "objNoCheck.baz = 'quux'"); const RecordExpectation expected_records2[] = { - { instance, "new", "foo", Handle<Value>() }, - { instance, "new", "5", Handle<Value>() }, - { obj_no_check, "new", "baz", Handle<Value>() }, + { instance, "add", "foo", Handle<Value>() }, + { instance, "add", "5", Handle<Value>() }, + { obj_no_check, "add", "baz", Handle<Value>() }, }; EXPECT_RECORDS(CompileRun("records2"), expected_records2); } const RecordExpectation expected_records[] = { - { obj_no_check, "new", "baz", Handle<Value>() } + { obj_no_check, "add", "baz", Handle<Value>() } }; EXPECT_RECORDS(CompileRun("records"), expected_records); } @@ -699,22 +723,24 @@ TEST(AccessCheckDisallowApiModifications) { HandleScope scope(isolate.GetIsolate()); LocalContext context(isolate.GetIsolate()); Handle<Object> instance = CreateAccessCheckedObject( - BlockAccessKeys, IndexedAccessAlwaysAllowed); + isolate.GetIsolate(), BlockAccessKeys, IndexedAccessAlwaysAllowed); CompileRun("var records = null;" "var observer = function(r) { records = r };" "Object.observe(obj, observer);"); { LocalContext context2(isolate.GetIsolate()); - context2->Global()->Set(String::New("obj"), instance); + context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), + instance); CompileRun("var records2 = null;" "var observer2 = function(r) { records2 = r };" "Object.observe(obj, observer2);"); - instance->Set(5, String::New("bar")); - instance->Set(String::New("foo"), String::New("bar")); + instance->Set(5, String::NewFromUtf8(isolate.GetIsolate(), "bar")); + instance->Set(String::NewFromUtf8(isolate.GetIsolate(), "foo"), + String::NewFromUtf8(isolate.GetIsolate(), "bar")); CompileRun(""); // trigger delivery const RecordExpectation expected_records2[] = { - { instance, "new", "5", Handle<Value>() }, - { instance, "new", "foo", Handle<Value>() } + { instance, "add", "5", Handle<Value>() }, + { instance, "add", "foo", Handle<Value>() } }; EXPECT_RECORDS(CompileRun("records2"), expected_records2); } @@ -730,8 +756,11 @@ TEST(HiddenPropertiesLeakage) { "var records = null;" "var observer = function(r) { records = r };" "Object.observe(obj, observer);"); - Handle<Value> obj = context->Global()->Get(String::New("obj")); - Handle<Object>::Cast(obj)->SetHiddenValue(String::New("foo"), Null()); + Handle<Value> obj = + context->Global()->Get(String::NewFromUtf8(isolate.GetIsolate(), "obj")); + Handle<Object>::Cast(obj) + ->SetHiddenValue(String::NewFromUtf8(isolate.GetIsolate(), "foo"), + Null(isolate.GetIsolate())); CompileRun(""); // trigger delivery CHECK(CompileRun("records")->IsNull()); } diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc index 952cb68cec..30e97aabdc 100644 --- a/deps/v8/test/cctest/test-parsing.cc +++ b/deps/v8/test/cctest/test-parsing.cc @@ -108,6 +108,7 @@ TEST(ScanKeywords) { TEST(ScanHTMLEndComments) { v8::V8::Initialize(); v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope handles(isolate); // Regression test. See: // http://code.google.com/p/chromium/issues/detail?id=53548 @@ -144,15 +145,20 @@ TEST(ScanHTMLEndComments) { reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); for (int i = 0; tests[i]; i++) { - v8::ScriptData* data = - v8::ScriptData::PreCompile(isolate, tests[i], i::StrLength(tests[i])); + v8::Handle<v8::String> source = v8::String::NewFromUtf8( + isolate, tests[i], v8::String::kNormalString, i::StrLength(tests[i])); + v8::ScriptData* data = v8::ScriptData::PreCompile(source); CHECK(data != NULL && !data->HasError()); delete data; } for (int i = 0; fail_tests[i]; i++) { - v8::ScriptData* data = v8::ScriptData::PreCompile( - isolate, fail_tests[i], i::StrLength(fail_tests[i])); + v8::Handle<v8::String> source = + v8::String::NewFromUtf8(isolate, + fail_tests[i], + v8::String::kNormalString, + i::StrLength(fail_tests[i])); + v8::ScriptData* data = v8::ScriptData::PreCompile(source); CHECK(data == NULL || data->HasError()); delete data; } @@ -199,14 +205,15 @@ TEST(Preparsing) { const char* error_source = "var x = y z;"; int error_source_length = i::StrLength(error_source); - v8::ScriptData* preparse = - v8::ScriptData::PreCompile(isolate, source, source_length); + v8::ScriptData* preparse = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( + isolate, source, v8::String::kNormalString, source_length)); CHECK(!preparse->HasError()); bool lazy_flag = i::FLAG_lazy; { i::FLAG_lazy = true; ScriptResource* resource = new ScriptResource(source, source_length); - v8::Local<v8::String> script_source = v8::String::NewExternal(resource); + v8::Local<v8::String> script_source = + v8::String::NewExternal(isolate, resource); v8::Script::Compile(script_source, NULL, preparse); } @@ -214,15 +221,19 @@ TEST(Preparsing) { i::FLAG_lazy = false; ScriptResource* resource = new ScriptResource(source, source_length); - v8::Local<v8::String> script_source = v8::String::NewExternal(resource); + v8::Local<v8::String> script_source = + v8::String::NewExternal(isolate, resource); v8::Script::New(script_source, NULL, preparse, v8::Local<v8::String>()); } delete preparse; i::FLAG_lazy = lazy_flag; // Syntax error. - v8::ScriptData* error_preparse = - v8::ScriptData::PreCompile(isolate, error_source, error_source_length); + v8::ScriptData* error_preparse = v8::ScriptData::PreCompile( + v8::String::NewFromUtf8(isolate, + error_source, + v8::String::kNormalString, + error_source_length)); CHECK(error_preparse->HasError()); i::ScriptDataImpl *pre_impl = reinterpret_cast<i::ScriptDataImpl*>(error_preparse); @@ -233,8 +244,11 @@ TEST(Preparsing) { CHECK_EQ(11, error_location.end_pos); // Should not crash. const char* message = pre_impl->BuildMessage(); - pre_impl->BuildArgs(); + i::Vector<const char*> args = pre_impl->BuildArgs(); CHECK_GT(strlen(message), 0); + args.Dispose(); + i::DeleteArray(message); + delete error_preparse; } @@ -388,13 +402,13 @@ TEST(PreParseOverflow) { size_t kProgramSize = 1024 * 1024; i::SmartArrayPointer<char> program(i::NewArray<char>(kProgramSize + 1)); - memset(*program, '(', kProgramSize); + memset(program.get(), '(', kProgramSize); program[kProgramSize] = '\0'; uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); i::Utf8ToUtf16CharacterStream stream( - reinterpret_cast<const i::byte*>(*program), + reinterpret_cast<const i::byte*>(program.get()), static_cast<unsigned>(kProgramSize)); i::CompleteParserRecorder log; i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); @@ -445,7 +459,7 @@ void TestCharacterStream(const char* ascii_source, i::Vector<const char> ascii_vector(ascii_source, static_cast<int>(length)); i::Handle<i::String> ascii_string( factory->NewStringFromAscii(ascii_vector)); - TestExternalResource resource(*uc16_buffer, length); + TestExternalResource resource(uc16_buffer.get(), length); i::Handle<i::String> uc16_string( factory->NewExternalStringFromTwoByte(&resource)); @@ -1008,7 +1022,7 @@ TEST(ScopePositions) { int kSuffixByteLen = i::StrLength(source_data[i].outer_suffix); int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen; int kProgramByteSize = kPrefixByteLen + kInnerByteLen + kSuffixByteLen; - i::Vector<char> program = i::Vector<char>::New(kProgramByteSize + 1); + i::ScopedVector<char> program(kProgramByteSize + 1); i::OS::SNPrintF(program, "%s%s%s", source_data[i].outer_prefix, source_data[i].inner_source, @@ -1050,15 +1064,14 @@ i::Handle<i::String> FormatMessage(i::ScriptDataImpl* data) { i::Factory* factory = isolate->factory(); const char* message = data->BuildMessage(); i::Handle<i::String> format = v8::Utils::OpenHandle( - *v8::String::New(message)); + *v8::String::NewFromUtf8(CcTest::isolate(), message)); i::Vector<const char*> args = data->BuildArgs(); i::Handle<i::JSArray> args_array = factory->NewJSArray(args.length()); for (int i = 0; i < args.length(); i++) { - i::JSArray::SetElement(args_array, - i, - v8::Utils::OpenHandle(*v8::String::New(args[i])), - NONE, - i::kNonStrictMode); + i::JSArray::SetElement( + args_array, i, v8::Utils::OpenHandle(*v8::String::NewFromUtf8( + CcTest::isolate(), args[i])), + NONE, i::kNonStrictMode); } i::Handle<i::JSObject> builtins(isolate->js_builtins_object()); i::Handle<i::Object> format_fun = @@ -1089,7 +1102,15 @@ enum ParserFlag { }; -void SetParserFlags(i::ParserBase* parser, i::EnumSet<ParserFlag> flags) { +enum ParserSyncTestResult { + kSuccessOrError, + kSuccess, + kError +}; + +template <typename Traits> +void SetParserFlags(i::ParserBase<Traits>* parser, + i::EnumSet<ParserFlag> flags) { parser->set_allow_lazy(flags.Contains(kAllowLazy)); parser->set_allow_natives_syntax(flags.Contains(kAllowNativesSyntax)); parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping)); @@ -1102,7 +1123,8 @@ void SetParserFlags(i::ParserBase* parser, i::EnumSet<ParserFlag> flags) { void TestParserSyncWithFlags(i::Handle<i::String> source, - i::EnumSet<ParserFlag> flags) { + i::EnumSet<ParserFlag> flags, + ParserSyncTestResult result) { i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); @@ -1144,6 +1166,17 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, i::Handle<i::String> message_string = i::Handle<i::String>::cast(i::GetProperty(exception_handle, "message")); + if (result == kSuccess) { + i::OS::Print( + "Parser failed on:\n" + "\t%s\n" + "with error:\n" + "\t%s\n" + "However, we expected no error.", + source->ToCString().get(), message_string->ToCString().get()); + CHECK(false); + } + if (!data.has_error()) { i::OS::Print( "Parser failed on:\n" @@ -1151,7 +1184,7 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, "with error:\n" "\t%s\n" "However, the preparser succeeded", - *source->ToCString(), *message_string->ToCString()); + source->ToCString().get(), message_string->ToCString().get()); CHECK(false); } // Check that preparser and parser produce the same error. @@ -1163,9 +1196,9 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, "However, found the following error messages\n" "\tparser: %s\n" "\tpreparser: %s\n", - *source->ToCString(), - *message_string->ToCString(), - *preparser_message->ToCString()); + source->ToCString().get(), + message_string->ToCString().get(), + preparser_message->ToCString().get()); CHECK(false); } } else if (data.has_error()) { @@ -1175,7 +1208,14 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, "with error:\n" "\t%s\n" "However, the parser succeeded", - *source->ToCString(), *FormatMessage(&data)->ToCString()); + source->ToCString().get(), FormatMessage(&data)->ToCString().get()); + CHECK(false); + } else if (result == kError) { + i::OS::Print( + "Expected error on:\n" + "\t%s\n" + "However, parser and preparser succeeded", + source->ToCString().get()); CHECK(false); } } @@ -1183,7 +1223,8 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, void TestParserSync(const char* source, const ParserFlag* flag_list, - size_t flag_list_length) { + size_t flag_list_length, + ParserSyncTestResult result = kSuccessOrError) { i::Handle<i::String> str = CcTest::i_isolate()->factory()->NewStringFromAscii(i::CStrVector(source)); for (int bits = 0; bits < (1 << flag_list_length); bits++) { @@ -1191,7 +1232,7 @@ void TestParserSync(const char* source, for (size_t flag_index = 0; flag_index < flag_list_length; flag_index++) { if ((bits & (1 << flag_index)) != 0) flags.Add(flag_list[flag_index]); } - TestParserSyncWithFlags(str, flags); + TestParserSyncWithFlags(str, flags, result); } } @@ -1329,9 +1370,754 @@ TEST(PreparserStrictOctal) { " 01; \n" " }; \n" "}; \n"; - v8::Script::Compile(v8::String::New(script)); + v8::Script::Compile(v8::String::NewFromUtf8(CcTest::isolate(), script)); CHECK(try_catch.HasCaught()); v8::String::Utf8Value exception(try_catch.Exception()); CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.", *exception); } + + +void RunParserSyncTest(const char* context_data[][2], + const char* statement_data[], + ParserSyncTestResult result) { + v8::HandleScope handles(CcTest::isolate()); + v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); + v8::Context::Scope context_scope(context); + + int marker; + CcTest::i_isolate()->stack_guard()->SetStackLimit( + reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); + + static const ParserFlag flags[] = { + kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators, + kAllowForOf, kAllowNativesSyntax + }; + for (int i = 0; context_data[i][0] != NULL; ++i) { + for (int j = 0; statement_data[j] != NULL; ++j) { + int kPrefixLen = i::StrLength(context_data[i][0]); + int kStatementLen = i::StrLength(statement_data[j]); + int kSuffixLen = i::StrLength(context_data[i][1]); + int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen; + + // Plug the source code pieces together. + i::ScopedVector<char> program(kProgramSize + 1); + int length = i::OS::SNPrintF(program, + "%s%s%s", + context_data[i][0], + statement_data[j], + context_data[i][1]); + CHECK(length == kProgramSize); + TestParserSync(program.start(), + flags, + ARRAY_SIZE(flags), + result); + } + } +} + + +TEST(ErrorsEvalAndArguments) { + // Tests that both preparsing and parsing produce the right kind of errors for + // using "eval" and "arguments" as identifiers. Without the strict mode, it's + // ok to use "eval" or "arguments" as identifiers. With the strict mode, it + // isn't. + const char* context_data[][2] = { + { "\"use strict\";", "" }, + { "var eval; function test_func() {\"use strict\"; ", "}"}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "var eval;", + "var arguments", + "var foo, eval;", + "var foo, arguments;", + "try { } catch (eval) { }", + "try { } catch (arguments) { }", + "function eval() { }", + "function arguments() { }", + "function foo(eval) { }", + "function foo(arguments) { }", + "function foo(bar, eval) { }", + "function foo(bar, arguments) { }", + "eval = 1;", + "arguments = 1;", + "var foo = eval = 1;", + "var foo = arguments = 1;", + "++eval;", + "++arguments;", + "eval++;", + "arguments++;", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(NoErrorsEvalAndArgumentsClassic) { + // Tests that both preparsing and parsing accept "eval" and "arguments" as + // identifiers when needed. + const char* context_data[][2] = { + { "", "" }, + { "function test_func() {", "}"}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "var eval;", + "var arguments", + "var foo, eval;", + "var foo, arguments;", + "try { } catch (eval) { }", + "try { } catch (arguments) { }", + "function eval() { }", + "function arguments() { }", + "function foo(eval) { }", + "function foo(arguments) { }", + "function foo(bar, eval) { }", + "function foo(bar, arguments) { }", + "eval = 1;", + "arguments = 1;", + "var foo = eval = 1;", + "var foo = arguments = 1;", + "++eval;", + "++arguments;", + "eval++;", + "arguments++;", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kSuccess); +} + + +TEST(NoErrorsEvalAndArgumentsStrict) { + const char* context_data[][2] = { + { "\"use strict\";", "" }, + { "function test_func() { \"use strict\";", "}" }, + { NULL, NULL } + }; + + const char* statement_data[] = { + "eval;", + "arguments;", + "var foo = eval;", + "var foo = arguments;", + "var foo = { eval: 1 };", + "var foo = { arguments: 1 };", + "var foo = { }; foo.eval = {};", + "var foo = { }; foo.arguments = {};", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kSuccess); +} + + +TEST(ErrorsFutureStrictReservedWords) { + // Tests that both preparsing and parsing produce the right kind of errors for + // using future strict reserved words as identifiers. Without the strict mode, + // it's ok to use future strict reserved words as identifiers. With the strict + // mode, it isn't. + const char* context_data[][2] = { + { "\"use strict\";", "" }, + { "function test_func() {\"use strict\"; ", "}"}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "var interface;", + "var foo, interface;", + "try { } catch (interface) { }", + "function interface() { }", + "function foo(interface) { }", + "function foo(bar, interface) { }", + "interface = 1;", + "var foo = interface = 1;", + "++interface;", + "interface++;", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(NoErrorsFutureStrictReservedWords) { + const char* context_data[][2] = { + { "", "" }, + { "function test_func() {", "}"}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "var interface;", + "var foo, interface;", + "try { } catch (interface) { }", + "function interface() { }", + "function foo(interface) { }", + "function foo(bar, interface) { }", + "interface = 1;", + "var foo = interface = 1;", + "++interface;", + "interface++;", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kSuccess); +} + + +TEST(ErrorsReservedWords) { + // Tests that both preparsing and parsing produce the right kind of errors for + // using future reserved words as identifiers. These tests don't depend on the + // strict mode. + const char* context_data[][2] = { + { "", "" }, + { "\"use strict\";", "" }, + { "var eval; function test_func() {", "}"}, + { "var eval; function test_func() {\"use strict\"; ", "}"}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "var super;", + "var foo, super;", + "try { } catch (super) { }", + "function super() { }", + "function foo(super) { }", + "function foo(bar, super) { }", + "super = 1;", + "var foo = super = 1;", + "++super;", + "super++;", + "function foo super", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(NoErrorsYieldClassic) { + // In classic mode, it's okay to use "yield" as identifier, *except* inside a + // generator (see next test). + const char* context_data[][2] = { + { "", "" }, + { "function is_not_gen() {", "}" }, + { NULL, NULL } + }; + + const char* statement_data[] = { + "var yield;", + "var foo, yield;", + "try { } catch (yield) { }", + "function yield() { }", + "function foo(yield) { }", + "function foo(bar, yield) { }", + "yield = 1;", + "var foo = yield = 1;", + "++yield;", + "yield++;", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kSuccess); +} + + +TEST(ErrorsYieldClassicGenerator) { + const char* context_data[][2] = { + { "function * is_gen() {", "}" }, + { NULL, NULL } + }; + + const char* statement_data[] = { + "var yield;", + "var foo, yield;", + "try { } catch (yield) { }", + "function yield() { }", + // BUG: These should not be allowed, but they are (if kAllowGenerators is + // set) + // "function foo(yield) { }", + // "function foo(bar, yield) { }", + "yield = 1;", + "var foo = yield = 1;", + "++yield;", + "yield++;", + NULL + }; + + // If generators are not allowed, the error will be produced at the '*' token, + // so this test works both with and without the kAllowGenerators flag. + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(ErrorsYieldStrict) { + const char* context_data[][2] = { + { "\"use strict\";", "" }, + { "\"use strict\"; function is_not_gen() {", "}" }, + { "function test_func() {\"use strict\"; ", "}"}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "var yield;", + "var foo, yield;", + "try { } catch (yield) { }", + "function yield() { }", + "function foo(yield) { }", + "function foo(bar, yield) { }", + "yield = 1;", + "var foo = yield = 1;", + "++yield;", + "yield++;", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(ErrorsYield) { + const char* context_data[][2] = { + { "function * is_gen() {", "}" }, + { NULL, NULL } + }; + + const char* statement_data[] = { + "yield 2;", // this is legal inside generator + "yield * 2;", // this is legal inside generator + NULL + }; + + // Here we cannot assert that there is no error, since there will be without + // the kAllowGenerators flag. However, we test that Parser and PreParser + // produce the same errors. + RunParserSyncTest(context_data, statement_data, kSuccessOrError); +} + + +TEST(ErrorsNameOfStrictFunction) { + // Tests that illegal tokens as names of a strict function produce the correct + // errors. + const char* context_data[][2] = { + { "", ""}, + { "\"use strict\";", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "function eval() {\"use strict\";}", + "function arguments() {\"use strict\";}", + "function interface() {\"use strict\";}", + "function yield() {\"use strict\";}", + // Future reserved words are always illegal + "function super() { }", + "function super() {\"use strict\";}", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(NoErrorsNameOfStrictFunction) { + const char* context_data[][2] = { + { "", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "function eval() { }", + "function arguments() { }", + "function interface() { }", + "function yield() { }", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kSuccess); +} + + + +TEST(ErrorsIllegalWordsAsLabelsClassic) { + // Using future reserved words as labels is always an error. + const char* context_data[][2] = { + { "", ""}, + { "function test_func() {", "}" }, + { NULL, NULL } + }; + + const char* statement_data[] = { + "super: while(true) { break super; }", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(ErrorsIllegalWordsAsLabelsStrict) { + // Tests that illegal tokens as labels produce the correct errors. + const char* context_data[][2] = { + { "\"use strict\";", "" }, + { "function test_func() {\"use strict\"; ", "}"}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "super: while(true) { break super; }", + "interface: while(true) { break interface; }", + "yield: while(true) { break yield; }", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(NoErrorsIllegalWordsAsLabels) { + // Using eval and arguments as labels is legal even in strict mode. + const char* context_data[][2] = { + { "", ""}, + { "function test_func() {", "}" }, + { "\"use strict\";", "" }, + { "\"use strict\"; function test_func() {", "}" }, + { NULL, NULL } + }; + + const char* statement_data[] = { + "mylabel: while(true) { break mylabel; }", + "eval: while(true) { break eval; }", + "arguments: while(true) { break arguments; }", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kSuccess); +} + + +TEST(ErrorsParenthesizedLabels) { + // Parenthesized identifiers shouldn't be recognized as labels. + const char* context_data[][2] = { + { "", ""}, + { "function test_func() {", "}" }, + { NULL, NULL } + }; + + const char* statement_data[] = { + "(mylabel): while(true) { break mylabel; }", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(NoErrorsParenthesizedDirectivePrologue) { + // Parenthesized directive prologue shouldn't be recognized. + const char* context_data[][2] = { + { "", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "(\"use strict\"); var eval;", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kSuccess); +} + + +TEST(ErrorsNotAnIdentifierName) { + const char* context_data[][2] = { + { "", ""}, + { "\"use strict\";", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "var foo = {}; foo.{;", + "var foo = {}; foo.};", + "var foo = {}; foo.=;", + "var foo = {}; foo.888;", + "var foo = {}; foo.-;", + "var foo = {}; foo.--;", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(NoErrorsIdentifierNames) { + // Keywords etc. are valid as property names. + const char* context_data[][2] = { + { "", ""}, + { "\"use strict\";", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "var foo = {}; foo.if;", + "var foo = {}; foo.yield;", + "var foo = {}; foo.super;", + "var foo = {}; foo.interface;", + "var foo = {}; foo.eval;", + "var foo = {}; foo.arguments;", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kSuccess); +} + + +TEST(DontRegressPreParserDataSizes) { + // These tests make sure that PreParser doesn't start producing less data. + + v8::V8::Initialize(); + + int marker; + CcTest::i_isolate()->stack_guard()->SetStackLimit( + reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); + + struct TestCase { + const char* program; + int symbols; + int functions; + } test_cases[] = { + // Labels, variables and functions are recorded as symbols. + {"{label: 42}", 1, 0}, {"{label: 42; label2: 43}", 2, 0}, + {"var x = 42;", 1, 0}, {"var x = 42, y = 43;", 2, 0}, + {"function foo() {}", 1, 1}, {"function foo() {} function bar() {}", 2, 2}, + // Labels, variables and functions insize lazy functions are not recorded. + {"function lazy() { var a, b, c; }", 1, 1}, + {"function lazy() { a: 1; b: 2; c: 3; }", 1, 1}, + {"function lazy() { function a() {} function b() {} function c() {} }", 1, + 1}, + {NULL, 0, 0} + }; + // Each function adds 5 elements to the preparse function data. + const int kDataPerFunction = 5; + + uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); + for (int i = 0; test_cases[i].program; i++) { + const char* program = test_cases[i].program; + i::Utf8ToUtf16CharacterStream stream( + reinterpret_cast<const i::byte*>(program), + static_cast<unsigned>(strlen(program))); + i::CompleteParserRecorder log; + i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); + scanner.Initialize(&stream); + + i::PreParser preparser(&scanner, &log, stack_limit); + preparser.set_allow_lazy(true); + preparser.set_allow_natives_syntax(true); + i::PreParser::PreParseResult result = preparser.PreParseProgram(); + CHECK_EQ(i::PreParser::kPreParseSuccess, result); + if (log.symbol_ids() != test_cases[i].symbols) { + i::OS::Print( + "Expected preparse data for program:\n" + "\t%s\n" + "to contain %d symbols, however, received %d symbols.\n", + program, test_cases[i].symbols, log.symbol_ids()); + CHECK(false); + } + if (log.function_position() != test_cases[i].functions * kDataPerFunction) { + i::OS::Print( + "Expected preparse data for program:\n" + "\t%s\n" + "to contain %d functions, however, received %d functions.\n", + program, test_cases[i].functions, + log.function_position() / kDataPerFunction); + CHECK(false); + } + i::ScriptDataImpl data(log.ExtractData()); + CHECK(!data.has_error()); + } +} + + +TEST(FunctionDeclaresItselfStrict) { + // Tests that we produce the right kinds of errors when a function declares + // itself strict (we cannot produce there errors as soon as we see the + // offending identifiers, because we don't know at that point whether the + // function is strict or not). + const char* context_data[][2] = { + {"function eval() {", "}"}, + {"function arguments() {", "}"}, + {"function yield() {", "}"}, + {"function interface() {", "}"}, + {"function foo(eval) {", "}"}, + {"function foo(arguments) {", "}"}, + {"function foo(yield) {", "}"}, + {"function foo(interface) {", "}"}, + {"function foo(bar, eval) {", "}"}, + {"function foo(bar, arguments) {", "}"}, + {"function foo(bar, yield) {", "}"}, + {"function foo(bar, interface) {", "}"}, + {"function foo(bar, bar) {", "}"}, + { NULL, NULL } + }; + + const char* strict_statement_data[] = { + "\"use strict\";", + NULL + }; + + const char* non_strict_statement_data[] = { + ";", + NULL + }; + + RunParserSyncTest(context_data, strict_statement_data, kError); + RunParserSyncTest(context_data, non_strict_statement_data, kSuccess); +} + + +TEST(ErrorsTryWithoutCatchOrFinally) { + const char* context_data[][2] = { + {"", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "try { }", + "try { } foo();", + "try { } catch (e) foo();", + "try { } catch { }", + "try { } finally foo();", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(NoErrorsTryCatchFinally) { + const char* context_data[][2] = { + {"", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "try { } catch (e) { }", + "try { } catch (e) { } finally { }", + "try { } finally { }", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kSuccess); +} + + +TEST(ErrorsRegexpLiteral) { + const char* context_data[][2] = { + {"var r = ", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "/unterminated", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + +TEST(NoErrorsRegexpLiteral) { + const char* context_data[][2] = { + {"var r = ", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "/foo/", + "/foo/g", + "/foo/whatever", // This is an error but not detected by the parser. + NULL + }; + + RunParserSyncTest(context_data, statement_data, kSuccess); +} + + +TEST(Intrinsics) { + const char* context_data[][2] = { + {"", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "%someintrinsic(arg)", + NULL + }; + + // Parsing will fail or succeed depending on whether we allow natives syntax + // or not. + RunParserSyncTest(context_data, statement_data, kSuccessOrError); +} + + +TEST(NoErrorsNewExpression) { + const char* context_data[][2] = { + {"", ""}, + {"var f =", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "new foo", + "new foo();", + "new foo(1);", + "new foo(1, 2);", + // The first () will be processed as a part of the NewExpression and the + // second () will be processed as part of LeftHandSideExpression. + "new foo()();", + // The first () will be processed as a part of the inner NewExpression and + // the second () will be processed as a part of the outer NewExpression. + "new new foo()();", + "new foo.bar;", + "new foo.bar();", + "new foo.bar.baz;", + "new foo.bar().baz;", + "new foo[bar];", + "new foo[bar]();", + "new foo[bar][baz];", + "new foo[bar]()[baz];", + "new foo[bar].baz(baz)()[bar].baz;", + "new \"foo\"", // Runtime error + "new 1", // Runtime error + "new foo++", + // This even runs: + "(new new Function(\"this.x = 1\")).x;", + "new new Test_Two(String, 2).v(0123).length;", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kSuccess); +} + + +TEST(ErrorsNewExpression) { + const char* context_data[][2] = { + {"", ""}, + {"var f =", ""}, + { NULL, NULL } + }; + + const char* statement_data[] = { + "new foo bar", + "new ) foo", + "new ++foo", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} diff --git a/deps/v8/test/cctest/test-platform.cc b/deps/v8/test/cctest/test-platform.cc index 36ad487079..b9f8bafe4d 100644 --- a/deps/v8/test/cctest/test-platform.cc +++ b/deps/v8/test/cctest/test-platform.cc @@ -53,6 +53,12 @@ using namespace ::v8::internal; do { \ ASM("str %%sp, %0" : "=g" (sp_addr)); \ } while (0) +#elif defined(__AARCH64EL__) +#define GET_STACK_POINTER() \ + static int sp_addr = 0; \ + do { \ + ASM("mov x16, sp; str x16, %0" : "=g" (sp_addr)); \ + } while (0) #elif defined(__MIPSEL__) #define GET_STACK_POINTER() \ static int sp_addr = 0; \ @@ -72,9 +78,10 @@ void GetStackPointer(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(StackAlignment) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> global_template = + v8::ObjectTemplate::New(isolate); global_template->Set(v8_str("get_stack_pointer"), - v8::FunctionTemplate::New(GetStackPointer)); + v8::FunctionTemplate::New(isolate, GetStackPointer)); LocalContext env(NULL, global_template); CompileRun( diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc index 47146ecc48..c3198b1512 100644 --- a/deps/v8/test/cctest/test-profile-generator.cc +++ b/deps/v8/test/cctest/test-profile-generator.cc @@ -29,6 +29,7 @@ #include "v8.h" #include "profile-generator-inl.h" +#include "profiler-extension.h" #include "cctest.h" #include "cpu-profiler.h" #include "../include/v8-profiler.h" @@ -47,42 +48,42 @@ using i::Vector; TEST(ProfileNodeFindOrAddChild) { ProfileTree tree; - ProfileNode node(&tree, NULL); + ProfileNode* node = tree.root(); CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa"); - ProfileNode* childNode1 = node.FindOrAddChild(&entry1); + ProfileNode* childNode1 = node->FindOrAddChild(&entry1); CHECK_NE(NULL, childNode1); - CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); + CHECK_EQ(childNode1, node->FindOrAddChild(&entry1)); CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb"); - ProfileNode* childNode2 = node.FindOrAddChild(&entry2); + ProfileNode* childNode2 = node->FindOrAddChild(&entry2); CHECK_NE(NULL, childNode2); CHECK_NE(childNode1, childNode2); - CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); - CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); + CHECK_EQ(childNode1, node->FindOrAddChild(&entry1)); + CHECK_EQ(childNode2, node->FindOrAddChild(&entry2)); CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc"); - ProfileNode* childNode3 = node.FindOrAddChild(&entry3); + ProfileNode* childNode3 = node->FindOrAddChild(&entry3); CHECK_NE(NULL, childNode3); CHECK_NE(childNode1, childNode3); CHECK_NE(childNode2, childNode3); - CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); - CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); - CHECK_EQ(childNode3, node.FindOrAddChild(&entry3)); + CHECK_EQ(childNode1, node->FindOrAddChild(&entry1)); + CHECK_EQ(childNode2, node->FindOrAddChild(&entry2)); + CHECK_EQ(childNode3, node->FindOrAddChild(&entry3)); } TEST(ProfileNodeFindOrAddChildForSameFunction) { const char* aaa = "aaa"; ProfileTree tree; - ProfileNode node(&tree, NULL); + ProfileNode* node = tree.root(); CodeEntry entry1(i::Logger::FUNCTION_TAG, aaa); - ProfileNode* childNode1 = node.FindOrAddChild(&entry1); + ProfileNode* childNode1 = node->FindOrAddChild(&entry1); CHECK_NE(NULL, childNode1); - CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); + CHECK_EQ(childNode1, node->FindOrAddChild(&entry1)); // The same function again. CodeEntry entry2(i::Logger::FUNCTION_TAG, aaa); - CHECK_EQ(childNode1, node.FindOrAddChild(&entry2)); + CHECK_EQ(childNode1, node->FindOrAddChild(&entry2)); // Now with a different security token. CodeEntry entry3(i::Logger::FUNCTION_TAG, aaa); - CHECK_EQ(childNode1, node.FindOrAddChild(&entry3)); + CHECK_EQ(childNode1, node->FindOrAddChild(&entry3)); } @@ -400,7 +401,7 @@ class TestSetup { TEST(RecordTickSample) { TestSetup test_setup; CpuProfilesCollection profiles(CcTest::heap()); - profiles.StartProfiling("", 1, false); + profiles.StartProfiling("", false); ProfileGenerator generator(&profiles); CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa"); CodeEntry* entry2 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "bbb"); @@ -466,7 +467,7 @@ static void CheckNodeIds(ProfileNode* node, int* expectedId) { TEST(SampleIds) { TestSetup test_setup; CpuProfilesCollection profiles(CcTest::heap()); - profiles.StartProfiling("", 1, true); + profiles.StartProfiling("", true); ProfileGenerator generator(&profiles); CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa"); CodeEntry* entry2 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "bbb"); @@ -514,7 +515,7 @@ TEST(SampleIds) { TEST(NoSamples) { TestSetup test_setup; CpuProfilesCollection profiles(CcTest::heap()); - profiles.StartProfiling("", 1, false); + profiles.StartProfiling("", false); ProfileGenerator generator(&profiles); CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa"); generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200); @@ -536,60 +537,6 @@ TEST(NoSamples) { } -// --- P r o f i l e r E x t e n s i o n --- - -class ProfilerExtension : public v8::Extension { - public: - ProfilerExtension() : v8::Extension("v8/profiler", kSource) { } - virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( - v8::Handle<v8::String> name); - static void StartProfiling(const v8::FunctionCallbackInfo<v8::Value>& args); - static void StopProfiling(const v8::FunctionCallbackInfo<v8::Value>& args); - private: - static const char* kSource; -}; - - -const char* ProfilerExtension::kSource = - "native function startProfiling();" - "native function stopProfiling();"; - -v8::Handle<v8::FunctionTemplate> ProfilerExtension::GetNativeFunction( - v8::Handle<v8::String> name) { - if (name->Equals(v8::String::New("startProfiling"))) { - return v8::FunctionTemplate::New(ProfilerExtension::StartProfiling); - } else if (name->Equals(v8::String::New("stopProfiling"))) { - return v8::FunctionTemplate::New(ProfilerExtension::StopProfiling); - } else { - CHECK(false); - return v8::Handle<v8::FunctionTemplate>(); - } -} - - -void ProfilerExtension::StartProfiling( - const v8::FunctionCallbackInfo<v8::Value>& args) { - v8::CpuProfiler* cpu_profiler = args.GetIsolate()->GetCpuProfiler(); - if (args.Length() > 0) - cpu_profiler->StartCpuProfiling(args[0].As<v8::String>()); - else - cpu_profiler->StartCpuProfiling(v8::String::New("")); -} - - -void ProfilerExtension::StopProfiling( - const v8::FunctionCallbackInfo<v8::Value>& args) { - v8::CpuProfiler* cpu_profiler = args.GetIsolate()->GetCpuProfiler(); - if (args.Length() > 0) - cpu_profiler->StopCpuProfiling(args[0].As<v8::String>()); - else - cpu_profiler->StopCpuProfiling(v8::String::New("")); -} - - -static ProfilerExtension kProfilerExtension; -v8::DeclareExtension kProfilerExtensionDeclaration(&kProfilerExtension); - static const ProfileNode* PickChild(const ProfileNode* parent, const char* name) { for (int i = 0; i < parent->children()->length(); ++i) { @@ -605,12 +552,9 @@ TEST(RecordStackTraceAtStartProfiling) { // don't appear in the stack trace. i::FLAG_use_inlining = false; - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - const char* extensions[] = { "v8/profiler" }; - v8::ExtensionConfiguration config(1, extensions); - v8::Local<v8::Context> context = v8::Context::New(isolate, &config); - context->Enter(); + v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); + v8::Context::Scope context_scope(env); CpuProfiler* profiler = CcTest::i_isolate()->cpu_profiler(); CHECK_EQ(0, profiler->GetProfilesCount()); @@ -658,12 +602,10 @@ TEST(Issue51919) { for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) { i::Vector<char> title = i::Vector<char>::New(16); i::OS::SNPrintF(title, "%d", i); - // UID must be > 0. - CHECK(collection.StartProfiling(title.start(), i + 1, false)); + CHECK(collection.StartProfiling(title.start(), false)); titles[i] = title.start(); } - CHECK(!collection.StartProfiling( - "maximum", CpuProfilesCollection::kMaxSimultaneousProfiles + 1, false)); + CHECK(!collection.StartProfiling("maximum", false)); for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) i::DeleteArray(titles[i]); } @@ -673,7 +615,7 @@ static const v8::CpuProfileNode* PickChild(const v8::CpuProfileNode* parent, const char* name) { for (int i = 0; i < parent->GetChildrenCount(); ++i) { const v8::CpuProfileNode* child = parent->GetChild(i); - v8::String::AsciiValue function_name(child->GetFunctionName()); + v8::String::Utf8Value function_name(child->GetFunctionName()); if (strcmp(*function_name, name) == 0) return child; } return NULL; @@ -685,23 +627,24 @@ TEST(ProfileNodeScriptId) { // don't appear in the stack trace. i::FLAG_use_inlining = false; - const char* extensions[] = { "v8/profiler" }; - v8::ExtensionConfiguration config(1, extensions); - LocalContext env(&config); - v8::HandleScope hs(env->GetIsolate()); + v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); + v8::Context::Scope context_scope(env); v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler(); - CHECK_EQ(0, profiler->GetProfileCount()); - v8::Handle<v8::Script> script_a = v8::Script::Compile(v8::String::New( - "function a() { startProfiling(); }\n")); + i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler); + CHECK_EQ(0, iprofiler->GetProfilesCount()); + v8::Handle<v8::Script> script_a = v8::Script::Compile(v8::String::NewFromUtf8( + env->GetIsolate(), "function a() { startProfiling(); }\n")); script_a->Run(); - v8::Handle<v8::Script> script_b = v8::Script::Compile(v8::String::New( - "function b() { a(); }\n" - "b();\n" - "stopProfiling();\n")); + v8::Handle<v8::Script> script_b = + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + "function b() { a(); }\n" + "b();\n" + "stopProfiling();\n")); script_b->Run(); - CHECK_EQ(1, profiler->GetProfileCount()); - const v8::CpuProfile* profile = profiler->GetCpuProfile(0); + CHECK_EQ(1, iprofiler->GetProfilesCount()); + const v8::CpuProfile* profile = i::ProfilerExtension::last_profile; const v8::CpuProfileNode* current = profile->GetTopDownRoot(); reinterpret_cast<ProfileNode*>( const_cast<v8::CpuProfileNode*>(current))->Print(0); @@ -786,29 +729,31 @@ TEST(LineNumber) { TEST(BailoutReason) { - const char* extensions[] = { "v8/profiler" }; - v8::ExtensionConfiguration config(1, extensions); - LocalContext env(&config); - v8::HandleScope hs(env->GetIsolate()); + v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); + v8::Context::Scope context_scope(env); v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler(); - CHECK_EQ(0, profiler->GetProfileCount()); - v8::Handle<v8::Script> script = v8::Script::Compile(v8::String::New( - "function TryCatch() {\n" - " try {\n" - " startProfiling();\n" - " } catch (e) { };\n" - "}\n" - "function TryFinally() {\n" - " try {\n" - " TryCatch();\n" - " } finally { };\n" - "}\n" - "TryFinally();\n" - "stopProfiling();")); + i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler); + CHECK_EQ(0, iprofiler->GetProfilesCount()); + v8::Handle<v8::Script> script = + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), + "function TryCatch() {\n" + " try {\n" + " startProfiling();\n" + " } catch (e) { };\n" + "}\n" + "function TryFinally() {\n" + " try {\n" + " TryCatch();\n" + " } finally { };\n" + "}\n" + "TryFinally();\n" + "stopProfiling();")); script->Run(); - CHECK_EQ(1, profiler->GetProfileCount()); - const v8::CpuProfile* profile = profiler->GetCpuProfile(0); + CHECK_EQ(1, iprofiler->GetProfilesCount()); + const v8::CpuProfile* profile = i::ProfilerExtension::last_profile; + CHECK(profile); const v8::CpuProfileNode* current = profile->GetTopDownRoot(); reinterpret_cast<ProfileNode*>( const_cast<v8::CpuProfileNode*>(current))->Print(0); diff --git a/deps/v8/test/cctest/test-random.cc b/deps/v8/test/cctest/test-random.cc deleted file mode 100644 index ea1f36f24c..0000000000 --- a/deps/v8/test/cctest/test-random.cc +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "v8.h" - -#include "cctest.h" -#include "compiler.h" -#include "execution.h" -#include "isolate.h" - - -using namespace v8::internal; - - -void SetSeeds(Handle<ByteArray> seeds, uint32_t state0, uint32_t state1) { - for (int i = 0; i < 4; i++) { - seeds->set(i, static_cast<byte>(state0 >> (i * kBitsPerByte))); - seeds->set(i + 4, static_cast<byte>(state1 >> (i * kBitsPerByte))); - } -} - - -void TestSeeds(Handle<JSFunction> fun, - Handle<Context> context, - uint32_t state0, - uint32_t state1) { - bool has_pending_exception; - Handle<JSObject> global(context->global_object()); - Handle<ByteArray> seeds(context->random_seed()); - - SetSeeds(seeds, state0, state1); - Handle<Object> value = Execution::Call( - context->GetIsolate(), fun, global, 0, NULL, &has_pending_exception); - CHECK(value->IsHeapNumber()); - CHECK(fun->IsOptimized()); - double crankshaft_value = HeapNumber::cast(*value)->value(); - - SetSeeds(seeds, state0, state1); - V8::FillHeapNumberWithRandom(*value, *context); - double runtime_value = HeapNumber::cast(*value)->value(); - CHECK_EQ(runtime_value, crankshaft_value); -} - - -TEST(CrankshaftRandom) { - v8::V8::Initialize(); - // Skip test if crankshaft is disabled. - if (!CcTest::i_isolate()->use_crankshaft()) return; - v8::Isolate* v8_isolate = CcTest::isolate(); - v8::HandleScope scope(v8_isolate); - v8::Context::Scope context_scope(v8::Context::New(v8_isolate)); - - i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); - Handle<Context> context(isolate->context()); - Handle<JSObject> global(context->global_object()); - Handle<ByteArray> seeds(context->random_seed()); - bool has_pending_exception; - - CompileRun("function f() { return Math.random(); }"); - - Object* string = CcTest::i_isolate()->factory()->InternalizeOneByteString( - STATIC_ASCII_VECTOR("f"))->ToObjectChecked(); - MaybeObject* fun_object = - context->global_object()->GetProperty(String::cast(string)); - Handle<JSFunction> fun(JSFunction::cast(fun_object->ToObjectChecked())); - - // Optimize function. - Execution::Call(isolate, fun, global, 0, NULL, &has_pending_exception); - Execution::Call(isolate, fun, global, 0, NULL, &has_pending_exception); - if (!fun->IsOptimized()) fun->MarkForLazyRecompilation(); - - // Test with some random values. - TestSeeds(fun, context, 0xC0C0AFFE, 0x31415926); - TestSeeds(fun, context, 0x01020304, 0xFFFFFFFF); - TestSeeds(fun, context, 0x00000001, 0x00000001); -} diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc index cc946464b2..b3d62f4717 100644 --- a/deps/v8/test/cctest/test-regexp.cc +++ b/deps/v8/test/cctest/test-regexp.cc @@ -49,6 +49,11 @@ #include "arm/macro-assembler-arm.h" #include "arm/regexp-macro-assembler-arm.h" #endif +#if V8_TARGET_ARCH_A64 +#include "a64/assembler-a64.h" +#include "a64/macro-assembler-a64.h" +#include "a64/regexp-macro-assembler-a64.h" +#endif #if V8_TARGET_ARCH_MIPS #include "mips/assembler-mips.h" #include "mips/macro-assembler-mips.h" @@ -132,7 +137,7 @@ static MinMaxPair CheckMinMaxMatch(const char* input) { #define CHECK_PARSE_ERROR(input) CHECK(!CheckParse(input)) -#define CHECK_PARSE_EQ(input, expected) CHECK_EQ(expected, *Parse(input)) +#define CHECK_PARSE_EQ(input, expected) CHECK_EQ(expected, Parse(input).get()) #define CHECK_SIMPLE(input, simple) CHECK_EQ(simple, CheckSimple(input)); #define CHECK_MIN_MAX(input, min, max) \ { MinMaxPair min_max = CheckMinMaxMatch(input); \ @@ -399,7 +404,7 @@ static void ExpectError(const char* input, CHECK(result.tree == NULL); CHECK(!result.error.is_null()); SmartArrayPointer<char> str = result.error->ToCString(ALLOW_NULLS); - CHECK_EQ(expected, *str); + CHECK_EQ(expected, str.get()); } @@ -430,7 +435,7 @@ TEST(Errors) { accumulator.Add("()"); } SmartArrayPointer<const char> many_captures(accumulator.ToCString()); - ExpectError(*many_captures, kTooManyCaptures); + ExpectError(many_captures.get(), kTooManyCaptures); } @@ -444,27 +449,15 @@ static bool NotDigit(uc16 c) { } -static bool IsWhiteSpace(uc16 c) { - switch (c) { - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0d: - case 0x20: - case 0xA0: - case 0x2028: - case 0x2029: - case 0xFEFF: - return true; - default: - return unibrow::Space::Is(c); - } +static bool IsWhiteSpaceOrLineTerminator(uc16 c) { + // According to ECMA 5.1, 15.10.2.12 the CharacterClassEscape \s includes + // WhiteSpace (7.2) and LineTerminator (7.3) values. + return v8::internal::WhiteSpaceOrLineTerminator::Is(c); } -static bool NotWhiteSpace(uc16 c) { - return !IsWhiteSpace(c); +static bool NotWhiteSpaceNorLineTermiantor(uc16 c) { + return !IsWhiteSpaceOrLineTerminator(c); } @@ -494,8 +487,8 @@ TEST(CharacterClassEscapes) { TestCharacterClassEscapes('.', IsRegExpNewline); TestCharacterClassEscapes('d', IsDigit); TestCharacterClassEscapes('D', NotDigit); - TestCharacterClassEscapes('s', IsWhiteSpace); - TestCharacterClassEscapes('S', NotWhiteSpace); + TestCharacterClassEscapes('s', IsWhiteSpaceOrLineTerminator); + TestCharacterClassEscapes('S', NotWhiteSpaceNorLineTermiantor); TestCharacterClassEscapes('w', IsRegExpWord); TestCharacterClassEscapes('W', NotWord); } @@ -539,7 +532,6 @@ static void Execute(const char* input, #ifdef DEBUG if (dot_output) { RegExpEngine::DotPrint(input, node, false); - exit(0); } #endif // DEBUG } @@ -702,6 +694,8 @@ typedef RegExpMacroAssemblerIA32 ArchRegExpMacroAssembler; typedef RegExpMacroAssemblerX64 ArchRegExpMacroAssembler; #elif V8_TARGET_ARCH_ARM typedef RegExpMacroAssemblerARM ArchRegExpMacroAssembler; +#elif V8_TARGET_ARCH_A64 +typedef RegExpMacroAssemblerA64 ArchRegExpMacroAssembler; #elif V8_TARGET_ARCH_MIPS typedef RegExpMacroAssemblerMIPS ArchRegExpMacroAssembler; #endif diff --git a/deps/v8/test/cctest/test-reloc-info.cc b/deps/v8/test/cctest/test-reloc-info.cc index e638201db2..5ab9e803c2 100644 --- a/deps/v8/test/cctest/test-reloc-info.cc +++ b/deps/v8/test/cctest/test-reloc-info.cc @@ -47,8 +47,8 @@ TEST(Positions) { const int buffer_size = code_size + relocation_info_size; SmartArrayPointer<byte> buffer(new byte[buffer_size]); - byte* pc = *buffer; - byte* buffer_end = *buffer + buffer_size; + byte* pc = buffer.get(); + byte* buffer_end = buffer.get() + buffer_size; RelocInfoWriter writer(buffer_end, pc); byte* relocation_info_end = buffer_end - relocation_info_size; @@ -60,13 +60,13 @@ TEST(Positions) { } relocation_info_size = static_cast<int>(buffer_end - writer.pos()); - CodeDesc desc = { *buffer, buffer_size, code_size, + CodeDesc desc = { buffer.get(), buffer_size, code_size, relocation_info_size, NULL }; // Read only (non-statement) positions. { RelocIterator it(desc, RelocInfo::ModeMask(RelocInfo::POSITION)); - pc = *buffer; + pc = buffer.get(); for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) { RelocInfo::Mode mode = (i % 2 == 0) ? RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION; @@ -83,7 +83,7 @@ TEST(Positions) { // Read only statement positions. { RelocIterator it(desc, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION)); - pc = *buffer; + pc = buffer.get(); for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) { RelocInfo::Mode mode = (i % 2 == 0) ? RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION; @@ -100,7 +100,7 @@ TEST(Positions) { // Read both types of positions. { RelocIterator it(desc, RelocInfo::kPositionMask); - pc = *buffer; + pc = buffer.get(); for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) { RelocInfo::Mode mode = (i % 2 == 0) ? RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION; diff --git a/deps/v8/test/cctest/test-representation.cc b/deps/v8/test/cctest/test-representation.cc new file mode 100644 index 0000000000..95a65cbbf7 --- /dev/null +++ b/deps/v8/test/cctest/test-representation.cc @@ -0,0 +1,128 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "cctest.h" +#include "types.h" +#include "property-details.h" + +using namespace v8::internal; + + +void TestPairPositive(Representation more_general, + Representation less_general) { + CHECK(more_general.is_more_general_than(less_general)); +} + + +void TestPairNegative(Representation more_general, + Representation less_general) { + CHECK(!more_general.is_more_general_than(less_general)); +} + + +TEST(RepresentationMoreGeneralThan) { + TestPairNegative(Representation::None(), Representation::None()); + TestPairPositive(Representation::Integer8(), Representation::None()); + TestPairPositive(Representation::UInteger8(), Representation::None()); + TestPairPositive(Representation::Integer16(), Representation::None()); + TestPairPositive(Representation::UInteger16(), Representation::None()); + TestPairPositive(Representation::Smi(), Representation::None()); + TestPairPositive(Representation::Integer32(), Representation::None()); + TestPairPositive(Representation::HeapObject(), Representation::None()); + TestPairPositive(Representation::Double(), Representation::None()); + TestPairPositive(Representation::Tagged(), Representation::None()); + + TestPairNegative(Representation::None(), Representation::Integer8()); + TestPairNegative(Representation::Integer8(), Representation::Integer8()); + TestPairNegative(Representation::UInteger8(), Representation::Integer8()); + TestPairPositive(Representation::Integer16(), Representation::Integer8()); + TestPairPositive(Representation::UInteger16(), Representation::Integer8()); + TestPairPositive(Representation::Smi(), Representation::Integer8()); + TestPairPositive(Representation::Integer32(), Representation::Integer8()); + TestPairNegative(Representation::HeapObject(), Representation::Integer8()); + TestPairPositive(Representation::Double(), Representation::Integer8()); + TestPairPositive(Representation::Tagged(), Representation::Integer8()); + + TestPairNegative(Representation::None(), Representation::UInteger8()); + TestPairNegative(Representation::Integer8(), Representation::UInteger8()); + TestPairNegative(Representation::UInteger8(), Representation::UInteger8()); + TestPairPositive(Representation::Integer16(), Representation::UInteger8()); + TestPairPositive(Representation::UInteger16(), Representation::UInteger8()); + TestPairPositive(Representation::Smi(), Representation::UInteger8()); + TestPairPositive(Representation::Integer32(), Representation::UInteger8()); + TestPairNegative(Representation::HeapObject(), Representation::UInteger8()); + TestPairPositive(Representation::Double(), Representation::UInteger8()); + TestPairPositive(Representation::Tagged(), Representation::UInteger8()); + + TestPairNegative(Representation::None(), Representation::Integer16()); + TestPairNegative(Representation::Integer8(), Representation::Integer16()); + TestPairNegative(Representation::UInteger8(), Representation::Integer16()); + TestPairNegative(Representation::Integer16(), Representation::Integer16()); + TestPairNegative(Representation::UInteger16(), Representation::Integer16()); + TestPairPositive(Representation::Smi(), Representation::Integer16()); + TestPairPositive(Representation::Integer32(), Representation::Integer16()); + TestPairNegative(Representation::HeapObject(), Representation::Integer16()); + TestPairPositive(Representation::Double(), Representation::Integer16()); + TestPairPositive(Representation::Tagged(), Representation::Integer16()); + + TestPairNegative(Representation::None(), Representation::UInteger16()); + TestPairNegative(Representation::Integer8(), Representation::UInteger16()); + TestPairNegative(Representation::UInteger8(), Representation::UInteger16()); + TestPairNegative(Representation::Integer16(), Representation::UInteger16()); + TestPairNegative(Representation::UInteger16(), Representation::UInteger16()); + TestPairPositive(Representation::Smi(), Representation::UInteger16()); + TestPairPositive(Representation::Integer32(), Representation::UInteger16()); + TestPairNegative(Representation::HeapObject(), Representation::UInteger16()); + TestPairPositive(Representation::Double(), Representation::UInteger16()); + TestPairPositive(Representation::Tagged(), Representation::UInteger16()); + + TestPairNegative(Representation::None(), Representation::Smi()); + TestPairNegative(Representation::Integer8(), Representation::Smi()); + TestPairNegative(Representation::UInteger8(), Representation::Smi()); + TestPairNegative(Representation::Integer16(), Representation::Smi()); + TestPairNegative(Representation::UInteger16(), Representation::Smi()); + TestPairNegative(Representation::Smi(), Representation::Smi()); + TestPairPositive(Representation::Integer32(), Representation::Smi()); + TestPairNegative(Representation::HeapObject(), Representation::Smi()); + TestPairPositive(Representation::Double(), Representation::Smi()); + TestPairPositive(Representation::Tagged(), Representation::Smi()); + + TestPairNegative(Representation::None(), Representation::Integer32()); + TestPairNegative(Representation::Integer8(), Representation::Integer32()); + TestPairNegative(Representation::UInteger8(), Representation::Integer32()); + TestPairNegative(Representation::Integer16(), Representation::Integer32()); + TestPairNegative(Representation::UInteger16(), Representation::Integer32()); + TestPairNegative(Representation::Smi(), Representation::Integer32()); + TestPairNegative(Representation::Integer32(), Representation::Integer32()); + TestPairNegative(Representation::HeapObject(), Representation::Integer32()); + TestPairPositive(Representation::Double(), Representation::Integer32()); + TestPairPositive(Representation::Tagged(), Representation::Integer32()); + + TestPairNegative(Representation::None(), Representation::External()); + TestPairNegative(Representation::External(), Representation::External()); + TestPairPositive(Representation::External(), Representation::None()); +} diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index 4132d2d4cf..c01a6889c3 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -347,7 +347,7 @@ DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) { env->Enter(); const char* c_source = "\"1234\".length"; - v8::Local<v8::String> source = v8::String::New(c_source); + v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, c_source); v8::Local<v8::Script> script = v8::Script::Compile(source); CHECK_EQ(4, script->Run()->Int32Value()); } @@ -365,7 +365,7 @@ DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2, env->Enter(); const char* c_source = "\"1234\".length"; - v8::Local<v8::String> source = v8::String::New(c_source); + v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, c_source); v8::Local<v8::Script> script = v8::Script::Compile(source); CHECK_EQ(4, script->Run()->Int32Value()); } @@ -402,7 +402,7 @@ TEST(PartialSerialization) { Object* raw_foo; { v8::HandleScope handle_scope(v8_isolate); - v8::Local<v8::String> foo = v8::String::New("foo"); + v8::Local<v8::String> foo = v8::String::NewFromUtf8(v8_isolate, "foo"); ASSERT(!foo.IsEmpty()); raw_foo = *(v8::Utils::OpenHandle(*foo)); } @@ -415,7 +415,7 @@ TEST(PartialSerialization) { v8::HandleScope handle_scope(v8_isolate); v8::Local<v8::Context>::New(v8_isolate, env)->Exit(); } - env.Dispose(); + env.Reset(); FileByteSink startup_sink(startup_name.start()); StartupSerializer startup_serializer(isolate, &startup_sink); @@ -562,7 +562,7 @@ TEST(ContextSerialization) { i::Object* raw_context = *v8::Utils::OpenPersistent(env); - env.Dispose(); + env.Reset(); FileByteSink startup_sink(startup_name.start()); StartupSerializer startup_serializer(isolate, &startup_sink); diff --git a/deps/v8/test/cctest/test-spaces.cc b/deps/v8/test/cctest/test-spaces.cc index 73710658a2..223912e37b 100644 --- a/deps/v8/test/cctest/test-spaces.cc +++ b/deps/v8/test/cctest/test-spaces.cc @@ -327,9 +327,9 @@ TEST(NewSpace) { CcTest::heap()->ReservedSemiSpaceSize())); CHECK(new_space.HasBeenSetUp()); - while (new_space.Available() >= Page::kMaxNonCodeHeapObjectSize) { + while (new_space.Available() >= Page::kMaxRegularHeapObjectSize) { Object* obj = - new_space.AllocateRaw(Page::kMaxNonCodeHeapObjectSize)-> + new_space.AllocateRaw(Page::kMaxRegularHeapObjectSize)-> ToObjectUnchecked(); CHECK(new_space.Contains(HeapObject::cast(obj))); } @@ -359,7 +359,7 @@ TEST(OldSpace) { CHECK(s->SetUp()); while (s->Available() > 0) { - s->AllocateRaw(Page::kMaxNonCodeHeapObjectSize)->ToObjectUnchecked(); + s->AllocateRaw(Page::kMaxRegularHeapObjectSize)->ToObjectUnchecked(); } s->TearDown(); diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc index 4aa74a8191..4b31e614d5 100644 --- a/deps/v8/test/cctest/test-strings.cc +++ b/deps/v8/test/cctest/test-strings.cc @@ -38,7 +38,6 @@ #include "factory.h" #include "objects.h" #include "cctest.h" -#include "zone-inl.h" // Adapted from http://en.wikipedia.org/wiki/Multiply-with-carry class MyRandomNumberGenerator { @@ -100,12 +99,10 @@ static const int DEEP_DEPTH = 8 * 1024; static const int SUPER_DEEP_DEPTH = 80 * 1024; -class Resource: public v8::String::ExternalStringResource, - public ZoneObject { +class Resource: public v8::String::ExternalStringResource { public: - explicit Resource(Vector<const uc16> string): data_(string.start()) { - length_ = string.length(); - } + Resource(const uc16* data, size_t length): data_(data), length_(length) {} + ~Resource() { i::DeleteArray(data_); } virtual const uint16_t* data() const { return data_; } virtual size_t length() const { return length_; } @@ -115,12 +112,11 @@ class Resource: public v8::String::ExternalStringResource, }; -class AsciiResource: public v8::String::ExternalAsciiStringResource, - public ZoneObject { +class AsciiResource: public v8::String::ExternalAsciiStringResource { public: - explicit AsciiResource(Vector<const char> string): data_(string.start()) { - length_ = string.length(); - } + AsciiResource(const char* data, size_t length) + : data_(data), length_(length) {} + ~AsciiResource() { i::DeleteArray(data_); } virtual const char* data() const { return data_; } virtual size_t length() const { return length_; } @@ -133,8 +129,7 @@ class AsciiResource: public v8::String::ExternalAsciiStringResource, static void InitializeBuildingBlocks(Handle<String>* building_blocks, int bb_length, bool long_blocks, - MyRandomNumberGenerator* rng, - Zone* zone) { + MyRandomNumberGenerator* rng) { // A list of pointers that we don't have any interest in cleaning up. // If they are reachable from a root then leak detection won't complain. Isolate* isolate = CcTest::i_isolate(); @@ -189,25 +184,28 @@ static void InitializeBuildingBlocks(Handle<String>* building_blocks, break; } case 2: { - uc16* buf = zone->NewArray<uc16>(len); + uc16* buf = NewArray<uc16>(len); for (int j = 0; j < len; j++) { buf[j] = rng->next(0x10000); } - Resource* resource = new(zone) Resource(Vector<const uc16>(buf, len)); - building_blocks[i] = factory->NewExternalStringFromTwoByte(resource); + Resource* resource = new Resource(buf, len); + building_blocks[i] = + v8::Utils::OpenHandle( + *v8::String::NewExternal(CcTest::isolate(), resource)); for (int j = 0; j < len; j++) { CHECK_EQ(buf[j], building_blocks[i]->Get(j)); } break; } case 3: { - char* buf = zone->NewArray<char>(len); + char* buf = NewArray<char>(len); for (int j = 0; j < len; j++) { buf[j] = rng->next(0x80); } - AsciiResource* resource = - new(zone) AsciiResource(Vector<const char>(buf, len)); - building_blocks[i] = factory->NewExternalStringFromAscii(resource); + AsciiResource* resource = new AsciiResource(buf, len); + building_blocks[i] = + v8::Utils::OpenHandle( + *v8::String::NewExternal(CcTest::isolate(), resource)); for (int j = 0; j < len; j++) { CHECK_EQ(buf[j], building_blocks[i]->Get(j)); } @@ -263,7 +261,7 @@ void ConsStringStats::VerifyEqual(const ConsStringStats& that) const { class ConsStringGenerationData { public: static const int kNumberOfBuildingBlocks = 256; - ConsStringGenerationData(bool long_blocks, Zone* zone); + explicit ConsStringGenerationData(bool long_blocks); void Reset(); inline Handle<String> block(int offset); inline Handle<String> block(uint32_t offset); @@ -285,11 +283,10 @@ class ConsStringGenerationData { }; -ConsStringGenerationData::ConsStringGenerationData(bool long_blocks, - Zone* zone) { +ConsStringGenerationData::ConsStringGenerationData(bool long_blocks) { rng_.init(); InitializeBuildingBlocks( - building_blocks_, kNumberOfBuildingBlocks, long_blocks, &rng_, zone); + building_blocks_, kNumberOfBuildingBlocks, long_blocks, &rng_); empty_string_ = CcTest::heap()->empty_string(); Reset(); } @@ -571,8 +568,7 @@ TEST(Traverse) { printf("TestTraverse\n"); CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - Zone zone(CcTest::i_isolate()); - ConsStringGenerationData data(false, &zone); + ConsStringGenerationData data(false); Handle<String> flat = ConstructBalanced(&data); FlattenString(flat); Handle<String> left_asymmetric = ConstructLeft(&data, DEEP_DEPTH); @@ -661,8 +657,7 @@ void TestStringCharacterStream(BuildString build, int test_cases) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope outer_scope(isolate); - Zone zone(isolate); - ConsStringGenerationData data(true, &zone); + ConsStringGenerationData data(true); for (int i = 0; i < test_cases; i++) { printf("%d\n", i); HandleScope inner_scope(isolate); @@ -889,9 +884,9 @@ TEST(Utf8Conversion) { v8::HandleScope handle_scope(CcTest::isolate()); // A simple ascii string const char* ascii_string = "abcdef12345"; - int len = - v8::String::New(ascii_string, - StrLength(ascii_string))->Utf8Length(); + int len = v8::String::NewFromUtf8(CcTest::isolate(), ascii_string, + v8::String::kNormalString, + StrLength(ascii_string))->Utf8Length(); CHECK_EQ(StrLength(ascii_string), len); // A mixed ascii and non-ascii string // U+02E4 -> CB A4 @@ -906,7 +901,8 @@ TEST(Utf8Conversion) { // The number of bytes expected to be written for each length const int lengths[12] = {0, 0, 2, 3, 3, 3, 6, 7, 7, 7, 10, 11}; const int char_lengths[12] = {0, 0, 1, 2, 2, 2, 3, 4, 4, 4, 5, 5}; - v8::Handle<v8::String> mixed = v8::String::New(mixed_string, 5); + v8::Handle<v8::String> mixed = v8::String::NewFromTwoByte( + CcTest::isolate(), mixed_string, v8::String::kNormalString, 5); CHECK_EQ(10, mixed->Utf8Length()); // Try encoding the string with all capacities char buffer[11]; @@ -930,9 +926,6 @@ TEST(Utf8Conversion) { TEST(ExternalShortStringAdd) { - Isolate* isolate = CcTest::i_isolate(); - Zone zone(isolate); - LocalContext context; v8::HandleScope handle_scope(CcTest::isolate()); @@ -942,34 +935,34 @@ TEST(ExternalShortStringAdd) { // Allocate two JavaScript arrays for holding short strings. v8::Handle<v8::Array> ascii_external_strings = - v8::Array::New(kMaxLength + 1); + v8::Array::New(CcTest::isolate(), kMaxLength + 1); v8::Handle<v8::Array> non_ascii_external_strings = - v8::Array::New(kMaxLength + 1); + v8::Array::New(CcTest::isolate(), kMaxLength + 1); // Generate short ascii and non-ascii external strings. for (int i = 0; i <= kMaxLength; i++) { - char* ascii = zone.NewArray<char>(i + 1); + char* ascii = NewArray<char>(i + 1); for (int j = 0; j < i; j++) { ascii[j] = 'a'; } // Terminating '\0' is left out on purpose. It is not required for external // string data. - AsciiResource* ascii_resource = - new(&zone) AsciiResource(Vector<const char>(ascii, i)); + AsciiResource* ascii_resource = new AsciiResource(ascii, i); v8::Local<v8::String> ascii_external_string = - v8::String::NewExternal(ascii_resource); + v8::String::NewExternal(CcTest::isolate(), ascii_resource); - ascii_external_strings->Set(v8::Integer::New(i), ascii_external_string); - uc16* non_ascii = zone.NewArray<uc16>(i + 1); + ascii_external_strings->Set(v8::Integer::New(CcTest::isolate(), i), + ascii_external_string); + uc16* non_ascii = NewArray<uc16>(i + 1); for (int j = 0; j < i; j++) { non_ascii[j] = 0x1234; } // Terminating '\0' is left out on purpose. It is not required for external // string data. - Resource* resource = new(&zone) Resource(Vector<const uc16>(non_ascii, i)); + Resource* resource = new Resource(non_ascii, i); v8::Local<v8::String> non_ascii_external_string = - v8::String::NewExternal(resource); - non_ascii_external_strings->Set(v8::Integer::New(i), + v8::String::NewExternal(CcTest::isolate(), resource); + non_ascii_external_strings->Set(v8::Integer::New(CcTest::isolate(), i), non_ascii_external_string); } @@ -977,7 +970,8 @@ TEST(ExternalShortStringAdd) { v8::Handle<v8::Object> global = context->Global(); global->Set(v8_str("external_ascii"), ascii_external_strings); global->Set(v8_str("external_non_ascii"), non_ascii_external_strings); - global->Set(v8_str("max_length"), v8::Integer::New(kMaxLength)); + global->Set(v8_str("max_length"), + v8::Integer::New(CcTest::isolate(), kMaxLength)); // Add short external ascii and non-ascii strings checking the result. static const char* source = @@ -1019,8 +1013,6 @@ TEST(ExternalShortStringAdd) { TEST(JSONStringifySliceMadeExternal) { CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - Zone zone(isolate); // Create a sliced string from a one-byte string. The latter is turned // into a two-byte external string. Check that JSON.stringify works. v8::HandleScope handle_scope(CcTest::isolate()); @@ -1034,10 +1026,9 @@ TEST(JSONStringifySliceMadeExternal) { CHECK(v8::Utils::OpenHandle(*underlying)->IsSeqOneByteString()); int length = underlying->Length(); - uc16* two_byte = zone.NewArray<uc16>(length + 1); + uc16* two_byte = NewArray<uc16>(length + 1); underlying->Write(two_byte); - Resource* resource = - new(&zone) Resource(Vector<const uc16>(two_byte, length)); + Resource* resource = new Resource(two_byte, length); CHECK(underlying->MakeExternal(resource)); CHECK(v8::Utils::OpenHandle(*slice)->IsSlicedString()); CHECK(v8::Utils::OpenHandle(*underlying)->IsExternalTwoByteString()); @@ -1053,7 +1044,6 @@ TEST(CachedHashOverflow) { // values didn't fit in the hash field. // See http://code.google.com/p/v8/issues/detail?id=728 Isolate* isolate = CcTest::i_isolate(); - Zone zone(isolate); v8::HandleScope handle_scope(CcTest::isolate()); // Lines must be executed sequentially. Combining them into one script @@ -1083,8 +1073,8 @@ TEST(CachedHashOverflow) { const char* line; for (int i = 0; (line = lines[i]); i++) { printf("%s\n", line); - v8::Local<v8::Value> result = - v8::Script::Compile(v8::String::New(line))->Run(); + v8::Local<v8::Value> result = v8::Script::Compile( + v8::String::NewFromUtf8(CcTest::isolate(), line))->Run(); CHECK_EQ(results[i]->IsUndefined(), result->IsUndefined()); CHECK_EQ(results[i]->IsNumber(), result->IsNumber()); if (result->IsNumber()) { @@ -1174,7 +1164,7 @@ TEST(TrivialSlice) { CHECK(result->IsString()); string = v8::Utils::OpenHandle(v8::String::Cast(*result)); CHECK(string->IsSlicedString()); - CHECK_EQ("bcdefghijklmnopqrstuvwxy", *(string->ToCString())); + CHECK_EQ("bcdefghijklmnopqrstuvwxy", string->ToCString().get()); } @@ -1196,14 +1186,14 @@ TEST(SliceFromSlice) { string = v8::Utils::OpenHandle(v8::String::Cast(*result)); CHECK(string->IsSlicedString()); CHECK(SlicedString::cast(*string)->parent()->IsSeqString()); - CHECK_EQ("bcdefghijklmnopqrstuvwxy", *(string->ToCString())); + CHECK_EQ("bcdefghijklmnopqrstuvwxy", string->ToCString().get()); result = CompileRun(slice_from_slice); CHECK(result->IsString()); string = v8::Utils::OpenHandle(v8::String::Cast(*result)); CHECK(string->IsSlicedString()); CHECK(SlicedString::cast(*string)->parent()->IsSeqString()); - CHECK_EQ("cdefghijklmnopqrstuvwx", *(string->ToCString())); + CHECK_EQ("cdefghijklmnopqrstuvwx", string->ToCString().get()); } @@ -1213,7 +1203,7 @@ TEST(AsciiArrayJoin) { v8::ResourceConstraints constraints; constraints.set_max_young_space_size(256 * K); constraints.set_max_old_space_size(4 * K * K); - v8::SetResourceConstraints(&constraints); + v8::SetResourceConstraints(CcTest::isolate(), &constraints); // String s is made of 2^17 = 131072 'c' characters and a is an array // starting with 'bad', followed by 2^14 times the string s. That means the @@ -1230,8 +1220,8 @@ TEST(AsciiArrayJoin) { v8::HandleScope scope(CcTest::isolate()); LocalContext context; v8::V8::IgnoreOutOfMemoryException(); - v8::Local<v8::Script> script = - v8::Script::Compile(v8::String::New(join_causing_out_of_memory)); + v8::Local<v8::Script> script = v8::Script::Compile( + v8::String::NewFromUtf8(CcTest::isolate(), join_causing_out_of_memory)); v8::Local<v8::Value> result = script->Run(); // Check for out of memory state. @@ -1268,7 +1258,7 @@ TEST(RobustSubStringStub) { // Ordinary HeapNumbers can be handled (in runtime). result = CompileRun("%_SubString(short, Math.sqrt(4), 5.1);"); string = v8::Utils::OpenHandle(v8::String::Cast(*result)); - CHECK_EQ("cde", *(string->ToCString())); + CHECK_EQ("cde", string->ToCString().get()); CompileRun("var long = 'abcdefghijklmnopqrstuvwxyz';"); // Invalid indices. @@ -1283,7 +1273,7 @@ TEST(RobustSubStringStub) { // Ordinary HeapNumbers within bounds can be handled (in runtime). result = CompileRun("%_SubString(long, Math.sqrt(4), 17.1);"); string = v8::Utils::OpenHandle(v8::String::Cast(*result)); - CHECK_EQ("cdefghijklmnopq", *(string->ToCString())); + CHECK_EQ("cdefghijklmnopq", string->ToCString().get()); // Test that out-of-bounds substring of a slice fails when the indices // would have been valid for the underlying string. diff --git a/deps/v8/test/cctest/test-symbols.cc b/deps/v8/test/cctest/test-symbols.cc index a04ffa70c5..6fceea6135 100644 --- a/deps/v8/test/cctest/test-symbols.cc +++ b/deps/v8/test/cctest/test-symbols.cc @@ -37,7 +37,7 @@ TEST(Create) { #endif } - CcTest::heap()->PerformScavenge(); + CcTest::heap()->CollectGarbage(i::NEW_SPACE); CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); // All symbols should be distinct. diff --git a/deps/v8/test/cctest/test-thread-termination.cc b/deps/v8/test/cctest/test-thread-termination.cc index 13f594096f..569ee95c64 100644 --- a/deps/v8/test/cctest/test-thread-termination.cc +++ b/deps/v8/test/cctest/test-thread-termination.cc @@ -51,8 +51,8 @@ void Fail(const v8::FunctionCallbackInfo<v8::Value>& args) { void Loop(const v8::FunctionCallbackInfo<v8::Value>& args) { CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); - v8::Handle<v8::String> source = - v8::String::New("try { doloop(); fail(); } catch(e) { fail(); }"); + v8::Handle<v8::String> source = v8::String::NewFromUtf8( + args.GetIsolate(), "try { doloop(); fail(); } catch(e) { fail(); }"); v8::Handle<v8::Value> result = v8::Script::Compile(source)->Run(); CHECK(result.IsEmpty()); CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate())); @@ -62,19 +62,20 @@ void Loop(const v8::FunctionCallbackInfo<v8::Value>& args) { void DoLoop(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::TryCatch try_catch; CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); - v8::Script::Compile(v8::String::New("function f() {" - " var term = true;" - " try {" - " while(true) {" - " if (term) terminate();" - " term = false;" - " }" - " fail();" - " } catch(e) {" - " fail();" - " }" - "}" - "f()"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(), + "function f() {" + " var term = true;" + " try {" + " while(true) {" + " if (term) terminate();" + " term = false;" + " }" + " fail();" + " } catch(e) {" + " fail();" + " }" + "}" + "f()"))->Run(); CHECK(try_catch.HasCaught()); CHECK(try_catch.Exception()->IsNull()); CHECK(try_catch.Message().IsEmpty()); @@ -86,11 +87,12 @@ void DoLoop(const v8::FunctionCallbackInfo<v8::Value>& args) { void DoLoopNoCall(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::TryCatch try_catch; CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); - v8::Script::Compile(v8::String::New("var term = true;" - "while(true) {" - " if (term) terminate();" - " term = false;" - "}"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(), + "var term = true;" + "while(true) {" + " if (term) terminate();" + " term = false;" + "}"))->Run(); CHECK(try_catch.HasCaught()); CHECK(try_catch.Exception()->IsNull()); CHECK(try_catch.Message().IsEmpty()); @@ -100,14 +102,18 @@ void DoLoopNoCall(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::Handle<v8::ObjectTemplate> CreateGlobalTemplate( + v8::Isolate* isolate, v8::FunctionCallback terminate, v8::FunctionCallback doloop) { - v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); - global->Set(v8::String::New("terminate"), - v8::FunctionTemplate::New(terminate)); - global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail)); - global->Set(v8::String::New("loop"), v8::FunctionTemplate::New(Loop)); - global->Set(v8::String::New("doloop"), v8::FunctionTemplate::New(doloop)); + v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); + global->Set(v8::String::NewFromUtf8(isolate, "terminate"), + v8::FunctionTemplate::New(isolate, terminate)); + global->Set(v8::String::NewFromUtf8(isolate, "fail"), + v8::FunctionTemplate::New(isolate, Fail)); + global->Set(v8::String::NewFromUtf8(isolate, "loop"), + v8::FunctionTemplate::New(isolate, Loop)); + global->Set(v8::String::NewFromUtf8(isolate, "doloop"), + v8::FunctionTemplate::New(isolate, doloop)); return global; } @@ -117,14 +123,14 @@ v8::Handle<v8::ObjectTemplate> CreateGlobalTemplate( TEST(TerminateOnlyV8ThreadFromThreadItself) { v8::HandleScope scope(CcTest::isolate()); v8::Handle<v8::ObjectTemplate> global = - CreateGlobalTemplate(TerminateCurrentThread, DoLoop); + CreateGlobalTemplate(CcTest::isolate(), TerminateCurrentThread, DoLoop); v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate(), NULL, global); v8::Context::Scope context_scope(context); CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); // Run a loop that will be infinite if thread termination does not work. - v8::Handle<v8::String> source = - v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); + v8::Handle<v8::String> source = v8::String::NewFromUtf8( + CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }"); v8::Script::Compile(source)->Run(); // Test that we can run the code again after thread termination. CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); @@ -136,15 +142,15 @@ TEST(TerminateOnlyV8ThreadFromThreadItself) { // itself in a loop that performs no calls. TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) { v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> global = - CreateGlobalTemplate(TerminateCurrentThread, DoLoopNoCall); + v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate( + CcTest::isolate(), TerminateCurrentThread, DoLoopNoCall); v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate(), NULL, global); v8::Context::Scope context_scope(context); CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); // Run a loop that will be infinite if thread termination does not work. - v8::Handle<v8::String> source = - v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); + v8::Handle<v8::String> source = v8::String::NewFromUtf8( + CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }"); v8::Script::Compile(source)->Run(); CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); // Test that we can run the code again after thread termination. @@ -176,14 +182,15 @@ TEST(TerminateOnlyV8ThreadFromOtherThread) { thread.Start(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(Signal, DoLoop); + v8::Handle<v8::ObjectTemplate> global = + CreateGlobalTemplate(CcTest::isolate(), Signal, DoLoop); v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate(), NULL, global); v8::Context::Scope context_scope(context); CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); // Run a loop that will be infinite if thread termination does not work. - v8::Handle<v8::String> source = - v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); + v8::Handle<v8::String> source = v8::String::NewFromUtf8( + CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }"); v8::Script::Compile(source)->Run(); thread.Join(); @@ -201,8 +208,9 @@ void TerminateOrReturnObject(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::V8::TerminateExecution(args.GetIsolate()); return; } - v8::Local<v8::Object> result = v8::Object::New(); - result->Set(v8::String::New("x"), v8::Integer::New(42)); + v8::Local<v8::Object> result = v8::Object::New(args.GetIsolate()); + result->Set(v8::String::NewFromUtf8(args.GetIsolate(), "x"), + v8::Integer::New(args.GetIsolate(), 42)); args.GetReturnValue().Set(result); } @@ -210,17 +218,19 @@ void TerminateOrReturnObject(const v8::FunctionCallbackInfo<v8::Value>& args) { void LoopGetProperty(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::TryCatch try_catch; CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); - v8::Script::Compile(v8::String::New("function f() {" - " try {" - " while(true) {" - " terminate_or_return_object().x;" - " }" - " fail();" - " } catch(e) {" - " fail();" - " }" - "}" - "f()"))->Run(); + v8::Script::Compile( + v8::String::NewFromUtf8(args.GetIsolate(), + "function f() {" + " try {" + " while(true) {" + " terminate_or_return_object().x;" + " }" + " fail();" + " } catch(e) {" + " fail();" + " }" + "}" + "f()"))->Run(); CHECK(try_catch.HasCaught()); CHECK(try_catch.Exception()->IsNull()); CHECK(try_catch.Message().IsEmpty()); @@ -232,25 +242,28 @@ void LoopGetProperty(const v8::FunctionCallbackInfo<v8::Value>& args) { // Test that we correctly handle termination exceptions if they are // triggered by the creation of error objects in connection with ICs. TEST(TerminateLoadICException) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); - global->Set(v8::String::New("terminate_or_return_object"), - v8::FunctionTemplate::New(TerminateOrReturnObject)); - global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail)); - global->Set(v8::String::New("loop"), - v8::FunctionTemplate::New(LoopGetProperty)); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); + global->Set( + v8::String::NewFromUtf8(isolate, "terminate_or_return_object"), + v8::FunctionTemplate::New(isolate, TerminateOrReturnObject)); + global->Set(v8::String::NewFromUtf8(isolate, "fail"), + v8::FunctionTemplate::New(isolate, Fail)); + global->Set(v8::String::NewFromUtf8(isolate, "loop"), + v8::FunctionTemplate::New(isolate, LoopGetProperty)); v8::Handle<v8::Context> context = - v8::Context::New(CcTest::isolate(), NULL, global); + v8::Context::New(isolate, NULL, global); v8::Context::Scope context_scope(context); - CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); + CHECK(!v8::V8::IsExecutionTerminating(isolate)); // Run a loop that will be infinite if thread termination does not work. - v8::Handle<v8::String> source = - v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); + v8::Handle<v8::String> source = v8::String::NewFromUtf8( + isolate, "try { loop(); fail(); } catch(e) { fail(); }"); call_count = 0; v8::Script::Compile(source)->Run(); // Test that we can run the code again after thread termination. - CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); + CHECK(!v8::V8::IsExecutionTerminating(isolate)); call_count = 0; v8::Script::Compile(source)->Run(); } @@ -259,57 +272,66 @@ TEST(TerminateLoadICException) { void ReenterAfterTermination(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::TryCatch try_catch; CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate())); - v8::Script::Compile(v8::String::New("function f() {" - " var term = true;" - " try {" - " while(true) {" - " if (term) terminate();" - " term = false;" - " }" - " fail();" - " } catch(e) {" - " fail();" - " }" - "}" - "f()"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(), + "function f() {" + " var term = true;" + " try {" + " while(true) {" + " if (term) terminate();" + " term = false;" + " }" + " fail();" + " } catch(e) {" + " fail();" + " }" + "}" + "f()"))->Run(); CHECK(try_catch.HasCaught()); CHECK(try_catch.Exception()->IsNull()); CHECK(try_catch.Message().IsEmpty()); CHECK(!try_catch.CanContinue()); CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate())); - v8::Script::Compile(v8::String::New("function f() { fail(); } f()"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(), + "function f() { fail(); } f()")) + ->Run(); } // Test that reentry into V8 while the termination exception is still pending // (has not yet unwound the 0-level JS frame) does not crash. TEST(TerminateAndReenterFromThreadItself) { - v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::ObjectTemplate> global = - CreateGlobalTemplate(TerminateCurrentThread, ReenterAfterTermination); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate( + isolate, TerminateCurrentThread, ReenterAfterTermination); v8::Handle<v8::Context> context = - v8::Context::New(CcTest::isolate(), NULL, global); + v8::Context::New(isolate, NULL, global); v8::Context::Scope context_scope(context); CHECK(!v8::V8::IsExecutionTerminating()); - v8::Handle<v8::String> source = - v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); + v8::Handle<v8::String> source = v8::String::NewFromUtf8( + isolate, "try { loop(); fail(); } catch(e) { fail(); }"); v8::Script::Compile(source)->Run(); - CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); + CHECK(!v8::V8::IsExecutionTerminating(isolate)); // Check we can run JS again after termination. - CHECK(v8::Script::Compile(v8::String::New("function f() { return true; }" - "f()"))->Run()->IsTrue()); + CHECK(v8::Script::Compile( + v8::String::NewFromUtf8(isolate, + "function f() { return true; }" + "f()")) + ->Run() + ->IsTrue()); } void DoLoopCancelTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::TryCatch try_catch; CHECK(!v8::V8::IsExecutionTerminating()); - v8::Script::Compile(v8::String::New("var term = true;" - "while(true) {" - " if (term) terminate();" - " term = false;" - "}" - "fail();"))->Run(); + v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(), + "var term = true;" + "while(true) {" + " if (term) terminate();" + " term = false;" + "}" + "fail();"))->Run(); CHECK(try_catch.HasCaught()); CHECK(try_catch.Exception()->IsNull()); CHECK(try_catch.Message().IsEmpty()); @@ -326,13 +348,13 @@ void DoLoopCancelTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(TerminateCancelTerminateFromThreadItself) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> global = - CreateGlobalTemplate(TerminateCurrentThread, DoLoopCancelTerminate); + v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate( + isolate, TerminateCurrentThread, DoLoopCancelTerminate); v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global); v8::Context::Scope context_scope(context); CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate())); - v8::Handle<v8::String> source = - v8::String::New("try { doloop(); } catch(e) { fail(); } 'completed';"); + v8::Handle<v8::String> source = v8::String::NewFromUtf8( + isolate, "try { doloop(); } catch(e) { fail(); } 'completed';"); // Check that execution completed with correct return value. CHECK(v8::Script::Compile(source)->Run()->Equals(v8_str("completed"))); } diff --git a/deps/v8/test/cctest/test-threads.cc b/deps/v8/test/cctest/test-threads.cc index 4709961636..24fb1d1d75 100644 --- a/deps/v8/test/cctest/test-threads.cc +++ b/deps/v8/test/cctest/test-threads.cc @@ -33,28 +33,6 @@ #include "cctest.h" -TEST(Preemption) { - v8::Isolate* isolate = CcTest::isolate(); - v8::Locker locker(isolate); - v8::V8::Initialize(); - v8::HandleScope scope(isolate); - v8::Handle<v8::Context> context = v8::Context::New(isolate); - v8::Context::Scope context_scope(context); - - v8::Locker::StartPreemption(isolate, 100); - - v8::Handle<v8::Script> script = v8::Script::Compile( - v8::String::New("var count = 0; var obj = new Object(); count++;\n")); - - script->Run(); - - v8::Locker::StopPreemption(isolate); - v8::internal::OS::Sleep(500); // Make sure the timer fires. - - script->Run(); -} - - enum Turn { FILL_CACHE, CLEAN_CACHE, @@ -80,7 +58,8 @@ class ThreadA : public v8::internal::Thread { // Fill String.search cache. v8::Handle<v8::Script> script = v8::Script::Compile( - v8::String::New( + v8::String::NewFromUtf8( + isolate, "for (var i = 0; i < 3; i++) {" " var result = \"a\".search(\"a\");" " if (result != 0) throw \"result: \" + result + \" @\" + i;" @@ -180,18 +159,18 @@ TEST(ThreadIdValidation) { const int kNThreads = 100; i::List<ThreadIdValidationThread*> threads(kNThreads); i::List<i::ThreadId> refs(kNThreads); - i::Semaphore* semaphore = new i::Semaphore(0); + i::Semaphore semaphore(0); ThreadIdValidationThread* prev = NULL; for (int i = kNThreads - 1; i >= 0; i--) { ThreadIdValidationThread* newThread = - new ThreadIdValidationThread(prev, &refs, i, semaphore); + new ThreadIdValidationThread(prev, &refs, i, &semaphore); threads.Add(newThread); prev = newThread; refs.Add(i::ThreadId::Invalid()); } prev->Start(); for (int i = 0; i < kNThreads; i++) { - semaphore->Wait(); + semaphore.Wait(); } for (int i = 0; i < kNThreads; i++) { delete threads[i]; diff --git a/deps/v8/test/cctest/test-time.cc b/deps/v8/test/cctest/test-time.cc index 28d647a5c1..1ef9e08f65 100644 --- a/deps/v8/test/cctest/test-time.cc +++ b/deps/v8/test/cctest/test-time.cc @@ -25,10 +25,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include <cstdlib> - #include "v8.h" +#if V8_OS_POSIX +#include <sys/time.h> // NOLINT +#endif + #include "cctest.h" #if V8_OS_WIN #include "win32-headers.h" diff --git a/deps/v8/test/cctest/test-types.cc b/deps/v8/test/cctest/test-types.cc index 264d2ed881..d29ee41100 100644 --- a/deps/v8/test/cctest/test-types.cc +++ b/deps/v8/test/cctest/test-types.cc @@ -30,716 +30,848 @@ using namespace v8::internal; +template<class Type, class TypeHandle, class Region> +class Types { + public: + Types(Region* region, Isolate* isolate) : + None(Type::None(region)), + Any(Type::Any(region)), + Oddball(Type::Oddball(region)), + Boolean(Type::Boolean(region)), + Null(Type::Null(region)), + Undefined(Type::Undefined(region)), + Number(Type::Number(region)), + Smi(Type::Smi(region)), + Signed32(Type::Signed32(region)), + Double(Type::Double(region)), + Name(Type::Name(region)), + UniqueName(Type::UniqueName(region)), + String(Type::String(region)), + InternalizedString(Type::InternalizedString(region)), + Symbol(Type::Symbol(region)), + Receiver(Type::Receiver(region)), + Object(Type::Object(region)), + Array(Type::Array(region)), + Function(Type::Function(region)), + Proxy(Type::Proxy(region)), + object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)), + array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)), + region_(region) { + smi = handle(Smi::FromInt(666), isolate); + signed32 = isolate->factory()->NewHeapNumber(0x40000000); + object1 = isolate->factory()->NewJSObjectFromMap(object_map); + object2 = isolate->factory()->NewJSObjectFromMap(object_map); + array = isolate->factory()->NewJSArray(20); + ObjectClass = Type::Class(object_map, region); + ArrayClass = Type::Class(array_map, region); + SmiConstant = Type::Constant(smi, region); + Signed32Constant = Type::Constant(signed32, region); + ObjectConstant1 = Type::Constant(object1, region); + ObjectConstant2 = Type::Constant(object2, region); + ArrayConstant1 = Type::Constant(array, region); + ArrayConstant2 = Type::Constant(array, region); + } + + TypeHandle None; + TypeHandle Any; + TypeHandle Oddball; + TypeHandle Boolean; + TypeHandle Null; + TypeHandle Undefined; + TypeHandle Number; + TypeHandle Smi; + TypeHandle Signed32; + TypeHandle Double; + TypeHandle Name; + TypeHandle UniqueName; + TypeHandle String; + TypeHandle InternalizedString; + TypeHandle Symbol; + TypeHandle Receiver; + TypeHandle Object; + TypeHandle Array; + TypeHandle Function; + TypeHandle Proxy; + + TypeHandle ObjectClass; + TypeHandle ArrayClass; + + TypeHandle SmiConstant; + TypeHandle Signed32Constant; + TypeHandle ObjectConstant1; + TypeHandle ObjectConstant2; + TypeHandle ArrayConstant1; + TypeHandle ArrayConstant2; + + Handle<i::Map> object_map; + Handle<i::Map> array_map; + + Handle<i::Smi> smi; + Handle<i::HeapNumber> signed32; + Handle<i::JSObject> object1; + Handle<i::JSObject> object2; + Handle<i::JSArray> array; + + TypeHandle Union(TypeHandle t1, TypeHandle t2) { + return Type::Union(t1, t2, region_); + } + TypeHandle Intersect(TypeHandle t1, TypeHandle t2) { + return Type::Intersect(t1, t2, region_); + } + + template<class Type2, class TypeHandle2> + TypeHandle Convert(TypeHandle2 t) { + return Type::template Convert<Type2>(t, region_); + } + + TypeHandle Fuzz(int depth = 5) { + switch (rand() % (depth == 0 ? 3 : 20)) { + case 0: { // bitset + int n = 0 + #define COUNT_BITSET_TYPES(type, value) + 1 + BITSET_TYPE_LIST(COUNT_BITSET_TYPES) + #undef COUNT_BITSET_TYPES + ; + int i = rand() % n; + #define PICK_BITSET_TYPE(type, value) \ + if (i-- == 0) return Type::type(region_); + BITSET_TYPE_LIST(PICK_BITSET_TYPE) + #undef PICK_BITSET_TYPE + UNREACHABLE(); + } + case 1: // class + switch (rand() % 2) { + case 0: return ObjectClass; + case 1: return ArrayClass; + } + UNREACHABLE(); + case 2: // constant + switch (rand() % 6) { + case 0: return SmiConstant; + case 1: return Signed32Constant; + case 2: return ObjectConstant1; + case 3: return ObjectConstant2; + case 4: return ArrayConstant1; + case 5: return ArrayConstant2; + } + UNREACHABLE(); + default: { // union + int n = rand() % 10; + TypeHandle type = None; + for (int i = 0; i < n; ++i) { + type = Type::Union(type, Fuzz(depth - 1), region_); + } + return type; + } + } + UNREACHABLE(); + } + + private: + Region* region_; +}; + + // Testing auxiliaries (breaking the Type abstraction). -static bool IsBitset(Type* type) { return type->IsSmi(); } -static bool IsClass(Type* type) { return type->IsMap(); } -static bool IsConstant(Type* type) { return type->IsBox(); } -static bool IsUnion(Type* type) { return type->IsFixedArray(); } - -static int AsBitset(Type* type) { return Smi::cast(type)->value(); } -static Map* AsClass(Type* type) { return Map::cast(type); } -static Object* AsConstant(Type* type) { return Box::cast(type)->value(); } -static FixedArray* AsUnion(Type* type) { return FixedArray::cast(type); } - - -static void CheckEqual(Handle<Type> type1, Handle<Type> type2) { - CHECK_EQ(IsBitset(*type1), IsBitset(*type2)); - CHECK_EQ(IsClass(*type1), IsClass(*type2)); - CHECK_EQ(IsConstant(*type1), IsConstant(*type2)); - CHECK_EQ(IsUnion(*type1), IsUnion(*type2)); - CHECK_EQ(type1->NumClasses(), type2->NumClasses()); - CHECK_EQ(type1->NumConstants(), type2->NumConstants()); - if (IsBitset(*type1)) { - CHECK_EQ(AsBitset(*type1), AsBitset(*type2)); - } else if (IsClass(*type1)) { - CHECK_EQ(AsClass(*type1), AsClass(*type2)); - } else if (IsConstant(*type1)) { - CHECK_EQ(AsConstant(*type1), AsConstant(*type2)); - } else if (IsUnion(*type1)) { - CHECK_EQ(AsUnion(*type1)->length(), AsUnion(*type2)->length()); +struct ZoneRep { + static bool IsTagged(Type* t, int tag) { + return !IsBitset(t) + && reinterpret_cast<intptr_t>(AsTagged(t)->at(0)) == tag; + } + static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; } + static bool IsClass(Type* t) { return IsTagged(t, 0); } + static bool IsConstant(Type* t) { return IsTagged(t, 1); } + static bool IsUnion(Type* t) { return IsTagged(t, 2); } + + static ZoneList<void*>* AsTagged(Type* t) { + return reinterpret_cast<ZoneList<void*>*>(t); + } + static int AsBitset(Type* t) { + return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1); + } + static Map* AsClass(Type* t) { + return *reinterpret_cast<Map**>(AsTagged(t)->at(1)); + } + static Object* AsConstant(Type* t) { + return *reinterpret_cast<Object**>(AsTagged(t)->at(1)); + } + static ZoneList<Type*>* AsUnion(Type* t) { + return reinterpret_cast<ZoneList<Type*>*>(AsTagged(t)); } - CHECK(type1->Is(type2)); - CHECK(type2->Is(type1)); -} + static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; } +}; -static void CheckSub(Handle<Type> type1, Handle<Type> type2) { - CHECK(type1->Is(type2)); - CHECK(!type2->Is(type1)); - if (IsBitset(*type1) && IsBitset(*type2)) { - CHECK_NE(AsBitset(*type1), AsBitset(*type2)); + +struct HeapRep { + static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); } + static bool IsClass(Handle<HeapType> t) { return t->IsMap(); } + static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); } + static bool IsUnion(Handle<HeapType> t) { return t->IsFixedArray(); } + + static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } + static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); } + static Object* AsConstant(Handle<HeapType> t) { + return Box::cast(*t)->value(); + } + static FixedArray* AsUnion(Handle<HeapType> t) { + return FixedArray::cast(*t); } -} + static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } +}; + + +template<class Type, class TypeHandle, class Region, class Rep> +struct Tests : Rep { + Isolate* isolate; + HandleScope scope; + Zone zone; + Types<Type, TypeHandle, Region> T; -static void CheckUnordered(Handle<Type> type1, Handle<Type> type2) { - CHECK(!type1->Is(type2)); - CHECK(!type2->Is(type1)); - if (IsBitset(*type1) && IsBitset(*type2)) { - CHECK_NE(AsBitset(*type1), AsBitset(*type2)); + Tests() : + isolate(CcTest::i_isolate()), + scope(isolate), + zone(isolate), + T(Rep::ToRegion(&zone, isolate), isolate) { } -} + static void CheckEqual(TypeHandle type1, TypeHandle type2) { + CHECK_EQ(Rep::IsBitset(type1), Rep::IsBitset(type2)); + CHECK_EQ(Rep::IsClass(type1), Rep::IsClass(type2)); + CHECK_EQ(Rep::IsConstant(type1), Rep::IsConstant(type2)); + CHECK_EQ(Rep::IsUnion(type1), Rep::IsUnion(type2)); + CHECK_EQ(type1->NumClasses(), type2->NumClasses()); + CHECK_EQ(type1->NumConstants(), type2->NumConstants()); + if (Rep::IsBitset(type1)) { + CHECK_EQ(Rep::AsBitset(type1), Rep::AsBitset(type2)); + } else if (Rep::IsClass(type1)) { + CHECK_EQ(Rep::AsClass(type1), Rep::AsClass(type2)); + } else if (Rep::IsConstant(type1)) { + CHECK_EQ(Rep::AsConstant(type1), Rep::AsConstant(type2)); + } else if (Rep::IsUnion(type1)) { + CHECK_EQ(Rep::AsUnion(type1)->length(), Rep::AsUnion(type2)->length()); + } + CHECK(type1->Is(type2)); + CHECK(type2->Is(type1)); + } -static void CheckOverlap(Handle<Type> type1, Handle<Type> type2) { - CHECK(type1->Maybe(type2)); - CHECK(type2->Maybe(type1)); - if (IsBitset(*type1) && IsBitset(*type2)) { - CHECK_NE(0, AsBitset(*type1) & AsBitset(*type2)); + static void CheckSub(TypeHandle type1, TypeHandle type2) { + CHECK(type1->Is(type2)); + CHECK(!type2->Is(type1)); + if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { + CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); + } } -} + static void CheckUnordered(TypeHandle type1, TypeHandle type2) { + CHECK(!type1->Is(type2)); + CHECK(!type2->Is(type1)); + if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { + CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); + } + } -static void CheckDisjoint(Handle<Type> type1, Handle<Type> type2) { - CHECK(!type1->Is(type2)); - CHECK(!type2->Is(type1)); - CHECK(!type1->Maybe(type2)); - CHECK(!type2->Maybe(type1)); - if (IsBitset(*type1) && IsBitset(*type2)) { - CHECK_EQ(0, AsBitset(*type1) & AsBitset(*type2)); + static void CheckOverlap(TypeHandle type1, TypeHandle type2) { + CHECK(type1->Maybe(type2)); + CHECK(type2->Maybe(type1)); + if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { + CHECK_NE(0, Rep::AsBitset(type1) & Rep::AsBitset(type2)); + } + } + + static void CheckDisjoint(TypeHandle type1, TypeHandle type2) { + CHECK(!type1->Is(type2)); + CHECK(!type2->Is(type1)); + CHECK(!type1->Maybe(type2)); + CHECK(!type2->Maybe(type1)); + if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { + CHECK_EQ(0, Rep::AsBitset(type1) & Rep::AsBitset(type2)); + } } -} + void Bitset() { + CHECK(this->IsBitset(T.None)); + CHECK(this->IsBitset(T.Any)); + CHECK(this->IsBitset(T.String)); + CHECK(this->IsBitset(T.Object)); -class HandlifiedTypes { - public: - explicit HandlifiedTypes(Isolate* isolate) : - None(Type::None(), isolate), - Any(Type::Any(), isolate), - Oddball(Type::Oddball(), isolate), - Boolean(Type::Boolean(), isolate), - Null(Type::Null(), isolate), - Undefined(Type::Undefined(), isolate), - Number(Type::Number(), isolate), - Smi(Type::Smi(), isolate), - Signed32(Type::Signed32(), isolate), - Double(Type::Double(), isolate), - Name(Type::Name(), isolate), - UniqueName(Type::UniqueName(), isolate), - String(Type::String(), isolate), - InternalizedString(Type::InternalizedString(), isolate), - Symbol(Type::Symbol(), isolate), - Receiver(Type::Receiver(), isolate), - Object(Type::Object(), isolate), - Array(Type::Array(), isolate), - Function(Type::Function(), isolate), - Proxy(Type::Proxy(), isolate), - object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)), - array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)), - isolate_(isolate) { - smi = handle(Smi::FromInt(666), isolate); - signed32 = isolate->factory()->NewHeapNumber(0x40000000); - object1 = isolate->factory()->NewJSObjectFromMap(object_map); - object2 = isolate->factory()->NewJSObjectFromMap(object_map); - array = isolate->factory()->NewJSArray(20); - ObjectClass = Class(object_map); - ArrayClass = Class(array_map); - SmiConstant = Constant(smi); - Signed32Constant = Constant(signed32); - ObjectConstant1 = Constant(object1); - ObjectConstant2 = Constant(object2); - ArrayConstant1 = Constant(array); - ArrayConstant2 = Constant(array); + CHECK(this->IsBitset(T.Union(T.String, T.Number))); + CHECK(this->IsBitset(T.Union(T.String, T.Receiver))); + + CHECK_EQ(0, this->AsBitset(T.None)); + CHECK_EQ(this->AsBitset(T.Number) | this->AsBitset(T.String), + this->AsBitset(T.Union(T.String, T.Number))); + CHECK_EQ(this->AsBitset(T.Receiver), + this->AsBitset(T.Union(T.Receiver, T.Object))); } - Handle<Type> None; - Handle<Type> Any; - Handle<Type> Oddball; - Handle<Type> Boolean; - Handle<Type> Null; - Handle<Type> Undefined; - Handle<Type> Number; - Handle<Type> Smi; - Handle<Type> Signed32; - Handle<Type> Double; - Handle<Type> Name; - Handle<Type> UniqueName; - Handle<Type> String; - Handle<Type> InternalizedString; - Handle<Type> Symbol; - Handle<Type> Receiver; - Handle<Type> Object; - Handle<Type> Array; - Handle<Type> Function; - Handle<Type> Proxy; - - Handle<Type> ObjectClass; - Handle<Type> ArrayClass; - - Handle<Type> SmiConstant; - Handle<Type> Signed32Constant; - Handle<Type> ObjectConstant1; - Handle<Type> ObjectConstant2; - Handle<Type> ArrayConstant1; - Handle<Type> ArrayConstant2; - - Handle<Map> object_map; - Handle<Map> array_map; + void Class() { + CHECK(this->IsClass(T.ObjectClass)); + CHECK(this->IsClass(T.ArrayClass)); - Handle<i::Smi> smi; - Handle<HeapNumber> signed32; - Handle<JSObject> object1; - Handle<JSObject> object2; - Handle<JSArray> array; + CHECK(*T.object_map == this->AsClass(T.ObjectClass)); + CHECK(*T.array_map == this->AsClass(T.ArrayClass)); + } - Handle<Type> Class(Handle<Map> map) { - return handle(Type::Class(map), isolate_); + void Constant() { + CHECK(this->IsConstant(T.SmiConstant)); + CHECK(this->IsConstant(T.ObjectConstant1)); + CHECK(this->IsConstant(T.ObjectConstant2)); + CHECK(this->IsConstant(T.ArrayConstant1)); + CHECK(this->IsConstant(T.ArrayConstant2)); + + CHECK(*T.smi == this->AsConstant(T.SmiConstant)); + CHECK(*T.object1 == this->AsConstant(T.ObjectConstant1)); + CHECK(*T.object2 == this->AsConstant(T.ObjectConstant2)); + CHECK(*T.object1 != this->AsConstant(T.ObjectConstant2)); + CHECK(*T.array == this->AsConstant(T.ArrayConstant1)); + CHECK(*T.array == this->AsConstant(T.ArrayConstant2)); } - Handle<Type> Constant(Handle<i::Object> value) { - return handle(Type::Constant(value, isolate_), isolate_); + + void Is() { + // Reflexivity + CHECK(T.None->Is(T.None)); + CHECK(T.Any->Is(T.Any)); + CHECK(T.Object->Is(T.Object)); + + CHECK(T.ObjectClass->Is(T.ObjectClass)); + CHECK(T.ObjectConstant1->Is(T.ObjectConstant1)); + CHECK(T.ArrayConstant1->Is(T.ArrayConstant2)); + + // Symmetry and Transitivity + CheckSub(T.None, T.Number); + CheckSub(T.None, T.Any); + + CheckSub(T.Oddball, T.Any); + CheckSub(T.Boolean, T.Oddball); + CheckSub(T.Null, T.Oddball); + CheckSub(T.Undefined, T.Oddball); + CheckUnordered(T.Boolean, T.Null); + CheckUnordered(T.Undefined, T.Null); + CheckUnordered(T.Boolean, T.Undefined); + + CheckSub(T.Number, T.Any); + CheckSub(T.Smi, T.Number); + CheckSub(T.Signed32, T.Number); + CheckSub(T.Double, T.Number); + CheckSub(T.Smi, T.Signed32); + CheckUnordered(T.Smi, T.Double); + CheckUnordered(T.Signed32, T.Double); + + CheckSub(T.Name, T.Any); + CheckSub(T.UniqueName, T.Any); + CheckSub(T.UniqueName, T.Name); + CheckSub(T.String, T.Name); + CheckSub(T.InternalizedString, T.String); + CheckSub(T.InternalizedString, T.UniqueName); + CheckSub(T.InternalizedString, T.Name); + CheckSub(T.Symbol, T.UniqueName); + CheckSub(T.Symbol, T.Name); + CheckUnordered(T.String, T.UniqueName); + CheckUnordered(T.String, T.Symbol); + CheckUnordered(T.InternalizedString, T.Symbol); + + CheckSub(T.Receiver, T.Any); + CheckSub(T.Object, T.Any); + CheckSub(T.Object, T.Receiver); + CheckSub(T.Array, T.Object); + CheckSub(T.Function, T.Object); + CheckSub(T.Proxy, T.Receiver); + CheckUnordered(T.Object, T.Proxy); + CheckUnordered(T.Array, T.Function); + + // Structured subtyping + CheckSub(T.None, T.ObjectClass); + CheckSub(T.None, T.ObjectConstant1); + CheckSub(T.ObjectClass, T.Any); + CheckSub(T.ObjectConstant1, T.Any); + + CheckSub(T.ObjectClass, T.Object); + CheckSub(T.ArrayClass, T.Object); + CheckUnordered(T.ObjectClass, T.ArrayClass); + + CheckSub(T.SmiConstant, T.Smi); + CheckSub(T.SmiConstant, T.Signed32); + CheckSub(T.SmiConstant, T.Number); + CheckSub(T.ObjectConstant1, T.Object); + CheckSub(T.ObjectConstant2, T.Object); + CheckSub(T.ArrayConstant1, T.Object); + CheckSub(T.ArrayConstant1, T.Array); + CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); + CheckUnordered(T.ObjectConstant1, T.ArrayConstant1); + + CheckUnordered(T.ObjectConstant1, T.ObjectClass); + CheckUnordered(T.ObjectConstant2, T.ObjectClass); + CheckUnordered(T.ObjectConstant1, T.ArrayClass); + CheckUnordered(T.ObjectConstant2, T.ArrayClass); + CheckUnordered(T.ArrayConstant1, T.ObjectClass); } - Handle<Type> Union(Handle<Type> type1, Handle<Type> type2) { - return handle(Type::Union(type1, type2), isolate_); + + void Maybe() { + CheckOverlap(T.Any, T.Any); + CheckOverlap(T.Object, T.Object); + + CheckOverlap(T.Oddball, T.Any); + CheckOverlap(T.Boolean, T.Oddball); + CheckOverlap(T.Null, T.Oddball); + CheckOverlap(T.Undefined, T.Oddball); + CheckDisjoint(T.Boolean, T.Null); + CheckDisjoint(T.Undefined, T.Null); + CheckDisjoint(T.Boolean, T.Undefined); + + CheckOverlap(T.Number, T.Any); + CheckOverlap(T.Smi, T.Number); + CheckOverlap(T.Double, T.Number); + CheckDisjoint(T.Signed32, T.Double); + + CheckOverlap(T.Name, T.Any); + CheckOverlap(T.UniqueName, T.Any); + CheckOverlap(T.UniqueName, T.Name); + CheckOverlap(T.String, T.Name); + CheckOverlap(T.InternalizedString, T.String); + CheckOverlap(T.InternalizedString, T.UniqueName); + CheckOverlap(T.InternalizedString, T.Name); + CheckOverlap(T.Symbol, T.UniqueName); + CheckOverlap(T.Symbol, T.Name); + CheckOverlap(T.String, T.UniqueName); + CheckDisjoint(T.String, T.Symbol); + CheckDisjoint(T.InternalizedString, T.Symbol); + + CheckOverlap(T.Receiver, T.Any); + CheckOverlap(T.Object, T.Any); + CheckOverlap(T.Object, T.Receiver); + CheckOverlap(T.Array, T.Object); + CheckOverlap(T.Function, T.Object); + CheckOverlap(T.Proxy, T.Receiver); + CheckDisjoint(T.Object, T.Proxy); + CheckDisjoint(T.Array, T.Function); + + CheckOverlap(T.ObjectClass, T.Any); + CheckOverlap(T.ObjectConstant1, T.Any); + + CheckOverlap(T.ObjectClass, T.Object); + CheckOverlap(T.ArrayClass, T.Object); + CheckOverlap(T.ObjectClass, T.ObjectClass); + CheckOverlap(T.ArrayClass, T.ArrayClass); + CheckDisjoint(T.ObjectClass, T.ArrayClass); + + CheckOverlap(T.SmiConstant, T.Smi); + CheckOverlap(T.SmiConstant, T.Signed32); + CheckOverlap(T.SmiConstant, T.Number); + CheckDisjoint(T.SmiConstant, T.Double); + CheckOverlap(T.ObjectConstant1, T.Object); + CheckOverlap(T.ObjectConstant2, T.Object); + CheckOverlap(T.ArrayConstant1, T.Object); + CheckOverlap(T.ArrayConstant1, T.Array); + CheckOverlap(T.ArrayConstant1, T.ArrayConstant2); + CheckOverlap(T.ObjectConstant1, T.ObjectConstant1); + CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2); + CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1); + + CheckDisjoint(T.ObjectConstant1, T.ObjectClass); + CheckDisjoint(T.ObjectConstant2, T.ObjectClass); + CheckDisjoint(T.ObjectConstant1, T.ArrayClass); + CheckDisjoint(T.ObjectConstant2, T.ArrayClass); + CheckDisjoint(T.ArrayConstant1, T.ObjectClass); } - Handle<Type> Intersect(Handle<Type> type1, Handle<Type> type2) { - return handle(Type::Intersect(type1, type2), isolate_); + + void Union() { + // Bitset-bitset + CHECK(this->IsBitset(T.Union(T.Object, T.Number))); + CHECK(this->IsBitset(T.Union(T.Object, T.Object))); + CHECK(this->IsBitset(T.Union(T.Any, T.None))); + + CheckEqual(T.Union(T.None, T.Number), T.Number); + CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver); + CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number)); + CheckSub(T.Union(T.Number, T.String), T.Any); + + // Class-class + CHECK(this->IsClass(T.Union(T.ObjectClass, T.ObjectClass))); + CHECK(this->IsUnion(T.Union(T.ObjectClass, T.ArrayClass))); + + CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass); + CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass)); + CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Any); + CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass)); + CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass)); + CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); + CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); + CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array); + CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number); + + // Constant-constant + CHECK(this->IsConstant(T.Union(T.ObjectConstant1, T.ObjectConstant1))); + CHECK(this->IsConstant(T.Union(T.ArrayConstant1, T.ArrayConstant1))); + CHECK(this->IsUnion(T.Union(T.ObjectConstant1, T.ObjectConstant2))); + + CheckEqual( + T.Union(T.ObjectConstant1, T.ObjectConstant1), + T.ObjectConstant1); + CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1); + CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant2); + CheckSub(T.None, T.Union(T.ObjectConstant1, T.ObjectConstant2)); + CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Any); + CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)); + CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2)); + CheckSub(T.ArrayConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant2)); + CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); + CheckUnordered( + T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); + CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array); + CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array); + CheckOverlap( + T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2); + CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number); + CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass); + + // Bitset-class + CHECK(this->IsBitset(T.Union(T.ObjectClass, T.Object))); + CHECK(this->IsUnion(T.Union(T.ObjectClass, T.Number))); + + CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object); + CheckSub(T.None, T.Union(T.ObjectClass, T.Number)); + CheckSub(T.Union(T.ObjectClass, T.Number), T.Any); + CheckSub(T.Union(T.ObjectClass, T.Smi), T.Union(T.Object, T.Number)); + CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); + CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); + CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object); + CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number); + + // Bitset-constant + CHECK(this->IsBitset(T.Union(T.SmiConstant, T.Number))); + CHECK(this->IsBitset(T.Union(T.ObjectConstant1, T.Object))); + CHECK(this->IsUnion(T.Union(T.ObjectConstant2, T.Number))); + + CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number); + CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object); + CheckSub(T.None, T.Union(T.ObjectConstant1, T.Number)); + CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any); + CheckSub( + T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); + CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); + CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); + CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object); + CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number); + CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32); + + // Class-constant + CHECK(this->IsUnion(T.Union(T.ObjectConstant1, T.ObjectClass))); + CHECK(this->IsUnion(T.Union(T.ArrayClass, T.ObjectConstant2))); + + CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass)); + CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any); + CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); + CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass)); + CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass)); + CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); + CheckSub( + T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); + CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant1); + CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2); + CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass); + + // Bitset-union + CHECK(this->IsBitset( + T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); + CHECK(this->IsUnion( + T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); + + CheckEqual( + T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), + T.Object); + CheckEqual( + T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), + T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); + CheckSub( + T.Double, + T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); + CheckSub( + T.ObjectConstant1, + T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double)); + CheckSub( + T.None, + T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double)); + CheckSub( + T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double), + T.Any); + CheckSub( + T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double), + T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); + + // Class-union + CHECK(this->IsUnion( + T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); + CHECK(this->IsUnion( + T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass))); + + CheckEqual( + T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), + T.Union(T.ObjectClass, T.ObjectConstant1)); + CheckSub( + T.None, + T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass))); + CheckSub( + T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), + T.Any); + CheckSub( + T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), + T.Object); + CheckEqual( + T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), + T.Union(T.ArrayClass, T.ObjectConstant2)); + + // Constant-union + CHECK(this->IsUnion(T.Union( + T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); + CHECK(this->IsUnion(T.Union( + T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); + CHECK(this->IsUnion(T.Union( + T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1))); + + CheckEqual( + T.Union( + T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), + T.Union(T.ObjectConstant2, T.ObjectConstant1)); + CheckEqual( + T.Union( + T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1), + T.Union( + T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1))); + + // Union-union + CHECK(this->IsBitset(T.Union( + T.Union(T.Number, T.ArrayClass), + T.Union(T.Signed32, T.Array)))); + CHECK(this->IsUnion(T.Union( + T.Union(T.Number, T.ArrayClass), + T.Union(T.ObjectClass, T.ArrayClass)))); + + CheckEqual( + T.Union( + T.Union(T.ObjectConstant2, T.ObjectConstant1), + T.Union(T.ObjectConstant1, T.ObjectConstant2)), + T.Union(T.ObjectConstant2, T.ObjectConstant1)); + CheckEqual( + T.Union( + T.Union(T.ObjectConstant2, T.ArrayConstant1), + T.Union(T.ObjectConstant1, T.ArrayConstant2)), + T.Union( + T.Union(T.ObjectConstant1, T.ObjectConstant2), + T.ArrayConstant1)); + CheckEqual( + T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array)), + T.Union(T.Number, T.Array)); } - private: - Isolate* isolate_; + void Intersect() { + // Bitset-bitset + CHECK(this->IsBitset(T.Intersect(T.Object, T.Number))); + CHECK(this->IsBitset(T.Intersect(T.Object, T.Object))); + CHECK(this->IsBitset(T.Intersect(T.Any, T.None))); + + CheckEqual(T.Intersect(T.None, T.Number), T.None); + CheckEqual(T.Intersect(T.Object, T.Proxy), T.None); + CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name)); + CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString); + + // Class-class + CHECK(this->IsClass(T.Intersect(T.ObjectClass, T.ObjectClass))); + CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.ArrayClass))); + + CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass); + CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None); + + // Constant-constant + CHECK(this->IsConstant(T.Intersect(T.ObjectConstant1, T.ObjectConstant1))); + CHECK(this->IsConstant(T.Intersect(T.ArrayConstant1, T.ArrayConstant2))); + CHECK(this->IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectConstant2))); + + CheckEqual( + T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); + CheckEqual( + T.Intersect(T.ArrayConstant1, T.ArrayConstant2), T.ArrayConstant1); + CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None); + + // Bitset-class + CHECK(this->IsClass(T.Intersect(T.ObjectClass, T.Object))); + CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.Number))); + + CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); + CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None); + CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None); + + // Bitset-constant + CHECK(this->IsBitset(T.Intersect(T.Smi, T.Number))); + CHECK(this->IsConstant(T.Intersect(T.SmiConstant, T.Number))); + CHECK(this->IsConstant(T.Intersect(T.ObjectConstant1, T.Object))); + + CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi); + CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant); + CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1); + + // Class-constant + CHECK(this->IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectClass))); + CHECK(this->IsBitset(T.Intersect(T.ArrayClass, T.ObjectConstant2))); + + CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); + CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); + + // Bitset-union + CHECK(this->IsUnion( + T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); + CHECK(this->IsBitset( + T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); + + CheckEqual( + T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), + T.Union(T.ObjectConstant1, T.ObjectClass)); + CheckEqual( + T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), + T.None); + + // Class-union + CHECK(this->IsClass( + T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); + CHECK(this->IsClass( + T.Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass))); + CHECK(this->IsBitset( + T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass))); + + CheckEqual( + T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), + T.ArrayClass); + CheckEqual( + T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), + T.ArrayClass); + CheckEqual( + T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass), + T.None); + + // Constant-union + CHECK(this->IsConstant(T.Intersect( + T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); + CHECK(this->IsConstant(T.Intersect( + T.Union(T.Number, T.ObjectClass), T.SmiConstant))); + CHECK(this->IsBitset(T.Intersect( + T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); + + CheckEqual( + T.Intersect( + T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), + T.ObjectConstant1); + CheckEqual( + T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), + T.SmiConstant); + CheckEqual( + T.Intersect( + T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1), + T.None); + + // Union-union + CHECK(this->IsUnion(T.Intersect( + T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array)))); + CHECK(this->IsBitset(T.Intersect( + T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array)))); + + CheckEqual( + T.Intersect( + T.Union(T.Number, T.ArrayClass), + T.Union(T.Smi, T.Array)), + T.Union(T.Smi, T.ArrayClass)); + CheckEqual( + T.Intersect( + T.Union(T.Number, T.ObjectClass), + T.Union(T.Signed32, T.Array)), + T.Signed32); + CheckEqual( + T.Intersect( + T.Union(T.ObjectConstant2, T.ObjectConstant1), + T.Union(T.ObjectConstant1, T.ObjectConstant2)), + T.Union(T.ObjectConstant2, T.ObjectConstant1)); + CheckEqual( + T.Intersect( + T.Union( + T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass), + T.Union( + T.ObjectConstant1, + T.Union(T.ArrayConstant1, T.ObjectConstant2))), + T.Union(T.ObjectConstant2, T.ObjectConstant1)); + CheckEqual( + T.Intersect( + T.Union(T.ObjectConstant2, T.ArrayConstant1), + T.Union(T.ObjectConstant1, T.ArrayConstant2)), + T.ArrayConstant1); + } + + template<class Type2, class TypeHandle2, class Region2, class Rep2> + void Convert() { + Types<Type2, TypeHandle2, Region2> T2( + Rep2::ToRegion(&zone, isolate), isolate); + for (int i = 0; i < 100; ++i) { + TypeHandle type = T.Fuzz(); + CheckEqual(type, + T.template Convert<Type2>(T2.template Convert<Type>(type))); + } + } }; +typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests; +typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests; + TEST(Bitset) { CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - HandleScope scope(isolate); - HandlifiedTypes T(isolate); - - CHECK(IsBitset(*T.None)); - CHECK(IsBitset(*T.Any)); - CHECK(IsBitset(*T.String)); - CHECK(IsBitset(*T.Object)); - - CHECK(IsBitset(Type::Union(T.String, T.Number))); - CHECK(IsBitset(Type::Union(T.String, T.Receiver))); - CHECK(IsBitset(Type::Optional(T.Object))); - - CHECK_EQ(0, AsBitset(*T.None)); - CHECK_EQ(AsBitset(*T.Number) | AsBitset(*T.String), - AsBitset(Type::Union(T.String, T.Number))); - CHECK_EQ(AsBitset(*T.Receiver), - AsBitset(Type::Union(T.Receiver, T.Object))); - CHECK_EQ(AsBitset(*T.String) | AsBitset(*T.Undefined), - AsBitset(Type::Optional(T.String))); + ZoneTests().Bitset(); + HeapTests().Bitset(); } TEST(Class) { CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - HandleScope scope(isolate); - HandlifiedTypes T(isolate); - - CHECK(IsClass(*T.ObjectClass)); - CHECK(IsClass(*T.ArrayClass)); - - CHECK(*T.object_map == AsClass(*T.ObjectClass)); - CHECK(*T.array_map == AsClass(*T.ArrayClass)); + ZoneTests().Class(); + HeapTests().Class(); } TEST(Constant) { CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - HandleScope scope(isolate); - HandlifiedTypes T(isolate); - - CHECK(IsConstant(*T.SmiConstant)); - CHECK(IsConstant(*T.ObjectConstant1)); - CHECK(IsConstant(*T.ObjectConstant2)); - CHECK(IsConstant(*T.ArrayConstant1)); - CHECK(IsConstant(*T.ArrayConstant2)); - - CHECK(*T.smi == AsConstant(*T.SmiConstant)); - CHECK(*T.object1 == AsConstant(*T.ObjectConstant1)); - CHECK(*T.object2 == AsConstant(*T.ObjectConstant2)); - CHECK(*T.object1 != AsConstant(*T.ObjectConstant2)); - CHECK(*T.array == AsConstant(*T.ArrayConstant1)); - CHECK(*T.array == AsConstant(*T.ArrayConstant2)); + ZoneTests().Constant(); + HeapTests().Constant(); } TEST(Is) { CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - HandleScope scope(isolate); - HandlifiedTypes T(isolate); - - // Reflexivity - CHECK(T.None->Is(T.None)); - CHECK(T.Any->Is(T.Any)); - CHECK(T.Object->Is(T.Object)); - - CHECK(T.ObjectClass->Is(T.ObjectClass)); - CHECK(T.ObjectConstant1->Is(T.ObjectConstant1)); - CHECK(T.ArrayConstant1->Is(T.ArrayConstant2)); - - // Symmetry and Transitivity - CheckSub(T.None, T.Number); - CheckSub(T.None, T.Any); - - CheckSub(T.Oddball, T.Any); - CheckSub(T.Boolean, T.Oddball); - CheckSub(T.Null, T.Oddball); - CheckSub(T.Undefined, T.Oddball); - CheckUnordered(T.Boolean, T.Null); - CheckUnordered(T.Undefined, T.Null); - CheckUnordered(T.Boolean, T.Undefined); - - CheckSub(T.Number, T.Any); - CheckSub(T.Smi, T.Number); - CheckSub(T.Signed32, T.Number); - CheckSub(T.Double, T.Number); - CheckSub(T.Smi, T.Signed32); - CheckUnordered(T.Smi, T.Double); - CheckUnordered(T.Signed32, T.Double); - - CheckSub(T.Name, T.Any); - CheckSub(T.UniqueName, T.Any); - CheckSub(T.UniqueName, T.Name); - CheckSub(T.String, T.Name); - CheckSub(T.InternalizedString, T.String); - CheckSub(T.InternalizedString, T.UniqueName); - CheckSub(T.InternalizedString, T.Name); - CheckSub(T.Symbol, T.UniqueName); - CheckSub(T.Symbol, T.Name); - CheckUnordered(T.String, T.UniqueName); - CheckUnordered(T.String, T.Symbol); - CheckUnordered(T.InternalizedString, T.Symbol); - - CheckSub(T.Receiver, T.Any); - CheckSub(T.Object, T.Any); - CheckSub(T.Object, T.Receiver); - CheckSub(T.Array, T.Object); - CheckSub(T.Function, T.Object); - CheckSub(T.Proxy, T.Receiver); - CheckUnordered(T.Object, T.Proxy); - CheckUnordered(T.Array, T.Function); - - // Structured subtyping - CheckSub(T.None, T.ObjectClass); - CheckSub(T.None, T.ObjectConstant1); - CheckSub(T.ObjectClass, T.Any); - CheckSub(T.ObjectConstant1, T.Any); - - CheckSub(T.ObjectClass, T.Object); - CheckSub(T.ArrayClass, T.Object); - CheckUnordered(T.ObjectClass, T.ArrayClass); - - CheckSub(T.SmiConstant, T.Smi); - CheckSub(T.SmiConstant, T.Signed32); - CheckSub(T.SmiConstant, T.Number); - CheckSub(T.ObjectConstant1, T.Object); - CheckSub(T.ObjectConstant2, T.Object); - CheckSub(T.ArrayConstant1, T.Object); - CheckSub(T.ArrayConstant1, T.Array); - CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); - CheckUnordered(T.ObjectConstant1, T.ArrayConstant1); - - CheckUnordered(T.ObjectConstant1, T.ObjectClass); - CheckUnordered(T.ObjectConstant2, T.ObjectClass); - CheckUnordered(T.ObjectConstant1, T.ArrayClass); - CheckUnordered(T.ObjectConstant2, T.ArrayClass); - CheckUnordered(T.ArrayConstant1, T.ObjectClass); + ZoneTests().Is(); + HeapTests().Is(); } TEST(Maybe) { CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - HandleScope scope(isolate); - HandlifiedTypes T(isolate); - - CheckOverlap(T.Any, T.Any); - CheckOverlap(T.Object, T.Object); - - CheckOverlap(T.Oddball, T.Any); - CheckOverlap(T.Boolean, T.Oddball); - CheckOverlap(T.Null, T.Oddball); - CheckOverlap(T.Undefined, T.Oddball); - CheckDisjoint(T.Boolean, T.Null); - CheckDisjoint(T.Undefined, T.Null); - CheckDisjoint(T.Boolean, T.Undefined); - - CheckOverlap(T.Number, T.Any); - CheckOverlap(T.Smi, T.Number); - CheckOverlap(T.Double, T.Number); - CheckDisjoint(T.Signed32, T.Double); - - CheckOverlap(T.Name, T.Any); - CheckOverlap(T.UniqueName, T.Any); - CheckOverlap(T.UniqueName, T.Name); - CheckOverlap(T.String, T.Name); - CheckOverlap(T.InternalizedString, T.String); - CheckOverlap(T.InternalizedString, T.UniqueName); - CheckOverlap(T.InternalizedString, T.Name); - CheckOverlap(T.Symbol, T.UniqueName); - CheckOverlap(T.Symbol, T.Name); - CheckOverlap(T.String, T.UniqueName); - CheckDisjoint(T.String, T.Symbol); - CheckDisjoint(T.InternalizedString, T.Symbol); - - CheckOverlap(T.Receiver, T.Any); - CheckOverlap(T.Object, T.Any); - CheckOverlap(T.Object, T.Receiver); - CheckOverlap(T.Array, T.Object); - CheckOverlap(T.Function, T.Object); - CheckOverlap(T.Proxy, T.Receiver); - CheckDisjoint(T.Object, T.Proxy); - CheckDisjoint(T.Array, T.Function); - - CheckOverlap(T.ObjectClass, T.Any); - CheckOverlap(T.ObjectConstant1, T.Any); - - CheckOverlap(T.ObjectClass, T.Object); - CheckOverlap(T.ArrayClass, T.Object); - CheckOverlap(T.ObjectClass, T.ObjectClass); - CheckOverlap(T.ArrayClass, T.ArrayClass); - CheckDisjoint(T.ObjectClass, T.ArrayClass); - - CheckOverlap(T.SmiConstant, T.Smi); - CheckOverlap(T.SmiConstant, T.Signed32); - CheckOverlap(T.SmiConstant, T.Number); - CheckDisjoint(T.SmiConstant, T.Double); - CheckOverlap(T.ObjectConstant1, T.Object); - CheckOverlap(T.ObjectConstant2, T.Object); - CheckOverlap(T.ArrayConstant1, T.Object); - CheckOverlap(T.ArrayConstant1, T.Array); - CheckOverlap(T.ArrayConstant1, T.ArrayConstant2); - CheckOverlap(T.ObjectConstant1, T.ObjectConstant1); - CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2); - CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1); - - CheckDisjoint(T.ObjectConstant1, T.ObjectClass); - CheckDisjoint(T.ObjectConstant2, T.ObjectClass); - CheckDisjoint(T.ObjectConstant1, T.ArrayClass); - CheckDisjoint(T.ObjectConstant2, T.ArrayClass); - CheckDisjoint(T.ArrayConstant1, T.ObjectClass); + ZoneTests().Maybe(); + HeapTests().Maybe(); } TEST(Union) { CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - HandleScope scope(isolate); - HandlifiedTypes T(isolate); - - // Bitset-bitset - CHECK(IsBitset(Type::Union(T.Object, T.Number))); - CHECK(IsBitset(Type::Union(T.Object, T.Object))); - CHECK(IsBitset(Type::Union(T.Any, T.None))); - - CheckEqual(T.Union(T.None, T.Number), T.Number); - CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver); - CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number)); - CheckSub(T.Union(T.Number, T.String), T.Any); - - // Class-class - CHECK(IsClass(Type::Union(T.ObjectClass, T.ObjectClass))); - CHECK(IsUnion(Type::Union(T.ObjectClass, T.ArrayClass))); - - CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass); - CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass)); - CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Any); - CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass)); - CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass)); - CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); - CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); - CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array); - CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number); - - // Constant-constant - CHECK(IsConstant(Type::Union(T.ObjectConstant1, T.ObjectConstant1))); - CHECK(IsConstant(Type::Union(T.ArrayConstant1, T.ArrayConstant1))); - CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectConstant2))); - - CheckEqual(T.Union(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); - CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1); - CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant2); - CheckSub(T.None, T.Union(T.ObjectConstant1, T.ObjectConstant2)); - CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Any); - CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)); - CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2)); - CheckSub(T.ArrayConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant2)); - CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); - CheckUnordered(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); - CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array); - CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array); - CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2); - CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number); - CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass); - - // Bitset-class - CHECK(IsBitset(Type::Union(T.ObjectClass, T.Object))); - CHECK(IsUnion(Type::Union(T.ObjectClass, T.Number))); - - CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object); - CheckSub(T.None, T.Union(T.ObjectClass, T.Number)); - CheckSub(T.Union(T.ObjectClass, T.Number), T.Any); - CheckSub(T.Union(T.ObjectClass, T.Smi), T.Union(T.Object, T.Number)); - CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); - CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); - CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object); - CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number); - - // Bitset-constant - CHECK(IsBitset(Type::Union(T.SmiConstant, T.Number))); - CHECK(IsBitset(Type::Union(T.ObjectConstant1, T.Object))); - CHECK(IsUnion(Type::Union(T.ObjectConstant2, T.Number))); - - CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number); - CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object); - CheckSub(T.None, T.Union(T.ObjectConstant1, T.Number)); - CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any); - CheckSub(T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); - CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); - CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); - CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object); - CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number); - CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32); - - // Class-constant - CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectClass))); - CHECK(IsUnion(Type::Union(T.ArrayClass, T.ObjectConstant2))); - - CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass)); - CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any); - CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); - CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass)); - CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass)); - CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); - CheckSub( - T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); - CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant1); - CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2); - CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass); - - // Bitset-union - CHECK(IsBitset( - Type::Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); - CHECK(IsUnion( - Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); - - CheckEqual( - T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), - T.Object); - CheckEqual( - T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), - T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); - CheckSub( - T.Double, - T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); - CheckSub( - T.ObjectConstant1, - T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double)); - CheckSub( - T.None, - T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double)); - CheckSub( - T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double), - T.Any); - CheckSub( - T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double), - T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); - - // Class-union - CHECK(IsUnion( - Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); - CHECK(IsUnion( - Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass))); - - CheckEqual( - T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), - T.Union(T.ObjectClass, T.ObjectConstant1)); - CheckSub( - T.None, - T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass))); - CheckSub( - T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), - T.Any); - CheckSub( - T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), - T.Object); - CheckEqual( - T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), - T.Union(T.ArrayClass, T.ObjectConstant2)); - - // Constant-union - CHECK(IsUnion(Type::Union( - T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); - CHECK(IsUnion(Type::Union( - T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); - CHECK(IsUnion(Type::Union( - T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1))); - - CheckEqual( - T.Union(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), - T.Union(T.ObjectConstant2, T.ObjectConstant1)); - CheckEqual( - T.Union(T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1), - T.Union(T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1))); - - // Union-union - CHECK(IsBitset(Type::Union( - T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array)))); - CHECK(IsUnion(Type::Union( - T.Union(T.Number, T.ArrayClass), T.Union(T.ObjectClass, T.ArrayClass)))); - - CheckEqual( - T.Union( - T.Union(T.ObjectConstant2, T.ObjectConstant1), - T.Union(T.ObjectConstant1, T.ObjectConstant2)), - T.Union(T.ObjectConstant2, T.ObjectConstant1)); - CheckEqual( - T.Union( - T.Union(T.ObjectConstant2, T.ArrayConstant1), - T.Union(T.ObjectConstant1, T.ArrayConstant2)), - T.Union(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ArrayConstant1)); - CheckEqual( - T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array)), - T.Union(T.Number, T.Array)); + ZoneTests().Union(); + HeapTests().Union(); } TEST(Intersect) { CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - HandleScope scope(isolate); - HandlifiedTypes T(isolate); - - // Bitset-bitset - CHECK(IsBitset(Type::Intersect(T.Object, T.Number))); - CHECK(IsBitset(Type::Intersect(T.Object, T.Object))); - CHECK(IsBitset(Type::Intersect(T.Any, T.None))); - - CheckEqual(T.Intersect(T.None, T.Number), T.None); - CheckEqual(T.Intersect(T.Object, T.Proxy), T.None); - CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name)); - CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString); - - // Class-class - CHECK(IsClass(Type::Intersect(T.ObjectClass, T.ObjectClass))); - CHECK(IsBitset(Type::Intersect(T.ObjectClass, T.ArrayClass))); - - CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass); - CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None); - - // Constant-constant - CHECK(IsConstant(Type::Intersect(T.ObjectConstant1, T.ObjectConstant1))); - CHECK(IsConstant(Type::Intersect(T.ArrayConstant1, T.ArrayConstant2))); - CHECK(IsBitset(Type::Intersect(T.ObjectConstant1, T.ObjectConstant2))); - - CheckEqual( - T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); - CheckEqual( - T.Intersect(T.ArrayConstant1, T.ArrayConstant2), T.ArrayConstant1); - CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None); - - // Bitset-class - CHECK(IsClass(Type::Intersect(T.ObjectClass, T.Object))); - CHECK(IsBitset(Type::Intersect(T.ObjectClass, T.Number))); - - CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); - CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None); - CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None); - - // Bitset-constant - CHECK(IsBitset(Type::Intersect(T.Smi, T.Number))); - CHECK(IsConstant(Type::Intersect(T.SmiConstant, T.Number))); - CHECK(IsConstant(Type::Intersect(T.ObjectConstant1, T.Object))); - - CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi); - CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant); - CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1); - - // Class-constant - CHECK(IsBitset(Type::Intersect(T.ObjectConstant1, T.ObjectClass))); - CHECK(IsBitset(Type::Intersect(T.ArrayClass, T.ObjectConstant2))); - - CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); - CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); - - // Bitset-union - CHECK(IsUnion( - Type::Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); - CHECK(IsBitset( - Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); - - CheckEqual( - T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), - T.Union(T.ObjectConstant1, T.ObjectClass)); - CheckEqual( - T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), - T.None); - - // Class-union - CHECK(IsClass( - Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); - CHECK(IsClass( - Type::Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass))); - CHECK(IsBitset( - Type::Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass))); - - CheckEqual( - T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), - T.ArrayClass); - CheckEqual( - T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), - T.ArrayClass); - CheckEqual( - T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass), - T.None); - - // Constant-union - CHECK(IsConstant(Type::Intersect( - T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); - CHECK(IsConstant(Type::Intersect( - T.Union(T.Number, T.ObjectClass), T.SmiConstant))); - CHECK(IsBitset(Type::Intersect( - T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); - - CheckEqual( - T.Intersect( - T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), - T.ObjectConstant1); - CheckEqual( - T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), - T.SmiConstant); - CheckEqual( - T.Intersect(T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1), - T.None); - - // Union-union - CHECK(IsUnion(Type::Intersect( - T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array)))); - CHECK(IsBitset(Type::Intersect( - T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array)))); - - CheckEqual( - T.Intersect( - T.Union(T.Number, T.ArrayClass), - T.Union(T.Smi, T.Array)), - T.Union(T.Smi, T.ArrayClass)); - CheckEqual( - T.Intersect( - T.Union(T.Number, T.ObjectClass), - T.Union(T.Signed32, T.Array)), - T.Signed32); - CheckEqual( - T.Intersect( - T.Union(T.ObjectConstant2, T.ObjectConstant1), - T.Union(T.ObjectConstant1, T.ObjectConstant2)), - T.Union(T.ObjectConstant2, T.ObjectConstant1)); - CheckEqual( - T.Intersect( - T.Union(T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass), - T.Union( - T.ObjectConstant1, T.Union(T.ArrayConstant1, T.ObjectConstant2))), - T.Union(T.ObjectConstant2, T.ObjectConstant1)); - CheckEqual( - T.Intersect( - T.Union(T.ObjectConstant2, T.ArrayConstant1), - T.Union(T.ObjectConstant1, T.ArrayConstant2)), - T.ArrayConstant1); + ZoneTests().Intersect(); + HeapTests().Intersect(); +} + + +TEST(Convert) { + CcTest::InitializeVM(); + ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); + HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); } diff --git a/deps/v8/test/cctest/test-unbound-queue.cc b/deps/v8/test/cctest/test-unbound-queue.cc index 6d02fff0bb..dd9b9c142b 100644 --- a/deps/v8/test/cctest/test-unbound-queue.cc +++ b/deps/v8/test/cctest/test-unbound-queue.cc @@ -74,4 +74,3 @@ TEST(MultipleRecords) { } CHECK(cq.IsEmpty()); } - diff --git a/deps/v8/test/cctest/test-unique.cc b/deps/v8/test/cctest/test-unique.cc index 0936908f12..ad14ff1334 100644 --- a/deps/v8/test/cctest/test-unique.cc +++ b/deps/v8/test/cctest/test-unique.cc @@ -546,4 +546,3 @@ TEST(UniqueSet_UnionExhaustive) { } } } - diff --git a/deps/v8/test/cctest/test-utils-a64.cc b/deps/v8/test/cctest/test-utils-a64.cc new file mode 100644 index 0000000000..e637a6e52b --- /dev/null +++ b/deps/v8/test/cctest/test-utils-a64.cc @@ -0,0 +1,426 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "v8.h" + +#include "macro-assembler.h" +#include "a64/utils-a64.h" +#include "cctest.h" +#include "test-utils-a64.h" + +using namespace v8::internal; + + +#define __ masm-> + + +bool Equal32(uint32_t expected, const RegisterDump*, uint32_t result) { + if (result != expected) { + printf("Expected 0x%08" PRIx32 "\t Found 0x%08" PRIx32 "\n", + expected, result); + } + + return expected == result; +} + + +bool Equal64(uint64_t expected, const RegisterDump*, uint64_t result) { + if (result != expected) { + printf("Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", + expected, result); + } + + return expected == result; +} + + +bool EqualFP32(float expected, const RegisterDump*, float result) { + if (float_to_rawbits(expected) == float_to_rawbits(result)) { + return true; + } else { + if (std::isnan(expected) || (expected == 0.0)) { + printf("Expected 0x%08" PRIx32 "\t Found 0x%08" PRIx32 "\n", + float_to_rawbits(expected), float_to_rawbits(result)); + } else { + printf("Expected %.9f (0x%08" PRIx32 ")\t " + "Found %.9f (0x%08" PRIx32 ")\n", + expected, float_to_rawbits(expected), + result, float_to_rawbits(result)); + } + return false; + } +} + + +bool EqualFP64(double expected, const RegisterDump*, double result) { + if (double_to_rawbits(expected) == double_to_rawbits(result)) { + return true; + } + + if (std::isnan(expected) || (expected == 0.0)) { + printf("Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", + double_to_rawbits(expected), double_to_rawbits(result)); + } else { + printf("Expected %.17f (0x%016" PRIx64 ")\t " + "Found %.17f (0x%016" PRIx64 ")\n", + expected, double_to_rawbits(expected), + result, double_to_rawbits(result)); + } + return false; +} + + +bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg) { + ASSERT(reg.Is32Bits()); + // Retrieve the corresponding X register so we can check that the upper part + // was properly cleared. + int64_t result_x = core->xreg(reg.code()); + if ((result_x & 0xffffffff00000000L) != 0) { + printf("Expected 0x%08" PRIx32 "\t Found 0x%016" PRIx64 "\n", + expected, result_x); + return false; + } + uint32_t result_w = core->wreg(reg.code()); + return Equal32(expected, core, result_w); +} + + +bool Equal64(uint64_t expected, + const RegisterDump* core, + const Register& reg) { + ASSERT(reg.Is64Bits()); + uint64_t result = core->xreg(reg.code()); + return Equal64(expected, core, result); +} + + +bool EqualFP32(float expected, + const RegisterDump* core, + const FPRegister& fpreg) { + ASSERT(fpreg.Is32Bits()); + // Retrieve the corresponding D register so we can check that the upper part + // was properly cleared. + uint64_t result_64 = core->dreg_bits(fpreg.code()); + if ((result_64 & 0xffffffff00000000L) != 0) { + printf("Expected 0x%08" PRIx32 " (%f)\t Found 0x%016" PRIx64 "\n", + float_to_rawbits(expected), expected, result_64); + return false; + } + + return EqualFP32(expected, core, core->sreg(fpreg.code())); +} + + +bool EqualFP64(double expected, + const RegisterDump* core, + const FPRegister& fpreg) { + ASSERT(fpreg.Is64Bits()); + return EqualFP64(expected, core, core->dreg(fpreg.code())); +} + + +bool Equal64(const Register& reg0, + const RegisterDump* core, + const Register& reg1) { + ASSERT(reg0.Is64Bits() && reg1.Is64Bits()); + int64_t expected = core->xreg(reg0.code()); + int64_t result = core->xreg(reg1.code()); + return Equal64(expected, core, result); +} + + +static char FlagN(uint32_t flags) { + return (flags & NFlag) ? 'N' : 'n'; +} + + +static char FlagZ(uint32_t flags) { + return (flags & ZFlag) ? 'Z' : 'z'; +} + + +static char FlagC(uint32_t flags) { + return (flags & CFlag) ? 'C' : 'c'; +} + + +static char FlagV(uint32_t flags) { + return (flags & VFlag) ? 'V' : 'v'; +} + + +bool EqualNzcv(uint32_t expected, uint32_t result) { + ASSERT((expected & ~NZCVFlag) == 0); + ASSERT((result & ~NZCVFlag) == 0); + if (result != expected) { + printf("Expected: %c%c%c%c\t Found: %c%c%c%c\n", + FlagN(expected), FlagZ(expected), FlagC(expected), FlagV(expected), + FlagN(result), FlagZ(result), FlagC(result), FlagV(result)); + return false; + } + + return true; +} + + +bool EqualRegisters(const RegisterDump* a, const RegisterDump* b) { + for (unsigned i = 0; i < kNumberOfRegisters; i++) { + if (a->xreg(i) != b->xreg(i)) { + printf("x%d\t Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", + i, a->xreg(i), b->xreg(i)); + return false; + } + } + + for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { + uint64_t a_bits = a->dreg_bits(i); + uint64_t b_bits = b->dreg_bits(i); + if (a_bits != b_bits) { + printf("d%d\t Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", + i, a_bits, b_bits); + return false; + } + } + + return true; +} + + +RegList PopulateRegisterArray(Register* w, Register* x, Register* r, + int reg_size, int reg_count, RegList allowed) { + RegList list = 0; + int i = 0; + for (unsigned n = 0; (n < kNumberOfRegisters) && (i < reg_count); n++) { + if (((1UL << n) & allowed) != 0) { + // Only assign allowed registers. + if (r) { + r[i] = Register::Create(n, reg_size); + } + if (x) { + x[i] = Register::Create(n, kXRegSize); + } + if (w) { + w[i] = Register::Create(n, kWRegSize); + } + list |= (1UL << n); + i++; + } + } + // Check that we got enough registers. + ASSERT(CountSetBits(list, kNumberOfRegisters) == reg_count); + + return list; +} + + +RegList PopulateFPRegisterArray(FPRegister* s, FPRegister* d, FPRegister* v, + int reg_size, int reg_count, RegList allowed) { + RegList list = 0; + int i = 0; + for (unsigned n = 0; (n < kNumberOfFPRegisters) && (i < reg_count); n++) { + if (((1UL << n) & allowed) != 0) { + // Only assigned allowed registers. + if (v) { + v[i] = FPRegister::Create(n, reg_size); + } + if (d) { + d[i] = FPRegister::Create(n, kDRegSize); + } + if (s) { + s[i] = FPRegister::Create(n, kSRegSize); + } + list |= (1UL << n); + i++; + } + } + // Check that we got enough registers. + ASSERT(CountSetBits(list, kNumberOfFPRegisters) == reg_count); + + return list; +} + + +void Clobber(MacroAssembler* masm, RegList reg_list, uint64_t const value) { + Register first = NoReg; + for (unsigned i = 0; i < kNumberOfRegisters; i++) { + if (reg_list & (1UL << i)) { + Register xn = Register::Create(i, kXRegSize); + // We should never write into csp here. + ASSERT(!xn.Is(csp)); + if (!xn.IsZero()) { + if (!first.IsValid()) { + // This is the first register we've hit, so construct the literal. + __ Mov(xn, value); + first = xn; + } else { + // We've already loaded the literal, so re-use the value already + // loaded into the first register we hit. + __ Mov(xn, first); + } + } + } + } +} + + +void ClobberFP(MacroAssembler* masm, RegList reg_list, double const value) { + FPRegister first = NoFPReg; + for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { + if (reg_list & (1UL << i)) { + FPRegister dn = FPRegister::Create(i, kDRegSize); + if (!first.IsValid()) { + // This is the first register we've hit, so construct the literal. + __ Fmov(dn, value); + first = dn; + } else { + // We've already loaded the literal, so re-use the value already loaded + // into the first register we hit. + __ Fmov(dn, first); + } + } + } +} + + +void Clobber(MacroAssembler* masm, CPURegList reg_list) { + if (reg_list.type() == CPURegister::kRegister) { + // This will always clobber X registers. + Clobber(masm, reg_list.list()); + } else if (reg_list.type() == CPURegister::kFPRegister) { + // This will always clobber D registers. + ClobberFP(masm, reg_list.list()); + } else { + UNREACHABLE(); + } +} + + +void RegisterDump::Dump(MacroAssembler* masm) { + ASSERT(__ StackPointer().Is(csp)); + + // Ensure that we don't unintentionally clobber any registers. + Register old_tmp0 = __ Tmp0(); + Register old_tmp1 = __ Tmp1(); + FPRegister old_fptmp0 = __ FPTmp0(); + __ SetScratchRegisters(NoReg, NoReg); + __ SetFPScratchRegister(NoFPReg); + + // Preserve some temporary registers. + Register dump_base = x0; + Register dump = x1; + Register tmp = x2; + Register dump_base_w = dump_base.W(); + Register dump_w = dump.W(); + Register tmp_w = tmp.W(); + + // Offsets into the dump_ structure. + const int x_offset = offsetof(dump_t, x_); + const int w_offset = offsetof(dump_t, w_); + const int d_offset = offsetof(dump_t, d_); + const int s_offset = offsetof(dump_t, s_); + const int sp_offset = offsetof(dump_t, sp_); + const int wsp_offset = offsetof(dump_t, wsp_); + const int flags_offset = offsetof(dump_t, flags_); + + __ Push(xzr, dump_base, dump, tmp); + + // Load the address where we will dump the state. + __ Mov(dump_base, reinterpret_cast<uint64_t>(&dump_)); + + // Dump the stack pointer (csp and wcsp). + // The stack pointer cannot be stored directly; it needs to be moved into + // another register first. Also, we pushed four X registers, so we need to + // compensate here. + __ Add(tmp, csp, 4 * kXRegSizeInBytes); + __ Str(tmp, MemOperand(dump_base, sp_offset)); + __ Add(tmp_w, wcsp, 4 * kXRegSizeInBytes); + __ Str(tmp_w, MemOperand(dump_base, wsp_offset)); + + // Dump X registers. + __ Add(dump, dump_base, x_offset); + for (unsigned i = 0; i < kNumberOfRegisters; i += 2) { + __ Stp(Register::XRegFromCode(i), Register::XRegFromCode(i + 1), + MemOperand(dump, i * kXRegSizeInBytes)); + } + + // Dump W registers. + __ Add(dump, dump_base, w_offset); + for (unsigned i = 0; i < kNumberOfRegisters; i += 2) { + __ Stp(Register::WRegFromCode(i), Register::WRegFromCode(i + 1), + MemOperand(dump, i * kWRegSizeInBytes)); + } + + // Dump D registers. + __ Add(dump, dump_base, d_offset); + for (unsigned i = 0; i < kNumberOfFPRegisters; i += 2) { + __ Stp(FPRegister::DRegFromCode(i), FPRegister::DRegFromCode(i + 1), + MemOperand(dump, i * kDRegSizeInBytes)); + } + + // Dump S registers. + __ Add(dump, dump_base, s_offset); + for (unsigned i = 0; i < kNumberOfFPRegisters; i += 2) { + __ Stp(FPRegister::SRegFromCode(i), FPRegister::SRegFromCode(i + 1), + MemOperand(dump, i * kSRegSizeInBytes)); + } + + // Dump the flags. + __ Mrs(tmp, NZCV); + __ Str(tmp, MemOperand(dump_base, flags_offset)); + + // To dump the values that were in tmp amd dump, we need a new scratch + // register. We can use any of the already dumped registers since we can + // easily restore them. + Register dump2_base = x10; + Register dump2 = x11; + ASSERT(!AreAliased(dump_base, dump, tmp, dump2_base, dump2)); + + // Don't lose the dump_ address. + __ Mov(dump2_base, dump_base); + + __ Pop(tmp, dump, dump_base, xzr); + + __ Add(dump2, dump2_base, w_offset); + __ Str(dump_base_w, MemOperand(dump2, dump_base.code() * kWRegSizeInBytes)); + __ Str(dump_w, MemOperand(dump2, dump.code() * kWRegSizeInBytes)); + __ Str(tmp_w, MemOperand(dump2, tmp.code() * kWRegSizeInBytes)); + + __ Add(dump2, dump2_base, x_offset); + __ Str(dump_base, MemOperand(dump2, dump_base.code() * kXRegSizeInBytes)); + __ Str(dump, MemOperand(dump2, dump.code() * kXRegSizeInBytes)); + __ Str(tmp, MemOperand(dump2, tmp.code() * kXRegSizeInBytes)); + + // Finally, restore dump2_base and dump2. + __ Ldr(dump2_base, MemOperand(dump2, dump2_base.code() * kXRegSizeInBytes)); + __ Ldr(dump2, MemOperand(dump2, dump2.code() * kXRegSizeInBytes)); + + // Restore the MacroAssembler's scratch registers. + __ SetScratchRegisters(old_tmp0, old_tmp1); + __ SetFPScratchRegister(old_fptmp0); + + completed_ = true; +} diff --git a/deps/v8/test/cctest/test-utils-a64.h b/deps/v8/test/cctest/test-utils-a64.h new file mode 100644 index 0000000000..250277542a --- /dev/null +++ b/deps/v8/test/cctest/test-utils-a64.h @@ -0,0 +1,233 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef V8_A64_TEST_UTILS_A64_H_ +#define V8_A64_TEST_UTILS_A64_H_ + +#include "v8.h" + +#include "macro-assembler.h" +#include "a64/macro-assembler-a64.h" +#include "a64/utils-a64.h" +#include "cctest.h" + + +using namespace v8::internal; + + +// RegisterDump: Object allowing integer, floating point and flags registers +// to be saved to itself for future reference. +class RegisterDump { + public: + RegisterDump() : completed_(false) {} + + // The Dump method generates code to store a snapshot of the register values. + // It needs to be able to use the stack temporarily, and requires that the + // current stack pointer is csp, and is properly aligned. + // + // The dumping code is generated though the given MacroAssembler. No registers + // are corrupted in the process, but the stack is used briefly. The flags will + // be corrupted during this call. + void Dump(MacroAssembler* assm); + + // Register accessors. + inline int32_t wreg(unsigned code) const { + if (code == kSPRegInternalCode) { + return wspreg(); + } + ASSERT(RegAliasesMatch(code)); + return dump_.w_[code]; + } + + inline int64_t xreg(unsigned code) const { + if (code == kSPRegInternalCode) { + return spreg(); + } + ASSERT(RegAliasesMatch(code)); + return dump_.x_[code]; + } + + // FPRegister accessors. + inline uint32_t sreg_bits(unsigned code) const { + ASSERT(FPRegAliasesMatch(code)); + return dump_.s_[code]; + } + + inline float sreg(unsigned code) const { + return rawbits_to_float(sreg_bits(code)); + } + + inline uint64_t dreg_bits(unsigned code) const { + ASSERT(FPRegAliasesMatch(code)); + return dump_.d_[code]; + } + + inline double dreg(unsigned code) const { + return rawbits_to_double(dreg_bits(code)); + } + + // Stack pointer accessors. + inline int64_t spreg() const { + ASSERT(SPRegAliasesMatch()); + return dump_.sp_; + } + + inline int64_t wspreg() const { + ASSERT(SPRegAliasesMatch()); + return dump_.wsp_; + } + + // Flags accessors. + inline uint64_t flags_nzcv() const { + ASSERT(IsComplete()); + ASSERT((dump_.flags_ & ~Flags_mask) == 0); + return dump_.flags_ & Flags_mask; + } + + inline bool IsComplete() const { + return completed_; + } + + private: + // Indicate whether the dump operation has been completed. + bool completed_; + + // Check that the lower 32 bits of x<code> exactly match the 32 bits of + // w<code>. A failure of this test most likely represents a failure in the + // ::Dump method, or a failure in the simulator. + bool RegAliasesMatch(unsigned code) const { + ASSERT(IsComplete()); + ASSERT(code < kNumberOfRegisters); + return ((dump_.x_[code] & kWRegMask) == dump_.w_[code]); + } + + // As RegAliasesMatch, but for the stack pointer. + bool SPRegAliasesMatch() const { + ASSERT(IsComplete()); + return ((dump_.sp_ & kWRegMask) == dump_.wsp_); + } + + // As RegAliasesMatch, but for floating-point registers. + bool FPRegAliasesMatch(unsigned code) const { + ASSERT(IsComplete()); + ASSERT(code < kNumberOfFPRegisters); + return (dump_.d_[code] & kSRegMask) == dump_.s_[code]; + } + + // Store all the dumped elements in a simple struct so the implementation can + // use offsetof to quickly find the correct field. + struct dump_t { + // Core registers. + uint64_t x_[kNumberOfRegisters]; + uint32_t w_[kNumberOfRegisters]; + + // Floating-point registers, as raw bits. + uint64_t d_[kNumberOfFPRegisters]; + uint32_t s_[kNumberOfFPRegisters]; + + // The stack pointer. + uint64_t sp_; + uint64_t wsp_; + + // NZCV flags, stored in bits 28 to 31. + // bit[31] : Negative + // bit[30] : Zero + // bit[29] : Carry + // bit[28] : oVerflow + uint64_t flags_; + } dump_; + + static dump_t for_sizeof(); + STATIC_ASSERT(sizeof(for_sizeof().d_[0]) == kDRegSizeInBytes); + STATIC_ASSERT(sizeof(for_sizeof().s_[0]) == kSRegSizeInBytes); + STATIC_ASSERT(sizeof(for_sizeof().d_[0]) == kXRegSizeInBytes); + STATIC_ASSERT(sizeof(for_sizeof().s_[0]) == kWRegSizeInBytes); + STATIC_ASSERT(sizeof(for_sizeof().x_[0]) == kXRegSizeInBytes); + STATIC_ASSERT(sizeof(for_sizeof().w_[0]) == kWRegSizeInBytes); +}; + +// Some of these methods don't use the RegisterDump argument, but they have to +// accept them so that they can overload those that take register arguments. +bool Equal32(uint32_t expected, const RegisterDump*, uint32_t result); +bool Equal64(uint64_t expected, const RegisterDump*, uint64_t result); + +bool EqualFP32(float expected, const RegisterDump*, float result); +bool EqualFP64(double expected, const RegisterDump*, double result); + +bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg); +bool Equal64(uint64_t expected, const RegisterDump* core, const Register& reg); + +bool EqualFP32(float expected, const RegisterDump* core, + const FPRegister& fpreg); +bool EqualFP64(double expected, const RegisterDump* core, + const FPRegister& fpreg); + +bool Equal64(const Register& reg0, const RegisterDump* core, + const Register& reg1); + +bool EqualNzcv(uint32_t expected, uint32_t result); + +bool EqualRegisters(const RegisterDump* a, const RegisterDump* b); + +// Populate the w, x and r arrays with registers from the 'allowed' mask. The +// r array will be populated with <reg_size>-sized registers, +// +// This allows for tests which use large, parameterized blocks of registers +// (such as the push and pop tests), but where certain registers must be +// avoided as they are used for other purposes. +// +// Any of w, x, or r can be NULL if they are not required. +// +// The return value is a RegList indicating which registers were allocated. +RegList PopulateRegisterArray(Register* w, Register* x, Register* r, + int reg_size, int reg_count, RegList allowed); + +// As PopulateRegisterArray, but for floating-point registers. +RegList PopulateFPRegisterArray(FPRegister* s, FPRegister* d, FPRegister* v, + int reg_size, int reg_count, RegList allowed); + +// Ovewrite the contents of the specified registers. This enables tests to +// check that register contents are written in cases where it's likely that the +// correct outcome could already be stored in the register. +// +// This always overwrites X-sized registers. If tests are operating on W +// registers, a subsequent write into an aliased W register should clear the +// top word anyway, so clobbering the full X registers should make tests more +// rigorous. +void Clobber(MacroAssembler* masm, RegList reg_list, + uint64_t const value = 0xfedcba9876543210UL); + +// As Clobber, but for FP registers. +void ClobberFP(MacroAssembler* masm, RegList reg_list, + double const value = kFP64SignallingNaN); + +// As Clobber, but for a CPURegList with either FP or integer registers. When +// using this method, the clobber value is always the default for the basic +// Clobber or ClobberFP functions. +void Clobber(MacroAssembler* masm, CPURegList reg_list); + +#endif // V8_A64_TEST_UTILS_A64_H_ diff --git a/deps/v8/test/cctest/test-weakmaps.cc b/deps/v8/test/cctest/test-weakmaps.cc index 932b06b850..97eca86f1b 100644 --- a/deps/v8/test/cctest/test-weakmaps.cc +++ b/deps/v8/test/cctest/test-weakmaps.cc @@ -25,6 +25,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include <utility> + #include "v8.h" #include "global-handles.h" @@ -56,7 +58,7 @@ static Handle<JSWeakMap> AllocateJSWeakMap(Isolate* isolate) { static void PutIntoWeakMap(Handle<JSWeakMap> weakmap, Handle<JSObject> key, Handle<Object> value) { - Handle<ObjectHashTable> table = PutIntoObjectHashTable( + Handle<ObjectHashTable> table = ObjectHashTable::Put( Handle<ObjectHashTable>(ObjectHashTable::cast(weakmap->table())), Handle<JSObject>(JSObject::cast(*key)), value); @@ -64,12 +66,14 @@ static void PutIntoWeakMap(Handle<JSWeakMap> weakmap, } static int NumberOfWeakCalls = 0; -static void WeakPointerCallback(v8::Isolate* isolate, - v8::Persistent<v8::Value>* handle, - void* id) { - ASSERT(id == reinterpret_cast<void*>(1234)); +static void WeakPointerCallback( + const v8::WeakCallbackData<v8::Value, void>& data) { + std::pair<v8::Persistent<v8::Value>*, int>* p = + reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>( + data.GetParameter()); + ASSERT_EQ(1234, p->second); NumberOfWeakCalls++; - handle->Dispose(); + p->first->Reset(); } @@ -112,9 +116,10 @@ TEST(Weakness) { // Make the global reference to the key weak. { HandleScope scope(isolate); - global_handles->MakeWeak(key.location(), - reinterpret_cast<void*>(1234), - &WeakPointerCallback); + std::pair<Handle<Object>*, int> handle_and_id(&key, 1234); + GlobalHandles::MakeWeak(key.location(), + reinterpret_cast<void*>(&handle_and_id), + &WeakPointerCallback); } CHECK(global_handles->IsWeak(key.location())); diff --git a/deps/v8/test/cctest/test-weaksets.cc b/deps/v8/test/cctest/test-weaksets.cc index aff4c7fcbe..514b6b2393 100644 --- a/deps/v8/test/cctest/test-weaksets.cc +++ b/deps/v8/test/cctest/test-weaksets.cc @@ -25,6 +25,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include <utility> + #include "v8.h" #include "global-handles.h" @@ -56,7 +58,7 @@ static Handle<JSWeakSet> AllocateJSWeakSet(Isolate* isolate) { static void PutIntoWeakSet(Handle<JSWeakSet> weakset, Handle<JSObject> key, Handle<Object> value) { - Handle<ObjectHashTable> table = PutIntoObjectHashTable( + Handle<ObjectHashTable> table = ObjectHashTable::Put( Handle<ObjectHashTable>(ObjectHashTable::cast(weakset->table())), Handle<JSObject>(JSObject::cast(*key)), value); @@ -64,12 +66,14 @@ static void PutIntoWeakSet(Handle<JSWeakSet> weakset, } static int NumberOfWeakCalls = 0; -static void WeakPointerCallback(v8::Isolate* isolate, - v8::Persistent<v8::Value>* handle, - void* id) { - ASSERT(id == reinterpret_cast<void*>(1234)); +static void WeakPointerCallback( + const v8::WeakCallbackData<v8::Value, void>& data) { + std::pair<v8::Persistent<v8::Value>*, int>* p = + reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>( + data.GetParameter()); + ASSERT_EQ(1234, p->second); NumberOfWeakCalls++; - handle->Dispose(); + p->first->Reset(); } @@ -112,9 +116,10 @@ TEST(WeakSet_Weakness) { // Make the global reference to the key weak. { HandleScope scope(isolate); - global_handles->MakeWeak(key.location(), - reinterpret_cast<void*>(1234), - &WeakPointerCallback); + std::pair<Handle<Object>*, int> handle_and_id(&key, 1234); + GlobalHandles::MakeWeak(key.location(), + reinterpret_cast<void*>(&handle_and_id), + &WeakPointerCallback); } CHECK(global_handles->IsWeak(key.location())); diff --git a/deps/v8/test/cctest/test-weaktypedarrays.cc b/deps/v8/test/cctest/test-weaktypedarrays.cc index fe1ef04940..daf07eed02 100644 --- a/deps/v8/test/cctest/test-weaktypedarrays.cc +++ b/deps/v8/test/cctest/test-weaktypedarrays.cc @@ -89,22 +89,24 @@ TEST(WeakArrayBuffersFromApi) { LocalContext context; Isolate* isolate = GetIsolateFrom(&context); - CHECK_EQ(0, CountArrayBuffersInWeakList(isolate->heap())); + int start = CountArrayBuffersInWeakList(isolate->heap()); { v8::HandleScope s1(context->GetIsolate()); - v8::Handle<v8::ArrayBuffer> ab1 = v8::ArrayBuffer::New(256); + v8::Handle<v8::ArrayBuffer> ab1 = + v8::ArrayBuffer::New(context->GetIsolate(), 256); { v8::HandleScope s2(context->GetIsolate()); - v8::Handle<v8::ArrayBuffer> ab2 = v8::ArrayBuffer::New(128); + v8::Handle<v8::ArrayBuffer> ab2 = + v8::ArrayBuffer::New(context->GetIsolate(), 128); Handle<JSArrayBuffer> iab1 = v8::Utils::OpenHandle(*ab1); Handle<JSArrayBuffer> iab2 = v8::Utils::OpenHandle(*ab2); - CHECK_EQ(2, CountArrayBuffersInWeakList(isolate->heap())); + CHECK_EQ(2, CountArrayBuffersInWeakList(isolate->heap()) - start); CHECK(HasArrayBufferInWeakList(isolate->heap(), *iab1)); CHECK(HasArrayBufferInWeakList(isolate->heap(), *iab2)); } isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); - CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap())); + CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap()) - start); { HandleScope scope2(isolate); Handle<JSArrayBuffer> iab1 = v8::Utils::OpenHandle(*ab1); @@ -114,7 +116,7 @@ TEST(WeakArrayBuffersFromApi) { } isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); - CHECK_EQ(0, CountArrayBuffersInWeakList(isolate->heap())); + CHECK_EQ(start, CountArrayBuffersInWeakList(isolate->heap())); } @@ -122,11 +124,12 @@ TEST(WeakArrayBuffersFromScript) { v8::V8::Initialize(); LocalContext context; Isolate* isolate = GetIsolateFrom(&context); + int start = CountArrayBuffersInWeakList(isolate->heap()); for (int i = 1; i <= 3; i++) { // Create 3 array buffers, make i-th of them garbage, // validate correct state of array buffer weak list. - CHECK_EQ(0, CountArrayBuffersInWeakList(isolate->heap())); + CHECK_EQ(start, CountArrayBuffersInWeakList(isolate->heap())); { v8::HandleScope scope(context->GetIsolate()); @@ -142,7 +145,7 @@ TEST(WeakArrayBuffersFromScript) { v8::Handle<v8::ArrayBuffer> ab3 = v8::Handle<v8::ArrayBuffer>::Cast(CompileRun("ab3")); - CHECK_EQ(3, CountArrayBuffersInWeakList(isolate->heap())); + CHECK_EQ(3, CountArrayBuffersInWeakList(isolate->heap()) - start); CHECK(HasArrayBufferInWeakList(isolate->heap(), *v8::Utils::OpenHandle(*ab1))); CHECK(HasArrayBufferInWeakList(isolate->heap(), @@ -156,7 +159,7 @@ TEST(WeakArrayBuffersFromScript) { CompileRun(source.start()); isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); - CHECK_EQ(2, CountArrayBuffersInWeakList(isolate->heap())); + CHECK_EQ(2, CountArrayBuffersInWeakList(isolate->heap()) - start); { v8::HandleScope s2(context->GetIsolate()); @@ -174,7 +177,7 @@ TEST(WeakArrayBuffersFromScript) { } isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); - CHECK_EQ(0, CountArrayBuffersInWeakList(isolate->heap())); + CHECK_EQ(start, CountArrayBuffersInWeakList(isolate->heap())); } } @@ -185,7 +188,8 @@ void TestViewFromApi() { Isolate* isolate = GetIsolateFrom(&context); v8::HandleScope s1(context->GetIsolate()); - v8::Handle<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(2048); + v8::Handle<v8::ArrayBuffer> ab = + v8::ArrayBuffer::New(context->GetIsolate(), 2048); Handle<JSArrayBuffer> iab = v8::Utils::OpenHandle(*ab); { v8::HandleScope s2(context->GetIsolate()); @@ -266,6 +270,7 @@ static void TestTypedArrayFromScript(const char* constructor) { LocalContext context; Isolate* isolate = GetIsolateFrom(&context); v8::HandleScope scope(context->GetIsolate()); + int start = CountArrayBuffersInWeakList(isolate->heap()); CompileRun("var ab = new ArrayBuffer(2048);"); for (int i = 1; i <= 3; i++) { // Create 3 typed arrays, make i-th of them garbage, @@ -273,7 +278,7 @@ static void TestTypedArrayFromScript(const char* constructor) { v8::HandleScope s0(context->GetIsolate()); i::ScopedVector<char> source(2048); - CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap())); + CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap()) - start); { v8::HandleScope s1(context->GetIsolate()); @@ -292,7 +297,7 @@ static void TestTypedArrayFromScript(const char* constructor) { v8::Handle<TypedArray>::Cast(CompileRun("ta2")); v8::Handle<TypedArray> ta3 = v8::Handle<TypedArray>::Cast(CompileRun("ta3")); - CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap())); + CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap()) - start); Handle<JSArrayBuffer> iab = v8::Utils::OpenHandle(*ab); CHECK_EQ(3, CountViews(*iab)); CHECK(HasViewInWeakList(*iab, *v8::Utils::OpenHandle(*ta1))); @@ -304,7 +309,7 @@ static void TestTypedArrayFromScript(const char* constructor) { CompileRun(source.start()); isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); - CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap())); + CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap()) - start); { v8::HandleScope s2(context->GetIsolate()); @@ -324,7 +329,7 @@ static void TestTypedArrayFromScript(const char* constructor) { CompileRun("ta1 = null; ta2 = null; ta3 = null;"); isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); - CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap())); + CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap()) - start); { v8::HandleScope s3(context->GetIsolate()); diff --git a/deps/v8/test/cctest/trace-extension.cc b/deps/v8/test/cctest/trace-extension.cc new file mode 100644 index 0000000000..2da6813166 --- /dev/null +++ b/deps/v8/test/cctest/trace-extension.cc @@ -0,0 +1,142 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "trace-extension.h" + +#include "cctest.h" +#include "sampler.h" + +namespace v8 { +namespace internal { + +const char* TraceExtension::kSource = + "native function trace();" + "native function js_trace();" + "native function js_entry_sp();" + "native function js_entry_sp_level2();"; + + +v8::Handle<v8::FunctionTemplate> TraceExtension::GetNativeFunctionTemplate( + v8::Isolate* isolate, v8::Handle<v8::String> name) { + if (name->Equals(v8::String::NewFromUtf8(isolate, "trace"))) { + return v8::FunctionTemplate::New(isolate, TraceExtension::Trace); + } else if (name->Equals(v8::String::NewFromUtf8(isolate, "js_trace"))) { + return v8::FunctionTemplate::New(isolate, TraceExtension::JSTrace); + } else if (name->Equals(v8::String::NewFromUtf8(isolate, "js_entry_sp"))) { + return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySP); + } else if (name->Equals(v8::String::NewFromUtf8(isolate, + "js_entry_sp_level2"))) { + return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySPLevel2); + } else { + CHECK(false); + return v8::Handle<v8::FunctionTemplate>(); + } +} + + +Address TraceExtension::GetFP(const v8::FunctionCallbackInfo<v8::Value>& args) { + // Convert frame pointer from encoding as smis in the arguments to a pointer. + CHECK_EQ(2, args.Length()); // Ignore second argument on 32-bit platform. +#if defined(V8_HOST_ARCH_32_BIT) + Address fp = *reinterpret_cast<Address*>(*args[0]); +#elif defined(V8_HOST_ARCH_64_BIT) + int64_t low_bits = *reinterpret_cast<uint64_t*>(*args[0]) >> 32; + int64_t high_bits = *reinterpret_cast<uint64_t*>(*args[1]); + Address fp = reinterpret_cast<Address>(high_bits | low_bits); +#else +#error Host architecture is neither 32-bit nor 64-bit. +#endif + printf("Trace: %p\n", fp); + return fp; +} + + +static struct { + TickSample* sample; +} trace_env = { NULL }; + + +void TraceExtension::InitTraceEnv(TickSample* sample) { + trace_env.sample = sample; +} + + +void TraceExtension::DoTrace(Address fp) { + RegisterState regs; + regs.fp = fp; + // sp is only used to define stack high bound + regs.sp = + reinterpret_cast<Address>(trace_env.sample) - 10240; + trace_env.sample->Init(CcTest::i_isolate(), regs); +} + + +void TraceExtension::Trace(const v8::FunctionCallbackInfo<v8::Value>& args) { + DoTrace(GetFP(args)); +} + + +// Hide c_entry_fp to emulate situation when sampling is done while +// pure JS code is being executed +static void DoTraceHideCEntryFPAddress(Address fp) { + v8::internal::Address saved_c_frame_fp = + *(CcTest::i_isolate()->c_entry_fp_address()); + CHECK(saved_c_frame_fp); + *(CcTest::i_isolate()->c_entry_fp_address()) = 0; + i::TraceExtension::DoTrace(fp); + *(CcTest::i_isolate()->c_entry_fp_address()) = saved_c_frame_fp; +} + + +void TraceExtension::JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args) { + DoTraceHideCEntryFPAddress(GetFP(args)); +} + + +Address TraceExtension::GetJsEntrySp() { + CHECK_NE(NULL, CcTest::i_isolate()->thread_local_top()); + return CcTest::i_isolate()->js_entry_sp(); +} + + +void TraceExtension::JSEntrySP( + const v8::FunctionCallbackInfo<v8::Value>& args) { + CHECK_NE(0, GetJsEntrySp()); +} + + +void TraceExtension::JSEntrySPLevel2( + const v8::FunctionCallbackInfo<v8::Value>& args) { + v8::HandleScope scope(args.GetIsolate()); + const Address js_entry_sp = GetJsEntrySp(); + CHECK_NE(0, js_entry_sp); + CompileRun("js_entry_sp();"); + CHECK_EQ(js_entry_sp, GetJsEntrySp()); +} + + +} } // namespace v8::internal diff --git a/deps/v8/test/cctest/trace-extension.h b/deps/v8/test/cctest/trace-extension.h new file mode 100644 index 0000000000..b80b3d45dc --- /dev/null +++ b/deps/v8/test/cctest/trace-extension.h @@ -0,0 +1,56 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef V8_TEST_CCTEST_TRACE_EXTENSION_H_ +#define V8_TEST_CCTEST_TRACE_EXTENSION_H_ + +#include "v8.h" + +namespace v8 { +namespace internal { + +class TraceExtension : public v8::Extension { + public: + TraceExtension() : v8::Extension("v8/trace", kSource) { } + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( + v8::Isolate* isolate, + v8::Handle<v8::String> name); + static void Trace(const v8::FunctionCallbackInfo<v8::Value>& args); + static void JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args); + static void JSEntrySP(const v8::FunctionCallbackInfo<v8::Value>& args); + static void JSEntrySPLevel2(const v8::FunctionCallbackInfo<v8::Value>& args); + static Address GetJsEntrySp(); + static void InitTraceEnv(TickSample* sample); + static void DoTrace(Address fp); + private: + static Address GetFP(const v8::FunctionCallbackInfo<v8::Value>& args); + static const char* kSource; +}; + +} } // namespace v8::internal + +#endif diff --git a/deps/v8/test/intl/collator/sr-sort.js b/deps/v8/test/intl/collator/sr-sort.js index 53c784ce0d..b7e6f30d57 100644 --- a/deps/v8/test/intl/collator/sr-sort.js +++ b/deps/v8/test/intl/collator/sr-sort.js @@ -43,4 +43,3 @@ assertEquals('Стара Планина', result[6]); assertEquals('ћук', result[7]); assertEquals('чука', result[8]); assertEquals('џак', result[9]); - diff --git a/deps/v8/test/intl/intl.status b/deps/v8/test/intl/intl.status index fc3c66b9c1..4ecbf325ad 100644 --- a/deps/v8/test/intl/intl.status +++ b/deps/v8/test/intl/intl.status @@ -25,9 +25,10 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# The following tests use getDefaultTimeZone(). [ [ALWAYS, { - # The following tests use getDefaultTimeZone(). 'date-format/resolved-options': [FAIL], 'date-format/timezone': [FAIL], 'general/v8Intl-exists': [FAIL], diff --git a/deps/v8/test/intl/overrides/caching.js b/deps/v8/test/intl/overrides/caching.js index 5ff3c390e7..abcd64031f 100644 --- a/deps/v8/test/intl/overrides/caching.js +++ b/deps/v8/test/intl/overrides/caching.js @@ -57,4 +57,3 @@ collatorTime = endTime.getTime() - startTime.getTime(); assertTrue(collatorTime < cachedTime); // Non-cached time is much slower, measured to 12.5 times. assertTrue(cachedTime < nonCachedTime); - diff --git a/deps/v8/test/intl/string/normalization.js b/deps/v8/test/intl/string/normalization.js new file mode 100644 index 0000000000..446d6277db --- /dev/null +++ b/deps/v8/test/intl/string/normalization.js @@ -0,0 +1,145 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Tests the new String.prototype.normalize method. + + +// Common use case when searching for 'not very exact' match. +// These are examples of data one might encounter in real use. +var testRealUseCases = function() { + // Vietnamese legacy text, old Windows 9x / non-Unicode applications use + // windows-1258 code page, which is neither precomposed, nor decomposed. + assertEquals('ti\u00ea\u0301ng Vi\u00ea\u0323t'.normalize('NFKD'), + 'ti\u1ebfng Vi\u1ec7t'.normalize('NFKD')); // all precomposed + + // Various kinds of spaces + assertEquals('Google\u0020Maps'.normalize('NFKD'), // normal space + 'Google\u00a0Maps'.normalize('NFKD')); // non-breaking space + assertEquals('Google\u0020Maps'.normalize('NFKD'), // normal space + 'Google\u2002Maps'.normalize('NFKD')); // en-space + assertEquals('Google\u0020Maps'.normalize('NFKD'), // normal space + 'Google\u2003Maps'.normalize('NFKD')); // em-space + assertEquals('Google\u0020Maps'.normalize('NFKD'), // normal space + 'Google\u3000Maps'.normalize('NFKC')); // ideographic space + + // Latin small ligature "fi" + assertEquals('fi'.normalize('NFKD'), '\ufb01'.normalize('NFKD')); + + // ŀ, Latin small L with middle dot, used in Catalan and often represented + // as decomposed for non-Unicode environments ( l + ·) + assertEquals('l\u00b7'.normalize('NFKD'), '\u0140'.normalize('NFKD')); + + // Legacy text, Japanese narrow Kana (MS-DOS & Win 3.x time) + assertEquals('\u30d1\u30bd\u30b3\u30f3'.normalize('NFKD'), // パソコン : wide + '\uff8a\uff9f\uff7f\uff7a\uff9d'.normalize('NFKD')); // パソコン : narrow + // Also for Japanese, Latin fullwidth forms vs. ASCII + assertEquals('ABCD'.normalize('NFKD'), + '\uff21\uff22\uff23\uff24'.normalize('NFKD')); // ABCD, fullwidth +}(); + + +var testEdgeCases = function() { + // Make sure we throw RangeError, as the standard requires. + assertThrows('"".normalize(1234)', RangeError); + assertThrows('"".normalize("BAD")', RangeError); + + // The standard does not say what kind of exceptions we should throw, so we + // will not be specific. But we still test that we throw errors. + assertThrows('s.normalize()'); // s is not defined + assertThrows('var s = null; s.normalize()'); + assertThrows('var s = undefined; s.normalize()'); + assertThrows('var s = 1234; s.normalize()'); // no normalize for non-strings +}(); + + +// Several kinds of mappings. No need to be comprehensive, we don't test +// the ICU functionality, we only test C - JavaScript 'glue' +var testData = [ + // org, default, NFC, NFD, NKFC, NKFD + ['\u00c7', // Ç : Combining sequence, Latin 1 + '\u00c7', '\u0043\u0327', + '\u00c7', '\u0043\u0327'], + ['\u0218', // Ș : Combining sequence, non-Latin 1 + '\u0218', '\u0053\u0326', + '\u0218', '\u0053\u0326'], + ['\uac00', // 가 : Hangul + '\uac00', '\u1100\u1161', + '\uac00', '\u1100\u1161'], + ['\uff76', // カ : Narrow Kana + '\uff76', '\uff76', + '\u30ab', '\u30ab'], + ['\u00bc', // ¼ : Fractions + '\u00bc', '\u00bc', + '\u0031\u2044\u0034', '\u0031\u2044\u0034'], + ['\u01c6', // dž : Latin ligature + '\u01c6', '\u01c6', + '\u0064\u017e', '\u0064\u007a\u030c'], + ['s\u0307\u0323', // s + dot above + dot below, ordering of combining marks + '\u1e69', 's\u0323\u0307', + '\u1e69', 's\u0323\u0307'], + ['\u3300', // ㌀ : Squared characters + '\u3300', '\u3300', + '\u30a2\u30d1\u30fc\u30c8', // アパート + '\u30a2\u30cf\u309a\u30fc\u30c8'], // アパート + ['\ufe37', // ︷ : Vertical forms + '\ufe37', '\ufe37', + '{' , '{'], + ['\u2079', // ⁹ : superscript 9 + '\u2079', '\u2079', + '9', '9'], + ['\ufee5\ufee6\ufee7\ufee8', // Arabic forms + '\ufee5\ufee6\ufee7\ufee8', '\ufee5\ufee6\ufee7\ufee8', + '\u0646\u0646\u0646\u0646', '\u0646\u0646\u0646\u0646'], + ['\u2460', // ① : Circled + '\u2460', '\u2460', + '1', '1'], + ['\u210c', // ℌ : Font variants + '\u210c', '\u210c', + 'H', 'H'], + ['\u2126', // Ω : Singleton, OHM sign vs. Greek capital letter OMEGA + '\u03a9', '\u03a9', + '\u03a9', '\u03a9'], + ['\ufdfb', // Long ligature, ARABIC LIGATURE JALLAJALALOUHOU + '\ufdfb', '\ufdfb', + '\u062C\u0644\u0020\u062C\u0644\u0627\u0644\u0647', + '\u062C\u0644\u0020\u062C\u0644\u0627\u0644\u0647'] +]; + +var testArray = function() { + var kNFC = 1, kNFD = 2, kNFKC = 3, kNFKD = 4; + for (var i = 0; i < testData.length; ++i) { + // the original, NFC and NFD should normalize to the same thing + for (var column = 0; column < 3; ++column) { + var str = testData[i][column]; + assertEquals(str.normalize(), testData[i][kNFC]); // defaults to NFC + assertEquals(str.normalize('NFC'), testData[i][kNFC]); + assertEquals(str.normalize('NFD'), testData[i][kNFD]); + assertEquals(str.normalize('NFKC'), testData[i][kNFKC]); + assertEquals(str.normalize('NFKD'), testData[i][kNFKD]); + } + } +}(); diff --git a/deps/v8/test/message/instanceof.js b/deps/v8/test/message/instanceof.js new file mode 100644 index 0000000000..1d55e0f94e --- /dev/null +++ b/deps/v8/test/message/instanceof.js @@ -0,0 +1,28 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +1 instanceof 2; diff --git a/deps/v8/test/message/instanceof.out b/deps/v8/test/message/instanceof.out new file mode 100644 index 0000000000..d279bc44e7 --- /dev/null +++ b/deps/v8/test/message/instanceof.out @@ -0,0 +1,5 @@ +*%(basename)s:28: TypeError: Expecting a function in instanceof check, but got 2 +1 instanceof 2; + ^ +TypeError: Expecting a function in instanceof check, but got 2 + at *%(basename)s:28:3 diff --git a/deps/v8/test/message/isvar.js b/deps/v8/test/message/isvar.js index 67793a00b9..fedf9d5f68 100644 --- a/deps/v8/test/message/isvar.js +++ b/deps/v8/test/message/isvar.js @@ -28,4 +28,4 @@ // Flags: --allow-natives-syntax var x; %IS_VAR(x); -%IS_VAR(x+x);
\ No newline at end of file +%IS_VAR(x+x); diff --git a/deps/v8/test/message/message.status b/deps/v8/test/message/message.status index 234bf0f35c..00f6e34720 100644 --- a/deps/v8/test/message/message.status +++ b/deps/v8/test/message/message.status @@ -25,9 +25,10 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# All tests in the bug directory are expected to fail. [ [ALWAYS, { - # All tests in the bug directory are expected to fail. 'bugs/*': [FAIL], }], # ALWAYS ] diff --git a/deps/v8/test/message/paren_in_arg_string.js b/deps/v8/test/message/paren_in_arg_string.js index bab762a6a4..83ba7c0859 100644 --- a/deps/v8/test/message/paren_in_arg_string.js +++ b/deps/v8/test/message/paren_in_arg_string.js @@ -26,4 +26,4 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. var paren_in_arg_string_good = new Function('x', 'return;'); -var paren_in_arg_string_bad = new Function(')', 'return;');
\ No newline at end of file +var paren_in_arg_string_bad = new Function(')', 'return;'); diff --git a/deps/v8/test/message/replacement-marker-as-argument.js b/deps/v8/test/message/replacement-marker-as-argument.js index 9036654d98..22a68ecbe5 100644 --- a/deps/v8/test/message/replacement-marker-as-argument.js +++ b/deps/v8/test/message/replacement-marker-as-argument.js @@ -28,4 +28,4 @@ "use strict"; var o = { get "%3" (){} }; -o["%3"] = 10;
\ No newline at end of file +o["%3"] = 10; diff --git a/deps/v8/test/message/single-function-literal.js b/deps/v8/test/message/single-function-literal.js index 372063737f..96d3bd663a 100644 --- a/deps/v8/test/message/single-function-literal.js +++ b/deps/v8/test/message/single-function-literal.js @@ -29,4 +29,4 @@ var single_function_good = "(function() { return 5; })"; %CompileString(single_function_good, true); var single_function_bad = "(function() { return 5; })();"; -%CompileString(single_function_bad, true);
\ No newline at end of file +%CompileString(single_function_bad, true); diff --git a/deps/v8/test/message/testcfg.py b/deps/v8/test/message/testcfg.py index e4f3f5587a..b472f9cfb3 100644 --- a/deps/v8/test/message/testcfg.py +++ b/deps/v8/test/message/testcfg.py @@ -73,7 +73,7 @@ class MessageTestSuite(testsuite.TestSuite): return f.read() def _IgnoreLine(self, string): - """Ignore empty lines, valgrind output and Android output.""" + """Ignore empty lines, valgrind output, Android output.""" if not string: return True return (string.startswith("==") or string.startswith("**") or string.startswith("ANDROID") or diff --git a/deps/v8/test/mjsunit/allocation-folding.js b/deps/v8/test/mjsunit/allocation-folding.js index ec07392f2c..fcf909d6af 100644 --- a/deps/v8/test/mjsunit/allocation-folding.js +++ b/deps/v8/test/mjsunit/allocation-folding.js @@ -100,3 +100,16 @@ gc(); assertEquals(result[1], 4); assertEquals(result2[1], 6); + +// Test to almost exceed the Page::MaxRegularHeapObjectSize limit. + +function boom() { + var a1 = new Array(84632); + var a2 = new Array(84632); + var a3 = new Array(84632); + return [ a1, a2, a3 ]; +} + +boom(); boom(); boom(); +%OptimizeFunctionOnNextCall(boom); +boom(); diff --git a/deps/v8/test/mjsunit/allocation-site-info.js b/deps/v8/test/mjsunit/allocation-site-info.js index f32344a405..cd086d3506 100644 --- a/deps/v8/test/mjsunit/allocation-site-info.js +++ b/deps/v8/test/mjsunit/allocation-site-info.js @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax --smi-only-arrays --expose-gc -// Flags: --track-allocation-sites --noalways-opt +// Flags: --noalways-opt // Test element kind of objects. // Since --smi-only-arrays affects builtins, its default setting at compile @@ -35,11 +35,6 @@ // in this test case. Depending on whether smi-only arrays are actually // enabled, this test takes the appropriate code path to check smi-only arrays. -// Reset the GC stress mode to be off. Needed because AllocationMementos only -// live for one gc, so a gc that happens in certain fragile areas of the test -// can break assumptions. -%SetFlags("--gc-interval=-1") - // support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8)); support_smi_only_arrays = true; @@ -148,8 +143,12 @@ if (support_smi_only_arrays) { assertKind(elements_kind.fast_double, obj); obj = fastliteralcase([3, 6, 2], 1.5); assertKind(elements_kind.fast_double, obj); + + // Note: thanks to pessimistic transition store stubs, we'll attempt + // to transition to the most general elements kind seen at a particular + // store site. So, the elements kind will be double. obj = fastliteralcase([2, 6, 3], 2); - assertKind(elements_kind.fast_smi_only, obj); + assertKind(elements_kind.fast_double, obj); } // Verify that we will not pretransition the double->fast path. diff --git a/deps/v8/test/mjsunit/arguments-apply-deopt.js b/deps/v8/test/mjsunit/arguments-apply-deopt.js new file mode 100644 index 0000000000..b7251af5aa --- /dev/null +++ b/deps/v8/test/mjsunit/arguments-apply-deopt.js @@ -0,0 +1,77 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +(function ApplyArgumentsDeoptInReceiverMapCheck() { + function invoker(h, r) { + return function XXXXX() { + var res = h.apply({ fffffff : r(this) }, arguments); + return res; + }; + } + + var y = invoker(m, selfOf); + + function selfOf(c) { + var sssss = c.self_; + return sssss; + } + + function m() { + return this.fffffff; + } + + y.apply({ self_ : 3 }); + y.apply({ self_ : 3 }); + y.apply({ self_ : 3 }); + + %OptimizeFunctionOnNextCall(y); + + assertEquals(y.apply({ self_ : 3, uuu : 4 }), 3); +})(); + +(function ApplyArgumentsDeoptInReceiverExplicit() { + function f() { return this + 21; } + + function deopt() { + %DeoptimizeFunction(XXXXX); + return 21; + } + + function XXXXX() { + return f.apply(deopt(), arguments); + }; + + XXXXX(); + XXXXX(); + XXXXX(); + + %OptimizeFunctionOnNextCall(XXXXX); + + assertEquals(42, XXXXX()); +})(); diff --git a/deps/v8/test/mjsunit/arguments-load-across-eval.js b/deps/v8/test/mjsunit/arguments-load-across-eval.js index e97c11329e..295b62cd46 100644 --- a/deps/v8/test/mjsunit/arguments-load-across-eval.js +++ b/deps/v8/test/mjsunit/arguments-load-across-eval.js @@ -82,5 +82,3 @@ function testShadowing(x, h) { } testShadowing(1, function() { return 2; }); - - diff --git a/deps/v8/test/mjsunit/arguments-read-and-assignment.js b/deps/v8/test/mjsunit/arguments-read-and-assignment.js index c5d34bfa9b..fba052bfb7 100644 --- a/deps/v8/test/mjsunit/arguments-read-and-assignment.js +++ b/deps/v8/test/mjsunit/arguments-read-and-assignment.js @@ -161,4 +161,4 @@ function weirdargs(a,b,c) { if (!a) return arguments; var args1 = weirdargs(false, null, 40); var res = weirdargs(true, args1, 15); assertEquals(40, res[0], "return old args element"); -assertEquals(15, res[1], "return own args element");
\ No newline at end of file +assertEquals(15, res[1], "return own args element"); diff --git a/deps/v8/test/mjsunit/arguments.js b/deps/v8/test/mjsunit/arguments.js index 78b7722e6d..56c1d7224d 100644 --- a/deps/v8/test/mjsunit/arguments.js +++ b/deps/v8/test/mjsunit/arguments.js @@ -187,4 +187,4 @@ function arg_del(x) { return delete arguments[x]; } function arg_set(x) { return (arguments[x] = 117); } assertEquals(undefined, arg_get(0xFFFFFFFF)); assertEquals(true, arg_del(0xFFFFFFFF)); -assertEquals(117, arg_set(0xFFFFFFFF));
\ No newline at end of file +assertEquals(117, arg_set(0xFFFFFFFF)); diff --git a/deps/v8/test/mjsunit/array-constructor-feedback.js b/deps/v8/test/mjsunit/array-constructor-feedback.js index 72ff12c08f..7cd421bd1b 100644 --- a/deps/v8/test/mjsunit/array-constructor-feedback.js +++ b/deps/v8/test/mjsunit/array-constructor-feedback.js @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax --smi-only-arrays --expose-gc -// Flags: --track-allocation-sites --noalways-opt +// Flags: --noalways-opt // Test element kind of objects. // Since --smi-only-arrays affects builtins, its default setting at compile @@ -35,11 +35,6 @@ // in this test case. Depending on whether smi-only arrays are actually // enabled, this test takes the appropriate code path to check smi-only arrays. -// Reset the GC stress mode to be off. Needed because AllocationMementos only -// live for one gc, so a gc that happens in certain fragile areas of the test -// can break assumptions. -%SetFlags("--gc-interval=-1") - // support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8)); support_smi_only_arrays = true; @@ -138,8 +133,8 @@ if (support_smi_only_arrays) { })(); - // Test: Ensure that bailouts from the stub don't deopt a crankshafted - // method with a call to that stub. + // Test: Ensure that inlined array calls in crankshaft learn from deopts + // based on the move to a dictionary for the array. (function() { function bar(len) { return new Array(len); @@ -152,10 +147,16 @@ if (support_smi_only_arrays) { a = bar(10); assertKind(elements_kind.fast, a); assertOptimized(bar); - // The stub bails out, but the method call should be fine. + // bar should deopt because the length is too large. + a = bar(100000); + assertUnoptimized(bar); + assertKind(elements_kind.dictionary, a); + // The allocation site now has feedback that means the array constructor + // will not be inlined. + %OptimizeFunctionOnNextCall(bar); a = bar(100000); - assertOptimized(bar); assertKind(elements_kind.dictionary, a); + assertOptimized(bar); // If the argument isn't a smi, it bails out as well a = bar("oops"); @@ -172,8 +173,12 @@ if (support_smi_only_arrays) { barn(1, 2, 3); assertOptimized(barn); a = barn(1, "oops", 3); - // The stub should bail out but the method should remain optimized. + // The method should deopt, but learn from the failure to avoid inlining + // the array. assertKind(elements_kind.fast, a); + assertUnoptimized(barn); + %OptimizeFunctionOnNextCall(barn); + a = barn(1, "oops", 3); assertOptimized(barn); })(); @@ -219,4 +224,29 @@ if (support_smi_only_arrays) { assertFalse(Realm.eval(contextB, "bar2();") instanceof Array); assertTrue(Realm.eval(contextB, "bar2() instanceof Array")); })(); + + // Test: create array with packed feedback, then optimize/inline + // function. Verify that if we ask for a holey array then we deopt. + // Reoptimization will proceed with the correct feedback and we + // won't deopt anymore. + (function() { + function bar(len) { return new Array(len); } + bar(0); + bar(0); + %OptimizeFunctionOnNextCall(bar); + a = bar(0); + assertOptimized(bar); + assertFalse(isHoley(a)); + a = bar(1); // ouch! + assertUnoptimized(bar); + assertTrue(isHoley(a)); + // Try again + %OptimizeFunctionOnNextCall(bar); + a = bar(100); + assertOptimized(bar); + assertTrue(isHoley(a)); + a = bar(0); + assertOptimized(bar); + assertTrue(isHoley(a)); + })(); } diff --git a/deps/v8/test/mjsunit/array-feedback.js b/deps/v8/test/mjsunit/array-feedback.js index 6b1cbb3f5f..4129be1f88 100644 --- a/deps/v8/test/mjsunit/array-feedback.js +++ b/deps/v8/test/mjsunit/array-feedback.js @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax --smi-only-arrays --expose-gc -// Flags: --track-allocation-sites --noalways-opt +// Flags: --noalways-opt // Test element kind of objects. // Since --smi-only-arrays affects builtins, its default setting at compile @@ -35,11 +35,6 @@ // in this test case. Depending on whether smi-only arrays are actually // enabled, this test takes the appropriate code path to check smi-only arrays. -// Reset the GC stress mode to be off. Needed because AllocationMementos only -// live for one gc, so a gc that happens in certain fragile areas of the test -// can break assumptions. -%SetFlags("--gc-interval=-1") - // support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8)); support_smi_only_arrays = true; @@ -90,66 +85,66 @@ if (support_smi_only_arrays) { // Verify that basic elements kind feedback works for non-constructor // array calls (as long as the call is made through an IC, and not // a CallStub). - (function (){ - function create0() { - return Array(); - } - - // Calls through ICs need warm up through uninitialized, then - // premonomorphic first. - create0(); - create0(); - a = create0(); - assertKind(elements_kind.fast_smi_only, a); - a[0] = 3.5; - b = create0(); - assertKind(elements_kind.fast_double, b); - - function create1(arg) { - return Array(arg); - } - - create1(0); - create1(0); - a = create1(0); - assertFalse(isHoley(a)); - assertKind(elements_kind.fast_smi_only, a); - a[0] = "hello"; - b = create1(10); - assertTrue(isHoley(b)); - assertKind(elements_kind.fast, b); - - a = create1(100000); - assertKind(elements_kind.dictionary, a); - - function create3(arg1, arg2, arg3) { - return Array(arg1, arg2, arg3); - } - - create3(); - create3(); - a = create3(1,2,3); - a[0] = 3.5; - b = create3(1,2,3); - assertKind(elements_kind.fast_double, b); - assertFalse(isHoley(b)); - })(); + // (function (){ + // function create0() { + // return Array(); + // } + + // // Calls through ICs need warm up through uninitialized, then + // // premonomorphic first. + // create0(); + // create0(); + // a = create0(); + // assertKind(elements_kind.fast_smi_only, a); + // a[0] = 3.5; + // b = create0(); + // assertKind(elements_kind.fast_double, b); + + // function create1(arg) { + // return Array(arg); + // } + + // create1(0); + // create1(0); + // a = create1(0); + // assertFalse(isHoley(a)); + // assertKind(elements_kind.fast_smi_only, a); + // a[0] = "hello"; + // b = create1(10); + // assertTrue(isHoley(b)); + // assertKind(elements_kind.fast, b); + + // a = create1(100000); + // assertKind(elements_kind.dictionary, a); + + // function create3(arg1, arg2, arg3) { + // return Array(arg1, arg2, arg3); + // } + + // create3(); + // create3(); + // a = create3(1,2,3); + // a[0] = 3.5; + // b = create3(1,2,3); + // assertKind(elements_kind.fast_double, b); + // assertFalse(isHoley(b)); + // })(); // Verify that keyed calls work - (function (){ - function create0(name) { - return this[name](); - } + // (function (){ + // function create0(name) { + // return this[name](); + // } - name = "Array"; - create0(name); - create0(name); - a = create0(name); - a[0] = 3.5; - b = create0(name); - assertKind(elements_kind.fast_double, b); - })(); + // name = "Array"; + // create0(name); + // create0(name); + // a = create0(name); + // a[0] = 3.5; + // b = create0(name); + // assertKind(elements_kind.fast_double, b); + // })(); // Verify that the IC can't be spoofed by patching @@ -173,28 +168,28 @@ if (support_smi_only_arrays) { // though the type information is reset. // TODO(mvstanton): instead, consume the type feedback gathered up // until crankshaft time. - (function (){ - function create0() { - return Array(); - } - - create0(); - create0(); - a = create0(); - a[0] = 3.5; - %OptimizeFunctionOnNextCall(create0); - create0(); - // This test only makes sense if crankshaft is allowed - if (4 != %GetOptimizationStatus(create0)) { - create0(); - b = create0(); - assertKind(elements_kind.fast_smi_only, b); - b[0] = 3.5; - c = create0(); - assertKind(elements_kind.fast_double, c); - assertOptimized(create0); - } - })(); + // (function (){ + // function create0() { + // return Array(); + // } + + // create0(); + // create0(); + // a = create0(); + // a[0] = 3.5; + // %OptimizeFunctionOnNextCall(create0); + // create0(); + // // This test only makes sense if crankshaft is allowed + // if (4 != %GetOptimizationStatus(create0)) { + // create0(); + // b = create0(); + // assertKind(elements_kind.fast_smi_only, b); + // b[0] = 3.5; + // c = create0(); + // assertKind(elements_kind.fast_double, c); + // assertOptimized(create0); + // } + // })(); // Verify that cross context calls work diff --git a/deps/v8/test/mjsunit/array-iteration.js b/deps/v8/test/mjsunit/array-iteration.js index 033bb5443a..d11f984bee 100644 --- a/deps/v8/test/mjsunit/array-iteration.js +++ b/deps/v8/test/mjsunit/array-iteration.js @@ -225,4 +225,3 @@ assertEquals(2, count); })(); - diff --git a/deps/v8/test/mjsunit/array-literal-feedback.js b/deps/v8/test/mjsunit/array-literal-feedback.js index d2245c62a2..cfda0f6d5f 100644 --- a/deps/v8/test/mjsunit/array-literal-feedback.js +++ b/deps/v8/test/mjsunit/array-literal-feedback.js @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax --smi-only-arrays --expose-gc -// Flags: --track-allocation-sites --noalways-opt +// Flags: --noalways-opt // Test element kind of objects. // Since --smi-only-arrays affects builtins, its default setting at compile @@ -88,11 +88,15 @@ if (support_smi_only_arrays) { } get_literal(3); - get_literal(3); - %OptimizeFunctionOnNextCall(get_literal); + // It's important to store a from before we crankshaft get_literal, because + // mementos won't be created from crankshafted code at all. a = get_literal(3); + %OptimizeFunctionOnNextCall(get_literal); + get_literal(3); assertOptimized(get_literal); assertTrue(%HasFastSmiElements(a)); + // a has a memento so the transition caused by the store will affect the + // boilerplate. a[0] = 3.5; // We should have transitioned the boilerplate array to double, and diff --git a/deps/v8/test/mjsunit/array-natives-elements.js b/deps/v8/test/mjsunit/array-natives-elements.js index 04c2f73d7e..cf848bb4b9 100644 --- a/deps/v8/test/mjsunit/array-natives-elements.js +++ b/deps/v8/test/mjsunit/array-natives-elements.js @@ -26,7 +26,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax --smi-only-arrays -// Flags: --notrack-allocation-sites // Test element kind of objects. // Since --smi-only-arrays affects builtins, its default setting at compile time diff --git a/deps/v8/test/mjsunit/array-non-smi-length.js b/deps/v8/test/mjsunit/array-non-smi-length.js index 23a25ee797..11277aff60 100644 --- a/deps/v8/test/mjsunit/array-non-smi-length.js +++ b/deps/v8/test/mjsunit/array-non-smi-length.js @@ -43,4 +43,3 @@ function TestNonSmiArrayLength() { } TestNonSmiArrayLength(); - diff --git a/deps/v8/test/mjsunit/array-pop.js b/deps/v8/test/mjsunit/array-pop.js index f193f09c2f..17771839ab 100644 --- a/deps/v8/test/mjsunit/array-pop.js +++ b/deps/v8/test/mjsunit/array-pop.js @@ -25,6 +25,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Flags: --allow-natives-syntax +// // Check pops with various number of arguments. (function() { var a = []; @@ -121,3 +123,18 @@ assertEquals(99 - i, x.pop(), i + 'th iteration'); } })(); + +(function () { + function f(a, deopt) { + var v = a.pop() ? 1 : 2; + if (deopt) %DeoptimizeFunction(f); + return v; + } + + var a = [true, true, true, true] + assertEquals(1, f(a, false)); + assertEquals(1, f(a, false)); + %OptimizeFunctionOnNextCall(f); + assertEquals(1, f(a, false)); + assertEquals(1, f(a, true)); +})(); diff --git a/deps/v8/test/mjsunit/array-push.js b/deps/v8/test/mjsunit/array-push.js index 2a25a9cc9e..c87fd128e4 100644 --- a/deps/v8/test/mjsunit/array-push.js +++ b/deps/v8/test/mjsunit/array-push.js @@ -25,6 +25,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Flags: --allow-natives-syntax + // Check pushes with various number of arguments. (function() { var a = []; @@ -113,3 +115,34 @@ assertEquals(i + 1, x.length, i + 'th iteration'); } })(); + +(function() { + function f(a, i) { + a.push(i); + } + + var a = [1,2,3]; + a.f = function() { return 10; } + f(a, 4); + f(a, 5); + f(a, 6); + f(a, 7); + f(a, {}); + assertEquals(10, a.f()); +})(); + +(function() { + function f(a, i) { + a.push(i); + } + + var a = [1,2,3]; + a.f = function() { return 10; } + f(a, 4); + f(a, 5); + f(a, 6); + %OptimizeFunctionOnNextCall(f); + f(a, 7); + f(a, {}); + assertEquals(10, a.f()); +})(); diff --git a/deps/v8/test/mjsunit/array-tostring.js b/deps/v8/test/mjsunit/array-tostring.js index 6708657eef..5be3d5045c 100644 --- a/deps/v8/test/mjsunit/array-tostring.js +++ b/deps/v8/test/mjsunit/array-tostring.js @@ -156,4 +156,4 @@ for (var i = 0; i < 3; i++) { }}); } Number.prototype.arrayToLocaleString = Array.prototype.toLocaleString; -assertEquals("42,42,42", (42).arrayToLocaleString());
\ No newline at end of file +assertEquals("42,42,42", (42).arrayToLocaleString()); diff --git a/deps/v8/test/mjsunit/bool-concat.js b/deps/v8/test/mjsunit/bool-concat.js new file mode 100644 index 0000000000..1306dcbbbc --- /dev/null +++ b/deps/v8/test/mjsunit/bool-concat.js @@ -0,0 +1,39 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +function format(a) { + if (a) { + return "X"+true+"Y"; + } else { + return "X"+false+"Y"; + } +} + +for (var i = 0; i < 1000; i++) { + assertEquals("XtrueY", format(true)); + assertEquals("XfalseY", format(false)); +} diff --git a/deps/v8/test/mjsunit/bugs/bug-1344252.js b/deps/v8/test/mjsunit/bugs/bug-1344252.js index 1723834c09..747ce199ce 100644 --- a/deps/v8/test/mjsunit/bugs/bug-1344252.js +++ b/deps/v8/test/mjsunit/bugs/bug-1344252.js @@ -76,4 +76,3 @@ Object.prototype.__defineSetter__('z', function(value) { result_z = value; }); o2.z = 27; assertEquals(27, result_z); assertTrue(typeof o2.z == 'undefined'); - diff --git a/deps/v8/test/mjsunit/bugs/bug-proto.js b/deps/v8/test/mjsunit/bugs/bug-proto.js index 149088e9de..5638336c45 100644 --- a/deps/v8/test/mjsunit/bugs/bug-proto.js +++ b/deps/v8/test/mjsunit/bugs/bug-proto.js @@ -59,4 +59,3 @@ assertSame(undefined, Realm.eval(realmB, "Realm.shared.__proto__")); Realm.eval(realmB, "Realm.shared.__proto__ = {c: 3}"); assertSame(1, o.a); assertSame(undefined, o.c); - diff --git a/deps/v8/test/mjsunit/closures.js b/deps/v8/test/mjsunit/closures.js index 7c1197107f..5ce26ca747 100644 --- a/deps/v8/test/mjsunit/closures.js +++ b/deps/v8/test/mjsunit/closures.js @@ -44,4 +44,3 @@ function test(n) { test(1); test(42); test(239); - diff --git a/deps/v8/test/mjsunit/compare-character.js b/deps/v8/test/mjsunit/compare-character.js index cabe0137bf..8c812eec0e 100644 --- a/deps/v8/test/mjsunit/compare-character.js +++ b/deps/v8/test/mjsunit/compare-character.js @@ -47,4 +47,3 @@ for (var i in a) { assertEquals(f < x, 'f' < x, ">r" + x); assertEquals(f <= x, 'f' <= x, ">=r" + x); } - diff --git a/deps/v8/test/mjsunit/compare-nan.js b/deps/v8/test/mjsunit/compare-nan.js index c4f7817ff8..a4224ff1b3 100644 --- a/deps/v8/test/mjsunit/compare-nan.js +++ b/deps/v8/test/mjsunit/compare-nan.js @@ -63,4 +63,3 @@ for (var i in b) { "assertFalse(" + x + " >= NaN, '' + " + x + " + ' >= NaN');\n"; eval(program); } - diff --git a/deps/v8/test/mjsunit/compiler/alloc-number-debug.js b/deps/v8/test/mjsunit/compiler/alloc-number-debug.js new file mode 100644 index 0000000000..ccfcc0c185 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/alloc-number-debug.js @@ -0,0 +1,44 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +// Try to get a GC because of a heap number allocation while we +// have live values (o) in a register. +function f(o) { + var x = 1.5; + var y = 2.5; + for (var i = 1; i < 3; i += 1) { + %SetAllocationTimeout(1, 0, false); + o.val = x + y + i; + %SetAllocationTimeout(-1, -1, true); + } + return o; +} + +var o = { val: 0 }; +f(o); diff --git a/deps/v8/test/mjsunit/compiler/compare-map-elim.js b/deps/v8/test/mjsunit/compiler/compare-map-elim.js new file mode 100644 index 0000000000..288d4811a6 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/compare-map-elim.js @@ -0,0 +1,51 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --check-elimination + +a = { + f: function() { this.y = 3; } +}; +b = { + f: function() { this.y = 4; } +}; + +function x(z) { + return z.f(); +} + +x(a); +x(b); +x(a); +x(b); +x(a); +x(b); + +%OptimizeFunctionOnNextCall(x) + +x(a); +x(b); diff --git a/deps/v8/test/mjsunit/compiler/compare-map-elim2.js b/deps/v8/test/mjsunit/compiler/compare-map-elim2.js new file mode 100644 index 0000000000..0c0540ccab --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/compare-map-elim2.js @@ -0,0 +1,130 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --check-elimination + + +function test_empty() { + function foo(o) { + return { value: o.value }; + } + + function Base() { + this.v_ = 5; + } + Base.prototype.__defineGetter__("value", function() { return 1; }); + + var a = new Base(); + a.a = 1; + foo(a); + + Base.prototype.__defineGetter__("value", function() { return this.v_; }); + + var b = new Base(); + b.b = 1; + foo(b); + + var d = new Base(); + d.d = 1; + d.value; + + %OptimizeFunctionOnNextCall(foo); + + var o = foo(b); +} + + +function test_narrow1() { + function foo(o) { + return { value: o.value }; + } + + function Base() { + this.v_ = 5; + } + Base.prototype.__defineGetter__("value", function() { return 1; }); + + var a = new Base(); + a.a = 1; + foo(a); + + Base.prototype.__defineGetter__("value", function() { return this.v_; }); + + var b = new Base(); + b.b = 1; + foo(b); + + var c = new Base(); + c.c = 1; + foo(c); + + var d = new Base(); + d.d = 1; + d.value; + + %OptimizeFunctionOnNextCall(foo); + + var o = foo(b); +} + + +function test_narrow2() { + function foo(o, flag) { + return { value: o.value(flag) }; + } + + function Base() { + this.v_ = 5; + } + Base.prototype.value = function(flag) { return flag ? this.v_ : this.v_; }; + + + var a = new Base(); + a.a = 1; + foo(a, false); + foo(a, false); + + var b = new Base(); + b.b = 1; + foo(b, true); + + var c = new Base(); + c.c = 1; + foo(c, true); + + var d = new Base(); + d.d = 1; + d.value(true); + + %OptimizeFunctionOnNextCall(foo); + + var o = foo(b); +} + +test_empty(); +test_narrow1(); +test_narrow2(); diff --git a/deps/v8/test/mjsunit/compiler/compare-objeq-elim.js b/deps/v8/test/mjsunit/compiler/compare-objeq-elim.js new file mode 100644 index 0000000000..4492df45c3 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/compare-objeq-elim.js @@ -0,0 +1,85 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --check-elimination + +function A(x, y) { + this.x = x; + this.y = y; +} + +function B(x, y) { + this.x = x; + this.y = y; +} + +function F1(a, b) { + if (a == b) return a.x; + else return b.x; +} + +function F2(a, b) { + if (a == b) return a.x; + else return b.x; +} + +function F3(a, b) { + var f = a.y; + if (a == b) return a.x; + else return b.x; +} + +function F4(a, b) { + var f = b.y; + if (a == b) return a.x; + else return b.x; +} + +%NeverOptimizeFunction(test); + +function test(f, a, b) { + f(a, a); + f(a, b); + f(b, a); + f(b, c); + f(b, b); + f(c, c); + + %OptimizeFunctionOnNextCall(f) + + assertEquals(a.x, f(a, a)); + assertEquals(b.x, f(b, b)); +} + +var a = new A(3, 5); +var b = new B(2, 6); +var c = new A(1, 7); + +test(F1, a, c); +test(F2, a, b); +test(F3, a, b); +test(F4, a, b); diff --git a/deps/v8/test/mjsunit/compiler/concurrent-invalidate-transition-map.js b/deps/v8/test/mjsunit/compiler/concurrent-invalidate-transition-map.js index 699534f665..2a20790eaa 100644 --- a/deps/v8/test/mjsunit/compiler/concurrent-invalidate-transition-map.js +++ b/deps/v8/test/mjsunit/compiler/concurrent-invalidate-transition-map.js @@ -59,3 +59,5 @@ assertUnoptimized(add_field, "no sync"); %UnblockConcurrentRecompilation(); // Sync with background thread to conclude optimization that bailed out. assertUnoptimized(add_field, "sync"); +// Clear type info for stress runs. +%ClearFunctionTypeFeedback(add_field); diff --git a/deps/v8/test/mjsunit/compiler/concurrent-proto-change.js b/deps/v8/test/mjsunit/compiler/concurrent-proto-change.js index e126465a95..3abf292c92 100644 --- a/deps/v8/test/mjsunit/compiler/concurrent-proto-change.js +++ b/deps/v8/test/mjsunit/compiler/concurrent-proto-change.js @@ -54,3 +54,5 @@ assertUnoptimized(f, "no sync"); // Optimization eventually bails out due to map dependency. assertUnoptimized(f, "sync"); assertEquals(2, f(o)); +//Clear type info for stress runs. +%ClearFunctionTypeFeedback(f); diff --git a/deps/v8/test/mjsunit/compiler/control-flow-1.js b/deps/v8/test/mjsunit/compiler/control-flow-1.js index 973d9b6668..ca7ad87850 100644 --- a/deps/v8/test/mjsunit/compiler/control-flow-1.js +++ b/deps/v8/test/mjsunit/compiler/control-flow-1.js @@ -52,4 +52,4 @@ function g1(x, y) { } assertTrue(g1(0, 0)); -assertFalse(g1(0, 1));
\ No newline at end of file +assertFalse(g1(0, 1)); diff --git a/deps/v8/test/mjsunit/compiler/dead-loops-neg.js b/deps/v8/test/mjsunit/compiler/dead-loops-neg.js new file mode 100644 index 0000000000..dbf500b48e --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/dead-loops-neg.js @@ -0,0 +1,100 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +// Presents negative opportunities for dead loop removal. + +function loop1() { + while (true) return; +} + +function loop2() { + var i = 0; + while (i++ < 10) ; + return i; // value of {i} escapes. + // can only remove the loop with induction variable analysis. +} + +function loop3() { + var i = 0; + for (; i < 10; i++) ; + return i; // value of {i} escapes. + // can only remove the loop with induction variable analysis. +} + +function loop4() { + var a = 0; + for (var i = 0; i < 10; i++) a++; + return a; // value of {a} escapes. + // can only remove the loop with induction variable analysis. +} + +function loop5() { + var a = new Int32Array(4), sum = 0; + for (var i = 0; i < a.length; i++) { + sum += a[i]; + } + return sum; // {sum} escapes. + // can only remove the loop by figuring out that all elements of {a} are 0. +} + +function loop6(a) { + for (var i = 0; i < a; i++) ; // implicit a.valueOf(). + // can only remove the loop by guarding on the type of a. +} + +function loop7(a) { + for (var i = 0; i < 10; i++) a.toString(); // unknown side-effect on a. + // can only remove the loop by guarding on the type of a. +} + +function loop8(a) { + for (var i = 0; i < 10; i++) a.valueOf(); // unknown side-effect on a. + // can only remove the loop by guarding on the type of a. +} + +var no_params_loops = [loop1, loop2, loop3, loop4, loop5, loop6]; +var params_loops = [loop6, loop7, loop8]; + +for (var i = 0; i < no_params_loops.length; i++) { + var f = no_params_loops[i]; + f(); + f(); + f(); + %OptimizeFunctionOnNextCall(f); + f(); +} + +for (var i = 0; i < params_loops.length; i++) { + var f = params_loops[i]; + f(3); + f(7); + f(11); + %OptimizeFunctionOnNextCall(f); + f(9); +} diff --git a/deps/v8/test/mjsunit/compiler/dead-loops.js b/deps/v8/test/mjsunit/compiler/dead-loops.js new file mode 100644 index 0000000000..2301b129dd --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/dead-loops.js @@ -0,0 +1,87 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +// Presents opportunities for dead loop removal. + +function loop1() { + while (false) ; // doesn't even loop. +} + +function loop2() { + var i = 0; + while (i++ < 10) ; // nothing in the body. +} + +function loop3() { + for (var i = 0; i < 10; i++) ; // nothing in the body. +} + +function loop4() { + var a = 0; + for (var i = 0; i < 10; i++) a++; // {a} is dead after the loop. +} + +function loop5() { + var a = new Int32Array(4), sum = 0; + for (var i = 0; i < a.length; i++) { + // Involves only reads on typed arrays, and {i} doesn't overflow. + sum += a[i]; + } +} + +function loop6() { + var a = new Array(4), sum = 0; + for (var i = 0; i < a.length; i++) { + // Involves only in-bounds read on the array {a}. + // Have to prove that {a} doesn't have getters...? + sum += a[i]; + } +} + +function loop7() { + for (var i = 0; i < 10; i++) { + new Object(); // Have to prove the allocation doesn't escape. + } +} + +function loop8() { + for (var i = 0; i < 10; i++) { + var x = {}; // Have to prove the allocation doesn't escape. + } +} + +var loops = [loop1, loop2, loop3, loop4, loop5, loop6, loop7, loop8]; + +for (var i = 0; i < loops.length; i++) { + var f = loops[i]; + f(); + f(); + %OptimizeFunctionOnNextCall(f); + f(); +} diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis-arguments.js b/deps/v8/test/mjsunit/compiler/escape-analysis-arguments.js new file mode 100644 index 0000000000..bdab182fed --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/escape-analysis-arguments.js @@ -0,0 +1,187 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --use-escape-analysis --expose-gc + + +// Simple test of capture +(function testCapturedArguments() { + function h() { + return g.arguments[0]; + } + + function g(x) { + return h(); + } + + function f() { + var l = { y : { z : 4 }, x : 2 } + var r = g(l); + assertEquals(2, r.x); + assertEquals(2, l.x); + l.x = 3; + l.y.z = 5; + // Test that the arguments object is properly + // aliased + assertEquals(3, r.x); + assertEquals(3, l.x); + assertEquals(5, r.y.z); + } + + f(); f(); f(); + %OptimizeFunctionOnNextCall(f); + f(); +})(); + + +// Get the arguments object twice, test aliasing +(function testTwoCapturedArguments() { + function h() { + return g.arguments[0]; + } + + function i() { + return g.arguments[0]; + } + + function g(x) { + return {h : h() , i : i()}; + } + + function f() { + var l = { y : { z : 4 }, x : 2 } + var r = g(l); + assertEquals(2, r.h.x) + l.y.z = 3; + assertEquals(3, r.h.y.z); + assertEquals(3, r.i.y.z); + } + + f(); f(); f(); + %OptimizeFunctionOnNextCall(f); + f(); +})(); + + +// Nested arguments object test +(function testTwoCapturedArgumentsNested() { + function i() { + return { gx : g.arguments[0], hx : h.arguments[0] }; + } + + function h(x) { + return i(); + } + + function g(x) { + return h(x.y); + } + + function f() { + var l = { y : { z : 4 }, x : 2 } + var r = g(l); + assertEquals(2, r.gx.x) + assertEquals(4, r.gx.y.z) + assertEquals(4, r.hx.z) + l.y.z = 3; + assertEquals(3, r.gx.y.z) + assertEquals(3, r.hx.z) + assertEquals(3, l.y.z) + } + + f(); f(); f(); + %OptimizeFunctionOnNextCall(f); + f(); f(); + %OptimizeFunctionOnNextCall(f); + f(); f(); +})(); + + +// Nested arguments object test with different inlining +(function testTwoCapturedArgumentsNested2() { + function i() { + return { gx : g.arguments[0], hx : h.arguments[0] }; + } + + function h(x) { + return i(); + } + + function g(x) { + return h(x.y); + } + + function f() { + var l = { y : { z : 4 }, x : 2 } + var r = g(l); + assertEquals(2, r.gx.x) + assertEquals(4, r.gx.y.z) + assertEquals(4, r.hx.z) + l.y.z = 3; + assertEquals(3, r.gx.y.z) + assertEquals(3, r.hx.z) + assertEquals(3, l.y.z) + } + + %NeverOptimizeFunction(i); + f(); f(); f(); + %OptimizeFunctionOnNextCall(f); + f(); f(); + %OptimizeFunctionOnNextCall(f); + f(); f(); +})(); + + +// Multiple captured argument test +(function testTwoArgumentsCapture() { + function h() { + return { a : g.arguments[1], b : g.arguments[0] }; + } + + function g(x, y) { + return h(); + } + + function f() { + var l = { y : { z : 4 }, x : 2 } + var k = { t : { u : 3 } }; + var r = g(k, l); + assertEquals(2, r.a.x) + assertEquals(4, r.a.y.z) + assertEquals(3, r.b.t.u) + l.y.z = 6; + r.b.t.u = 7; + assertEquals(6, r.a.y.z) + assertEquals(7, k.t.u) + } + + f(); f(); f(); + %OptimizeFunctionOnNextCall(f); + f(); f(); + %OptimizeFunctionOnNextCall(f); + f(); f(); +})(); diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis.js b/deps/v8/test/mjsunit/compiler/escape-analysis.js index dccc476925..b12e7bfca0 100644 --- a/deps/v8/test/mjsunit/compiler/escape-analysis.js +++ b/deps/v8/test/mjsunit/compiler/escape-analysis.js @@ -303,6 +303,101 @@ })(); +// Test non-shallow nested graph of captured objects with duplicates +(function testDeepDuplicate() { + function constructor1() { + this.x = 23; + } + function constructor2(nested) { + this.a = 17; + this.b = nested; + this.c = 42; + } + function deep(shouldDeopt) { + var o1 = new constructor1(); + var o2 = new constructor2(o1); + var o3 = new constructor2(o1); + assertEquals(17, o2.a); + assertEquals(23, o2.b.x); + assertEquals(42, o2.c); + o3.c = 54; + o1.x = 99; + if (shouldDeopt) %DeoptimizeFunction(deep); + assertEquals(99, o1.x); + assertEquals(99, o2.b.x); + assertEquals(99, o3.b.x); + assertEquals(54, o3.c); + assertEquals(17, o3.a); + assertEquals(42, o2.c); + assertEquals(17, o2.a); + o3.b.x = 1; + assertEquals(1, o1.x); + } + deep(false); deep(false); + %OptimizeFunctionOnNextCall(deep); + deep(false); deep(false); + deep(true); deep(true); +})(); + + +// Test non-shallow nested graph of captured objects with inline +(function testDeepInline() { + function h() { + return { y : 3 }; + } + + function g(x) { + var u = { x : h() }; + %DeoptimizeFunction(f); + return u; + } + + function f() { + var l = { dummy : { } }; + var r = g(l); + assertEquals(3, r.x.y); + } + + f(); f(); f(); + %OptimizeFunctionOnNextCall(f); + f(); +})(); + + +// Test two nested objects +(function testTwoNestedObjects() { + function f() { + var l = { x : { y : 111 } }; + var l2 = { x : { y : 111 } }; + %DeoptimizeFunction(f); + assertEquals(111, l.x.y); + assertEquals(111, l2.x.y); + } + + f(); f(); f(); + %OptimizeFunctionOnNextCall(f); + f(); +})(); + + +// Test a nested object and a duplicate +(function testTwoObjectsWithDuplicate() { + function f() { + var l = { x : { y : 111 } }; + var dummy = { d : 0 }; + var l2 = l.x; + %DeoptimizeFunction(f); + assertEquals(111, l.x.y); + assertEquals(111, l2.y); + assertEquals(0, dummy.d); + } + + f(); f(); f(); + %OptimizeFunctionOnNextCall(f); + f(); +})(); + + // Test materialization of a field that requires a Smi value. (function testSmiField() { var deopt = { deopt:false }; diff --git a/deps/v8/test/mjsunit/compiler/inline-throw.js b/deps/v8/test/mjsunit/compiler/inline-throw.js index e3aab39efa..099b9d3351 100644 --- a/deps/v8/test/mjsunit/compiler/inline-throw.js +++ b/deps/v8/test/mjsunit/compiler/inline-throw.js @@ -66,4 +66,3 @@ try { } catch(e) { assertEquals("wow", e); } - diff --git a/deps/v8/test/mjsunit/compiler/lazy-const-lookup.js b/deps/v8/test/mjsunit/compiler/lazy-const-lookup.js index b4f15a1c9f..ff4558e7ef 100644 --- a/deps/v8/test/mjsunit/compiler/lazy-const-lookup.js +++ b/deps/v8/test/mjsunit/compiler/lazy-const-lookup.js @@ -38,4 +38,3 @@ function outer() { } outer(); - diff --git a/deps/v8/test/mjsunit/compiler/load-elimination-params.js b/deps/v8/test/mjsunit/compiler/load-elimination-params.js new file mode 100644 index 0000000000..13a4a8596d --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/load-elimination-params.js @@ -0,0 +1,71 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --load-elimination + +// Test local load elimination of redundant loads and stores. + +function B(x, y) { + this.x = x; + this.y = y; + return this; +} + +function test_params1(a, b) { + var i = a.x; + var j = a.x; + var k = b.x; + var l = b.x; + return i + j + k + l; +} + +assertEquals(14, test_params1(new B(3, 4), new B(4, 5))); +assertEquals(110, test_params1(new B(11, 7), new B(44, 8))); + +%OptimizeFunctionOnNextCall(test_params1); + +assertEquals(6, test_params1(new B(1, 7), new B(2, 8))); + +function test_params2(a, b) { + var o = new B(a + 1, b); + o.x = a; + var i = o.x; + o.x = a; + var j = o.x; + o.x = b; + var k = o.x; + o.x = b; + var l = o.x; + return i + j + k + l; +} + +assertEquals(14, test_params2(3, 4)); +assertEquals(110, test_params2(11, 44)); + +%OptimizeFunctionOnNextCall(test_params2); + +assertEquals(6, test_params2(1, 2)); diff --git a/deps/v8/test/mjsunit/compiler/load-elimination.js b/deps/v8/test/mjsunit/compiler/load-elimination.js index e019508c65..9bf8564308 100644 --- a/deps/v8/test/mjsunit/compiler/load-elimination.js +++ b/deps/v8/test/mjsunit/compiler/load-elimination.js @@ -35,11 +35,34 @@ function B(x, y) { return this; } +function C() { +} + function test_load() { var a = new B(1, 2); return a.x + a.x + a.x + a.x; } + +function test_load_from_different_contexts() { + var r = 1; + this.f = function() { + var fr = r; + this.g = function(flag) { + var gr; + if (flag) { + gr = r; + } else { + gr = r; + } + return gr + r + fr; + }; + }; + this.f(); + return this.g(true); +} + + function test_store_load() { var a = new B(1, 2); a.x = 4; @@ -64,6 +87,31 @@ function test_nonaliasing_store1() { return f + g + h + a.x; } +function test_transitioning_store1() { + var a = new B(2, 3); + var f = a.x, g = a.y; + var b = new B(3, 4); + return a.x + a.y; +} + +function test_transitioning_store2() { + var b = new C(); + var a = new B(-1, 5); + var f = a.x, g = a.y; + b.x = 9; + b.y = 11; + return a.x + a.y; +} + +var false_v = false; +function test_transitioning_store3() { + var o = new C(); + var v = o; + if (false_v) v = 0; + v.x = 20; + return o.x; +} + function killall() { try { } catch(e) { } } @@ -100,7 +148,11 @@ function test(x, f) { } test(4, test_load); +test(3, new test_load_from_different_contexts().g); test(22, test_store_load); test(8, test_nonaliasing_store1); +test(5, test_transitioning_store1); +test(4, test_transitioning_store2); +test(20, test_transitioning_store3); test(22, test_store_load_kill); test(7, test_store_store); diff --git a/deps/v8/test/mjsunit/compiler/math-floor-global.js b/deps/v8/test/mjsunit/compiler/math-floor-global.js index 9ec183fab1..3b9d125453 100644 --- a/deps/v8/test/mjsunit/compiler/math-floor-global.js +++ b/deps/v8/test/mjsunit/compiler/math-floor-global.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --max-new-space-size=256 --allow-natives-syntax +// Flags: --max-new-space-size=128 --allow-natives-syntax // Test inlining of Math.floor when assigned to a global. var flo = Math.floor; @@ -140,8 +140,9 @@ function test() { // Test in a loop to cover the custom IC and GC-related issues. -for (var i = 0; i < 50; i++) { +for (var i = 0; i < 10; i++) { test(); + new Array(i * 10000); } @@ -158,4 +159,4 @@ assertEquals(-0, floorsum(1, -0)); %OptimizeFunctionOnNextCall(floorsum); // The optimized function will deopt. Run it with enough iterations to try // to optimize via OSR (triggering the bug). -assertEquals(-0, floorsum(100000, -0)); +assertEquals(-0, floorsum(50000, -0)); diff --git a/deps/v8/test/mjsunit/compiler/math-floor-local.js b/deps/v8/test/mjsunit/compiler/math-floor-local.js index e44b15c734..fef3347e80 100644 --- a/deps/v8/test/mjsunit/compiler/math-floor-local.js +++ b/deps/v8/test/mjsunit/compiler/math-floor-local.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --max-new-space-size=256 --allow-natives-syntax +// Flags: --max-new-space-size=128 --allow-natives-syntax // Test inlining of Math.floor when assigned to a local. var test_id = 0; @@ -140,8 +140,9 @@ function test() { // Test in a loop to cover the custom IC and GC-related issues. -for (var i = 0; i < 50; i++) { +for (var i = 0; i < 10; i++) { test(); + new Array(i * 10000); } diff --git a/deps/v8/test/mjsunit/compiler/minus-zero.js b/deps/v8/test/mjsunit/compiler/minus-zero.js index 6efceb54e3..c161257d77 100644 --- a/deps/v8/test/mjsunit/compiler/minus-zero.js +++ b/deps/v8/test/mjsunit/compiler/minus-zero.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --allow-natives-syntax +// Flags: --allow-natives-syntax --no-fold-constants function add(x, y) { return x + y; @@ -35,3 +35,59 @@ assertEquals(0, add(0, 0)); assertEquals(0, add(0, 0)); %OptimizeFunctionOnNextCall(add); assertEquals(-0, add(-0, -0)); + + +function test(x, y) { + assertTrue(%_IsMinusZero(-0)); + assertTrue(%_IsMinusZero(1/(-Infinity))); + assertTrue(%_IsMinusZero(x)); + + assertFalse(%_IsMinusZero(0)); + assertFalse(%_IsMinusZero(1/Infinity)); + assertFalse(%_IsMinusZero(0.1)); + assertFalse(%_IsMinusZero(-0.2)); + assertFalse(%_IsMinusZero({})); + assertFalse(%_IsMinusZero("")); + assertFalse(%_IsMinusZero("-0")); + assertFalse(%_IsMinusZero(function() {})); + assertFalse(%_IsMinusZero(y)); +} + +test(-0, 1.2); +test(-0, 1.2); +%OptimizeFunctionOnNextCall(test); +test(-0, 1.2); +assertOptimized(test); + + +function testsin() { + assertTrue(%_IsMinusZero(Math.sin(-0))); +} + +testsin(); +testsin(); +%OptimizeFunctionOnNextCall(testsin); +testsin(); + + +function testfloor() { + assertTrue(%_IsMinusZero(Math.floor(-0))); + assertFalse(%_IsMinusZero(Math.floor(2))); +} + +testfloor(); +testfloor(); +%OptimizeFunctionOnNextCall(testfloor); +testfloor(); + + +var double_one = Math.cos(0); + +function add(a, b) { + return a + b; +} + +assertEquals(1, 1/add(double_one, 0)); +assertEquals(1, 1/add(0, double_one)); +%OptimizeFunctionOnNextCall(add); +assertEquals(1/(-0 + -0), 1/add(-0, -0)); diff --git a/deps/v8/test/mjsunit/compiler/optimized-closures.js b/deps/v8/test/mjsunit/compiler/optimized-closures.js index eaf75f8d00..499e4d5e24 100644 --- a/deps/v8/test/mjsunit/compiler/optimized-closures.js +++ b/deps/v8/test/mjsunit/compiler/optimized-closures.js @@ -51,7 +51,3 @@ f(); assertEquals(42, a[0]); assertEquals(49, a[7]); assertEquals(-19, a[23]); - - - - diff --git a/deps/v8/test/mjsunit/compiler/osr-with-args.js b/deps/v8/test/mjsunit/compiler/osr-with-args.js index 44fa1cb2cf..4817ad7d44 100644 --- a/deps/v8/test/mjsunit/compiler/osr-with-args.js +++ b/deps/v8/test/mjsunit/compiler/osr-with-args.js @@ -29,7 +29,7 @@ function f() { var sum = 0; - for (var i = 0; i < 1000000; i++) { + for (var i = 0; i < 100000; i++) { var t = arguments[0] + 2; var x = arguments[1] + 2; var y = t + x + 5; @@ -39,6 +39,6 @@ function f() { return sum; } -for (var i = 0; i < 4; i++) { - assertEquals(17000000, f(2, 3)); +for (var i = 0; i < 3; i++) { + assertEquals(1700000, f(2, 3)); } diff --git a/deps/v8/test/mjsunit/compiler/regress-1394.js b/deps/v8/test/mjsunit/compiler/regress-1394.js index b1ce19267f..fbf435731f 100644 --- a/deps/v8/test/mjsunit/compiler/regress-1394.js +++ b/deps/v8/test/mjsunit/compiler/regress-1394.js @@ -56,4 +56,3 @@ for (var i = 0; i < 3; i++) assertEquals(i, f(i)); assertEquals(0, f(0)); assertEquals(1, f(1)); - diff --git a/deps/v8/test/mjsunit/compiler/regress-3260426.js b/deps/v8/test/mjsunit/compiler/regress-3260426.js index dfef424e7f..457064d2bb 100644 --- a/deps/v8/test/mjsunit/compiler/regress-3260426.js +++ b/deps/v8/test/mjsunit/compiler/regress-3260426.js @@ -33,4 +33,3 @@ function always_false() {} function test() { return always_false() ? 0 : 1; } assertEquals(1, test()); - diff --git a/deps/v8/test/mjsunit/compiler/regress-4.js b/deps/v8/test/mjsunit/compiler/regress-4.js index 0ec9a12b81..9a212baf2d 100644 --- a/deps/v8/test/mjsunit/compiler/regress-4.js +++ b/deps/v8/test/mjsunit/compiler/regress-4.js @@ -34,7 +34,7 @@ function f(p) { return y+x; } -for (var i=0; i<10000000; i++) f(42); +for (var i=0; i<100000; i++) f(42); var result = f("foo"); assertEquals("0foo6", result); diff --git a/deps/v8/test/mjsunit/compiler/regress-arguments.js b/deps/v8/test/mjsunit/compiler/regress-arguments.js index ebae5a0399..d32b435ff3 100644 --- a/deps/v8/test/mjsunit/compiler/regress-arguments.js +++ b/deps/v8/test/mjsunit/compiler/regress-arguments.js @@ -25,6 +25,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Flags: --allow-natives-syntax + // Test of arguments. // Test passing null or undefined as receiver. @@ -35,8 +37,15 @@ function h() { return f.apply(void 0, arguments); } var foo = 42; -for (var i=0; i<1000000; i++) assertEquals(42, g()); -for (var i=0; i<1000000; i++) assertEquals(42, h()); +for (var i = 0; i < 3; i++) assertEquals(42, g()); +%OptimizeFunctionOnNextCall(g); +%OptimizeFunctionOnNextCall(f); +assertEquals(42, g()); + +for (var i = 0; i < 3; i++) assertEquals(42, h()); +%OptimizeFunctionOnNextCall(h); +%OptimizeFunctionOnNextCall(f); +assertEquals(42, h()); var G1 = 21; var G2 = 22; @@ -49,4 +58,7 @@ function u() { Number.prototype.foo = 42; delete Number.prototype.foo; -for (var i=0; i<100000; i++) assertEquals(void 0, u()); +for (var i = 0; i < 3; i++) assertEquals(void 0, u()); +%OptimizeFunctionOnNextCall(u); +%OptimizeFunctionOnNextCall(f); +assertEquals(void 0, u()); diff --git a/deps/v8/test/mjsunit/compiler/regress-closures-with-eval.js b/deps/v8/test/mjsunit/compiler/regress-closures-with-eval.js index 57afb1643e..d95d128a9d 100644 --- a/deps/v8/test/mjsunit/compiler/regress-closures-with-eval.js +++ b/deps/v8/test/mjsunit/compiler/regress-closures-with-eval.js @@ -53,4 +53,4 @@ for (var n = 0; n < 5; n++) { withEval(expr, function(a) { return a; }); } %OptimizeFunctionOnNextCall(withEval); -withEval(expr, function(a) { return a; });
\ No newline at end of file +withEval(expr, function(a) { return a; }); diff --git a/deps/v8/test/mjsunit/compiler/regress-inline-callfunctionstub.js b/deps/v8/test/mjsunit/compiler/regress-inline-callfunctionstub.js index a39d26df0e..33655346a8 100644 --- a/deps/v8/test/mjsunit/compiler/regress-inline-callfunctionstub.js +++ b/deps/v8/test/mjsunit/compiler/regress-inline-callfunctionstub.js @@ -43,4 +43,3 @@ main(o.g); main(o.g); %OptimizeFunctionOnNextCall(main); main(o.g); - diff --git a/deps/v8/test/mjsunit/compiler/regress-rep-change.js b/deps/v8/test/mjsunit/compiler/regress-rep-change.js index 937099937d..c8a0983c44 100644 --- a/deps/v8/test/mjsunit/compiler/regress-rep-change.js +++ b/deps/v8/test/mjsunit/compiler/regress-rep-change.js @@ -25,6 +25,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Flags: --allow-natives-syntax + // Regression test for the case where a phi has two input operands with // the same value. @@ -35,8 +37,11 @@ function test(start) { for (var i = start; i < 10; i++) { } } -var n = 5000000; +var n = 3; for (var i = 0; i < n; ++i) { test(0); } + +%OptimizeFunctionOnNextCall(test); +test(0); diff --git a/deps/v8/test/mjsunit/compiler/regress-toint32.js b/deps/v8/test/mjsunit/compiler/regress-toint32.js index 54c2f76dd7..75892d4775 100644 --- a/deps/v8/test/mjsunit/compiler/regress-toint32.js +++ b/deps/v8/test/mjsunit/compiler/regress-toint32.js @@ -42,4 +42,3 @@ assertEquals(G, f(G)); assertEquals(G, f(G)); %OptimizeFunctionOnNextCall(f); assertEquals(G, f(G)); - diff --git a/deps/v8/test/mjsunit/compiler/rotate.js b/deps/v8/test/mjsunit/compiler/rotate.js index 2f4bc5a967..1c81e496ea 100644 --- a/deps/v8/test/mjsunit/compiler/rotate.js +++ b/deps/v8/test/mjsunit/compiler/rotate.js @@ -306,5 +306,3 @@ assertEquals(ROR4(0xFFFFFFFF, 40), ROR4_sa40(0xFFFFFFFF)); assertEquals(ROR4(0xFFFFFFFF, 40), ROR4_sa40(0xFFFFFFFF)); %OptimizeFunctionOnNextCall(ROR4_sa40); assertEquals(ROR4(0xFFFFFFFF, 40), ROR4_sa40(0xFFFFFFFF)); - - diff --git a/deps/v8/test/mjsunit/compiler/smi-stores-opt.js b/deps/v8/test/mjsunit/compiler/smi-stores-opt.js new file mode 100644 index 0000000000..ca0923abc9 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/smi-stores-opt.js @@ -0,0 +1,49 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +var o = {a:1.5}; +o.a = 0; +var a = o.a; + +function g() { + return 1; +} + +var o2 = {a:{}}; + +function f() { + var result = {a: a}; + var literal = {x:g()}; + return [result, literal]; +} + +f(); +f(); +%OptimizeFunctionOnNextCall(f); +assertEquals(1, f()[1].x); diff --git a/deps/v8/test/mjsunit/compiler/to-fast-properties.js b/deps/v8/test/mjsunit/compiler/to-fast-properties.js new file mode 100644 index 0000000000..26829d95e9 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/to-fast-properties.js @@ -0,0 +1,43 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This test requires OSR or --stress-runs=3 to optimize the top level script. + +for (var i = 0; i < 3; i++) { + // HToFastProperties is used for top-level object literals that have + // function property. + var obj = { + index: function() { return i; }, + x: 0 + } + var n = 10000; + // Loop to hit OSR. + for (var j = 0; j < n; j++) { + obj.x += i; + } + assertEquals(obj.index() * n, obj.x); +} diff --git a/deps/v8/test/mjsunit/concurrent-initial-prototype-change.js b/deps/v8/test/mjsunit/concurrent-initial-prototype-change.js index d5b1b99491..1b6f97b433 100644 --- a/deps/v8/test/mjsunit/concurrent-initial-prototype-change.js +++ b/deps/v8/test/mjsunit/concurrent-initial-prototype-change.js @@ -55,3 +55,5 @@ assertUnoptimized(f1, "no sync"); // Sync with background thread to conclude optimization, which bails out // due to map dependency. assertUnoptimized(f1, "sync"); +//Clear type info for stress runs. +%ClearFunctionTypeFeedback(f1); diff --git a/deps/v8/test/mjsunit/const-declaration.js b/deps/v8/test/mjsunit/const-declaration.js index 48c0cf2717..e7bb678eb6 100644 --- a/deps/v8/test/mjsunit/const-declaration.js +++ b/deps/v8/test/mjsunit/const-declaration.js @@ -169,4 +169,3 @@ } f("const x = 0;"); })(); - diff --git a/deps/v8/test/mjsunit/constant-folding-2.js b/deps/v8/test/mjsunit/constant-folding-2.js index 9e6b2c6306..f429c6ca10 100644 --- a/deps/v8/test/mjsunit/constant-folding-2.js +++ b/deps/v8/test/mjsunit/constant-folding-2.js @@ -128,30 +128,6 @@ test(function mathMax() { assertEquals("Infinity", String(1 / Math.max(0.0, -0.0))); }); -test(function mathSin() { - assertEquals(0.0, Math.sin(0.0)); - assertTrue(0.8 < Math.sin(1) && Math.sin(1) < 0.9); - assertEquals("NaN", String(Math.sin(Infinity))); - assertEquals("NaN", String(Math.sin(-Infinity))); - assertEquals("NaN", String(Math.sin(NaN))); -}); - -test(function mathCos() { - assertEquals(1.0, Math.cos(0.0)); - assertTrue(0.5 < Math.cos(1) && Math.cos(1) < 0.6); - assertEquals("NaN", String(Math.cos(Infinity))); - assertEquals("NaN", String(Math.cos(-Infinity))); - assertEquals("NaN", String(Math.cos(NaN))); -}); - -test(function mathTan() { - assertEquals(0.0, Math.tan(0.0)); - assertTrue(1.5 < Math.tan(1) && Math.tan(1) < 1.6); - assertEquals("NaN", String(Math.tan(Infinity))); - assertEquals("NaN", String(Math.tan(-Infinity))); - assertEquals("NaN", String(Math.tan(NaN))); -}); - test(function mathExp() { assertEquals(1.0, Math.exp(0.0)); assertTrue(2.7 < Math.exp(1) && Math.exp(1) < 2.8); diff --git a/deps/v8/test/mjsunit/context-calls-maintained.js b/deps/v8/test/mjsunit/context-calls-maintained.js new file mode 100644 index 0000000000..95bf55240b --- /dev/null +++ b/deps/v8/test/mjsunit/context-calls-maintained.js @@ -0,0 +1,116 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --expose-gc --allow-natives-syntax + +function clear_all_ics() { + %NotifyContextDisposed(); + gc(); + gc(); + gc(); +} + + +// Test: verify that a monomorphic call retains the structural knowledge +// of a global call, correctly throwing either ReferenceError or +// TypeError on undefined depending on how the call is made. +(function() { + foo = function(arg) { return arg + 1; } + + function f() { foo(1); } + + // Drive to monomorphic + f(); f(); f(); + + delete foo; + assertThrows(function() { f(); }, ReferenceError); + foo = function(arg) { return arg * 2; } + assertDoesNotThrow(function() { f(); }); + f(); f(); f(); + delete foo; + assertThrows(function() { f(); }, ReferenceError); + clear_all_ics(); + foo = function(arg) { return arg * 3; } + f(); + %OptimizeFunctionOnNextCall(f); + f(); + delete foo; + assertThrows(function() { f(); }, ReferenceError); + + foo = function(arg) { return arg * 3; } + function g() { this.foo(1); } + g(); g(); g(); + delete foo; + assertThrows(function() { g(); }, TypeError); + foo = function(arg) { return arg * 3; } + g(); + %OptimizeFunctionOnNextCall(g); + g(); + delete foo; + assertThrows(function() { g(); }, TypeError); +})(); + + +// Test: verify that a load with IC does the right thing. +(function() { + var foo = function() { return a; } + a = 3; + foo(); foo(); foo(); + delete a; + assertThrows(function() { foo(); }, ReferenceError); + a = "hi"; + foo(); + clear_all_ics(); + foo(); + %OptimizeFunctionOnNextCall(foo); + foo(); + delete a; + assertThrows(function() { foo(); }, ReferenceError); + foo = function() { return this.a; } + assertDoesNotThrow(function() { foo(); }); +})(); + + +// Test: verify that a store with IC does the right thing. +// If store is contextual and strict mode is set, throw a ReferenceError +// if the variable isn't found. +(function() { + var foo = function() { a = 3; } + var bar = function() { "use strict"; a = 3; } + foo(); foo(); foo(); + delete a; + assertThrows(function() { bar(); }, ReferenceError); + a = 6; + foo(); foo(); foo(); + bar(); bar(); + clear_all_ics(); + bar(); + %OptimizeFunctionOnNextCall(bar); + bar(); + delete a; + assertThrows(function() { bar(); }, ReferenceError); +})(); diff --git a/deps/v8/test/mjsunit/contextual-calls.js b/deps/v8/test/mjsunit/contextual-calls.js new file mode 100644 index 0000000000..10c3e8d82c --- /dev/null +++ b/deps/v8/test/mjsunit/contextual-calls.js @@ -0,0 +1,103 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var realms = [Realm.current(), Realm.create()]; +globals = [Realm.global(0), Realm.global(1)]; +Realm.shared = {} + +function install(name, value) { + Realm.shared[name] = value; + for (i in realms) { + Realm.eval(realms[i], name + " = Realm.shared['" + name + "'];"); + } +} + +install('return_this', function() { return this; }); +install('return_this_strict', function () { 'use strict'; return this; }); + +// test behaviour of 'with' scope +for (i in realms) { + Realm.shared.results = []; + // in the second case, 'this' is found in the with scope, + // so the receiver is 'this' + Realm.eval(realms[i]," \ + with('irrelevant') { \ + Realm.shared.results.push(return_this()); \ + Realm.shared.results.push(return_this_strict()); \ + } \ + with(this) { \ + Realm.shared.results.push(return_this()); \ + Realm.shared.results.push(return_this_strict()); \ + } \ + "); + assertSame(globals[0], Realm.shared.results[0]); + assertSame(undefined, Realm.shared.results[1]); + assertSame(globals[i], Realm.shared.results[2]); + assertSame(globals[i], Realm.shared.results[3]); +} + +// test 'apply' and 'call' +for (i in realms) { + // 'apply' without a receiver is a contextual call + assertSame(globals[0], Realm.eval(realms[i],'return_this.apply()')) ; + assertSame(undefined, Realm.eval(realms[i],'return_this_strict.apply()')); + assertSame(globals[0], Realm.eval(realms[i],'return_this.apply(null)')) ; + assertSame(null, Realm.eval(realms[i],'return_this_strict.apply(null)')); + // 'call' without a receiver is a contextual call + assertSame(globals[0], Realm.eval(realms[i],'return_this.call()')) ; + assertSame(undefined, Realm.eval(realms[i],'return_this_strict.call()')); + assertSame(globals[0], Realm.eval(realms[i],'return_this.call(null)')) ; + assertSame(null, Realm.eval(realms[i],'return_this_strict.call(null)')); +} + +// test ics +for (var i = 0; i < 4; i++) { + assertSame(globals[0], return_this()); + assertSame(undefined, return_this_strict()); +} + +// BUG(1547) + +Realm.eval(realms[0], "var name = 'o'"); +Realm.eval(realms[1], "var name = 'i'"); + +install('f', function() { return this.name; }); +install('g', function() { "use strict"; return this ? this.name : "u"; }); + +for (i in realms) { + result = Realm.eval(realms[i], " \ + (function(){return f();})() + \ + (function(){return (1,f)();})() + \ + (function(){'use strict'; return f();})() + \ + (function(){'use strict'; return (1,f)();})() + \ + (function(){return g();})() + \ + (function(){return (1,g)();})() + \ + (function(){'use strict'; return g();})() + \ + (function(){'use strict'; return (1,g)();})(); \ + "); + assertSame("oooouuuu", result); +} diff --git a/deps/v8/test/mjsunit/cyclic-array-to-string.js b/deps/v8/test/mjsunit/cyclic-array-to-string.js index 0a2d6e379e..ad77743c07 100644 --- a/deps/v8/test/mjsunit/cyclic-array-to-string.js +++ b/deps/v8/test/mjsunit/cyclic-array-to-string.js @@ -62,4 +62,3 @@ a1.push(a2); assertEquals("", a1.toString()); assertEquals("", a1.toLocaleString()); assertEquals("", a1.join()); - diff --git a/deps/v8/test/mjsunit/d8-performance-now.js b/deps/v8/test/mjsunit/d8-performance-now.js index 13eb1d3f00..3e5485e81d 100644 --- a/deps/v8/test/mjsunit/d8-performance-now.js +++ b/deps/v8/test/mjsunit/d8-performance-now.js @@ -30,11 +30,6 @@ // Test the performance.now() function of d8. This test only makes sense with // d8. -// Don't run this test in gc stress mode. Time differences may be long -// due to garbage collections. -%SetFlags("--gc-interval=-1"); -%SetFlags("--nostress-compaction"); - if (this.performance && performance.now) { (function run() { var start_test = performance.now(); diff --git a/deps/v8/test/mjsunit/debug-breakpoints.js b/deps/v8/test/mjsunit/debug-breakpoints.js index 148acfc9ef..a04fac5c73 100644 --- a/deps/v8/test/mjsunit/debug-breakpoints.js +++ b/deps/v8/test/mjsunit/debug-breakpoints.js @@ -222,4 +222,3 @@ for(var i = 0; i < scenario.length; i++) { Debug.BreakPositionAlignment.BreakPosition).indexOf(scenario[i][1]) > 0); Debug.clearBreakPoint(bp1); } - diff --git a/deps/v8/test/mjsunit/debug-constructor.js b/deps/v8/test/mjsunit/debug-constructor.js index 38028aa8c1..6d4e7f3a8f 100644 --- a/deps/v8/test/mjsunit/debug-constructor.js +++ b/deps/v8/test/mjsunit/debug-constructor.js @@ -75,4 +75,4 @@ Debug.clearStepping(); // Clear stepping as the listener leaves it on. assertEquals("bbccdcb", call_graph); // Get rid of the debug event listener. -Debug.setListener(null);
\ No newline at end of file +Debug.setListener(null); diff --git a/deps/v8/test/mjsunit/debug-evaluate-const.js b/deps/v8/test/mjsunit/debug-evaluate-const.js index cb9695b6f2..7fad483cd5 100644 --- a/deps/v8/test/mjsunit/debug-evaluate-const.js +++ b/deps/v8/test/mjsunit/debug-evaluate-const.js @@ -118,4 +118,3 @@ Debug.setListener(null); assertFalse(exception, "exception in listener") assertTrue(listenerComplete); - diff --git a/deps/v8/test/mjsunit/debug-function-scopes.js b/deps/v8/test/mjsunit/debug-function-scopes.js index 4262b950da..b51e8b4432 100644 --- a/deps/v8/test/mjsunit/debug-function-scopes.js +++ b/deps/v8/test/mjsunit/debug-function-scopes.js @@ -159,4 +159,3 @@ CheckNoScopeVisible(Function.toString); // This getter is known to be implemented as closure. CheckNoScopeVisible(new Error().__lookupGetter__("stack")); - diff --git a/deps/v8/test/mjsunit/debug-ignore-breakpoints.js b/deps/v8/test/mjsunit/debug-ignore-breakpoints.js index 96c6044e7b..3cb283bc48 100644 --- a/deps/v8/test/mjsunit/debug-ignore-breakpoints.js +++ b/deps/v8/test/mjsunit/debug-ignore-breakpoints.js @@ -86,4 +86,3 @@ f(); assertEquals(5, break_point_hit_count); f(); assertEquals(6, break_point_hit_count); - diff --git a/deps/v8/test/mjsunit/debug-liveedit-3.js b/deps/v8/test/mjsunit/debug-liveedit-3.js index b2106579d8..023c94e8e2 100644 --- a/deps/v8/test/mjsunit/debug-liveedit-3.js +++ b/deps/v8/test/mjsunit/debug-liveedit-3.js @@ -66,5 +66,3 @@ assertEquals(8, z6()); var z100 = Factory(100)(); assertEquals(102, z100()); - - diff --git a/deps/v8/test/mjsunit/debug-liveedit-check-stack.js b/deps/v8/test/mjsunit/debug-liveedit-check-stack.js index df9e1cfab0..6948a70d6b 100644 --- a/deps/v8/test/mjsunit/debug-liveedit-check-stack.js +++ b/deps/v8/test/mjsunit/debug-liveedit-check-stack.js @@ -138,4 +138,3 @@ test = new TestBase("Test with C++ frame above ChooseAnimal frame"); exception_holder = {}; assertEquals("Cat", test.ChooseAnimal(WrapInNativeCall(WrapInDebuggerCall(WrapInCatcher(test.ScriptChanger, exception_holder))))); assertTrue(!!exception_holder[0]); - diff --git a/deps/v8/test/mjsunit/debug-liveedit-compile-error.js b/deps/v8/test/mjsunit/debug-liveedit-compile-error.js index 2fd6aedabf..99ac0314a8 100644 --- a/deps/v8/test/mjsunit/debug-liveedit-compile-error.js +++ b/deps/v8/test/mjsunit/debug-liveedit-compile-error.js @@ -56,5 +56,3 @@ assertEquals("Unexpected token )", caught_exception.details.syntaxErrorMessage); assertEquals(2, caught_exception.details.position.start.line); - - diff --git a/deps/v8/test/mjsunit/debug-liveedit-diff.js b/deps/v8/test/mjsunit/debug-liveedit-diff.js index 0d26a30b40..2fd2497295 100644 --- a/deps/v8/test/mjsunit/debug-liveedit-diff.js +++ b/deps/v8/test/mjsunit/debug-liveedit-diff.js @@ -110,4 +110,3 @@ CheckCompare( "yesterday\nall\nmy\ntroubles\nseemed\nso\nfar\naway", "yesterday\nall\nmy\ntroubles\nseemed\nso\n" ); - diff --git a/deps/v8/test/mjsunit/debug-liveedit-utils.js b/deps/v8/test/mjsunit/debug-liveedit-utils.js index c892ec9ae6..8521a6dae2 100644 --- a/deps/v8/test/mjsunit/debug-liveedit-utils.js +++ b/deps/v8/test/mjsunit/debug-liveedit-utils.js @@ -93,5 +93,3 @@ assertEquals(69, MultiChunkTranslator.Translate(59)); assertEquals(2010, MultiChunkTranslator.Translate(60, Return2010)); assertEquals(70, MultiChunkTranslator.Translate(70)); assertEquals(75, MultiChunkTranslator.Translate(75)); - - diff --git a/deps/v8/test/mjsunit/debug-mirror-cache.js b/deps/v8/test/mjsunit/debug-mirror-cache.js index 5b85306a18..07aaf880dc 100644 --- a/deps/v8/test/mjsunit/debug-mirror-cache.js +++ b/deps/v8/test/mjsunit/debug-mirror-cache.js @@ -82,4 +82,3 @@ debugger; assertEquals([], listenerExceptions, "Exception in listener"); // Make sure that the debug event listener vas invoked. assertEquals(2, listenerCallCount, "Listener not called"); - diff --git a/deps/v8/test/mjsunit/debug-setbreakpoint.js b/deps/v8/test/mjsunit/debug-setbreakpoint.js index 8531c4e935..bc23021ec7 100644 --- a/deps/v8/test/mjsunit/debug-setbreakpoint.js +++ b/deps/v8/test/mjsunit/debug-setbreakpoint.js @@ -214,4 +214,3 @@ function SetBreakpointInI1Script() { // moment. Since there's no way of simply getting the pointer to the function, // we run this code while the script function is being activated on stack. eval('SetBreakpointInI1Script()\nfunction i1(){}\n\n\n\nfunction i2(){}\n'); - diff --git a/deps/v8/test/mjsunit/debug-step-4-in-frame.js b/deps/v8/test/mjsunit/debug-step-4-in-frame.js index 65ac4902dd..93884303ca 100644 --- a/deps/v8/test/mjsunit/debug-step-4-in-frame.js +++ b/deps/v8/test/mjsunit/debug-step-4-in-frame.js @@ -37,18 +37,18 @@ var state; function f() { var a = 1978; - for (state[2] = 0; state[2] < 5; state[2]++) { + for (state[2] = 0; state[2] < 3; state[2]++) { void String(a); } } function g() { - for (state[1] = 0; state[1] < 5; state[1]++) { + for (state[1] = 0; state[1] < 3; state[1]++) { f(); } } function h() { state = [-1, -1, -1]; - for (state[0] = 0; state[0] < 5; state[0]++) { + for (state[0] = 0; state[0] < 3; state[0]++) { g(); } } @@ -123,10 +123,10 @@ TestCase(0, 5, "0,0,1"); TestCase(0, 8, "0,0,3"); // Stepping in the frame #1. -TestCase(1, 0, "0,0,5"); -TestCase(1, 3, "0,1,5"); -TestCase(1, 8, "0,4,5"); +TestCase(1, 0, "0,0,3"); +TestCase(1, 3, "0,1,3"); +TestCase(1, 7, "0,3,3"); // Stepping in the frame #2. -TestCase(2, 3, "1,5,5"); -TestCase(2, 8, "4,5,5"); +TestCase(2, 3, "1,3,3"); +TestCase(2, 7, "3,3,3"); diff --git a/deps/v8/test/mjsunit/debug-stepin-positions.js b/deps/v8/test/mjsunit/debug-stepin-positions.js index e6d8204611..722df53666 100644 --- a/deps/v8/test/mjsunit/debug-stepin-positions.js +++ b/deps/v8/test/mjsunit/debug-stepin-positions.js @@ -221,5 +221,3 @@ var fun = (function(p) { }; })(Object); TestCaseWithDebugger(fun); - - diff --git a/deps/v8/test/mjsunit/debug-stepout-scope-part1.js b/deps/v8/test/mjsunit/debug-stepout-scope-part1.js index f2f9d91419..f49b1a07eb 100644 --- a/deps/v8/test/mjsunit/debug-stepout-scope-part1.js +++ b/deps/v8/test/mjsunit/debug-stepout-scope-part1.js @@ -187,4 +187,4 @@ function nop() {} // With block as the last(!) statement in global code. -with ({}) { debugger; }
\ No newline at end of file +with ({}) { debugger; } diff --git a/deps/v8/test/mjsunit/deopt-with-fp-regs.js b/deps/v8/test/mjsunit/deopt-with-fp-regs.js new file mode 100644 index 0000000000..10e3d9abb3 --- /dev/null +++ b/deps/v8/test/mjsunit/deopt-with-fp-regs.js @@ -0,0 +1,90 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +deopt_trigger = 0; +side_effect = 0; + +function test(a, b, c, d, e, v) { + // This test expects some specific input values. + assertEquals(10.0, a); + assertEquals(20.0, b); + assertEquals(30.0, c); + assertEquals(40.0, d); + assertEquals(50.0, e); + assertEquals(1.5, v); + + // Perform a few double calculations. + a = a * 0.1; + b = b * 0.2; + c = c * 0.3; + d = d * 0.4; + e = e * 0.5; + + // Write to a field of a global object. As for any side effect, a HSimulate + // will be introduced after the instructions to support this. If we deopt + // later in this function, the execution will resume in full-codegen after + // this point. + side_effect++; + // The following field of the global object will be deleted to force a deopt. + // If we use type feedback to deopt, then tests ran with --stress-opt will + // not deopt after a few iteration. + // If we use %DeoptimizeFunction, all values will be on the frame due to the + // call and we will not exercise the translation mechanism handling fp + // registers. + deopt_trigger = v; + + // Do a few more calculations using the previous values after our deopt point + // so the floating point registers which hold those values are recorded in the + // environment and will be used during deoptimization. + a = a * v; + b = b * v; + c = c * v; + d = d * v; + e = e * v; + + // Check that we got the expected results. + assertEquals(1.5, a); + assertEquals(6, b); + assertEquals(13.5, c); + assertEquals(24, d); + assertEquals(37.5, e); +} + + +test(10.0, 20.0, 30.0, 40.0, 50.0, 1.5); +test(10.0, 20.0, 30.0, 40.0, 50.0, 1.5); +%OptimizeFunctionOnNextCall(test); +test(10.0, 20.0, 30.0, 40.0, 50.0, 1.5); +assertTrue(2 != %GetOptimizationStatus(test)); + +// By deleting the field we are forcing the code to deopt when the field is +// read on next execution. +delete deopt_trigger; +test(10.0, 20.0, 30.0, 40.0, 50.0, 1.5); +assertTrue(1 != %GetOptimizationStatus(test)); diff --git a/deps/v8/test/mjsunit/div-mod.js b/deps/v8/test/mjsunit/div-mod.js index c3144955cb..08cee8cdd1 100644 --- a/deps/v8/test/mjsunit/div-mod.js +++ b/deps/v8/test/mjsunit/div-mod.js @@ -126,9 +126,15 @@ function compute_mod(dividend, divisor) { var example_numbers = [ NaN, 0, + + // Due to a bug in fmod(), modulos involving denormals + // return the wrong result for glibc <= 2.16. + // Details: http://sourceware.org/bugzilla/show_bug.cgi?id=14048 + Number.MIN_VALUE, 3 * Number.MIN_VALUE, max_denormal, + min_normal, repeating_decimal, finite_decimal, diff --git a/deps/v8/test/mjsunit/div-mul-minus-one.js b/deps/v8/test/mjsunit/div-mul-minus-one.js index f05bf0f54c..5ade61492d 100644 --- a/deps/v8/test/mjsunit/div-mul-minus-one.js +++ b/deps/v8/test/mjsunit/div-mul-minus-one.js @@ -36,9 +36,7 @@ var expected_MinInt = div(kMinInt); var expected_minus_zero = div(0); %OptimizeFunctionOnNextCall(div); assertEquals(expected_MinInt, div(kMinInt)); -assertOptimized(div); assertEquals(expected_minus_zero , div(0)); -assertOptimized(div); function mul(g) { return (g * -1) ^ 1 diff --git a/deps/v8/test/mjsunit/elements-kind.js b/deps/v8/test/mjsunit/elements-kind.js index 442d756ae9..e2bbc31a41 100644 --- a/deps/v8/test/mjsunit/elements-kind.js +++ b/deps/v8/test/mjsunit/elements-kind.js @@ -25,13 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc -// Flags: --notrack_allocation_sites - -// Limit the number of stress runs to reduce polymorphism it defeats some of the -// assumptions made about how elements transitions work because transition stubs -// end up going generic. -// Flags: --stress-runs=2 +// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc --nostress-opt // Test element kind of objects. // Since --smi-only-arrays affects builtins, its default setting at compile @@ -71,31 +65,31 @@ function getKind(obj) { if (%HasDictionaryElements(obj)) return elements_kind.dictionary; // Every external kind is also an external array. assertTrue(%HasExternalArrayElements(obj)); - if (%HasExternalByteElements(obj)) { + if (%HasExternalInt8Elements(obj)) { return elements_kind.external_byte; } - if (%HasExternalUnsignedByteElements(obj)) { + if (%HasExternalUint8Elements(obj)) { return elements_kind.external_unsigned_byte; } - if (%HasExternalShortElements(obj)) { + if (%HasExternalInt16Elements(obj)) { return elements_kind.external_short; } - if (%HasExternalUnsignedShortElements(obj)) { + if (%HasExternalUint16Elements(obj)) { return elements_kind.external_unsigned_short; } - if (%HasExternalIntElements(obj)) { + if (%HasExternalInt32Elements(obj)) { return elements_kind.external_int; } - if (%HasExternalUnsignedIntElements(obj)) { + if (%HasExternalUint32Elements(obj)) { return elements_kind.external_unsigned_int; } - if (%HasExternalFloatElements(obj)) { + if (%HasExternalFloat32Elements(obj)) { return elements_kind.external_float; } - if (%HasExternalDoubleElements(obj)) { + if (%HasExternalFloat64Elements(obj)) { return elements_kind.external_double; } - if (%HasExternalPixelElements(obj)) { + if (%HasExternalUint8ClampedElements(obj)) { return elements_kind.external_pixel; } } @@ -123,56 +117,75 @@ if (support_smi_only_arrays) { } // Make sure the element kind transitions from smi when a non-smi is stored. -var you = new Array(); -assertKind(elements_kind.fast_smi_only, you); -for (var i = 0; i < 1337; i++) { - var val = i; - if (i == 1336) { - assertKind(elements_kind.fast_smi_only, you); - val = new Object(); +function test_wrapper() { + var you = new Array(); + assertKind(elements_kind.fast_smi_only, you); + for (var i = 0; i < 1337; i++) { + var val = i; + if (i == 1336) { + assertKind(elements_kind.fast_smi_only, you); + val = new Object(); + } + you[i] = val; } - you[i] = val; -} -assertKind(elements_kind.fast, you); + assertKind(elements_kind.fast, you); -assertKind(elements_kind.dictionary, new Array(0xDECAF)); + assertKind(elements_kind.dictionary, new Array(0xDECAF)); -var fast_double_array = new Array(0xDECAF); -for (var i = 0; i < 0xDECAF; i++) fast_double_array[i] = i / 2; -assertKind(elements_kind.fast_double, fast_double_array); + var fast_double_array = new Array(0xDECAF); + for (var i = 0; i < 0xDECAF; i++) fast_double_array[i] = i / 2; + assertKind(elements_kind.fast_double, fast_double_array); -assertKind(elements_kind.external_byte, new Int8Array(9001)); -assertKind(elements_kind.external_unsigned_byte, new Uint8Array(007)); -assertKind(elements_kind.external_short, new Int16Array(666)); -assertKind(elements_kind.external_unsigned_short, new Uint16Array(42)); -assertKind(elements_kind.external_int, new Int32Array(0xF)); -assertKind(elements_kind.external_unsigned_int, new Uint32Array(23)); -assertKind(elements_kind.external_float, new Float32Array(7)); -assertKind(elements_kind.external_double, new Float64Array(0)); -assertKind(elements_kind.external_pixel, new Uint8ClampedArray(512)); + assertKind(elements_kind.external_byte, new Int8Array(9001)); + assertKind(elements_kind.external_unsigned_byte, new Uint8Array(007)); + assertKind(elements_kind.external_short, new Int16Array(666)); + assertKind(elements_kind.external_unsigned_short, new Uint16Array(42)); + assertKind(elements_kind.external_int, new Int32Array(0xF)); + assertKind(elements_kind.external_unsigned_int, new Uint32Array(23)); + assertKind(elements_kind.external_float, new Float32Array(7)); + assertKind(elements_kind.external_double, new Float64Array(0)); + assertKind(elements_kind.external_pixel, new Uint8ClampedArray(512)); -// Crankshaft support for smi-only array elements. -function monomorphic(array) { - assertKind(elements_kind.fast_smi_only, array); - for (var i = 0; i < 3; i++) { - array[i] = i + 10; - } - assertKind(elements_kind.fast_smi_only, array); - for (var i = 0; i < 3; i++) { - var a = array[i]; - assertEquals(i + 10, a); + // Crankshaft support for smi-only array elements. + function monomorphic(array) { + assertKind(elements_kind.fast_smi_only, array); + for (var i = 0; i < 3; i++) { + array[i] = i + 10; + } + assertKind(elements_kind.fast_smi_only, array); + for (var i = 0; i < 3; i++) { + var a = array[i]; + assertEquals(i + 10, a); + } } + var smi_only = new Array(1, 2, 3); + assertKind(elements_kind.fast_smi_only, smi_only); + for (var i = 0; i < 3; i++) monomorphic(smi_only); + %OptimizeFunctionOnNextCall(monomorphic); + monomorphic(smi_only); } -var smi_only = new Array(1, 2, 3); -assertKind(elements_kind.fast_smi_only, smi_only); -for (var i = 0; i < 3; i++) monomorphic(smi_only); -%OptimizeFunctionOnNextCall(monomorphic); -monomorphic(smi_only); + +// The test is called in a wrapper function to eliminate the transition learning +// feedback of AllocationSites. +test_wrapper(); +%ClearFunctionTypeFeedback(test_wrapper); if (support_smi_only_arrays) { %NeverOptimizeFunction(construct_smis); + + // This code exists to eliminate the learning influence of AllocationSites + // on the following tests. + var __sequence = 0; + function make_array_string() { + this.__sequence = this.__sequence + 1; + return "/* " + this.__sequence + " */ [0, 0, 0];" + } + function make_array() { + return eval(make_array_string()); + } + function construct_smis() { - var a = [0, 0, 0]; + var a = make_array(); a[0] = 0; // Send the COW array map to the steak house. assertKind(elements_kind.fast_smi_only, a); return a; diff --git a/deps/v8/test/mjsunit/elements-transition-and-store.js b/deps/v8/test/mjsunit/elements-transition-and-store.js index 7a07b3eeca..0b4786b4b8 100644 --- a/deps/v8/test/mjsunit/elements-transition-and-store.js +++ b/deps/v8/test/mjsunit/elements-transition-and-store.js @@ -25,8 +25,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --notrack-allocation-sites - function foo(a, v) { a[0] = v; return a; diff --git a/deps/v8/test/mjsunit/elements-transition-hoisting.js b/deps/v8/test/mjsunit/elements-transition-hoisting.js index 0295318f6a..76027b9ed1 100644 --- a/deps/v8/test/mjsunit/elements-transition-hoisting.js +++ b/deps/v8/test/mjsunit/elements-transition-hoisting.js @@ -25,10 +25,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --allow-natives-syntax --smi-only-arrays --notrack-allocation-sites - -// No tracking of allocation sites because it interfers with the semantics -// the test is trying to ensure. +// Flags: --allow-natives-syntax --smi-only-arrays +// Flags: --nostress-opt // Ensure that ElementsKind transitions in various situations are hoisted (or // not hoisted) correctly, don't change the semantics programs and don't trigger @@ -42,7 +40,7 @@ if (support_smi_only_arrays) { print("Tests do NOT include smi-only arrays."); } -if (support_smi_only_arrays) { +function test_wrapper() { // Make sure that a simple elements array transitions inside a loop before // stores to an array gets hoisted in a way that doesn't generate a deopt in // simple cases.} @@ -239,3 +237,10 @@ if (support_smi_only_arrays) { assertOptimized(testStraightLineDupeElinination); %ClearFunctionTypeFeedback(testStraightLineDupeElinination); } + +if (support_smi_only_arrays) { + // The test is called in a test wrapper that has type feedback cleared to + // prevent the influence of allocation-sites, which learn from transitions. + test_wrapper(); + %ClearFunctionTypeFeedback(test_wrapper); +} diff --git a/deps/v8/test/mjsunit/elements-transition.js b/deps/v8/test/mjsunit/elements-transition.js index e28f3c3d64..7298e68a12 100644 --- a/deps/v8/test/mjsunit/elements-transition.js +++ b/deps/v8/test/mjsunit/elements-transition.js @@ -25,7 +25,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --allow-natives-syntax --smi-only-arrays --notrack-allocation-sites +// Flags: --allow-natives-syntax --smi-only-arrays +// Flags: --nostress-opt support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8)); @@ -36,14 +37,26 @@ if (support_smi_only_arrays) { } if (support_smi_only_arrays) { + // This code exists to eliminate the learning influence of AllocationSites + // on the following tests. + var __sequence = 0; + function make_array_string(length) { + this.__sequence = this.__sequence + 1; + return "/* " + this.__sequence + " */ new Array(" + length + ");"; + } + function make_array(length) { + return eval(make_array_string(length)); + } + function test(test_double, test_object, set, length) { // We apply the same operations to two identical arrays. The first array // triggers an IC miss, upon which the conversion stub is generated, but the // actual conversion is done in runtime. The second array, arriving at // the previously patched IC, is then converted using the conversion stub. - var array_1 = new Array(length); - var array_2 = new Array(length); + var array_1 = make_array(length); + var array_2 = make_array(length); + // false, true, nice setter function, 20 assertTrue(%HasFastSmiElements(array_1)); assertTrue(%HasFastSmiElements(array_2)); for (var i = 0; i < length; i++) { @@ -86,15 +99,20 @@ if (support_smi_only_arrays) { assertEquals(length, array_2.length); } - test(false, false, function(a,i,v){ a[i] = v; }, 20); - test(true, false, function(a,i,v){ a[i] = v; }, 20); - test(false, true, function(a,i,v){ a[i] = v; }, 20); - test(true, true, function(a,i,v){ a[i] = v; }, 20); + function run_test(test_double, test_object, set, length) { + test(test_double, test_object, set, length); + %ClearFunctionTypeFeedback(test); + } + + run_test(false, false, function(a,i,v){ a[i] = v; }, 20); + run_test(true, false, function(a,i,v){ a[i] = v; }, 20); + run_test(false, true, function(a,i,v){ a[i] = v; }, 20); + run_test(true, true, function(a,i,v){ a[i] = v; }, 20); - test(false, false, function(a,i,v){ a[i] = v; }, 10000); - test(true, false, function(a,i,v){ a[i] = v; }, 10000); - test(false, true, function(a,i,v){ a[i] = v; }, 10000); - test(true, true, function(a,i,v){ a[i] = v; }, 10000); + run_test(false, false, function(a,i,v){ a[i] = v; }, 10000); + run_test(true, false, function(a,i,v){ a[i] = v; }, 10000); + run_test(false, true, function(a,i,v){ a[i] = v; }, 10000); + run_test(true, true, function(a,i,v){ a[i] = v; }, 10000); // Check COW arrays function get_cow() { return [1, 2, 3]; } diff --git a/deps/v8/test/mjsunit/elide-double-hole-check-9.js b/deps/v8/test/mjsunit/elide-double-hole-check-9.js index 88bbc7eaaa..bbcbfb2be6 100644 --- a/deps/v8/test/mjsunit/elide-double-hole-check-9.js +++ b/deps/v8/test/mjsunit/elide-double-hole-check-9.js @@ -46,4 +46,3 @@ assertEquals(0.5, f(arr, 0)); assertEquals(0.5, f(arr, 0)); do_set = true; assertEquals(2, f(arr, 1)); - diff --git a/deps/v8/test/mjsunit/enumeration-order.js b/deps/v8/test/mjsunit/enumeration-order.js index a328121d73..70942ee13c 100644 --- a/deps/v8/test/mjsunit/enumeration-order.js +++ b/deps/v8/test/mjsunit/enumeration-order.js @@ -103,7 +103,3 @@ var expected = ['23', '42', // indexed from 'o' var actual = []; for (var p in o) actual.push(p); assertArrayEquals(expected, actual); - - - - diff --git a/deps/v8/test/mjsunit/error-accessors.js b/deps/v8/test/mjsunit/error-accessors.js index 9581050240..cdaf080a3c 100644 --- a/deps/v8/test/mjsunit/error-accessors.js +++ b/deps/v8/test/mjsunit/error-accessors.js @@ -51,4 +51,3 @@ assertEquals("x is not defined", o.message = "another message"; assertEquals("another message", o.message); assertEquals("x is not defined", error2.message); - diff --git a/deps/v8/test/mjsunit/error-tostring-omit.js b/deps/v8/test/mjsunit/error-tostring-omit.js new file mode 100644 index 0000000000..111adfc212 --- /dev/null +++ b/deps/v8/test/mjsunit/error-tostring-omit.js @@ -0,0 +1,63 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +function veryLongString() { + return "Lorem ipsum dolor sit amet, consectetur adipiscing elit." + + "Nam vulputate metus est. Maecenas quis pellentesque eros," + + "ac mattis augue. Nam porta purus vitae tincidunt blandit." + + "Aliquam lacus dui, blandit id consectetur id, hendrerit ut" + + "felis. Class aptent taciti sociosqu ad litora torquent per" + + "conubia nostra, per inceptos himenaeos. Ut posuere eros et" + + "tempus luctus. Nullam condimentum aliquam odio, at dignissim" + + "augue tincidunt in. Nam mattis vitae mauris eget dictum." + + "Nam accumsan dignissim turpis a turpis duis."; +} + + +var re = /omitted/; + +try { + veryLongString.nonexistentMethod(); +} catch (e) { + assertTrue(e.message.length < 350); + // TODO(verwaest): Proper error message. + // assertTrue(re.test(e.message)); +} + +try { + veryLongString().nonexistentMethod(); +} catch (e) { + assertTrue(e.message.length < 350); + // TODO(verwaest): Proper error message. + // assertTrue(re.test(e.message)); +} + +try { + throw Error(veryLongString()); +} catch (e) { + assertEquals(veryLongString(), e.message); +} diff --git a/deps/v8/test/mjsunit/eval-stack-trace.js b/deps/v8/test/mjsunit/eval-stack-trace.js index d83b84c16f..f95e50fa38 100644 --- a/deps/v8/test/mjsunit/eval-stack-trace.js +++ b/deps/v8/test/mjsunit/eval-stack-trace.js @@ -201,4 +201,3 @@ try { [true, false].verifyUndefined(frames, "getFileName"); ["eval at <anonymous> ("].verifyContains(frames, "getEvalOrigin"); } - diff --git a/deps/v8/test/mjsunit/extra-arguments.js b/deps/v8/test/mjsunit/extra-arguments.js index 186277a006..29063672ee 100644 --- a/deps/v8/test/mjsunit/extra-arguments.js +++ b/deps/v8/test/mjsunit/extra-arguments.js @@ -50,5 +50,3 @@ for (var i = 0; i < 25; i++) { } assertEquals(expected, f.apply(null, array), String(i)); } - - diff --git a/deps/v8/test/mjsunit/fast-array-length.js b/deps/v8/test/mjsunit/fast-array-length.js index 42f2c38f49..3917d97f2c 100644 --- a/deps/v8/test/mjsunit/fast-array-length.js +++ b/deps/v8/test/mjsunit/fast-array-length.js @@ -34,4 +34,3 @@ var a = [0, 1, 2, 3, 4, 5]; assertTrue(%HasFastSmiElements(a)); a.length = (1 << 30); assertFalse(%HasFastSmiElements(a)); - diff --git a/deps/v8/test/mjsunit/fast-literal.js b/deps/v8/test/mjsunit/fast-literal.js index 822d90656b..4fd92c4d3a 100644 --- a/deps/v8/test/mjsunit/fast-literal.js +++ b/deps/v8/test/mjsunit/fast-literal.js @@ -27,16 +27,13 @@ // Flags: --allow-natives-syntax --no-inline-new --nouse-allocation-folding -%SetAllocationTimeout(10, 0); +%SetAllocationTimeout(20, 0); function f() { return [[1, 2, 3], [1.1, 1.2, 1.3], [[], [], []]]; } f(); f(); f(); %OptimizeFunctionOnNextCall(f); -for (var i=0; i<1000; i++) { +for (var i=0; i<50; i++) { f(); } - - - diff --git a/deps/v8/test/mjsunit/fast-prototype.js b/deps/v8/test/mjsunit/fast-prototype.js index d700c3c3cc..cdcc1a9ed6 100644 --- a/deps/v8/test/mjsunit/fast-prototype.js +++ b/deps/v8/test/mjsunit/fast-prototype.js @@ -26,9 +26,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax --expose-gc - -// TODO(mstarzinger): This test does not succeed when GCs happen in -// between prototype transitions, we disable GC stress for now. // Flags: --noincremental-marking // Check that objects that are used for prototypes are in the fast mode. diff --git a/deps/v8/test/mjsunit/fun-name.js b/deps/v8/test/mjsunit/fun-name.js index 676daaa133..1688438ac8 100644 --- a/deps/v8/test/mjsunit/fun-name.js +++ b/deps/v8/test/mjsunit/fun-name.js @@ -31,4 +31,3 @@ function strip(s) { assertEquals('function(){}', strip((function () { }).toString())); assertEquals('functionanonymous(){}', strip(new Function().toString())); - diff --git a/deps/v8/test/mjsunit/function-arguments-duplicate.js b/deps/v8/test/mjsunit/function-arguments-duplicate.js new file mode 100644 index 0000000000..80f03a106b --- /dev/null +++ b/deps/v8/test/mjsunit/function-arguments-duplicate.js @@ -0,0 +1,36 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Execises ArgumentsAccessStub::GenerateNewNonStrictSlow. + +function f(a, a) { + assertEquals(2, a); + assertEquals(1, arguments[0]); + assertEquals(2, arguments[1]); +} + +f(1, 2); diff --git a/deps/v8/test/mjsunit/function.js b/deps/v8/test/mjsunit/function.js index b5e83dba6e..5c33762b3e 100644 --- a/deps/v8/test/mjsunit/function.js +++ b/deps/v8/test/mjsunit/function.js @@ -80,4 +80,3 @@ assertEquals(42, f(2, 21)); f = new Function(x, y, z); assertEquals(25, f(5, 5)); assertEquals(42, f(2, 21)); - diff --git a/deps/v8/test/mjsunit/fuzz-natives-part1.js b/deps/v8/test/mjsunit/fuzz-natives-part1.js index e76b9be6d4..e22ac49472 100644 --- a/deps/v8/test/mjsunit/fuzz-natives-part1.js +++ b/deps/v8/test/mjsunit/fuzz-natives-part1.js @@ -116,6 +116,7 @@ function testArgumentTypes(name, argc) { var knownProblems = { "Abort": true, + "ThrowMessage": true, // Avoid calling the concat operation, because weird lengths // may lead to out-of-memory. Ditto for StringBuilderJoin. @@ -148,9 +149,9 @@ var knownProblems = { "PushCatchContext": true, "PushBlockContext": true, "PushModuleContext": true, - "LazyCompile": true, - "LazyRecompile": true, - "ConcurrentRecompile": true, + "CompileUnoptimized": true, + "CompileOptimized": true, + "CompileOptimizedConcurrent": true, "NotifyDeoptimized": true, "NotifyStubFailure": true, "NotifyOSR": true, @@ -170,6 +171,7 @@ var knownProblems = { // Vararg with minimum number > 0. "Call": true, + "SetAllocationTimeout": true, // Requires integer arguments to be non-negative. "Apply": true, @@ -203,11 +205,15 @@ var knownProblems = { "_OneByteSeqStringSetChar": true, "_TwoByteSeqStringSetChar": true, + // Only applicable to TypedArrays. + "TypedArrayInitialize": true, + // Only applicable to generators. "_GeneratorNext": true, "_GeneratorThrow": true, // Only applicable to DataViews. + "DataViewInitialize": true, "DataViewGetBuffer": true, "DataViewGetByteLength": true, "DataViewGetByteOffset": true diff --git a/deps/v8/test/mjsunit/fuzz-natives-part2.js b/deps/v8/test/mjsunit/fuzz-natives-part2.js index 0797deb18d..293ad7e524 100644 --- a/deps/v8/test/mjsunit/fuzz-natives-part2.js +++ b/deps/v8/test/mjsunit/fuzz-natives-part2.js @@ -116,6 +116,7 @@ function testArgumentTypes(name, argc) { var knownProblems = { "Abort": true, + "ThrowMessage": true, // Avoid calling the concat operation, because weird lengths // may lead to out-of-memory. Ditto for StringBuilderJoin. @@ -148,9 +149,9 @@ var knownProblems = { "PushCatchContext": true, "PushBlockContext": true, "PushModuleContext": true, - "LazyCompile": true, - "LazyRecompile": true, - "ConcurrentRecompile": true, + "CompileUnoptimized": true, + "CompileOptimized": true, + "CompileOptimizedConcurrent": true, "NotifyDeoptimized": true, "NotifyStubFailure": true, "NotifyOSR": true, @@ -171,6 +172,7 @@ var knownProblems = { // Vararg with minimum number > 0. "Call": true, + "SetAllocationTimeout": true, // Requires integer arguments to be non-negative. "Apply": true, @@ -204,11 +206,15 @@ var knownProblems = { "_OneByteSeqStringSetChar": true, "_TwoByteSeqStringSetChar": true, + // Only applicable to TypedArrays. + "TypedArrayInitialize": true, + // Only applicable to generators. "_GeneratorNext": true, "_GeneratorThrow": true, // Only applicable to DataViews. + "DataViewInitialize": true, "DataViewGetBuffer": true, "DataViewGetByteLength": true, "DataViewGetByteOffset": true diff --git a/deps/v8/test/mjsunit/fuzz-natives-part3.js b/deps/v8/test/mjsunit/fuzz-natives-part3.js index 9a3a883fe4..b3a1fb610c 100644 --- a/deps/v8/test/mjsunit/fuzz-natives-part3.js +++ b/deps/v8/test/mjsunit/fuzz-natives-part3.js @@ -116,6 +116,7 @@ function testArgumentTypes(name, argc) { var knownProblems = { "Abort": true, + "ThrowMessage": true, // Avoid calling the concat operation, because weird lengths // may lead to out-of-memory. Ditto for StringBuilderJoin. @@ -148,9 +149,9 @@ var knownProblems = { "PushCatchContext": true, "PushBlockContext": true, "PushModuleContext": true, - "LazyCompile": true, - "LazyRecompile": true, - "ConcurrentRecompile": true, + "CompileUnoptimized": true, + "CompileOptimized": true, + "CompileOptimizedConcurrent": true, "NotifyDeoptimized": true, "NotifyStubFailure": true, "NotifyOSR": true, @@ -170,6 +171,7 @@ var knownProblems = { // Vararg with minimum number > 0. "Call": true, + "SetAllocationTimeout": true, // Requires integer arguments to be non-negative. "Apply": true, @@ -203,14 +205,21 @@ var knownProblems = { "_OneByteSeqStringSetChar": true, "_TwoByteSeqStringSetChar": true, + // Only applicable to TypedArrays. + "TypedArrayInitialize": true, + // Only applicable to generators. "_GeneratorNext": true, "_GeneratorThrow": true, // Only applicable to DataViews. + "DataViewInitialize":true, "DataViewGetBuffer": true, "DataViewGetByteLength": true, - "DataViewGetByteOffset": true + "DataViewGetByteOffset": true, + + // Only ever called internally. + "RunMicrotasks": true }; var currentlyUncallable = { diff --git a/deps/v8/test/mjsunit/fuzz-natives-part4.js b/deps/v8/test/mjsunit/fuzz-natives-part4.js index 83e00d2b66..5f1f912063 100644 --- a/deps/v8/test/mjsunit/fuzz-natives-part4.js +++ b/deps/v8/test/mjsunit/fuzz-natives-part4.js @@ -116,6 +116,7 @@ function testArgumentTypes(name, argc) { var knownProblems = { "Abort": true, + "ThrowMessage": true, // Avoid calling the concat operation, because weird lengths // may lead to out-of-memory. Ditto for StringBuilderJoin. @@ -148,9 +149,9 @@ var knownProblems = { "PushCatchContext": true, "PushBlockContext": true, "PushModuleContext": true, - "LazyCompile": true, - "LazyRecompile": true, - "ConcurrentRecompile": true, + "CompileUnoptimized": true, + "CompileOptimized": true, + "CompileOptimizedConcurrent": true, "NotifyDeoptimized": true, "NotifyStubFailure": true, "NotifyOSR": true, @@ -170,6 +171,7 @@ var knownProblems = { // Vararg with minimum number > 0. "Call": true, + "SetAllocationTimeout": true, // Requires integer arguments to be non-negative. "Apply": true, @@ -203,11 +205,15 @@ var knownProblems = { "_OneByteSeqStringSetChar": true, "_TwoByteSeqStringSetChar": true, + // Only applicable to TypedArrays. + "TypedArrayInitialize": true, + // Only applicable to generators. "_GeneratorNext": true, "_GeneratorThrow": true, // Only applicable to DataViews. + "DataViewInitialize": true, "DataViewGetBuffer": true, "DataViewGetByteLength": true, "DataViewGetByteOffset": true diff --git a/deps/v8/test/mjsunit/get-prototype-of.js b/deps/v8/test/mjsunit/get-prototype-of.js index 6475bde651..c2a492a3cf 100644 --- a/deps/v8/test/mjsunit/get-prototype-of.js +++ b/deps/v8/test/mjsunit/get-prototype-of.js @@ -65,4 +65,3 @@ GetPrototypeOfObject(y); GetPrototypeOfObject({x:5}); GetPrototypeOfObject(F); GetPrototypeOfObject(RegExp); - diff --git a/deps/v8/test/mjsunit/getter-in-value-prototype.js b/deps/v8/test/mjsunit/getter-in-value-prototype.js index abe2cb1934..835710604b 100644 --- a/deps/v8/test/mjsunit/getter-in-value-prototype.js +++ b/deps/v8/test/mjsunit/getter-in-value-prototype.js @@ -32,4 +32,3 @@ String.prototype.__defineGetter__('x', function() { return this; }); assertEquals(Object('asdf'), 'asdf'.x); - diff --git a/deps/v8/test/mjsunit/getters-on-elements.js b/deps/v8/test/mjsunit/getters-on-elements.js new file mode 100644 index 0000000000..3bc360f143 --- /dev/null +++ b/deps/v8/test/mjsunit/getters-on-elements.js @@ -0,0 +1,221 @@ +// Copyright 2011 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --max-opt-count=100 --noalways-opt +// Flags: --nocollect-maps + +// We specify max-opt-count because we opt/deopt the same function many +// times. + +// We specify nocollect-maps because in gcstress we can end up deoptimizing +// a function in a gc in the stack guard at the beginning of the (optimized) +// function due to leftover map clearing work that results in deoptimizing +// dependent code from those maps. The choice is to insert strategic gc() +// calls or specify this flag. + +// It's nice to run this in other browsers too. +var standalone = false; +if (standalone) { + assertTrue = function(val) { + if (val != true) { + print("FAILURE"); + } + } + + assertFalse = function(val) { + if (val != false) { + print("FAILURE"); + } + } + + assertEquals = function(expected, val) { + if (expected !== val) { + print("FAILURE"); + } + } + + empty_func = function(name) { } + assertUnoptimized = empty_func; + assertOptimized = empty_func; + + optimize = empty_func; + clearFunctionTypeFeedback = empty_func; + deoptimizeFunction = empty_func; +} else { + optimize = function(name) { + %OptimizeFunctionOnNextCall(name); + } + clearFunctionTypeFeedback = function(name) { + %ClearFunctionTypeFeedback(name); + } + deoptimizeFunction = function(name) { + %DeoptimizeFunction(name); + } +} + +function base_getter_test(create_func) { + var calls = 0; + + // Testcase: setter in prototype chain + foo = function(a) { var x = a[0]; return x + 3; } + var a = create_func(); + var ap = []; + ap.__defineGetter__(0, function() { calls++; return 0; }); + + foo(a); + foo(a); + foo(a); + delete a[0]; + + assertEquals(0, calls); + a.__proto__ = ap; + foo(a); + assertEquals(1, calls); + optimize(foo); + foo(a); + assertEquals(2, calls); + assertOptimized(foo); + + // Testcase: getter "deep" in prototype chain. + clearFunctionTypeFeedback(foo); + deoptimizeFunction(foo); + clearFunctionTypeFeedback(foo); + calls = 0; + + a = create_func(); + var ap2 = []; + a.__proto__ = ap2; + foo(a); + foo(a); + foo(a); + delete a[0]; + + assertEquals(0, calls); + + ap2.__proto__ = ap; // "sneak" in a callback. + // The sneak case should be caught by unoptimized code too. + assertUnoptimized(foo); + foo(a); + foo(a); + foo(a); + assertEquals(3, calls); + + // Testcase: getter added after optimization (feedback is monomorphic) + clearFunctionTypeFeedback(foo); + deoptimizeFunction(foo); + clearFunctionTypeFeedback(foo); + calls = 0; + + a = create_func(); + ap2 = []; + a.__proto__ = ap2; + foo(a); + foo(a); + foo(a); + optimize(foo); + foo(a); + assertOptimized(foo); + delete a[0]; + ap2.__proto__ = ap; + foo(a); + assertOptimized(foo); // getters don't require deopt on shape change. + assertEquals(1, calls); + + // Testcase: adding additional getters to a prototype chain that already has + // one shouldn't deopt anything. + clearFunctionTypeFeedback(foo); + calls = 0; + + a = create_func(); + a.__proto__ = ap2; + bar = function(a) { return a[3] + 600; } + bar(a); + bar(a); + bar(a); + optimize(bar); + bar(a); + assertOptimized(bar); + assertEquals(0, calls); + delete a[3]; + ap2.__defineGetter__(3, function() { calls++; return 0; }); + bar(a); + assertOptimized(bar); + assertEquals(1, calls); +} + +// Verify that map transitions don't confuse us. +create_func_smi = function() { return [,,,,,,5]; } +create_func_double = function() { return [,,,,,,5.5]; } +create_func_fast = function() { return [,,,,,,true]; } + +var cf = [create_func_smi, + create_func_double, + create_func_fast]; + +for(var c = 0; c < 3; c++) { + base_getter_test(cf[c]); +} + +// A special test for LoadKeyedHoleMode. Ensure that optimized is generated +// which sets ALLOW_RETURN_HOLE, then add a setter on the prototype that should +// cause the function to deoptimize. + +var a = [3.5,,,3.5]; +fun = function(a) { return a[0] + 5.5; } +fun(a); +fun(a); +fun(a); // should have a monomorphic KeyedLoadIC. +optimize(fun); +fun(a); +assertOptimized(fun); + +// returning undefined shouldn't phase us. +delete a[0]; +fun(a); +assertOptimized(fun); + +// but messing up the prototype chain will. +a.__proto__ = []; +fun(a); +assertUnoptimized(fun); + +// Construct a non-trivial prototype chain. +var a = [3.5,,,,3.5]; +var ap = [,,3.5]; +ap.__proto__ = a.__proto__; +a.__proto__ = ap; +fun(a); +optimize(fun); +fun(a); +assertOptimized(fun); + +var calls = 0; +delete a[0]; +ap.__defineGetter__(0, function() { calls++; return 0; }); +fun(a); +assertEquals(1, calls); +assertUnoptimized(fun); diff --git a/deps/v8/test/mjsunit/global-load-from-eval-in-with.js b/deps/v8/test/mjsunit/global-load-from-eval-in-with.js index d733f6c8d4..a41ad7ee00 100644 --- a/deps/v8/test/mjsunit/global-load-from-eval-in-with.js +++ b/deps/v8/test/mjsunit/global-load-from-eval-in-with.js @@ -56,4 +56,3 @@ test({ y: 42 }, "function f() { eval('1'); assertEquals(27, x) }; f();"); // in the eval scopes. Deeper nesting this time. test({ x: 42 }, "function f() { function g() { eval('1'); assertEquals(42, x) }; g() }; f();"); test({ y: 42 }, "function f() { function g() { eval('1'); assertEquals(27, x) }; g() }; f();"); - diff --git a/deps/v8/test/mjsunit/global-load-from-nested-eval.js b/deps/v8/test/mjsunit/global-load-from-nested-eval.js index 3c7ff75691..9c9b015aea 100644 --- a/deps/v8/test/mjsunit/global-load-from-nested-eval.js +++ b/deps/v8/test/mjsunit/global-load-from-nested-eval.js @@ -59,8 +59,3 @@ function testEvalDontShadow(source) { eval('eval(' + source +')'); } testEvalDontShadow('assertEquals(42, x)'); - - - - - diff --git a/deps/v8/test/mjsunit/harmony/array-find.js b/deps/v8/test/mjsunit/harmony/array-find.js index 906c9cde7b..9f5750eca0 100644 --- a/deps/v8/test/mjsunit/harmony/array-find.js +++ b/deps/v8/test/mjsunit/harmony/array-find.js @@ -277,4 +277,4 @@ assertThrows('Array.prototype.find.apply({}, false, [])', TypeError); assertThrows('Array.prototype.find.apply({}, "", [])', TypeError); assertThrows('Array.prototype.find.apply({}, {}, [])', TypeError); assertThrows('Array.prototype.find.apply({}, [], [])', TypeError); -assertThrows('Array.prototype.find.apply({}, /\d+/, [])', TypeError);
\ No newline at end of file +assertThrows('Array.prototype.find.apply({}, /\d+/, [])', TypeError); diff --git a/deps/v8/test/mjsunit/harmony/array-findindex.js b/deps/v8/test/mjsunit/harmony/array-findindex.js index 928cad79e4..a33849dab3 100644 --- a/deps/v8/test/mjsunit/harmony/array-findindex.js +++ b/deps/v8/test/mjsunit/harmony/array-findindex.js @@ -277,4 +277,4 @@ assertThrows('Array.prototype.findIndex.apply({}, false, [])', TypeError); assertThrows('Array.prototype.findIndex.apply({}, "", [])', TypeError); assertThrows('Array.prototype.findIndex.apply({}, {}, [])', TypeError); assertThrows('Array.prototype.findIndex.apply({}, [], [])', TypeError); -assertThrows('Array.prototype.findIndex.apply({}, /\d+/, [])', TypeError);
\ No newline at end of file +assertThrows('Array.prototype.findIndex.apply({}, /\d+/, [])', TypeError); diff --git a/deps/v8/test/mjsunit/harmony/collections.js b/deps/v8/test/mjsunit/harmony/collections.js index 174d3d1dc7..7e95b9e110 100644 --- a/deps/v8/test/mjsunit/harmony/collections.js +++ b/deps/v8/test/mjsunit/harmony/collections.js @@ -483,4 +483,26 @@ for (var i = 9; i >= 0; i--) { assertTrue(w.has(k)); w.clear(); assertFalse(w.has(k)); -})();
\ No newline at end of file +})(); + + +(function TestMinusZeroSet() { + var m = new Set(); + m.add(0); + m.add(-0); + assertEquals(1, m.size); + assertTrue(m.has(0)); + assertTrue(m.has(-0)); +})(); + + +(function TestMinusZeroMap() { + var m = new Map(); + m.set(0, 'plus'); + m.set(-0, 'minus'); + assertEquals(1, m.size); + assertTrue(m.has(0)); + assertTrue(m.has(-0)); + assertEquals('minus', m.get(0)); + assertEquals('minus', m.get(-0)); +})(); diff --git a/deps/v8/test/mjsunit/harmony/dataview-accessors.js b/deps/v8/test/mjsunit/harmony/dataview-accessors.js index 7b03da7089..c54f8cc20d 100644 --- a/deps/v8/test/mjsunit/harmony/dataview-accessors.js +++ b/deps/v8/test/mjsunit/harmony/dataview-accessors.js @@ -114,11 +114,13 @@ function runIntegerTestCases(isTestingGet, array, start, length) { test(isTestingGet, "Int8", undefined, 0); test(isTestingGet, "Int8", 8, -128); test(isTestingGet, "Int8", 15, -1); + test(isTestingGet, "Int8", 1e12, undefined); test(isTestingGet, "Uint8", 0, 0); test(isTestingGet, "Uint8", undefined, 0); test(isTestingGet, "Uint8", 8, 128); test(isTestingGet, "Uint8", 15, 255); + test(isTestingGet, "Uint8", 1e12, undefined); // Little endian. test(isTestingGet, "Int16", 0, 256, true); @@ -126,6 +128,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) { test(isTestingGet, "Int16", 5, 26213, true); test(isTestingGet, "Int16", 9, -32127, true); test(isTestingGet, "Int16", 14, -2, true); + test(isTestingGet, "Int16", 1e12, undefined, true); // Big endian. test(isTestingGet, "Int16", 0, 1); @@ -133,6 +136,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) { test(isTestingGet, "Int16", 5, 25958); test(isTestingGet, "Int16", 9, -32382); test(isTestingGet, "Int16", 14, -257); + test(isTestingGet, "Int16", 1e12, undefined); // Little endian. test(isTestingGet, "Uint16", 0, 256, true); @@ -140,6 +144,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) { test(isTestingGet, "Uint16", 5, 26213, true); test(isTestingGet, "Uint16", 9, 33409, true); test(isTestingGet, "Uint16", 14, 65534, true); + test(isTestingGet, "Uint16", 1e12, undefined, true); // Big endian. test(isTestingGet, "Uint16", 0, 1); @@ -147,6 +152,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) { test(isTestingGet, "Uint16", 5, 25958); test(isTestingGet, "Uint16", 9, 33154); test(isTestingGet, "Uint16", 14, 65279); + test(isTestingGet, "Uint16", 1e12, undefined); // Little endian. test(isTestingGet, "Int32", 0, 50462976, true); @@ -155,6 +161,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) { test(isTestingGet, "Int32", 6, -2122291354, true); test(isTestingGet, "Int32", 9, -58490239, true); test(isTestingGet, "Int32", 12,-66052, true); + test(isTestingGet, "Int32", 1e12, undefined, true); // Big endian. test(isTestingGet, "Int32", 0, 66051); @@ -163,6 +170,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) { test(isTestingGet, "Int32", 6, 1718059137); test(isTestingGet, "Int32", 9, -2122152964); test(isTestingGet, "Int32", 12, -50462977); + test(isTestingGet, "Int32", 1e12, undefined); // Little endian. test(isTestingGet, "Uint32", 0, 50462976, true); @@ -171,6 +179,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) { test(isTestingGet, "Uint32", 6, 2172675942, true); test(isTestingGet, "Uint32", 9, 4236477057, true); test(isTestingGet, "Uint32", 12,4294901244, true); + test(isTestingGet, "Uint32", 1e12, undefined, true); // Big endian. test(isTestingGet, "Uint32", 0, 66051); @@ -179,6 +188,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) { test(isTestingGet, "Uint32", 6, 1718059137); test(isTestingGet, "Uint32", 9, 2172814332); test(isTestingGet, "Uint32", 12, 4244504319); + test(isTestingGet, "Uint32", 1e12, undefined); } function testFloat(isTestingGet, func, array, start, expected) { @@ -192,6 +202,7 @@ function testFloat(isTestingGet, func, array, start, expected) { test(isTestingGet, func, 7, expected, true); createDataView(array, 10, true, start); test(isTestingGet, func, 10, expected, true); + test(isTestingGet, func, 1e12, undefined, true); // Big endian. createDataView(array, 0, false); @@ -203,6 +214,7 @@ function testFloat(isTestingGet, func, array, start, expected) { test(isTestingGet, func, 7, expected, false); createDataView(array, 10, false); test(isTestingGet, func, 10, expected, false); + test(isTestingGet, func, 1e12, undefined, false); } function runFloatTestCases(isTestingGet, start) { diff --git a/deps/v8/test/mjsunit/harmony/generators-iteration.js b/deps/v8/test/mjsunit/harmony/generators-iteration.js index 7fad97e944..d86a20f9e7 100644 --- a/deps/v8/test/mjsunit/harmony/generators-iteration.js +++ b/deps/v8/test/mjsunit/harmony/generators-iteration.js @@ -35,6 +35,18 @@ function assertIteratorResult(value, done, result) { assertEquals({ value: value, done: done}, result); } +function assertIteratorIsClosed(iter) { + assertIteratorResult(undefined, true, iter.next()); + assertDoesNotThrow(function() { iter.next(); }); +} + +function assertThrownIteratorIsClosed(iter) { + // TODO(yusukesuzuki): Since status of a thrown generator is "executing", + // following tests are failed. + // https://code.google.com/p/v8/issues/detail?id=3096 + // assertIteratorIsClosed(iter); +} + function TestGeneratorResultPrototype() { function* g() { yield 1; } var iter = g(); @@ -53,11 +65,12 @@ function TestGenerator(g, expected_values_for_next, function testNext(thunk) { var iter = thunk(); for (var i = 0; i < expected_values_for_next.length; i++) { - assertIteratorResult(expected_values_for_next[i], - i == expected_values_for_next.length - 1, - iter.next()); + var v1 = expected_values_for_next[i]; + var v2 = i == expected_values_for_next.length - 1; + // var v3 = iter.next(); + assertIteratorResult(v1, v2, iter.next()); } - assertThrows(function() { iter.next(); }, Error); + assertIteratorIsClosed(iter); } function testSend(thunk) { var iter = thunk(); @@ -66,7 +79,7 @@ function TestGenerator(g, expected_values_for_next, i == expected_values_for_send.length - 1, iter.next(send_val)); } - assertThrows(function() { iter.next(send_val); }, Error); + assertIteratorIsClosed(iter); } function testThrow(thunk) { for (var i = 0; i < expected_values_for_next.length; i++) { @@ -78,7 +91,7 @@ function TestGenerator(g, expected_values_for_next, } function Sentinel() {} assertThrows(function () { iter.throw(new Sentinel); }, Sentinel); - assertThrows(function () { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } } @@ -393,21 +406,20 @@ function TestTryCatch(instantiate) { assertIteratorResult(1, false, iter.next()); assertIteratorResult(2, false, iter.next()); assertIteratorResult(3, false, iter.next()); - assertIteratorResult(undefined, true, iter.next()); - assertThrows(function() { iter.next(); }, Error); + assertIteratorIsClosed(iter); } Test1(instantiate(g)); function Test2(iter) { assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); - assertThrows(function() { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } Test2(instantiate(g)); function Test3(iter) { assertIteratorResult(1, false, iter.next()); assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); - assertThrows(function() { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } Test3(instantiate(g)); @@ -417,8 +429,7 @@ function TestTryCatch(instantiate) { var exn = new Sentinel; assertIteratorResult(exn, false, iter.throw(exn)); assertIteratorResult(3, false, iter.next()); - assertIteratorResult(undefined, true, iter.next()); - assertThrows(function() { iter.next(); }, Error); + assertIteratorIsClosed(iter); } Test4(instantiate(g)); @@ -429,8 +440,7 @@ function TestTryCatch(instantiate) { assertIteratorResult(exn, false, iter.throw(exn)); assertIteratorResult(3, false, iter.next()); assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); - assertThrows(function() { iter.next(); }, Error); - + assertThrownIteratorIsClosed(iter); } Test5(instantiate(g)); @@ -440,7 +450,7 @@ function TestTryCatch(instantiate) { var exn = new Sentinel; assertIteratorResult(exn, false, iter.throw(exn)); assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); - assertThrows(function() { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } Test6(instantiate(g)); @@ -448,8 +458,7 @@ function TestTryCatch(instantiate) { assertIteratorResult(1, false, iter.next()); assertIteratorResult(2, false, iter.next()); assertIteratorResult(3, false, iter.next()); - assertIteratorResult(undefined, true, iter.next()); - assertThrows(function() { iter.next(); }, Error); + assertIteratorIsClosed(iter); } Test7(instantiate(g)); } @@ -466,21 +475,20 @@ function TestTryFinally(instantiate) { assertIteratorResult(2, false, iter.next()); assertIteratorResult(3, false, iter.next()); assertIteratorResult(4, false, iter.next()); - assertIteratorResult(undefined, true, iter.next()); - assertThrows(function() { iter.next(); }, Error); + assertIteratorIsClosed(iter); } Test1(instantiate(g)); function Test2(iter) { assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); - assertThrows(function() { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } Test2(instantiate(g)); function Test3(iter) { assertIteratorResult(1, false, iter.next()); assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); - assertThrows(function() { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } Test3(instantiate(g)); @@ -489,8 +497,7 @@ function TestTryFinally(instantiate) { assertIteratorResult(2, false, iter.next()); assertIteratorResult(3, false, iter.throw(new Sentinel)); assertThrows(function() { iter.next(); }, Sentinel); - assertThrows(function() { iter.next(); }, Error); - + assertThrownIteratorIsClosed(iter); } Test4(instantiate(g)); @@ -499,7 +506,7 @@ function TestTryFinally(instantiate) { assertIteratorResult(2, false, iter.next()); assertIteratorResult(3, false, iter.throw(new Sentinel)); assertThrows(function() { iter.throw(new Sentinel2); }, Sentinel2); - assertThrows(function() { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } Test5(instantiate(g)); @@ -508,7 +515,7 @@ function TestTryFinally(instantiate) { assertIteratorResult(2, false, iter.next()); assertIteratorResult(3, false, iter.next()); assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); - assertThrows(function() { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } Test6(instantiate(g)); @@ -518,7 +525,7 @@ function TestTryFinally(instantiate) { assertIteratorResult(3, false, iter.next()); assertIteratorResult(4, false, iter.next()); assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); - assertThrows(function() { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } Test7(instantiate(g)); @@ -527,9 +534,7 @@ function TestTryFinally(instantiate) { assertIteratorResult(2, false, iter.next()); assertIteratorResult(3, false, iter.next()); assertIteratorResult(4, false, iter.next()); - assertIteratorResult(undefined, true, iter.next()); - assertThrows(function() { iter.next(); }, Error); - + assertIteratorIsClosed(iter); } Test8(instantiate(g)); } @@ -556,14 +561,13 @@ function TestNestedTry(instantiate) { assertIteratorResult(3, false, iter.next()); assertIteratorResult(4, false, iter.next()); assertIteratorResult(5, false, iter.next()); - assertIteratorResult(undefined, true, iter.next()); - assertThrows(function() { iter.next(); }, Error); + assertIteratorIsClosed(iter); } Test1(instantiate(g)); function Test2(iter) { assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); - assertThrows(function() { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } Test2(instantiate(g)); @@ -571,7 +575,7 @@ function TestNestedTry(instantiate) { assertIteratorResult(1, false, iter.next()); assertIteratorResult(4, false, iter.throw(new Sentinel)); assertThrows(function() { iter.next(); }, Sentinel); - assertThrows(function() { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } Test3(instantiate(g)); @@ -579,7 +583,7 @@ function TestNestedTry(instantiate) { assertIteratorResult(1, false, iter.next()); assertIteratorResult(4, false, iter.throw(new Sentinel)); assertThrows(function() { iter.throw(new Sentinel2); }, Sentinel2); - assertThrows(function() { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } Test4(instantiate(g)); @@ -591,9 +595,7 @@ function TestNestedTry(instantiate) { assertIteratorResult(3, false, iter.next()); assertIteratorResult(4, false, iter.next()); assertIteratorResult(5, false, iter.next()); - assertIteratorResult(undefined, true, iter.next()); - assertThrows(function() { iter.next(); }, Error); - + assertIteratorIsClosed(iter); } Test5(instantiate(g)); @@ -604,7 +606,7 @@ function TestNestedTry(instantiate) { assertIteratorResult(exn, false, iter.throw(exn)); assertIteratorResult(4, false, iter.throw(new Sentinel2)); assertThrows(function() { iter.next(); }, Sentinel2); - assertThrows(function() { iter.next(); }, Error); + assertThrownIteratorIsClosed(iter); } Test6(instantiate(g)); @@ -616,8 +618,7 @@ function TestNestedTry(instantiate) { assertIteratorResult(3, false, iter.next()); assertIteratorResult(4, false, iter.throw(new Sentinel2)); assertThrows(function() { iter.next(); }, Sentinel2); - assertThrows(function() { iter.next(); }, Error); - + assertThrownIteratorIsClosed(iter); } Test7(instantiate(g)); diff --git a/deps/v8/test/mjsunit/harmony/iteration-semantics.js b/deps/v8/test/mjsunit/harmony/iteration-semantics.js index 96b6d1452c..2449115dd4 100644 --- a/deps/v8/test/mjsunit/harmony/iteration-semantics.js +++ b/deps/v8/test/mjsunit/harmony/iteration-semantics.js @@ -25,7 +25,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --harmony --harmony-generators +// Flags: --harmony-iteration +// Flags: --harmony-generators --harmony-scoping --harmony-proxies // Test for-of semantics. diff --git a/deps/v8/test/mjsunit/harmony/math-clz32.js b/deps/v8/test/mjsunit/harmony/math-clz32.js new file mode 100644 index 0000000000..bc15ad2569 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/math-clz32.js @@ -0,0 +1,28 @@ +// 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-maths + +[NaN, Infinity, -Infinity, 0, -0, "abc", "Infinity", "-Infinity", {}].forEach( + function(x) { + assertEquals(32, Math.clz32(x)); + } +); + +function testclz(x) { + for (var i = 0; i < 33; i++) { + if (x & 0x80000000) return i; + x <<= 1; + } + return 32; +} + +var max = Math.pow(2, 40); +for (var x = 0; x < max; x = x * 1.01 + 1) { + assertEquals(testclz(x), Math.clz32(x)); + assertEquals(testclz(-x), Math.clz32(-x)); + assertEquals(testclz(x), Math.clz32({ valueOf: function() { return x; } })); + assertEquals(testclz(-x), + Math.clz32({ toString: function() { return -x; } })); +} diff --git a/deps/v8/test/mjsunit/harmony/math-fround.js b/deps/v8/test/mjsunit/harmony/math-fround.js new file mode 100644 index 0000000000..ea432ea2de --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/math-fround.js @@ -0,0 +1,99 @@ +// 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-maths + +// Monkey-patch Float32Array. +Float32Array = function(x) { this[0] = 0; }; + +assertTrue(isNaN(Math.fround(NaN))); +assertTrue(isNaN(Math.fround(function() {}))); +assertTrue(isNaN(Math.fround({ toString: function() { return NaN; } }))); +assertTrue(isNaN(Math.fround({ valueOf: function() { return "abc"; } }))); +assertEquals("Infinity", String(1/Math.fround(0))); +assertEquals("-Infinity", String(1/Math.fround(-0))); +assertEquals("Infinity", String(Math.fround(Infinity))); +assertEquals("-Infinity", String(Math.fround(-Infinity))); + +assertEquals("Infinity", String(Math.fround(1E200))); +assertEquals("-Infinity", String(Math.fround(-1E200))); +assertEquals("Infinity", String(1/Math.fround(1E-300))); +assertEquals("-Infinity", String(1/Math.fround(-1E-300))); + +mantissa_23_shift = Math.pow(2, -23); +mantissa_29_shift = Math.pow(2, -23-29); + +// Javascript implementation of IEEE 754 to test double to single conversion. +function ieee754float(sign_bit, + exponent_bits, + mantissa_23_bits, + mantissa_29_bits) { + this.sign_bit = sign_bit & 1; + this.exponent_bits = exponent_bits & ((1 << 11) - 1); + this.mantissa_23_bits = mantissa_23_bits & ((1 << 23) - 1); + this.mantissa_29_bits = mantissa_29_bits & ((1 << 29) - 1); +} + +ieee754float.prototype.returnSpecial = function() { + if (mantissa_23_bits == 0 && mantissa_29_bits == 0) return sign * Infinity; + return NaN; +} + +ieee754float.prototype.toDouble = function() { + var sign = this.sign_bit ? -1 : 1; + var exponent = this.exponent_bits - 1023; + if (exponent == -1023) returnSpecial(); + var mantissa = 1 + this.mantissa_23_bits * mantissa_23_shift + + this.mantissa_29_bits * mantissa_29_shift; + return sign * Math.pow(2, exponent) * mantissa; +} + +ieee754float.prototype.toSingle = function() { + var sign = this.sign_bit ? -1 : 1; + var exponent = this.exponent_bits - 1023; + if (exponent == -1023) returnSpecial(); + if (exponent > 127) return sign * Infinity; + if (exponent < -126) return this.toSingleSubnormal(sign, exponent); + var round = this.mantissa_29_bits >> 28; + var mantissa = 1 + (this.mantissa_23_bits + round) * mantissa_23_shift; + return sign * Math.pow(2, exponent) * mantissa; +} + +ieee754float.prototype.toSingleSubnormal = function(sign, exponent) { + var shift = -126 - exponent; + if (shift > 24) return sign * 0; + var round_mask = 1 << (shift - 1); + var mantissa_23_bits = this.mantissa_23_bits + (1 << 23); + var round = ((mantissa_23_bits & round_mask) != 0) | 0; + if (round) { // Round to even if tied. + var tied_mask = round_mask - 1; + var result_last_bit_mask = 1 << shift; + var tied = this.mantissa_29_bits == 0 && + (mantissa_23_bits & tied_mask ) == 0; + var result_already_even = (mantissa_23_bits & result_last_bit_mask) == 0; + if (tied && result_already_even) round = 0; + } + mantissa_23_bits >>= shift; + var mantissa = (mantissa_23_bits + round) * mantissa_23_shift; + return sign * Math.pow(2, -126) * mantissa; +} + + +var pi = new ieee754float(0, 0x400, 0x490fda, 0x14442d18); +assertEquals(pi.toSingle(), Math.fround(pi.toDouble())); + +function fuzz_mantissa(sign, exp, m1inc, m2inc) { + for (var m1 = 0; m1 < (1 << 23); m1 += m1inc) { + for (var m2 = 0; m2 < (1 << 29); m2 += m2inc) { + var float = new ieee754float(sign, exp, m1, m2); + assertEquals(float.toSingle(), Math.fround(float.toDouble())); + } + } +} + +for (var sign = 0; sign < 2; sign++) { + for (var exp = 1024 - 170; exp < 1024 + 170; exp++) { + fuzz_mantissa(sign, exp, 1337 * exp - sign, 127913 * exp - sign); + } +} diff --git a/deps/v8/test/mjsunit/harmony/math-hyperbolic.js b/deps/v8/test/mjsunit/harmony/math-hyperbolic.js new file mode 100644 index 0000000000..c45a19c526 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/math-hyperbolic.js @@ -0,0 +1,138 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --harmony-maths + +[Math.sinh, Math.cosh, Math.tanh, Math.asinh, Math.acosh, Math.atanh]. + forEach(function(fun) { + assertTrue(isNaN(fun(NaN))); + assertTrue(isNaN(fun("abc"))); + assertTrue(isNaN(fun({}))); + assertEquals(fun(0), fun([])); + assertTrue(isNaN(fun([1, 1]))); + assertEquals(fun(1.11), fun({ toString: function() { return "1.11"; } })); + assertEquals(fun(-3.1), fun({ toString: function() { return -3.1; } })); + assertEquals(fun(-1.1), fun({ valueOf: function() { return "-1.1"; } })); + assertEquals(fun(3.11), fun({ valueOf: function() { return 3.11; } })); +}); + + +function test_id(fun, rev, value) { + assertEqualsDelta(1, rev(fun(value))/value, 1E-7); +} + +[Math.PI, 2, 5, 1E-5, 0.3].forEach(function(x) { + test_id(Math.sinh, Math.asinh, x); + test_id(Math.sinh, Math.asinh, -x); + test_id(Math.cosh, Math.acosh, x); + test_id(Math.tanh, Math.atanh, x); + test_id(Math.tanh, Math.atanh, -x); +}); + + +[Math.sinh, Math.asinh, Math.tanh, Math.atanh].forEach(function(fun) { + assertEquals("-Infinity", String(1/fun(-0))); + assertEquals("Infinity", String(1/fun(0))); +}); + + +[Math.sinh, Math.asinh].forEach(function(fun) { + assertEquals("-Infinity", String(fun(-Infinity))); + assertEquals("Infinity", String(fun(Infinity))); + assertEquals("-Infinity", String(fun("-Infinity"))); + assertEquals("Infinity", String(fun("Infinity"))); +}); + + +assertEquals("Infinity", String(Math.cosh(-Infinity))); +assertEquals("Infinity", String(Math.cosh(Infinity))); +assertEquals("Infinity", String(Math.cosh("-Infinity"))); +assertEquals("Infinity", String(Math.cosh("Infinity"))); + + +assertEquals("-Infinity", String(Math.atanh(-1))); +assertEquals("Infinity", String(Math.atanh(1))); + +// Math.atanh(x) is NaN for |x| > 1 and NaN +[1.000000000001, Math.PI, 10000000, 2, Infinity, NaN].forEach(function(x) { + assertTrue(isNaN(Math.atanh(-x))); + assertTrue(isNaN(Math.atanh(x))); +}); + + +assertEquals(1, Math.tanh(Infinity)); +assertEquals(-1, Math.tanh(-Infinity)); +assertEquals(1, Math.cosh(0)); +assertEquals(1, Math.cosh(-0)); + +assertEquals(0, Math.acosh(1)); +assertEquals("Infinity", String(Math.acosh(Infinity))); + +// Math.acosh(x) is NaN for x < 1 +[0.99999999999, 0.2, -1000, 0, -0].forEach(function(x) { + assertTrue(isNaN(Math.acosh(x))); +}); + + +// Some random samples. +assertEqualsDelta(0.5210953054937, Math.sinh(0.5), 1E-12); +assertEqualsDelta(74.203210577788, Math.sinh(5), 1E-12); +assertEqualsDelta(-0.5210953054937, Math.sinh(-0.5), 1E-12); +assertEqualsDelta(-74.203210577788, Math.sinh(-5), 1E-12); + +assertEqualsDelta(1.1276259652063, Math.cosh(0.5), 1E-12); +assertEqualsDelta(74.209948524787, Math.cosh(5), 1E-12); +assertEqualsDelta(1.1276259652063, Math.cosh(-0.5), 1E-12); +assertEqualsDelta(74.209948524787, Math.cosh(-5), 1E-12); + +assertEqualsDelta(0.4621171572600, Math.tanh(0.5), 1E-12); +assertEqualsDelta(0.9999092042625, Math.tanh(5), 1E-12); +assertEqualsDelta(-0.4621171572600, Math.tanh(-0.5), 1E-12); +assertEqualsDelta(-0.9999092042625, Math.tanh(-5), 1E-12); + +assertEqualsDelta(0.4812118250596, Math.asinh(0.5), 1E-12); +assertEqualsDelta(2.3124383412727, Math.asinh(5), 1E-12); +assertEqualsDelta(-0.4812118250596, Math.asinh(-0.5), 1E-12); +assertEqualsDelta(-2.3124383412727, Math.asinh(-5), 1E-12); + +assertEqualsDelta(0.9624236501192, Math.acosh(1.5), 1E-12); +assertEqualsDelta(2.2924316695612, Math.acosh(5), 1E-12); +assertEqualsDelta(0.4435682543851, Math.acosh(1.1), 1E-12); +assertEqualsDelta(1.3169578969248, Math.acosh(2), 1E-12); + +assertEqualsDelta(0.5493061443341, Math.atanh(0.5), 1E-12); +assertEqualsDelta(0.1003353477311, Math.atanh(0.1), 1E-12); +assertEqualsDelta(-0.5493061443341, Math.atanh(-0.5), 1E-12); +assertEqualsDelta(-0.1003353477311, Math.atanh(-0.1), 1E-12); + +[0, 1E-50, 1E-10, 1E10, 1E50, 1E100, 1E150].forEach(function(x) { + assertEqualsDelta(Math.asinh(x), -Math.asinh(-x), 1E-12); +}); + +[1-(1E-16), 0, 1E-10, 1E-50].forEach(function(x) { + assertEqualsDelta(Math.atanh(x), -Math.atanh(-x), 1E-12); +}); diff --git a/deps/v8/test/mjsunit/harmony/math-hypot.js b/deps/v8/test/mjsunit/harmony/math-hypot.js new file mode 100644 index 0000000000..1052627213 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/math-hypot.js @@ -0,0 +1,94 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --harmony-maths + +assertTrue(isNaN(Math.hypot({}))); +assertTrue(isNaN(Math.hypot(undefined, 1))); +assertTrue(isNaN(Math.hypot(1, undefined))); +assertTrue(isNaN(Math.hypot(Math.hypot, 1))); +assertEquals(1, Math.hypot(1)); +assertEquals(Math.PI, Math.hypot(Math.PI)); +assertEquals(5, Math.hypot(3, 4)); +assertEquals(13, Math.hypot(3, 4, 12)); +assertEquals(15, Math.hypot(" 2 ", + "0x5", + { valueOf: function() { return "0xe"; } })); +assertEquals(17, Math.hypot({ valueOf: function() { return 1; } }, + { toString: function() { return 12; } }, + { toString: function() { return "12"; } })); + +// Check function length. +assertEquals(2, Math.hypot.length); + +// Check that 0 is returned for no arguments. +assertEquals(0, Math.hypot()); + +// Check that Infinity is returned if any of the arguments is +/-Infinity. +assertEquals("Infinity", String(Math.hypot(NaN, Infinity))); +assertEquals("Infinity", String(Math.hypot(1, -Infinity, 2))); + +// Check that NaN is returned if any argument is NaN and none is +/-Infinity/ +assertTrue(isNaN(Math.hypot(1, 2, NaN))); +assertTrue(isNaN(Math.hypot(NaN, NaN, 4))); + +// Check that +0 is returned if all arguments are +/-0. +assertEquals("Infinity", String(1/Math.hypot(-0))); +assertEquals("Infinity", String(1/Math.hypot(0))); +assertEquals("Infinity", String(1/Math.hypot(-0, -0))); +assertEquals("Infinity", String(1/Math.hypot(-0, 0))); + +// Check that we avoid overflows and underflows. +assertEqualsDelta(5E300, Math.hypot(3E300, 4E300), 1E285); +assertEqualsDelta(17E-300, Math.hypot(8E-300, 15E-300), 1E-315); +assertEqualsDelta(19E300, Math.hypot(6E300, 6E300, 17E300), 1E285); + +// Check that we sufficiently account for rounding errors when summing up. +// For this, we calculate a simple fractal square that recurses in the +// fourth quarter. +var fractals = []; +var edge_length = Math.E * 1E20; + +var fractal_length = edge_length; +while(fractal_length >= 1) { + fractal_length *= 0.5; + fractals.push(fractal_length); + fractals.push(fractal_length); + fractals.push(fractal_length); +} + +fractals.push(fractal_length); +assertEqualsDelta(edge_length, Math.hypot.apply(Math, fractals), 1E-15); +fractals.reverse(); +assertEqualsDelta(edge_length, Math.hypot.apply(Math, fractals), 1E-15); +// Also shuffle the array. +var c = 0; +function random_sort(a, b) { c++; return (c & 3) - 1.5; } +fractals.sort(random_sort); +assertEqualsDelta(edge_length, Math.hypot.apply(Math, fractals), 1E-15); +fractals.sort(random_sort); +assertEqualsDelta(edge_length, Math.hypot.apply(Math, fractals), 1E-15); diff --git a/deps/v8/test/mjsunit/harmony/math-log2-log10.js b/deps/v8/test/mjsunit/harmony/math-log2-log10.js new file mode 100644 index 0000000000..2ab496012c --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/math-log2-log10.js @@ -0,0 +1,47 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --harmony-maths + +[Math.log10, Math.log2].forEach( function(fun) { + assertTrue(isNaN(fun(NaN))); + assertTrue(isNaN(fun(fun))); + assertTrue(isNaN(fun({ toString: function() { return NaN; } }))); + assertTrue(isNaN(fun({ valueOf: function() { return -1; } }))); + assertTrue(isNaN(fun({ valueOf: function() { return "abc"; } }))); + assertTrue(isNaN(fun(-0.1))); + assertTrue(isNaN(fun(-1))); + assertEquals("-Infinity", String(fun(0))); + assertEquals("-Infinity", String(fun(-0))); + assertEquals(0, fun(1)); + assertEquals("Infinity", String(fun(Infinity))); +}); + +for (var i = -300; i < 300; i += 0.7) { + assertEqualsDelta(i, Math.log10(Math.pow(10, i)), 1E-13); + assertEqualsDelta(i, Math.log2(Math.pow(2, i)), 1E-13); +} diff --git a/deps/v8/test/mjsunit/harmony/microtask-delivery.js b/deps/v8/test/mjsunit/harmony/microtask-delivery.js new file mode 100644 index 0000000000..566a39d03e --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/microtask-delivery.js @@ -0,0 +1,168 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --harmony-observation --harmony-promises --allow-natives-syntax + +var ordering = []; +function reset() { + ordering = []; +} + +function assertArrayValues(expected, actual) { + assertEquals(expected.length, actual.length); + for (var i = 0; i < expected.length; i++) { + assertEquals(expected[i], actual[i]); + } +} + +function assertOrdering(expected) { + %RunMicrotasks(); + assertArrayValues(expected, ordering); +} + +function newPromise(id, fn) { + var r; + var t = 1; + var promise = new Promise(function(resolve) { + r = resolve; + if (fn) fn(); + }); + + var next = promise.then(function(value) { + ordering.push('p' + id); + return value; + }); + + return { + resolve: r, + then: function(fn) { + next = next.then(function(value) { + ordering.push('p' + id + ':' + t++); + return fn ? fn(value) : value; + }); + + return this; + } + }; +} + +function newObserver(id, fn, obj) { + var observer = { + value: 1, + recordCounts: [] + }; + + Object.observe(observer, function(records) { + ordering.push('o' + id); + observer.recordCounts.push(records.length); + if (fn) fn(); + }); + + return observer; +} + + +(function PromiseThens() { + reset(); + + var p1 = newPromise(1).then(); + var p2 = newPromise(2).then(); + + p1.resolve(); + p2.resolve(); + + assertOrdering(['p1', 'p2', 'p1:1', 'p2:1']); +})(); + + +(function ObserversBatch() { + reset(); + + var p1 = newPromise(1); + var p2 = newPromise(2); + var p3 = newPromise(3); + + var ob1 = newObserver(1); + var ob2 = newObserver(2, function() { + ob3.value++; + p3.resolve(); + ob1.value++; + }); + var ob3 = newObserver(3); + + p1.resolve(); + ob1.value++; + p2.resolve(); + ob2.value++; + + assertOrdering(['p1', 'o1', 'o2', 'p2', 'o1', 'o3', 'p3']); + assertArrayValues([1, 1], ob1.recordCounts); + assertArrayValues([1], ob2.recordCounts); + assertArrayValues([1], ob3.recordCounts); +})(); + + +(function ObserversGetAllRecords() { + reset(); + + var p1 = newPromise(1); + var p2 = newPromise(2); + var ob1 = newObserver(1, function() { + ob2.value++; + }); + var ob2 = newObserver(2); + + p1.resolve(); + ob1.value++; + p2.resolve(); + ob2.value++; + + assertOrdering(['p1', 'o1', 'o2', 'p2']); + assertArrayValues([1], ob1.recordCounts); + assertArrayValues([2], ob2.recordCounts); +})(); + + +(function NewObserverDeliveryGetsNewMicrotask() { + reset(); + + var p1 = newPromise(1); + var p2 = newPromise(2); + var ob1 = newObserver(1); + var ob2 = newObserver(2, function() { + ob1.value++; + }); + + p1.resolve(); + ob1.value++; + p2.resolve(); + ob2.value++; + + assertOrdering(['p1', 'o1', 'o2', 'p2', 'o1']); + assertArrayValues([1, 1], ob1.recordCounts); + assertArrayValues([1], ob2.recordCounts); +})(); diff --git a/deps/v8/test/mjsunit/harmony/object-observe.js b/deps/v8/test/mjsunit/harmony/object-observe.js index f94ab75e9a..fb15a1fa83 100644 --- a/deps/v8/test/mjsunit/harmony/object-observe.js +++ b/deps/v8/test/mjsunit/harmony/object-observe.js @@ -147,8 +147,9 @@ assertThrows(function() { notifier.performChange(1, function(){}); }, TypeError) assertThrows(function() { notifier.performChange(undefined, function(){}); }, TypeError); assertThrows(function() { notifier.performChange('foo', undefined); }, TypeError); assertThrows(function() { notifier.performChange('foo', 'bar'); }, TypeError); +var global = this; notifier.performChange('foo', function() { - assertEquals(undefined, this); + assertEquals(global, this); }); var notify = notifier.notify; @@ -187,21 +188,21 @@ Object.deliverChangeRecords(observer.callback); // Multiple records are delivered. reset(); notifier.notify({ - type: 'updated', + type: 'update', name: 'foo', expando: 1 }); notifier.notify({ object: notifier, // object property is ignored - type: 'deleted', + type: 'delete', name: 'bar', expando2: 'str' }); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, name: 'foo', type: 'updated', expando: 1 }, - { object: obj, name: 'bar', type: 'deleted', expando2: 'str' } + { object: obj, name: 'foo', type: 'update', expando: 1 }, + { object: obj, name: 'bar', type: 'delete', expando2: 'str' } ]); // Non-string accept values are coerced to strings @@ -235,7 +236,7 @@ reset(); Object.observe(obj, observer.callback); Object.observe(obj, observer.callback); Object.getNotifier(obj).notify({ - type: 'updated', + type: 'update', }); Object.deliverChangeRecords(observer.callback); observer.assertCalled(); @@ -245,7 +246,7 @@ observer.assertCalled(); reset(); Object.unobserve(obj, observer.callback); Object.getNotifier(obj).notify({ - type: 'updated', + type: 'update', }); Object.deliverChangeRecords(observer.callback); observer.assertNotCalled(); @@ -256,7 +257,7 @@ reset(); Object.unobserve(obj, observer.callback); Object.unobserve(obj, observer.callback); Object.getNotifier(obj).notify({ - type: 'updated', + type: 'update', }); Object.deliverChangeRecords(observer.callback); observer.assertNotCalled(); @@ -265,11 +266,11 @@ observer.assertNotCalled(); // Re-observation works and only includes changeRecords after of call. reset(); Object.getNotifier(obj).notify({ - type: 'updated', + type: 'update', }); Object.observe(obj, observer.callback); Object.getNotifier(obj).notify({ - type: 'updated', + type: 'update', }); records = undefined; Object.deliverChangeRecords(observer.callback); @@ -283,7 +284,7 @@ Object.observe(obj, observer.callback); obj.id = 1; Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, type: 'new', name: 'id' }, + { object: obj, type: 'add', name: 'id' }, ]); // The empty-string property is observable @@ -295,110 +296,205 @@ obj[''] = ' '; delete obj['']; Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, type: 'new', name: '' }, - { object: obj, type: 'updated', name: '', oldValue: '' }, - { object: obj, type: 'deleted', name: '', oldValue: ' ' }, + { object: obj, type: 'add', name: '' }, + { object: obj, type: 'update', name: '', oldValue: '' }, + { object: obj, type: 'delete', name: '', oldValue: ' ' }, ]); +// Object.preventExtensions +reset(); +var obj = { foo: 'bar'}; +Object.observe(obj, observer.callback); +obj.baz = 'bat'; +Object.preventExtensions(obj); + +Object.deliverChangeRecords(observer.callback); +observer.assertCallbackRecords([ + { object: obj, type: 'add', name: 'baz' }, + { object: obj, type: 'preventExtensions' }, +]); + +reset(); +var obj = { foo: 'bar'}; +Object.preventExtensions(obj); +Object.observe(obj, observer.callback); +Object.preventExtensions(obj); +Object.deliverChangeRecords(observer.callback); +observer.assertNotCalled(); + +// Object.freeze +reset(); +var obj = { a: 'a' }; +Object.defineProperty(obj, 'b', { + writable: false, + configurable: true, + value: 'b' +}); +Object.defineProperty(obj, 'c', { + writable: true, + configurable: false, + value: 'c' +}); +Object.defineProperty(obj, 'd', { + writable: false, + configurable: false, + value: 'd' +}); +Object.observe(obj, observer.callback); +Object.freeze(obj); + +Object.deliverChangeRecords(observer.callback); +observer.assertCallbackRecords([ + { object: obj, type: 'reconfigure', name: 'a' }, + { object: obj, type: 'reconfigure', name: 'b' }, + { object: obj, type: 'reconfigure', name: 'c' }, + { object: obj, type: 'preventExtensions' }, +]); + +reset(); +var obj = { foo: 'bar'}; +Object.freeze(obj); +Object.observe(obj, observer.callback); +Object.freeze(obj); +Object.deliverChangeRecords(observer.callback); +observer.assertNotCalled(); + +// Object.seal +reset(); +var obj = { a: 'a' }; +Object.defineProperty(obj, 'b', { + writable: false, + configurable: true, + value: 'b' +}); +Object.defineProperty(obj, 'c', { + writable: true, + configurable: false, + value: 'c' +}); +Object.defineProperty(obj, 'd', { + writable: false, + configurable: false, + value: 'd' +}); +Object.observe(obj, observer.callback); +Object.seal(obj); + +Object.deliverChangeRecords(observer.callback); +observer.assertCallbackRecords([ + { object: obj, type: 'reconfigure', name: 'a' }, + { object: obj, type: 'reconfigure', name: 'b' }, + { object: obj, type: 'preventExtensions' }, +]); + +reset(); +var obj = { foo: 'bar'}; +Object.seal(obj); +Object.observe(obj, observer.callback); +Object.seal(obj); +Object.deliverChangeRecords(observer.callback); +observer.assertNotCalled(); + // Observing a continuous stream of changes, while itermittantly unobserving. reset(); +var obj = {}; Object.observe(obj, observer.callback); Object.getNotifier(obj).notify({ - type: 'updated', + type: 'update', val: 1 }); Object.unobserve(obj, observer.callback); Object.getNotifier(obj).notify({ - type: 'updated', + type: 'update', val: 2 }); Object.observe(obj, observer.callback); Object.getNotifier(obj).notify({ - type: 'updated', + type: 'update', val: 3 }); Object.unobserve(obj, observer.callback); Object.getNotifier(obj).notify({ - type: 'updated', + type: 'update', val: 4 }); Object.observe(obj, observer.callback); Object.getNotifier(obj).notify({ - type: 'updated', + type: 'update', val: 5 }); Object.unobserve(obj, observer.callback); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, type: 'updated', val: 1 }, - { object: obj, type: 'updated', val: 3 }, - { object: obj, type: 'updated', val: 5 } + { object: obj, type: 'update', val: 1 }, + { object: obj, type: 'update', val: 3 }, + { object: obj, type: 'update', val: 5 } ]); // Accept reset(); Object.observe(obj, observer.callback, ['somethingElse']); Object.getNotifier(obj).notify({ - type: 'new' + type: 'add' }); Object.getNotifier(obj).notify({ - type: 'updated' + type: 'update' }); Object.getNotifier(obj).notify({ - type: 'deleted' + type: 'delete' }); Object.getNotifier(obj).notify({ - type: 'reconfigured' + type: 'reconfigure' }); Object.getNotifier(obj).notify({ - type: 'prototype' + type: 'setPrototype' }); Object.deliverChangeRecords(observer.callback); observer.assertNotCalled(); reset(); -Object.observe(obj, observer.callback, ['new', 'deleted', 'prototype']); +Object.observe(obj, observer.callback, ['add', 'delete', 'setPrototype']); Object.getNotifier(obj).notify({ - type: 'new' + type: 'add' }); Object.getNotifier(obj).notify({ - type: 'updated' + type: 'update' }); Object.getNotifier(obj).notify({ - type: 'deleted' + type: 'delete' }); Object.getNotifier(obj).notify({ - type: 'deleted' + type: 'delete' }); Object.getNotifier(obj).notify({ - type: 'reconfigured' + type: 'reconfigure' }); Object.getNotifier(obj).notify({ - type: 'prototype' + type: 'setPrototype' }); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, type: 'new' }, - { object: obj, type: 'deleted' }, - { object: obj, type: 'deleted' }, - { object: obj, type: 'prototype' } + { object: obj, type: 'add' }, + { object: obj, type: 'delete' }, + { object: obj, type: 'delete' }, + { object: obj, type: 'setPrototype' } ]); reset(); -Object.observe(obj, observer.callback, ['updated', 'foo']); +Object.observe(obj, observer.callback, ['update', 'foo']); Object.getNotifier(obj).notify({ - type: 'new' + type: 'add' }); Object.getNotifier(obj).notify({ - type: 'updated' + type: 'update' }); Object.getNotifier(obj).notify({ - type: 'deleted' + type: 'delete' }); Object.getNotifier(obj).notify({ type: 'foo' @@ -411,7 +507,7 @@ Object.getNotifier(obj).notify({ }); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, type: 'updated' }, + { object: obj, type: 'update' }, { object: obj, type: 'foo' }, { object: obj, type: 'foo' } ]); @@ -434,12 +530,10 @@ Thingy.prototype = { notifier.performChange(Thingy.INCREMENT, function() { self.a += amount; self.b += amount; - }); - notifier.notify({ - object: this, - type: Thingy.INCREMENT, - incremented: amount + return { + incremented: amount + }; // implicit notify }); }, @@ -450,12 +544,10 @@ Thingy.prototype = { notifier.performChange(Thingy.MULTIPLY, function() { self.a *= amount; self.b *= amount; - }); - notifier.notify({ - object: this, - type: Thingy.MULTIPLY, - multiplied: amount + return { + multiplied: amount + }; // implicit notify }); }, @@ -466,13 +558,11 @@ Thingy.prototype = { notifier.performChange(Thingy.INCREMENT_AND_MULTIPLY, function() { self.increment(incAmount); self.multiply(multAmount); - }); - notifier.notify({ - object: this, - type: Thingy.INCREMENT_AND_MULTIPLY, - incremented: incAmount, - multiplied: multAmount + return { + incremented: incAmount, + multiplied: multAmount + }; // implicit notify }); } } @@ -481,7 +571,7 @@ Thingy.observe = function(thingy, callback) { Object.observe(thingy, callback, [Thingy.INCREMENT, Thingy.MULTIPLY, Thingy.INCREMENT_AND_MULTIPLY, - 'updated']); + 'update']); } Thingy.unobserve = function(thingy, callback) { @@ -501,22 +591,22 @@ thingy.incrementAndMultiply(2, 2); // { a: 26, b: 36 } Object.deliverChangeRecords(observer.callback); Object.deliverChangeRecords(observer2.callback); observer.assertCallbackRecords([ - { object: thingy, type: 'updated', name: 'a', oldValue: 2 }, - { object: thingy, type: 'updated', name: 'b', oldValue: 4 }, - { object: thingy, type: 'updated', name: 'b', oldValue: 7 }, - { object: thingy, type: 'updated', name: 'a', oldValue: 5 }, - { object: thingy, type: 'updated', name: 'b', oldValue: 8 }, - { object: thingy, type: 'updated', name: 'a', oldValue: 10 }, - { object: thingy, type: 'updated', name: 'a', oldValue: 11 }, - { object: thingy, type: 'updated', name: 'b', oldValue: 16 }, - { object: thingy, type: 'updated', name: 'a', oldValue: 13 }, - { object: thingy, type: 'updated', name: 'b', oldValue: 18 }, + { object: thingy, type: 'update', name: 'a', oldValue: 2 }, + { object: thingy, type: 'update', name: 'b', oldValue: 4 }, + { object: thingy, type: 'update', name: 'b', oldValue: 7 }, + { object: thingy, type: 'update', name: 'a', oldValue: 5 }, + { object: thingy, type: 'update', name: 'b', oldValue: 8 }, + { object: thingy, type: 'update', name: 'a', oldValue: 10 }, + { object: thingy, type: 'update', name: 'a', oldValue: 11 }, + { object: thingy, type: 'update', name: 'b', oldValue: 16 }, + { object: thingy, type: 'update', name: 'a', oldValue: 13 }, + { object: thingy, type: 'update', name: 'b', oldValue: 18 }, ]); observer2.assertCallbackRecords([ { object: thingy, type: Thingy.INCREMENT, incremented: 3 }, - { object: thingy, type: 'updated', name: 'b', oldValue: 7 }, + { object: thingy, type: 'update', name: 'b', oldValue: 7 }, { object: thingy, type: Thingy.MULTIPLY, multiplied: 2 }, - { object: thingy, type: 'updated', name: 'a', oldValue: 10 }, + { object: thingy, type: 'update', name: 'a', oldValue: 10 }, { object: thingy, type: Thingy.INCREMENT_AND_MULTIPLY, @@ -525,6 +615,69 @@ observer2.assertCallbackRecords([ } ]); +// ArrayPush cached stub +reset(); + +function pushMultiple(arr) { + arr.push('a'); + arr.push('b'); + arr.push('c'); +} + +for (var i = 0; i < 5; i++) { + var arr = []; + pushMultiple(arr); +} + +for (var i = 0; i < 5; i++) { + reset(); + var arr = []; + Object.observe(arr, observer.callback); + pushMultiple(arr); + Object.unobserve(arr, observer.callback); + Object.deliverChangeRecords(observer.callback); + observer.assertCallbackRecords([ + { object: arr, type: 'add', name: '0' }, + { object: arr, type: 'update', name: 'length', oldValue: 0 }, + { object: arr, type: 'add', name: '1' }, + { object: arr, type: 'update', name: 'length', oldValue: 1 }, + { object: arr, type: 'add', name: '2' }, + { object: arr, type: 'update', name: 'length', oldValue: 2 }, + ]); +} + + +// ArrayPop cached stub +reset(); + +function popMultiple(arr) { + arr.pop(); + arr.pop(); + arr.pop(); +} + +for (var i = 0; i < 5; i++) { + var arr = ['a', 'b', 'c']; + popMultiple(arr); +} + +for (var i = 0; i < 5; i++) { + reset(); + var arr = ['a', 'b', 'c']; + Object.observe(arr, observer.callback); + popMultiple(arr); + Object.unobserve(arr, observer.callback); + Object.deliverChangeRecords(observer.callback); + observer.assertCallbackRecords([ + { object: arr, type: 'delete', name: '2', oldValue: 'c' }, + { object: arr, type: 'update', name: 'length', oldValue: 3 }, + { object: arr, type: 'delete', name: '1', oldValue: 'b' }, + { object: arr, type: 'update', name: 'length', oldValue: 2 }, + { object: arr, type: 'delete', name: '0', oldValue: 'a' }, + { object: arr, type: 'update', name: 'length', oldValue: 1 }, + ]); +} + reset(); function RecursiveThingy() {} @@ -545,7 +698,6 @@ RecursiveThingy.prototype = { }); notifier.notify({ - object: this, type: RecursiveThingy.MULTIPLY_FIRST_N, multiplied: amount, n: n @@ -571,9 +723,9 @@ thingy.multiplyFirstN(2, 3); // [2, 4, 6, 4] Object.deliverChangeRecords(observer.callback); Object.deliverChangeRecords(observer2.callback); observer.assertCallbackRecords([ - { object: thingy, type: 'updated', name: '2', oldValue: 3 }, - { object: thingy, type: 'updated', name: '1', oldValue: 2 }, - { object: thingy, type: 'updated', name: '0', oldValue: 1 } + { object: thingy, type: 'update', name: '2', oldValue: 3 }, + { object: thingy, type: 'update', name: '1', oldValue: 2 }, + { object: thingy, type: 'update', name: '0', oldValue: 1 } ]); observer2.assertCallbackRecords([ { object: thingy, type: RecursiveThingy.MULTIPLY_FIRST_N, multiplied: 2, n: 3 } @@ -606,7 +758,6 @@ DeckSuit.prototype = { }); notifier.notify({ - object: this, type: DeckSuit.SHUFFLE }); }, @@ -638,20 +789,20 @@ Object.observe(obj, observer.callback); Object.observe(obj3, observer.callback); Object.observe(obj2, observer.callback); Object.getNotifier(obj).notify({ - type: 'new', + type: 'add', }); Object.getNotifier(obj2).notify({ - type: 'updated', + type: 'update', }); Object.getNotifier(obj3).notify({ - type: 'deleted', + type: 'delete', }); Object.observe(obj3, observer.callback); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, type: 'new' }, - { object: obj2, type: 'updated' }, - { object: obj3, type: 'deleted' } + { object: obj, type: 'add' }, + { object: obj2, type: 'update' }, + { object: obj3, type: 'delete' } ]); @@ -718,28 +869,28 @@ delete obj.a; Object.defineProperty(obj, "a", {value: 11, configurable: true}); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, name: "a", type: "updated", oldValue: 1 }, - { object: obj, name: "a", type: "updated", oldValue: 2 }, - { object: obj, name: "a", type: "deleted", oldValue: 3 }, - { object: obj, name: "a", type: "new" }, - { object: obj, name: "a", type: "updated", oldValue: 4 }, - { object: obj, name: "a", type: "updated", oldValue: 5 }, - { object: obj, name: "a", type: "reconfigured" }, - { object: obj, name: "a", type: "updated", oldValue: 6 }, - { object: obj, name: "a", type: "reconfigured", oldValue: 8 }, - { object: obj, name: "a", type: "reconfigured", oldValue: 7 }, - { object: obj, name: "a", type: "reconfigured" }, - { object: obj, name: "a", type: "reconfigured" }, - { object: obj, name: "a", type: "reconfigured" }, - { object: obj, name: "a", type: "deleted" }, - { object: obj, name: "a", type: "new" }, - { object: obj, name: "a", type: "reconfigured" }, - { object: obj, name: "a", type: "updated", oldValue: 9 }, - { object: obj, name: "a", type: "updated", oldValue: 10 }, - { object: obj, name: "a", type: "updated", oldValue: 11 }, - { object: obj, name: "a", type: "updated", oldValue: 12 }, - { object: obj, name: "a", type: "deleted", oldValue: 36 }, - { object: obj, name: "a", type: "new" }, + { object: obj, name: "a", type: "update", oldValue: 1 }, + { object: obj, name: "a", type: "update", oldValue: 2 }, + { object: obj, name: "a", type: "delete", oldValue: 3 }, + { object: obj, name: "a", type: "add" }, + { object: obj, name: "a", type: "update", oldValue: 4 }, + { object: obj, name: "a", type: "update", oldValue: 5 }, + { object: obj, name: "a", type: "reconfigure" }, + { object: obj, name: "a", type: "update", oldValue: 6 }, + { object: obj, name: "a", type: "reconfigure", oldValue: 8 }, + { object: obj, name: "a", type: "reconfigure", oldValue: 7 }, + { object: obj, name: "a", type: "reconfigure" }, + { object: obj, name: "a", type: "reconfigure" }, + { object: obj, name: "a", type: "reconfigure" }, + { object: obj, name: "a", type: "delete" }, + { object: obj, name: "a", type: "add" }, + { object: obj, name: "a", type: "reconfigure" }, + { object: obj, name: "a", type: "update", oldValue: 9 }, + { object: obj, name: "a", type: "update", oldValue: 10 }, + { object: obj, name: "a", type: "update", oldValue: 11 }, + { object: obj, name: "a", type: "update", oldValue: 12 }, + { object: obj, name: "a", type: "delete", oldValue: 36 }, + { object: obj, name: "a", type: "add" }, ]); @@ -776,28 +927,28 @@ delete obj[1]; Object.defineProperty(obj, "1", {value: 11, configurable: true}); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, name: "1", type: "updated", oldValue: 1 }, - { object: obj, name: "1", type: "updated", oldValue: 2 }, - { object: obj, name: "1", type: "deleted", oldValue: 3 }, - { object: obj, name: "1", type: "new" }, - { object: obj, name: "1", type: "updated", oldValue: 4 }, - { object: obj, name: "1", type: "updated", oldValue: 5 }, - { object: obj, name: "1", type: "reconfigured" }, - { object: obj, name: "1", type: "updated", oldValue: 6 }, - { object: obj, name: "1", type: "reconfigured", oldValue: 8 }, - { object: obj, name: "1", type: "reconfigured", oldValue: 7 }, - { object: obj, name: "1", type: "reconfigured" }, - { object: obj, name: "1", type: "reconfigured" }, - { object: obj, name: "1", type: "reconfigured" }, - { object: obj, name: "1", type: "deleted" }, - { object: obj, name: "1", type: "new" }, - { object: obj, name: "1", type: "reconfigured" }, - { object: obj, name: "1", type: "updated", oldValue: 9 }, - { object: obj, name: "1", type: "updated", oldValue: 10 }, - { object: obj, name: "1", type: "updated", oldValue: 11 }, - { object: obj, name: "1", type: "updated", oldValue: 12 }, - { object: obj, name: "1", type: "deleted", oldValue: 36 }, - { object: obj, name: "1", type: "new" }, + { object: obj, name: "1", type: "update", oldValue: 1 }, + { object: obj, name: "1", type: "update", oldValue: 2 }, + { object: obj, name: "1", type: "delete", oldValue: 3 }, + { object: obj, name: "1", type: "add" }, + { object: obj, name: "1", type: "update", oldValue: 4 }, + { object: obj, name: "1", type: "update", oldValue: 5 }, + { object: obj, name: "1", type: "reconfigure" }, + { object: obj, name: "1", type: "update", oldValue: 6 }, + { object: obj, name: "1", type: "reconfigure", oldValue: 8 }, + { object: obj, name: "1", type: "reconfigure", oldValue: 7 }, + { object: obj, name: "1", type: "reconfigure" }, + { object: obj, name: "1", type: "reconfigure" }, + { object: obj, name: "1", type: "reconfigure" }, + { object: obj, name: "1", type: "delete" }, + { object: obj, name: "1", type: "add" }, + { object: obj, name: "1", type: "reconfigure" }, + { object: obj, name: "1", type: "update", oldValue: 9 }, + { object: obj, name: "1", type: "update", oldValue: 10 }, + { object: obj, name: "1", type: "update", oldValue: 11 }, + { object: obj, name: "1", type: "update", oldValue: 12 }, + { object: obj, name: "1", type: "delete", oldValue: 36 }, + { object: obj, name: "1", type: "add" }, ]); @@ -865,32 +1016,32 @@ function TestObserveConfigurable(obj, prop) { Object.defineProperty(obj, prop, {value: 11, configurable: true}); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, name: prop, type: "updated", oldValue: 1 }, - { object: obj, name: prop, type: "updated", oldValue: 2 }, - { object: obj, name: prop, type: "deleted", oldValue: 3 }, - { object: obj, name: prop, type: "new" }, - { object: obj, name: prop, type: "updated", oldValue: 4 }, - { object: obj, name: prop, type: "updated", oldValue: 5 }, - { object: obj, name: prop, type: "reconfigured" }, - { object: obj, name: prop, type: "updated", oldValue: 6 }, - { object: obj, name: prop, type: "reconfigured", oldValue: 8 }, - { object: obj, name: prop, type: "reconfigured", oldValue: 7 }, - { object: obj, name: prop, type: "reconfigured" }, - { object: obj, name: prop, type: "reconfigured" }, - { object: obj, name: prop, type: "reconfigured" }, - { object: obj, name: prop, type: "reconfigured" }, - { object: obj, name: prop, type: "reconfigured" }, - { object: obj, name: prop, type: "deleted" }, - { object: obj, name: prop, type: "new" }, - { object: obj, name: prop, type: "deleted" }, - { object: obj, name: prop, type: "new" }, - { object: obj, name: prop, type: "reconfigured" }, - { object: obj, name: prop, type: "updated", oldValue: 9 }, - { object: obj, name: prop, type: "updated", oldValue: 10 }, - { object: obj, name: prop, type: "updated", oldValue: 11 }, - { object: obj, name: prop, type: "updated", oldValue: 12 }, - { object: obj, name: prop, type: "deleted", oldValue: 36 }, - { object: obj, name: prop, type: "new" }, + { object: obj, name: prop, type: "update", oldValue: 1 }, + { object: obj, name: prop, type: "update", oldValue: 2 }, + { object: obj, name: prop, type: "delete", oldValue: 3 }, + { object: obj, name: prop, type: "add" }, + { object: obj, name: prop, type: "update", oldValue: 4 }, + { object: obj, name: prop, type: "update", oldValue: 5 }, + { object: obj, name: prop, type: "reconfigure" }, + { object: obj, name: prop, type: "update", oldValue: 6 }, + { object: obj, name: prop, type: "reconfigure", oldValue: 8 }, + { object: obj, name: prop, type: "reconfigure", oldValue: 7 }, + { object: obj, name: prop, type: "reconfigure" }, + { object: obj, name: prop, type: "reconfigure" }, + { object: obj, name: prop, type: "reconfigure" }, + { object: obj, name: prop, type: "reconfigure" }, + { object: obj, name: prop, type: "reconfigure" }, + { object: obj, name: prop, type: "delete" }, + { object: obj, name: prop, type: "add" }, + { object: obj, name: prop, type: "delete" }, + { object: obj, name: prop, type: "add" }, + { object: obj, name: prop, type: "reconfigure" }, + { object: obj, name: prop, type: "update", oldValue: 9 }, + { object: obj, name: prop, type: "update", oldValue: 10 }, + { object: obj, name: prop, type: "update", oldValue: 11 }, + { object: obj, name: prop, type: "update", oldValue: 12 }, + { object: obj, name: prop, type: "delete", oldValue: 36 }, + { object: obj, name: prop, type: "add" }, ]); Object.unobserve(obj, observer.callback); delete obj[prop]; @@ -913,11 +1064,11 @@ function TestObserveNonConfigurable(obj, prop, desc) { obj[prop] = 7; // ignored Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, name: prop, type: "updated", oldValue: 1 }, - { object: obj, name: prop, type: "updated", oldValue: 4 }, - { object: obj, name: prop, type: "updated", oldValue: 5 }, - { object: obj, name: prop, type: "updated", oldValue: 6 }, - { object: obj, name: prop, type: "reconfigured" }, + { object: obj, name: prop, type: "update", oldValue: 1 }, + { object: obj, name: prop, type: "update", oldValue: 4 }, + { object: obj, name: prop, type: "update", oldValue: 5 }, + { object: obj, name: prop, type: "update", oldValue: 6 }, + { object: obj, name: prop, type: "reconfigure" }, ]); Object.unobserve(obj, observer.callback); } @@ -977,7 +1128,7 @@ var objects = [ createProxy(Proxy.create, null), createProxy(Proxy.createFunction, function(){}), ]; -var properties = ["a", "1", 1, "length", "prototype", "name", "caller"]; +var properties = ["a", "1", 1, "length", "setPrototype", "name", "caller"]; // Cases that yield non-standard results. function blacklisted(obj, prop) { @@ -1031,31 +1182,31 @@ arr3[4] = 5; Object.defineProperty(arr3, 'length', {value: 1, writable: false}); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: arr, name: '3', type: 'deleted', oldValue: 'd' }, - { object: arr, name: '2', type: 'deleted' }, - { object: arr, name: 'length', type: 'updated', oldValue: 4 }, - { object: arr, name: '1', type: 'deleted', oldValue: 'b' }, - { object: arr, name: 'length', type: 'updated', oldValue: 2 }, - { object: arr, name: 'length', type: 'updated', oldValue: 1 }, - { object: arr, name: 'length', type: 'reconfigured' }, - { object: arr2, name: '1', type: 'deleted', oldValue: 'beta' }, - { object: arr2, name: 'length', type: 'updated', oldValue: 2 }, - { object: arr2, name: 'length', type: 'reconfigured' }, - { object: arr3, name: '2', type: 'deleted', oldValue: 'goodbye' }, - { object: arr3, name: '0', type: 'deleted', oldValue: 'hello' }, - { object: arr3, name: 'length', type: 'updated', oldValue: 6 }, - { object: arr3, name: 'length', type: 'updated', oldValue: 0 }, - { object: arr3, name: 'length', type: 'updated', oldValue: 1 }, - { object: arr3, name: 'length', type: 'updated', oldValue: 2 }, - { object: arr3, name: 'length', type: 'updated', oldValue: 1 }, - { object: arr3, name: '4', type: 'new' }, - { object: arr3, name: '4', type: 'deleted', oldValue: 5 }, + { object: arr, name: '3', type: 'delete', oldValue: 'd' }, + { object: arr, name: '2', type: 'delete' }, + { object: arr, name: 'length', type: 'update', oldValue: 4 }, + { object: arr, name: '1', type: 'delete', oldValue: 'b' }, + { object: arr, name: 'length', type: 'update', oldValue: 2 }, + { object: arr, name: 'length', type: 'update', oldValue: 1 }, + { object: arr, name: 'length', type: 'reconfigure' }, + { object: arr2, name: '1', type: 'delete', oldValue: 'beta' }, + { object: arr2, name: 'length', type: 'update', oldValue: 2 }, + { object: arr2, name: 'length', type: 'reconfigure' }, + { object: arr3, name: '2', type: 'delete', oldValue: 'goodbye' }, + { object: arr3, name: '0', type: 'delete', oldValue: 'hello' }, + { object: arr3, name: 'length', type: 'update', oldValue: 6 }, + { object: arr3, name: 'length', type: 'update', oldValue: 0 }, + { object: arr3, name: 'length', type: 'update', oldValue: 1 }, + { object: arr3, name: 'length', type: 'update', oldValue: 2 }, + { object: arr3, name: 'length', type: 'update', oldValue: 1 }, + { object: arr3, name: '4', type: 'add' }, + { object: arr3, name: '4', type: 'delete', oldValue: 5 }, // TODO(rafaelw): It breaks spec compliance to get two records here. // When the TODO in v8natives.js::DefineArrayProperty is addressed // which prevents DefineProperty from over-writing the magic length // property, these will collapse into a single record. - { object: arr3, name: 'length', type: 'updated', oldValue: 5 }, - { object: arr3, name: 'length', type: 'reconfigured' } + { object: arr3, name: 'length', type: 'update', oldValue: 5 }, + { object: arr3, name: 'length', type: 'reconfigure' } ]); Object.deliverChangeRecords(observer2.callback); observer2.assertCallbackRecords([ @@ -1068,7 +1219,7 @@ observer2.assertCallbackRecords([ { object: arr3, type: 'splice', index: 1, removed: [], addedCount: 1 }, { object: arr3, type: 'splice', index: 1, removed: [,], addedCount: 0 }, { object: arr3, type: 'splice', index: 1, removed: [], addedCount: 4 }, - { object: arr3, name: '4', type: 'new' }, + { object: arr3, name: '4', type: 'add' }, { object: arr3, type: 'splice', index: 1, removed: [,,,5], addedCount: 0 } ]); @@ -1086,8 +1237,8 @@ Array.observe(slow_arr, slowSpliceCallback); slow_arr.length = 100; Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: slow_arr, name: '500000000', type: 'deleted', oldValue: 'hello' }, - { object: slow_arr, name: 'length', type: 'updated', oldValue: 1000000000 }, + { object: slow_arr, name: '500000000', type: 'delete', oldValue: 'hello' }, + { object: slow_arr, name: 'length', type: 'update', oldValue: 1000000000 }, ]); Object.deliverChangeRecords(slowSpliceCallback); assertEquals(spliceRecords.length, 1); @@ -1113,11 +1264,11 @@ for (var i = 0; i < 5; i++) { } Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, name: "a0", type: "new" }, - { object: obj, name: "a1", type: "new" }, - { object: obj, name: "a2", type: "new" }, - { object: obj, name: "a3", type: "new" }, - { object: obj, name: "a4", type: "new" }, + { object: obj, name: "a0", type: "add" }, + { object: obj, name: "a1", type: "add" }, + { object: obj, name: "a2", type: "add" }, + { object: obj, name: "a3", type: "add" }, + { object: obj, name: "a4", type: "add" }, ]); reset(); @@ -1128,11 +1279,11 @@ for (var i = 0; i < 5; i++) { } Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, name: "0", type: "new" }, - { object: obj, name: "1", type: "new" }, - { object: obj, name: "2", type: "new" }, - { object: obj, name: "3", type: "new" }, - { object: obj, name: "4", type: "new" }, + { object: obj, name: "0", type: "add" }, + { object: obj, name: "1", type: "add" }, + { object: obj, name: "2", type: "add" }, + { object: obj, name: "3", type: "add" }, + { object: obj, name: "4", type: "add" }, ]); @@ -1149,15 +1300,15 @@ Object.defineProperty(arr, '400', {get: function(){}}); arr[50] = 30; // no length change expected Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: arr, name: '3', type: 'new' }, - { object: arr, name: 'length', type: 'updated', oldValue: 3 }, - { object: arr, name: '100', type: 'new' }, - { object: arr, name: 'length', type: 'updated', oldValue: 4 }, - { object: arr, name: '200', type: 'new' }, - { object: arr, name: 'length', type: 'updated', oldValue: 101 }, - { object: arr, name: '400', type: 'new' }, - { object: arr, name: 'length', type: 'updated', oldValue: 201 }, - { object: arr, name: '50', type: 'new' }, + { object: arr, name: '3', type: 'add' }, + { object: arr, name: 'length', type: 'update', oldValue: 3 }, + { object: arr, name: '100', type: 'add' }, + { object: arr, name: 'length', type: 'update', oldValue: 4 }, + { object: arr, name: '200', type: 'add' }, + { object: arr, name: 'length', type: 'update', oldValue: 101 }, + { object: arr, name: '400', type: 'add' }, + { object: arr, name: 'length', type: 'update', oldValue: 201 }, + { object: arr, name: '50', type: 'add' }, ]); Object.deliverChangeRecords(observer2.callback); observer2.assertCallbackRecords([ @@ -1165,7 +1316,7 @@ observer2.assertCallbackRecords([ { object: arr, type: 'splice', index: 4, removed: [], addedCount: 97 }, { object: arr, type: 'splice', index: 101, removed: [], addedCount: 100 }, { object: arr, type: 'splice', index: 201, removed: [], addedCount: 200 }, - { object: arr, type: 'new', name: '50' }, + { object: arr, type: 'add', name: '50' }, ]); @@ -1182,12 +1333,12 @@ array.push(3, 4); array.push(5); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '2', type: 'new' }, - { object: array, name: 'length', type: 'updated', oldValue: 2 }, - { object: array, name: '3', type: 'new' }, - { object: array, name: 'length', type: 'updated', oldValue: 3 }, - { object: array, name: '4', type: 'new' }, - { object: array, name: 'length', type: 'updated', oldValue: 4 }, + { object: array, name: '2', type: 'add' }, + { object: array, name: 'length', type: 'update', oldValue: 2 }, + { object: array, name: '3', type: 'add' }, + { object: array, name: 'length', type: 'update', oldValue: 3 }, + { object: array, name: '4', type: 'add' }, + { object: array, name: 'length', type: 'update', oldValue: 4 }, ]); Object.deliverChangeRecords(observer2.callback); observer2.assertCallbackRecords([ @@ -1203,10 +1354,10 @@ array.pop(); array.pop(); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '1', type: 'deleted', oldValue: 2 }, - { object: array, name: 'length', type: 'updated', oldValue: 2 }, - { object: array, name: '0', type: 'deleted', oldValue: 1 }, - { object: array, name: 'length', type: 'updated', oldValue: 1 }, + { object: array, name: '1', type: 'delete', oldValue: 2 }, + { object: array, name: 'length', type: 'update', oldValue: 2 }, + { object: array, name: '0', type: 'delete', oldValue: 1 }, + { object: array, name: 'length', type: 'update', oldValue: 1 }, ]); // Shift @@ -1217,11 +1368,11 @@ array.shift(); array.shift(); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '0', type: 'updated', oldValue: 1 }, - { object: array, name: '1', type: 'deleted', oldValue: 2 }, - { object: array, name: 'length', type: 'updated', oldValue: 2 }, - { object: array, name: '0', type: 'deleted', oldValue: 2 }, - { object: array, name: 'length', type: 'updated', oldValue: 1 }, + { object: array, name: '0', type: 'update', oldValue: 1 }, + { object: array, name: '1', type: 'delete', oldValue: 2 }, + { object: array, name: 'length', type: 'update', oldValue: 2 }, + { object: array, name: '0', type: 'delete', oldValue: 2 }, + { object: array, name: 'length', type: 'update', oldValue: 1 }, ]); // Unshift @@ -1231,11 +1382,11 @@ Object.observe(array, observer.callback); array.unshift(3, 4); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '3', type: 'new' }, - { object: array, name: 'length', type: 'updated', oldValue: 2 }, - { object: array, name: '2', type: 'new' }, - { object: array, name: '0', type: 'updated', oldValue: 1 }, - { object: array, name: '1', type: 'updated', oldValue: 2 }, + { object: array, name: '3', type: 'add' }, + { object: array, name: 'length', type: 'update', oldValue: 2 }, + { object: array, name: '2', type: 'add' }, + { object: array, name: '0', type: 'update', oldValue: 1 }, + { object: array, name: '1', type: 'update', oldValue: 2 }, ]); // Splice @@ -1245,10 +1396,10 @@ Object.observe(array, observer.callback); array.splice(1, 1, 4, 5); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '3', type: 'new' }, - { object: array, name: 'length', type: 'updated', oldValue: 3 }, - { object: array, name: '1', type: 'updated', oldValue: 2 }, - { object: array, name: '2', type: 'updated', oldValue: 3 }, + { object: array, name: '3', type: 'add' }, + { object: array, name: 'length', type: 'update', oldValue: 3 }, + { object: array, name: '1', type: 'update', oldValue: 2 }, + { object: array, name: '2', type: 'update', oldValue: 3 }, ]); // Sort @@ -1261,11 +1412,11 @@ assertEquals(2, array[1]); assertEquals(3, array[2]); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '1', type: 'updated', oldValue: 2 }, - { object: array, name: '0', type: 'updated', oldValue: 3 }, - { object: array, name: '2', type: 'updated', oldValue: 1 }, - { object: array, name: '1', type: 'updated', oldValue: 3 }, - { object: array, name: '0', type: 'updated', oldValue: 2 }, + { object: array, name: '1', type: 'update', oldValue: 2 }, + { object: array, name: '0', type: 'update', oldValue: 3 }, + { object: array, name: '2', type: 'update', oldValue: 1 }, + { object: array, name: '1', type: 'update', oldValue: 3 }, + { object: array, name: '0', type: 'update', oldValue: 2 }, ]); // Splice emitted after Array mutation methods @@ -1347,9 +1498,9 @@ Object.observe(array, observer.callback); Array.prototype.push.call(array, 3, 4); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '2', type: 'new' }, - { object: array, name: '3', type: 'new' }, - { object: array, name: 'length', type: 'updated', oldValue: 2 }, + { object: array, name: '2', type: 'add' }, + { object: array, name: '3', type: 'add' }, + { object: array, name: 'length', type: 'update', oldValue: 2 }, ]); // Pop @@ -1362,10 +1513,10 @@ array.pop(); array.pop(); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '1', type: 'deleted', oldValue: 2 }, - { object: array, name: 'length', type: 'updated', oldValue: 2 }, - { object: array, name: '0', type: 'deleted', oldValue: 1 }, - { object: array, name: 'length', type: 'updated', oldValue: 1 }, + { object: array, name: '1', type: 'delete', oldValue: 2 }, + { object: array, name: 'length', type: 'update', oldValue: 2 }, + { object: array, name: '0', type: 'delete', oldValue: 1 }, + { object: array, name: 'length', type: 'update', oldValue: 1 }, ]); Object.deliverChangeRecords(observer2.callback); observer2.assertCallbackRecords([ @@ -1383,11 +1534,11 @@ array.shift(); array.shift(); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '0', type: 'updated', oldValue: 1 }, - { object: array, name: '1', type: 'deleted', oldValue: 2 }, - { object: array, name: 'length', type: 'updated', oldValue: 2 }, - { object: array, name: '0', type: 'deleted', oldValue: 2 }, - { object: array, name: 'length', type: 'updated', oldValue: 1 }, + { object: array, name: '0', type: 'update', oldValue: 1 }, + { object: array, name: '1', type: 'delete', oldValue: 2 }, + { object: array, name: 'length', type: 'update', oldValue: 2 }, + { object: array, name: '0', type: 'delete', oldValue: 2 }, + { object: array, name: 'length', type: 'update', oldValue: 1 }, ]); Object.deliverChangeRecords(observer2.callback); observer2.assertCallbackRecords([ @@ -1404,17 +1555,17 @@ array.unshift(3, 4); array.unshift(5); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '3', type: 'new' }, - { object: array, name: 'length', type: 'updated', oldValue: 2 }, - { object: array, name: '2', type: 'new' }, - { object: array, name: '0', type: 'updated', oldValue: 1 }, - { object: array, name: '1', type: 'updated', oldValue: 2 }, - { object: array, name: '4', type: 'new' }, - { object: array, name: 'length', type: 'updated', oldValue: 4 }, - { object: array, name: '3', type: 'updated', oldValue: 2 }, - { object: array, name: '2', type: 'updated', oldValue: 1 }, - { object: array, name: '1', type: 'updated', oldValue: 4 }, - { object: array, name: '0', type: 'updated', oldValue: 3 }, + { object: array, name: '3', type: 'add' }, + { object: array, name: 'length', type: 'update', oldValue: 2 }, + { object: array, name: '2', type: 'add' }, + { object: array, name: '0', type: 'update', oldValue: 1 }, + { object: array, name: '1', type: 'update', oldValue: 2 }, + { object: array, name: '4', type: 'add' }, + { object: array, name: 'length', type: 'update', oldValue: 4 }, + { object: array, name: '3', type: 'update', oldValue: 2 }, + { object: array, name: '2', type: 'update', oldValue: 1 }, + { object: array, name: '1', type: 'update', oldValue: 4 }, + { object: array, name: '0', type: 'update', oldValue: 3 }, ]); Object.deliverChangeRecords(observer2.callback); observer2.assertCallbackRecords([ @@ -1433,21 +1584,21 @@ array.splice(1, 2, 6, 7); // 5 6 7 array.splice(2, 0); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '4', type: 'new' }, - { object: array, name: 'length', type: 'updated', oldValue: 3 }, - { object: array, name: '3', type: 'new' }, - { object: array, name: '1', type: 'updated', oldValue: 2 }, - { object: array, name: '2', type: 'updated', oldValue: 3 }, - - { object: array, name: '0', type: 'updated', oldValue: 1 }, - { object: array, name: '1', type: 'updated', oldValue: 4 }, - { object: array, name: '2', type: 'updated', oldValue: 5 }, - { object: array, name: '4', type: 'deleted', oldValue: 3 }, - { object: array, name: '3', type: 'deleted', oldValue: 2 }, - { object: array, name: 'length', type: 'updated', oldValue: 5 }, - - { object: array, name: '1', type: 'updated', oldValue: 2 }, - { object: array, name: '2', type: 'updated', oldValue: 3 }, + { object: array, name: '4', type: 'add' }, + { object: array, name: 'length', type: 'update', oldValue: 3 }, + { object: array, name: '3', type: 'add' }, + { object: array, name: '1', type: 'update', oldValue: 2 }, + { object: array, name: '2', type: 'update', oldValue: 3 }, + + { object: array, name: '0', type: 'update', oldValue: 1 }, + { object: array, name: '1', type: 'update', oldValue: 4 }, + { object: array, name: '2', type: 'update', oldValue: 5 }, + { object: array, name: '4', type: 'delete', oldValue: 3 }, + { object: array, name: '3', type: 'delete', oldValue: 2 }, + { object: array, name: 'length', type: 'update', oldValue: 5 }, + + { object: array, name: '1', type: 'update', oldValue: 2 }, + { object: array, name: '2', type: 'update', oldValue: 3 }, ]); Object.deliverChangeRecords(observer2.callback); observer2.assertCallbackRecords([ @@ -1466,8 +1617,8 @@ Object.observe(array, observer.callback); array.splice(0, 1); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '0', type: 'deleted', oldValue: 0 }, - { object: array, name: 'length', type: 'updated', oldValue: 1}, + { object: array, name: '0', type: 'delete', oldValue: 0 }, + { object: array, name: 'length', type: 'update', oldValue: 1}, ]); @@ -1485,10 +1636,10 @@ obj.__proto__ = q; // the __proto__ accessor is gone // once we support observing the global object. Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: obj, name: '__proto__', type: 'prototype', + { object: obj, name: '__proto__', type: 'setPrototype', oldValue: Object.prototype }, - { object: obj, name: '__proto__', type: 'prototype', oldValue: p }, - { object: obj, name: '__proto__', type: 'new' }, + { object: obj, name: '__proto__', type: 'setPrototype', oldValue: p }, + { object: obj, name: '__proto__', type: 'add' }, ]); @@ -1507,7 +1658,7 @@ observer.assertRecordCount(3); // lazy creation of oldValue assertSame(fun, observer.records[0].object); assertEquals('prototype', observer.records[0].name); -assertEquals('updated', observer.records[0].type); +assertEquals('update', observer.records[0].type); // The only existing reference to the oldValue object is in this // record, so to test that lazy creation happened correctly // we compare its constructor to our function (one of the invariants @@ -1515,8 +1666,8 @@ assertEquals('updated', observer.records[0].type); assertSame(fun, observer.records[0].oldValue.constructor); observer.records.splice(0, 1); observer.assertCallbackRecords([ - { object: fun, name: 'prototype', type: 'updated', oldValue: myproto }, - { object: fun, name: 'prototype', type: 'updated', oldValue: 7 }, + { object: fun, name: 'prototype', type: 'update', oldValue: myproto }, + { object: fun, name: 'prototype', type: 'update', oldValue: 7 }, ]); // Function.prototype should not be observable except on the object itself @@ -1562,7 +1713,7 @@ function TestFastElements(prop, mutation, prepopulate, polymorphic, optimize) { setElement(arr, prop, 989898); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: arr, name: "" + prop, type: 'updated', oldValue: 5 } + { object: arr, name: "" + prop, type: 'update', oldValue: 5 } ]); } @@ -1619,7 +1770,7 @@ function TestFastElementsLength( var lengthRecord = observer.records[count]; assertSame(arr, lengthRecord.object); assertEquals('length', lengthRecord.name); - assertEquals('updated', lengthRecord.type); + assertEquals('update', lengthRecord.type); assertSame(oldSize, lengthRecord.oldValue); } } diff --git a/deps/v8/test/mjsunit/harmony/private.js b/deps/v8/test/mjsunit/harmony/private.js new file mode 100644 index 0000000000..09cf7f7408 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/private.js @@ -0,0 +1,324 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --harmony-symbols --harmony-collections +// Flags: --expose-gc --allow-natives-syntax + +var symbols = [] + +// Test different forms of constructor calls, all equivalent. +function TestNew() { + for (var i = 0; i < 2; ++i) { + for (var j = 0; j < 5; ++j) { + symbols.push(%CreatePrivateSymbol("66")) + symbols.push(Object(%CreatePrivateSymbol("66")).valueOf()) + } + gc() // Promote existing symbols and then allocate some more. + } +} +TestNew() + + +function TestType() { + for (var i in symbols) { + assertEquals("symbol", typeof symbols[i]) + assertTrue(typeof symbols[i] === "symbol") + assertTrue(%SymbolIsPrivate(symbols[i])) + assertEquals(null, %_ClassOf(symbols[i])) + assertEquals("Symbol", %_ClassOf(new Symbol(symbols[i]))) + assertEquals("Symbol", %_ClassOf(Object(symbols[i]))) + } +} +TestType() + + +function TestPrototype() { + for (var i in symbols) { + assertSame(Symbol.prototype, symbols[i].__proto__) + } +} +TestPrototype() + + +function TestConstructor() { + for (var i in symbols) { + assertSame(Symbol, symbols[i].__proto__.constructor) + } +} +TestConstructor() + + +function TestName() { + for (var i in symbols) { + var name = symbols[i].name + assertTrue(name === "66") + } +} +TestName() + + +function TestToString() { + for (var i in symbols) { + assertThrows(function() { String(symbols[i]) }, TypeError) + assertThrows(function() { symbols[i] + "" }, TypeError) + assertThrows(function() { symbols[i].toString() }, TypeError) + assertThrows(function() { (new Symbol(symbols[i])).toString() }, TypeError) + assertThrows(function() { Object(symbols[i]).toString() }, TypeError) + assertEquals("[object Symbol]", Object.prototype.toString.call(symbols[i])) + } +} +TestToString() + + +function TestToBoolean() { + for (var i in symbols) { + assertTrue(Boolean(symbols[i]).valueOf()) + assertFalse(!symbols[i]) + assertTrue(!!symbols[i]) + assertTrue(symbols[i] && true) + assertFalse(!symbols[i] && false) + assertTrue(!symbols[i] || true) + assertEquals(1, symbols[i] ? 1 : 2) + assertEquals(2, !symbols[i] ? 1 : 2) + if (!symbols[i]) assertUnreachable(); + if (symbols[i]) {} else assertUnreachable(); + } +} +TestToBoolean() + + +function TestToNumber() { + for (var i in symbols) { + assertSame(NaN, Number(symbols[i]).valueOf()) + assertSame(NaN, symbols[i] + 0) + } +} +TestToNumber() + + +function TestEquality() { + // Every symbol should equal itself, and non-strictly equal its wrapper. + for (var i in symbols) { + assertSame(symbols[i], symbols[i]) + assertEquals(symbols[i], symbols[i]) + assertTrue(Object.is(symbols[i], symbols[i])) + assertTrue(symbols[i] === symbols[i]) + assertTrue(symbols[i] == symbols[i]) + assertFalse(symbols[i] === new Symbol(symbols[i])) + assertFalse(new Symbol(symbols[i]) === symbols[i]) + assertTrue(symbols[i] == new Symbol(symbols[i])) + assertTrue(new Symbol(symbols[i]) == symbols[i]) + } + + // All symbols should be distinct. + for (var i = 0; i < symbols.length; ++i) { + for (var j = i + 1; j < symbols.length; ++j) { + assertFalse(Object.is(symbols[i], symbols[j])) + assertFalse(symbols[i] === symbols[j]) + assertFalse(symbols[i] == symbols[j]) + } + } + + // Symbols should not be equal to any other value (and the test terminates). + var values = [347, 1.275, NaN, "string", null, undefined, {}, function() {}] + for (var i in symbols) { + for (var j in values) { + assertFalse(symbols[i] === values[j]) + assertFalse(values[j] === symbols[i]) + assertFalse(symbols[i] == values[j]) + assertFalse(values[j] == symbols[i]) + } + } +} +TestEquality() + + +function TestGet() { + for (var i in symbols) { + assertThrows(function() { symbols[i].toString() }, TypeError) + assertEquals(symbols[i], symbols[i].valueOf()) + assertEquals(undefined, symbols[i].a) + assertEquals(undefined, symbols[i]["a" + "b"]) + assertEquals(undefined, symbols[i]["" + "1"]) + assertEquals(undefined, symbols[i][62]) + } +} +TestGet() + + +function TestSet() { + for (var i in symbols) { + symbols[i].toString = 0 + assertThrows(function() { symbols[i].toString() }, TypeError) + symbols[i].valueOf = 0 + assertEquals(symbols[i], symbols[i].valueOf()) + symbols[i].a = 0 + assertEquals(undefined, symbols[i].a) + symbols[i]["a" + "b"] = 0 + assertEquals(undefined, symbols[i]["a" + "b"]) + symbols[i][62] = 0 + assertEquals(undefined, symbols[i][62]) + } +} +TestSet() + + +function TestCollections() { + var set = new Set + var map = new Map + var weakmap = new WeakMap + for (var i in symbols) { + set.add(symbols[i]) + map.set(symbols[i], i) + weakmap.set(symbols[i], i) + } + assertEquals(symbols.length, set.size) + assertEquals(symbols.length, map.size) + for (var i in symbols) { + assertTrue(set.has(symbols[i])) + assertTrue(map.has(symbols[i])) + assertTrue(weakmap.has(symbols[i])) + assertEquals(i, map.get(symbols[i])) + assertEquals(i, weakmap.get(symbols[i])) + } + for (var i in symbols) { + assertTrue(set.delete(symbols[i])) + assertTrue(map.delete(symbols[i])) + assertTrue(weakmap.delete(symbols[i])) + } + assertEquals(0, set.size) + assertEquals(0, map.size) +} +TestCollections() + + + +function TestKeySet(obj) { + assertTrue(%HasFastProperties(obj)) + // Set the even symbols via assignment. + for (var i = 0; i < symbols.length; i += 2) { + obj[symbols[i]] = i + // Object should remain in fast mode until too many properties were added. + assertTrue(%HasFastProperties(obj) || i >= 30) + } +} + + +function TestKeyDefine(obj) { + // Set the odd symbols via defineProperty (as non-enumerable). + for (var i = 1; i < symbols.length; i += 2) { + Object.defineProperty(obj, symbols[i], {value: i, configurable: true}) + } +} + + +function TestKeyGet(obj) { + var obj2 = Object.create(obj) + for (var i in symbols) { + assertEquals(i|0, obj[symbols[i]]) + assertEquals(i|0, obj2[symbols[i]]) + } +} + + +function TestKeyHas() { + for (var i in symbols) { + assertTrue(symbols[i] in obj) + assertTrue(Object.hasOwnProperty.call(obj, symbols[i])) + } +} + + +function TestKeyEnum(obj) { + for (var name in obj) { + assertEquals("string", typeof name) + } +} + + +function TestKeyNames(obj) { + assertEquals(0, Object.keys(obj).length) + + var names = Object.getOwnPropertyNames(obj) + for (var i in names) { + assertEquals("string", typeof names[i]) + } +} + + +function TestKeyDescriptor(obj) { + for (var i in symbols) { + var desc = Object.getOwnPropertyDescriptor(obj, symbols[i]); + assertEquals(i|0, desc.value) + assertTrue(desc.configurable) + assertEquals(i % 2 == 0, desc.writable) + assertEquals(i % 2 == 0, desc.enumerable) + assertEquals(i % 2 == 0, + Object.prototype.propertyIsEnumerable.call(obj, symbols[i])) + } +} + + +function TestKeyDelete(obj) { + for (var i in symbols) { + delete obj[symbols[i]] + } + for (var i in symbols) { + assertEquals(undefined, Object.getOwnPropertyDescriptor(obj, symbols[i])) + } +} + + +var objs = [{}, [], Object.create(null), Object(1), new Map, function(){}] + +for (var i in objs) { + var obj = objs[i] + TestKeySet(obj) + TestKeyDefine(obj) + TestKeyGet(obj) + TestKeyHas(obj) + TestKeyEnum(obj) + TestKeyNames(obj) + TestKeyDescriptor(obj) + TestKeyDelete(obj) +} + + +function TestCachedKeyAfterScavenge() { + gc(); + // Keyed property lookup are cached. Hereby we assume that the keys are + // tenured, so that we only have to clear the cache between mark compacts, + // but not between scavenges. This must also apply for symbol keys. + var key = Symbol("key"); + var a = {}; + a[key] = "abc"; + + for (var i = 0; i < 100000; i++) { + a[key] += "a"; // Allocations cause a scavenge. + } +} +TestCachedKeyAfterScavenge(); diff --git a/deps/v8/test/mjsunit/harmony/promises.js b/deps/v8/test/mjsunit/harmony/promises.js new file mode 100644 index 0000000000..38ccd7fb2b --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/promises.js @@ -0,0 +1,791 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --harmony-promises --harmony-observation --allow-natives-syntax + +var asyncAssertsExpected = 0; + +function assertAsyncRan() { ++asyncAssertsExpected } + +function assertAsync(b, s) { + if (b) { + print(s, "succeeded") + } else { + %AbortJS(s + " FAILED!") // Simply throwing here will have no effect. + } + --asyncAssertsExpected +} + +function assertAsyncDone(iteration) { + var iteration = iteration || 0 + var dummy = {} + Object.observe(dummy, + function() { + if (asyncAssertsExpected === 0) + assertAsync(true, "all") + else if (iteration > 10) // Shouldn't take more. + assertAsync(false, "all") + else + assertAsyncDone(iteration + 1) + } + ) + dummy.dummy = dummy +} + + +(function() { + assertThrows(function() { Promise(function() {}) }, TypeError) +})(); + +(function() { + assertTrue(new Promise(function() {}) instanceof Promise) +})(); + +(function() { + assertThrows(function() { new Promise(5) }, TypeError) +})(); + +(function() { + assertDoesNotThrow(function() { new Promise(function() { throw 5 }) }) +})(); + +(function() { + (new Promise(function() { throw 5 })).chain( + assertUnreachable, + function(r) { assertAsync(r === 5, "new-throw") } + ) + assertAsyncRan() +})(); + +(function() { + Promise.resolve(5); + Promise.resolve(5).chain(undefined, assertUnreachable).chain( + function(x) { assertAsync(x === 5, "resolved/chain-nohandler") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + Promise.reject(5).chain(assertUnreachable, undefined).chain( + assertUnreachable, + function(r) { assertAsync(r === 5, "rejected/chain-nohandler") } + ) + assertAsyncRan() +})(); + +(function() { + Promise.resolve(5).then(undefined, assertUnreachable).chain( + function(x) { assertAsync(x === 5, "resolved/then-nohandler") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + Promise.reject(5).then(assertUnreachable, undefined).chain( + assertUnreachable, + function(r) { assertAsync(r === 5, "rejected/then-nohandler") } + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.chain( + function(x) { assertAsync(x === p2, "resolved/chain") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then( + function(x) { assertAsync(x === 5, "resolved/then") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.reject(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.chain( + function(x) { assertAsync(x === p2, "rejected/chain") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.reject(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then( + assertUnreachable, + function(x) { assertAsync(x === 5, "rejected/then") } + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.chain(function(x) { return x }, assertUnreachable).chain( + function(x) { assertAsync(x === p1, "resolved/chain/chain") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.chain(function(x) { return x }, assertUnreachable).then( + function(x) { assertAsync(x === 5, "resolved/chain/then") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.chain(function(x) { return 6 }, assertUnreachable).chain( + function(x) { assertAsync(x === 6, "resolved/chain/chain2") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.chain(function(x) { return 6 }, assertUnreachable).then( + function(x) { assertAsync(x === 6, "resolved/chain/then2") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then(function(x) { return x + 1 }, assertUnreachable).chain( + function(x) { assertAsync(x === 6, "resolved/then/chain") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then(function(x) { return x + 1 }, assertUnreachable).then( + function(x) { assertAsync(x === 6, "resolved/then/then") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then(function(x){ return Promise.resolve(x+1) }, assertUnreachable).chain( + function(x) { assertAsync(x === 6, "resolved/then/chain2") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then(function(x) { return Promise.resolve(x+1) }, assertUnreachable).then( + function(x) { assertAsync(x === 6, "resolved/then/then2") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.chain(function(x) { throw 6 }, assertUnreachable).chain( + assertUnreachable, + function(x) { assertAsync(x === 6, "resolved/chain-throw/chain") } + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.chain(function(x) { throw 6 }, assertUnreachable).then( + assertUnreachable, + function(x) { assertAsync(x === 6, "resolved/chain-throw/then") } + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then(function(x) { throw 6 }, assertUnreachable).chain( + assertUnreachable, + function(x) { assertAsync(x === 6, "resolved/then-throw/chain") } + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then(function(x) { throw 6 }, assertUnreachable).then( + assertUnreachable, + function(x) { assertAsync(x === 6, "resolved/then-throw/then") } + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} + var p3 = Promise.resolve(p2) + p3.chain( + function(x) { assertAsync(x === p2, "resolved/thenable/chain") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} + var p3 = Promise.resolve(p2) + p3.then( + function(x) { assertAsync(x === 5, "resolved/thenable/then") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.reject(5) + var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} + var p3 = Promise.resolve(p2) + p3.chain( + function(x) { assertAsync(x === p2, "rejected/thenable/chain") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.reject(5) + var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} + var p3 = Promise.resolve(p2) + p3.then( + assertUnreachable, + function(x) { assertAsync(x === 5, "rejected/thenable/then") } + ) + assertAsyncRan() +})(); + +(function() { + var deferred = Promise.defer() + var p1 = deferred.promise + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.chain( + function(x) { assertAsync(x === p2, "chain/resolve") }, + assertUnreachable + ) + deferred.resolve(5) + assertAsyncRan() +})(); + +(function() { + var deferred = Promise.defer() + var p1 = deferred.promise + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then( + function(x) { assertAsync(x === 5, "then/resolve") }, + assertUnreachable + ) + deferred.resolve(5) + assertAsyncRan() +})(); + +(function() { + var deferred = Promise.defer() + var p1 = deferred.promise + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.chain( + function(x) { assertAsync(x === p2, "chain/reject") }, + assertUnreachable + ) + deferred.reject(5) + assertAsyncRan() +})(); + +(function() { + var deferred = Promise.defer() + var p1 = deferred.promise + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then( + assertUnreachable, + function(x) { assertAsync(x === 5, "then/reject") } + ) + deferred.reject(5) + assertAsyncRan() +})(); + +(function() { + var deferred = Promise.defer() + var p1 = deferred.promise + var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} + var p3 = Promise.resolve(p2) + p3.chain( + function(x) { assertAsync(x === p2, "chain/resolve/thenable") }, + assertUnreachable + ) + deferred.resolve(5) + assertAsyncRan() +})(); + +(function() { + var deferred = Promise.defer() + var p1 = deferred.promise + var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} + var p3 = Promise.resolve(p2) + p3.then( + function(x) { assertAsync(x === 5, "then/resolve/thenable") }, + assertUnreachable + ) + deferred.resolve(5) + assertAsyncRan() +})(); + +(function() { + var deferred = Promise.defer() + var p1 = deferred.promise + var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} + var p3 = Promise.resolve(p2) + p3.chain( + function(x) { assertAsync(x === p2, "chain/reject/thenable") }, + assertUnreachable + ) + deferred.reject(5) + assertAsyncRan() +})(); + +(function() { + var deferred = Promise.defer() + var p1 = deferred.promise + var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} + var p3 = Promise.resolve(p2) + p3.then( + assertUnreachable, + function(x) { assertAsync(x === 5, "then/reject/thenable") } + ) + deferred.reject(5) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var deferred = Promise.defer() + var p3 = deferred.promise + p3.chain( + function(x) { assertAsync(x === p2, "chain/resolve2") }, + assertUnreachable + ) + deferred.resolve(p2) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var deferred = Promise.defer() + var p3 = deferred.promise + p3.then( + function(x) { assertAsync(x === 5, "then/resolve2") }, + assertUnreachable + ) + deferred.resolve(p2) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var deferred = Promise.defer() + var p3 = deferred.promise + p3.chain( + assertUnreachable, + function(x) { assertAsync(x === 5, "chain/reject2") } + ) + deferred.reject(5) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var deferred = Promise.defer() + var p3 = deferred.promise + p3.then( + assertUnreachable, + function(x) { assertAsync(x === 5, "then/reject2") } + ) + deferred.reject(5) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} + var deferred = Promise.defer() + var p3 = deferred.promise + p3.chain( + function(x) { assertAsync(x === p2, "chain/resolve/thenable2") }, + assertUnreachable + ) + deferred.resolve(p2) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(5) + var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} + var deferred = Promise.defer() + var p3 = deferred.promise + p3.then( + function(x) { assertAsync(x === 5, "then/resolve/thenable2") }, + assertUnreachable + ) + deferred.resolve(p2) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(0) + var p2 = p1.chain(function(x) { return p2 }, assertUnreachable) + p2.chain( + assertUnreachable, + function(r) { assertAsync(r instanceof TypeError, "cyclic/chain") } + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(0) + var p2 = p1.then(function(x) { return p2 }, assertUnreachable) + p2.chain( + assertUnreachable, + function(r) { assertAsync(r instanceof TypeError, "cyclic/then") } + ) + assertAsyncRan() +})(); + +(function() { + var deferred = Promise.defer() + var p = deferred.promise + deferred.resolve(p) + p.chain( + function(x) { assertAsync(x === p, "cyclic/deferred/chain") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var deferred = Promise.defer() + var p = deferred.promise + deferred.resolve(p) + p.then( + assertUnreachable, + function(r) { assertAsync(r instanceof TypeError, "cyclic/deferred/then") } + ) + assertAsyncRan() +})(); + +(function() { + Promise.all({get length() { throw 666 }}).chain( + assertUnreachable, + function(r) { assertAsync(r === 666, "all/no-array") } + ) + assertAsyncRan() +})(); + +(function() { + Promise.all([]).chain( + function(x) { assertAsync(x.length === 0, "all/resolve/empty") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var deferred1 = Promise.defer() + var p1 = deferred1.promise + var deferred2 = Promise.defer() + var p2 = deferred2.promise + var deferred3 = Promise.defer() + var p3 = deferred3.promise + Promise.all([p1, p2, p3]).chain( + function(x) { + assertAsync(x.length === 3, "all/resolve") + assertAsync(x[0] === 1, "all/resolve/0") + assertAsync(x[1] === 2, "all/resolve/1") + assertAsync(x[2] === 3, "all/resolve/2") + }, + assertUnreachable + ) + deferred1.resolve(1) + deferred3.resolve(3) + deferred2.resolve(2) + assertAsyncRan() + assertAsyncRan() + assertAsyncRan() + assertAsyncRan() +})(); + +(function() { + var deferred = Promise.defer() + var p1 = deferred.promise + var p2 = Promise.resolve(2) + var p3 = Promise.defer().promise + Promise.all([p1, p2, p3]).chain( + assertUnreachable, + assertUnreachable + ) + deferred.resolve(1) +})(); + +(function() { + var deferred1 = Promise.defer() + var p1 = deferred1.promise + var deferred2 = Promise.defer() + var p2 = deferred2.promise + var deferred3 = Promise.defer() + var p3 = deferred3.promise + Promise.all([p1, p2, p3]).chain( + assertUnreachable, + function(x) { assertAsync(x === 2, "all/reject") } + ) + deferred1.resolve(1) + deferred3.resolve(3) + deferred2.reject(2) + assertAsyncRan() +})(); + +(function() { + Promise.race([]).chain( + assertUnreachable, + assertUnreachable + ) +})(); + +(function() { + var p1 = Promise.resolve(1) + var p2 = Promise.resolve(2) + var p3 = Promise.resolve(3) + Promise.race([p1, p2, p3]).chain( + function(x) { assertAsync(x === 1, "resolved/one") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + var p1 = Promise.resolve(1) + var p2 = Promise.resolve(2) + var p3 = Promise.resolve(3) + Promise.race([0, p1, p2, p3]).chain( + function(x) { assertAsync(x === 0, "resolved-const/one") }, + assertUnreachable + ) + assertAsyncRan() +})(); + +(function() { + Promise.race({get length() { throw 666 }}).chain( + assertUnreachable, + function(r) { assertAsync(r === 666, "one/no-array") } + ) + assertAsyncRan() +})(); + +(function() { + var deferred1 = Promise.defer() + var p1 = deferred1.promise + var deferred2 = Promise.defer() + var p2 = deferred2.promise + var deferred3 = Promise.defer() + var p3 = deferred3.promise + Promise.race([p1, p2, p3]).chain( + function(x) { assertAsync(x === 3, "one/resolve") }, + assertUnreachable + ) + deferred3.resolve(3) + deferred1.resolve(1) + assertAsyncRan() +})(); + +(function() { + var deferred = Promise.defer() + var p1 = deferred.promise + var p2 = Promise.resolve(2) + var p3 = Promise.defer().promise + Promise.race([p1, p2, p3]).chain( + function(x) { assertAsync(x === 2, "resolved/one") }, + assertUnreachable + ) + deferred.resolve(1) + assertAsyncRan() +})(); + +(function() { + var deferred1 = Promise.defer() + var p1 = deferred1.promise + var deferred2 = Promise.defer() + var p2 = deferred2.promise + var deferred3 = Promise.defer() + var p3 = deferred3.promise + Promise.race([p1, p2, p3]).chain( + function(x) { assertAsync(x === 3, "one/resolve/reject") }, + assertUnreachable + ) + deferred3.resolve(3) + deferred1.reject(1) + assertAsyncRan() +})(); + +(function() { + var deferred1 = Promise.defer() + var p1 = deferred1.promise + var deferred2 = Promise.defer() + var p2 = deferred2.promise + var deferred3 = Promise.defer() + var p3 = deferred3.promise + Promise.race([p1, p2, p3]).chain( + assertUnreachable, + function(x) { assertAsync(x === 3, "one/reject/resolve") } + ) + deferred3.reject(3) + deferred1.resolve(1) + assertAsyncRan() +})(); + +(function() { + var log + function MyPromise(resolver) { + log += "n" + var promise = new Promise(function(resolve, reject) { + resolver( + function(x) { log += "x" + x; resolve(x) }, + function(r) { log += "r" + r; reject(r) } + ) + }) + promise.__proto__ = MyPromise.prototype + return promise + } + + MyPromise.__proto__ = Promise + MyPromise.defer = function() { + log += "d" + return this.__proto__.defer.call(this) + } + + MyPromise.prototype.__proto__ = Promise.prototype + MyPromise.prototype.chain = function(resolve, reject) { + log += "c" + return this.__proto__.__proto__.chain.call(this, resolve, reject) + } + + log = "" + var p1 = new MyPromise(function(resolve, reject) { resolve(1) }) + var p2 = new MyPromise(function(resolve, reject) { reject(2) }) + var d3 = MyPromise.defer() + assertTrue(d3.promise instanceof Promise, "subclass/instance") + assertTrue(d3.promise instanceof MyPromise, "subclass/instance-my3") + assertTrue(log === "nx1nr2dn", "subclass/create") + + log = "" + var p4 = MyPromise.resolve(4) + var p5 = MyPromise.reject(5) + assertTrue(p4 instanceof Promise, "subclass/instance4") + assertTrue(p4 instanceof MyPromise, "subclass/instance-my4") + assertTrue(p5 instanceof Promise, "subclass/instance5") + assertTrue(p5 instanceof MyPromise, "subclass/instance-my5") + d3.resolve(3) + assertTrue(log === "nx4nr5x3", "subclass/resolve") + + log = "" + var d6 = MyPromise.defer() + d6.promise.chain(function(x) { + return new Promise(function(resolve) { resolve(x) }) + }).chain(function() {}) + d6.resolve(6) + assertTrue(log === "dncncnx6", "subclass/chain") + + log = "" + Promise.all([11, Promise.resolve(12), 13, MyPromise.resolve(14), 15, 16]) + assertTrue(log === "nx14cn", "subclass/all/arg") + + log = "" + MyPromise.all([21, Promise.resolve(22), 23, MyPromise.resolve(24), 25, 26]) + assertTrue(log === "nx24nnx21cnnx23cncnnx25cnnx26cn", "subclass/all/self") +})(); + + +assertAsyncDone() diff --git a/deps/v8/test/mjsunit/harmony/proxies-function.js b/deps/v8/test/mjsunit/harmony/proxies-function.js index 6b8d098442..7b07d42423 100644 --- a/deps/v8/test/mjsunit/harmony/proxies-function.js +++ b/deps/v8/test/mjsunit/harmony/proxies-function.js @@ -53,8 +53,7 @@ var receiver function TestCall(isStrict, callTrap) { assertEquals(42, callTrap(5, 37)) - // TODO(rossberg): strict mode seems to be broken on x64... - // assertSame(isStrict ? undefined : global_object, receiver) + assertSame(isStrict ? undefined : global_object, receiver) var handler = { get: function(r, k) { @@ -67,8 +66,7 @@ function TestCall(isStrict, callTrap) { receiver = 333 assertEquals(42, f(11, 31)) - // TODO(rossberg): strict mode seems to be broken on x64... - // assertSame(isStrict ? undefined : global_object, receiver) + assertSame(isStrict ? undefined : global_object, receiver) receiver = 333 assertEquals(42, o.f(10, 32)) assertSame(o, receiver) @@ -746,3 +744,31 @@ function TestCalls() { TestCalls() */ + +var realms = [Realm.create(), Realm.create()]; +Realm.shared = {}; + +Realm.eval(realms[0], "function f() { return this; };"); +Realm.eval(realms[0], "Realm.shared.f = f;"); +Realm.eval(realms[0], "Realm.shared.fg = this;"); +Realm.eval(realms[1], "function g() { return this; };"); +Realm.eval(realms[1], "Realm.shared.g = g;"); +Realm.eval(realms[1], "Realm.shared.gg = this;"); + +var fp = Proxy.createFunction({}, Realm.shared.f); +var gp = Proxy.createFunction({}, Realm.shared.g); + +for (var i = 0; i < 10; i++) { + assertEquals(Realm.shared.fg, fp()); + assertEquals(Realm.shared.gg, gp()); + + with (this) { + assertEquals(this, fp()); + assertEquals(this, gp()); + } + + with ({}) { + assertEquals(Realm.shared.fg, fp()); + assertEquals(Realm.shared.gg, gp()); + } +} diff --git a/deps/v8/test/mjsunit/harmony/proxies.js b/deps/v8/test/mjsunit/harmony/proxies.js index f68e3bd157..d26ce1d149 100644 --- a/deps/v8/test/mjsunit/harmony/proxies.js +++ b/deps/v8/test/mjsunit/harmony/proxies.js @@ -25,7 +25,11 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --harmony-proxies +// We change the stack size for the A64 simulator because at one point this test +// enters an infinite recursion which goes through the runtime and we overflow +// the system stack before the simulator stack. + +// Flags: --harmony-proxies --sim-stack-size=500 // Helper. diff --git a/deps/v8/test/mjsunit/harmony/string-endswith.js b/deps/v8/test/mjsunit/harmony/string-endswith.js index 128cf1d023..cc76b5fe4e 100644 --- a/deps/v8/test/mjsunit/harmony/string-endswith.js +++ b/deps/v8/test/mjsunit/harmony/string-endswith.js @@ -1,4 +1,4 @@ -// Copyright 2013 the V8 project authors. All rights reserved. +// Copyright 2014 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -66,8 +66,6 @@ var TEST_INPUT = [{ }, { msg: "Boolean false", val: false }, { - msg: "Regular expression /\d+/", val: /\d+/ -}, { msg: "Empty array []", val: [] }, { msg: "Empty object {}", val: {} @@ -134,3 +132,281 @@ assertTrue("abc".endsWith("bc", undefined)); assertFalse("abc".endsWith("bc", -43)); assertFalse("abc".endsWith("bc", -Infinity)); assertFalse("abc".endsWith("bc", NaN)); + +// Test cases taken from +// https://github.com/mathiasbynens/String.prototype.endsWith/blob/master/tests/tests.js +Object.prototype[1] = 2; // try to break `arguments[1]` + +assertEquals(String.prototype.endsWith.length, 1); +assertEquals(String.prototype.propertyIsEnumerable("endsWith"), false); + +assertEquals("undefined".endsWith(), true); +assertEquals("undefined".endsWith(undefined), true); +assertEquals("undefined".endsWith(null), false); +assertEquals("null".endsWith(), false); +assertEquals("null".endsWith(undefined), false); +assertEquals("null".endsWith(null), true); + +assertEquals("abc".endsWith(), false); +assertEquals("abc".endsWith(""), true); +assertEquals("abc".endsWith("\0"), false); +assertEquals("abc".endsWith("c"), true); +assertEquals("abc".endsWith("b"), false); +assertEquals("abc".endsWith("ab"), false); +assertEquals("abc".endsWith("bc"), true); +assertEquals("abc".endsWith("abc"), true); +assertEquals("abc".endsWith("bcd"), false); +assertEquals("abc".endsWith("abcd"), false); +assertEquals("abc".endsWith("bcde"), false); + +assertEquals("abc".endsWith("", NaN), true); +assertEquals("abc".endsWith("\0", NaN), false); +assertEquals("abc".endsWith("c", NaN), false); +assertEquals("abc".endsWith("b", NaN), false); +assertEquals("abc".endsWith("ab", NaN), false); +assertEquals("abc".endsWith("bc", NaN), false); +assertEquals("abc".endsWith("abc", NaN), false); +assertEquals("abc".endsWith("bcd", NaN), false); +assertEquals("abc".endsWith("abcd", NaN), false); +assertEquals("abc".endsWith("bcde", NaN), false); + +assertEquals("abc".endsWith("", false), true); +assertEquals("abc".endsWith("\0", false), false); +assertEquals("abc".endsWith("c", false), false); +assertEquals("abc".endsWith("b", false), false); +assertEquals("abc".endsWith("ab", false), false); +assertEquals("abc".endsWith("bc", false), false); +assertEquals("abc".endsWith("abc", false), false); +assertEquals("abc".endsWith("bcd", false), false); +assertEquals("abc".endsWith("abcd", false), false); +assertEquals("abc".endsWith("bcde", false), false); + +assertEquals("abc".endsWith("", undefined), true); +assertEquals("abc".endsWith("\0", undefined), false); +assertEquals("abc".endsWith("c", undefined), true); +assertEquals("abc".endsWith("b", undefined), false); +assertEquals("abc".endsWith("ab", undefined), false); +assertEquals("abc".endsWith("bc", undefined), true); +assertEquals("abc".endsWith("abc", undefined), true); +assertEquals("abc".endsWith("bcd", undefined), false); +assertEquals("abc".endsWith("abcd", undefined), false); +assertEquals("abc".endsWith("bcde", undefined), false); + +assertEquals("abc".endsWith("", null), true); +assertEquals("abc".endsWith("\0", null), false); +assertEquals("abc".endsWith("c", null), false); +assertEquals("abc".endsWith("b", null), false); +assertEquals("abc".endsWith("ab", null), false); +assertEquals("abc".endsWith("bc", null), false); +assertEquals("abc".endsWith("abc", null), false); +assertEquals("abc".endsWith("bcd", null), false); +assertEquals("abc".endsWith("abcd", null), false); +assertEquals("abc".endsWith("bcde", null), false); + +assertEquals("abc".endsWith("", -Infinity), true); +assertEquals("abc".endsWith("\0", -Infinity), false); +assertEquals("abc".endsWith("c", -Infinity), false); +assertEquals("abc".endsWith("b", -Infinity), false); +assertEquals("abc".endsWith("ab", -Infinity), false); +assertEquals("abc".endsWith("bc", -Infinity), false); +assertEquals("abc".endsWith("abc", -Infinity), false); +assertEquals("abc".endsWith("bcd", -Infinity), false); +assertEquals("abc".endsWith("abcd", -Infinity), false); +assertEquals("abc".endsWith("bcde", -Infinity), false); + +assertEquals("abc".endsWith("", -1), true); +assertEquals("abc".endsWith("\0", -1), false); +assertEquals("abc".endsWith("c", -1), false); +assertEquals("abc".endsWith("b", -1), false); +assertEquals("abc".endsWith("ab", -1), false); +assertEquals("abc".endsWith("bc", -1), false); +assertEquals("abc".endsWith("abc", -1), false); +assertEquals("abc".endsWith("bcd", -1), false); +assertEquals("abc".endsWith("abcd", -1), false); +assertEquals("abc".endsWith("bcde", -1), false); + +assertEquals("abc".endsWith("", -0), true); +assertEquals("abc".endsWith("\0", -0), false); +assertEquals("abc".endsWith("c", -0), false); +assertEquals("abc".endsWith("b", -0), false); +assertEquals("abc".endsWith("ab", -0), false); +assertEquals("abc".endsWith("bc", -0), false); +assertEquals("abc".endsWith("abc", -0), false); +assertEquals("abc".endsWith("bcd", -0), false); +assertEquals("abc".endsWith("abcd", -0), false); +assertEquals("abc".endsWith("bcde", -0), false); + +assertEquals("abc".endsWith("", +0), true); +assertEquals("abc".endsWith("\0", +0), false); +assertEquals("abc".endsWith("c", +0), false); +assertEquals("abc".endsWith("b", +0), false); +assertEquals("abc".endsWith("ab", +0), false); +assertEquals("abc".endsWith("bc", +0), false); +assertEquals("abc".endsWith("abc", +0), false); +assertEquals("abc".endsWith("bcd", +0), false); +assertEquals("abc".endsWith("abcd", +0), false); +assertEquals("abc".endsWith("bcde", +0), false); + +assertEquals("abc".endsWith("", 1), true); +assertEquals("abc".endsWith("\0", 1), false); +assertEquals("abc".endsWith("c", 1), false); +assertEquals("abc".endsWith("b", 1), false); +assertEquals("abc".endsWith("ab", 1), false); +assertEquals("abc".endsWith("bc", 1), false); +assertEquals("abc".endsWith("abc", 1), false); +assertEquals("abc".endsWith("bcd", 1), false); +assertEquals("abc".endsWith("abcd", 1), false); +assertEquals("abc".endsWith("bcde", 1), false); + +assertEquals("abc".endsWith("", 2), true); +assertEquals("abc".endsWith("\0", 2), false); +assertEquals("abc".endsWith("c", 2), false); +assertEquals("abc".endsWith("b", 2), true); +assertEquals("abc".endsWith("ab", 2), true); +assertEquals("abc".endsWith("bc", 2), false); +assertEquals("abc".endsWith("abc", 2), false); +assertEquals("abc".endsWith("bcd", 2), false); +assertEquals("abc".endsWith("abcd", 2), false); +assertEquals("abc".endsWith("bcde", 2), false); + +assertEquals("abc".endsWith("", +Infinity), true); +assertEquals("abc".endsWith("\0", +Infinity), false); +assertEquals("abc".endsWith("c", +Infinity), true); +assertEquals("abc".endsWith("b", +Infinity), false); +assertEquals("abc".endsWith("ab", +Infinity), false); +assertEquals("abc".endsWith("bc", +Infinity), true); +assertEquals("abc".endsWith("abc", +Infinity), true); +assertEquals("abc".endsWith("bcd", +Infinity), false); +assertEquals("abc".endsWith("abcd", +Infinity), false); +assertEquals("abc".endsWith("bcde", +Infinity), false); + +assertEquals("abc".endsWith("", true), true); +assertEquals("abc".endsWith("\0", true), false); +assertEquals("abc".endsWith("c", true), false); +assertEquals("abc".endsWith("b", true), false); +assertEquals("abc".endsWith("ab", true), false); +assertEquals("abc".endsWith("bc", true), false); +assertEquals("abc".endsWith("abc", true), false); +assertEquals("abc".endsWith("bcd", true), false); +assertEquals("abc".endsWith("abcd", true), false); +assertEquals("abc".endsWith("bcde", true), false); + +assertEquals("abc".endsWith("", "x"), true); +assertEquals("abc".endsWith("\0", "x"), false); +assertEquals("abc".endsWith("c", "x"), false); +assertEquals("abc".endsWith("b", "x"), false); +assertEquals("abc".endsWith("ab", "x"), false); +assertEquals("abc".endsWith("bc", "x"), false); +assertEquals("abc".endsWith("abc", "x"), false); +assertEquals("abc".endsWith("bcd", "x"), false); +assertEquals("abc".endsWith("abcd", "x"), false); +assertEquals("abc".endsWith("bcde", "x"), false); + +assertEquals("[a-z]+(bar)?".endsWith("(bar)?"), true); +assertThrows(function() { "[a-z]+(bar)?".endsWith(/(bar)?/); +}, TypeError); +assertEquals("[a-z]+(bar)?".endsWith("[a-z]+", 6), true); +assertThrows(function() { "[a-z]+(bar)?".endsWith(/(bar)?/); +}, TypeError); +assertThrows(function() { "[a-z]+/(bar)?/".endsWith(/(bar)?/); +}, TypeError); + +// http://mathiasbynens.be/notes/javascript-unicode#poo-test +var string = "I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n\u2603\uD83D\uDCA9"; +assertEquals(string.endsWith(""), true); +assertEquals(string.endsWith("\xF1t\xEBr"), false); +assertEquals(string.endsWith("\xF1t\xEBr", 5), true); +assertEquals(string.endsWith("\xE0liz\xE6"), false); +assertEquals(string.endsWith("\xE0liz\xE6", 16), true); +assertEquals(string.endsWith("\xF8n\u2603\uD83D\uDCA9"), true); +assertEquals(string.endsWith("\xF8n\u2603\uD83D\uDCA9", 23), true); +assertEquals(string.endsWith("\u2603"), false); +assertEquals(string.endsWith("\u2603", 21), true); +assertEquals(string.endsWith("\uD83D\uDCA9"), true); +assertEquals(string.endsWith("\uD83D\uDCA9", 23), true); + +assertThrows(function() { + String.prototype.endsWith.call(undefined); +}, TypeError); +assertThrows(function() { + String.prototype.endsWith.call(undefined, "b"); +}, TypeError); +assertThrows(function() { + String.prototype.endsWith.call(undefined, "b", 4); +}, TypeError); +assertThrows(function() { + String.prototype.endsWith.call(null); +}, TypeError); +assertThrows(function() { + String.prototype.endsWith.call(null, "b"); +}, TypeError); +assertThrows(function() { + String.prototype.endsWith.call(null, "b", 4); +}, TypeError); +assertEquals(String.prototype.endsWith.call(42, "2"), true); +assertEquals(String.prototype.endsWith.call(42, "4"), false); +assertEquals(String.prototype.endsWith.call(42, "b", 4), false); +assertEquals(String.prototype.endsWith.call(42, "2", 1), false); +assertEquals(String.prototype.endsWith.call(42, "2", 4), true); +assertEquals(String.prototype.endsWith.call({ + "toString": function() { return "abc"; } +}, "b", 0), false); +assertEquals(String.prototype.endsWith.call({ + "toString": function() { return "abc"; } +}, "b", 1), false); +assertEquals(String.prototype.endsWith.call({ + "toString": function() { return "abc"; } +}, "b", 2), true); +assertThrows(function() { + String.prototype.endsWith.call({ + "toString": function() { throw RangeError(); } + }, /./); +}, RangeError); +assertThrows(function() { + String.prototype.endsWith.call({ + "toString": function() { return "abc"; } + }, /./); +}, TypeError); + +assertThrows(function() { + String.prototype.endsWith.apply(undefined); +}, TypeError); +assertThrows(function() { + String.prototype.endsWith.apply(undefined, ["b"]); }, +TypeError); +assertThrows(function() { + String.prototype.endsWith.apply(undefined, ["b", 4]); +}, TypeError); +assertThrows(function() { + String.prototype.endsWith.apply(null); +}, TypeError); +assertThrows(function() { + String.prototype.endsWith.apply(null, ["b"]); +}, TypeError); +assertThrows(function() { + String.prototype.endsWith.apply(null, ["b", 4]); +}, TypeError); +assertEquals(String.prototype.endsWith.apply(42, ["2"]), true); +assertEquals(String.prototype.endsWith.apply(42, ["4"]), false); +assertEquals(String.prototype.endsWith.apply(42, ["b", 4]), false); +assertEquals(String.prototype.endsWith.apply(42, ["2", 1]), false); +assertEquals(String.prototype.endsWith.apply(42, ["2", 4]), true); +assertEquals(String.prototype.endsWith.apply({ + "toString": function() { return "abc"; } +}, ["b", 0]), false); +assertEquals(String.prototype.endsWith.apply({ + "toString": function() { return "abc"; } +}, ["b", 1]), false); +assertEquals(String.prototype.endsWith.apply({ + "toString": function() { return "abc"; } +}, ["b", 2]), true); +assertThrows(function() { + String.prototype.endsWith.apply({ + "toString": function() { throw RangeError(); } + }, [/./]); +}, RangeError); +assertThrows(function() { + String.prototype.endsWith.apply({ + "toString": function() { return "abc"; } + }, [/./]); +}, TypeError); diff --git a/deps/v8/test/mjsunit/harmony/string-repeat.js b/deps/v8/test/mjsunit/harmony/string-repeat.js index 182e5c0e0e..761089b1d0 100644 --- a/deps/v8/test/mjsunit/harmony/string-repeat.js +++ b/deps/v8/test/mjsunit/harmony/string-repeat.js @@ -71,4 +71,4 @@ var myobj = { repeat : String.prototype.repeat }; assertEquals("abc", myobj.repeat(1)); -assertEquals("abcabc", myobj.repeat(2));
\ No newline at end of file +assertEquals("abcabc", myobj.repeat(2)); diff --git a/deps/v8/test/mjsunit/harmony/string-startswith.js b/deps/v8/test/mjsunit/harmony/string-startswith.js index 60c85d31b3..d72f2946f5 100644 --- a/deps/v8/test/mjsunit/harmony/string-startswith.js +++ b/deps/v8/test/mjsunit/harmony/string-startswith.js @@ -1,4 +1,4 @@ -// Copyright 2013 the V8 project authors. All rights reserved. +// Copyright 2014 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -66,8 +66,6 @@ var TEST_INPUT = [{ }, { msg: "Boolean false", val: false }, { - msg: "Regular expression /\d+/", val: /\d+/ -}, { msg: "Empty array []", val: [] }, { msg: "Empty object {}", val: {} @@ -133,3 +131,273 @@ assertTrue("abc".startsWith("ab", -43)); assertTrue("abc".startsWith("ab", -Infinity)); assertFalse("abc".startsWith("bc", -42)); assertFalse("abc".startsWith("bc", -Infinity)); + +// Test cases taken from +// https://github.com/mathiasbynens/String.prototype.startsWith/blob/master/tests/tests.js +Object.prototype[1] = 2; // try to break `arguments[1]` + +assertEquals(String.prototype.startsWith.length, 1); +assertEquals(String.prototype.propertyIsEnumerable("startsWith"), false); + +assertEquals("undefined".startsWith(), true); +assertEquals("undefined".startsWith(undefined), true); +assertEquals("undefined".startsWith(null), false); +assertEquals("null".startsWith(), false); +assertEquals("null".startsWith(undefined), false); +assertEquals("null".startsWith(null), true); + +assertEquals("abc".startsWith(), false); +assertEquals("abc".startsWith(""), true); +assertEquals("abc".startsWith("\0"), false); +assertEquals("abc".startsWith("a"), true); +assertEquals("abc".startsWith("b"), false); +assertEquals("abc".startsWith("ab"), true); +assertEquals("abc".startsWith("bc"), false); +assertEquals("abc".startsWith("abc"), true); +assertEquals("abc".startsWith("bcd"), false); +assertEquals("abc".startsWith("abcd"), false); +assertEquals("abc".startsWith("bcde"), false); + +assertEquals("abc".startsWith("", NaN), true); +assertEquals("abc".startsWith("\0", NaN), false); +assertEquals("abc".startsWith("a", NaN), true); +assertEquals("abc".startsWith("b", NaN), false); +assertEquals("abc".startsWith("ab", NaN), true); +assertEquals("abc".startsWith("bc", NaN), false); +assertEquals("abc".startsWith("abc", NaN), true); +assertEquals("abc".startsWith("bcd", NaN), false); +assertEquals("abc".startsWith("abcd", NaN), false); +assertEquals("abc".startsWith("bcde", NaN), false); + +assertEquals("abc".startsWith("", false), true); +assertEquals("abc".startsWith("\0", false), false); +assertEquals("abc".startsWith("a", false), true); +assertEquals("abc".startsWith("b", false), false); +assertEquals("abc".startsWith("ab", false), true); +assertEquals("abc".startsWith("bc", false), false); +assertEquals("abc".startsWith("abc", false), true); +assertEquals("abc".startsWith("bcd", false), false); +assertEquals("abc".startsWith("abcd", false), false); +assertEquals("abc".startsWith("bcde", false), false); + +assertEquals("abc".startsWith("", undefined), true); +assertEquals("abc".startsWith("\0", undefined), false); +assertEquals("abc".startsWith("a", undefined), true); +assertEquals("abc".startsWith("b", undefined), false); +assertEquals("abc".startsWith("ab", undefined), true); +assertEquals("abc".startsWith("bc", undefined), false); +assertEquals("abc".startsWith("abc", undefined), true); +assertEquals("abc".startsWith("bcd", undefined), false); +assertEquals("abc".startsWith("abcd", undefined), false); +assertEquals("abc".startsWith("bcde", undefined), false); + +assertEquals("abc".startsWith("", null), true); +assertEquals("abc".startsWith("\0", null), false); +assertEquals("abc".startsWith("a", null), true); +assertEquals("abc".startsWith("b", null), false); +assertEquals("abc".startsWith("ab", null), true); +assertEquals("abc".startsWith("bc", null), false); +assertEquals("abc".startsWith("abc", null), true); +assertEquals("abc".startsWith("bcd", null), false); +assertEquals("abc".startsWith("abcd", null), false); +assertEquals("abc".startsWith("bcde", null), false); + +assertEquals("abc".startsWith("", -Infinity), true); +assertEquals("abc".startsWith("\0", -Infinity), false); +assertEquals("abc".startsWith("a", -Infinity), true); +assertEquals("abc".startsWith("b", -Infinity), false); +assertEquals("abc".startsWith("ab", -Infinity), true); +assertEquals("abc".startsWith("bc", -Infinity), false); +assertEquals("abc".startsWith("abc", -Infinity), true); +assertEquals("abc".startsWith("bcd", -Infinity), false); +assertEquals("abc".startsWith("abcd", -Infinity), false); +assertEquals("abc".startsWith("bcde", -Infinity), false); + +assertEquals("abc".startsWith("", -1), true); +assertEquals("abc".startsWith("\0", -1), false); +assertEquals("abc".startsWith("a", -1), true); +assertEquals("abc".startsWith("b", -1), false); +assertEquals("abc".startsWith("ab", -1), true); +assertEquals("abc".startsWith("bc", -1), false); +assertEquals("abc".startsWith("abc", -1), true); +assertEquals("abc".startsWith("bcd", -1), false); +assertEquals("abc".startsWith("abcd", -1), false); +assertEquals("abc".startsWith("bcde", -1), false); + +assertEquals("abc".startsWith("", -0), true); +assertEquals("abc".startsWith("\0", -0), false); +assertEquals("abc".startsWith("a", -0), true); +assertEquals("abc".startsWith("b", -0), false); +assertEquals("abc".startsWith("ab", -0), true); +assertEquals("abc".startsWith("bc", -0), false); +assertEquals("abc".startsWith("abc", -0), true); +assertEquals("abc".startsWith("bcd", -0), false); +assertEquals("abc".startsWith("abcd", -0), false); +assertEquals("abc".startsWith("bcde", -0), false); + +assertEquals("abc".startsWith("", +0), true); +assertEquals("abc".startsWith("\0", +0), false); +assertEquals("abc".startsWith("a", +0), true); +assertEquals("abc".startsWith("b", +0), false); +assertEquals("abc".startsWith("ab", +0), true); +assertEquals("abc".startsWith("bc", +0), false); +assertEquals("abc".startsWith("abc", +0), true); +assertEquals("abc".startsWith("bcd", +0), false); +assertEquals("abc".startsWith("abcd", +0), false); +assertEquals("abc".startsWith("bcde", +0), false); + +assertEquals("abc".startsWith("", 1), true); +assertEquals("abc".startsWith("\0", 1), false); +assertEquals("abc".startsWith("a", 1), false); +assertEquals("abc".startsWith("b", 1), true); +assertEquals("abc".startsWith("ab", 1), false); +assertEquals("abc".startsWith("bc", 1), true); +assertEquals("abc".startsWith("abc", 1), false); +assertEquals("abc".startsWith("bcd", 1), false); +assertEquals("abc".startsWith("abcd", 1), false); +assertEquals("abc".startsWith("bcde", 1), false); + +assertEquals("abc".startsWith("", +Infinity), true); +assertEquals("abc".startsWith("\0", +Infinity), false); +assertEquals("abc".startsWith("a", +Infinity), false); +assertEquals("abc".startsWith("b", +Infinity), false); +assertEquals("abc".startsWith("ab", +Infinity), false); +assertEquals("abc".startsWith("bc", +Infinity), false); +assertEquals("abc".startsWith("abc", +Infinity), false); +assertEquals("abc".startsWith("bcd", +Infinity), false); +assertEquals("abc".startsWith("abcd", +Infinity), false); +assertEquals("abc".startsWith("bcde", +Infinity), false); + +assertEquals("abc".startsWith("", true), true); +assertEquals("abc".startsWith("\0", true), false); +assertEquals("abc".startsWith("a", true), false); +assertEquals("abc".startsWith("b", true), true); +assertEquals("abc".startsWith("ab", true), false); +assertEquals("abc".startsWith("bc", true), true); +assertEquals("abc".startsWith("abc", true), false); +assertEquals("abc".startsWith("bcd", true), false); +assertEquals("abc".startsWith("abcd", true), false); +assertEquals("abc".startsWith("bcde", true), false); + +assertEquals("abc".startsWith("", "x"), true); +assertEquals("abc".startsWith("\0", "x"), false); +assertEquals("abc".startsWith("a", "x"), true); +assertEquals("abc".startsWith("b", "x"), false); +assertEquals("abc".startsWith("ab", "x"), true); +assertEquals("abc".startsWith("bc", "x"), false); +assertEquals("abc".startsWith("abc", "x"), true); +assertEquals("abc".startsWith("bcd", "x"), false); +assertEquals("abc".startsWith("abcd", "x"), false); +assertEquals("abc".startsWith("bcde", "x"), false); + +assertEquals("[a-z]+(bar)?".startsWith("[a-z]+"), true); +assertThrows(function() { "[a-z]+(bar)?".startsWith(/[a-z]+/); }, TypeError); +assertEquals("[a-z]+(bar)?".startsWith("(bar)?", 6), true); +assertThrows(function() { "[a-z]+(bar)?".startsWith(/(bar)?/); }, TypeError); +assertThrows(function() { "[a-z]+/(bar)?/".startsWith(/(bar)?/); }, TypeError); + +// http://mathiasbynens.be/notes/javascript-unicode#poo-test +var string = "I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n\u2603\uD83D\uDCA9"; +assertEquals(string.startsWith(""), true); +assertEquals(string.startsWith("\xF1t\xEBr"), false); +assertEquals(string.startsWith("\xF1t\xEBr", 1), true); +assertEquals(string.startsWith("\xE0liz\xE6"), false); +assertEquals(string.startsWith("\xE0liz\xE6", 11), true); +assertEquals(string.startsWith("\xF8n\u2603\uD83D\uDCA9"), false); +assertEquals(string.startsWith("\xF8n\u2603\uD83D\uDCA9", 18), true); +assertEquals(string.startsWith("\u2603"), false); +assertEquals(string.startsWith("\u2603", 20), true); +assertEquals(string.startsWith("\uD83D\uDCA9"), false); +assertEquals(string.startsWith("\uD83D\uDCA9", 21), true); + +assertThrows(function() { + String.prototype.startsWith.call(undefined); +}, TypeError); +assertThrows(function() { + String.prototype.startsWith.call(undefined, "b"); +}, TypeError); +assertThrows(function() { + String.prototype.startsWith.call(undefined, "b", 4); +}, TypeError); +assertThrows(function() { + String.prototype.startsWith.call(null); +}, TypeError); +assertThrows(function() { + String.prototype.startsWith.call(null, "b"); +}, TypeError); +assertThrows(function() { + String.prototype.startsWith.call(null, "b", 4); +}, TypeError); +assertEquals(String.prototype.startsWith.call(42, "2"), false); +assertEquals(String.prototype.startsWith.call(42, "4"), true); +assertEquals(String.prototype.startsWith.call(42, "b", 4), false); +assertEquals(String.prototype.startsWith.call(42, "2", 1), true); +assertEquals(String.prototype.startsWith.call(42, "2", 4), false); +assertEquals(String.prototype.startsWith.call({ + "toString": function() { return "abc"; } +}, "b", 0), false); +assertEquals(String.prototype.startsWith.call({ + "toString": function() { return "abc"; } +}, "b", 1), true); +assertEquals(String.prototype.startsWith.call({ + "toString": function() { return "abc"; } +}, "b", 2), false); +assertThrows(function() { + String.prototype.startsWith.call({ + "toString": function() { throw RangeError(); } + }, /./); +}, RangeError); +assertThrows(function() { + String.prototype.startsWith.call({ + "toString": function() { return "abc"; } + }, /./); +}, TypeError); + +assertThrows(function() { + String.prototype.startsWith.apply(undefined); +}, TypeError); +assertThrows(function() { + String.prototype.startsWith.apply(undefined, ["b"]); +}, TypeError); +assertThrows(function() { + String.prototype.startsWith.apply(undefined, ["b", 4]); +}, TypeError); +assertThrows(function() { + String.prototype.startsWith.apply(null); +}, TypeError); +assertThrows(function() { + String.prototype.startsWith.apply(null, ["b"]); +}, TypeError); +assertThrows(function() { + String.prototype.startsWith.apply(null, ["b", 4]); +}, TypeError); +assertEquals(String.prototype.startsWith.apply(42, ["2"]), false); +assertEquals(String.prototype.startsWith.apply(42, ["4"]), true); +assertEquals(String.prototype.startsWith.apply(42, ["b", 4]), false); +assertEquals(String.prototype.startsWith.apply(42, ["2", 1]), true); +assertEquals(String.prototype.startsWith.apply(42, ["2", 4]), false); +assertEquals(String.prototype.startsWith.apply({ + "toString": function() { + return "abc"; + } +}, ["b", 0]), false); +assertEquals(String.prototype.startsWith.apply({ + "toString": function() { + return "abc"; + } +}, ["b", 1]), true); +assertEquals(String.prototype.startsWith.apply({ + "toString": function() { + return "abc"; + } +}, ["b", 2]), false); +assertThrows(function() { + String.prototype.startsWith.apply({ + "toString": function() { throw RangeError(); } + }, [/./]); +}, RangeError); +assertThrows(function() { + String.prototype.startsWith.apply({ + "toString": function() { return "abc"; } + }, [/./]); +}, TypeError); diff --git a/deps/v8/test/mjsunit/harmony/symbols.js b/deps/v8/test/mjsunit/harmony/symbols.js index 5eaa1a37d8..ce02a05ace 100644 --- a/deps/v8/test/mjsunit/harmony/symbols.js +++ b/deps/v8/test/mjsunit/harmony/symbols.js @@ -59,6 +59,7 @@ function TestType() { for (var i in symbols) { assertEquals("symbol", typeof symbols[i]) assertTrue(typeof symbols[i] === "symbol") + assertFalse(%SymbolIsPrivate(symbols[i])) assertEquals(null, %_ClassOf(symbols[i])) assertEquals("Symbol", %_ClassOf(new Symbol(symbols[i]))) assertEquals("Symbol", %_ClassOf(Object(symbols[i]))) @@ -272,7 +273,7 @@ function TestKeyGet(obj) { } -function TestKeyHas() { +function TestKeyHas(obj) { for (var i in symbols) { assertTrue(symbols[i] in obj) assertTrue(Object.hasOwnProperty.call(obj, symbols[i])) @@ -297,6 +298,15 @@ function TestKeyNames(obj) { } +function TestGetOwnPropertySymbols(obj) { + var syms = Object.getOwnPropertySymbols(obj) + assertEquals(syms.length, symbols.length) + for (var i in syms) { + assertEquals("symbol", typeof syms[i]) + } +} + + function TestKeyDescriptor(obj) { for (var i in symbols) { var desc = Object.getOwnPropertyDescriptor(obj, symbols[i]); @@ -330,6 +340,7 @@ for (var i in objs) { TestKeyHas(obj) TestKeyEnum(obj) TestKeyNames(obj) + TestGetOwnPropertySymbols(obj) TestKeyDescriptor(obj) TestKeyDelete(obj) } @@ -344,8 +355,49 @@ function TestCachedKeyAfterScavenge() { var a = {}; a[key] = "abc"; - for (var i = 0; i < 1000000; i++) { + for (var i = 0; i < 100000; i++) { a[key] += "a"; // Allocations cause a scavenge. } } TestCachedKeyAfterScavenge(); + + +function TestGetOwnPropertySymbolsWithProto() { + // We need to be have fast properties to have insertion order for property + // keys. The current limit is currently 30 properties. + var syms = symbols.slice(0, 30); + var proto = {} + var object = Object.create(proto) + for (var i = 0; i < syms.length; i++) { + // Even on object, odd on proto. + if (i % 2) { + proto[syms[i]] = i + } else { + object[syms[i]] = i + } + } + + assertTrue(%HasFastProperties(object)); + + var objectOwnSymbols = Object.getOwnPropertySymbols(object) + assertEquals(objectOwnSymbols.length, syms.length / 2) + + for (var i = 0; i < objectOwnSymbols.length; i++) { + assertEquals(objectOwnSymbols[i], syms[i * 2]) + } +} +TestGetOwnPropertySymbolsWithProto() + + +function TestGetOwnPropertySymbolsWithPrivateSymbols() { + var privateSymbol = %CreatePrivateSymbol("private") + var publicSymbol = Symbol() + var publicSymbol2 = Symbol() + var obj = {} + obj[publicSymbol] = 1 + obj[privateSymbol] = 2 + obj[publicSymbol2] = 3 + var syms = Object.getOwnPropertySymbols(obj) + assertEquals(syms, [publicSymbol, publicSymbol2]) +} +TestGetOwnPropertySymbolsWithPrivateSymbols() diff --git a/deps/v8/test/mjsunit/json2.js b/deps/v8/test/mjsunit/json2.js index cf20b909b4..0894d779ac 100644 --- a/deps/v8/test/mjsunit/json2.js +++ b/deps/v8/test/mjsunit/json2.js @@ -40,12 +40,13 @@ function TestStringify(expected, input) { var array_1 = []; var array_2 = []; -array_1[100000] = 1; -array_2[100000] = function() { return 1; }; -var nulls = ""; -for (var i = 0; i < 100000; i++) { - nulls += 'null,'; +array_1[1<<17] = 1; +array_2[1<<17] = function() { return 1; }; +var nulls = "null,"; +for (var i = 0; i < 17; i++) { + nulls += nulls; } + expected_1 = '[' + nulls + '1]'; expected_2 = '[' + nulls + 'null]'; TestStringify(expected_1, array_1); diff --git a/deps/v8/test/mjsunit/keyed-array-call.js b/deps/v8/test/mjsunit/keyed-array-call.js new file mode 100644 index 0000000000..b97da3cf1b --- /dev/null +++ b/deps/v8/test/mjsunit/keyed-array-call.js @@ -0,0 +1,56 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var a = [function(a) { return a+10; }, + function(a) { return a+20; }]; +a.__proto__.test = function(a) { return a+30; } +function f(i) { + return "r" + (1, a[i](i+1), a[i](i+2)); +} + +assertEquals("r12", f(0)); +assertEquals("r12", f(0)); +assertEquals("r23", f(1)); +assertEquals("r23", f(1)); + +// Deopt the stub. +assertEquals("rtest230", f("test")); + +var a2 = [function(a) { return a+10; },, + function(a) { return a+20; }]; +a2.__proto__.test = function(a) { return a+30; } +function f2(i) { + return "r" + (1, a2[i](i+1), a2[i](i+2)); +} + +assertEquals("r12", f2(0)); +assertEquals("r12", f2(0)); +assertEquals("r24", f2(2)); +assertEquals("r24", f2(2)); + +// Deopt the stub. This will throw given that undefined is not a function. +assertThrows(function() { f2(1) }); diff --git a/deps/v8/test/mjsunit/large-object-literal.js b/deps/v8/test/mjsunit/large-object-literal.js index 70a27696ba..47ba56e101 100644 --- a/deps/v8/test/mjsunit/large-object-literal.js +++ b/deps/v8/test/mjsunit/large-object-literal.js @@ -53,4 +53,3 @@ var sizes = [0, 1, 2, 100, 200, 400, 1000]; for (var i = 0; i < sizes.length; i++) { testLiteral(sizes[i]); } - diff --git a/deps/v8/test/mjsunit/limit-locals.js b/deps/v8/test/mjsunit/limit-locals.js index a166f30617..1d36c80e5d 100644 --- a/deps/v8/test/mjsunit/limit-locals.js +++ b/deps/v8/test/mjsunit/limit-locals.js @@ -34,9 +34,9 @@ function function_with_n_locals(n) { test_suffix = " suffix"; var src = "test_prefix + (function () {" for (var i = 1; i <= n; i++) { - src += "var x" + i + ";"; + src += "; var x" + i; } - src += "return " + n + ";})() + test_suffix"; + src += "; return " + n + ";})() + test_suffix"; return eval(src); } diff --git a/deps/v8/test/mjsunit/load-callback-from-value-classic.js b/deps/v8/test/mjsunit/load-callback-from-value-classic.js new file mode 100644 index 0000000000..0030c61cf8 --- /dev/null +++ b/deps/v8/test/mjsunit/load-callback-from-value-classic.js @@ -0,0 +1,38 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Object.defineProperty(Boolean.prototype, "v", + {get:function() { return this; }}); + +function f(b) { + return b.v; +} + +assertEquals("object", typeof f(true)); +assertEquals("object", typeof f(true)); +assertEquals("object", typeof f(true)); +assertEquals("object", typeof f(true)); diff --git a/deps/v8/test/mjsunit/local-load-from-eval.js b/deps/v8/test/mjsunit/local-load-from-eval.js index 0fdac9a791..e07cd0d574 100644 --- a/deps/v8/test/mjsunit/local-load-from-eval.js +++ b/deps/v8/test/mjsunit/local-load-from-eval.js @@ -36,4 +36,3 @@ test("assertEquals(27, x);"); test("(function() { assertEquals(27, x) })();"); test("(function() { var y = 42; eval('1'); assertEquals(42, y); })();"); test("(function() { var y = 42; eval('var y = 2; var z = 2;'); assertEquals(2, y); })();"); - diff --git a/deps/v8/test/mjsunit/math-floor-part1.js b/deps/v8/test/mjsunit/math-floor-part1.js index 313f27236a..b57b3e20dc 100644 --- a/deps/v8/test/mjsunit/math-floor-part1.js +++ b/deps/v8/test/mjsunit/math-floor-part1.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --max-new-space-size=256 --allow-natives-syntax +// Flags: --max-new-space-size=128 --allow-natives-syntax var test_id = 0; @@ -60,15 +60,19 @@ function test() { testFloor(0, 0.49999999999999994); testFloor(0, 0.5); testFloor(0, 0.7); + testFloor(0, 1.0 - Number.EPSILON); testFloor(-1, -0.1); testFloor(-1, -0.49999999999999994); testFloor(-1, -0.5); testFloor(-1, -0.7); testFloor(1, 1); testFloor(1, 1.1); + testFloor(1, 1.0 + Number.EPSILON); testFloor(1, 1.5); testFloor(1, 1.7); testFloor(-1, -1); + testFloor(-1, -1 + Number.EPSILON); + testFloor(-2, -1 - Number.EPSILON); testFloor(-2, -1.1); testFloor(-2, -1.5); testFloor(-2, -1.7); @@ -83,6 +87,7 @@ function test() { // Test in a loop to cover the custom IC and GC-related issues. -for (var i = 0; i < 100; i++) { +for (var i = 0; i < 10; i++) { test(); + new Array(i * 10000); } diff --git a/deps/v8/test/mjsunit/math-pow.js b/deps/v8/test/mjsunit/math-pow.js index fb5f8a1f90..ffbf418242 100644 --- a/deps/v8/test/mjsunit/math-pow.js +++ b/deps/v8/test/mjsunit/math-pow.js @@ -170,4 +170,4 @@ function test() { test(); test(); %OptimizeFunctionOnNextCall(test); -test();
\ No newline at end of file +test(); diff --git a/deps/v8/test/mjsunit/math-round.js b/deps/v8/test/mjsunit/math-round.js index 102c970f38..bf59069207 100644 --- a/deps/v8/test/mjsunit/math-round.js +++ b/deps/v8/test/mjsunit/math-round.js @@ -80,6 +80,15 @@ testRound(-9007199254740990, -9007199254740990); testRound(-9007199254740991, -9007199254740991); testRound(Number.MAX_VALUE, Number.MAX_VALUE); testRound(-Number.MAX_VALUE, -Number.MAX_VALUE); +testRound(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER); +testRound(Number.MAX_SAFE_INTEGER + 1, Number.MAX_SAFE_INTEGER + 1); +testRound(Number.MAX_SAFE_INTEGER + 2, Number.MAX_SAFE_INTEGER + 2); +testRound(Number.MAX_SAFE_INTEGER + 3, Number.MAX_SAFE_INTEGER + 3); +testRound(Number.MAX_SAFE_INTEGER + 4, Number.MAX_SAFE_INTEGER + 4); +testRound(Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER); +testRound(Number.MIN_SAFE_INTEGER - 1, Number.MIN_SAFE_INTEGER - 1); +testRound(Number.MIN_SAFE_INTEGER - 2, Number.MIN_SAFE_INTEGER - 2); +testRound(Number.MIN_SAFE_INTEGER - 3, Number.MIN_SAFE_INTEGER - 3); testRound(536870911, 536870910.5); testRound(536870911, 536870911); @@ -170,5 +179,3 @@ testRound(min_smi31, min_smi31 - 0.5); testRound(min_smi31 + 1, min_smi31 + 0.5); testRound(min_smi32, min_smi32 - 0.5); testRound(min_smi32 + 1, min_smi32 + 0.5); - - diff --git a/deps/v8/test/mjsunit/math-sqrt.js b/deps/v8/test/mjsunit/math-sqrt.js index 43fbf6b2dc..d5de2e97fe 100644 --- a/deps/v8/test/mjsunit/math-sqrt.js +++ b/deps/v8/test/mjsunit/math-sqrt.js @@ -50,4 +50,3 @@ test(-0, -0); test(Infinity, Infinity); // -Infinity is smaller than 0 so it should return NaN test(NaN, -Infinity); - diff --git a/deps/v8/test/mjsunit/mirror-boolean.js b/deps/v8/test/mjsunit/mirror-boolean.js index 311c781760..bbcec7325e 100644 --- a/deps/v8/test/mjsunit/mirror-boolean.js +++ b/deps/v8/test/mjsunit/mirror-boolean.js @@ -56,4 +56,4 @@ function testBooleanMirror(b) { // Test all boolean values. testBooleanMirror(true); -testBooleanMirror(false);
\ No newline at end of file +testBooleanMirror(false); diff --git a/deps/v8/test/mjsunit/mirror-undefined.js b/deps/v8/test/mjsunit/mirror-undefined.js index 7f63239e56..1d54b51b92 100644 --- a/deps/v8/test/mjsunit/mirror-undefined.js +++ b/deps/v8/test/mjsunit/mirror-undefined.js @@ -47,4 +47,4 @@ assertEquals('undefined', mirror.toText()); // Parse JSON representation and check. var fromJSON = eval('(' + json + ')'); -assertEquals('undefined', fromJSON.type);
\ No newline at end of file +assertEquals('undefined', fromJSON.type); diff --git a/deps/v8/test/mjsunit/mjsunit.js b/deps/v8/test/mjsunit/mjsunit.js index 129353730c..5f03774d75 100644 --- a/deps/v8/test/mjsunit/mjsunit.js +++ b/deps/v8/test/mjsunit/mjsunit.js @@ -54,6 +54,10 @@ var assertSame; // and the properties of non-Array objects). var assertEquals; + +// The difference between expected and found value is within certain tolerance. +var assertEqualsDelta; + // The found object is an Array with the same length and elements // as the expected object. The expected object doesn't need to be an Array, // as long as it's "array-ish". @@ -247,6 +251,12 @@ var assertUnoptimized; }; + assertEqualsDelta = + function assertEqualsDelta(expected, found, delta, name_opt) { + assertTrue(Math.abs(expected - found) <= delta, name_opt); + }; + + assertArrayEquals = function assertArrayEquals(expected, found, name_opt) { var start = ""; if (name_opt) { @@ -383,4 +393,3 @@ var assertUnoptimized; } })(); - diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status index 256bd3ecd4..4dcf7eec63 100644 --- a/deps/v8/test/mjsunit/mjsunit.status +++ b/deps/v8/test/mjsunit/mjsunit.status @@ -30,15 +30,10 @@ # All tests in the bug directory are expected to fail. 'bugs/*': [FAIL], - # TODO(mvstanton) Re-enable when the performance is bearable again. - 'regress/regress-2185-2': [SKIP], - ############################################################################## # Flaky tests. - # BUG(v8:2921): Flaky on ia32 nosnap, arm and nacl. - 'debug-step-4-in-frame': [PASS, [('system == linux and arch == ia32 or ' - 'arch == arm or arch == nacl_ia32 or ' - 'arch == nacl_x64'), FLAKY]], + # BUG(v8:2921). + 'debug-step-4-in-frame': [PASS, FAIL, SLOW], ############################################################################## # Fails. @@ -104,9 +99,106 @@ ############################################################################## # Long running test that reproduces memory leak and should be run manually. 'regress/regress-2073': [SKIP], + + ############################################################################## + # Tests verifying CHECK and ASSERT. + 'verify-check-false': [FAIL, NO_VARIANTS], + 'verify-assert-false': [NO_VARIANTS, ['mode == release', PASS], ['mode == debug', FAIL]], + + ############################################################################## + # Tests with different versions for release and debug. + 'compiler/alloc-number': [PASS, ['mode == debug', SKIP]], + 'compiler/alloc-number-debug': [PASS, ['mode == release', SKIP]], + 'regress/regress-634': [PASS, ['mode == debug', SKIP]], + 'regress/regress-634-debug': [PASS, ['mode == release', SKIP]], + + # BUG(336820). TODO(bmeurer): Investigate. + 'regress/regress-336820': [PASS, FAIL], + + # BUG(v8:2989). PASS/FAIL on linux32 because crankshaft is turned off for + # nosse2. Also for arm novfp3. + 'regress/regress-2989': [FAIL, NO_VARIANTS, ['system == linux and arch == ia32 or arch == arm and simulator == True', PASS]], }], # ALWAYS ############################################################################## +['gc_stress == True', { + # Skip tests not suitable for GC stress. + 'allocation-site-info': [SKIP], + 'array-constructor-feedback': [SKIP], + 'array-feedback': [SKIP], + 'array-literal-feedback': [SKIP], + 'd8-performance-now': [SKIP], + 'elements-kind': [SKIP], + 'fast-prototype': [SKIP], + 'opt-elements-kind': [SKIP], + 'osr-elements-kind': [SKIP], + 'regress/regress-165637': [SKIP], + 'regress/regress-2249': [SKIP], +}], # 'gc_stress == True' + +############################################################################## +['arch == a64', { + + # Requires bigger stack size in the Genesis and if stack size is increased, + # the test requires too much time to run. However, the problem test covers + # should be platform-independent. + 'regress/regress-1132': [SKIP], + + # Pass but take too long to run. Skip. + # Some similar tests (with fewer iterations) may be included in a64-js tests. + 'compiler/regress-arguments': [SKIP], + 'compiler/regress-gvn': [SKIP], + 'compiler/regress-max-locals-for-osr': [SKIP], + 'compiler/regress-4': [SKIP], + 'compiler/regress-or': [SKIP], + 'compiler/regress-rep-change': [SKIP], + 'regress/regress-1117': [SKIP], + 'regress/regress-1145': [SKIP], + 'regress/regress-1849': [SKIP], + 'regress/regress-3247124': [SKIP], + 'regress/regress-634': [SKIP], + 'regress/regress-91008': [SKIP], + 'regress/regress-91010': [SKIP], + 'regress/regress-91013': [SKIP], + 'regress/regress-99167': [SKIP], + + # Long running tests. + 'regress/regress-2185': [PASS, ['mode == debug', PASS, TIMEOUT]], + 'regress/regress-2185-2': [PASS, TIMEOUT], + 'whitespaces': [PASS, TIMEOUT], + + # Stack manipulations in LiveEdit is not implemented for this arch. + 'debug-liveedit-check-stack': [SKIP], + 'debug-liveedit-stack-padding': [SKIP], + 'debug-liveedit-restart-frame': [SKIP], + 'debug-liveedit-double-call': [SKIP], + + # BUG(v8:3147). It works on other architectures by accident. + 'regress/regress-conditional-position': [FAIL], + + # BUG(v8:3156): Fails on gc stress bots. + 'compiler/concurrent-invalidate-transition-map': [PASS, ['gc_stress == True', FAIL]], +}], # 'arch == a64' + +['arch == a64 and mode == debug and simulator_run == True', { + + # Pass but take too long with the simulator in debug mode. + 'array-sort': [PASS, TIMEOUT], + 'packed-elements': [SKIP], + 'regexp-global': [SKIP], + 'compiler/alloc-numbers': [SKIP], + 'harmony/symbols': [SKIP], +}], # 'arch == a64 and mode == debug and simulator_run == True' + +############################################################################## +['asan == True', { + # Skip tests not suitable for ASAN. + 'big-array-literal': [SKIP], + 'big-object-literal': [SKIP], + 'regress/regress-crbug-178790': [SKIP], +}], # 'asan == True' + +############################################################################## ['arch == arm or arch == android_arm', { # Slow tests which times out in debug mode. @@ -126,30 +218,12 @@ 'string-indexof-2': [PASS, TIMEOUT], 'mirror-object': [PASS, TIMEOUT], - # BUG(3251035): Timeouts in long looping crankshaft optimization - # tests. Skipping because having them timeout takes too long on the - # buildbot. + # Long running tests. Skipping because having them timeout takes too long on + # the buildbot. 'compiler/alloc-number': [SKIP], - 'compiler/array-length': [SKIP], - 'compiler/assignment-deopt': [SKIP], - 'compiler/deopt-args': [SKIP], - 'compiler/inline-compare': [SKIP], - 'compiler/inline-global-access': [SKIP], - 'compiler/optimized-function-calls': [SKIP], - 'compiler/pic': [SKIP], - 'compiler/property-calls': [SKIP], - 'compiler/recursive-deopt': [SKIP], - 'compiler/regress-4': [SKIP], - 'compiler/regress-funcaller': [SKIP], - 'compiler/regress-rep-change': [SKIP], - 'compiler/regress-arguments': [SKIP], - 'compiler/regress-funarguments': [SKIP], - 'compiler/regress-3249650': [SKIP], - 'compiler/simple-deopt': [SKIP], 'regress/regress-490': [SKIP], 'regress/regress-634': [SKIP], 'regress/regress-create-exception': [SKIP], - 'regress/regress-3218915': [SKIP], 'regress/regress-3247124': [SKIP], # Requires bigger stack size in the Genesis and if stack size is increased, @@ -165,6 +239,18 @@ # Currently always deopt on minus zero 'math-floor-of-div-minus-zero': [SKIP], + + ############################################################################ + # Slow tests. + 'regress/regress-2185-2': [PASS, SLOW], + 'mirror-object': [PASS, SLOW], + 'compiler/osr-with-args': [PASS, SLOW], + 'array-sort': [PASS, SLOW], + 'packed-elements': [PASS, SLOW], + 'regress/regress-91008': [PASS, SLOW], + 'regress/regress-2790': [PASS, SLOW], + 'regress/regress-json-stringify-gc': [PASS, SLOW], + 'regress/regress-1122': [PASS, SLOW], }], # 'arch == arm or arch == android_arm' ############################################################################## @@ -183,30 +269,12 @@ 'mirror-object': [PASS, TIMEOUT], 'string-indexof-2': [PASS, TIMEOUT], - # BUG(3251035): Timeouts in long looping crankshaft optimization - # tests. Skipping because having them timeout takes too long on the - # buildbot. + # Long running tests. Skipping because having them timeout takes too long on + # the buildbot. 'compiler/alloc-number': [SKIP], - 'compiler/array-length': [SKIP], - 'compiler/assignment-deopt': [SKIP], - 'compiler/deopt-args': [SKIP], - 'compiler/inline-compare': [SKIP], - 'compiler/inline-global-access': [SKIP], - 'compiler/optimized-function-calls': [SKIP], - 'compiler/pic': [SKIP], - 'compiler/property-calls': [SKIP], - 'compiler/recursive-deopt': [SKIP], - 'compiler/regress-4': [SKIP], - 'compiler/regress-funcaller': [SKIP], - 'compiler/regress-rep-change': [SKIP], - 'compiler/regress-arguments': [SKIP], - 'compiler/regress-funarguments': [SKIP], - 'compiler/regress-3249650': [SKIP], - 'compiler/simple-deopt': [SKIP], 'regress/regress-490': [SKIP], 'regress/regress-634': [SKIP], 'regress/regress-create-exception': [SKIP], - 'regress/regress-3218915': [SKIP], 'regress/regress-3247124': [SKIP], # Requires bigger stack size in the Genesis and if stack size is increased, diff --git a/deps/v8/test/mjsunit/mul-exhaustive-part6.js b/deps/v8/test/mjsunit/mul-exhaustive-part6.js index 91cb798a7d..fb2b2ce8e5 100644 --- a/deps/v8/test/mjsunit/mul-exhaustive-part6.js +++ b/deps/v8/test/mjsunit/mul-exhaustive-part6.js @@ -551,4 +551,4 @@ f(281475001876479, 8388609); f(562949903089665, 16777215); f(562949936644096, 16777216); f(562949970198527, 16777217); -f(1125899839733761, 33554431);
\ No newline at end of file +f(1125899839733761, 33554431); diff --git a/deps/v8/test/mjsunit/nans.js b/deps/v8/test/mjsunit/nans.js index d212afdeed..987ad6e78e 100644 --- a/deps/v8/test/mjsunit/nans.js +++ b/deps/v8/test/mjsunit/nans.js @@ -97,7 +97,3 @@ function TestFloatQuietNan() { } TestFloatQuietNan(); - - - - diff --git a/deps/v8/test/mjsunit/never-optimize.js b/deps/v8/test/mjsunit/never-optimize.js index 55b1f11981..643588ebf4 100644 --- a/deps/v8/test/mjsunit/never-optimize.js +++ b/deps/v8/test/mjsunit/never-optimize.js @@ -60,4 +60,4 @@ if (%GetOptimizationStatus(o1) != 4) { // 2 => not optimized. assertUnoptimized(u1); assertOptimized(u2); -}
\ No newline at end of file +} diff --git a/deps/v8/test/mjsunit/new-string-add.js b/deps/v8/test/mjsunit/new-string-add.js new file mode 100644 index 0000000000..f5b7cbfbf2 --- /dev/null +++ b/deps/v8/test/mjsunit/new-string-add.js @@ -0,0 +1,197 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --new-string-add + +assertEquals("ab", "a" + "b", "ll"); + +assertEquals("12", "1" + "2", "dd"); +assertEquals("123", "1" + "2" + "3", "ddd"); +assertEquals("123", 1 + "2" + "3", "ndd"); +assertEquals("123", "1" + 2 + "3", "dnd"); +assertEquals("123", "1" + "2" + 3, "ddn"); + +assertEquals("123", "1" + 2 + 3, "dnn"); +assertEquals("123", 1 + "2" + 3, "ndn"); +assertEquals("33", 1 + 2 + "3", "nnd"); + +var x = "1"; +assertEquals("12", x + 2, "vn"); +assertEquals("12", x + "2", "vd"); +assertEquals("21", 2 + x, "nv"); +assertEquals("21", "2" + x, "dv"); + +var y = "2"; +assertEquals("12", x + y, "vdvd"); + +x = 1; +assertEquals("12", x + y, "vnvd"); + +y = 2; +assertEquals(3, x + y, "vnvn"); + +x = "1"; +assertEquals("12", x + y, "vdvn"); + +y = "2"; +assertEquals("12", x + y, "vdvd2"); + +(function(x, y) { + var z = "3"; + var w = "4"; + + assertEquals("11", x + x, "xx"); + assertEquals("12", x + y, "xy"); + assertEquals("13", x + z, "xz"); + assertEquals("14", x + w, "xw"); + + assertEquals("21", y + x, "yx"); + assertEquals("22", y + y, "yy"); + assertEquals("23", y + z, "yz"); + assertEquals("24", y + w, "yw"); + + assertEquals("31", z + x, "zx"); + assertEquals("32", z + y, "zy"); + assertEquals("33", z + z, "zz"); + assertEquals("34", z + w, "zw"); + + assertEquals("41", w + x, "wx"); + assertEquals("42", w + y, "wy"); + assertEquals("43", w + z, "wz"); + assertEquals("44", w + w, "ww"); + + (function(){x = 1; z = 3;})(); + + assertEquals(2, x + x, "x'x"); + assertEquals("12", x + y, "x'y"); + assertEquals(4, x + z, "x'z'"); + assertEquals("14", x + w, "x'w"); + + assertEquals("21", y + x, "yx'"); + assertEquals("22", y + y, "yy"); + assertEquals("23", y + z, "yz'"); + assertEquals("24", y + w, "yw"); + + assertEquals(4, z + x, "z'x'"); + assertEquals("32", z + y, "z'y"); + assertEquals(6, z + z, "z'z'"); + assertEquals("34", z + w, "z'w"); + + assertEquals("41", w + x, "wx'"); + assertEquals("42", w + y, "wy"); + assertEquals("43", w + z, "wz'"); + assertEquals("44", w + w, "ww"); +})("1", "2"); + +assertEquals("142", "1" + new Number(42), "sN"); +assertEquals("421", new Number(42) + "1", "Ns"); +assertEquals(84, new Number(42) + new Number(42), "NN"); + +assertEquals("142", "1" + new String("42"), "sS"); +assertEquals("421", new String("42") + "1", "Ss"); +assertEquals("142", "1" + new String("42"), "sS"); +assertEquals("4242", new String("42") + new String("42"), "SS"); + +assertEquals("1true", "1" + true, "sb"); +assertEquals("true1", true + "1", "bs"); +assertEquals(2, true + true, "bs"); + +assertEquals("1true", "1" + new Boolean(true), "sB"); +assertEquals("true1", new Boolean(true) + "1", "Bs"); +assertEquals(2, new Boolean(true) + new Boolean(true), "Bs"); + +assertEquals("1undefined", "1" + void 0, "sv"); +assertEquals("undefined1", (void 0) + "1", "vs"); +assertTrue(isNaN(void 0 + void 0), "vv"); + +assertEquals("1null", "1" + null, "su"); +assertEquals("null1", null + "1", "us"); +assertEquals(0, null + null, "uu"); + +(function (i) { + // Check that incoming frames are merged correctly. + var x; + var y; + var z; + var w; + switch (i) { + case 1: x = 42; y = "stry"; z = "strz"; w = 42; break; + default: x = "strx", y = 42; z = "strz"; w = 42; break; + } + var resxx = x + x; + var resxy = x + y; + var resxz = x + z; + var resxw = x + w; + var resyx = y + x; + var resyy = y + y; + var resyz = y + z; + var resyw = y + w; + var reszx = z + x; + var reszy = z + y; + var reszz = z + z; + var reszw = z + w; + var reswx = w + x; + var reswy = w + y; + var reswz = w + z; + var resww = w + w; + assertEquals(84, resxx, "swxx"); + assertEquals("42stry", resxy, "swxy"); + assertEquals("42strz", resxz, "swxz"); + assertEquals(84, resxw, "swxw"); + assertEquals("stry42", resyx, "swyx"); + assertEquals("strystry", resyy, "swyy"); + assertEquals("strystrz", resyz, "swyz"); + assertEquals("stry42", resyw, "swyw"); + assertEquals("strz42", reszx, "swzx"); + assertEquals("strzstry", reszy, "swzy"); + assertEquals("strzstrz", reszz, "swzz"); + assertEquals("strz42", reszw, "swzw"); + assertEquals(84, reswx, "swwx"); + assertEquals("42stry", reswy, "swwy"); + assertEquals("42strz", reswz, "swwz"); + assertEquals(84, resww, "swww"); +})(1); + +// Generate ascii and non ascii strings from length 0 to 20. +var ascii = 'aaaaaaaaaaaaaaaaaaaa'; +var non_ascii = '\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234\u1234'; +assertEquals(20, ascii.length); +assertEquals(20, non_ascii.length); +var a = Array(21); +var b = Array(21); +for (var i = 0; i <= 20; i++) { + a[i] = ascii.substring(0, i); + b[i] = non_ascii.substring(0, i); +} + +// Add ascii and non-ascii strings generating strings with length from 0 to 20. +for (var i = 0; i <= 20; i++) { + for (var j = 0; j < i; j++) { + assertEquals(a[i], a[j] + a[i - j]) + assertEquals(b[i], b[j] + b[i - j]) + } +} diff --git a/deps/v8/test/mjsunit/new.js b/deps/v8/test/mjsunit/new.js index 1062628b20..ca098a12bd 100644 --- a/deps/v8/test/mjsunit/new.js +++ b/deps/v8/test/mjsunit/new.js @@ -53,4 +53,3 @@ x = new String('foo'); assertTrue(x === new Construct(x)); x = function() { }; assertTrue(x === new Construct(x)); - diff --git a/deps/v8/test/mjsunit/newline-in-string.js b/deps/v8/test/mjsunit/newline-in-string.js index 8c3ff86402..e71d8cf6a2 100644 --- a/deps/v8/test/mjsunit/newline-in-string.js +++ b/deps/v8/test/mjsunit/newline-in-string.js @@ -42,5 +42,3 @@ assertEquals('asdfasdf', eval(code)); // Allow LF+CR in multiline string literals. code = "'asdf\\" + String.fromCharCode(0xA) + String.fromCharCode(0xD) + "asdf'"; assertEquals('asdfasdf', eval(code)); - - diff --git a/deps/v8/test/mjsunit/number-is.js b/deps/v8/test/mjsunit/number-is.js index 1589fc64ad..53f0876786 100644 --- a/deps/v8/test/mjsunit/number-is.js +++ b/deps/v8/test/mjsunit/number-is.js @@ -25,11 +25,16 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Test Harmony Number.isFinite() and Number.isNaN() functions. +// Test number predicates that Harmony adds to the Number constructor: +// isFinite(), isNaN(), isInteger(), isSafeInteger(). assertTrue(Number.isFinite(0)); assertTrue(Number.isFinite(Number.MIN_VALUE)); assertTrue(Number.isFinite(Number.MAX_VALUE)); +assertTrue(Number.isFinite(Number.MIN_SAFE_INTEGER)); +assertTrue(Number.isFinite(Number.MIN_SAFE_INTEGER - 13)); +assertTrue(Number.isFinite(Number.MAX_SAFE_INTEGER)); +assertTrue(Number.isFinite(Number.MAX_SAFE_INTEGER + 23)); assertFalse(Number.isFinite(Number.NaN)); assertFalse(Number.isFinite(Number.POSITIVE_INFINITY)); assertFalse(Number.isFinite(Number.NEGATIVE_INFINITY)); @@ -45,9 +50,12 @@ assertFalse(Number.isFinite(undefined)); assertFalse(Number.isNaN(0)); assertFalse(Number.isNaN(Number.MIN_VALUE)); assertFalse(Number.isNaN(Number.MAX_VALUE)); +assertFalse(Number.isNaN(Number.MIN_SAFE_INTEGER - 13)); +assertFalse(Number.isNaN(Number.MAX_SAFE_INTEGER + 23)); assertTrue(Number.isNaN(Number.NaN)); assertFalse(Number.isNaN(Number.POSITIVE_INFINITY)); assertFalse(Number.isNaN(Number.NEGATIVE_INFINITY)); +assertFalse(Number.isNaN(Number.EPSILON)); assertFalse(Number.isNaN(new Number(0))); assertFalse(Number.isNaN(1/0)); assertFalse(Number.isNaN(-1/0)); @@ -56,3 +64,63 @@ assertFalse(Number.isNaN([])); assertFalse(Number.isNaN("s")); assertFalse(Number.isNaN(null)); assertFalse(Number.isNaN(undefined)); + +assertFalse(Number.isInteger({})); +assertFalse(Number.isInteger([])); +assertFalse(Number.isInteger("s")); +assertFalse(Number.isInteger(null)); +assertFalse(Number.isInteger(undefined)); +assertFalse(Number.isInteger(new Number(2))); +assertTrue(Number.isInteger(0)); +assertFalse(Number.isInteger(Number.MIN_VALUE)); +assertTrue(Number.isInteger(Number.MAX_VALUE)); +assertTrue(Number.isInteger(Number.MIN_SAFE_INTEGER)); +assertTrue(Number.isInteger(Number.MIN_SAFE_INTEGER - 13)); +assertTrue(Number.isInteger(Number.MAX_SAFE_INTEGER)); +assertTrue(Number.isInteger(Number.MAX_SAFE_INTEGER + 23)); +assertFalse(Number.isInteger(Number.NaN)); +assertFalse(Number.isInteger(Number.POSITIVE_INFINITY)); +assertFalse(Number.isInteger(Number.NEGATIVE_INFINITY)); +assertFalse(Number.isInteger(1/0)); +assertFalse(Number.isInteger(-1/0)); +assertFalse(Number.isInteger(Number.EPSILON)); + +assertFalse(Number.isSafeInteger({})); +assertFalse(Number.isSafeInteger([])); +assertFalse(Number.isSafeInteger("s")); +assertFalse(Number.isSafeInteger(null)); +assertFalse(Number.isSafeInteger(undefined)); +assertFalse(Number.isSafeInteger(new Number(2))); +assertTrue(Number.isSafeInteger(0)); +assertTrue(Number.isSafeInteger(Number.MIN_SAFE_INTEGER)); +assertFalse(Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 13)); +assertTrue(Number.isSafeInteger(Number.MIN_SAFE_INTEGER + 13)); +assertTrue(Number.isSafeInteger(Number.MAX_SAFE_INTEGER)); +assertFalse(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 23)); +assertTrue(Number.isSafeInteger(Number.MAX_SAFE_INTEGER - 23)); +assertFalse(Number.isSafeInteger(Number.MIN_VALUE)); +assertFalse(Number.isSafeInteger(Number.MAX_VALUE)); +assertFalse(Number.isSafeInteger(Number.NaN)); +assertFalse(Number.isSafeInteger(Number.POSITIVE_INFINITY)); +assertFalse(Number.isSafeInteger(Number.NEGATIVE_INFINITY)); +assertFalse(Number.isSafeInteger(1/0)); +assertFalse(Number.isSafeInteger(-1/0)); +assertFalse(Number.isSafeInteger(Number.EPSILON)); + +var near_upper = Math.pow(2, 52); +assertTrue(Number.isSafeInteger(near_upper)); +assertFalse(Number.isSafeInteger(2 * near_upper)); +assertTrue(Number.isSafeInteger(2 * near_upper - 1)); +assertTrue(Number.isSafeInteger(2 * near_upper - 2)); +assertFalse(Number.isSafeInteger(2 * near_upper + 1)); +assertFalse(Number.isSafeInteger(2 * near_upper + 2)); +assertFalse(Number.isSafeInteger(2 * near_upper + 7)); + +var near_lower = -near_upper; +assertTrue(Number.isSafeInteger(near_lower)); +assertFalse(Number.isSafeInteger(2 * near_lower)); +assertTrue(Number.isSafeInteger(2 * near_lower + 1)); +assertTrue(Number.isSafeInteger(2 * near_lower + 2)); +assertFalse(Number.isSafeInteger(2 * near_lower - 1)); +assertFalse(Number.isSafeInteger(2 * near_lower - 2)); +assertFalse(Number.isSafeInteger(2 * near_lower - 7)); diff --git a/deps/v8/test/mjsunit/number-tostring-func.js b/deps/v8/test/mjsunit/number-tostring-func.js index c64706e703..4fc97e5e0d 100644 --- a/deps/v8/test/mjsunit/number-tostring-func.js +++ b/deps/v8/test/mjsunit/number-tostring-func.js @@ -362,6 +362,3 @@ testToPrecision("-1.234e+4", Number(-12344.67), (4)); // dtoa does not do this in its original form. assertEquals("1.3", 1.25.toPrecision(2), "1.25.toPrecision(2)"); assertEquals("1.4", 1.35.toPrecision(2), "1.35.toPrecision(2)"); - - - diff --git a/deps/v8/test/mjsunit/number-tostring-small.js b/deps/v8/test/mjsunit/number-tostring-small.js index dbd2b59235..068b3a46e5 100644 --- a/deps/v8/test/mjsunit/number-tostring-small.js +++ b/deps/v8/test/mjsunit/number-tostring-small.js @@ -392,4 +392,3 @@ Number(-12344.67).toPrecision(4); (-91.1234).toPrecision(6); (-91.1234).toPrecision(7); (-91.1234).toPrecision(8); - diff --git a/deps/v8/test/mjsunit/number-tostring.js b/deps/v8/test/mjsunit/number-tostring.js index 35e77e2a69..55655f4082 100644 --- a/deps/v8/test/mjsunit/number-tostring.js +++ b/deps/v8/test/mjsunit/number-tostring.js @@ -335,6 +335,3 @@ assertEquals("-1.234e+4", Number(-12344.67).toPrecision(4)); // dtoa does not do this in its original form. assertEquals("1.3", 1.25.toPrecision(2), "1.25.toPrecision(2)"); assertEquals("1.4", 1.35.toPrecision(2), "1.35.toPrecision(2)"); - - - diff --git a/deps/v8/test/mjsunit/object-freeze.js b/deps/v8/test/mjsunit/object-freeze.js index a0717a171c..3b7987402f 100644 --- a/deps/v8/test/mjsunit/object-freeze.js +++ b/deps/v8/test/mjsunit/object-freeze.js @@ -314,3 +314,26 @@ assertTrue(%HasFastProperties(obj)); Object.freeze(obj); assertTrue(%HasFastProperties(obj)); assertTrue(Object.isFrozen(obj)); + +// Test array built-in functions with freeze. +obj = [1,2,3]; +Object.freeze(obj); +// if frozen implies sealed, then the tests in object-seal.js are mostly +// sufficient. +assertTrue(Object.isSealed(obj)); + +assertDoesNotThrow(function() { obj.push(); }); +assertDoesNotThrow(function() { obj.unshift(); }); +assertDoesNotThrow(function() { obj.splice(0,0); }); +assertTrue(Object.isFrozen(obj)); + +// Verify that an item can't be changed with splice. +assertThrows(function() { obj.splice(0,1,1); }, TypeError); + +// Verify that unshift() with no arguments will fail if it reifies from +// the prototype into the object. +obj = [1,,3]; +obj.__proto__[1] = 1; +assertEquals(1, obj[1]); +Object.freeze(obj); +assertThrows(function() { obj.unshift(); }, TypeError); diff --git a/deps/v8/test/mjsunit/object-literal-conversions.js b/deps/v8/test/mjsunit/object-literal-conversions.js index 742f814ba3..7db2cf519c 100644 --- a/deps/v8/test/mjsunit/object-literal-conversions.js +++ b/deps/v8/test/mjsunit/object-literal-conversions.js @@ -43,4 +43,3 @@ var test6 = { 17.31: function() {}, "17.31": 7 }; assertEquals(7, test5[13]); assertEquals(7, test6[17.31]); - diff --git a/deps/v8/test/mjsunit/object-literal-gc.js b/deps/v8/test/mjsunit/object-literal-gc.js index b9d6285cfe..ddbeef635b 100644 --- a/deps/v8/test/mjsunit/object-literal-gc.js +++ b/deps/v8/test/mjsunit/object-literal-gc.js @@ -63,4 +63,3 @@ var sizes = [0, 1, 2, 100, 200, 400, 1000]; for (var i = 0; i < sizes.length; i++) { testLiteral(sizes[i]); } - diff --git a/deps/v8/test/mjsunit/object-seal.js b/deps/v8/test/mjsunit/object-seal.js index f21baed377..3afddb9d60 100644 --- a/deps/v8/test/mjsunit/object-seal.js +++ b/deps/v8/test/mjsunit/object-seal.js @@ -28,6 +28,7 @@ // Tests the Object.seal and Object.isSealed methods - ES 15.2.3.9 and // ES 15.2.3.12 +// Flags: --allow-natives-syntax --noalways-opt // Test that we throw an error if an object is not passed as argument. var non_objects = new Array(undefined, null, 1, -1, 0, 42.43); @@ -192,3 +193,77 @@ assertFalse(Object.isSealed(obj4)); // Make sure that Object.seal returns the sealed object. var obj4 = {}; assertTrue(obj4 === Object.seal(obj4)); + +// +// Test that built-in array functions can't modify a sealed array. +// +obj = [1, 2, 3]; +var objControl = [4, 5, 6]; + +// Allow these functions to set up monomorphic calls, using custom built-ins. +var push_call = function(a) { a.push(10); return a; } +var pop_call = function(a) { return a.pop(); } +for (var i = 0; i < 3; i++) { + push_call(obj); + pop_call(obj); +} + +Object.seal(obj); +assertThrows(function() { push_call(obj); }, TypeError); +assertThrows(function() { pop_call(obj); }, TypeError); + +// But the control object is fine at these sites. +assertDoesNotThrow(function() { push_call(objControl); }); +assertDoesNotThrow(function() { pop_call(objControl); }); + +assertDoesNotThrow(function() { obj.push(); }); +assertThrows(function() { obj.push(3); }, TypeError); +assertThrows(function() { obj.pop(); }, TypeError); +assertThrows(function() { obj.shift(3); }, TypeError); +assertDoesNotThrow(function() { obj.unshift(); }); +assertThrows(function() { obj.unshift(1); }, TypeError); +assertThrows(function() { obj.splice(0, 0, 100, 101, 102); }, TypeError); +assertDoesNotThrow(function() { obj.splice(0,0); }); + +assertDoesNotThrow(function() { objControl.push(3); }); +assertDoesNotThrow(function() { objControl.pop(); }); +assertDoesNotThrow(function() { objControl.shift(3); }); +assertDoesNotThrow(function() { objControl.unshift(); }); +assertDoesNotThrow(function() { objControl.splice(0, 0, 100, 101, 102); }); + +// Verify that crankshaft still does the right thing. +obj = [1, 2, 3]; + +push_call = function(a) { a.push(1000); return a; } +// Include a call site that doesn't have a custom built-in. +var shift_call = function(a) { a.shift(1000); return a; } +for (var i = 0; i < 3; i++) { + push_call(obj); + shift_call(obj); +} + +%OptimizeFunctionOnNextCall(push_call); +%OptimizeFunctionOnNextCall(shift_call); +push_call(obj); +shift_call(obj); +assertOptimized(push_call); +assertOptimized(shift_call); +Object.seal(obj); +assertThrows(function() { push_call(obj); }, TypeError); +assertThrows(function() { shift_call(obj); }, TypeError); +assertUnoptimized(push_call); +assertUnoptimized(shift_call); +assertDoesNotThrow(function() { push_call(objControl); }); +assertDoesNotThrow(function() { shift_call(objControl); }); + +// Verify special behavior of splice on sealed objects. +obj = [1,2,3]; +Object.seal(obj); +assertDoesNotThrow(function() { obj.splice(0,1,100); }); +assertEquals(100, obj[0]); +assertDoesNotThrow(function() { obj.splice(0,2,1,2); }); +assertDoesNotThrow(function() { obj.splice(1,2,1,2); }); +// Count of items to delete is clamped by length. +assertDoesNotThrow(function() { obj.splice(1,2000,1,2); }); +assertThrows(function() { obj.splice(0,0,1); }, TypeError); +assertThrows(function() { obj.splice(1,2000,1,2,3); }, TypeError); diff --git a/deps/v8/test/mjsunit/opt-elements-kind.js b/deps/v8/test/mjsunit/opt-elements-kind.js index fe6b8b9bfb..f26bb42067 100644 --- a/deps/v8/test/mjsunit/opt-elements-kind.js +++ b/deps/v8/test/mjsunit/opt-elements-kind.js @@ -26,7 +26,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax --smi-only-arrays --expose-gc -// Flags: --notrack_allocation_sites // Limit the number of stress runs to reduce polymorphism it defeats some of the // assumptions made about how elements transitions work because transition stubs @@ -40,11 +39,6 @@ // in this test case. Depending on whether smi-only arrays are actually // enabled, this test takes the appropriate code path to check smi-only arrays. -// Reset the GC stress mode to be off. Needed because AllocationMementos only -// live for one gc, so a gc that happens in certain fragile areas of the test -// can break assumptions. -%SetFlags("--gc-interval=-1") - support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8)); if (support_smi_only_arrays) { @@ -114,8 +108,20 @@ function assertKind(expected, obj, name_opt) { } %NeverOptimizeFunction(construct_smis); + +// This code exists to eliminate the learning influence of AllocationSites +// on the following tests. +var __sequence = 0; +function make_array_string() { + this.__sequence = this.__sequence + 1; + return "/* " + this.__sequence + " */ [0, 0, 0];" +} +function make_array() { + return eval(make_array_string()); +} + function construct_smis() { - var a = [0, 0, 0]; + var a = make_array(); a[0] = 0; // Send the COW array map to the steak house. assertKind(elements_kind.fast_smi_only, a); return a; diff --git a/deps/v8/test/mjsunit/osr-elements-kind.js b/deps/v8/test/mjsunit/osr-elements-kind.js index 8d43377321..2ad3c43487 100644 --- a/deps/v8/test/mjsunit/osr-elements-kind.js +++ b/deps/v8/test/mjsunit/osr-elements-kind.js @@ -26,7 +26,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax --smi-only-arrays --expose-gc -// Flags: --notrack_allocation_sites // Limit the number of stress runs to reduce polymorphism it defeats some of the // assumptions made about how elements transitions work because transition stubs @@ -40,11 +39,6 @@ // in this test case. Depending on whether smi-only arrays are actually // enabled, this test takes the appropriate code path to check smi-only arrays. -// Reset the GC stress mode to be off. Needed because AllocationMementos only -// live for one gc, so a gc that happens in certain fragile areas of the test -// can break assumptions. -%SetFlags("--gc-interval=-1") - support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8)); if (support_smi_only_arrays) { @@ -120,8 +114,19 @@ function assertKind(expected, obj, name_opt) { for (var i = 0; i < 1000000; i++) { } if (support_smi_only_arrays) { + // This code exists to eliminate the learning influence of AllocationSites + // on the following tests. + var __sequence = 0; + function make_array_string() { + this.__sequence = this.__sequence + 1; + return "/* " + this.__sequence + " */ [0, 0, 0];" + } + function make_array() { + return eval(make_array_string()); + } + function construct_smis() { - var a = [0, 0, 0]; + var a = make_array(); a[0] = 0; // Send the COW array map to the steak house. assertKind(elements_kind.fast_smi_only, a); return a; diff --git a/deps/v8/test/mjsunit/packed-elements.js b/deps/v8/test/mjsunit/packed-elements.js index cfcdf8031f..4a87373064 100644 --- a/deps/v8/test/mjsunit/packed-elements.js +++ b/deps/v8/test/mjsunit/packed-elements.js @@ -109,4 +109,3 @@ if (has_packed_elements) { test_with_optimization(test5); test_with_optimization(test6); } - diff --git a/deps/v8/test/mjsunit/parse-int-float.js b/deps/v8/test/mjsunit/parse-int-float.js index 5a9b6f33cc..a0f5039230 100644 --- a/deps/v8/test/mjsunit/parse-int-float.js +++ b/deps/v8/test/mjsunit/parse-int-float.js @@ -114,3 +114,12 @@ assertEquals(state, "throwingString"); state = null; try { parseInt(throwingString, throwingRadix); } catch (e) {} assertEquals(state, "throwingString"); + +// And finally, check that the Harmony additions to the Number +// constructor is available: +assertTrue("parseInt" in Number); +assertTrue("parseFloat" in Number); +assertSame( Number.parseInt, parseInt); +assertSame(Number.parseFloat, parseFloat); +assertEquals(Number.parseFloat('0.1'), parseFloat('0.1')); +assertEquals(Number.parseInt('0xea'), parseInt('0xEA')); diff --git a/deps/v8/test/mjsunit/property-object-key.js b/deps/v8/test/mjsunit/property-object-key.js index 5eb1e1b9ec..3556cb9ee2 100644 --- a/deps/v8/test/mjsunit/property-object-key.js +++ b/deps/v8/test/mjsunit/property-object-key.js @@ -33,4 +33,3 @@ object[key] = 87; assertEquals(87, object[key]); object[key]++; assertEquals(88, object[key]); - diff --git a/deps/v8/test/mjsunit/proto-accessor.js b/deps/v8/test/mjsunit/proto-accessor.js new file mode 100644 index 0000000000..aca6ec5428 --- /dev/null +++ b/deps/v8/test/mjsunit/proto-accessor.js @@ -0,0 +1,81 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__"); +assertEquals("function", typeof desc.get); +assertEquals("function", typeof desc.set); +assertDoesNotThrow("desc.get.call({})"); +assertDoesNotThrow("desc.set.call({}, {})"); + + +var obj = {}; +var obj2 = {}; +desc.set.call(obj, obj2); +assertEquals(obj.__proto__, obj2); +assertEquals(desc.get.call(obj), obj2); + + +// Check that any redefinition of the __proto__ accessor works. +Object.defineProperty(Object.prototype, "__proto__", { + get: function() { + return 42; + } +}); +assertEquals({}.__proto__, 42); +assertEquals(desc.get.call({}), Object.prototype); + + +var desc2 = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__"); +assertEquals(desc2.get.call({}), 42); +assertDoesNotThrow("desc2.set.call({})"); + + +Object.defineProperty(Object.prototype, "__proto__", { set:function(x){} }); +var desc3 = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__"); +assertDoesNotThrow("desc3.get.call({})"); +assertDoesNotThrow("desc3.set.call({})"); + + +Object.defineProperty(Object.prototype, "__proto__", { set: undefined }); +assertThrows(function() { + "use strict"; + var o = {}; + var p = {}; + o.__proto__ = p; +}, TypeError); + + +assertTrue(delete Object.prototype.__proto__); +var o = {}; +var p = {}; +o.__proto__ = p; +assertEquals(Object.getPrototypeOf(o), Object.prototype); +var desc4 = Object.getOwnPropertyDescriptor(o, "__proto__"); +assertTrue(desc4.configurable); +assertTrue(desc4.enumerable); +assertTrue(desc4.writable); +assertEquals(desc4.value, p); diff --git a/deps/v8/test/mjsunit/prototype.js b/deps/v8/test/mjsunit/prototype.js index bfc1a799d4..a953422c32 100644 --- a/deps/v8/test/mjsunit/prototype.js +++ b/deps/v8/test/mjsunit/prototype.js @@ -89,5 +89,3 @@ var test = new Object; test.__proto__ = (new Array()).__proto__; test.length = 14; assertEquals(14, test.length); - - diff --git a/deps/v8/test/mjsunit/recursive-store-opt.js b/deps/v8/test/mjsunit/recursive-store-opt.js new file mode 100644 index 0000000000..fb2649248d --- /dev/null +++ b/deps/v8/test/mjsunit/recursive-store-opt.js @@ -0,0 +1,41 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function g() { + this.x = this; +} + +function f() { + return new g(); +} + +f(); +f(); +%OptimizeFunctionOnNextCall(f); +f(); diff --git a/deps/v8/test/mjsunit/regexp-indexof.js b/deps/v8/test/mjsunit/regexp-indexof.js index a504dd8d57..09f2fec007 100644 --- a/deps/v8/test/mjsunit/regexp-indexof.js +++ b/deps/v8/test/mjsunit/regexp-indexof.js @@ -74,4 +74,4 @@ CheckMatch(/a(.)/g, "xyzzyabxyzzyacxyzzy", [[5, 2], [12, 2]]); CheckMatch(/a|(?:)/g, "aba", [[0, 1], [1, 0], [2, 1], [3, 0]]); CheckMatch(/a|(?:)/g, "baba", [[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]); -CheckMatch(/a|(?:)/g, "bab", [[0, 0], [1, 1], [2, 0], [3, 0]]);
\ No newline at end of file +CheckMatch(/a|(?:)/g, "bab", [[0, 0], [1, 1], [2, 0], [3, 0]]); diff --git a/deps/v8/test/mjsunit/regexp-multiline-stack-trace.js b/deps/v8/test/mjsunit/regexp-multiline-stack-trace.js deleted file mode 100644 index fc248ef6a2..0000000000 --- a/deps/v8/test/mjsunit/regexp-multiline-stack-trace.js +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2008 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The flags below are to test the trace-calls functionality and the -// preallocated meessage memory. -// Flags: --trace-calls --preallocate-message-memory - -/** - * @fileoverview Check that various regexp constructs work as intended. - * Particularly those regexps that use ^ and $. - */ - -assertTrue(/^bar/.test("bar")); -assertTrue(/^bar/.test("bar\nfoo")); -assertFalse(/^bar/.test("foo\nbar")); -assertTrue(/^bar/m.test("bar")); -assertTrue(/^bar/m.test("bar\nfoo")); -assertTrue(/^bar/m.test("foo\nbar")); - -assertTrue(/bar$/.test("bar")); -assertFalse(/bar$/.test("bar\nfoo")); -assertTrue(/bar$/.test("foo\nbar")); -assertTrue(/bar$/m.test("bar")); -assertTrue(/bar$/m.test("bar\nfoo")); -assertTrue(/bar$/m.test("foo\nbar")); - -assertFalse(/^bxr/.test("bar")); -assertFalse(/^bxr/.test("bar\nfoo")); -assertFalse(/^bxr/m.test("bar")); -assertFalse(/^bxr/m.test("bar\nfoo")); -assertFalse(/^bxr/m.test("foo\nbar")); - -assertFalse(/bxr$/.test("bar")); -assertFalse(/bxr$/.test("foo\nbar")); -assertFalse(/bxr$/m.test("bar")); -assertFalse(/bxr$/m.test("bar\nfoo")); -assertFalse(/bxr$/m.test("foo\nbar")); - - -assertTrue(/^.*$/.test("")); -assertTrue(/^.*$/.test("foo")); -assertFalse(/^.*$/.test("\n")); -assertTrue(/^.*$/m.test("\n")); - -assertTrue(/^[\s]*$/.test(" ")); -assertTrue(/^[\s]*$/.test("\n")); - -assertTrue(/^[^]*$/.test("")); -assertTrue(/^[^]*$/.test("foo")); -assertTrue(/^[^]*$/.test("\n")); - -assertTrue(/^([()\s]|.)*$/.test("()\n()")); -assertTrue(/^([()\n]|.)*$/.test("()\n()")); -assertFalse(/^([()]|.)*$/.test("()\n()")); -assertTrue(/^([()]|.)*$/m.test("()\n()")); -assertTrue(/^([()]|.)*$/m.test("()\n")); -assertTrue(/^[()]*$/m.test("()\n.")); - -assertTrue(/^[\].]*$/.test("...]...")); - - -function check_case(lc, uc) { - var a = new RegExp("^" + lc + "$"); - assertFalse(a.test(uc)); - a = new RegExp("^" + lc + "$", "i"); - assertTrue(a.test(uc)); - - var A = new RegExp("^" + uc + "$"); - assertFalse(A.test(lc)); - A = new RegExp("^" + uc + "$", "i"); - assertTrue(A.test(lc)); - - a = new RegExp("^[" + lc + "]$"); - assertFalse(a.test(uc)); - a = new RegExp("^[" + lc + "]$", "i"); - assertTrue(a.test(uc)); - - A = new RegExp("^[" + uc + "]$"); - assertFalse(A.test(lc)); - A = new RegExp("^[" + uc + "]$", "i"); - assertTrue(A.test(lc)); -} - - -check_case("a", "A"); -// Aring -check_case(String.fromCharCode(229), String.fromCharCode(197)); -// Russian G -check_case(String.fromCharCode(0x413), String.fromCharCode(0x433)); - - -assertThrows("a = new RegExp('[z-a]');"); diff --git a/deps/v8/test/mjsunit/regexp-results-cache.js b/deps/v8/test/mjsunit/regexp-results-cache.js index 7ee8c3fac4..9de866106b 100644 --- a/deps/v8/test/mjsunit/regexp-results-cache.js +++ b/deps/v8/test/mjsunit/regexp-results-cache.js @@ -75,4 +75,3 @@ assertEquals("Friends,", words[0]); words[0] = "Enemies,"; words = string.split(" "); assertEquals("Friends,", words[0]); - diff --git a/deps/v8/test/mjsunit/regress-3135.js b/deps/v8/test/mjsunit/regress-3135.js new file mode 100644 index 0000000000..8088432c8e --- /dev/null +++ b/deps/v8/test/mjsunit/regress-3135.js @@ -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. + +// Properties are serialized once. +assertEquals('{"x":1}', JSON.stringify({ x : 1 }, ["x", 1, "x", 1])); +assertEquals('{"1":1}', JSON.stringify({ 1 : 1 }, ["x", 1, "x", 1])); +assertEquals('{"1":1}', JSON.stringify({ 1 : 1 }, ["1", 1, "1", 1])); +assertEquals('{"1":1}', JSON.stringify({ 1 : 1 }, [1, "1", 1, "1"])); + +// Properties are visited at most once. +var fired = 0; +var getter_obj = { get x() { fired++; return 2; } }; +assertEquals('{"x":2}', JSON.stringify(getter_obj, ["x", "y", "x"])); +assertEquals(1, fired); + +// Order of the replacer array is followed. +assertEquals('{"y":4,"x":3}', JSON.stringify({ x : 3, y : 4}, ["y", "x"])); +assertEquals('{"y":4,"1":2,"x":3}', + JSON.stringify({ x : 3, y : 4, 1 : 2 }, ["y", 1, "x"])); + +// __proto__ is ignored and doesn't break anything. +var a = { x : 8 }; +a.__proto__ = { x : 7 }; +assertEquals('{"x":8}', JSON.stringify(a, ["__proto__", "x", "__proto__"])); + +// Arrays are not affected by the replacer array. +assertEquals("[9,8,7]", JSON.stringify([9, 8, 7], [1, 1])); +var mixed_arr = [11,12,13]; +mixed_arr.x = 10; +assertEquals('[11,12,13]', JSON.stringify(mixed_arr, [1, 0, 1])); + +// Array elements of objects are affected. +var mixed_obj = { x : 3 }; +mixed_obj[0] = 6; +mixed_obj[1] = 5; +assertEquals('{"1":5,"0":6}', JSON.stringify(mixed_obj, [1, 0, 1])); + +// Nested object. +assertEquals('{"z":{"x":3},"x":1}', + JSON.stringify({ x: 1, y:2, z: {x:3, b:4}}, ["z","x"])); + +// Objects in the replacer array are ignored. +assertEquals('{}', + JSON.stringify({ x : 1, "1": 1 }, [{}])); +assertEquals('{}', + JSON.stringify({ x : 1, "1": 1 }, [true, undefined, null])); +assertEquals('{}', + JSON.stringify({ x : 1, "1": 1 }, + [{ toString: function() { return "x";} }])); +assertEquals('{}', + JSON.stringify({ x : 1, "1": 1 }, + [{ valueOf: function() { return 1;} }])); diff --git a/deps/v8/test/mjsunit/regress-330046.js b/deps/v8/test/mjsunit/regress-330046.js new file mode 100644 index 0000000000..d94b804ac0 --- /dev/null +++ b/deps/v8/test/mjsunit/regress-330046.js @@ -0,0 +1,61 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --use-osr --allow-natives-syntax --crankshaft + +var o1 = {a : 10}; +var o2 = { }; +o2.__proto__ = o1; +var o3 = { }; +o3.__proto__ = o2; + +function f(n, x, b) { + var sum = x.a; + for (var i = 0; i < n; i++) { + sum = 1.0 / i; + } + return sum; +} + +f(10, o3); +f(20, o3); +f(30, o3); +%OptimizeFunctionOnNextCall(f, "concurrent"); +f(100000, o3); +// At this point OSR replaces already optimized code. +// Check that it evicts old code from cache. + +// This causes all code for f to be lazily deopted. +o2.a = 5; + +// If OSR did not evict the old code, it will be installed in f here. +%OptimizeFunctionOnNextCall(f); +f(10, o3); + +// The old code is already deoptimized, but f still points to it. +// Disassembling it will crash. +%DebugDisassembleFunction(f); diff --git a/deps/v8/test/mjsunit/regress/binop-in-effect-context-deopt.js b/deps/v8/test/mjsunit/regress/binop-in-effect-context-deopt.js new file mode 100644 index 0000000000..fb7280a0d1 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/binop-in-effect-context-deopt.js @@ -0,0 +1,65 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +(function BinopInEffectContextDeoptAndOsr() { + function f(a, deopt, osr) { + var result = (a + 10, "result"); + var dummy = deopt + 0; + if (osr) while (%GetOptimizationStatus(f) == 2) {} + return result; + } + + assertEquals("result", f(true, 3, false)); + assertEquals("result", f(true, 3, false)); + %OptimizeFunctionOnNextCall(f); + assertEquals("result", f(true, "foo", true)); +})(); + + +(function BinopInEffectContextLazyDeopt() { + function deopt_f() { + %DeoptimizeFunction(f); + return "dummy"; + } + + function h() { + return { toString : deopt_f }; + } + + function g(x) { + } + + function f() { + return g(void(h() + "")); + }; + + f(); + %OptimizeFunctionOnNextCall(f); + f(); +})(); diff --git a/deps/v8/test/mjsunit/regress/call-function-in-effect-context-deopt.js b/deps/v8/test/mjsunit/regress/call-function-in-effect-context-deopt.js new file mode 100644 index 0000000000..9a36c141b7 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/call-function-in-effect-context-deopt.js @@ -0,0 +1,41 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function f(deopt, osr) { + var result = "result"; + %_CallFunction(0, 0, function() {}); + var dummy = deopt + 0; + if (osr) while (%GetOptimizationStatus(f) == 2) {} + return result; +} + +assertEquals("result", f(3, false)); +assertEquals("result", f(3, false)); +%OptimizeFunctionOnNextCall(f); +assertEquals("result", f("foo", true)); diff --git a/deps/v8/test/mjsunit/regress/clear-keyed-call.js b/deps/v8/test/mjsunit/regress/clear-keyed-call.js new file mode 100644 index 0000000000..6870f606c0 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/clear-keyed-call.js @@ -0,0 +1,40 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --expose-gc --allow-natives-syntax + +function f(a) { + a[0](1); +} + +f([function(a) { return a; }]); +f([function(a) { return a; }]); +f([function(a) { return a; }]); +%NotifyContextDisposed(); +gc(); +gc(); +gc(); diff --git a/deps/v8/test/mjsunit/regress/comparison-in-effect-context-deopt.js b/deps/v8/test/mjsunit/regress/comparison-in-effect-context-deopt.js new file mode 100644 index 0000000000..b28dff73a7 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/comparison-in-effect-context-deopt.js @@ -0,0 +1,47 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function lazyDeopt() { + %DeoptimizeFunction(test); + return "deopt"; +} + +var x = { toString : lazyDeopt }; + +function g(x) { + return "result"; +} + +function test(x) { + return g(void(x == "")); +} + +test(x); +%OptimizeFunctionOnNextCall(test); +assertEquals("result", test(x)); diff --git a/deps/v8/test/mjsunit/regress/d8-readbuffer.js b/deps/v8/test/mjsunit/regress/d8-readbuffer.js new file mode 100644 index 0000000000..8aec02dcac --- /dev/null +++ b/deps/v8/test/mjsunit/regress/d8-readbuffer.js @@ -0,0 +1,40 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Test that reading a file actually returns the file's contents. + +// Env: TEST_FILE_NAME +assertEquals("string", typeof TEST_FILE_NAME); + +var a = new Uint8Array(readbuffer(TEST_FILE_NAME)); + +// First line of this file. +var expected = "// Copyright 2014 the V8 project authors. All rights reserved."; + +for (var i = 0; i < expected.length; i++) { + assertEquals(expected.charCodeAt(i), a[i]); +} diff --git a/deps/v8/test/mjsunit/regress/internalized-string-not-equal.js b/deps/v8/test/mjsunit/regress/internalized-string-not-equal.js new file mode 100644 index 0000000000..911279b43e --- /dev/null +++ b/deps/v8/test/mjsunit/regress/internalized-string-not-equal.js @@ -0,0 +1,40 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +// A bug in r15773, when masks for internalized string and string types +// were reorganized. +function equal(o1, o2) { + return (o1 == o2); +} +var a = "abc"; +var b = "abc"; +equal(a, b); +equal(a, b); +%OptimizeFunctionOnNextCall(equal); +assertTrue(equal(1.3, 1.3)); diff --git a/deps/v8/test/mjsunit/regress/number-named-call-deopt.js b/deps/v8/test/mjsunit/regress/number-named-call-deopt.js new file mode 100644 index 0000000000..1598af12b4 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/number-named-call-deopt.js @@ -0,0 +1,41 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function f(x, deopt, osr) { + var res = "result"; + void(x.toString(10, deopt + 0)); + if (osr) for (var i = 0; i < 100000; i++) { } + return res; +} + +f(4, 0, false); +f(4, 0, false); +f(4, 0, false); +%OptimizeFunctionOnNextCall(f); +assertEquals("result", f(4, "deopt", true)); diff --git a/deps/v8/test/mjsunit/regress/polymorphic-accessor-test-context.js b/deps/v8/test/mjsunit/regress/polymorphic-accessor-test-context.js new file mode 100644 index 0000000000..6188279248 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/polymorphic-accessor-test-context.js @@ -0,0 +1,25 @@ +// 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 + +function t1() { return this instanceof t1; } +function t2() { return this instanceof t2; } + +var o1 = new (function() { })(); +Object.defineProperty(o1, "t", {get:function() { return this instanceof o1.constructor; }}); +var o2 = new (function() { })(); +Object.defineProperty(o2, "t", {get:function() { return this instanceof o1.constructor; }}); +var o3 = new (function() { })(); +o3.t = true; + +function f(o) { + return 1 + (o.t ? 1 : 2); +} + +f(o1); +f(o1); +f(o2); +%OptimizeFunctionOnNextCall(f); +f(o3); diff --git a/deps/v8/test/mjsunit/regress/regress-1017.js b/deps/v8/test/mjsunit/regress/regress-1017.js index 3daf5428ab..440449a5bf 100644 --- a/deps/v8/test/mjsunit/regress/regress-1017.js +++ b/deps/v8/test/mjsunit/regress/regress-1017.js @@ -33,4 +33,3 @@ // to store the 33rd character. This fails an ASSERT in debug mode. assertEquals(33, "12345678901234567890123456789012\u2028".length); - diff --git a/deps/v8/test/mjsunit/regress/regress-1039610.js b/deps/v8/test/mjsunit/regress/regress-1039610.js index fd5c549c1c..757801fcee 100644 --- a/deps/v8/test/mjsunit/regress/regress-1039610.js +++ b/deps/v8/test/mjsunit/regress/regress-1039610.js @@ -26,4 +26,4 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Make sure that the Debug object does not return to the global object -assertTrue(typeof(Debug) === 'undefined');
\ No newline at end of file +assertTrue(typeof(Debug) === 'undefined'); diff --git a/deps/v8/test/mjsunit/regress/regress-105.js b/deps/v8/test/mjsunit/regress/regress-105.js index 9a4d5c4744..8b8030ffec 100644 --- a/deps/v8/test/mjsunit/regress/regress-105.js +++ b/deps/v8/test/mjsunit/regress/regress-105.js @@ -41,4 +41,3 @@ object.toString = custom_toString; assertEquals(2, Number(object)); assertEquals('I', String(object)[0]); - diff --git a/deps/v8/test/mjsunit/regress/regress-1066899.js b/deps/v8/test/mjsunit/regress/regress-1066899.js index 37fd554b54..5840f26234 100644 --- a/deps/v8/test/mjsunit/regress/regress-1066899.js +++ b/deps/v8/test/mjsunit/regress/regress-1066899.js @@ -34,4 +34,3 @@ function Crash() { } Crash(); - diff --git a/deps/v8/test/mjsunit/regress/regress-1092.js b/deps/v8/test/mjsunit/regress/regress-1092.js index 00422cb452..24efb37b40 100644 --- a/deps/v8/test/mjsunit/regress/regress-1092.js +++ b/deps/v8/test/mjsunit/regress/regress-1092.js @@ -32,4 +32,3 @@ this.w = 0; this.x = 1; this.y = 2; this.z = 3; - diff --git a/deps/v8/test/mjsunit/regress/regress-1099.js b/deps/v8/test/mjsunit/regress/regress-1099.js index 36f09e4eb9..49e4a52794 100644 --- a/deps/v8/test/mjsunit/regress/regress-1099.js +++ b/deps/v8/test/mjsunit/regress/regress-1099.js @@ -48,4 +48,4 @@ for (var i = 0; i < 5; i++) { } %OptimizeFunctionOnNextCall(y); -assertTrue(y("foo"));
\ No newline at end of file +assertTrue(y("foo")); diff --git a/deps/v8/test/mjsunit/regress/regress-1112.js b/deps/v8/test/mjsunit/regress/regress-1112.js index d780106ba0..41c9193898 100644 --- a/deps/v8/test/mjsunit/regress/regress-1112.js +++ b/deps/v8/test/mjsunit/regress/regress-1112.js @@ -33,4 +33,3 @@ Object.defineProperty(this, { configurable: true, enumerable: true, value: 3 }); assertEquals(3, this[1]); assertTrue(this.hasOwnProperty("1")); - diff --git a/deps/v8/test/mjsunit/regress/regress-1114040.js b/deps/v8/test/mjsunit/regress/regress-1114040.js index 9d1b320a9a..ef7ee31f09 100644 --- a/deps/v8/test/mjsunit/regress/regress-1114040.js +++ b/deps/v8/test/mjsunit/regress/regress-1114040.js @@ -55,4 +55,3 @@ function TestContinue() { assertEquals("01", TestBreak()); assertEquals("01", TestContinue()); - diff --git a/deps/v8/test/mjsunit/regress/regress-1117.js b/deps/v8/test/mjsunit/regress/regress-1117.js index 981a1b7a3f..664dadd067 100644 --- a/deps/v8/test/mjsunit/regress/regress-1117.js +++ b/deps/v8/test/mjsunit/regress/regress-1117.js @@ -41,4 +41,3 @@ assertEquals(Infinity, 1/bar(5)); assertEquals(Infinity, 1/bar(5)); %OptimizeFunctionOnNextCall(bar); assertEquals(-Infinity, 1/bar(-5)); - diff --git a/deps/v8/test/mjsunit/regress/regress-1178598.js b/deps/v8/test/mjsunit/regress/regress-1178598.js index 9caaec2f01..135c596872 100644 --- a/deps/v8/test/mjsunit/regress/regress-1178598.js +++ b/deps/v8/test/mjsunit/regress/regress-1178598.js @@ -86,5 +86,3 @@ var value = (function() { })(); assertEquals(87, value); - - diff --git a/deps/v8/test/mjsunit/regress/regress-1181.js b/deps/v8/test/mjsunit/regress/regress-1181.js index d45a0bee35..d5b8ab1797 100644 --- a/deps/v8/test/mjsunit/regress/regress-1181.js +++ b/deps/v8/test/mjsunit/regress/regress-1181.js @@ -51,4 +51,4 @@ function check(count) { check(150); check(200); -check(350);
\ No newline at end of file +check(350); diff --git a/deps/v8/test/mjsunit/regress/regress-1246.js b/deps/v8/test/mjsunit/regress/regress-1246.js index f3dbec627b..ca425ec2b7 100644 --- a/deps/v8/test/mjsunit/regress/regress-1246.js +++ b/deps/v8/test/mjsunit/regress/regress-1246.js @@ -80,4 +80,3 @@ for (var i = 0; i < radix16.length; i++) { assertEquals(0xaf, parseInt("0xaf", radix)); assertEquals(0xaf, parseInt("af", radix)); } - diff --git a/deps/v8/test/mjsunit/regress/regress-1254366.js b/deps/v8/test/mjsunit/regress/regress-1254366.js index 2f9e011e94..9acda3c19b 100644 --- a/deps/v8/test/mjsunit/regress/regress-1254366.js +++ b/deps/v8/test/mjsunit/regress/regress-1254366.js @@ -35,4 +35,3 @@ Object.prototype.findOrStore = function() { var a = new Object(); assertEquals(gee, a.findOrStore()); assertEquals(gee, a.findOrStore()); - diff --git a/deps/v8/test/mjsunit/regress/regress-131994.js b/deps/v8/test/mjsunit/regress/regress-131994.js index 8347653a94..7f600959da 100644 --- a/deps/v8/test/mjsunit/regress/regress-131994.js +++ b/deps/v8/test/mjsunit/regress/regress-131994.js @@ -67,4 +67,3 @@ function h() { h(); assertFalse(exception); - diff --git a/deps/v8/test/mjsunit/regress/regress-137.js b/deps/v8/test/mjsunit/regress/regress-137.js index cc7b68c0f2..f343eba14a 100644 --- a/deps/v8/test/mjsunit/regress/regress-137.js +++ b/deps/v8/test/mjsunit/regress/regress-137.js @@ -43,4 +43,3 @@ }; fail("case 10", "Default case", "Heap number not recognized as Smi value"); })(); - diff --git a/deps/v8/test/mjsunit/regress/regress-1546.js b/deps/v8/test/mjsunit/regress/regress-1546.js index 7f1fa58b49..3f1839cd37 100644 --- a/deps/v8/test/mjsunit/regress/regress-1546.js +++ b/deps/v8/test/mjsunit/regress/regress-1546.js @@ -29,4 +29,4 @@ // Should't throw. Scanner incorrectly truncated to char before comparing // with "*", so it ended the comment early. -eval("/*\u822a/ */");
\ No newline at end of file +eval("/*\u822a/ */"); diff --git a/deps/v8/test/mjsunit/regress/regress-1591.js b/deps/v8/test/mjsunit/regress/regress-1591.js index 69efd0bd87..dbf40dfdbe 100644 --- a/deps/v8/test/mjsunit/regress/regress-1591.js +++ b/deps/v8/test/mjsunit/regress/regress-1591.js @@ -45,4 +45,3 @@ var used_custom_lookup = false; var expected_message = "ReferenceError: f is not defined"; assertTrue(stack.indexOf(expected_message) >= 0); assertFalse(used_custom_lookup); - diff --git a/deps/v8/test/mjsunit/regress/regress-1647.js b/deps/v8/test/mjsunit/regress/regress-1647.js index a6afcc0be2..ab6608c1ef 100644 --- a/deps/v8/test/mjsunit/regress/regress-1647.js +++ b/deps/v8/test/mjsunit/regress/regress-1647.js @@ -40,4 +40,3 @@ for (var i = 0; i < 10; i++) f(); %OptimizeFunctionOnNextCall(f); t.number = 2; f(); - diff --git a/deps/v8/test/mjsunit/regress/regress-165637.js b/deps/v8/test/mjsunit/regress/regress-165637.js index 72af528a86..84c9041216 100644 --- a/deps/v8/test/mjsunit/regress/regress-165637.js +++ b/deps/v8/test/mjsunit/regress/regress-165637.js @@ -45,10 +45,6 @@ function do_slices() { return Date.now() - start; } -// Reset the GC stress mode to be off. Needed so that the runtime of this test -// stays within bounds even if we run in GC stress mode. -%SetFlags("--gc-interval=-1 --noforce-marking-deque-overflows"); - // Should never take more than 3 seconds (if the bug is fixed, the test takes // considerably less time than 3 seconds). assertTrue(do_slices() < (3 * 1000)); diff --git a/deps/v8/test/mjsunit/regress/regress-166379.js b/deps/v8/test/mjsunit/regress/regress-166379.js index b19afbdde6..2cda61182b 100644 --- a/deps/v8/test/mjsunit/regress/regress-166379.js +++ b/deps/v8/test/mjsunit/regress/regress-166379.js @@ -36,4 +36,3 @@ assertEquals(1, mod(3, 2)); // Surprise mod with overflow. assertEquals(-Infinity, 1/mod(-2147483648, -1)); - diff --git a/deps/v8/test/mjsunit/regress/regress-1748.js b/deps/v8/test/mjsunit/regress/regress-1748.js index e287e55496..41b7c70c01 100644 --- a/deps/v8/test/mjsunit/regress/regress-1748.js +++ b/deps/v8/test/mjsunit/regress/regress-1748.js @@ -32,4 +32,4 @@ var str = Array(10000).join("X"); str.replace(/^|X/g, function(m, i, s) { if (i > 0) assertEquals("X", m, "at position 0x" + i.toString(16)); -});
\ No newline at end of file +}); diff --git a/deps/v8/test/mjsunit/regress/regress-1757.js b/deps/v8/test/mjsunit/regress/regress-1757.js index f7a5516cac..35e7355c33 100644 --- a/deps/v8/test/mjsunit/regress/regress-1757.js +++ b/deps/v8/test/mjsunit/regress/regress-1757.js @@ -29,4 +29,4 @@ var a = "abcdefghijklmnopqrstuvqxy"+"z"; externalizeString(a, true); -assertEquals('b', a.substring(1).charAt(0));
\ No newline at end of file +assertEquals('b', a.substring(1).charAt(0)); diff --git a/deps/v8/test/mjsunit/regress/regress-1853.js b/deps/v8/test/mjsunit/regress/regress-1853.js index cfafe82fa3..7175688821 100644 --- a/deps/v8/test/mjsunit/regress/regress-1853.js +++ b/deps/v8/test/mjsunit/regress/regress-1853.js @@ -113,4 +113,3 @@ eval('function test2() { \n' + test1(); test2(); assertEquals(3, break_count); - diff --git a/deps/v8/test/mjsunit/regress/regress-186.js b/deps/v8/test/mjsunit/regress/regress-186.js index 335869d6b0..0212855896 100644 --- a/deps/v8/test/mjsunit/regress/regress-186.js +++ b/deps/v8/test/mjsunit/regress/regress-186.js @@ -69,4 +69,3 @@ function testGlobal() { runTest(testLocal); runTest(testConstLocal); runTest(testGlobal); - diff --git a/deps/v8/test/mjsunit/regress/regress-1919169.js b/deps/v8/test/mjsunit/regress/regress-1919169.js index a73231289f..fbb82bae67 100644 --- a/deps/v8/test/mjsunit/regress/regress-1919169.js +++ b/deps/v8/test/mjsunit/regress/regress-1919169.js @@ -37,4 +37,3 @@ function test() { // Crash does not occur when code is run at the top level. test(); - diff --git a/deps/v8/test/mjsunit/regress/regress-193.js b/deps/v8/test/mjsunit/regress/regress-193.js index f803483106..457c208153 100644 --- a/deps/v8/test/mjsunit/regress/regress-193.js +++ b/deps/v8/test/mjsunit/regress/regress-193.js @@ -40,5 +40,3 @@ f()(); // The call to f should get the constructor of the receiver which is // the constructor of the global object. assertEquals(constructor, f()); - - diff --git a/deps/v8/test/mjsunit/regress/regress-20070207.js b/deps/v8/test/mjsunit/regress/regress-20070207.js index b7f7a5cc6f..701a079ade 100644 --- a/deps/v8/test/mjsunit/regress/regress-20070207.js +++ b/deps/v8/test/mjsunit/regress/regress-20070207.js @@ -39,4 +39,3 @@ assertFalse(f(-10)); assertFalse(f(-5)); assertFalse(f(0)); assertFalse(f(10)); - diff --git a/deps/v8/test/mjsunit/regress/regress-2027.js b/deps/v8/test/mjsunit/regress/regress-2027.js index 00ed03f650..3f2062b90c 100644 --- a/deps/v8/test/mjsunit/regress/regress-2027.js +++ b/deps/v8/test/mjsunit/regress/regress-2027.js @@ -45,4 +45,3 @@ Check(d.setUTCHours(10)); Check(d.setUTCDate(10)); Check(d.setUTCMonth(10)); Check(d.setUTCFullYear(2010)); - diff --git a/deps/v8/test/mjsunit/regress/regress-2119.js b/deps/v8/test/mjsunit/regress/regress-2119.js index 54840c238b..b735ddf3a6 100644 --- a/deps/v8/test/mjsunit/regress/regress-2119.js +++ b/deps/v8/test/mjsunit/regress/regress-2119.js @@ -33,4 +33,3 @@ function strict_function() { } assertThrows(strict_function); - diff --git a/deps/v8/test/mjsunit/regress/regress-2170.js b/deps/v8/test/mjsunit/regress/regress-2170.js index 01cb1eaf8f..99f432dfcf 100644 --- a/deps/v8/test/mjsunit/regress/regress-2170.js +++ b/deps/v8/test/mjsunit/regress/regress-2170.js @@ -55,4 +55,3 @@ try { } catch (e) { assertUnreachable(); } - diff --git a/deps/v8/test/mjsunit/regress/regress-2172.js b/deps/v8/test/mjsunit/regress/regress-2172.js index 5d06f4eef4..6d938453d3 100644 --- a/deps/v8/test/mjsunit/regress/regress-2172.js +++ b/deps/v8/test/mjsunit/regress/regress-2172.js @@ -32,4 +32,3 @@ for (var i = 0; i < 10000; i++){ for (var i = 0; i < 10000; i++){ (i + "\u1234\0").split(/(.)\1/i); } - diff --git a/deps/v8/test/mjsunit/regress/regress-2250.js b/deps/v8/test/mjsunit/regress/regress-2250.js index 9d2fd4412f..88d4dd434f 100644 --- a/deps/v8/test/mjsunit/regress/regress-2250.js +++ b/deps/v8/test/mjsunit/regress/regress-2250.js @@ -65,4 +65,3 @@ test(); // function should no longer deopt when called. test(); assertOptimized(test); - diff --git a/deps/v8/test/mjsunit/regress/regress-2284.js b/deps/v8/test/mjsunit/regress/regress-2284.js index 561401998a..24bf58e2db 100644 --- a/deps/v8/test/mjsunit/regress/regress-2284.js +++ b/deps/v8/test/mjsunit/regress/regress-2284.js @@ -27,6 +27,6 @@ // Flags: --allow-natives-syntax -assertThrows("%foobar();", TypeError); -assertThrows("%constructor();", TypeError); -assertThrows("%constructor(23);", TypeError); +assertThrows("%foobar();", Error); +assertThrows("%constructor();", Error); +assertThrows("%constructor(23);", Error); diff --git a/deps/v8/test/mjsunit/regress/regress-2285.js b/deps/v8/test/mjsunit/regress/regress-2285.js index efda4cde32..a0d628df93 100644 --- a/deps/v8/test/mjsunit/regress/regress-2285.js +++ b/deps/v8/test/mjsunit/regress/regress-2285.js @@ -29,4 +29,3 @@ assertThrows(function() { %_CallFunction(null, 0, ""); }); assertThrows(function() { %_CallFunction(null, 0, 1); }); - diff --git a/deps/v8/test/mjsunit/regress/regress-2286.js b/deps/v8/test/mjsunit/regress/regress-2286.js index 372451ec44..0264900442 100644 --- a/deps/v8/test/mjsunit/regress/regress-2286.js +++ b/deps/v8/test/mjsunit/regress/regress-2286.js @@ -28,5 +28,5 @@ // Flags: --allow-natives-syntax assertThrows("f()", ReferenceError); -assertThrows("%f()", TypeError); +assertThrows("%f()", Error); assertThrows("%_f()", SyntaxError); diff --git a/deps/v8/test/mjsunit/regress/regress-2289.js b/deps/v8/test/mjsunit/regress/regress-2289.js index e89ec6e143..d860bbbf70 100644 --- a/deps/v8/test/mjsunit/regress/regress-2289.js +++ b/deps/v8/test/mjsunit/regress/regress-2289.js @@ -30,5 +30,3 @@ for (var i = 0; i < 12; i++) foo += foo; foo = foo + 'b' + foo; foo.replace(/b/, "a"); - - diff --git a/deps/v8/test/mjsunit/regress/regress-231.js b/deps/v8/test/mjsunit/regress/regress-231.js index 0c6e5b3495..bce0500013 100644 --- a/deps/v8/test/mjsunit/regress/regress-231.js +++ b/deps/v8/test/mjsunit/regress/regress-231.js @@ -89,4 +89,4 @@ var str = 'GgcyDGgcy.saaaa.aDGaaa.aynaaaaaaaaacaaaaagcaaaaaaaancaDGgnayr' + //Shouldn't crash. var res = re.test(str); -assertTrue(res);
\ No newline at end of file +assertTrue(res); diff --git a/deps/v8/test/mjsunit/regress/regress-2318.js b/deps/v8/test/mjsunit/regress/regress-2318.js index ca67ab2ca5..e31e0f904e 100644 --- a/deps/v8/test/mjsunit/regress/regress-2318.js +++ b/deps/v8/test/mjsunit/regress/regress-2318.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --expose-debug-as debug --nostack-trace-on-abort +// Flags: --expose-debug-as debug --nostack-trace-on-abort --stack-size=150 function f() { var i = 0; diff --git a/deps/v8/test/mjsunit/regress/regress-2374.js b/deps/v8/test/mjsunit/regress/regress-2374.js index b333720ac0..f379cc55b7 100644 --- a/deps/v8/test/mjsunit/regress/regress-2374.js +++ b/deps/v8/test/mjsunit/regress/regress-2374.js @@ -31,4 +31,4 @@ var obj = JSON.parse(msg); var obj2 = JSON.parse(msg); assertEquals(JSON.stringify(obj), JSON.stringify(obj2)); -assertEquals(JSON.stringify(obj, null, 0), JSON.stringify(obj2));
\ No newline at end of file +assertEquals(JSON.stringify(obj, null, 0), JSON.stringify(obj2)); diff --git a/deps/v8/test/mjsunit/regress/regress-237617.js b/deps/v8/test/mjsunit/regress/regress-237617.js index dabf828ae8..7b7e50f247 100644 --- a/deps/v8/test/mjsunit/regress/regress-237617.js +++ b/deps/v8/test/mjsunit/regress/regress-237617.js @@ -40,4 +40,3 @@ try { assertTrue(error_stack.indexOf("test stack") > 0); assertTrue(error_stack.indexOf("illegal") < 0); - diff --git a/deps/v8/test/mjsunit/regress/regress-2419.js b/deps/v8/test/mjsunit/regress/regress-2419.js index 9cd453a58e..4ffafbe6eb 100644 --- a/deps/v8/test/mjsunit/regress/regress-2419.js +++ b/deps/v8/test/mjsunit/regress/regress-2419.js @@ -34,4 +34,3 @@ var b = {0: 5, 1: 4, 2: 3, 3: 2, 4: 1, 5: 0, length: 6}; Object.freeze(b); Array.prototype.sort.call(b); assertPropertiesEqual({0: 5, 1: 4, 2: 3, 3: 2, 4: 1, 5: 0, length: 6}, b); - diff --git a/deps/v8/test/mjsunit/regress/regress-2438.js b/deps/v8/test/mjsunit/regress/regress-2438.js index 3f4fd7df57..7be7e71687 100644 --- a/deps/v8/test/mjsunit/regress/regress-2438.js +++ b/deps/v8/test/mjsunit/regress/regress-2438.js @@ -49,4 +49,3 @@ testSideEffects("zzzz", /a/); testSideEffects("zzzz", /a/g); testSideEffects("xaxa", /a/); testSideEffects("xaxa", /a/g); - diff --git a/deps/v8/test/mjsunit/regress/regress-2444.js b/deps/v8/test/mjsunit/regress/regress-2444.js index 8fb8d8b52e..41b6a95e7a 100644 --- a/deps/v8/test/mjsunit/regress/regress-2444.js +++ b/deps/v8/test/mjsunit/regress/regress-2444.js @@ -116,5 +116,3 @@ assertEquals(0, object_factory(1, 0, [1, 0, 0]), object_factory(2, 1, [1, 1, 0]))); assertFlags([1, 1, 1]); - - diff --git a/deps/v8/test/mjsunit/regress/regress-246.js b/deps/v8/test/mjsunit/regress/regress-246.js index 09b746b7aa..22e29fdde0 100644 --- a/deps/v8/test/mjsunit/regress/regress-246.js +++ b/deps/v8/test/mjsunit/regress/regress-246.js @@ -28,4 +28,4 @@ // See: http://code.google.com/p/v8/issues/detail?id=246 assertTrue(/(?:text)/.test("text")); -assertEquals(["text"], /(?:text)/.exec("text"));
\ No newline at end of file +assertEquals(["text"], /(?:text)/.exec("text")); diff --git a/deps/v8/test/mjsunit/regress/regress-2570.js b/deps/v8/test/mjsunit/regress/regress-2570.js index 4e32a21e4b..f1331e8805 100644 --- a/deps/v8/test/mjsunit/regress/regress-2570.js +++ b/deps/v8/test/mjsunit/regress/regress-2570.js @@ -29,4 +29,4 @@ var o = ["\u56e7", // Switch JSON stringifier to two-byte mode. "\u00e6"]; // Latin-1 character. assertEquals('["\u56e7","\u00e6"]', JSON.stringify(o)); -assertEquals('["\u56e7","\u00e6"]', JSON.stringify(o, null, 0));
\ No newline at end of file +assertEquals('["\u56e7","\u00e6"]', JSON.stringify(o, null, 0)); diff --git a/deps/v8/test/mjsunit/regress/regress-2596.js b/deps/v8/test/mjsunit/regress/regress-2596.js index 1d327fe0f8..e7006085a1 100644 --- a/deps/v8/test/mjsunit/regress/regress-2596.js +++ b/deps/v8/test/mjsunit/regress/regress-2596.js @@ -51,6 +51,3 @@ assertTrue(isNaN(boom(0))); assertTrue(isNaN(boom(0))); assertTrue(isNaN(boom(0))); assertTrue(isNaN(boom(0))); - - - diff --git a/deps/v8/test/mjsunit/regress/regress-2618.js b/deps/v8/test/mjsunit/regress/regress-2618.js index d1afa368dc..363557bff8 100644 --- a/deps/v8/test/mjsunit/regress/regress-2618.js +++ b/deps/v8/test/mjsunit/regress/regress-2618.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --use-osr --allow-natives-syntax +// Flags: --use-osr --allow-natives-syntax --no-concurrent-osr function f() { do { diff --git a/deps/v8/test/mjsunit/regress/regress-2624.js b/deps/v8/test/mjsunit/regress/regress-2624.js index 2bfd7b2585..fe94a10133 100644 --- a/deps/v8/test/mjsunit/regress/regress-2624.js +++ b/deps/v8/test/mjsunit/regress/regress-2624.js @@ -33,4 +33,3 @@ for(var i = 0; i < 800; i++) { } source += '"'; eval(source); - diff --git a/deps/v8/test/mjsunit/regress/regress-2671-1.js b/deps/v8/test/mjsunit/regress/regress-2671-1.js index 042a501e5a..7937d6a336 100644 --- a/deps/v8/test/mjsunit/regress/regress-2671-1.js +++ b/deps/v8/test/mjsunit/regress/regress-2671-1.js @@ -42,4 +42,3 @@ f(); f(); %OptimizeFunctionOnNextCall(f); f(); - diff --git a/deps/v8/test/mjsunit/regress/regress-2671.js b/deps/v8/test/mjsunit/regress/regress-2671.js index 8da1b8f07f..73a3098d80 100644 --- a/deps/v8/test/mjsunit/regress/regress-2671.js +++ b/deps/v8/test/mjsunit/regress/regress-2671.js @@ -42,4 +42,3 @@ f(); f(); %OptimizeFunctionOnNextCall(f); f(); - diff --git a/deps/v8/test/mjsunit/regress/regress-2690.js b/deps/v8/test/mjsunit/regress/regress-2690.js index 5fe7dc42dc..0ed4c5c679 100644 --- a/deps/v8/test/mjsunit/regress/regress-2690.js +++ b/deps/v8/test/mjsunit/regress/regress-2690.js @@ -26,4 +26,3 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. assertTrue(/\1[a]/.test("\1a")); - diff --git a/deps/v8/test/mjsunit/regress/regress-270142.js b/deps/v8/test/mjsunit/regress/regress-270142.js new file mode 100644 index 0000000000..6e0865c4f8 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-270142.js @@ -0,0 +1,48 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Check that "name"'s property descriptor for non-strict and strict +// functions correspond. + +function f(x) { + return x; +} + +function g(x) { + "use strict"; + return x; +} + +function checkNameDescriptor(f) { + var descriptor = Object.getOwnPropertyDescriptor(f, "name"); + assertFalse(descriptor.configurable); + assertFalse(descriptor.enumerable); + assertFalse(descriptor.writable); +} + +checkNameDescriptor(f); +checkNameDescriptor(g); diff --git a/deps/v8/test/mjsunit/regress/regress-2711.js b/deps/v8/test/mjsunit/regress/regress-2711.js index a58e789745..d5ac2baa33 100644 --- a/deps/v8/test/mjsunit/regress/regress-2711.js +++ b/deps/v8/test/mjsunit/regress/regress-2711.js @@ -27,7 +27,7 @@ // Test that frozen arrays don't let their length change var a = Object.freeze([1]); -a.push(2); +assertThrows(function() { a.push(2); }, TypeError); assertEquals(1, a.length); -a.push(2); +assertThrows(function() { a.push(2); }, TypeError); assertEquals(1, a.length); diff --git a/deps/v8/test/mjsunit/bugs/bug-2758.js b/deps/v8/test/mjsunit/regress/regress-2758.js index ee78844400..ee78844400 100644 --- a/deps/v8/test/mjsunit/bugs/bug-2758.js +++ b/deps/v8/test/mjsunit/regress/regress-2758.js diff --git a/deps/v8/test/mjsunit/regress/regress-2790.js b/deps/v8/test/mjsunit/regress/regress-2790.js index 86305b8867..927f2607cc 100644 --- a/deps/v8/test/mjsunit/regress/regress-2790.js +++ b/deps/v8/test/mjsunit/regress/regress-2790.js @@ -26,6 +26,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Test that we can create arrays of any size. -for (var i = 1000; i < 1000000; i += 97) { +for (var i = 1000; i < 1000000; i += 197) { new Array(i); } diff --git a/deps/v8/test/mjsunit/regress/regress-298269.js b/deps/v8/test/mjsunit/regress/regress-298269.js index 329ff824df..f6604dfcb6 100644 --- a/deps/v8/test/mjsunit/regress/regress-298269.js +++ b/deps/v8/test/mjsunit/regress/regress-298269.js @@ -42,4 +42,4 @@ Cb(s1); var s3 = "string for triggering osr in Cb"; for (var i = 0; i < 16; i++) s3 = s3 + s3; Cb(s3); -Cb(s1 + s2);
\ No newline at end of file +Cb(s1 + s2); diff --git a/deps/v8/test/mjsunit/regress/regress-2984.js b/deps/v8/test/mjsunit/regress/regress-2984.js index de7895db0f..914409cd91 100644 --- a/deps/v8/test/mjsunit/regress/regress-2984.js +++ b/deps/v8/test/mjsunit/regress/regress-2984.js @@ -31,4 +31,3 @@ assertEquals("abcdefghijklmn\xffopq", assertEquals("\xff", "\u0178".toLowerCase()); assertEquals("ABCDEFGHIJKLMN\u0178OPQ", ("abcdefghijk" + "lmn\xffopq").toUpperCase()); - diff --git a/deps/v8/test/mjsunit/regress/regress-2988.js b/deps/v8/test/mjsunit/regress/regress-2988.js new file mode 100644 index 0000000000..0311d2b76d --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-2988.js @@ -0,0 +1,39 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --gc-global --throws + +var f = eval("(function f() { throw 'kaboom'; })"); + +// Prepare that next MessageHandler::MakeMessageObject will result in +// reclamation of existing script wrapper while weak handle is used. +%FunctionGetScript(f); +%SetAllocationTimeout(1000, 2); + +// This call throws to the console but the --throws flag passed to this +// test will make sure we don't count it as an actual failure. +f(); diff --git a/deps/v8/test/mjsunit/regress/regress-2989.js b/deps/v8/test/mjsunit/regress/regress-2989.js new file mode 100644 index 0000000000..49c4a1cb03 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-2989.js @@ -0,0 +1,35 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +(function ArgumentsObjectChange() { + function f(x) { + x = 42; + return f.arguments[0]; + } + + f(0); + %OptimizeFunctionOnNextCall(f); + assertEquals(42, f(0)); +})(); diff --git a/deps/v8/test/mjsunit/regress/regress-299979.js b/deps/v8/test/mjsunit/regress/regress-299979.js new file mode 100644 index 0000000000..0afbcb3571 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-299979.js @@ -0,0 +1,34 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +(function(){ + "use strict"; + var list = Object.freeze([1, 2, 3]); + assertThrows(function() { list.unshift(4); }, TypeError); + assertThrows(function() { list.shift(); }, TypeError); +})(); diff --git a/deps/v8/test/mjsunit/regress/regress-3010.js b/deps/v8/test/mjsunit/regress/regress-3010.js new file mode 100644 index 0000000000..7aeec64828 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-3010.js @@ -0,0 +1,65 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +(function() { + function testOneSize(current_size) { + var eval_string = 'obj = {'; + for (var current = 0; current <= current_size; ++current) { + eval_string += 'k' + current + ':' + current + ',' + } + eval_string += '};'; + eval(eval_string); + for (var i = 0; i <= current_size; i++) { + assertEquals(i, obj['k'+i]); + } + var current_number = 0; + for (var x in obj) { + assertEquals(current_number, obj[x]); + current_number++; + } + } + + testOneSize(127); + testOneSize(128); + testOneSize(129); + + testOneSize(255); + testOneSize(256); + testOneSize(257); + + testOneSize(511); + testOneSize(512); + testOneSize(513); + + testOneSize(1023); + testOneSize(1024); + testOneSize(1025); + + testOneSize(2047); + testOneSize(2048); + testOneSize(2049); +}()) diff --git a/deps/v8/test/mjsunit/regress/regress-3025.js b/deps/v8/test/mjsunit/regress/regress-3025.js new file mode 100644 index 0000000000..ccb3830687 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-3025.js @@ -0,0 +1,32 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var n = 0x8000000000000800; +assertEquals(n, 9223372036854778000); +var s = n.toString(5); +var v = parseInt(s, 5); +assertEquals(n, v); diff --git a/deps/v8/test/mjsunit/regress/regress-3026.js b/deps/v8/test/mjsunit/regress/regress-3026.js new file mode 100644 index 0000000000..d25c88d432 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-3026.js @@ -0,0 +1,28 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +assertEquals([], "abc".split(undefined, 0)); diff --git a/deps/v8/test/mjsunit/regress/regress-3027.js b/deps/v8/test/mjsunit/regress/regress-3027.js index c7ebd539b6..6336594052 100644 --- a/deps/v8/test/mjsunit/regress/regress-3027.js +++ b/deps/v8/test/mjsunit/regress/regress-3027.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Test to exceed the Heap::MaxRegularSpaceAllocationSize with an array +// Test to exceed the Page::MaxRegularHeapObjectSize with an array // constructor call taking many arguments. function boom() { diff --git a/deps/v8/test/mjsunit/regress/regress-3029.js b/deps/v8/test/mjsunit/regress/regress-3029.js new file mode 100644 index 0000000000..ae412dff2b --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-3029.js @@ -0,0 +1,45 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function c(x) { + undefined.boom(); +} + +function f() { + return new c(); +} + +function g() { + f(); +} + +assertThrows("g()", TypeError); +assertThrows("g()", TypeError); +%OptimizeFunctionOnNextCall(g); +assertThrows("g()", TypeError); diff --git a/deps/v8/test/mjsunit/regress/regress-3032.js b/deps/v8/test/mjsunit/regress/regress-3032.js new file mode 100755 index 0000000000..ae54543758 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-3032.js @@ -0,0 +1,30 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +for (var i = 0; i < 1000000; i++) { } +var xl = 4096; +var z = i % xl; diff --git a/deps/v8/test/mjsunit/regress/regress-3039.js b/deps/v8/test/mjsunit/regress/regress-3039.js new file mode 100644 index 0000000000..3c7f62c16e --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-3039.js @@ -0,0 +1,41 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function do_div(x, y) { + return (x / y) | 0; +} + +// Preparation. +assertEquals(17, do_div(51, 3)); +assertEquals(13, do_div(65, 5)); +%OptimizeFunctionOnNextCall(do_div); +assertEquals(11, do_div(77, 7)); + +// The actual test. We should not trigger a floating point exception. +assertEquals(-2147483648, do_div(-2147483648, -1)); diff --git a/deps/v8/test/mjsunit/regress/regress-3138.js b/deps/v8/test/mjsunit/regress/regress-3138.js new file mode 100644 index 0000000000..acb121d2bd --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-3138.js @@ -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. + +(function f(){ + assertEquals("function", typeof f); +})(); + +(function f(){ + var f; // Variable shadows function name. + assertEquals("undefined", typeof f); +})(); + +(function f(){ + var f; + assertEquals("undefined", typeof f); + with ({}); // Force context allocation of both variable and function name. +})(); + +assertEquals("undefined", typeof f); + +// var initialization is intercepted by with scope. +(function() { + var o = { a: 1 }; + with (o) { + var a = 2; + } + assertEquals("undefined", typeof a); + assertEquals(2, o.a); +})(); + +// const initialization is not intercepted by with scope. +(function() { + var o = { a: 1 }; + with (o) { + const a = 2; + } + assertEquals(2, a); + assertEquals(1, o.a); +})(); diff --git a/deps/v8/test/mjsunit/regress/regress-3158.js b/deps/v8/test/mjsunit/regress/regress-3158.js new file mode 100644 index 0000000000..c69127395e --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-3158.js @@ -0,0 +1,24 @@ +// 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 + +Array.prototype[0] = 'a'; +delete Array.prototype[0]; + +function foo(a, i) { + return a[i]; +} + +var a = new Array(100000); +a[3] = 'x'; + +foo(a, 3); +foo(a, 3); +foo(a, 3); +%OptimizeFunctionOnNextCall(foo); +foo(a, 3); +Array.prototype[0] = 'a'; +var z = foo(a, 0); +assertEquals('a', z); diff --git a/deps/v8/test/mjsunit/regress/regress-3159.js b/deps/v8/test/mjsunit/regress/regress-3159.js new file mode 100644 index 0000000000..cfc8a39b8d --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-3159.js @@ -0,0 +1,10 @@ +// 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. + +try { + new Uint32Array(new ArrayBuffer(1), 2, 3); +} catch (e) { + assertEquals("start offset of Uint32Array should be a multiple of 4", + e.message); +} diff --git a/deps/v8/test/mjsunit/regress/regress-317.js b/deps/v8/test/mjsunit/regress/regress-317.js index b742fa1f86..85f408b841 100644 --- a/deps/v8/test/mjsunit/regress/regress-317.js +++ b/deps/v8/test/mjsunit/regress/regress-317.js @@ -28,4 +28,3 @@ // Ensure replacement with string allows $ in replacement string. assertEquals("a$ec", "abc".replace("b", "$e"), "$e isn't meaningful"); - diff --git a/deps/v8/test/mjsunit/regress/regress-319722-ArrayBuffer.js b/deps/v8/test/mjsunit/regress/regress-319722-ArrayBuffer.js index c8aed9e38c..4a48a61ab3 100644 --- a/deps/v8/test/mjsunit/regress/regress-319722-ArrayBuffer.js +++ b/deps/v8/test/mjsunit/regress/regress-319722-ArrayBuffer.js @@ -25,9 +25,20 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --nostress-opt --allow-natives-syntax +// Flags: --nostress-opt --allow-natives-syntax --mock-arraybuffer-allocator var maxSize = %MaxSmi() + 1; -var ab = new ArrayBuffer(maxSize); +var ab; + +// Allocate the largest ArrayBuffer we can on this architecture. +for (k = 8; k >= 1 && ab == null; k = k/2) { + try { + ab = new ArrayBuffer(maxSize * k); + } catch (e) { + ab = null; + } +} + +assertTrue(ab != null); function TestArray(constr) { assertThrows(function() { @@ -44,4 +55,3 @@ TestArray(Int32Array); TestArray(Float32Array); TestArray(Float64Array); TestArray(Uint8ClampedArray); - diff --git a/deps/v8/test/mjsunit/regress/regress-320532.js b/deps/v8/test/mjsunit/regress/regress-320532.js new file mode 100644 index 0000000000..6ec4b97293 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-320532.js @@ -0,0 +1,42 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc +// Flags: --noalways-opt +// Flags: --stress-runs=8 --send-idle-notification --gc-global + + +function bar() { return new Array(); } +bar(); +bar(); +%OptimizeFunctionOnNextCall(bar); +a = bar(); +function foo(len) { return new Array(len); } +foo(0); +foo(0); +%OptimizeFunctionOnNextCall(bar); +foo(0); diff --git a/deps/v8/test/mjsunit/regress/regress-323845.js b/deps/v8/test/mjsunit/regress/regress-323845.js new file mode 100644 index 0000000000..4e81657917 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-323845.js @@ -0,0 +1,47 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Regression test that breaks escape analysis because objects escape over +// the arguments object. + +// Flags: --allow-natives-syntax + +function h() { + g.arguments; +} + +function g(x) { + h(); +} + +function f() { + g({}); +} + +f(); f(); f(); +%OptimizeFunctionOnNextCall(f); +f(); diff --git a/deps/v8/test/mjsunit/regress/regress-324028.js b/deps/v8/test/mjsunit/regress/regress-324028.js new file mode 100644 index 0000000000..7fe0fcd81f --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-324028.js @@ -0,0 +1,38 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var badObj = { length : 1e40 }; + +assertThrows(function() { new Uint8Array(badObj); }, RangeError); +assertThrows(function() { new Uint8ClampedArray(badObj); }, RangeError); +assertThrows(function() { new Int8Array(badObj); }, RangeError); +assertThrows(function() { new Uint16Array(badObj); }, RangeError); +assertThrows(function() { new Int16Array(badObj); }, RangeError); +assertThrows(function() { new Uint32Array(badObj); }, RangeError); +assertThrows(function() { new Int32Array(badObj); }, RangeError); +assertThrows(function() { new Float32Array(badObj); }, RangeError); +assertThrows(function() { new Float64Array(badObj); }, RangeError); diff --git a/deps/v8/test/mjsunit/regress/regress-325676.js b/deps/v8/test/mjsunit/regress/regress-325676.js new file mode 100644 index 0000000000..427bbc38dc --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-325676.js @@ -0,0 +1,69 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --expose-debug-as debug + +// If a function parameter is forced to be context allocated, +// debug evaluate need to resolve it to a context slot instead of +// parameter slot on the stack. + +var Debug = debug.Debug; + +var expected; +var exception = null; + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + try { + assertEquals(expected, exec_state.frame(0).evaluate('arg').value()); + exec_state.frame(0).evaluate('arg = "evaluated";'); + } catch (e) { + exception = e; + } +} + +Debug.setListener(listener); + +function f(arg) { + expected = arg; + debugger; + assertEquals("evaluated", arg); + + arg = "value"; + expected = arg; + debugger; + assertEquals("evaluated", arg); + + // Forces arg to be context allocated even though a parameter. + function g() { arg; } +} + +f(); +f(1); +f(1, 2); + +assertNull(exception); diff --git a/deps/v8/test/mjsunit/regress/regress-331416.js b/deps/v8/test/mjsunit/regress/regress-331416.js new file mode 100644 index 0000000000..0c60fced14 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-331416.js @@ -0,0 +1,52 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function load(a, i) { + return a[i]; +} +load([1, 2, 3], "length"); +load(3); +load([1, 2, 3], 3); +load(0, 0); +%OptimizeFunctionOnNextCall(load); +assertEquals(2, load([1, 2, 3], 1)); +assertEquals(undefined, load(0, 0)); + +function store(a, i, x) { + a[i] = x; +} +store([1, 2, 3], "length", 3); +store(3); +store([1, 2, 3], 3, 3); +store(0, 0, 1); +%OptimizeFunctionOnNextCall(store); +var a = [1, 2, 3]; +store(a, 1, 1); +assertEquals(1, a[1]); +store(0, 0, 1); diff --git a/deps/v8/test/mjsunit/regress/regress-336820.js b/deps/v8/test/mjsunit/regress/regress-336820.js new file mode 100644 index 0000000000..9b46629604 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-336820.js @@ -0,0 +1,36 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +assertThrows((function() { + s = "Hello World!\n"; + while (true) { + x = new Array(); + x[0] = s; + x[1000] = s; + x[1000000] = s; + s = x.join("::"); + }}), RangeError); diff --git a/deps/v8/test/mjsunit/regress/regress-340125.js b/deps/v8/test/mjsunit/regress/regress-340125.js new file mode 100644 index 0000000000..a3e40a8d5a --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-340125.js @@ -0,0 +1,30 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +var a = new Int8Array(2); +var b = a.subarray(2, 4); +assertThrows(function () { a.set(b, 1e10); }, RangeError); diff --git a/deps/v8/test/mjsunit/regress/regress-45469.js b/deps/v8/test/mjsunit/regress/regress-45469.js index 832a73f063..1abe0f9d77 100644 --- a/deps/v8/test/mjsunit/regress/regress-45469.js +++ b/deps/v8/test/mjsunit/regress/regress-45469.js @@ -42,5 +42,3 @@ for (var i = 0; i < 15; i++) { var res = re.test("xx"); assertEquals(i % 3 != 2, res, "testres" + i); } - - diff --git a/deps/v8/test/mjsunit/regress/regress-483.js b/deps/v8/test/mjsunit/regress/regress-483.js index db93f59d0c..7370134d6d 100644 --- a/deps/v8/test/mjsunit/regress/regress-483.js +++ b/deps/v8/test/mjsunit/regress/regress-483.js @@ -32,4 +32,3 @@ function X() { X.prototype.x = {x:1} new X() - diff --git a/deps/v8/test/mjsunit/regress/regress-490.js b/deps/v8/test/mjsunit/regress/regress-490.js index 8dd8959171..6ce89db2f0 100644 --- a/deps/v8/test/mjsunit/regress/regress-490.js +++ b/deps/v8/test/mjsunit/regress/regress-490.js @@ -42,6 +42,9 @@ for (var i = 0; i < 10; i++) { var b = ''; for (var j = 0; j < 10; j++) { b += '$1'; + + // TODO(machenbach): Do we need all these replacements? Wouldn't corner + // cases like smallest and biggest suffice? a.replace(/^(.*)/, b); } a += a; diff --git a/deps/v8/test/mjsunit/regress/regress-588599.js b/deps/v8/test/mjsunit/regress/regress-588599.js index a1c16e245a..eece4926e3 100644 --- a/deps/v8/test/mjsunit/regress/regress-588599.js +++ b/deps/v8/test/mjsunit/regress/regress-588599.js @@ -28,4 +28,3 @@ assertFalse(Infinity == -Infinity); assertEquals(Infinity, 1 / 1e-9999); assertEquals(-Infinity, 1 / -1e-9999); - diff --git a/deps/v8/test/mjsunit/regress/regress-619.js b/deps/v8/test/mjsunit/regress/regress-619.js index 4d3e66b298..c18a8ac964 100644 --- a/deps/v8/test/mjsunit/regress/regress-619.js +++ b/deps/v8/test/mjsunit/regress/regress-619.js @@ -58,4 +58,3 @@ for(var i = 0; i < 1024; i++) { for(var i = 0; i < 1024; i++) { assertEquals(i, obj[i]); } - diff --git a/deps/v8/test/mjsunit/regress/regress-634-debug.js b/deps/v8/test/mjsunit/regress/regress-634-debug.js new file mode 100644 index 0000000000..17ca828c68 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-634-debug.js @@ -0,0 +1,41 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function f() { + %SetAllocationTimeout(1, 0, false); + a = new Array(0); + assertEquals(0, a.length); + assertEquals(0, a.length); + %SetAllocationTimeout(-1, -1, true); +} + +f(); +f(); +%OptimizeFunctionOnNextCall(f); +f(); diff --git a/deps/v8/test/mjsunit/regress/regress-670147.js b/deps/v8/test/mjsunit/regress/regress-670147.js index b5b00d071a..916c13db31 100644 --- a/deps/v8/test/mjsunit/regress/regress-670147.js +++ b/deps/v8/test/mjsunit/regress/regress-670147.js @@ -31,4 +31,3 @@ function XXX(x) { } assertFalse(XXX('Hello')); - diff --git a/deps/v8/test/mjsunit/regress/regress-674753.js b/deps/v8/test/mjsunit/regress/regress-674753.js index 361b457e47..b3704ea96a 100644 --- a/deps/v8/test/mjsunit/regress/regress-674753.js +++ b/deps/v8/test/mjsunit/regress/regress-674753.js @@ -84,4 +84,3 @@ assertFalse(typeof 'x' == 'object'); // bug #674753 assertFalse(typeof 'x' === 'object'); assertFalse(typeof Object == 'object'); assertFalse(typeof Object === 'object'); - diff --git a/deps/v8/test/mjsunit/regress/regress-675.js b/deps/v8/test/mjsunit/regress/regress-675.js index 19ca646f61..bef7b27a41 100644 --- a/deps/v8/test/mjsunit/regress/regress-675.js +++ b/deps/v8/test/mjsunit/regress/regress-675.js @@ -58,4 +58,3 @@ this.y = 42; // Check that IC bails out. assertEquals(42, g()); - diff --git a/deps/v8/test/mjsunit/regress/regress-678525.js b/deps/v8/test/mjsunit/regress/regress-678525.js index 11eaf74fc8..49059c6f14 100644 --- a/deps/v8/test/mjsunit/regress/regress-678525.js +++ b/deps/v8/test/mjsunit/regress/regress-678525.js @@ -55,5 +55,3 @@ assertEquals('\027', '\27'); assertEquals(73, '\111'.charCodeAt(0)); assertEquals(105, '\151'.charCodeAt(0)); - - diff --git a/deps/v8/test/mjsunit/regress/regress-734862.js b/deps/v8/test/mjsunit/regress/regress-734862.js index 6239047310..40e5b1dcdb 100644 --- a/deps/v8/test/mjsunit/regress/regress-734862.js +++ b/deps/v8/test/mjsunit/regress/regress-734862.js @@ -34,4 +34,3 @@ assertTrue(catcher(null, 'foo') instanceof TypeError); assertTrue(catcher(void 0, 'foo') instanceof TypeError); assertTrue(catcher(null, 123) instanceof TypeError); assertTrue(catcher(void 0, 123) instanceof TypeError); - diff --git a/deps/v8/test/mjsunit/regress/regress-74.js b/deps/v8/test/mjsunit/regress/regress-74.js index f22b33c155..bdc3b5cf79 100644 --- a/deps/v8/test/mjsunit/regress/regress-74.js +++ b/deps/v8/test/mjsunit/regress/regress-74.js @@ -38,4 +38,3 @@ function test() { } test(); - diff --git a/deps/v8/test/mjsunit/regress/regress-753.js b/deps/v8/test/mjsunit/regress/regress-753.js index 4621de6ba4..0253962f50 100644 --- a/deps/v8/test/mjsunit/regress/regress-753.js +++ b/deps/v8/test/mjsunit/regress/regress-753.js @@ -33,4 +33,3 @@ var obj = {a1: {b1: [1,2,3,4], b2: {c1: 1, c2: 2}},a2: 'a2'}; assertEquals(JSON.stringify(obj, null, 5.99999), JSON.stringify(obj, null, 5)); - diff --git a/deps/v8/test/mjsunit/regress/regress-806473.js b/deps/v8/test/mjsunit/regress/regress-806473.js index 6d6485d6e9..91c9a9f60b 100644 --- a/deps/v8/test/mjsunit/regress/regress-806473.js +++ b/deps/v8/test/mjsunit/regress/regress-806473.js @@ -56,5 +56,3 @@ for (var j = 0; j < 10; j++) { assertEquals(10, i); assertEquals(10, j); - - diff --git a/deps/v8/test/mjsunit/regress/regress-85177.js b/deps/v8/test/mjsunit/regress/regress-85177.js index 275bbe7a9b..aa938f5e24 100644 --- a/deps/v8/test/mjsunit/regress/regress-85177.js +++ b/deps/v8/test/mjsunit/regress/regress-85177.js @@ -62,4 +62,3 @@ function f(){ f(); %OptimizeFunctionOnNextCall(f); f(); - diff --git a/deps/v8/test/mjsunit/regress/regress-892742.js b/deps/v8/test/mjsunit/regress/regress-892742.js index 78a57b2ad5..fd79fc0fac 100644 --- a/deps/v8/test/mjsunit/regress/regress-892742.js +++ b/deps/v8/test/mjsunit/regress/regress-892742.js @@ -45,4 +45,3 @@ function h() { assertEquals(1, f()); assertEquals(undefined, g()); assertEquals(undefined, h()); - diff --git a/deps/v8/test/mjsunit/regress/regress-925537.js b/deps/v8/test/mjsunit/regress/regress-925537.js index d50c5689a5..6d75504693 100644 --- a/deps/v8/test/mjsunit/regress/regress-925537.js +++ b/deps/v8/test/mjsunit/regress/regress-925537.js @@ -39,4 +39,3 @@ assertClose( Math.PI / 4, Math.atan2(pinf, pinf)); assertClose(-Math.PI / 4, Math.atan2(ninf, pinf)); assertClose( 3 * Math.PI / 4, Math.atan2(pinf, ninf)); assertClose(-3 * Math.PI / 4, Math.atan2(ninf, ninf)); - diff --git a/deps/v8/test/mjsunit/regress/regress-94873.js b/deps/v8/test/mjsunit/regress/regress-94873.js index 41ca9921c6..b61bc0c15d 100644 --- a/deps/v8/test/mjsunit/regress/regress-94873.js +++ b/deps/v8/test/mjsunit/regress/regress-94873.js @@ -75,4 +75,4 @@ function a(x, y) { } Debug.setBreakPoint(a, 0, 0); -new a(1, 2);
\ No newline at end of file +new a(1, 2); diff --git a/deps/v8/test/mjsunit/regress/regress-990205.js b/deps/v8/test/mjsunit/regress/regress-990205.js index b3024c23fd..7eb66f0616 100644 --- a/deps/v8/test/mjsunit/regress/regress-990205.js +++ b/deps/v8/test/mjsunit/regress/regress-990205.js @@ -36,4 +36,3 @@ function f() { }; assertThrows("f()"); - diff --git a/deps/v8/test/mjsunit/regress/regress-995.js b/deps/v8/test/mjsunit/regress/regress-995.js index e88121a20c..6f3dac1330 100644 --- a/deps/v8/test/mjsunit/regress/regress-995.js +++ b/deps/v8/test/mjsunit/regress/regress-995.js @@ -54,4 +54,3 @@ function h(value) { } } h(undefined); - diff --git a/deps/v8/test/mjsunit/regress/regress-998565.js b/deps/v8/test/mjsunit/regress/regress-998565.js index 260b791186..840c045c0c 100644 --- a/deps/v8/test/mjsunit/regress/regress-998565.js +++ b/deps/v8/test/mjsunit/regress/regress-998565.js @@ -48,4 +48,4 @@ Debug.setBreakPoint(f, 0, 0); f(); // Make sure that the debug event listener vas invoked. -assertTrue(listenerCalled);
\ No newline at end of file +assertTrue(listenerCalled); diff --git a/deps/v8/test/mjsunit/regress/regress-add-minus-zero.js b/deps/v8/test/mjsunit/regress/regress-add-minus-zero.js index 0b4af75424..cb77cdfb61 100644 --- a/deps/v8/test/mjsunit/regress/regress-add-minus-zero.js +++ b/deps/v8/test/mjsunit/regress/regress-add-minus-zero.js @@ -35,4 +35,3 @@ assertEquals("Infinity", String(1/f())); assertEquals("Infinity", String(1/f())); %OptimizeFunctionOnNextCall(f); assertEquals("Infinity", String(1/f())); - diff --git a/deps/v8/test/mjsunit/regress/regress-array-pop-deopt.js b/deps/v8/test/mjsunit/regress/regress-array-pop-deopt.js new file mode 100644 index 0000000000..9a0d35d3aa --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-array-pop-deopt.js @@ -0,0 +1,41 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +var o = [6,7,8,9]; + +function f(b) { + var v = o.pop() + b; + return v; +} + +assertEquals(10, f(1)); +assertEquals(9, f(1)); +assertEquals(8, f(1)); +%OptimizeFunctionOnNextCall(f); +assertEquals("61", f("1")); diff --git a/deps/v8/test/mjsunit/regress/regress-array-pop-nonconfigurable.js b/deps/v8/test/mjsunit/regress/regress-array-pop-nonconfigurable.js index 129e1980a4..823bb6b1a8 100644 --- a/deps/v8/test/mjsunit/regress/regress-array-pop-nonconfigurable.js +++ b/deps/v8/test/mjsunit/regress/regress-array-pop-nonconfigurable.js @@ -28,4 +28,3 @@ var a = []; Object.defineProperty(a, 0, {}); assertThrows(function() { a.pop(); }); - diff --git a/deps/v8/test/mjsunit/regress/regress-binop-nosse2.js b/deps/v8/test/mjsunit/regress/regress-binop-nosse2.js index c6cbaf7ebf..29c8a048fc 100644 --- a/deps/v8/test/mjsunit/regress/regress-binop-nosse2.js +++ b/deps/v8/test/mjsunit/regress/regress-binop-nosse2.js @@ -165,4 +165,3 @@ assertEquals(t2(1.3,null), 1.3/0); assertEquals(t2(undefined,2), NaN/2); assertEquals(t2(1,1<<30), 1/(1<<30)); assertEquals(t2(1,2), 1/2); - diff --git a/deps/v8/test/mjsunit/regress/regress-builtin-array-op.js b/deps/v8/test/mjsunit/regress/regress-builtin-array-op.js index 1e37af3648..ea5891f7df 100644 --- a/deps/v8/test/mjsunit/regress/regress-builtin-array-op.js +++ b/deps/v8/test/mjsunit/regress/regress-builtin-array-op.js @@ -35,4 +35,3 @@ var a = [2,3,1]; a[100000] = 0; a.join(); assertEquals("hest", foo); - diff --git a/deps/v8/test/mjsunit/regress/regress-check-eliminate-loop-phis.js b/deps/v8/test/mjsunit/regress/regress-check-eliminate-loop-phis.js new file mode 100644 index 0000000000..3791c35f71 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-check-eliminate-loop-phis.js @@ -0,0 +1,21 @@ +// 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 + +function f() { + var o = {x:1}; + var y = {y:2.5, x:0}; + var result; + for (var i = 0; i < 2; i++) { + result = o.x + 3; + o = y; + } + return result; +} + +f(); +f(); +%OptimizeFunctionOnNextCall(f); +assertEquals(3, f()); diff --git a/deps/v8/test/mjsunit/regress/regress-clobbered-fp-regs.js b/deps/v8/test/mjsunit/regress/regress-clobbered-fp-regs.js new file mode 100644 index 0000000000..7795ae9a30 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-clobbered-fp-regs.js @@ -0,0 +1,54 @@ +// Copyright 2011 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Flags: --allow-natives-syntax + +function store(a, x, y) { + var f1 = 0.1 * y; + var f2 = 0.2 * y; + var f3 = 0.3 * y; + var f4 = 0.4 * y; + var f5 = 0.5 * y; + var f6 = 0.6 * y; + var f7 = 0.7 * y; + var f8 = 0.8 * y; + a[0] = x; + var sum = (f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8); + assertEquals(1, y); + var expected = 3.6; + if (Math.abs(expected - sum) > 0.01) { + assertEquals(expected, sum); + } +} + +// Generate TransitionElementsKindStub. +store([1], 1, 1); +store([1], 1.1, 1); +store([1], 1.1, 1); +%OptimizeFunctionOnNextCall(store); +// This will trap on allocation site in TransitionElementsKindStub. +store([1], 1, 1) diff --git a/deps/v8/test/mjsunit/regress/regress-context-osr.js b/deps/v8/test/mjsunit/regress/regress-context-osr.js new file mode 100644 index 0000000000..b74907de6a --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-context-osr.js @@ -0,0 +1,39 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"use strict"; +function f() { + try { } catch (e) { } +} + +for (this.x = 0; this.x < 1; ++this.x) { + for (this.y = 0; this.y < 1; ++this.y) { + for (this.ll = 0; this.ll < 70670; ++this.ll) { + f(); + } + } +} diff --git a/deps/v8/test/mjsunit/regress/regress-convert-hole2.js b/deps/v8/test/mjsunit/regress/regress-convert-hole2.js index b434ed3996..02ef4dd1dd 100644 --- a/deps/v8/test/mjsunit/regress/regress-convert-hole2.js +++ b/deps/v8/test/mjsunit/regress/regress-convert-hole2.js @@ -24,7 +24,7 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --allow-natives-syntax --notrack-allocation-sites +// Flags: --allow-natives-syntax // Test adding undefined from hole in double-holey to string. var a = [1.5, , 1.8]; diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-158185.js b/deps/v8/test/mjsunit/regress/regress-crbug-158185.js index 99f19c72fd..5cb5900c8a 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-158185.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-158185.js @@ -36,4 +36,3 @@ assertEquals("12A", assertEquals(1, JSON.parse('{"0":1}')[0]); assertEquals(undefined, JSON.parse('{"00":1}')[0]); - diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-178790.js b/deps/v8/test/mjsunit/regress/regress-crbug-178790.js index 57071eaa08..25cc96b852 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-178790.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-178790.js @@ -49,4 +49,3 @@ for (var i = 0; i < 1000; i++) { r3 = "(" + r3 + ")a"; } "test".match(RegExp(r3)); - diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-18639.js b/deps/v8/test/mjsunit/regress/regress-crbug-18639.js index 4f4bb7c796..6c8e6ad2c6 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-18639.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-18639.js @@ -35,4 +35,4 @@ try { ((0).toLocaleString)(); } catch (e) { assertInstanceof(e, TypeError); -}
\ No newline at end of file +} diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-222893.js b/deps/v8/test/mjsunit/regress/regress-crbug-222893.js index d5baa7b257..39363bc912 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-222893.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-222893.js @@ -61,4 +61,3 @@ function g(a, b) { g.apply(this, array); g("a", "b", "c"); assertNull(error); - diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-233737.js b/deps/v8/test/mjsunit/regress/regress-crbug-233737.js index 835726b224..38b44e056f 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-233737.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-233737.js @@ -39,4 +39,4 @@ function hole(i) { assertEquals(1, hole(0)); assertEquals(1, hole(0)); %OptimizeFunctionOnNextCall(hole); -assertEquals(0, hole(1));
\ No newline at end of file +assertEquals(0, hole(1)); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-244461.js b/deps/v8/test/mjsunit/regress/regress-crbug-244461.js index 9c7c2b6c43..7b465482e0 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-244461.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-244461.js @@ -26,7 +26,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax --smi-only-arrays -// Flags: --track-allocation-sites function foo(arg) { var a = arg(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-245480.js b/deps/v8/test/mjsunit/regress/regress-crbug-245480.js index 4769486403..ec8850905b 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-245480.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-245480.js @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax --smi-only-arrays --expose-gc -// Flags: --track-allocation-sites --noalways-opt +// Flags: --noalways-opt // Test element kind of objects. // Since --smi-only-arrays affects builtins, its default setting at compile @@ -87,4 +87,4 @@ function g(a) { var b = [0]; g(b); g(b); -assertEquals(undefined, g(a));
\ No newline at end of file +assertEquals(undefined, g(a)); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-259300.js b/deps/v8/test/mjsunit/regress/regress-crbug-259300.js index c57b0e6f91..eac494a0e6 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-259300.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-259300.js @@ -46,4 +46,3 @@ Debug.setListener(listener); eval("debugger"); Debug.setListener(null); assertTrue(listened); - diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-306220.js b/deps/v8/test/mjsunit/regress/regress-crbug-306220.js new file mode 100644 index 0000000000..a481ee9dba --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-306220.js @@ -0,0 +1,38 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var CustomError = function(x) { this.x = x; }; +CustomError.prototype = new Error(); +CustomError.prototype.x = "prototype"; + +Object.defineProperties(CustomError.prototype, { + 'message': { + 'get': function() { return this.x; } + } +}); + +assertEquals("Error: instance", String(new CustomError("instance"))); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-315252.js b/deps/v8/test/mjsunit/regress/regress-crbug-315252.js new file mode 100644 index 0000000000..51454bf285 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-315252.js @@ -0,0 +1,61 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function f(a, b, c) { + this.a = a; + this.b = b; + this.c = c; +} +var o3 = new f(1, 2, 3.5); +var o4 = new f(1, 2.5, 3); +var o1 = new f(1.5, 2, 3); +var o2 = new f(1.5, 2, 3); +function migrate(o) { + return o.a; +} +// Use migrate to stabilize o1, o2 and o4 in [double, double, smi]. +migrate(o4); +migrate(o1); +migrate(o2); +function store_transition(o) { + o.d = 1; +} +// Optimize "store_transition" to transition from [double, double, smi] to +// [double, double, smi, smi]. This adds a dependency on the +// [double, double, smi] map. +store_transition(o4); +store_transition(o1); +store_transition(o2); +%OptimizeFunctionOnNextCall(store_transition); +// Pass in a deprecated object of format [smi, smi, double]. This will migrate +// the instance, forcing a merge with [double, double, smi], ending up with +// [double, double, double], which deprecates [double, double, smi] and +// deoptimizes all dependencies of [double, double, smi], including +// store_transition itself. +store_transition(o3); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-3184.js b/deps/v8/test/mjsunit/regress/regress-crbug-3184.js index ed78183f78..054668ea55 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-3184.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-3184.js @@ -80,4 +80,3 @@ Object.extend( Array.prototype, }); assertEquals("Test1 test1", "test1 test1".cap()); assertEquals("Test2 Test2", "test2 test2".cap(true)); - diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-320922.js b/deps/v8/test/mjsunit/regress/regress-crbug-320922.js new file mode 100644 index 0000000000..4a5b5813e0 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-320922.js @@ -0,0 +1,48 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +var string = "hello world"; +var expected = "Hello " + "world"; +function Capitalize() { + %_OneByteSeqStringSetChar(string, 0, 0x48); +} +Capitalize(); +assertEquals(expected, string); +Capitalize(); +assertEquals(expected, string); + +var twobyte = "\u20ACello world"; + +function TwoByteCapitalize() { + %_TwoByteSeqStringSetChar(twobyte, 0, 0x48); +} +TwoByteCapitalize(); +assertEquals(expected, twobyte); +TwoByteCapitalize(); +assertEquals(expected, twobyte); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-323942.js b/deps/v8/test/mjsunit/regress/regress-crbug-323942.js new file mode 100644 index 0000000000..15af494b0f --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-323942.js @@ -0,0 +1,57 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +"use strict"; + +// Function is defined on the prototype chain. +var holder = { f: function() { return 42; } }; +var receiver = { }; +receiver.__proto__ = { }; +receiver.__proto__.__proto__ = holder; + +// Inline two levels. +function h(o) { return o.f.apply(this, arguments); } +function g(o) { return h(o); } + +// Collect type information for apply call. +assertEquals(42, g(receiver)); +assertEquals(42, g(receiver)); + +// Sneakily remove the function from the prototype chain. +// The receiver map does not change. +receiver.__proto__.__proto__ = {}; + +// Lookup of o.f during graph creation fails. +%OptimizeFunctionOnNextCall(g); + +assertThrows(function() { g(receiver); }); + +// Put function back. +receiver.__proto__.__proto__ = holder; +assertEquals(42, g(receiver)); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-325225.js b/deps/v8/test/mjsunit/regress/regress-crbug-325225.js new file mode 100644 index 0000000000..798d54839d --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-325225.js @@ -0,0 +1,46 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +function f1(a) { + a[0](0); +} + +function do1() { + f1([f1]); +} + +assertThrows(do1, TypeError); + +function f2(a) { + a[0](true); +} + +function do2() { + f2([function(a) { return f2("undefined", typeof f2(42, 0)); }]); +} + +assertThrows(do2, TypeError); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-329709.js b/deps/v8/test/mjsunit/regress/regress-crbug-329709.js new file mode 100644 index 0000000000..c5316f391c --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-329709.js @@ -0,0 +1,41 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function boom(x) { + switch(x) { + case 1: return "one"; + case 1500000000: return "non-smi int32"; + default: return "default"; + } +} + +assertEquals("one", boom(1)); +assertEquals("one", boom(1)); +%OptimizeFunctionOnNextCall(boom) +assertEquals("non-smi int32", boom(1500000000)); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-336148.js b/deps/v8/test/mjsunit/regress/regress-crbug-336148.js new file mode 100644 index 0000000000..8157c9fcc1 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-336148.js @@ -0,0 +1,56 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function f(o) { + var a = 1; + if (true) return o.v && a; +} + +f({}); +f({}); +%OptimizeFunctionOnNextCall(f); +assertEquals(1, f({ v: 1 })); + + +function f1() { return 1 && 2; }; +function f2() { return 1 || 2; }; +function f3() { return 0 && 2; }; +function f4() { return 0 || 2; }; + +function test() { + assertEquals(2, f1()); + assertEquals(1, f2()); + assertEquals(0, f3()); + assertEquals(2, f4()); +} + +test(); +test(); +[f1, f2, f3, f4].forEach(function(f) { %OptimizeFunctionOnNextCall(f); }); +test(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-340064.js b/deps/v8/test/mjsunit/regress/regress-crbug-340064.js new file mode 100644 index 0000000000..f2ab1d6675 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-340064.js @@ -0,0 +1,38 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function f(v) { + return v.length; +} + +assertEquals(4, f("test")); +assertEquals(4, f("test")); +assertEquals(undefined, f(true)); +%OptimizeFunctionOnNextCall(f); +assertEquals(undefined, f(true)); diff --git a/deps/v8/test/mjsunit/regress/regress-frame-details-null-receiver.js b/deps/v8/test/mjsunit/regress/regress-frame-details-null-receiver.js index d15ed4d00a..ffe5fbb84c 100644 --- a/deps/v8/test/mjsunit/regress/regress-frame-details-null-receiver.js +++ b/deps/v8/test/mjsunit/regress/regress-frame-details-null-receiver.js @@ -49,4 +49,3 @@ Debug.clearBreakOnException(); Debug.setListener(null); assertTrue(listened); - diff --git a/deps/v8/test/mjsunit/regress/regress-is-contextual.js b/deps/v8/test/mjsunit/regress/regress-is-contextual.js new file mode 100644 index 0000000000..844f4a2264 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-is-contextual.js @@ -0,0 +1,41 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// CallIC accumulates feedback that string index is out of bounds, then +// misses +function foo(index) { + return text.charAt(index); +} + +var text = "hi there"; +foo(0); +foo(0); +foo(100); // Accumulate feedback that index is out of bounds. +text = false; + +// This line ASSERTS in debug without fix. +assertThrows(function () { foo(); }, TypeError); diff --git a/deps/v8/test/mjsunit/regress/regress-json-stringify-gc.js b/deps/v8/test/mjsunit/regress/regress-json-stringify-gc.js index 4b355ae1ac..905ab40694 100644 --- a/deps/v8/test/mjsunit/regress/regress-json-stringify-gc.js +++ b/deps/v8/test/mjsunit/regress/regress-json-stringify-gc.js @@ -26,9 +26,9 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. var a = []; -var new_space_string = ""; -for (var i = 0; i < 128; i++) { - new_space_string += String.fromCharCode((Math.random() * 26 + 65) | 0); +var new_space_string = "a"; +for (var i = 0; i < 8; i++) { + new_space_string += new_space_string; } for (var i = 0; i < 10000; i++) a.push(new_space_string); @@ -40,12 +40,12 @@ json2 = JSON.stringify(a); assertTrue(json1 == json2, "GC caused JSON.stringify to fail."); // Check that the slow path of JSON.stringify works correctly wrt GC. -for (var i = 0; i < 100000; i++) { +for (var i = 0; i < 10000; i++) { var s = i.toString(); assertEquals('"' + s + '"', JSON.stringify(s, null, 0)); } -for (var i = 0; i < 100000; i++) { +for (var i = 0; i < 10000; i++) { var s = i.toString() + "\u2603"; assertEquals('"' + s + '"', JSON.stringify(s, null, 0)); } diff --git a/deps/v8/test/mjsunit/regress/regress-keyed-access-string-length.js b/deps/v8/test/mjsunit/regress/regress-keyed-access-string-length.js new file mode 100644 index 0000000000..f2ead686c6 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-keyed-access-string-length.js @@ -0,0 +1,37 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function f(i) { + return "abc"[i]; +} + +f("length"); +f("length"); +%OptimizeFunctionOnNextCall(f); +f("length"); diff --git a/deps/v8/test/mjsunit/regress/regress-lookup-transition.js b/deps/v8/test/mjsunit/regress/regress-lookup-transition.js new file mode 100644 index 0000000000..9b32939306 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-lookup-transition.js @@ -0,0 +1,14 @@ +// 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-proxies --expose-gc + +var proxy = Proxy.create({ getPropertyDescriptor:function(key) { + gc(); +}}); + +function f() { this.x = 23; } +f.prototype = proxy; +new f(); +new f(); diff --git a/deps/v8/test/mjsunit/regress/regress-map-invalidation-1.js b/deps/v8/test/mjsunit/regress/regress-map-invalidation-1.js index bcc6bbb615..430972b75a 100644 --- a/deps/v8/test/mjsunit/regress/regress-map-invalidation-1.js +++ b/deps/v8/test/mjsunit/regress/regress-map-invalidation-1.js @@ -30,7 +30,7 @@ var c = { x: 2, y: 1 }; function h() { - %MigrateInstance(c); + %TryMigrateInstance(c); return 2; } %NeverOptimizeFunction(h); @@ -45,4 +45,3 @@ function f() { } f(); - diff --git a/deps/v8/test/mjsunit/regress/regress-map-invalidation-2.js b/deps/v8/test/mjsunit/regress/regress-map-invalidation-2.js index 1f896a495f..7674e425cb 100644 --- a/deps/v8/test/mjsunit/regress/regress-map-invalidation-2.js +++ b/deps/v8/test/mjsunit/regress/regress-map-invalidation-2.js @@ -47,7 +47,9 @@ function g() { var fun = g(); fun(false, c); fun(false, c); +%OptimizeFunctionOnNextCall(fun); fun(false, c); +%TryMigrateInstance(c); %OptimizeFunctionOnNextCall(fun); fun(false, c); fun(true, c); diff --git a/deps/v8/test/mjsunit/regress/regress-param-local-type.js b/deps/v8/test/mjsunit/regress/regress-param-local-type.js new file mode 100644 index 0000000000..bf26090089 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-param-local-type.js @@ -0,0 +1,58 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +// Test that we do not confuse the first local and the first parameter +// when gathering type information. + +function f(a) { // First parameter is tagged. + var s = ''; // First local has string type. + var n = 0; + var i = 1; + n = i + a; +} + +f(1); +f(1); +%OptimizeFunctionOnNextCall(f); +f(1); +assertOptimized(f); + + +function g() { // 0th parameter (receiver) is tagged. + var s = ''; // First local has string type. + var n = 0; + var i = 1; + n = i + this; +} + +g.call(1); +g.call(1); +%OptimizeFunctionOnNextCall(g); +g.call(1); +assertOptimized(g); diff --git a/deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex1.js b/deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex1.js index be54be6740..c85cf56e0c 100644 --- a/deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex1.js +++ b/deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex1.js @@ -57,4 +57,3 @@ StringFromCharCode(0x7C, 0x7C); %OptimizeFunctionOnNextCall(StringFromCharCode); StringFromCharCode(0x7C, 0x7C); StringFromCharCode(0xFFF, 0xFFF); - diff --git a/deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex2.js b/deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex2.js index 6acc2f285e..6a5ba9195c 100644 --- a/deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex2.js +++ b/deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex2.js @@ -32,4 +32,3 @@ String.fromCharCode(0x7C, 0x7C); %OptimizeFunctionOnNextCall(String.fromCharCode); String.fromCharCode(0x7C, 0x7C); String.fromCharCode(0xFFF, 0xFFF); - diff --git a/deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex3.js b/deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex3.js index e2592a1615..43d2b08352 100644 --- a/deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex3.js +++ b/deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex3.js @@ -42,4 +42,3 @@ test(); test(); %OptimizeFunctionOnNextCall(test); test(); - diff --git a/deps/v8/test/mjsunit/regress/regress-transcendental.js b/deps/v8/test/mjsunit/regress/regress-transcendental.js index b5dbcb48af..4065f50bbe 100644 --- a/deps/v8/test/mjsunit/regress/regress-transcendental.js +++ b/deps/v8/test/mjsunit/regress/regress-transcendental.js @@ -46,4 +46,3 @@ function test(f, x, name) { test(Math.tan, -1.57079632679489660000, "Math.tan"); test(Math.sin, 6.283185307179586, "Math.sin"); - diff --git a/deps/v8/test/mjsunit/regress/setvalueof-deopt.js b/deps/v8/test/mjsunit/regress/setvalueof-deopt.js new file mode 100644 index 0000000000..8c42c8a20b --- /dev/null +++ b/deps/v8/test/mjsunit/regress/setvalueof-deopt.js @@ -0,0 +1,42 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function g(x, y) { + return y; +} + +function f(deopt) { + return g(%_SetValueOf(1, 1), deopt + 0); +} + +f(0); +f(0); +f(0); +%OptimizeFunctionOnNextCall(f); +assertEquals("result0", f("result")); diff --git a/deps/v8/test/mjsunit/regress/string-set-char-deopt.js b/deps/v8/test/mjsunit/regress/string-set-char-deopt.js new file mode 100644 index 0000000000..9f6d434538 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/string-set-char-deopt.js @@ -0,0 +1,85 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +(function OneByteSeqStringSetCharDeoptOsr() { + function deopt() { + %DeoptimizeFunction(f); + } + + function f(string, osr) { + var world = " world"; + %_OneByteSeqStringSetChar(string, 0, (deopt(), 0x48)); + + if (osr) while (%GetOptimizationStatus(f) == 2) {} + + return string + world; + } + + assertEquals("Hello " + "world", f("hello", false)); + %OptimizeFunctionOnNextCall(f); + assertEquals("Hello " + "world", f("hello", true)); +})(); + + +(function OneByteSeqStringSetCharDeopt() { + function deopt() { + %DeoptimizeFunction(f); + } + + function g(x) { + } + + function f(string) { + g(%_OneByteSeqStringSetChar(string, 0, (deopt(), 0x48))); + return string; + } + + assertEquals("Hell" + "o", f("hello")); + %OptimizeFunctionOnNextCall(f); + assertEquals("Hell" + "o", f("hello")); +})(); + + +(function TwoByteSeqStringSetCharDeopt() { + function deopt() { + %DeoptimizeFunction(f); + } + + function g(x) { + } + + function f(string) { + g(%_TwoByteSeqStringSetChar(string, 0, (deopt(), 0x48))); + return string; + } + + assertEquals("Hell" + "o", f("\u20ACello")); + %OptimizeFunctionOnNextCall(f); + assertEquals("Hell" + "o", f("\u20ACello")); +})(); diff --git a/deps/v8/test/mjsunit/set-prototype-of.js b/deps/v8/test/mjsunit/set-prototype-of.js new file mode 100644 index 0000000000..02bd5e2ee6 --- /dev/null +++ b/deps/v8/test/mjsunit/set-prototype-of.js @@ -0,0 +1,170 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --harmony-symbols + + +function getObjects() { + function func() {} + return [ + func, + new func(), + {x: 5}, + /regexp/, + ['array'], + // new Error(), + new Date(), + new Number(1), + new Boolean(true), + new String('str'), + Object(Symbol()) + ]; +} + + +var coercibleValues = [ + 1, + true, + 'string', + Symbol() +]; + + +var nonCoercibleValues = [ + undefined, + null +]; + + +var valuesWithoutNull = coercibleValues.concat(undefined); + + +function TestSetPrototypeOfCoercibleValues() { + for (var i = 0; i < coercibleValues.length; i++) { + var value = coercibleValues[i]; + assertThrows(function() { + Object.getPrototypeOf(value); + }, TypeError); + + assertEquals(Object.setPrototypeOf(value, {}), value); + + assertThrows(function() { + Object.getPrototypeOf(value); + }, TypeError); + } +} +TestSetPrototypeOfCoercibleValues(); + + +function TestSetPrototypeOfNonCoercibleValues() { + for (var i = 0; i < nonCoercibleValues.length; i++) { + var value = nonCoercibleValues[i]; + assertThrows(function() { + Object.setPrototypeOf(value, {}); + }, TypeError); + } +} +TestSetPrototypeOfNonCoercibleValues(); + + +function TestSetPrototypeToNonObject(proto) { + var objects = getObjects(); + for (var i = 0; i < objects.length; i++) { + var object = objects[i]; + for (var j = 0; j < valuesWithoutNull.length; j++) { + var proto = valuesWithoutNull[j]; + assertThrows(function() { + Object.setPrototypeOf(object, proto); + }, TypeError); + } + } +} +TestSetPrototypeToNonObject(); + + +function TestSetPrototypeOf(object, proto) { + assertEquals(Object.setPrototypeOf(object, proto), object); + assertEquals(Object.getPrototypeOf(object), proto); +} + + +function TestSetPrototypeOfForObjects() { + var objects1 = getObjects(); + var objects2 = getObjects(); + for (var i = 0; i < objects1.length; i++) { + for (var j = 0; j < objects2.length; j++) { + TestSetPrototypeOf(objects1[i], objects2[j]); + } + } +} +TestSetPrototypeOfForObjects(); + + +function TestSetPrototypeToNull() { + var objects = getObjects(); + for (var i = 0; i < objects.length; i++) { + TestSetPrototypeOf(objects[i], null); + } +} +TestSetPrototypeToNull(); + + +function TestSetPrototypeOfNonExtensibleObject() { + var objects = getObjects(); + var proto = {}; + for (var i = 0; i < objects.length; i++) { + var object = objects[i]; + Object.preventExtensions(object); + assertThrows(function() { + Object.setPrototypeOf(object, proto); + }, TypeError); + } +} +TestSetPrototypeOfNonExtensibleObject(); + + +function TestLookup() { + var object = {}; + assertFalse('x' in object); + assertFalse('y' in object); + + var oldProto = { + x: 'old x', + y: 'old y' + }; + Object.setPrototypeOf(object, oldProto); + assertEquals(object.x, 'old x'); + assertEquals(object.y, 'old y'); + + var newProto = { + x: 'new x' + }; + Object.setPrototypeOf(object, newProto); + assertEquals(object.x, 'new x'); + assertFalse('y' in object); +} +TestLookup(); diff --git a/deps/v8/test/mjsunit/setters-on-elements.js b/deps/v8/test/mjsunit/setters-on-elements.js new file mode 100644 index 0000000000..dd3fabf309 --- /dev/null +++ b/deps/v8/test/mjsunit/setters-on-elements.js @@ -0,0 +1,199 @@ +// Copyright 2011 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --max-opt-count=100 --noalways-opt + +// We specify max-opt-count because we opt/deopt the same function many +// times. + +// It's nice to run this in other browsers too. +var standalone = false; +if (standalone) { + assertTrue = function(val) { + if (val != true) { + print("FAILURE"); + } + } + + assertFalse = function(val) { + if (val != false) { + print("FAILURE"); + } + } + + assertEquals = function(expected, val) { + if (expected !== val) { + print("FAILURE"); + } + } + + empty_func = function(name) { } + assertUnoptimized = empty_func; + assertOptimized = empty_func; + + optimize = empty_func; + clearFunctionTypeFeedback = empty_func; + deoptimizeFunction = empty_func; +} else { + optimize = function(name) { + %OptimizeFunctionOnNextCall(name); + } + clearFunctionTypeFeedback = function(name) { + %ClearFunctionTypeFeedback(name); + } + deoptimizeFunction = function(name) { + %DeoptimizeFunction(name); + } +} + +function base_setter_test(create_func, index, store_value) { + var calls = 0; + + // Testcase: setter in prototype chain + foo = function(a) { a[index] = store_value; } + var a = create_func(); + var ap = []; + ap.__defineSetter__(index, function() { calls++; }); + + foo(a); + foo(a); + foo(a); + delete a[index]; + + assertEquals(0, calls); + a.__proto__ = ap; + foo(a); + assertEquals(1, calls); + optimize(foo); + foo(a); + assertEquals(2, calls); + assertOptimized(foo); + + // Testcase: setter added on prototype chain object already in place. + clearFunctionTypeFeedback(foo); + deoptimizeFunction(foo); + clearFunctionTypeFeedback(foo); + calls = 0; + a = create_func(); + var apap = []; + a.__proto__ = apap; + foo(a); + foo(a); + foo(a); + delete a[index]; + apap.__defineSetter__(index, function() { calls++; }); + foo(a); + foo(a); + foo(a); + assertEquals(3, calls); + + // Testcase: setter "deep" in prototype chain. + clearFunctionTypeFeedback(foo); + deoptimizeFunction(foo); + clearFunctionTypeFeedback(foo); + calls = 0; + + a = create_func(); + var ap2 = []; + a.__proto__ = ap2; + foo(a); + foo(a); + foo(a); + delete a[index]; + + assertEquals(0, calls); + + ap2.__proto__ = ap; // "sneak" in a callback. + // The sneak case should be caught by unoptimized code too. + assertUnoptimized(foo); + foo(a); + foo(a); + foo(a); + assertEquals(3, calls); + + // Testcase: setter added after optimization (feedback is monomorphic) + clearFunctionTypeFeedback(foo); + deoptimizeFunction(foo); + clearFunctionTypeFeedback(foo); + calls = 0; + + a = create_func(); + ap2 = []; + a.__proto__ = ap2; + foo(a); + foo(a); + foo(a); + optimize(foo); + foo(a); + assertOptimized(foo); + delete a[index]; + ap2.__proto__ = ap; + foo(a); + assertUnoptimized(foo); // map shape change should deopt foo. + assertEquals(1, calls); + + // Testcase: adding additional setters to a prototype chain that already has + // one shouldn't deopt anything. (ie, we aren't changing the map shape). + clearFunctionTypeFeedback(foo); + calls = 0; + + a = create_func(); + a.__proto__ = ap2; + bar = function(a) { a[index+1] = store_value; } + bar(a); + bar(a); + bar(a); // store should be generic + optimize(bar); + bar(a); + assertOptimized(bar); + assertEquals(0, calls); + delete a[index+1]; + ap2.__defineSetter__(index+1, function() { calls++; }); + bar(a); + assertOptimized(bar); + assertEquals(1, calls); +} + +// Verify that map transitions don't confuse us. +create_func_smi = function() { return [,,,,,,5]; } +create_func_double = function() { return [0,,3.2,,,,5.5]; } +create_func_fast = function() { return [,,,,,,true]; } +create_func_dictionary = function() { var a = []; a.length = 100000; return a; } + +var cf = [create_func_smi, + create_func_double, + create_func_fast, + create_func_dictionary]; + +var values = [3, 3.5, true]; + +for(var c = 0; c < 3; c++) { + for(var s = 0; s < 3; s++) { + base_setter_test(cf[c], 0, values[s]); + base_setter_test(cf[c], 1, values[s]); + } +} diff --git a/deps/v8/test/mjsunit/shift-for-integer-div.js b/deps/v8/test/mjsunit/shift-for-integer-div.js index aaa67e97fe..884202d313 100644 --- a/deps/v8/test/mjsunit/shift-for-integer-div.js +++ b/deps/v8/test/mjsunit/shift-for-integer-div.js @@ -60,7 +60,7 @@ divn1(2); divn1(2); %OptimizeFunctionOnNextCall(divn1); assertEquals(-2, divn1(2)); -assertEquals(two_31, divn1(-two_31)); +assertEquals(-two_31, divn1(two_31)); //Check for truncating to int32 case @@ -85,3 +85,14 @@ divn4t(8); assertEquals(1, divn4t(-5)); assertEquals(-1, divn4t(5)); assertOptimized(divn4t); + +// Check kMinInt case. +function div_by_two(x) { + return (x / 2) | 0; +} + +div_by_two(12); +div_by_two(34); +%OptimizeFunctionOnNextCall(div_by_two); +div_by_two(56); +assertEquals(-(1 << 30), div_by_two(1 << 31)); diff --git a/deps/v8/test/mjsunit/simple-constructor.js b/deps/v8/test/mjsunit/simple-constructor.js index e9ae921009..391ef3d6d1 100755 --- a/deps/v8/test/mjsunit/simple-constructor.js +++ b/deps/v8/test/mjsunit/simple-constructor.js @@ -137,4 +137,3 @@ assertEquals(2, o.y); o = new g(); assertEquals(1, o.x); assertEquals(2, o.y); - diff --git a/deps/v8/test/mjsunit/sin-cos.js b/deps/v8/test/mjsunit/sin-cos.js index e38dfdf814..02ae57ba27 100644 --- a/deps/v8/test/mjsunit/sin-cos.js +++ b/deps/v8/test/mjsunit/sin-cos.js @@ -27,6 +27,24 @@ // Test Math.sin and Math.cos. +// Flags: --allow-natives-syntax + +assertEquals("-Infinity", String(1/Math.sin(-0))); +assertEquals(1, Math.cos(-0)); +assertEquals("-Infinity", String(1/Math.tan(-0))); + +// Assert that minus zero does not cause deopt. +function no_deopt_on_minus_zero(x) { + return Math.sin(x) + Math.cos(x) + Math.tan(x); +} + +no_deopt_on_minus_zero(1); +no_deopt_on_minus_zero(1); +%OptimizeFunctionOnNextCall(no_deopt_on_minus_zero); +no_deopt_on_minus_zero(-0); +assertOptimized(no_deopt_on_minus_zero); + + function sinTest() { assertEquals(0, Math.sin(0)); assertEquals(1, Math.sin(Math.PI / 2)); @@ -42,9 +60,128 @@ cosTest(); // By accident, the slow case for sine and cosine were both sine at // some point. This is a regression test for that issue. -var x = Math.pow(2, 70); +var x = Math.pow(2, 30); assertTrue(Math.sin(x) != Math.cos(x)); // Ensure that sine and log are not the same. x = 0.5; assertTrue(Math.sin(x) != Math.log(x)); + +// Test against approximation by series. +var factorial = [1]; +var accuracy = 50; +for (var i = 1; i < accuracy; i++) { + factorial[i] = factorial[i-1] * i; +} + +// We sum up in the reverse order for higher precision, as we expect the terms +// to grow smaller for x reasonably close to 0. +function precision_sum(array) { + var result = 0; + while (array.length > 0) { + result += array.pop(); + } + return result; +} + +function sin(x) { + var sign = 1; + var x2 = x*x; + var terms = []; + for (var i = 1; i < accuracy; i += 2) { + terms.push(sign * x / factorial[i]); + x *= x2; + sign *= -1; + } + return precision_sum(terms); +} + +function cos(x) { + var sign = -1; + var x2 = x*x; + x = x2; + var terms = [1]; + for (var i = 2; i < accuracy; i += 2) { + terms.push(sign * x / factorial[i]); + x *= x2; + sign *= -1; + } + return precision_sum(terms); +} + +function abs_error(fun, ref, x) { + return Math.abs(ref(x) - fun(x)); +} + +var test_inputs = []; +for (var i = -10000; i < 10000; i += 177) test_inputs.push(i/1257); +var epsilon = 0.0000001; + +test_inputs.push(0); +test_inputs.push(0 + epsilon); +test_inputs.push(0 - epsilon); +test_inputs.push(Math.PI/2); +test_inputs.push(Math.PI/2 + epsilon); +test_inputs.push(Math.PI/2 - epsilon); +test_inputs.push(Math.PI); +test_inputs.push(Math.PI + epsilon); +test_inputs.push(Math.PI - epsilon); +test_inputs.push(- 2*Math.PI); +test_inputs.push(- 2*Math.PI + epsilon); +test_inputs.push(- 2*Math.PI - epsilon); + +var squares = []; +for (var i = 0; i < test_inputs.length; i++) { + var x = test_inputs[i]; + var err_sin = abs_error(Math.sin, sin, x); + var err_cos = abs_error(Math.cos, cos, x) + assertEqualsDelta(0, err_sin, 1E-13); + assertEqualsDelta(0, err_cos, 1E-13); + squares.push(err_sin*err_sin + err_cos*err_cos); +} + +// Sum squares up by adding them pairwise, to avoid losing precision. +while (squares.length > 1) { + var reduced = []; + if (squares.length % 2 == 1) reduced.push(squares.pop()); + // Remaining number of elements is even. + while(squares.length > 1) reduced.push(squares.pop() + squares.pop()); + squares = reduced; +} + +var err_rms = Math.sqrt(squares[0] / test_inputs.length / 2); +assertEqualsDelta(0, err_rms, 1E-14); + +assertEquals(-1, Math.cos({ valueOf: function() { return Math.PI; } })); +assertEquals(0, Math.sin("0x00000")); +assertEquals(1, Math.cos("0x00000")); +assertTrue(isNaN(Math.sin(Infinity))); +assertTrue(isNaN(Math.cos("-Infinity"))); +assertEquals("Infinity", String(Math.tan(Math.PI/2))); +assertEquals("-Infinity", String(Math.tan(-Math.PI/2))); +assertEquals("-Infinity", String(1/Math.sin("-0"))); + +// Assert that the remainder after division by pi is reasonably precise. +function assertError(expected, x, epsilon) { + assertTrue(Math.abs(x - expected) < epsilon); +} + +assertEqualsDelta(0.9367521275331447, Math.cos(1e06), 1e-15); +assertEqualsDelta(0.8731196226768560, Math.cos(1e10), 1e-08); +assertEqualsDelta(0.9367521275331447, Math.cos(-1e06), 1e-15); +assertEqualsDelta(0.8731196226768560, Math.cos(-1e10), 1e-08); +assertEqualsDelta(-0.3499935021712929, Math.sin(1e06), 1e-15); +assertEqualsDelta(-0.4875060250875106, Math.sin(1e10), 1e-08); +assertEqualsDelta(0.3499935021712929, Math.sin(-1e06), 1e-15); +assertEqualsDelta(0.4875060250875106, Math.sin(-1e10), 1e-08); +assertEqualsDelta(0.7796880066069787, Math.sin(1e16), 1e-05); +assertEqualsDelta(-0.6261681981330861, Math.cos(1e16), 1e-05); + +// Assert that remainder calculation terminates. +for (var i = -1024; i < 1024; i++) { + assertFalse(isNaN(Math.sin(Math.pow(2, i)))); +} + +assertFalse(isNaN(Math.cos(1.57079632679489700))); +assertFalse(isNaN(Math.cos(-1e-100))); +assertFalse(isNaN(Math.cos(-1e-323))); diff --git a/deps/v8/test/mjsunit/smi-mul-const.js b/deps/v8/test/mjsunit/smi-mul-const.js new file mode 100644 index 0000000000..ca627fc27e --- /dev/null +++ b/deps/v8/test/mjsunit/smi-mul-const.js @@ -0,0 +1,87 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax --noalways-opt + +function check(func, input, expected) { + func(-1); + func(-1); + %OptimizeFunctionOnNextCall(func); + assertEquals(expected, func(input)); + assertOptimized(func); +} + +function mul_by_neg_1(a) { return a * -1; } +function mul_by_0(a) { return a * 0; } +function mul_by_1(a) { return a * 1; } +function mul_by_2(a) { return a * 2; } + +check(mul_by_neg_1, 2, -2); +check(mul_by_0, 2, 0); +check(mul_by_1, 2, 2); +check(mul_by_2, 2, 4); + +function limit_range(a) { + // Limit the range of 'a' to enable no-overflow optimizations. + return Math.max(Math.min(a | 0, 10), -10); +} + +function mul_by_neg_127(a) { return limit_range(a) * -127; } +function mul_by_neg_128(a) { return limit_range(a) * -128; } +function mul_by_neg_129(a) { return limit_range(a) * -129; } +function mul_by_1023(a) { return limit_range(a) * 1023; } +function mul_by_1024(a) { return limit_range(a) * 1024; } +function mul_by_1025(a) { return limit_range(a) * 1025; } + +check(mul_by_neg_127, 2, -254); +check(mul_by_neg_128, 2, -256); +check(mul_by_neg_129, 2, -258); +check(mul_by_1023, 2, 2046); +check(mul_by_1024, 2, 2048); +check(mul_by_1025, 2, 2050); + +// Deopt on minus zero. +assertEquals(-0, mul_by_neg_128(0)); +assertUnoptimized(mul_by_neg_128); +assertEquals(-0, mul_by_2(-0)); +assertUnoptimized(mul_by_2); + +// Deopt on overflow. + +// 2^30 is a smi boundary on arm and ia32. +var two_30 = 1 << 30; +// 2^31 is a smi boundary on arm64 and x64. +var two_31 = 2 * two_30; + +// TODO(rmcilroy): replace after r16361 with: if (%IsValidSmi(two_31)) { +if (true) { + assertEquals(two_31, mul_by_neg_1(-two_31)); + assertUnoptimized(mul_by_neg_1); +} else { + assertEquals(two_30, mul_by_neg_1(-two_30)); + assertUnoptimized(mul_by_neg_1); +} diff --git a/deps/v8/test/mjsunit/sparse-array.js b/deps/v8/test/mjsunit/sparse-array.js index 0952f2caaa..114ab0aafd 100644 --- a/deps/v8/test/mjsunit/sparse-array.js +++ b/deps/v8/test/mjsunit/sparse-array.js @@ -37,5 +37,3 @@ for (var repetitions = 0; repetitions < 20; repetitions++) { array[i * stride] = i; } } - - diff --git a/deps/v8/test/mjsunit/stack-traces-2.js b/deps/v8/test/mjsunit/stack-traces-2.js index 165c4dfcec..3bec963701 100644 --- a/deps/v8/test/mjsunit/stack-traces-2.js +++ b/deps/v8/test/mjsunit/stack-traces-2.js @@ -84,4 +84,4 @@ testNotOmittedBuiltin(function(){ [thrower, 2].sort(function (a,b) { }, "QuickSort"); // Not omitted even though ADD from runtime.js is a non-native builtin. -testNotOmittedBuiltin(function(){ thrower + 2; }, "ADD");
\ No newline at end of file +testNotOmittedBuiltin(function(){ thrower + 2; }, "ADD"); diff --git a/deps/v8/test/mjsunit/stack-traces-custom-lazy.js b/deps/v8/test/mjsunit/stack-traces-custom-lazy.js index 91d97f3739..02a465e658 100644 --- a/deps/v8/test/mjsunit/stack-traces-custom-lazy.js +++ b/deps/v8/test/mjsunit/stack-traces-custom-lazy.js @@ -46,4 +46,3 @@ function testPrepareStackTrace(closure) { testPrepareStackTrace(function() { throw new Error("foo"); }); testPrepareStackTrace(function f() { f(); }); - diff --git a/deps/v8/test/mjsunit/store-dictionary.js b/deps/v8/test/mjsunit/store-dictionary.js index 45e254bd2b..377352f39e 100644 --- a/deps/v8/test/mjsunit/store-dictionary.js +++ b/deps/v8/test/mjsunit/store-dictionary.js @@ -62,4 +62,3 @@ assertEquals(42, o.x); delete o.x; store(o); assertEquals(42, o.x); - diff --git a/deps/v8/test/mjsunit/str-to-num.js b/deps/v8/test/mjsunit/str-to-num.js index cbec87fab9..8c9a307001 100644 --- a/deps/v8/test/mjsunit/str-to-num.js +++ b/deps/v8/test/mjsunit/str-to-num.js @@ -211,4 +211,4 @@ assertTrue(isNaN(toNumber("+0xFF"))); assertTrue(isNaN(toNumber("+0x012"))); assertTrue(isNaN(toNumber("-0x0"))); assertTrue(isNaN(toNumber("-0xFF"))); -assertTrue(isNaN(toNumber("-0x012")));
\ No newline at end of file +assertTrue(isNaN(toNumber("-0x012"))); diff --git a/deps/v8/test/mjsunit/strict-equals.js b/deps/v8/test/mjsunit/strict-equals.js index d080ce8c4c..d5577c7a35 100644 --- a/deps/v8/test/mjsunit/strict-equals.js +++ b/deps/v8/test/mjsunit/strict-equals.js @@ -84,7 +84,3 @@ assertFalse(0 === new Number(0)); assertFalse(1 === new Number(1)); assertTrue(4.2 === 4.2); assertTrue(4.2 === Number(4.2)); - - - - diff --git a/deps/v8/test/mjsunit/string-natives.js b/deps/v8/test/mjsunit/string-natives.js index b1ec875420..7a9009bfd1 100644 --- a/deps/v8/test/mjsunit/string-natives.js +++ b/deps/v8/test/mjsunit/string-natives.js @@ -29,15 +29,23 @@ function test() { var s1 = %NewString(26, true); + for (i = 0; i < 26; i++) %_OneByteSeqStringSetChar(s1, i, 65); + assertEquals("AAAAAAAAAAAAAAAAAAAAAAAAAA", s1); + %_OneByteSeqStringSetChar(s1, 25, 66); + assertEquals("AAAAAAAAAAAAAAAAAAAAAAAAAB", s1); for (i = 0; i < 26; i++) %_OneByteSeqStringSetChar(s1, i, i+65); assertEquals("ABCDEFGHIJKLMNOPQRSTUVWXYZ", s1); s1 = %TruncateString(s1, 13); assertEquals("ABCDEFGHIJKLM", s1); var s2 = %NewString(26, false); + for (i = 0; i < 26; i++) %_TwoByteSeqStringSetChar(s2, i, 65); + assertEquals("AAAAAAAAAAAAAAAAAAAAAAAAAA", s2); + %_TwoByteSeqStringSetChar(s2, 25, 66); + assertEquals("AAAAAAAAAAAAAAAAAAAAAAAAAB", s2); for (i = 0; i < 26; i++) %_TwoByteSeqStringSetChar(s2, i, i+65); assertEquals("ABCDEFGHIJKLMNOPQRSTUVWXYZ", s2); - s2 = %TruncateString(s1, 13); + s2 = %TruncateString(s2, 13); assertEquals("ABCDEFGHIJKLM", s2); var s3 = %NewString(26, false); @@ -69,4 +77,3 @@ test(); test(); %OptimizeFunctionOnNextCall(test); test(); - diff --git a/deps/v8/test/mjsunit/string-replace-gc.js b/deps/v8/test/mjsunit/string-replace-gc.js index 73b310f9c0..2f1efd8813 100644 --- a/deps/v8/test/mjsunit/string-replace-gc.js +++ b/deps/v8/test/mjsunit/string-replace-gc.js @@ -53,4 +53,3 @@ var moving_string = "b" + "c"; var bar = foo.replace(/[a]/g, moving_string); print(bar.length); - diff --git a/deps/v8/test/mjsunit/string-search.js b/deps/v8/test/mjsunit/string-search.js index 4de17bca23..037725b95e 100644 --- a/deps/v8/test/mjsunit/string-search.js +++ b/deps/v8/test/mjsunit/string-search.js @@ -37,4 +37,3 @@ for (var i = 0; i < 100; i++) { var r = s.search(s); assertEquals(0, r); } - diff --git a/deps/v8/test/mjsunit/string-slices.js b/deps/v8/test/mjsunit/string-slices.js index 5b1dc360ab..2fec04b0b0 100755 --- a/deps/v8/test/mjsunit/string-slices.js +++ b/deps/v8/test/mjsunit/string-slices.js @@ -222,4 +222,15 @@ function test_crankshaft() { test_crankshaft(); %OptimizeFunctionOnNextCall(test_crankshaft); -test_crankshaft();
\ No newline at end of file +test_crankshaft(); + +var s1 = "12345678901234567890"; +var s2 = "abcdefghijklmnopqrstuvwxyz"; +var c1 = s1 + s2; +var c2 = s1 + c1 + s2; +assertEquals("234567890123456789", c1.substring(1, 19)); +assertEquals("bcdefghijklmno", c1.substring(21, 35)); +assertEquals("2345678901234567890abcdefghijklmno", c1.substring(1, 35)); +assertEquals("234567890123456789", c2.substring(1, 19)); +assertEquals("bcdefghijklmno", c2.substring(41, 55)); +assertEquals("2345678901234567890abcdefghijklmno", c2.substring(21, 55)); diff --git a/deps/v8/test/mjsunit/string-split.js b/deps/v8/test/mjsunit/string-split.js index 1308244cab..efd0ef3eae 100644 --- a/deps/v8/test/mjsunit/string-split.js +++ b/deps/v8/test/mjsunit/string-split.js @@ -145,3 +145,22 @@ for (var i = 0; i < 128; i++) { assertEquals(1, split_chars[i].length); assertEquals(i, split_chars[i].charCodeAt(0)); } + +// Check that the separator is converted to string before returning due to +// limit == 0. +var counter = 0; +var separator = { toString: function() { counter++; return "b"; }}; +assertEquals([], "abc".split(separator, 0)); +assertEquals(1, counter); + +// Check that the subject is converted to string before the separator. +counter = 0; +var subject = { toString: function() { assertEquals(0, counter); + counter++; + return "abc"; }}; +separator = { toString: function() { assertEquals(1, counter); + counter++; + return "b"; }}; + +assertEquals(["a", "c"], String.prototype.split.call(subject, separator)); +assertEquals(2, counter); diff --git a/deps/v8/test/mjsunit/switch-opt.js b/deps/v8/test/mjsunit/switch-opt.js new file mode 100644 index 0000000000..c1d5d38374 --- /dev/null +++ b/deps/v8/test/mjsunit/switch-opt.js @@ -0,0 +1,221 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +(function() { + var result = []; + var x = 0; + + function branch(b) { + if (b == "deopt") { + %DeoptimizeFunction(f); + return "c"; + } + + return b ? "a" : "b"; + } + + function f(label, b1, b2, b3) { + switch (label) { + case "string": + result.push(1); + break; + case branch(b1) + branch(b2): + result.push(2); + break; + case 10: + result.push(3); + break; + default: + branch(b3); + result.push(4); + break; + case x++: + branch(b3); + result.push(5); + break; + } + } + + function assertResult(r, label, b1, b2, b3) { + f(label, b1, b2, b3); + assertEquals(result, r); + result = []; + } + + // Warmup. + assertResult([2], "aa", true, true); + assertResult([2], "ab", true, false); + assertResult([2], "ba", false, true); + assertResult([2], "bb", false, false); + assertEquals(0, x); + assertResult([4], "other"); + assertEquals(1, x); + assertResult([5], 1, true, true); + assertResult([4], 1, true, true); + assertResult([5], 3, true, true); + assertResult([4], 3, true, true); + assertResult([5], 5, true, true); + assertResult([4], 5, true, true); + assertEquals(7, x); + + // Test regular behavior. + %OptimizeFunctionOnNextCall(f); + assertResult([2], "aa", true, true); + assertResult([1], "string"); + assertResult([4], "other"); + assertEquals(8, x); + assertResult([5], 8); + assertEquals(9, x); + + // Test deopt at the beginning of the case label evaluation. + assertResult([2], "ca", "deopt", true); + %OptimizeFunctionOnNextCall(f); + assertResult([4], "ca", "deopt", false); + assertEquals(10, x); + %OptimizeFunctionOnNextCall(f); + + // Test deopt in the middle of the case label evaluation. + assertResult([2], "ac", true, "deopt"); + %OptimizeFunctionOnNextCall(f); + assertResult([4], "ac", false, "deopt"); + assertEquals(11, x); + + // Test deopt in the default case. + %OptimizeFunctionOnNextCall(f); + print("here"); + assertResult([4], 10000, false, false, "deopt"); + assertEquals(12, x); + + // Test deopt in the default case. + %OptimizeFunctionOnNextCall(f); + assertResult([4], 10000, false, false, "deopt"); + assertEquals(13, x); + + // Test deopt in x++ case. + %OptimizeFunctionOnNextCall(f); + assertResult([5], 13, false, false, "deopt"); + assertEquals(14, x); +})(); + + +(function() { + var result = []; + var x = 0; + + function branch(b) { + if (b == "deopt") { + %DeoptimizeFunction(f); + return "c"; + } + + return b ? "a" : "b"; + } + + function f(label, b1, b2, b3) { + switch (label) { + case "string": + result.push(1); + break; + case branch(b1) + branch(b2): + result.push(2); + // Fall through. + case 10: + result.push(3); + break; + default: + branch(b3); + result.push(4); + // Fall through. + case x++: + branch(b3); + result.push(5); + break; + } + } + + function assertResult(r, label, b1, b2, b3) { + f(label, b1, b2, b3); + assertEquals(r, result); + result = []; + } + + // Warmup. + assertResult([2,3], "aa", true, true); + assertResult([2,3], "ab", true, false); + assertResult([2,3], "ba", false, true); + assertResult([2,3], "bb", false, false); + assertEquals(0, x); + assertResult([4,5], "other"); + assertEquals(1, x); + assertResult([5], 1, true, true); + assertResult([4,5], 1, true, true); + assertResult([5], 3, true, true); + assertResult([4,5], 3, true, true); + assertResult([5], 5, true, true); + assertResult([4,5], 5, true, true); + assertEquals(7, x); + + // Test regular behavior. + %OptimizeFunctionOnNextCall(f); + assertResult([2,3], "aa", true, true); + assertResult([1], "string"); + assertResult([4,5], "other"); + assertEquals(8, x); + assertResult([5], 8); + assertEquals(9, x); + + // Test deopt at the beginning of the case label evaluation. + assertResult([2,3], "ca", "deopt", true); + %OptimizeFunctionOnNextCall(f); + assertResult([4,5], "ca", "deopt", false); + assertEquals(10, x); + %OptimizeFunctionOnNextCall(f); + + // Test deopt in the middle of the case label evaluation. + assertResult([2,3], "ac", true, "deopt"); + %OptimizeFunctionOnNextCall(f); + assertResult([4,5], "ac", false, "deopt"); + assertEquals(11, x); + + // Test deopt in the default case. + %OptimizeFunctionOnNextCall(f); + print("here"); + assertResult([4,5], 10000, false, false, "deopt"); + assertEquals(12, x); + + // Test deopt in the default case. + %OptimizeFunctionOnNextCall(f); + assertResult([4,5], 10000, false, false, "deopt"); + assertEquals(13, x); + + // Test deopt in x++ case. + %OptimizeFunctionOnNextCall(f); + assertResult([5], 13, false, false, "deopt"); + assertEquals(14, x); +})(); diff --git a/deps/v8/test/mjsunit/third_party/array-isarray.js b/deps/v8/test/mjsunit/third_party/array-isarray.js deleted file mode 100644 index 0fc42a3f27..0000000000 --- a/deps/v8/test/mjsunit/third_party/array-isarray.js +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2009 Apple Computer, Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// -// 3. Neither the name of the copyright holder(s) nor the names of any -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. - -// Based on LayoutTests/fast/js/resources/Array-isArray.js - -assertTrue(Array.isArray([])); -assertTrue(Array.isArray(new Array)); -assertTrue(Array.isArray(Array())); -assertTrue(Array.isArray('abc'.match(/(a)*/g))); -assertFalse((function(){ return Array.isArray(arguments); })()); -assertFalse(Array.isArray()); -assertFalse(Array.isArray(null)); -assertFalse(Array.isArray(undefined)); -assertFalse(Array.isArray(true)); -assertFalse(Array.isArray(false)); -assertFalse(Array.isArray('a string')); -assertFalse(Array.isArray({})); -assertFalse(Array.isArray({length: 5})); -assertFalse(Array.isArray({__proto__: Array.prototype, length:1, 0:1, 1:2})); - diff --git a/deps/v8/test/mjsunit/third_party/array-splice-webkit.js b/deps/v8/test/mjsunit/third_party/array-splice-webkit.js deleted file mode 100644 index 974ac55e6b..0000000000 --- a/deps/v8/test/mjsunit/third_party/array-splice-webkit.js +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2006 Apple Computer, Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// -// 3. Neither the name of the copyright holder(s) nor the names of any -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. - -// Simple splice tests based on webkit layout tests. -var arr = ['a','b','c','d']; -assertArrayEquals(['a','b','c','d'], arr); -assertArrayEquals(['c','d'], arr.splice(2)); -assertArrayEquals(['a','b'], arr); -assertArrayEquals(['a','b'], arr.splice(0)); -assertArrayEquals([], arr) - -arr = ['a','b','c','d']; -assertEquals([], arr.splice()) -assertArrayEquals(['a','b','c','d'], arr); -assertArrayEquals(['a','b','c','d'], arr.splice(undefined)) -assertArrayEquals([], arr); - -arr = ['a','b','c','d']; -assertArrayEquals(['a','b','c','d'], arr.splice(null)) -assertArrayEquals([], arr); - -arr = ['a','b','c','d']; -assertArrayEquals([], arr.splice(100)) -assertArrayEquals(['a','b','c','d'], arr); -assertArrayEquals(['d'], arr.splice(-1)) -assertArrayEquals(['a','b','c'], arr); - -assertArrayEquals([], arr.splice(2, undefined)) -assertArrayEquals([], arr.splice(2, null)) -assertArrayEquals([], arr.splice(2, -1)) -assertArrayEquals([], arr.splice(2, 0)) -assertArrayEquals(['a','b','c'], arr); -assertArrayEquals(['c'], arr.splice(2, 100)) -assertArrayEquals(['a','b'], arr); diff --git a/deps/v8/test/mjsunit/third_party/string-trim.js b/deps/v8/test/mjsunit/third_party/string-trim.js deleted file mode 100644 index 234dff6dcd..0000000000 --- a/deps/v8/test/mjsunit/third_party/string-trim.js +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2009 Apple Computer, Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// -// 3. Neither the name of the copyright holder(s) nor the names of any -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. - -// Based on LayoutTests/fast/js/script-tests/string-trim.js - -// References to trim(), trimLeft() and trimRight() functions for -// testing Function's *.call() and *.apply() methods. - -var trim = String.prototype.trim; -var trimLeft = String.prototype.trimLeft; -var trimRight = String.prototype.trimRight; - -var testString = 'foo bar'; -var trimString = ''; -var leftTrimString = ''; -var rightTrimString = ''; -var wsString = ''; - -var whitespace = [ - {s : '\u0009', t : 'HORIZONTAL TAB'}, - {s : '\u000A', t : 'LINE FEED OR NEW LINE'}, - {s : '\u000B', t : 'VERTICAL TAB'}, - {s : '\u000C', t : 'FORMFEED'}, - {s : '\u000D', t : 'CARRIAGE RETURN'}, - {s : '\u0020', t : 'SPACE'}, - {s : '\u00A0', t : 'NO-BREAK SPACE'}, - {s : '\u2000', t : 'EN QUAD'}, - {s : '\u2001', t : 'EM QUAD'}, - {s : '\u2002', t : 'EN SPACE'}, - {s : '\u2003', t : 'EM SPACE'}, - {s : '\u2004', t : 'THREE-PER-EM SPACE'}, - {s : '\u2005', t : 'FOUR-PER-EM SPACE'}, - {s : '\u2006', t : 'SIX-PER-EM SPACE'}, - {s : '\u2007', t : 'FIGURE SPACE'}, - {s : '\u2008', t : 'PUNCTUATION SPACE'}, - {s : '\u2009', t : 'THIN SPACE'}, - {s : '\u200A', t : 'HAIR SPACE'}, - {s : '\u3000', t : 'IDEOGRAPHIC SPACE'}, - {s : '\u2028', t : 'LINE SEPARATOR'}, - {s : '\u2029', t : 'PARAGRAPH SEPARATOR'}, - {s : '\u200B', t : 'ZERO WIDTH SPACE (category Cf)'} -]; - -for (var i = 0; i < whitespace.length; i++) { - assertEquals(whitespace[i].s.trim(), ''); - assertEquals(whitespace[i].s.trimLeft(), ''); - assertEquals(whitespace[i].s.trimRight(), ''); - wsString += whitespace[i].s; -} - -trimString = wsString + testString + wsString; -leftTrimString = testString + wsString; // Trimmed from the left. -rightTrimString = wsString + testString; // Trimmed from the right. - -assertEquals(wsString.trim(), ''); -assertEquals(wsString.trimLeft(), ''); -assertEquals(wsString.trimRight(), ''); - -assertEquals(trimString.trim(), testString); -assertEquals(trimString.trimLeft(), leftTrimString); -assertEquals(trimString.trimRight(), rightTrimString); - -assertEquals(leftTrimString.trim(), testString); -assertEquals(leftTrimString.trimLeft(), leftTrimString); -assertEquals(leftTrimString.trimRight(), testString); - -assertEquals(rightTrimString.trim(), testString); -assertEquals(rightTrimString.trimLeft(), testString); -assertEquals(rightTrimString.trimRight(), rightTrimString); - -var testValues = [0, Infinity, NaN, true, false, ({}), ['an','array'], - ({toString:function(){return 'wibble'}}) -]; - -for (var i = 0; i < testValues.length; i++) { - assertEquals(trim.call(testValues[i]), String(testValues[i])); - assertEquals(trimLeft.call(testValues[i]), String(testValues[i])); - assertEquals(trimRight.call(testValues[i]), String(testValues[i])); -} diff --git a/deps/v8/test/mjsunit/to-precision.js b/deps/v8/test/mjsunit/to-precision.js index 04c7d7614e..ded71853b4 100644 --- a/deps/v8/test/mjsunit/to-precision.js +++ b/deps/v8/test/mjsunit/to-precision.js @@ -79,4 +79,3 @@ assertEquals("-91.123", (-91.1234).toPrecision(5)); assertEquals("-91.1234", (-91.1234).toPrecision(6)); assertEquals("-91.12340", (-91.1234).toPrecision(7)); assertEquals("-91.123400", (-91.1234).toPrecision(8)); - diff --git a/deps/v8/test/mjsunit/tobool.js b/deps/v8/test/mjsunit/tobool.js index 65bffb624f..44a5a3cd40 100644 --- a/deps/v8/test/mjsunit/tobool.js +++ b/deps/v8/test/mjsunit/tobool.js @@ -32,5 +32,3 @@ assertTrue(!!new Boolean(false), "new Boolean(false)"); assertTrue(!!new Number(-1), "new Number(-1)"); assertTrue(!!new Number(0), "new Number(0)"); assertTrue(!!new Number(1), "new Number(1)"); - - diff --git a/deps/v8/test/mjsunit/tools/profile.js b/deps/v8/test/mjsunit/tools/profile.js index 4df1a08f92..0f79aeaa83 100644 --- a/deps/v8/test/mjsunit/tools/profile.js +++ b/deps/v8/test/mjsunit/tools/profile.js @@ -345,4 +345,3 @@ function assertNodeWeights(root, path, selfTicks, totalTicks) { } })(); - diff --git a/deps/v8/test/mjsunit/touint32.js b/deps/v8/test/mjsunit/touint32.js index f06bddfcf5..9c4cc36016 100644 --- a/deps/v8/test/mjsunit/touint32.js +++ b/deps/v8/test/mjsunit/touint32.js @@ -68,5 +68,3 @@ assertEquals(2147483649, ToUInt32('2147483649'), "'2147483649'"); assertEquals(4294967295, ToUInt32('4294967295'), "'4294967295'"); assertEquals(0, ToUInt32('4294967296'), "'4294967296'"); assertEquals(1, ToUInt32('4294967297'), "'4294967297'"); - - diff --git a/deps/v8/test/mjsunit/transcendentals.js b/deps/v8/test/mjsunit/transcendentals.js index 78e6c48072..2a75d6da82 100644 --- a/deps/v8/test/mjsunit/transcendentals.js +++ b/deps/v8/test/mjsunit/transcendentals.js @@ -46,4 +46,3 @@ assertTrue(Math.acos(x) != Math.acos(y)); assertTrue(Math.atan(x) != Math.atan(y)); assertTrue(Math.exp(x) != Math.exp(y)); - diff --git a/deps/v8/test/mjsunit/transition-elements-kind.js b/deps/v8/test/mjsunit/transition-elements-kind.js index 9fac78036e..9acf52c0d2 100644 --- a/deps/v8/test/mjsunit/transition-elements-kind.js +++ b/deps/v8/test/mjsunit/transition-elements-kind.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --allow-natives-syntax --track-allocation-sites +// Flags: --allow-natives-syntax // Allocation site for empty double arrays. function foo() { diff --git a/deps/v8/test/mjsunit/try-finally-continue.js b/deps/v8/test/mjsunit/try-finally-continue.js index b55e7acc78..5e04930c5d 100644 --- a/deps/v8/test/mjsunit/try-finally-continue.js +++ b/deps/v8/test/mjsunit/try-finally-continue.js @@ -69,4 +69,4 @@ for (x in a) { } } } -assertEquals(9, f);
\ No newline at end of file +assertEquals(9, f); diff --git a/deps/v8/test/mjsunit/unicode-string-to-number.js b/deps/v8/test/mjsunit/unicode-string-to-number.js index 13a7acfbc2..2376a60cac 100644 --- a/deps/v8/test/mjsunit/unicode-string-to-number.js +++ b/deps/v8/test/mjsunit/unicode-string-to-number.js @@ -43,4 +43,3 @@ for (var i = 0; i < 7; i++) { s += s; } assertTrue(isNaN(Number(s)), "long-string"); - diff --git a/deps/v8/test/mjsunit/unicode-test.js b/deps/v8/test/mjsunit/unicode-test.js index 66a029a7ef..5be1b41562 100644 --- a/deps/v8/test/mjsunit/unicode-test.js +++ b/deps/v8/test/mjsunit/unicode-test.js @@ -9165,5 +9165,3 @@ var thai_l_regexp = new RegExp(thai_l_thingy); var thai_l_regexp2 = new RegExp("[" + thai_l_thingy + "]"); assertTrue(thai_l_regexp.test(thai_l_thingy)); assertTrue(thai_l_regexp2.test(thai_l_thingy)); - - diff --git a/deps/v8/test/mjsunit/value-wrapper-accessor.js b/deps/v8/test/mjsunit/value-wrapper-accessor.js new file mode 100644 index 0000000000..2a51fee991 --- /dev/null +++ b/deps/v8/test/mjsunit/value-wrapper-accessor.js @@ -0,0 +1,99 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// When calling user-defined accessors on strings, booleans or +// numbers, we should create a wrapper object in classic-mode. + +// Flags: --allow-natives-syntax + +function test(object, prototype) { + var result; + Object.defineProperty(prototype, "nonstrict", { + get: function() { result = this; }, + set: function(v) { result = this; } + }); + Object.defineProperty(prototype, "strict", { + get: function() { "use strict"; result = this; }, + set: function(v) { "use strict"; result = this; } + }); + + (function() { + function nonstrict(s) { + return s.nonstrict; + } + function strict(s) { + return s.strict; + } + + nonstrict(object); + nonstrict(object); + %OptimizeFunctionOnNextCall(nonstrict); + result = undefined; + nonstrict(object); + assertEquals("object", typeof result); + + strict(object); + strict(object); + %OptimizeFunctionOnNextCall(strict); + result = undefined; + strict(object); + assertEquals(typeof object, typeof result); + })(); + + (function() { + function nonstrict(s) { + return s.nonstrict = 10; + } + function strict(s) { + return s.strict = 10; + } + + nonstrict(object); + nonstrict(object); + %OptimizeFunctionOnNextCall(nonstrict); + result = undefined; + nonstrict(object); + // TODO(1475): Support storing to primitive values. + // This should return "object" once storing to primitive values is + // supported. + assertEquals("undefined", typeof result); + + strict(object); + strict(object); + %OptimizeFunctionOnNextCall(strict); + result = undefined; + strict(object); + // TODO(1475): Support storing to primitive values. + // This should return "object" once storing to primitive values is + // supported. + assertEquals("undefined", typeof result); + })(); +} + +test(1, Number.prototype); +test("string", String.prototype); +test(true, Boolean.prototype); diff --git a/deps/v8/test/mjsunit/value-wrapper.js b/deps/v8/test/mjsunit/value-wrapper.js index 76e200f36e..cc81f95559 100644 --- a/deps/v8/test/mjsunit/value-wrapper.js +++ b/deps/v8/test/mjsunit/value-wrapper.js @@ -31,6 +31,7 @@ // When running the tests use loops to ensure that the call site moves through // the different IC states and that both the runtime system and the generated // IC code is tested. + function RunTests() { for (var i = 0; i < 10; i++) { assertEquals('object', 'xxx'.TypeOfThis()); diff --git a/deps/v8/test/mjsunit/verify-assert-false.js b/deps/v8/test/mjsunit/verify-assert-false.js new file mode 100644 index 0000000000..8bea7df399 --- /dev/null +++ b/deps/v8/test/mjsunit/verify-assert-false.js @@ -0,0 +1,30 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --expose-trigger-failure + +triggerAssertFalse(); diff --git a/deps/v8/test/mjsunit/verify-check-false.js b/deps/v8/test/mjsunit/verify-check-false.js new file mode 100644 index 0000000000..426bf846a6 --- /dev/null +++ b/deps/v8/test/mjsunit/verify-check-false.js @@ -0,0 +1,30 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --expose-trigger-failure + +triggerCheckFalse(); diff --git a/deps/v8/test/mjsunit/whitespaces.js b/deps/v8/test/mjsunit/whitespaces.js new file mode 100644 index 0000000000..78e4ad5d36 --- /dev/null +++ b/deps/v8/test/mjsunit/whitespaces.js @@ -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. + +var whitespaces = [ + // WhiteSpace defined in ECMA-262 5.1, 7.2 + 0x0009, // Tab TAB + 0x000B, // Vertical Tab VT + 0x000C, // Form Feed FF + 0x0020, // Space SP + 0x00A0, // No-break space NBSP + 0xFEFF, // Byte Order Mark BOM + + // LineTerminator defined in ECMA-262 5.1, 7.3 + 0x000A, // Line Feed LF + 0x000D, // Carriage Return CR + 0x2028, // Line Separator LS + 0x2029, // Paragraph Separator PS + + // Unicode 6.3.0 whitespaces (category 'Zs') + 0x1680, // Ogham Space Mark + 0x180E, // Mongolian Vowel Separator + 0x2000, // EN QUAD + 0x2001, // EM QUAD + 0x2002, // EN SPACE + 0x2003, // EM SPACE + 0x2004, // THREE-PER-EM SPACE + 0x2005, // FOUR-PER-EM SPACE + 0x2006, // SIX-PER-EM SPACE + 0x2007, // FIGURE SPACE + 0x2008, // PUNCTUATION SPACE + 0x2009, // THIN SPACE + 0x200A, // HAIR SPACE + 0x2028, // LINE SEPARATOR + 0x2029, // PARAGRAPH SEPARATOR + 0x202F, // NARROW NO-BREAK SPACE + 0x205F, // MEDIUM MATHEMATICAL SPACE + 0x3000, // IDEOGRAPHIC SPACE +]; + +// Add single twobyte char to force twobyte representation. +// Interestingly, snowman is not "white" space :) +var twobyte = "\u2603"; +var onebyte = "\u007E"; +var twobytespace = "\u2000"; +var onebytespace = "\u0020"; + +function is_whitespace(c) { + return whitespaces.indexOf(c.charCodeAt(0)) > -1; +} + +function test_regexp(str) { + var pos_match = str.match(/\s/); + var neg_match = str.match(/\S/); + var test_char = str[0]; + var postfix = str[1]; + if (is_whitespace(test_char)) { + assertEquals(test_char, pos_match[0]); + assertEquals(postfix, neg_match[0]); + } else { + assertEquals(test_char, neg_match[0]); + assertNull(pos_match); + } +} + +function test_trim(c, infix) { + var str = c + c + c + infix + c; + if (is_whitespace(c)) { + assertEquals(infix, str.trim()); + } else { + assertEquals(str, str.trim()); + } +} + +function test_parseInt(c, postfix) { + // Skip if prefix is a digit. + if (c >= "0" && c <= "9") return; + var str = c + c + "123" + postfix; + if (is_whitespace(c)) { + assertEquals(123, parseInt(str)); + } else { + assertEquals(NaN, parseInt(str)); + } +} + +function test_eval(c, content) { + if (!is_whitespace(c)) return; + var str = c + c + "'" + content + "'" + c + c; + assertEquals(content, eval(str)); +} + +function test_stringtonumber(c, postfix) { + // Skip if prefix is a digit. + if (c >= "0" && c <= "9") return; + var result = 1 + Number(c + "123" + c + postfix); + if (is_whitespace(c)) { + assertEquals(124, result); + } else { + assertEquals(NaN, result); + } +} + +for (var i = 0; i < 0x10000; i++) { + c = String.fromCharCode(i); + test_regexp(c + onebyte); + test_regexp(c + twobyte); + test_trim(c, onebyte + "trim"); + test_trim(c, twobyte + "trim"); + test_parseInt(c, onebyte); + test_parseInt(c, twobyte); + test_eval(c, onebyte); + test_eval(c, twobyte); + test_stringtonumber(c, onebytespace); + test_stringtonumber(c, twobytespace); +} diff --git a/deps/v8/test/mjsunit/with-value.js b/deps/v8/test/mjsunit/with-value.js index a4da1fad9c..f7a89f3fb6 100644 --- a/deps/v8/test/mjsunit/with-value.js +++ b/deps/v8/test/mjsunit/with-value.js @@ -35,4 +35,4 @@ /* This should be fairly easy again. May need some work in the compiler's VisitWith() function, or perhaps the runtime routine's PushContextForWith(). -*/
\ No newline at end of file +*/ diff --git a/deps/v8/test/mozilla/mozilla.status b/deps/v8/test/mozilla/mozilla.status index b27e991b98..197e65137c 100644 --- a/deps/v8/test/mozilla/mozilla.status +++ b/deps/v8/test/mozilla/mozilla.status @@ -75,39 +75,39 @@ 'js1_2/function/Number': [SKIP], # TODO(2018): Temporarily allow timeout in debug mode. - 'js1_5/GC/regress-203278-2': [PASS, ['mode == debug', TIMEOUT, FAIL]], + 'js1_5/GC/regress-203278-2': [PASS, ['mode == debug', TIMEOUT, NO_VARIANTS, FAIL]], ##################### SLOW TESTS ##################### # This takes a long time to run (~100 seconds). It should only be run # by the really patient. - 'js1_5/GC/regress-324278': [SLOW], + 'js1_5/GC/regress-324278': [SKIP], # This takes a long time to run because our indexOf operation is # pretty slow - it causes a lot of GCs; see issue # #926379. We could consider marking this SKIP because it takes a # while to run to completion. - 'js1_5/GC/regress-338653': [SLOW], + 'js1_5/GC/regress-338653': [SKIP], # This test is designed to run until it runs out of memory. This takes # a very long time because it builds strings character by character # and compiles a lot of regular expressions. We could consider marking # this SKIP because it takes a while to run to completion. - 'js1_5/GC/regress-346794': [SLOW], + 'js1_5/GC/regress-346794': [SKIP], # Runs out of memory while trying to build huge string of 'x' # characters. This takes a long time to run (~32 seconds). - 'js1_5/GC/regress-348532': [SLOW], + 'js1_5/GC/regress-348532': [SKIP], ##################### FLAKY TESTS ##################### # These tests time out in debug mode but pass in product mode - 'js1_5/Regress/regress-360969-03': [PASS, ['mode == debug', TIMEOUT]], - 'js1_5/Regress/regress-360969-04': [PASS, ['mode == debug', TIMEOUT]], - 'js1_5/Regress/regress-360969-05': [PASS, ['mode == debug', TIMEOUT]], - 'js1_5/Regress/regress-360969-06': [PASS, ['mode == debug', TIMEOUT]], - 'js1_5/extensions/regress-365527': [PASS, ['mode == debug', TIMEOUT]], + 'js1_5/Regress/regress-360969-03': [PASS, ['mode == debug', TIMEOUT, NO_VARIANTS]], + 'js1_5/Regress/regress-360969-04': [PASS, ['mode == debug', TIMEOUT, NO_VARIANTS]], + 'js1_5/Regress/regress-360969-05': [PASS, ['mode == debug', TIMEOUT, NO_VARIANTS]], + 'js1_5/Regress/regress-360969-06': [PASS, ['mode == debug', TIMEOUT, NO_VARIANTS]], + 'js1_5/extensions/regress-365527': [PASS, ['mode == debug', TIMEOUT, NO_VARIANTS]], 'js1_5/Regress/regress-280769-3': [PASS, ['mode == debug', FAIL]], 'js1_5/Regress/regress-203278-1': [PASS, ['mode == debug', FAIL]], @@ -116,7 +116,7 @@ 'js1_5/GC/regress-278725': [PASS, ['mode == debug', FAIL]], # http://b/issue?id=1206983 'js1_5/Regress/regress-367561-03': [PASS, ['mode == debug', FAIL]], - 'ecma/Date/15.9.5.10-2': [PASS, FAIL, ['mode == debug', TIMEOUT]], + 'ecma/Date/15.9.5.10-2': [PASS, FAIL, ['mode == debug', TIMEOUT, NO_VARIANTS]], # These tests create two Date objects just after each other and # expects them to match. Sometimes this happens on the border @@ -166,7 +166,7 @@ 'js1_5/Array/regress-99120-01': [PASS, FAIL], 'js1_5/Array/regress-99120-02': [PASS, FAIL], 'js1_5/Regress/regress-347306-01': [PASS, FAIL], - 'js1_5/Regress/regress-416628': [PASS, FAIL, ['mode == debug', TIMEOUT]], + 'js1_5/Regress/regress-416628': [PASS, FAIL, ['mode == debug', TIMEOUT, NO_VARIANTS]], # The following two tests assume that daylight savings time starts first @@ -187,7 +187,7 @@ # Tests that sorting arrays of ints is less than 3 times as fast # as sorting arrays of strings. - 'js1_5/extensions/regress-371636': [PASS, FAIL, ['mode == debug', TIMEOUT]], + 'js1_5/extensions/regress-371636': [PASS, FAIL, ['mode == debug', TIMEOUT, NO_VARIANTS]], # Tests depend on GC timings. Inherently flaky. @@ -273,14 +273,18 @@ # PCRE's match limit is reached. SpiderMonkey hangs on the first one, # JSC returns true somehow. Maybe they up the match limit? There is # an open V8 bug 676063 about this. - 'ecma_3/RegExp/regress-330684': [TIMEOUT], + # TODO(yangguo): Hangs on complex regexp. Please investigate if this gives + # any useful coverage. + 'ecma_3/RegExp/regress-330684': [SKIP], # This test contains a regexp that runs exponentially long. Spidermonkey # standalone will hang, though apparently inside Firefox it will trigger a # long-running-script timeout. JSCRE passes by hitting the matchLimit and # just pretending that an exhaustive search found no match. - 'ecma_3/RegExp/regress-307456': [PASS, TIMEOUT], + # TODO(yangguo): Hangs on complex regexp. Please investigate if this gives + # any useful coverage. + 'ecma_3/RegExp/regress-307456': [SKIP], # We do not detect overflow in bounds for back references and {} @@ -599,7 +603,6 @@ # Negative hexadecimal literals are parsed as NaN. This test is outdated. 'ecma/TypeConversion/9.3.1-3': [FAIL_OK], - ##################### FAILING TESTS ##################### # This section is for tests that fail in V8 and pass in JSC. @@ -614,7 +617,7 @@ # This test seems designed to fail (it produces a 700Mbyte string). # We fail on out of memory. The important thing is not to crash. - 'js1_5/Regress/regress-303213': [FAIL, ['mode == debug', TIMEOUT]], + 'js1_5/Regress/regress-303213': [FAIL, ['mode == debug', TIMEOUT, NO_VARIANTS]], # This test fails since we now throw in String.prototype.match when apply # is given null or undefined as this argument (and so does firefox nightly). @@ -748,12 +751,15 @@ 'js1_5/extensions/toLocaleFormat-01': [FAIL_OK], 'js1_5/extensions/toLocaleFormat-02': [FAIL_OK], - 'js1_5/extensions/regress-330569': [TIMEOUT], - 'js1_5/extensions/regress-351448': [TIMEOUT], + # TODO(yangguo): Both tests have complex regular expressions (nested (.*)* + # and the like). Please investigate if these tests provide any coverage. + # Furthermore, an exception is expected which is not thrown by v8. + 'js1_5/extensions/regress-330569': [SKIP], + 'js1_5/extensions/regress-351448': [SKIP], # In the 64-bit version, this test takes longer to run out of memory # than it does in the 32-bit version when attempting to generate a huge # error message in debug mode. - 'js1_5/extensions/regress-336410-1': [FAIL_OK, ['mode == debug and arch == x64', TIMEOUT]], + 'js1_5/extensions/regress-336410-1': [FAIL_OK, ['mode == debug and arch == x64', TIMEOUT, NO_VARIANTS]], ##################### DECOMPILATION TESTS ##################### @@ -816,7 +822,7 @@ }], # ALWAYS -['arch == arm', { +['arch == arm or arch == a64', { # BUG(3251229): Times out when running new crankshaft test script. 'ecma_3/RegExp/regress-311414': [SKIP], @@ -832,8 +838,14 @@ # BUG(1040): Allow this test to timeout. - 'js1_5/GC/regress-203278-2': [PASS, TIMEOUT], -}], # 'arch == arm' + 'js1_5/GC/regress-203278-2': [PASS, TIMEOUT, NO_VARIANTS], +}], # 'arch == arm or arch == a64' + + +['arch == a64', { + # BUG(v8:3152): Runs out of stack in debug mode. + 'js1_5/extensions/regress-355497': [FAIL_OK, ['mode == debug', SKIP]], +}], # 'arch == a64' ['arch == mipsel', { @@ -852,6 +864,27 @@ # BUG(1040): Allow this test to timeout. - 'js1_5/GC/regress-203278-2': [PASS, TIMEOUT], + 'js1_5/GC/regress-203278-2': [PASS, TIMEOUT, NO_VARIANTS], }], # 'arch == mipsel' + +['arch == a64 and simulator_run == True', { + + 'js1_5/GC/regress-203278-2': [SKIP], + + # These tests time out in debug mode but pass in product mode + 'js1_5/Regress/regress-360969-03': [SKIP], + 'js1_5/Regress/regress-360969-04': [SKIP], + 'js1_5/Regress/regress-360969-05': [SKIP], + 'js1_5/Regress/regress-360969-06': [SKIP], + 'js1_5/extensions/regress-365527': [SKIP], + 'ecma/Date/15.9.5.10-2': [SKIP], + 'js1_5/Regress/regress-416628': [SKIP], + 'js1_5/extensions/regress-371636': [SKIP], + 'ecma_3/RegExp/regress-330684': [SKIP], + 'ecma_3/RegExp/regress-307456': [SKIP], + 'js1_5/Regress/regress-303213': [SKIP], + 'js1_5/extensions/regress-330569': [SKIP], + 'js1_5/extensions/regress-351448': [SKIP], + 'js1_5/extensions/regress-336410-1': [SKIP], +}], # 'arch == a64 and simulator_run == True' ] diff --git a/deps/v8/test/preparser/non-use-strict-hex-escape.js b/deps/v8/test/preparser/non-use-strict-hex-escape.js index bf28923160..44db66e42f 100644 --- a/deps/v8/test/preparser/non-use-strict-hex-escape.js +++ b/deps/v8/test/preparser/non-use-strict-hex-escape.js @@ -32,4 +32,4 @@ function foo() { "use\x20strict"; var x = "hello\040world"; return x; -}
\ No newline at end of file +} diff --git a/deps/v8/test/preparser/non-use-strict-octal-escape.js b/deps/v8/test/preparser/non-use-strict-octal-escape.js index 9e00742c21..55f035a7e0 100644 --- a/deps/v8/test/preparser/non-use-strict-octal-escape.js +++ b/deps/v8/test/preparser/non-use-strict-octal-escape.js @@ -32,4 +32,4 @@ function foo() { "use\040strict"; var x = "hello\040world"; return x; -}
\ No newline at end of file +} diff --git a/deps/v8/test/preparser/non-use-strict-uhex-escape.js b/deps/v8/test/preparser/non-use-strict-uhex-escape.js index 5fba673163..c7df2cb97e 100644 --- a/deps/v8/test/preparser/non-use-strict-uhex-escape.js +++ b/deps/v8/test/preparser/non-use-strict-uhex-escape.js @@ -32,4 +32,4 @@ function foo() { "use\u0020strict"; var x = "hello\040world"; return x; -}
\ No newline at end of file +} diff --git a/deps/v8/test/preparser/nonstrict-arguments.js b/deps/v8/test/preparser/nonstrict-arguments.js index 890f62e739..43c7e2e940 100644 --- a/deps/v8/test/preparser/nonstrict-arguments.js +++ b/deps/v8/test/preparser/nonstrict-arguments.js @@ -48,4 +48,3 @@ arguments -= ++arguments; arguments *= arguments--; function arguments(arguments) {}; try {} catch (arguments) {} - diff --git a/deps/v8/test/preparser/nonstrict-eval.js b/deps/v8/test/preparser/nonstrict-eval.js index ad994ab438..db6feda3e3 100644 --- a/deps/v8/test/preparser/nonstrict-eval.js +++ b/deps/v8/test/preparser/nonstrict-eval.js @@ -48,4 +48,3 @@ eval -= ++eval; eval *= eval--; function eval(eval) {}; try {} catch (eval) {} - diff --git a/deps/v8/test/preparser/nonstrict-with.js b/deps/v8/test/preparser/nonstrict-with.js index 12d05a0536..17f0c930a6 100644 --- a/deps/v8/test/preparser/nonstrict-with.js +++ b/deps/v8/test/preparser/nonstrict-with.js @@ -38,6 +38,3 @@ with ({x : 42}) { } with ({}) {} - - - diff --git a/deps/v8/test/preparser/preparser.status b/deps/v8/test/preparser/preparser.status index 9d69988f71..babf35d5d8 100644 --- a/deps/v8/test/preparser/preparser.status +++ b/deps/v8/test/preparser/preparser.status @@ -25,6 +25,10 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# We don't parse RegExps at scanning time, so we can't fail on octal +# escapes (we need to parse to distinguish octal escapes from valid +# back-references). [ [ALWAYS, { # TODO(mstarzinger): This script parses but throws a TypeError when run. diff --git a/deps/v8/test/preparser/strict-const.js b/deps/v8/test/preparser/strict-const.js index 91e9e39e7c..2b9230c053 100644 --- a/deps/v8/test/preparser/strict-const.js +++ b/deps/v8/test/preparser/strict-const.js @@ -26,4 +26,4 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. "use strict"; -const x = 42;
\ No newline at end of file +const x = 42; diff --git a/deps/v8/test/preparser/strict-octal-indirect-regexp.js b/deps/v8/test/preparser/strict-octal-indirect-regexp.js index 122bd3de06..ea5c5e3348 100644 --- a/deps/v8/test/preparser/strict-octal-indirect-regexp.js +++ b/deps/v8/test/preparser/strict-octal-indirect-regexp.js @@ -31,4 +31,4 @@ function foo() { "use strict"; var re = RegExp("Hello\\040World"); return re; -}
\ No newline at end of file +} diff --git a/deps/v8/test/preparser/strict-octal-number.js b/deps/v8/test/preparser/strict-octal-number.js index d387d6a32e..3e991279fa 100644 --- a/deps/v8/test/preparser/strict-octal-number.js +++ b/deps/v8/test/preparser/strict-octal-number.js @@ -31,4 +31,4 @@ function foo() { "use strict"; var x = 012; return x; -}
\ No newline at end of file +} diff --git a/deps/v8/test/preparser/strict-octal-regexp.js b/deps/v8/test/preparser/strict-octal-regexp.js index fded9bf86c..b39d0b27c7 100644 --- a/deps/v8/test/preparser/strict-octal-regexp.js +++ b/deps/v8/test/preparser/strict-octal-regexp.js @@ -31,4 +31,4 @@ function foo() { "use strict"; var re = /hello\040world/; return re; -}
\ No newline at end of file +} diff --git a/deps/v8/test/preparser/strict-octal-string.js b/deps/v8/test/preparser/strict-octal-string.js index 40408e6fe6..87c0e99fb1 100644 --- a/deps/v8/test/preparser/strict-octal-string.js +++ b/deps/v8/test/preparser/strict-octal-string.js @@ -31,4 +31,4 @@ function foo() { "use strict"; var x = "hello\040world"; return x; -}
\ No newline at end of file +} diff --git a/deps/v8/test/preparser/strict-octal-use-strict-after.js b/deps/v8/test/preparser/strict-octal-use-strict-after.js index 1af078a8f6..57d0f20151 100644 --- a/deps/v8/test/preparser/strict-octal-use-strict-after.js +++ b/deps/v8/test/preparser/strict-octal-use-strict-after.js @@ -32,4 +32,4 @@ function foo() { "use strict"; "use\040strict"; return true; -}
\ No newline at end of file +} diff --git a/deps/v8/test/preparser/strict-octal-use-strict-before.js b/deps/v8/test/preparser/strict-octal-use-strict-before.js index 1dbb57128d..bfc380f950 100644 --- a/deps/v8/test/preparser/strict-octal-use-strict-before.js +++ b/deps/v8/test/preparser/strict-octal-use-strict-before.js @@ -32,4 +32,4 @@ function foo() { "use\040strict"; "use strict"; return true; -}
\ No newline at end of file +} diff --git a/deps/v8/test/preparser/strict-with.js b/deps/v8/test/preparser/strict-with.js index a19355eec1..411fc2926c 100644 --- a/deps/v8/test/preparser/strict-with.js +++ b/deps/v8/test/preparser/strict-with.js @@ -30,4 +30,4 @@ function foo() { "use strict"; with ({}) {} -}
\ No newline at end of file +} diff --git a/deps/v8/test/test262/test262.status b/deps/v8/test/test262/test262.status index e546266f3a..fdbdc65118 100644 --- a/deps/v8/test/test262/test262.status +++ b/deps/v8/test/test262/test262.status @@ -29,12 +29,6 @@ [ALWAYS, { ############################### BUGS ################################### - # Sequencing of getter side effects on receiver and argument properties - # is wrong. The receiver callback should be called before any arguments - # are evaluated. - # V8 Bug: http://code.google.com/p/v8/issues/detail?id=691 - '11.2.3-3_3': [FAIL], - '15.5.4.9_CE': [['no_i18n', SKIP]], ######################## NEEDS INVESTIGATION ########################### @@ -73,6 +67,7 @@ # trigonometric functions are platform/compiler dependent. Furthermore, the # expectation values by far deviates from the actual result given by an # arbitrary-precision calculator, making those tests partly bogus. + 'S15.8.2.7_A7': [PASS, FAIL_OK], # Math.cos 'S15.8.2.8_A6': [PASS, FAIL_OK], # Math.exp (less precise with --fast-math) 'S15.8.2.16_A7': [PASS, FAIL_OK], # Math.sin 'S15.8.2.18_A7': [PASS, FAIL_OK], # Math.tan @@ -104,7 +99,7 @@ 'S15.1.3.2_A2.5_T1': [PASS, ['mode == debug', SKIP]], }], # ALWAYS -['arch == arm or arch == mipsel', { +['arch == arm or arch == mipsel or arch == a64', { # TODO(mstarzinger): Causes stack overflow on simulators due to eager # compilation of parenthesized function literals. Needs investigation. @@ -117,5 +112,5 @@ 'S15.1.3.2_A2.5_T1': [SKIP], 'S15.1.3.3_A2.3_T1': [SKIP], 'S15.1.3.4_A2.3_T1': [SKIP], -}], # 'arch == arm or arch == mipsel' +}], # 'arch == arm or arch == mipsel or arch == a64' ] diff --git a/deps/v8/test/webkit/Object-create-expected.txt b/deps/v8/test/webkit/Object-create-expected.txt index 519cfb4436..ff31544028 100644 --- a/deps/v8/test/webkit/Object-create-expected.txt +++ b/deps/v8/test/webkit/Object-create-expected.txt @@ -26,8 +26,8 @@ Test to ensure correct behaviour of Object.defineProperties On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS Object.create() threw exception TypeError: Object prototype may only be an Object or null. -PASS Object.create('a string') threw exception TypeError: Object prototype may only be an Object or null. +PASS Object.create() threw exception TypeError: Object prototype may only be an Object or null: undefined. +PASS Object.create('a string') threw exception TypeError: Object prototype may only be an Object or null: a string. PASS Object.create({}, 'a string') threw exception TypeError: Property description must be an object: a. PASS Object.create(null, 'a string') threw exception TypeError: Property description must be an object: a. PASS JSON.stringify(Object.create(null,{property:{value:'foo', enumerable:true}, property2:{value:'foo', enumerable:true}})) is '{"property":"foo","property2":"foo"}' diff --git a/deps/v8/test/webkit/arguments-bad-index.js b/deps/v8/test/webkit/arguments-bad-index.js index a4dd4d53b9..28a4fd67f5 100644 --- a/deps/v8/test/webkit/arguments-bad-index.js +++ b/deps/v8/test/webkit/arguments-bad-index.js @@ -34,4 +34,3 @@ shouldBe('indexArguments(1, "a")', '"a"'); shouldBe('indexArguments("1 ", "a")', 'undefined'); shouldBe('indexArguments(0xDEADBEEF)', 'undefined'); shouldBe('indexArguments(0xFFFFFFFF)', 'undefined'); - diff --git a/deps/v8/test/webkit/array-splice-expected.txt b/deps/v8/test/webkit/array-splice-expected.txt new file mode 100644 index 0000000000..800f2cdfe3 --- /dev/null +++ b/deps/v8/test/webkit/array-splice-expected.txt @@ -0,0 +1,53 @@ +# Copyright 2013 the V8 project authors. All rights reserved. +# Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This tests array.splice behavior. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS arr is ['a','b','c','d'] +PASS arr.splice(2) is ['c','d'] +PASS arr is ['a','b'] +PASS arr.splice(0) is ['a','b'] +PASS arr is [] +PASS arr.splice() is [] +PASS arr is ['a','b','c','d'] +PASS arr.splice(undefined) is ['a','b','c','d'] +PASS arr is [] +PASS arr.splice(null) is ['a','b','c','d'] +PASS arr is [] +PASS arr.splice(100) is [] +PASS arr is ['a','b','c','d'] +PASS arr.splice(-1) is ['d'] +PASS arr is ['a','b','c'] +PASS arr.splice(2, undefined) is [] +PASS arr.splice(2, null) is [] +PASS arr.splice(2, -1) is [] +PASS arr is ['a','b','c'] +PASS arr.splice(2, 100) is ['c'] +PASS arr is ['a','b'] +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/deps/v8/test/webkit/array-splice.js b/deps/v8/test/webkit/array-splice.js new file mode 100644 index 0000000000..045e39e379 --- /dev/null +++ b/deps/v8/test/webkit/array-splice.js @@ -0,0 +1,61 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +description( +"This tests array.splice behavior." +); + +var arr = ['a','b','c','d']; +shouldBe("arr", "['a','b','c','d']"); +shouldBe("arr.splice(2)", "['c','d']"); +shouldBe("arr", "['a','b']"); +shouldBe("arr.splice(0)", "['a','b']"); +shouldBe("arr", "[]") + +arr = ['a','b','c','d']; +shouldBe("arr.splice()", "[]") +shouldBe("arr", "['a','b','c','d']"); +shouldBe("arr.splice(undefined)", "['a','b','c','d']") +shouldBe("arr", "[]"); + +arr = ['a','b','c','d']; +shouldBe("arr.splice(null)", "['a','b','c','d']") +shouldBe("arr", "[]"); + +arr = ['a','b','c','d']; +shouldBe("arr.splice(100)", "[]") +shouldBe("arr", "['a','b','c','d']"); +shouldBe("arr.splice(-1)", "['d']") +shouldBe("arr", "['a','b','c']"); + +shouldBe("arr.splice(2, undefined)", "[]") +shouldBe("arr.splice(2, null)", "[]") +shouldBe("arr.splice(2, -1)", "[]") +shouldBe("arr", "['a','b','c']"); +shouldBe("arr.splice(2, 100)", "['c']") +shouldBe("arr", "['a','b']"); + +// Check this doesn't crash. +try { + String(Array(0xFFFFFFFD).splice(0)); +} catch (e) { } diff --git a/deps/v8/test/webkit/concat-while-having-a-bad-time.js b/deps/v8/test/webkit/concat-while-having-a-bad-time.js index dfda1e08a0..2c29917d5b 100644 --- a/deps/v8/test/webkit/concat-while-having-a-bad-time.js +++ b/deps/v8/test/webkit/concat-while-having-a-bad-time.js @@ -27,5 +27,3 @@ description( Object.defineProperty(Array.prototype, 0, { writable: false }); shouldBe("[42].concat()", "[42]"); - - diff --git a/deps/v8/test/webkit/dfg-abs-backwards-propagation.js b/deps/v8/test/webkit/dfg-abs-backwards-propagation.js index 828e2d620e..1685ba08e2 100644 --- a/deps/v8/test/webkit/dfg-abs-backwards-propagation.js +++ b/deps/v8/test/webkit/dfg-abs-backwards-propagation.js @@ -46,4 +46,3 @@ for (var i = 0; i < 200; ++i) { } shouldBe("foo(" + f + ", " + array + ", 0)", expected); } - diff --git a/deps/v8/test/webkit/dfg-add-not-number.js b/deps/v8/test/webkit/dfg-add-not-number.js index df6dcdf2ef..1d3764662e 100644 --- a/deps/v8/test/webkit/dfg-add-not-number.js +++ b/deps/v8/test/webkit/dfg-add-not-number.js @@ -32,4 +32,3 @@ function foo(a) { for (var i = 0; i < 100; ++i) shouldBe("foo(\"foo\" + i)", "NaN"); - diff --git a/deps/v8/test/webkit/dfg-arguments-alias-escape.js b/deps/v8/test/webkit/dfg-arguments-alias-escape.js index f7a012eebd..dce0c3dfd6 100644 --- a/deps/v8/test/webkit/dfg-arguments-alias-escape.js +++ b/deps/v8/test/webkit/dfg-arguments-alias-escape.js @@ -40,4 +40,3 @@ function bar(x) { for (var i = 0; i < 200; ++i) shouldBe("bar(42)", "1764"); - diff --git a/deps/v8/test/webkit/dfg-arguments-alias-one-block-overwrite.js b/deps/v8/test/webkit/dfg-arguments-alias-one-block-overwrite.js index e94ad8b011..33154e99ff 100644 --- a/deps/v8/test/webkit/dfg-arguments-alias-one-block-overwrite.js +++ b/deps/v8/test/webkit/dfg-arguments-alias-one-block-overwrite.js @@ -42,4 +42,3 @@ for (var i = 0; i < 300; ++i) { var c = i + 3; shouldBe("foo(a, b, c)", "6"); } - diff --git a/deps/v8/test/webkit/dfg-arguments-alias.js b/deps/v8/test/webkit/dfg-arguments-alias.js index c30fe89eb7..6fc7195e8c 100644 --- a/deps/v8/test/webkit/dfg-arguments-alias.js +++ b/deps/v8/test/webkit/dfg-arguments-alias.js @@ -39,4 +39,3 @@ function bar(x) { for (var i = 0; i < 200; ++i) shouldBe("bar(42)", "42"); - diff --git a/deps/v8/test/webkit/dfg-arguments-mixed-alias.js b/deps/v8/test/webkit/dfg-arguments-mixed-alias.js index 477eac3d5f..7d52ffb757 100644 --- a/deps/v8/test/webkit/dfg-arguments-mixed-alias.js +++ b/deps/v8/test/webkit/dfg-arguments-mixed-alias.js @@ -39,4 +39,3 @@ function bar(x) { for (var i = 0; i < 200; ++i) shouldBe("bar(42)", "42"); - diff --git a/deps/v8/test/webkit/dfg-arguments-out-of-bounds.js b/deps/v8/test/webkit/dfg-arguments-out-of-bounds.js index 8774d2cc09..e6e9a017ef 100644 --- a/deps/v8/test/webkit/dfg-arguments-out-of-bounds.js +++ b/deps/v8/test/webkit/dfg-arguments-out-of-bounds.js @@ -49,4 +49,3 @@ for (var i = 0; i < 3000; ++i) { result = "" +foo.apply(void 0, args); shouldBe("result", expected); } - diff --git a/deps/v8/test/webkit/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.js b/deps/v8/test/webkit/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.js index 54c049f1c2..ecd2ed2ffa 100644 --- a/deps/v8/test/webkit/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.js +++ b/deps/v8/test/webkit/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.js @@ -64,4 +64,3 @@ for (var i = 0; i < warmup + badCases.length; ++i) { } shouldBe("bar(" + a + ", " + b + ", {f:" + c + "})", "" + expected); } - diff --git a/deps/v8/test/webkit/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.js b/deps/v8/test/webkit/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.js index 292926eaba..718fa5ee5d 100644 --- a/deps/v8/test/webkit/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.js +++ b/deps/v8/test/webkit/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.js @@ -57,4 +57,3 @@ for (var i = 0; i < warmup + 1; ++i) { } shouldBe("bar(" + a + ", " + b + ")", "" + expected); } - diff --git a/deps/v8/test/webkit/dfg-array-dead.js b/deps/v8/test/webkit/dfg-array-dead.js index a6276178f3..c40a37c119 100644 --- a/deps/v8/test/webkit/dfg-array-dead.js +++ b/deps/v8/test/webkit/dfg-array-dead.js @@ -49,4 +49,3 @@ function bar(x) { for (var i = 0; i < 1000; ++i) { shouldBe("foo()", "2"); } - diff --git a/deps/v8/test/webkit/dfg-array-length-dead.js b/deps/v8/test/webkit/dfg-array-length-dead.js index 5256fe1eba..9191524edf 100644 --- a/deps/v8/test/webkit/dfg-array-length-dead.js +++ b/deps/v8/test/webkit/dfg-array-length-dead.js @@ -33,4 +33,3 @@ function foo(x) { for (var i = 0; i < 1000; ++i) { shouldBe("foo({f:[]})", "42"); } - diff --git a/deps/v8/test/webkit/dfg-branch-logical-not-peephole-around-osr-exit.js b/deps/v8/test/webkit/dfg-branch-logical-not-peephole-around-osr-exit.js index ab0215e7b5..9e92c24e8c 100644 --- a/deps/v8/test/webkit/dfg-branch-logical-not-peephole-around-osr-exit.js +++ b/deps/v8/test/webkit/dfg-branch-logical-not-peephole-around-osr-exit.js @@ -39,4 +39,3 @@ for (var i = 0; i < 200; ++i) { var expected = i + (i == 199 ? 2147483647 : 5) + (i !== 5 ? 1 : -1) shouldBe("foo(i, 5, i == 199 ? 2147483647 : 5)", "" + expected); } - diff --git a/deps/v8/test/webkit/dfg-branch-not-fail.js b/deps/v8/test/webkit/dfg-branch-not-fail.js index af7ba97052..31de5afc47 100644 --- a/deps/v8/test/webkit/dfg-branch-not-fail.js +++ b/deps/v8/test/webkit/dfg-branch-not-fail.js @@ -51,4 +51,3 @@ for (var i = 0; i < 200; ++i) { shouldBe("bar({f:True})", "0"); shouldBe("bar({f:False})", "1"); } - diff --git a/deps/v8/test/webkit/dfg-call-function-hit-watchpoint.js b/deps/v8/test/webkit/dfg-call-function-hit-watchpoint.js index 5a332c19f8..6ee1f687cd 100644 --- a/deps/v8/test/webkit/dfg-call-function-hit-watchpoint.js +++ b/deps/v8/test/webkit/dfg-call-function-hit-watchpoint.js @@ -43,4 +43,3 @@ for (var i = 0; i < 200; ++i) { expected = -1; shouldBe("bar(i, i + 1)", "" + expected); } - diff --git a/deps/v8/test/webkit/dfg-call-method-hit-watchpoint.js b/deps/v8/test/webkit/dfg-call-method-hit-watchpoint.js index 382f899fee..8c486c786e 100644 --- a/deps/v8/test/webkit/dfg-call-method-hit-watchpoint.js +++ b/deps/v8/test/webkit/dfg-call-method-hit-watchpoint.js @@ -50,4 +50,3 @@ for (var i = 0; i < 200; ++i) { expected = 56; shouldBe("callFoo(o)", "" + expected); } - diff --git a/deps/v8/test/webkit/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.js b/deps/v8/test/webkit/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.js index 6953ffa466..870b73d52a 100644 --- a/deps/v8/test/webkit/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.js +++ b/deps/v8/test/webkit/dfg-cfa-prove-put-by-id-simple-when-storing-to-specialized-function.js @@ -52,4 +52,3 @@ function fuzz() { } shouldBe("bar.call({f:baz}, fuzz)", "\"fuzz\""); - diff --git a/deps/v8/test/webkit/dfg-cfg-simplify-eliminate-set-local-type-check-then-branch-not-null-and-decrement.js b/deps/v8/test/webkit/dfg-cfg-simplify-eliminate-set-local-type-check-then-branch-not-null-and-decrement.js index cac2d10241..aea028da7e 100644 --- a/deps/v8/test/webkit/dfg-cfg-simplify-eliminate-set-local-type-check-then-branch-not-null-and-decrement.js +++ b/deps/v8/test/webkit/dfg-cfg-simplify-eliminate-set-local-type-check-then-branch-not-null-and-decrement.js @@ -51,5 +51,3 @@ for (var i = 0; i < 500; ++i) { } shouldBe("foo(o)", expected); } - - diff --git a/deps/v8/test/webkit/dfg-cfg-simplify-eliminate-set-local-type-check-then-branch-not-null.js b/deps/v8/test/webkit/dfg-cfg-simplify-eliminate-set-local-type-check-then-branch-not-null.js index 7226424426..f2312bd962 100644 --- a/deps/v8/test/webkit/dfg-cfg-simplify-eliminate-set-local-type-check-then-branch-not-null.js +++ b/deps/v8/test/webkit/dfg-cfg-simplify-eliminate-set-local-type-check-then-branch-not-null.js @@ -49,4 +49,3 @@ for (var i = 0; i < 500; ++i) { } shouldBe("foo(o)", expected); } - diff --git a/deps/v8/test/webkit/dfg-cfg-simplify-eliminate-set-local-type-check-then-typeof.js b/deps/v8/test/webkit/dfg-cfg-simplify-eliminate-set-local-type-check-then-typeof.js index bb4fee9261..c422d31c86 100644 --- a/deps/v8/test/webkit/dfg-cfg-simplify-eliminate-set-local-type-check-then-typeof.js +++ b/deps/v8/test/webkit/dfg-cfg-simplify-eliminate-set-local-type-check-then-typeof.js @@ -51,4 +51,3 @@ for (var i = 0; i < 500; ++i) { shouldBe("result[0]", expectedFirst); shouldBe("result[1]", expectedSecond); } - diff --git a/deps/v8/test/webkit/dfg-cfg-simplify-phantom-get-local-on-same-block-set-local.js b/deps/v8/test/webkit/dfg-cfg-simplify-phantom-get-local-on-same-block-set-local.js index 65be965ccf..73daacd62a 100644 --- a/deps/v8/test/webkit/dfg-cfg-simplify-phantom-get-local-on-same-block-set-local.js +++ b/deps/v8/test/webkit/dfg-cfg-simplify-phantom-get-local-on-same-block-set-local.js @@ -60,4 +60,3 @@ function thingy(o) { for (var i = 0; i < 200; ++i) shouldBe("thingy(o)", "42"); - diff --git a/deps/v8/test/webkit/dfg-check-structure-elimination-for-non-cell-expected.txt b/deps/v8/test/webkit/dfg-check-structure-elimination-for-non-cell-expected.txt index 63b6ba2bc3..5a0941dd39 100644 --- a/deps/v8/test/webkit/dfg-check-structure-elimination-for-non-cell-expected.txt +++ b/deps/v8/test/webkit/dfg-check-structure-elimination-for-non-cell-expected.txt @@ -216,7 +216,7 @@ PASS baz(i) is 66 PASS baz(i) is 66 PASS baz(i) is 66 PASS baz(i) is 66 -Caught exception: TypeError: Cannot call method 'g' of null +Caught exception: TypeError: Cannot read property 'g' of null PASS baz(i) is "ERROR" PASS baz(i) is 66 PASS baz(i) is 66 diff --git a/deps/v8/test/webkit/dfg-compare-final-object-to-final-object-or-other-when-both-proven-final-object.js b/deps/v8/test/webkit/dfg-compare-final-object-to-final-object-or-other-when-both-proven-final-object.js index 8b986a173d..491dda159e 100644 --- a/deps/v8/test/webkit/dfg-compare-final-object-to-final-object-or-other-when-both-proven-final-object.js +++ b/deps/v8/test/webkit/dfg-compare-final-object-to-final-object-or-other-when-both-proven-final-object.js @@ -36,4 +36,3 @@ for (var i = 0; i < 100; ++i) { } else shouldThrow("foo({f:42}, null)"); } - diff --git a/deps/v8/test/webkit/dfg-compare-final-object-to-final-object-or-other-when-proven-final-object.js b/deps/v8/test/webkit/dfg-compare-final-object-to-final-object-or-other-when-proven-final-object.js index f49eed9e80..4b1694ba94 100644 --- a/deps/v8/test/webkit/dfg-compare-final-object-to-final-object-or-other-when-proven-final-object.js +++ b/deps/v8/test/webkit/dfg-compare-final-object-to-final-object-or-other-when-proven-final-object.js @@ -36,4 +36,3 @@ for (var i = 0; i < 100; ++i) { } else shouldThrow("foo({f:42}, null)"); } - diff --git a/deps/v8/test/webkit/dfg-constant-fold-first-local-read-after-block-merge.js b/deps/v8/test/webkit/dfg-constant-fold-first-local-read-after-block-merge.js index 396924240d..85ae201b85 100644 --- a/deps/v8/test/webkit/dfg-constant-fold-first-local-read-after-block-merge.js +++ b/deps/v8/test/webkit/dfg-constant-fold-first-local-read-after-block-merge.js @@ -44,4 +44,3 @@ function bar(x) { for (var i = 0; i < 200; ++i) shouldBe("bar(5)", "42"); - diff --git a/deps/v8/test/webkit/dfg-constant-fold-logical-not-branch.js b/deps/v8/test/webkit/dfg-constant-fold-logical-not-branch.js index 6a91b14cba..bb48f63f21 100644 --- a/deps/v8/test/webkit/dfg-constant-fold-logical-not-branch.js +++ b/deps/v8/test/webkit/dfg-constant-fold-logical-not-branch.js @@ -51,5 +51,3 @@ for (var i = 0; i < 1000; ++i) { shouldBe("foo1(new Stuff())", "43"); shouldBe("foo2(new Stuff())", "58"); } - - diff --git a/deps/v8/test/webkit/dfg-constant-fold-misprediction.js b/deps/v8/test/webkit/dfg-constant-fold-misprediction.js index cd73f705a2..9760e4f56a 100644 --- a/deps/v8/test/webkit/dfg-constant-fold-misprediction.js +++ b/deps/v8/test/webkit/dfg-constant-fold-misprediction.js @@ -56,5 +56,3 @@ function foo(x) { // Call foo() enough times to make totally sure that we optimize. for (var i = 0; i < 5; ++i) shouldBe("foo(0.5)", "1000.50025"); - - diff --git a/deps/v8/test/webkit/dfg-cse-cfa-discrepancy.js b/deps/v8/test/webkit/dfg-cse-cfa-discrepancy.js index a40e7e6931..561776542e 100644 --- a/deps/v8/test/webkit/dfg-cse-cfa-discrepancy.js +++ b/deps/v8/test/webkit/dfg-cse-cfa-discrepancy.js @@ -51,4 +51,3 @@ function foo(a, b) { for (var i = 0; i < 200; ++i) shouldBe("foo(i, i + 1)", "162"); - diff --git a/deps/v8/test/webkit/dfg-cse-dead-get-scoped-var.js b/deps/v8/test/webkit/dfg-cse-dead-get-scoped-var.js index aec600b6f9..de181913c0 100644 --- a/deps/v8/test/webkit/dfg-cse-dead-get-scoped-var.js +++ b/deps/v8/test/webkit/dfg-cse-dead-get-scoped-var.js @@ -38,4 +38,3 @@ function foo(a) { for (var i = 0; i < 1000; ++i) shouldBe("foo(i)(false)", "42"); - diff --git a/deps/v8/test/webkit/dfg-dead-min-one-arg.js b/deps/v8/test/webkit/dfg-dead-min-one-arg.js index 48293be9d8..3195f5b3ce 100644 --- a/deps/v8/test/webkit/dfg-dead-min-one-arg.js +++ b/deps/v8/test/webkit/dfg-dead-min-one-arg.js @@ -44,4 +44,3 @@ for (var i = 0; i < 200; ++i) { shouldBe("ok", "" + i); shouldBe("result", "" + expected); } - diff --git a/deps/v8/test/webkit/dfg-dead-min-two-args.js b/deps/v8/test/webkit/dfg-dead-min-two-args.js index f723f43b3a..d5b2a50aaa 100644 --- a/deps/v8/test/webkit/dfg-dead-min-two-args.js +++ b/deps/v8/test/webkit/dfg-dead-min-two-args.js @@ -67,4 +67,3 @@ for (var i = 0; i < 200; ++i) { shouldBe("ok", "" + i); shouldBe("result", "100"); } - diff --git a/deps/v8/test/webkit/dfg-dead-speculation.js b/deps/v8/test/webkit/dfg-dead-speculation.js index 7778f5a48e..71cdd0f7c0 100644 --- a/deps/v8/test/webkit/dfg-dead-speculation.js +++ b/deps/v8/test/webkit/dfg-dead-speculation.js @@ -42,4 +42,3 @@ for (var i = 0; i < 200; ++i) { shouldBe("foo(thingy, i)", "10"); shouldBe("variable", "" + expected); } - diff --git a/deps/v8/test/webkit/dfg-dead-variable-on-exit.js b/deps/v8/test/webkit/dfg-dead-variable-on-exit.js index 0f9f48c8cd..bc4c9ea793 100644 --- a/deps/v8/test/webkit/dfg-dead-variable-on-exit.js +++ b/deps/v8/test/webkit/dfg-dead-variable-on-exit.js @@ -84,4 +84,3 @@ for (var i = 0; i < 300; ++i) { code += "); foo(firstArg, secondArg)"; shouldBe(code, "1"); } - diff --git a/deps/v8/test/webkit/dfg-double-use-of-post-simplification-double-prediction.js b/deps/v8/test/webkit/dfg-double-use-of-post-simplification-double-prediction.js index cf385791c0..2c11eb154e 100644 --- a/deps/v8/test/webkit/dfg-double-use-of-post-simplification-double-prediction.js +++ b/deps/v8/test/webkit/dfg-double-use-of-post-simplification-double-prediction.js @@ -37,4 +37,3 @@ function foo(a) { for (var i = 0; i < 200; ++i) shouldBe("foo(0.5)", "42.5"); - diff --git a/deps/v8/test/webkit/dfg-double-vote-fuzz.js b/deps/v8/test/webkit/dfg-double-vote-fuzz.js index 266bc155bb..722341a142 100644 --- a/deps/v8/test/webkit/dfg-double-vote-fuzz.js +++ b/deps/v8/test/webkit/dfg-double-vote-fuzz.js @@ -87,5 +87,3 @@ for (var i = 0; i < 256; ++i) { } shouldBe("grandResult", "14578304"); - - diff --git a/deps/v8/test/webkit/dfg-ensure-non-array-array-storage-on-window.js b/deps/v8/test/webkit/dfg-ensure-non-array-array-storage-on-window.js index 3ae47c5dc7..11e9fbdafc 100644 --- a/deps/v8/test/webkit/dfg-ensure-non-array-array-storage-on-window.js +++ b/deps/v8/test/webkit/dfg-ensure-non-array-array-storage-on-window.js @@ -85,4 +85,3 @@ shouldBe("thingy", "42"); shouldBe("foo(w)", "1"); w.length = 2; shouldBe("foo(w)", "0/0"); - diff --git a/deps/v8/test/webkit/dfg-get-by-val-clobber.js b/deps/v8/test/webkit/dfg-get-by-val-clobber.js index c6c57fe3de..19d0091c2c 100644 --- a/deps/v8/test/webkit/dfg-get-by-val-clobber.js +++ b/deps/v8/test/webkit/dfg-get-by-val-clobber.js @@ -49,4 +49,3 @@ for (var i = 0; i < 1000; ++i) { // Undo. array1[0] = 1; } - diff --git a/deps/v8/test/webkit/dfg-getter-throw.js b/deps/v8/test/webkit/dfg-getter-throw.js index c77b33d060..2632242bd3 100644 --- a/deps/v8/test/webkit/dfg-getter-throw.js +++ b/deps/v8/test/webkit/dfg-getter-throw.js @@ -47,5 +47,3 @@ for (var i = 0; i < 200; ++i) { }); shouldBe("bar(o)", i < 100 ? "\"Returned result: " + i + "\"" : "\"Threw exception: Oh hi, I'm an exception!\""); } - - diff --git a/deps/v8/test/webkit/dfg-getter.js b/deps/v8/test/webkit/dfg-getter.js index dafd9f9c8c..d0f566444e 100644 --- a/deps/v8/test/webkit/dfg-getter.js +++ b/deps/v8/test/webkit/dfg-getter.js @@ -34,5 +34,3 @@ for (var i = 0; i < 200; ++i) { o.__defineGetter__("f", function(){ return i; }); shouldBe("foo(o)", "" + i); } - - diff --git a/deps/v8/test/webkit/dfg-holy-put-by-val-interferes-with-get-array-length.js b/deps/v8/test/webkit/dfg-holy-put-by-val-interferes-with-get-array-length.js index 684ebe8194..4b83711a48 100644 --- a/deps/v8/test/webkit/dfg-holy-put-by-val-interferes-with-get-array-length.js +++ b/deps/v8/test/webkit/dfg-holy-put-by-val-interferes-with-get-array-length.js @@ -33,5 +33,3 @@ function foo(array) { for (var i = 0; i < 100; ++i) shouldBe("foo([75])", "[1,2]"); - - diff --git a/deps/v8/test/webkit/dfg-inline-arguments-osr-exit-and-capture.js b/deps/v8/test/webkit/dfg-inline-arguments-osr-exit-and-capture.js index 82a49faa68..4d254d8e7d 100644 --- a/deps/v8/test/webkit/dfg-inline-arguments-osr-exit-and-capture.js +++ b/deps/v8/test/webkit/dfg-inline-arguments-osr-exit-and-capture.js @@ -53,4 +53,3 @@ for (var i = 0; i < 300; ++i) { } shouldBe("baz(arg1, arg2)", "" + expected); } - diff --git a/deps/v8/test/webkit/dfg-inline-arguments-out-of-bounds.js b/deps/v8/test/webkit/dfg-inline-arguments-out-of-bounds.js index 23b9184cac..9cd6ec0f59 100644 --- a/deps/v8/test/webkit/dfg-inline-arguments-out-of-bounds.js +++ b/deps/v8/test/webkit/dfg-inline-arguments-out-of-bounds.js @@ -50,4 +50,3 @@ for (var i = 0; i < 3000; ++i) { result = "" + bar(); shouldBe("result", expected); } - diff --git a/deps/v8/test/webkit/dfg-inline-arguments-use-directly-from-inlined-code.js b/deps/v8/test/webkit/dfg-inline-arguments-use-directly-from-inlined-code.js index a1c5ca2576..95a98bc3cb 100644 --- a/deps/v8/test/webkit/dfg-inline-arguments-use-directly-from-inlined-code.js +++ b/deps/v8/test/webkit/dfg-inline-arguments-use-directly-from-inlined-code.js @@ -45,4 +45,3 @@ function argsToStr(args) { for (var __i = 0; __i < 200; ++__i) shouldBe("argsToStr(bar(\"a\" + __i, \"b\" + __i, \"c\" + __i))", "\"[object Arguments]: a" + __i + ", b" + __i + ", c" + __i + "\""); - diff --git a/deps/v8/test/webkit/dfg-inline-arguments-use-from-all-the-places-broken.js b/deps/v8/test/webkit/dfg-inline-arguments-use-from-all-the-places-broken.js index b4fa6c1883..cc22ec4e4d 100644 --- a/deps/v8/test/webkit/dfg-inline-arguments-use-from-all-the-places-broken.js +++ b/deps/v8/test/webkit/dfg-inline-arguments-use-from-all-the-places-broken.js @@ -58,4 +58,3 @@ function argsToStr(args) { for (var __i = 0; __i < 200; ++__i) shouldThrow("argsToStr(bar(\"a\" + __i, \"b\" + __i, \"c\" + __i))"); - diff --git a/deps/v8/test/webkit/dfg-inline-arguments-use-from-all-the-places.js b/deps/v8/test/webkit/dfg-inline-arguments-use-from-all-the-places.js index 4470d9cc66..fce5430d07 100644 --- a/deps/v8/test/webkit/dfg-inline-arguments-use-from-all-the-places.js +++ b/deps/v8/test/webkit/dfg-inline-arguments-use-from-all-the-places.js @@ -62,4 +62,3 @@ for (var __i = 0; __i < 200; ++__i) { var text3 = "[[object Arguments]: 42, 56]"; shouldBe("argsToStr(bar(o, \"b\" + __i, \"c\" + __i))", "\"[[object Arguments],[object Arguments],[object Arguments],[object Arguments],[object Arguments],[object Arguments],[object Arguments],[object Arguments],[object Arguments],[object Arguments]: " + text1 + ", " + text1 + ", " + text1 + ", " + text1 + ", " + text1 + ", " + text2 + ", " + text1 + ", " + text1 + ", " + text2 + ", " + text3 + "]\""); } - diff --git a/deps/v8/test/webkit/dfg-inline-arguments-use-from-getter.js b/deps/v8/test/webkit/dfg-inline-arguments-use-from-getter.js index f532d35ce8..bece496020 100644 --- a/deps/v8/test/webkit/dfg-inline-arguments-use-from-getter.js +++ b/deps/v8/test/webkit/dfg-inline-arguments-use-from-getter.js @@ -48,4 +48,3 @@ function argsToStr(args) { for (var __i = 0; __i < 200; ++__i) shouldBe("argsToStr(bar(o, \"b\" + __i, \"c\" + __i))", "\"[object Arguments]: [object Object], b" + __i + ", c" + __i + "\""); - diff --git a/deps/v8/test/webkit/dfg-inline-function-dot-caller.js b/deps/v8/test/webkit/dfg-inline-function-dot-caller.js index c6dd2b249f..dbbefb8ae2 100644 --- a/deps/v8/test/webkit/dfg-inline-function-dot-caller.js +++ b/deps/v8/test/webkit/dfg-inline-function-dot-caller.js @@ -66,4 +66,3 @@ shouldBe("resultArray[3]", "\"g\""); shouldBe("resultArray[2]", "\"makeInlinableCall\""); shouldBe("resultArray[1]", "\"inlineable\""); shouldBe("resultArray[0]", "\"nonInlineable\""); - diff --git a/deps/v8/test/webkit/dfg-inline-unused-this-method-check.js b/deps/v8/test/webkit/dfg-inline-unused-this-method-check.js index 929592eef9..13ad448b9e 100644 --- a/deps/v8/test/webkit/dfg-inline-unused-this-method-check.js +++ b/deps/v8/test/webkit/dfg-inline-unused-this-method-check.js @@ -51,4 +51,3 @@ for (var i = 0; i < 1000; ++i) { shouldBe("baz(object, " + i + ", " + (i * 2) + ")", "" + (offset + i + i * 2)); } - diff --git a/deps/v8/test/webkit/dfg-inline-unused-this.js b/deps/v8/test/webkit/dfg-inline-unused-this.js index 5983d72444..826008326b 100644 --- a/deps/v8/test/webkit/dfg-inline-unused-this.js +++ b/deps/v8/test/webkit/dfg-inline-unused-this.js @@ -54,4 +54,3 @@ for (var i = 0; i < 1000; ++i) { shouldBe("baz(object, " + i + ", " + (i * 2) + ")", "" + (offset + i + i * 2)); } - diff --git a/deps/v8/test/webkit/dfg-int-overflow-in-loop.js b/deps/v8/test/webkit/dfg-int-overflow-in-loop.js index 8752a12cbd..07b8e3442a 100644 --- a/deps/v8/test/webkit/dfg-int-overflow-in-loop.js +++ b/deps/v8/test/webkit/dfg-int-overflow-in-loop.js @@ -37,4 +37,3 @@ function foo(a) { } shouldBe("foo(0)", "-4094336"); - diff --git a/deps/v8/test/webkit/dfg-int-overflow-large-constants-in-a-line.js b/deps/v8/test/webkit/dfg-int-overflow-large-constants-in-a-line.js index 4e2f970dd4..dc6ff09fa2 100644 --- a/deps/v8/test/webkit/dfg-int-overflow-large-constants-in-a-line.js +++ b/deps/v8/test/webkit/dfg-int-overflow-large-constants-in-a-line.js @@ -72,5 +72,3 @@ function foo(a) { for (var i = 0; i < 200; ++i) shouldBe("foo(2147483647)", "2147483552"); - - diff --git a/deps/v8/test/webkit/dfg-integer-optimization.js b/deps/v8/test/webkit/dfg-integer-optimization.js index 31ec8fce4f..0041aec8d1 100644 --- a/deps/v8/test/webkit/dfg-integer-optimization.js +++ b/deps/v8/test/webkit/dfg-integer-optimization.js @@ -43,4 +43,3 @@ for (var i = 0; i < 1000; ++i) { shouldBe("result.a", "" + eval("((" + a + " + " + b + ") | 0)")) shouldBe("result.b", "" + eval(a + " + " + b)) } - diff --git a/deps/v8/test/webkit/dfg-intrinsic-side-effect-assignment-osr-exit.js b/deps/v8/test/webkit/dfg-intrinsic-side-effect-assignment-osr-exit.js index 4a32738159..f8316af724 100644 --- a/deps/v8/test/webkit/dfg-intrinsic-side-effect-assignment-osr-exit.js +++ b/deps/v8/test/webkit/dfg-intrinsic-side-effect-assignment-osr-exit.js @@ -46,4 +46,3 @@ for (var i = 0; i < 500; ++i) { } shouldBe("foo(array)", expected); } - diff --git a/deps/v8/test/webkit/dfg-intrinsic-unused-this-method-check.js b/deps/v8/test/webkit/dfg-intrinsic-unused-this-method-check.js index 4424400fb2..445cb0b34e 100644 --- a/deps/v8/test/webkit/dfg-intrinsic-unused-this-method-check.js +++ b/deps/v8/test/webkit/dfg-intrinsic-unused-this-method-check.js @@ -47,4 +47,3 @@ for (var i = 0; i < 1000; ++i) { shouldBe("baz(object, " + i + ", " + (i * 2) + ")", "" + (offset + Math.max(i, i * 2))); } - diff --git a/deps/v8/test/webkit/dfg-intrinsic-unused-this.js b/deps/v8/test/webkit/dfg-intrinsic-unused-this.js index f7d3aa5b27..fa2086873b 100644 --- a/deps/v8/test/webkit/dfg-intrinsic-unused-this.js +++ b/deps/v8/test/webkit/dfg-intrinsic-unused-this.js @@ -50,4 +50,3 @@ for (var i = 0; i < 1000; ++i) { shouldBe("baz(object, " + i + ", " + (i * 2) + ")", "" + (offset + Math.max(i, i * 2))); } - diff --git a/deps/v8/test/webkit/dfg-max-backwards-propagation.js b/deps/v8/test/webkit/dfg-max-backwards-propagation.js index b4041e1f63..0fd18fbb1c 100644 --- a/deps/v8/test/webkit/dfg-max-backwards-propagation.js +++ b/deps/v8/test/webkit/dfg-max-backwards-propagation.js @@ -46,4 +46,3 @@ for (var i = 0; i < 200; ++i) { } shouldBe("foo(" + f + ", " + array + ", 0)", expected); } - diff --git a/deps/v8/test/webkit/dfg-min-backwards-propagation.js b/deps/v8/test/webkit/dfg-min-backwards-propagation.js index 835aefa217..b423a8f357 100644 --- a/deps/v8/test/webkit/dfg-min-backwards-propagation.js +++ b/deps/v8/test/webkit/dfg-min-backwards-propagation.js @@ -46,4 +46,3 @@ for (var i = 0; i < 200; ++i) { } shouldBe("foo(" + f + ", " + array + ", 0)", expected); } - diff --git a/deps/v8/test/webkit/dfg-mispredict-variable-but-prove-int.js b/deps/v8/test/webkit/dfg-mispredict-variable-but-prove-int.js index c312670317..47530c6b54 100644 --- a/deps/v8/test/webkit/dfg-mispredict-variable-but-prove-int.js +++ b/deps/v8/test/webkit/dfg-mispredict-variable-but-prove-int.js @@ -41,4 +41,3 @@ shouldBe("foo(0, 1, 0)", "0.5"); for (var i = 0; i < 200; ++i) shouldBe("foo(i, i + 1, i + 2)", "1"); - diff --git a/deps/v8/test/webkit/dfg-mul-big-integer-with-small-integer-and-bitor.js b/deps/v8/test/webkit/dfg-mul-big-integer-with-small-integer-and-bitor.js index 51401ea87e..bdb4ecf5a6 100644 --- a/deps/v8/test/webkit/dfg-mul-big-integer-with-small-integer-and-bitor.js +++ b/deps/v8/test/webkit/dfg-mul-big-integer-with-small-integer-and-bitor.js @@ -31,6 +31,3 @@ function foo(a) { for (var i = 0; i < 100; ++i) shouldBe("foo(2147483647)", "-65536"); - - - diff --git a/deps/v8/test/webkit/dfg-mul-big-integer-with-small-integer-and-detect-overflow.js b/deps/v8/test/webkit/dfg-mul-big-integer-with-small-integer-and-detect-overflow.js index 65ed8b761c..b891794db6 100644 --- a/deps/v8/test/webkit/dfg-mul-big-integer-with-small-integer-and-detect-overflow.js +++ b/deps/v8/test/webkit/dfg-mul-big-integer-with-small-integer-and-detect-overflow.js @@ -31,5 +31,3 @@ function foo(a) { for (var i = 0; i < 1000; ++i) shouldBe("foo(2147483647)", "140737488289792"); - - diff --git a/deps/v8/test/webkit/dfg-mul-big-integers.js b/deps/v8/test/webkit/dfg-mul-big-integers.js index 0176a25855..2dbd30d9f9 100644 --- a/deps/v8/test/webkit/dfg-mul-big-integers.js +++ b/deps/v8/test/webkit/dfg-mul-big-integers.js @@ -31,5 +31,3 @@ function foo(a, b) { for (var i = 0; i < 100; ++i) shouldBe("foo(2147483647, 2147483646)", "-2147483648"); - - diff --git a/deps/v8/test/webkit/dfg-multi-basic-block-structure-clobber.js b/deps/v8/test/webkit/dfg-multi-basic-block-structure-clobber.js index a4d8bdb99a..741a60871f 100644 --- a/deps/v8/test/webkit/dfg-multi-basic-block-structure-clobber.js +++ b/deps/v8/test/webkit/dfg-multi-basic-block-structure-clobber.js @@ -53,4 +53,3 @@ for (var i = 0; i < 200; ++i) { } shouldBe("foo(predicate, {f:object})", "" + expected); } - diff --git a/deps/v8/test/webkit/dfg-multiply.js b/deps/v8/test/webkit/dfg-multiply.js index 95f278fece..e52c5bd61c 100644 --- a/deps/v8/test/webkit/dfg-multiply.js +++ b/deps/v8/test/webkit/dfg-multiply.js @@ -65,4 +65,3 @@ for (var i = 0; i < 10; ++i) { shouldBe("doMultiplyConstant4(-1073741824)", "-4294967296"); shouldBe("doMultiplyConstant4(-2147483648)", "-8589934592"); } - diff --git a/deps/v8/test/webkit/dfg-negative-array-index.js b/deps/v8/test/webkit/dfg-negative-array-index.js index f23c7fb8a9..8627ea5ed5 100644 --- a/deps/v8/test/webkit/dfg-negative-array-index.js +++ b/deps/v8/test/webkit/dfg-negative-array-index.js @@ -34,4 +34,3 @@ for (var i = 0; i < 100; ++i) { foo(array, -1); shouldBe("array[-1]", "42"); } - diff --git a/deps/v8/test/webkit/dfg-patchable-get-by-id-after-watchpoint.js b/deps/v8/test/webkit/dfg-patchable-get-by-id-after-watchpoint.js index 9866126ef0..f4d0035aac 100644 --- a/deps/v8/test/webkit/dfg-patchable-get-by-id-after-watchpoint.js +++ b/deps/v8/test/webkit/dfg-patchable-get-by-id-after-watchpoint.js @@ -67,4 +67,3 @@ for (var i = 0; i < 200; ++i) { } shouldBe("foo(o, p)", "" + expected); } - diff --git a/deps/v8/test/webkit/dfg-peephole-compare-final-object-to-final-object-or-other-when-both-proven-final-object.js b/deps/v8/test/webkit/dfg-peephole-compare-final-object-to-final-object-or-other-when-both-proven-final-object.js index f8a67946a2..cbe4343f0a 100644 --- a/deps/v8/test/webkit/dfg-peephole-compare-final-object-to-final-object-or-other-when-both-proven-final-object.js +++ b/deps/v8/test/webkit/dfg-peephole-compare-final-object-to-final-object-or-other-when-both-proven-final-object.js @@ -43,4 +43,3 @@ for (var i = 0; i < 100; ++i) { } else shouldThrow("foo({f:42}, null)"); } - diff --git a/deps/v8/test/webkit/dfg-peephole-compare-final-object-to-final-object-or-other-when-proven-final-object.js b/deps/v8/test/webkit/dfg-peephole-compare-final-object-to-final-object-or-other-when-proven-final-object.js index 5e27539b17..7fbc38619a 100644 --- a/deps/v8/test/webkit/dfg-peephole-compare-final-object-to-final-object-or-other-when-proven-final-object.js +++ b/deps/v8/test/webkit/dfg-peephole-compare-final-object-to-final-object-or-other-when-proven-final-object.js @@ -42,4 +42,3 @@ for (var i = 0; i < 100; ++i) { } else shouldThrow("foo({f:42}, null)"); } - diff --git a/deps/v8/test/webkit/dfg-phantom-base.js b/deps/v8/test/webkit/dfg-phantom-base.js index f881b899d1..9b32195754 100644 --- a/deps/v8/test/webkit/dfg-phantom-base.js +++ b/deps/v8/test/webkit/dfg-phantom-base.js @@ -39,4 +39,3 @@ function foo(o) { for (var i = 0; i < 200; ++i) shouldBe("foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}})", "false"); - diff --git a/deps/v8/test/webkit/dfg-phantom-get-local.js b/deps/v8/test/webkit/dfg-phantom-get-local.js index d813436d28..c29dcf6931 100644 --- a/deps/v8/test/webkit/dfg-phantom-get-local.js +++ b/deps/v8/test/webkit/dfg-phantom-get-local.js @@ -39,4 +39,3 @@ function foo(o) { for (var i = 0; i < 200; ++i) shouldBe("foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}})", "false"); - diff --git a/deps/v8/test/webkit/dfg-proto-access-inline-osr-exit.js b/deps/v8/test/webkit/dfg-proto-access-inline-osr-exit.js index 35299806da..19cd657819 100644 --- a/deps/v8/test/webkit/dfg-proto-access-inline-osr-exit.js +++ b/deps/v8/test/webkit/dfg-proto-access-inline-osr-exit.js @@ -41,4 +41,3 @@ for (var i = 0; i < 200; ++i) { myProto.g = 67; shouldBe("foo({g:new Thingy()})", "42"); } - diff --git a/deps/v8/test/webkit/dfg-proven-sqrt-backwards-propagation.js b/deps/v8/test/webkit/dfg-proven-sqrt-backwards-propagation.js index 5bc66d945d..bc2eef16b7 100644 --- a/deps/v8/test/webkit/dfg-proven-sqrt-backwards-propagation.js +++ b/deps/v8/test/webkit/dfg-proven-sqrt-backwards-propagation.js @@ -47,4 +47,3 @@ for (var i = 0; i < 200; ++i) { } shouldBe("foo(array, 0)", expected); } - diff --git a/deps/v8/test/webkit/dfg-put-by-id-allocate-storage-polymorphic.js b/deps/v8/test/webkit/dfg-put-by-id-allocate-storage-polymorphic.js index 5a8e2c05a0..710acb7b41 100644 --- a/deps/v8/test/webkit/dfg-put-by-id-allocate-storage-polymorphic.js +++ b/deps/v8/test/webkit/dfg-put-by-id-allocate-storage-polymorphic.js @@ -54,5 +54,3 @@ for (var i = 0; i < 150; ++i) { else shouldBe("o.foo", "void 0"); } - - diff --git a/deps/v8/test/webkit/dfg-put-by-id-allocate-storage.js b/deps/v8/test/webkit/dfg-put-by-id-allocate-storage.js index 4bd9d45363..e803f935f7 100644 --- a/deps/v8/test/webkit/dfg-put-by-id-allocate-storage.js +++ b/deps/v8/test/webkit/dfg-put-by-id-allocate-storage.js @@ -47,5 +47,3 @@ for (var i = 0; i < 150; ++i) { shouldBe("o.f", "6"); shouldBe("o.g", "7"); } - - diff --git a/deps/v8/test/webkit/dfg-put-by-id-prototype-check.js b/deps/v8/test/webkit/dfg-put-by-id-prototype-check.js index a8b61374ef..035bcb0f21 100644 --- a/deps/v8/test/webkit/dfg-put-by-id-prototype-check.js +++ b/deps/v8/test/webkit/dfg-put-by-id-prototype-check.js @@ -49,4 +49,3 @@ for (var i = 0; i < 1000; ++i) { } else shouldBe("o.f", "" + i); } - diff --git a/deps/v8/test/webkit/dfg-put-by-id-reallocate-storage-polymorphic.js b/deps/v8/test/webkit/dfg-put-by-id-reallocate-storage-polymorphic.js index c3fe0fd1e3..5498bb4601 100644 --- a/deps/v8/test/webkit/dfg-put-by-id-reallocate-storage-polymorphic.js +++ b/deps/v8/test/webkit/dfg-put-by-id-reallocate-storage-polymorphic.js @@ -68,5 +68,3 @@ for (var i = 0; i < 150; ++i) { else shouldBe("o.foo", "void 0"); } - - diff --git a/deps/v8/test/webkit/dfg-put-by-id-reallocate-storage.js b/deps/v8/test/webkit/dfg-put-by-id-reallocate-storage.js index e6c19eeeff..50948a2e47 100644 --- a/deps/v8/test/webkit/dfg-put-by-id-reallocate-storage.js +++ b/deps/v8/test/webkit/dfg-put-by-id-reallocate-storage.js @@ -61,5 +61,3 @@ for (var i = 0; i < 150; ++i) { shouldBe("o.m", "13"); shouldBe("o.n", "14"); } - - diff --git a/deps/v8/test/webkit/dfg-put-by-val-setter-then-get-by-val.js b/deps/v8/test/webkit/dfg-put-by-val-setter-then-get-by-val.js index 40d79e03aa..930fbe5cca 100644 --- a/deps/v8/test/webkit/dfg-put-by-val-setter-then-get-by-val.js +++ b/deps/v8/test/webkit/dfg-put-by-val-setter-then-get-by-val.js @@ -43,4 +43,3 @@ for (var i = 0; i < 200; ++i) { shouldBe("foo(array, -1, i)", "42"); shouldBe("thingy", "" + i); } - diff --git a/deps/v8/test/webkit/dfg-put-scoped-var-backward-flow.js b/deps/v8/test/webkit/dfg-put-scoped-var-backward-flow.js index 9f3bfd36b9..32df63b01c 100644 --- a/deps/v8/test/webkit/dfg-put-scoped-var-backward-flow.js +++ b/deps/v8/test/webkit/dfg-put-scoped-var-backward-flow.js @@ -35,4 +35,3 @@ function sum(nums) { for (var i = 0; i < 200; ++i) shouldBe("sum([2147483646, 2147483644])", "4294967290"); - diff --git a/deps/v8/test/webkit/dfg-sqrt-backwards-propagation.js b/deps/v8/test/webkit/dfg-sqrt-backwards-propagation.js index 9954e3a5bf..aec4b4bb67 100644 --- a/deps/v8/test/webkit/dfg-sqrt-backwards-propagation.js +++ b/deps/v8/test/webkit/dfg-sqrt-backwards-propagation.js @@ -46,4 +46,3 @@ for (var i = 0; i < 200; ++i) { } shouldBe("foo(" + f + ", " + array + ", 0)", expected); } - diff --git a/deps/v8/test/webkit/dfg-store-unexpected-value-into-argument-and-osr-exit.js b/deps/v8/test/webkit/dfg-store-unexpected-value-into-argument-and-osr-exit.js index 1006c2840a..77a02c326a 100644 --- a/deps/v8/test/webkit/dfg-store-unexpected-value-into-argument-and-osr-exit.js +++ b/deps/v8/test/webkit/dfg-store-unexpected-value-into-argument-and-osr-exit.js @@ -61,4 +61,3 @@ for (var i = 0; i < 200; ++i) { } shouldBe("foo(3, {f:f, g:g}, p)", "" + expected); } - diff --git a/deps/v8/test/webkit/dfg-string-stricteq.js b/deps/v8/test/webkit/dfg-string-stricteq.js index 27a809a850..510709ad27 100644 --- a/deps/v8/test/webkit/dfg-string-stricteq.js +++ b/deps/v8/test/webkit/dfg-string-stricteq.js @@ -49,4 +49,3 @@ for (var i = 0; i < 1000; ++i) { shouldBe("foo({f:\"" + a + "\"}, {f:\"" + b + "\"})", "[" + (a.length + b.length) + ", " + areEqual + "]"); shouldBe("bar({f:\"" + a + "\"}, {f:\"" + b + "\"})", "" + (areEqual ? a.length + b.length + 1 : a.length + b.length - 1)); } - diff --git a/deps/v8/test/webkit/dfg-tear-off-arguments-not-activation.js b/deps/v8/test/webkit/dfg-tear-off-arguments-not-activation.js index d3967ccfd0..e18a086a20 100644 --- a/deps/v8/test/webkit/dfg-tear-off-arguments-not-activation.js +++ b/deps/v8/test/webkit/dfg-tear-off-arguments-not-activation.js @@ -42,4 +42,3 @@ for (var i = 0; i < 200; ++i) { shouldBe("thingy.length", "1"); shouldBe("thingy[0]", "false"); } - diff --git a/deps/v8/test/webkit/dfg-tear-off-function-dot-arguments.js b/deps/v8/test/webkit/dfg-tear-off-function-dot-arguments.js index a8582bf335..cdbf4bde6e 100644 --- a/deps/v8/test/webkit/dfg-tear-off-function-dot-arguments.js +++ b/deps/v8/test/webkit/dfg-tear-off-function-dot-arguments.js @@ -42,4 +42,3 @@ for (var i = 0; i < 200; ++i) { shouldBe("thingy.length", "1"); shouldBe("thingy[0]", "false"); } - diff --git a/deps/v8/test/webkit/dfg-to-string-on-cell.js b/deps/v8/test/webkit/dfg-to-string-on-cell.js index 8ae7388c5f..75af16d723 100644 --- a/deps/v8/test/webkit/dfg-to-string-on-cell.js +++ b/deps/v8/test/webkit/dfg-to-string-on-cell.js @@ -29,4 +29,3 @@ function foo(a, o) { for (var i = 0; i < 100; ++i) shouldBe("\"\" + foo(\"foo\", i % 2 ? \"hello\" : [1, 2, 3])", i % 2 ? "\"foo,hello\"" : "\"foo,1,2,3\""); - diff --git a/deps/v8/test/webkit/dfg-to-string-on-value.js b/deps/v8/test/webkit/dfg-to-string-on-value.js index 0c89f3b89c..a10767bff2 100644 --- a/deps/v8/test/webkit/dfg-to-string-on-value.js +++ b/deps/v8/test/webkit/dfg-to-string-on-value.js @@ -29,4 +29,3 @@ function foo(a, o) { for (var i = 0; i < 100; ++i) shouldBe("\"\" + foo(\"foo\", i % 2 ? \"hello\" : 42)", i % 2 ? "\"foo,hello\"" : "\"foo,42\""); - diff --git a/deps/v8/test/webkit/dfg-to-string-toString-becomes-bad-with-check-structure.js b/deps/v8/test/webkit/dfg-to-string-toString-becomes-bad-with-check-structure.js index e37fa99b5a..254b5f24a8 100644 --- a/deps/v8/test/webkit/dfg-to-string-toString-becomes-bad-with-check-structure.js +++ b/deps/v8/test/webkit/dfg-to-string-toString-becomes-bad-with-check-structure.js @@ -34,4 +34,3 @@ for (var i = 0; i < 100; ++i) { String.prototype.toString = function() { return 42; } shouldBe("foo.call(new String(\"foo\"))", i >= 99 ? "\"42\"" : "\"foo\""); } - diff --git a/deps/v8/test/webkit/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype.js b/deps/v8/test/webkit/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype.js index 6db3467a49..faee44372f 100644 --- a/deps/v8/test/webkit/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype.js +++ b/deps/v8/test/webkit/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype.js @@ -46,4 +46,3 @@ for (var i = 0; i < 150; ++i) { } shouldBe("\"\" + foo(\"hello\")", expected); } - diff --git a/deps/v8/test/webkit/dfg-to-string-toString-becomes-bad.js b/deps/v8/test/webkit/dfg-to-string-toString-becomes-bad.js index d15917a17b..433475d844 100644 --- a/deps/v8/test/webkit/dfg-to-string-toString-becomes-bad.js +++ b/deps/v8/test/webkit/dfg-to-string-toString-becomes-bad.js @@ -39,4 +39,3 @@ for (var i = 0; i < 150; ++i) { } shouldBe("\"\" + foo(\"hello\")", expected); } - diff --git a/deps/v8/test/webkit/dfg-to-string-toString-in-string.js b/deps/v8/test/webkit/dfg-to-string-toString-in-string.js index 17f5794c25..f7f8099c55 100644 --- a/deps/v8/test/webkit/dfg-to-string-toString-in-string.js +++ b/deps/v8/test/webkit/dfg-to-string-toString-in-string.js @@ -41,4 +41,3 @@ for (var i = 0; i < 150; ++i) { } shouldBe("\"\" + foo(argument)", expected); } - diff --git a/deps/v8/test/webkit/dfg-to-string-valueOf-in-string.js b/deps/v8/test/webkit/dfg-to-string-valueOf-in-string.js index e591bf7fe7..e5c4c6be35 100644 --- a/deps/v8/test/webkit/dfg-to-string-valueOf-in-string.js +++ b/deps/v8/test/webkit/dfg-to-string-valueOf-in-string.js @@ -39,4 +39,3 @@ for (var i = 0; i < 150; ++i) { } shouldBe("\"\" + foo(argument)", "\"hello\""); } - diff --git a/deps/v8/test/webkit/dfg-uint32-to-number-in-middle-of-copy-propagation.js b/deps/v8/test/webkit/dfg-uint32-to-number-in-middle-of-copy-propagation.js index 7705f03df2..dc02237928 100644 --- a/deps/v8/test/webkit/dfg-uint32-to-number-in-middle-of-copy-propagation.js +++ b/deps/v8/test/webkit/dfg-uint32-to-number-in-middle-of-copy-propagation.js @@ -35,4 +35,3 @@ function foo(b) { for (var i = 0; i < 100; ++i) shouldBe("foo(-1)", "[-1, 4294967295]"); - diff --git a/deps/v8/test/webkit/dfg-uint32-to-number-on-captured-variable.js b/deps/v8/test/webkit/dfg-uint32-to-number-on-captured-variable.js index ec2be1d74b..123655453f 100644 --- a/deps/v8/test/webkit/dfg-uint32-to-number-on-captured-variable.js +++ b/deps/v8/test/webkit/dfg-uint32-to-number-on-captured-variable.js @@ -34,4 +34,3 @@ function foo(a) { for (var i = 0; i < 100; ++i) shouldBe("foo(" + i + ")()", "" + i); - diff --git a/deps/v8/test/webkit/dfg-uint32-to-number-skip-then-exit.js b/deps/v8/test/webkit/dfg-uint32-to-number-skip-then-exit.js index 13029d2f35..40d3a13697 100644 --- a/deps/v8/test/webkit/dfg-uint32-to-number-skip-then-exit.js +++ b/deps/v8/test/webkit/dfg-uint32-to-number-skip-then-exit.js @@ -42,4 +42,3 @@ for (var i = 0; i < 200; ++i) { } shouldBe("foo(i, 1, o)", "" + expected); } - diff --git a/deps/v8/test/webkit/dfg-uint32-to-number.js b/deps/v8/test/webkit/dfg-uint32-to-number.js index f7c11d1e23..7fc98da8c3 100644 --- a/deps/v8/test/webkit/dfg-uint32-to-number.js +++ b/deps/v8/test/webkit/dfg-uint32-to-number.js @@ -39,4 +39,3 @@ shouldBe("result", "124500"); shouldBe("foo({f:2147483648}, {f:32})", "2147483648"); shouldBe("foo({f:2147483648}, {f:31})", "1"); shouldBe("foo({f:2147483648}, {f:30})", "2"); - diff --git a/deps/v8/test/webkit/dfg-uint32array-overflow-constant.js b/deps/v8/test/webkit/dfg-uint32array-overflow-constant.js index 1de13a3b5d..6d7f06ae58 100644 --- a/deps/v8/test/webkit/dfg-uint32array-overflow-constant.js +++ b/deps/v8/test/webkit/dfg-uint32array-overflow-constant.js @@ -35,4 +35,3 @@ for (var i = 0; i < 200; ++i) { foo(array); shouldBe("array[0]", "0x8005465c"); } - diff --git a/deps/v8/test/webkit/dfg-weak-js-constant-silent-fill.js b/deps/v8/test/webkit/dfg-weak-js-constant-silent-fill.js index fa06a905bc..84f3f4bcb1 100644 --- a/deps/v8/test/webkit/dfg-weak-js-constant-silent-fill.js +++ b/deps/v8/test/webkit/dfg-weak-js-constant-silent-fill.js @@ -45,4 +45,3 @@ for (var i = 0; i < 1000; ++i) { shouldBe("o2.f", "false"); shouldBe("o3.f", "false"); } - diff --git a/deps/v8/test/webkit/exception-for-nonobject-expected.txt b/deps/v8/test/webkit/exception-for-nonobject-expected.txt index 86068b102c..e6003986b9 100644 --- a/deps/v8/test/webkit/exception-for-nonobject-expected.txt +++ b/deps/v8/test/webkit/exception-for-nonobject-expected.txt @@ -27,7 +27,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE PASS new {}.undefined threw exception TypeError: undefined is not a function. -PASS 1 instanceof {}.undefined threw exception TypeError: Expecting a function in instanceof check, but got 1. +PASS 1 instanceof {}.undefined threw exception TypeError: Expecting a function in instanceof check, but got undefined. PASS successfullyParsed is true TEST COMPLETE diff --git a/deps/v8/test/webkit/fast/js/JSON-parse-reviver.js b/deps/v8/test/webkit/fast/js/JSON-parse-reviver.js index b02a2fc468..1f04602ee9 100644 --- a/deps/v8/test/webkit/fast/js/JSON-parse-reviver.js +++ b/deps/v8/test/webkit/fast/js/JSON-parse-reviver.js @@ -201,5 +201,3 @@ function reviveIntroducesNewArrayLikeObject(i, v) { } shouldBe('JSON.stringify(JSON.parse("[0,1]", reviveIntroducesNewArrayLikeObject))', '\'[0,["a","a"]]\''); - - diff --git a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt index 70827fc0af..b8c4bec106 100644 --- a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt +++ b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt @@ -63,17 +63,17 @@ FAIL getSortedOwnPropertyNames(decodeURI) should be length,name. Was arguments,c FAIL getSortedOwnPropertyNames(decodeURIComponent) should be length,name. Was arguments,caller,length,name. FAIL getSortedOwnPropertyNames(encodeURI) should be length,name. Was arguments,caller,length,name. FAIL getSortedOwnPropertyNames(encodeURIComponent) should be length,name. Was arguments,caller,length,name. -FAIL getSortedOwnPropertyNames(Object) should be create,defineProperties,defineProperty,freeze,getOwnPropertyDescriptor,getOwnPropertyNames,getPrototypeOf,isExtensible,isFrozen,isSealed,keys,length,name,preventExtensions,prototype,seal. Was arguments,caller,create,defineProperties,defineProperty,freeze,getOwnPropertyDescriptor,getOwnPropertyNames,getPrototypeOf,is,isExtensible,isFrozen,isSealed,keys,length,name,preventExtensions,prototype,seal. +FAIL getSortedOwnPropertyNames(Object) should be create,defineProperties,defineProperty,freeze,getOwnPropertyDescriptor,getOwnPropertyNames,getPrototypeOf,isExtensible,isFrozen,isSealed,keys,length,name,preventExtensions,prototype,seal,setPrototypeOf. Was arguments,caller,create,defineProperties,defineProperty,freeze,getOwnPropertyDescriptor,getOwnPropertyNames,getPrototypeOf,is,isExtensible,isFrozen,isSealed,keys,length,name,preventExtensions,prototype,seal,setPrototypeOf. PASS getSortedOwnPropertyNames(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf'] FAIL getSortedOwnPropertyNames(Function) should be length,name,prototype. Was arguments,caller,length,name,prototype. FAIL getSortedOwnPropertyNames(Function.prototype) should be apply,bind,call,constructor,length,name,toString. Was apply,arguments,bind,call,caller,constructor,length,name,toString. FAIL getSortedOwnPropertyNames(Array) should be isArray,length,name,prototype. Was arguments,caller,isArray,length,name,prototype. PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'every', 'filter', 'forEach', 'indexOf', 'join', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift'] FAIL getSortedOwnPropertyNames(String) should be fromCharCode,length,name,prototype. Was arguments,caller,fromCharCode,length,name,prototype. -PASS getSortedOwnPropertyNames(String.prototype) is ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'replace', 'search', 'slice', 'small', 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf'] +PASS getSortedOwnPropertyNames(String.prototype) is ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'replace', 'search', 'slice', 'small', 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf'] FAIL getSortedOwnPropertyNames(Boolean) should be length,name,prototype. Was arguments,caller,length,name,prototype. PASS getSortedOwnPropertyNames(Boolean.prototype) is ['constructor', 'toString', 'valueOf'] -FAIL getSortedOwnPropertyNames(Number) should be MAX_VALUE,MIN_VALUE,NEGATIVE_INFINITY,NaN,POSITIVE_INFINITY,length,name,prototype. Was MAX_VALUE,MIN_VALUE,NEGATIVE_INFINITY,NaN,POSITIVE_INFINITY,arguments,caller,isFinite,isNaN,length,name,prototype. +FAIL getSortedOwnPropertyNames(Number) should be MAX_VALUE,MIN_VALUE,NEGATIVE_INFINITY,NaN,POSITIVE_INFINITY,length,name,prototype. Was EPSILON,MAX_SAFE_INTEGER,MAX_VALUE,MIN_SAFE_INTEGER,MIN_VALUE,NEGATIVE_INFINITY,NaN,POSITIVE_INFINITY,arguments,caller,isFinite,isInteger,isNaN,isSafeInteger,length,name,parseFloat,parseInt,prototype. PASS getSortedOwnPropertyNames(Number.prototype) is ['constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf'] FAIL getSortedOwnPropertyNames(Date) should be UTC,length,name,now,parse,prototype. Was UTC,arguments,caller,length,name,now,parse,prototype. PASS getSortedOwnPropertyNames(Date.prototype) is ['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf'] diff --git a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js index 4f3334a48e..6373cf1ae0 100644 --- a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js +++ b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js @@ -71,14 +71,14 @@ var expectedPropertyNamesSet = { "encodeURI": "['length', 'name']", "encodeURIComponent": "['length', 'name']", // Built-in ECMA objects - "Object": "['create', 'defineProperties', 'defineProperty', 'freeze', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getPrototypeOf', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'preventExtensions', 'prototype', 'seal']", + "Object": "['create', 'defineProperties', 'defineProperty', 'freeze', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getPrototypeOf', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf']", "Object.prototype": "['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']", "Function": "['length', 'name', 'prototype']", "Function.prototype": "['apply', 'bind', 'call', 'constructor', 'length', 'name', 'toString']", "Array": "['isArray', 'length', 'name', 'prototype']", "Array.prototype": "['concat', 'constructor', 'every', 'filter', 'forEach', 'indexOf', 'join', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']", "String": "['fromCharCode', 'length', 'name', 'prototype']", - "String.prototype": "['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'replace', 'search', 'slice', 'small', 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']", + "String.prototype": "['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'replace', 'search', 'slice', 'small', 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']", "Boolean": "['length', 'name', 'prototype']", "Boolean.prototype": "['constructor', 'toString', 'valueOf']", "Number": "['MAX_VALUE', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'length', 'name', 'prototype']", diff --git a/deps/v8/test/webkit/fast/js/array-bad-time-expected.txt b/deps/v8/test/webkit/fast/js/array-bad-time-expected.txt index 7668e7e333..478c9a8945 100644 --- a/deps/v8/test/webkit/fast/js/array-bad-time-expected.txt +++ b/deps/v8/test/webkit/fast/js/array-bad-time-expected.txt @@ -977,58 +977,57 @@ PASS "0,1,2,3,4" is "0,1,2,3,4" PASS "0,1,2,3,4" is "0,1,2,3,4" PASS "0,1,2,3,4" is "0,1,2,3,4" Henceforth I will have a bad time. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL ouches should be 50. Was 0. +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS ouches is 50 PASS successfullyParsed is true TEST COMPLETE - diff --git a/deps/v8/test/webkit/fast/js/array-bad-time.js b/deps/v8/test/webkit/fast/js/array-bad-time.js index 1d3802eda3..26241b229e 100644 --- a/deps/v8/test/webkit/fast/js/array-bad-time.js +++ b/deps/v8/test/webkit/fast/js/array-bad-time.js @@ -33,7 +33,7 @@ function foo(haveABadTime) { for (var i = 0; i < result.length; ++i) { if (i == haveABadTime) { debug("Henceforth I will have a bad time."); - Array.prototype.__defineSetter__("3", function() { debug("Ouch!"); ouches++; }); + Array.prototype.__defineSetter__("3", function() { ouches++; }); } result[i] = i; } diff --git a/deps/v8/test/webkit/fast/js/array-prototype-properties-expected.txt b/deps/v8/test/webkit/fast/js/array-prototype-properties-expected.txt index 6ab72a450e..9e98e2608b 100644 --- a/deps/v8/test/webkit/fast/js/array-prototype-properties-expected.txt +++ b/deps/v8/test/webkit/fast/js/array-prototype-properties-expected.txt @@ -42,7 +42,7 @@ PASS Array.prototype.every.call(undefined, toString) threw exception TypeError: PASS Array.prototype.forEach.call(undefined, toString) threw exception TypeError: Array.prototype.forEach called on null or undefined. PASS Array.prototype.some.call(undefined, toString) threw exception TypeError: Array.prototype.some called on null or undefined. PASS Array.prototype.indexOf.call(undefined, 0) threw exception TypeError: Array.prototype.indexOf called on null or undefined. -PASS Array.prototype.indlastIndexOfexOf.call(undefined, 0) threw exception TypeError: Cannot call method 'call' of undefined. +PASS Array.prototype.indlastIndexOfexOf.call(undefined, 0) threw exception TypeError: Cannot read property 'call' of undefined. PASS Array.prototype.filter.call(undefined, toString) threw exception TypeError: Array.prototype.filter called on null or undefined. PASS Array.prototype.reduce.call(undefined, toString) threw exception TypeError: Array.prototype.reduce called on null or undefined. PASS Array.prototype.reduceRight.call(undefined, toString) threw exception TypeError: Array.prototype.reduceRight called on null or undefined. diff --git a/deps/v8/test/webkit/fast/js/array-slow-put-expected.txt b/deps/v8/test/webkit/fast/js/array-slow-put-expected.txt index 474846255d..99b44c337a 100644 --- a/deps/v8/test/webkit/fast/js/array-slow-put-expected.txt +++ b/deps/v8/test/webkit/fast/js/array-slow-put-expected.txt @@ -26,108 +26,107 @@ Tests that defining a setter on the Array prototype works. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL ouches should be 100. Was 0. +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS ouches is 100 PASS successfullyParsed is true TEST COMPLETE - diff --git a/deps/v8/test/webkit/fast/js/array-slow-put.js b/deps/v8/test/webkit/fast/js/array-slow-put.js index 1e8c44d4ed..63bcad09d9 100644 --- a/deps/v8/test/webkit/fast/js/array-slow-put.js +++ b/deps/v8/test/webkit/fast/js/array-slow-put.js @@ -26,7 +26,7 @@ description( ); var ouches = 0; -Array.prototype.__defineSetter__("3", function() { debug("Ouch!"); ouches++; }); +Array.prototype.__defineSetter__("3", function() { ouches++; }); function foo() { var result = []; diff --git a/deps/v8/test/webkit/fast/js/basic-strict-mode-expected.txt b/deps/v8/test/webkit/fast/js/basic-strict-mode-expected.txt index f743f6d352..07ecf99ce3 100644 --- a/deps/v8/test/webkit/fast/js/basic-strict-mode-expected.txt +++ b/deps/v8/test/webkit/fast/js/basic-strict-mode-expected.txt @@ -53,22 +53,22 @@ PASS testThis.call() is undefined PASS testThis.apply() is undefined PASS testThis.call(undefined) is undefined PASS testThis.apply(undefined) is undefined -PASS (function eval(){'use strict';}) threw exception SyntaxError: Function name may not be eval or arguments in strict mode. -PASS (function(){(function eval(){'use strict';})}) threw exception SyntaxError: Function name may not be eval or arguments in strict mode. -PASS (function (eval){'use strict';}) threw exception SyntaxError: Parameter name eval or arguments is not allowed in strict mode. -PASS (function(){(function (eval){'use strict';})}) threw exception SyntaxError: Parameter name eval or arguments is not allowed in strict mode. -PASS (function arguments(){'use strict';}) threw exception SyntaxError: Function name may not be eval or arguments in strict mode. -PASS (function(){(function arguments(){'use strict';})}) threw exception SyntaxError: Function name may not be eval or arguments in strict mode. -PASS (function (arguments){'use strict';}) threw exception SyntaxError: Parameter name eval or arguments is not allowed in strict mode. -PASS (function(){(function (arguments){'use strict';})}) threw exception SyntaxError: Parameter name eval or arguments is not allowed in strict mode. -PASS (function (){'use strict'; var eval;}) threw exception SyntaxError: Variable name may not be eval or arguments in strict mode. -PASS (function(){(function (){'use strict'; var eval;})}) threw exception SyntaxError: Variable name may not be eval or arguments in strict mode. -PASS (function (){'use strict'; var arguments;}) threw exception SyntaxError: Variable name may not be eval or arguments in strict mode. -PASS (function(){(function (){'use strict'; var arguments;})}) threw exception SyntaxError: Variable name may not be eval or arguments in strict mode. -PASS (function (){'use strict'; try{}catch(eval){}}) threw exception SyntaxError: Catch variable may not be eval or arguments in strict mode. -PASS (function(){(function (){'use strict'; try{}catch(eval){}})}) threw exception SyntaxError: Catch variable may not be eval or arguments in strict mode. -PASS (function (){'use strict'; try{}catch(arguments){}}) threw exception SyntaxError: Catch variable may not be eval or arguments in strict mode. -PASS (function(){(function (){'use strict'; try{}catch(arguments){}})}) threw exception SyntaxError: Catch variable may not be eval or arguments in strict mode. +PASS (function eval(){'use strict';}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){(function eval(){'use strict';})}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function (eval){'use strict';}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){(function (eval){'use strict';})}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function arguments(){'use strict';}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){(function arguments(){'use strict';})}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function (arguments){'use strict';}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){(function (arguments){'use strict';})}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function (){'use strict'; var eval;}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){(function (){'use strict'; var eval;})}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function (){'use strict'; var arguments;}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){(function (){'use strict'; var arguments;})}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function (){'use strict'; try{}catch(eval){}}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){(function (){'use strict'; try{}catch(eval){}})}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function (){'use strict'; try{}catch(arguments){}}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){(function (){'use strict'; try{}catch(arguments){}})}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. PASS (function (a, a){'use strict';}) threw exception SyntaxError: Strict mode function may not have duplicate parameter names. PASS (function(){(function (a, a){'use strict';})}) threw exception SyntaxError: Strict mode function may not have duplicate parameter names. PASS (function (a){'use strict'; delete a;})() threw exception SyntaxError: Delete of an unqualified identifier in strict mode.. @@ -134,23 +134,23 @@ PASS 'use strict'; eval('var introducedVariable = "FAIL: variable introduced int PASS 'use strict'; objectWithReadonlyProperty.prop = 'fail' threw exception TypeError: Cannot assign to read only property 'prop' of #<Object>. PASS 'use strict'; delete objectWithReadonlyProperty.prop threw exception TypeError: Cannot delete property 'prop' of #<Object>. PASS 'use strict'; delete objectWithReadonlyProperty[readonlyPropName] threw exception TypeError: Cannot delete property 'prop' of #<Object>. -PASS 'use strict'; ++eval threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS (function(){'use strict'; ++eval}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS 'use strict'; eval++ threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS (function(){'use strict'; eval++}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS 'use strict'; --eval threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS (function(){'use strict'; --eval}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS 'use strict'; eval-- threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS (function(){'use strict'; eval--}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS 'use strict'; function f() { ++arguments } threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS (function(){'use strict'; function f() { ++arguments }}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS 'use strict'; function f() { arguments++ } threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS (function(){'use strict'; function f() { arguments++ }}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS 'use strict'; function f() { --arguments } threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS (function(){'use strict'; function f() { --arguments }}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS 'use strict'; function f() { arguments-- } threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS (function(){'use strict'; function f() { arguments-- }}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. -PASS global.eval('"use strict"; if (0) ++arguments; true;') threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode. +PASS 'use strict'; ++eval threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict'; ++eval}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS 'use strict'; eval++ threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict'; eval++}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS 'use strict'; --eval threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict'; --eval}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS 'use strict'; eval-- threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict'; eval--}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS 'use strict'; function f() { ++arguments } threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict'; function f() { ++arguments }}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS 'use strict'; function f() { arguments++ } threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict'; function f() { arguments++ }}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS 'use strict'; function f() { --arguments } threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict'; function f() { --arguments }}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS 'use strict'; function f() { arguments-- } threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict'; function f() { arguments-- }}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS global.eval('"use strict"; if (0) ++arguments; true;') threw exception SyntaxError: Unexpected eval or arguments in strict mode. PASS 'use strict'; ++(1, eval) threw exception ReferenceError: Invalid left-hand side expression in prefix operation. FAIL (function(){'use strict'; ++(1, eval)}) should throw an exception. Was function (){'use strict'; ++(1, eval)}. PASS 'use strict'; (1, eval)++ threw exception ReferenceError: Invalid left-hand side expression in postfix operation. @@ -212,16 +212,16 @@ PASS 'use strict';̻ threw exception SyntaxError: Unexpected token ILLEGAL. PASS (function(){'use strict';̻}) threw exception SyntaxError: Unexpected token ILLEGAL. PASS 'use strict';5.f threw exception SyntaxError: Unexpected token ILLEGAL. PASS (function(){'use strict';5.f}) threw exception SyntaxError: Unexpected token ILLEGAL. -PASS 'use strict';1-(eval=1); threw exception SyntaxError: Assignment to eval or arguments is not allowed in strict mode. -PASS (function(){'use strict';1-(eval=1);}) threw exception SyntaxError: Assignment to eval or arguments is not allowed in strict mode. -PASS 'use strict';arguments=1; threw exception SyntaxError: Assignment to eval or arguments is not allowed in strict mode. -PASS (function(){'use strict';arguments=1;}) threw exception SyntaxError: Assignment to eval or arguments is not allowed in strict mode. -PASS 'use strict';1-(arguments=1); threw exception SyntaxError: Assignment to eval or arguments is not allowed in strict mode. -PASS (function(){'use strict';1-(arguments=1);}) threw exception SyntaxError: Assignment to eval or arguments is not allowed in strict mode. -PASS 'use strict';var a=(eval=1); threw exception SyntaxError: Assignment to eval or arguments is not allowed in strict mode. -PASS (function(){'use strict';var a=(eval=1);}) threw exception SyntaxError: Assignment to eval or arguments is not allowed in strict mode. -PASS 'use strict';var a=(arguments=1); threw exception SyntaxError: Assignment to eval or arguments is not allowed in strict mode. -PASS (function(){'use strict';var a=(arguments=1);}) threw exception SyntaxError: Assignment to eval or arguments is not allowed in strict mode. +PASS 'use strict';1-(eval=1); threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict';1-(eval=1);}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS 'use strict';arguments=1; threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict';arguments=1;}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS 'use strict';1-(arguments=1); threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict';1-(arguments=1);}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS 'use strict';var a=(eval=1); threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict';var a=(eval=1);}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS 'use strict';var a=(arguments=1); threw exception SyntaxError: Unexpected eval or arguments in strict mode. +PASS (function(){'use strict';var a=(arguments=1);}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. PASS 'use strict'; try { throw 1; } catch (e) { aGlobal = true; } is true PASS 'use strict'; (function () { try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal; is true PASS (function () {'use strict'; try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal; is true diff --git a/deps/v8/test/webkit/fast/js/date-toisostring-expected.txt b/deps/v8/test/webkit/fast/js/date-toisostring-expected.txt index 865090aa14..26517264ae 100644 --- a/deps/v8/test/webkit/fast/js/date-toisostring-expected.txt +++ b/deps/v8/test/webkit/fast/js/date-toisostring-expected.txt @@ -26,8 +26,8 @@ Tests for Date.toISOString On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS Date.toISOString.call({}) threw exception TypeError: Cannot call method 'call' of undefined. -PASS Date.toISOString.call(0) threw exception TypeError: Cannot call method 'call' of undefined. +PASS Date.toISOString.call({}) threw exception TypeError: Cannot read property 'call' of undefined. +PASS Date.toISOString.call(0) threw exception TypeError: Cannot read property 'call' of undefined. PASS new Date(-400).toISOString() is '1969-12-31T23:59:59.600Z' PASS new Date(0).toISOString() is '1970-01-01T00:00:00.000Z' PASS new Date('1 January 1500 UTC').toISOString() is '1500-01-01T00:00:00.000Z' diff --git a/deps/v8/test/webkit/fast/js/deep-recursion-test.js b/deps/v8/test/webkit/fast/js/deep-recursion-test.js index 59df2f1c9a..c2a695da46 100644 --- a/deps/v8/test/webkit/fast/js/deep-recursion-test.js +++ b/deps/v8/test/webkit/fast/js/deep-recursion-test.js @@ -75,4 +75,4 @@ description("This test how deep we can recurse, and that we get an exception whe } catch (ex) { var msg = String(eval(ex)); shouldBe("msg", "'RangeError: Maximum call stack size exceeded.'"); - }
\ No newline at end of file + } diff --git a/deps/v8/test/webkit/fast/js/function-decompilation-operators.js b/deps/v8/test/webkit/fast/js/function-decompilation-operators.js index 759767f88e..cab6dfaf96 100644 --- a/deps/v8/test/webkit/fast/js/function-decompilation-operators.js +++ b/deps/v8/test/webkit/fast/js/function-decompilation-operators.js @@ -80,4 +80,4 @@ description("This test checks toString() round-trip decompilation for binary and for (test in tests) { var decompiledFunction = eval("(function () { " + tests[test] + ";})").toString().replace(/\n/g, ""); shouldBe("decompiledFunction", "'function () { " + tests[test] + ";}'"); - }
\ No newline at end of file + } diff --git a/deps/v8/test/webkit/fast/js/kde/Array.js b/deps/v8/test/webkit/fast/js/kde/Array.js index 26bf331588..595c3b3543 100644 --- a/deps/v8/test/webkit/fast/js/kde/Array.js +++ b/deps/v8/test/webkit/fast/js/kde/Array.js @@ -233,4 +233,4 @@ function testToString() { Number.prototype.toLocaleString = backupNumberToLocaleString; RegExp.prototype.toString = backupRegExpToString; RegExp.prototype.toLocaleString = backupRegExpToLocaleString; -}
\ No newline at end of file +} diff --git a/deps/v8/test/webkit/fast/js/kde/Boolean.js b/deps/v8/test/webkit/fast/js/kde/Boolean.js index dbc117a726..6ddb953094 100644 --- a/deps/v8/test/webkit/fast/js/kde/Boolean.js +++ b/deps/v8/test/webkit/fast/js/kde/Boolean.js @@ -29,4 +29,4 @@ shouldBe("(new Boolean(true)).valueOf()", "true"); shouldBe("(new Boolean(false)).valueOf()", "false"); shouldBe("(new Boolean(Boolean(true))).valueOf()", "true"); shouldBeTrue("true.valueOf() === true"); -shouldBeTrue("false.toString() === 'false'");
\ No newline at end of file +shouldBeTrue("false.toString() === 'false'"); diff --git a/deps/v8/test/webkit/fast/js/kde/Date-setYear.js b/deps/v8/test/webkit/fast/js/kde/Date-setYear.js index 4ccf02517a..140403d2b1 100644 --- a/deps/v8/test/webkit/fast/js/kde/Date-setYear.js +++ b/deps/v8/test/webkit/fast/js/kde/Date-setYear.js @@ -33,4 +33,4 @@ shouldBe("d.setYear(100), d.getFullYear()", "100"); shouldBe("d.setYear(2050), d.getFullYear()", "2050"); shouldBe("d.setYear(1899), d.getFullYear()", "1899"); shouldBe("d.setYear(2000), d.getFullYear()", "2000"); -shouldBe("d.setYear(2100), d.getFullYear()", "2100");
\ No newline at end of file +shouldBe("d.setYear(2100), d.getFullYear()", "2100"); diff --git a/deps/v8/test/webkit/fast/js/kde/Error.js b/deps/v8/test/webkit/fast/js/kde/Error.js index 6ecd5c3c8f..0f1d911a12 100644 --- a/deps/v8/test/webkit/fast/js/kde/Error.js +++ b/deps/v8/test/webkit/fast/js/kde/Error.js @@ -32,4 +32,4 @@ shouldBe("(new Error('msg')).name", "'Error'"); shouldBe("Object.prototype.toString.apply(Error())", "'[object Error]'"); shouldBe("Object.prototype.toString.apply(Error)", "'[object Function]'"); -shouldBe("Object.prototype.toString.apply(EvalError)", "'[object Function]'");
\ No newline at end of file +shouldBe("Object.prototype.toString.apply(EvalError)", "'[object Function]'"); diff --git a/deps/v8/test/webkit/fast/js/kde/GlobalObject.js b/deps/v8/test/webkit/fast/js/kde/GlobalObject.js index 112aea8cfd..aa09cd2d37 100644 --- a/deps/v8/test/webkit/fast/js/kde/GlobalObject.js +++ b/deps/v8/test/webkit/fast/js/kde/GlobalObject.js @@ -96,4 +96,4 @@ shouldBe("parseFloat('3.1x', 3)", "3.1"); shouldBeFalse("isFinite(parseFloat('Infinity'))"); shouldBeFalse("delete NaN"); shouldBeFalse("delete Infinity"); -shouldBeFalse("delete undefined");
\ No newline at end of file +shouldBeFalse("delete undefined"); diff --git a/deps/v8/test/webkit/fast/js/kde/Number.js b/deps/v8/test/webkit/fast/js/kde/Number.js index 358fe7a09f..946c09367c 100644 --- a/deps/v8/test/webkit/fast/js/kde/Number.js +++ b/deps/v8/test/webkit/fast/js/kde/Number.js @@ -496,4 +496,4 @@ shouldBe("Number(0).toPrecision(17)","\"0.0000000000000000\""); shouldBe("Number(0).toPrecision(18)","\"0.00000000000000000\""); shouldBe("Number(0).toPrecision(19)","\"0.000000000000000000\""); shouldBe("Number(0).toPrecision(20)","\"0.0000000000000000000\""); -shouldBe("Number(0).toPrecision(21)","\"0.00000000000000000000\"");
\ No newline at end of file +shouldBe("Number(0).toPrecision(21)","\"0.00000000000000000000\""); diff --git a/deps/v8/test/webkit/fast/js/kde/Object.js b/deps/v8/test/webkit/fast/js/kde/Object.js index 2637309464..5138128eac 100644 --- a/deps/v8/test/webkit/fast/js/kde/Object.js +++ b/deps/v8/test/webkit/fast/js/kde/Object.js @@ -39,4 +39,4 @@ shouldBe("(new Object('s')).valueOf()", "'s'"); shouldBe("String(Object())", "'[object Object]'"); shouldBe("Object().toString()", "'[object Object]'"); -shouldBe("String(Object().valueOf())", "'[object Object]'");
\ No newline at end of file +shouldBe("String(Object().valueOf())", "'[object Object]'"); diff --git a/deps/v8/test/webkit/fast/js/kde/Prototype.js b/deps/v8/test/webkit/fast/js/kde/Prototype.js index a2971fde18..8e6638eb7d 100644 --- a/deps/v8/test/webkit/fast/js/kde/Prototype.js +++ b/deps/v8/test/webkit/fast/js/kde/Prototype.js @@ -55,4 +55,4 @@ shouldBe("b.author", "'Fred'"); // outpus "Fred" /////////////////////////////////////////////////////// -shouldBe("delete Boolean.prototype", "false");
\ No newline at end of file +shouldBe("delete Boolean.prototype", "false"); diff --git a/deps/v8/test/webkit/fast/js/kde/RegExp.js b/deps/v8/test/webkit/fast/js/kde/RegExp.js index eea6a8776e..ede84d0ecb 100644 --- a/deps/v8/test/webkit/fast/js/kde/RegExp.js +++ b/deps/v8/test/webkit/fast/js/kde/RegExp.js @@ -179,4 +179,4 @@ shouldBe("(new RegExp('(?:)')).source", "'(?:)'"); shouldBe("/(?:)/.toString()", "'/(?:)/'"); shouldBe("/(?:)/.source", "'(?:)'"); -debug("Done.");
\ No newline at end of file +debug("Done."); diff --git a/deps/v8/test/webkit/fast/js/kde/arguments-scope.js b/deps/v8/test/webkit/fast/js/kde/arguments-scope.js index cef3698b5e..b6977390ea 100644 --- a/deps/v8/test/webkit/fast/js/kde/arguments-scope.js +++ b/deps/v8/test/webkit/fast/js/kde/arguments-scope.js @@ -70,4 +70,4 @@ test0(); test1(); test2(42); test3(); -test4();
\ No newline at end of file +test4(); diff --git a/deps/v8/test/webkit/fast/js/kde/assignments.js b/deps/v8/test/webkit/fast/js/kde/assignments.js index 2cb49cf933..d654bb3dca 100644 --- a/deps/v8/test/webkit/fast/js/kde/assignments.js +++ b/deps/v8/test/webkit/fast/js/kde/assignments.js @@ -33,4 +33,4 @@ shouldBe("var i = 8; i >>= 1", "4"); shouldBe("var i = 1; i >>= 2", "0"); shouldBe("var i = -8; i >>= 24", "-1"); shouldBe("var i = 8; i >>>= 2", "2"); -shouldBe("var i = -8; i >>>= 24", "255");
\ No newline at end of file +shouldBe("var i = -8; i >>>= 24", "255"); diff --git a/deps/v8/test/webkit/fast/js/kde/cast.js b/deps/v8/test/webkit/fast/js/kde/cast.js index c8d3792a63..72d5e1c8b3 100644 --- a/deps/v8/test/webkit/fast/js/kde/cast.js +++ b/deps/v8/test/webkit/fast/js/kde/cast.js @@ -25,4 +25,4 @@ description("KDE JS Test"); shouldBeTrue("Boolean(1) === true"); shouldBeTrue("var s = String; s(1) === '1'"); shouldBeTrue("n = Number; n(true) === 1"); -shouldBe("String(Array('a', 'b' ))", "'a,b'");
\ No newline at end of file +shouldBe("String(Array('a', 'b' ))", "'a,b'"); diff --git a/deps/v8/test/webkit/fast/js/kde/comment-1.js b/deps/v8/test/webkit/fast/js/kde/comment-1.js index 043f052f47..391ab8ec81 100644 --- a/deps/v8/test/webkit/fast/js/kde/comment-1.js +++ b/deps/v8/test/webkit/fast/js/kde/comment-1.js @@ -22,4 +22,4 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. description("KDE JS Test"); -// comment with linebreak
\ No newline at end of file +// comment with linebreak diff --git a/deps/v8/test/webkit/fast/js/kde/comment-2.js b/deps/v8/test/webkit/fast/js/kde/comment-2.js index 043f052f47..391ab8ec81 100644 --- a/deps/v8/test/webkit/fast/js/kde/comment-2.js +++ b/deps/v8/test/webkit/fast/js/kde/comment-2.js @@ -22,4 +22,4 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. description("KDE JS Test"); -// comment with linebreak
\ No newline at end of file +// comment with linebreak diff --git a/deps/v8/test/webkit/fast/js/kde/completion.js b/deps/v8/test/webkit/fast/js/kde/completion.js index f75c98f401..f9f0209397 100644 --- a/deps/v8/test/webkit/fast/js/kde/completion.js +++ b/deps/v8/test/webkit/fast/js/kde/completion.js @@ -46,4 +46,4 @@ shouldBe("val", "13"); val = eval("14; function f() {}"); shouldBe("val", "14"); val = eval("15; var v = 0"); -shouldBe("val", "15");
\ No newline at end of file +shouldBe("val", "15"); diff --git a/deps/v8/test/webkit/fast/js/kde/conditional.js b/deps/v8/test/webkit/fast/js/kde/conditional.js index ee9c0bf867..beed2073c3 100644 --- a/deps/v8/test/webkit/fast/js/kde/conditional.js +++ b/deps/v8/test/webkit/fast/js/kde/conditional.js @@ -30,4 +30,4 @@ shouldBe("undefined ? 1 : 2", "2"); var a = 1; if ( undefined ) a = 2; -shouldBe("/*var a=1;if (undefined) a = 2;*/ a", "1");
\ No newline at end of file +shouldBe("/*var a=1;if (undefined) a = 2;*/ a", "1"); diff --git a/deps/v8/test/webkit/fast/js/kde/constructor_length.js b/deps/v8/test/webkit/fast/js/kde/constructor_length.js index 5ec9dda0ad..75ddd50543 100644 --- a/deps/v8/test/webkit/fast/js/kde/constructor_length.js +++ b/deps/v8/test/webkit/fast/js/kde/constructor_length.js @@ -36,4 +36,4 @@ shouldBe("RangeError.length","1"); shouldBe("ReferenceError.length","1"); shouldBe("SyntaxError.length","1"); shouldBe("TypeError.length","1"); -shouldBe("URIError.length","1");
\ No newline at end of file +shouldBe("URIError.length","1"); diff --git a/deps/v8/test/webkit/fast/js/kde/crash-1.js b/deps/v8/test/webkit/fast/js/kde/crash-1.js index 316ce51342..e0b082e80f 100644 --- a/deps/v8/test/webkit/fast/js/kde/crash-1.js +++ b/deps/v8/test/webkit/fast/js/kde/crash-1.js @@ -29,4 +29,4 @@ try { v.toString(); } catch (e) { debug("OK. Caught an exception."); -}
\ No newline at end of file +} diff --git a/deps/v8/test/webkit/fast/js/kde/crash-2.js b/deps/v8/test/webkit/fast/js/kde/crash-2.js index 84bd67f32b..feab15b1bf 100644 --- a/deps/v8/test/webkit/fast/js/kde/crash-2.js +++ b/deps/v8/test/webkit/fast/js/kde/crash-2.js @@ -31,4 +31,4 @@ try { foo(); } catch (e) { debug("OK. Caught an exception"); -}
\ No newline at end of file +} diff --git a/deps/v8/test/webkit/fast/js/kde/delete.js b/deps/v8/test/webkit/fast/js/kde/delete.js index 0acb308de4..8aeb0d09e8 100644 --- a/deps/v8/test/webkit/fast/js/kde/delete.js +++ b/deps/v8/test/webkit/fast/js/kde/delete.js @@ -24,4 +24,4 @@ description("KDE JS Test"); shouldBe("a = 1; delete a;", "true"); shouldBe("delete nonexistant;", "true"); -shouldBe("delete NaN", "false");
\ No newline at end of file +shouldBe("delete NaN", "false"); diff --git a/deps/v8/test/webkit/fast/js/kde/empty.js b/deps/v8/test/webkit/fast/js/kde/empty.js index f09008a591..6ab1596527 100644 --- a/deps/v8/test/webkit/fast/js/kde/empty.js +++ b/deps/v8/test/webkit/fast/js/kde/empty.js @@ -21,4 +21,4 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -description("KDE JS Test");
\ No newline at end of file +description("KDE JS Test"); diff --git a/deps/v8/test/webkit/fast/js/kde/encode_decode_uri.js b/deps/v8/test/webkit/fast/js/kde/encode_decode_uri.js index c58cc12bab..54f374ea93 100644 --- a/deps/v8/test/webkit/fast/js/kde/encode_decode_uri.js +++ b/deps/v8/test/webkit/fast/js/kde/encode_decode_uri.js @@ -99,4 +99,4 @@ function checkWithFunctions(encodeFunction, decodeFunction) } checkWithFunctions("encodeURI", "decodeURI"); -checkWithFunctions("encodeURIComponent", "decodeURIComponent");
\ No newline at end of file +checkWithFunctions("encodeURIComponent", "decodeURIComponent"); diff --git a/deps/v8/test/webkit/fast/js/kde/eval.js b/deps/v8/test/webkit/fast/js/kde/eval.js index 7c4b5d4b92..03d05e4498 100644 --- a/deps/v8/test/webkit/fast/js/kde/eval.js +++ b/deps/v8/test/webkit/fast/js/kde/eval.js @@ -53,4 +53,4 @@ function lotto() { for (var j = 0; j < 1; j++) return eval('j'); } -shouldBe("lotto()", "0");
\ No newline at end of file +shouldBe("lotto()", "0"); diff --git a/deps/v8/test/webkit/fast/js/kde/evil-n.js b/deps/v8/test/webkit/fast/js/kde/evil-n.js index b9b5cdb376..71c9dc5e9f 100644 --- a/deps/v8/test/webkit/fast/js/kde/evil-n.js +++ b/deps/v8/test/webkit/fast/js/kde/evil-n.js @@ -25,4 +25,4 @@ description("KDE JS Test"); shouldBe("(new Error()).message", "''"); // the empty match isn't taken in account -shouldBe("''.split(/.*/).length", "0");
\ No newline at end of file +shouldBe("''.split(/.*/).length", "0"); diff --git a/deps/v8/test/webkit/fast/js/kde/exception_propagation.js b/deps/v8/test/webkit/fast/js/kde/exception_propagation.js index 71be4f784e..9d6e753bc6 100644 --- a/deps/v8/test/webkit/fast/js/kde/exception_propagation.js +++ b/deps/v8/test/webkit/fast/js/kde/exception_propagation.js @@ -443,4 +443,4 @@ try { catch (e) { } shouldBe("set_inside_with_cantconverttoobject","4"); -// ### test case, sw
\ No newline at end of file +// ### test case, sw diff --git a/deps/v8/test/webkit/fast/js/kde/exceptions.js b/deps/v8/test/webkit/fast/js/kde/exceptions.js index f2c9872830..73b7b57fb4 100644 --- a/deps/v8/test/webkit/fast/js/kde/exceptions.js +++ b/deps/v8/test/webkit/fast/js/kde/exceptions.js @@ -124,4 +124,4 @@ testThrow2(); testReferenceError(); testFunctionError(); testMathFunctionError(); -testWhileAbortion();
\ No newline at end of file +testWhileAbortion(); diff --git a/deps/v8/test/webkit/fast/js/kde/func-decl.js b/deps/v8/test/webkit/fast/js/kde/func-decl.js index b046b22bc9..672aeca719 100644 --- a/deps/v8/test/webkit/fast/js/kde/func-decl.js +++ b/deps/v8/test/webkit/fast/js/kde/func-decl.js @@ -65,4 +65,4 @@ function test() { } } -test();
\ No newline at end of file +test(); diff --git a/deps/v8/test/webkit/fast/js/kde/inbuilt_function_proto-expected.txt b/deps/v8/test/webkit/fast/js/kde/inbuilt_function_proto-expected.txt index 99818c3cb5..8fc28af4b2 100644 --- a/deps/v8/test/webkit/fast/js/kde/inbuilt_function_proto-expected.txt +++ b/deps/v8/test/webkit/fast/js/kde/inbuilt_function_proto-expected.txt @@ -47,6 +47,7 @@ PASS String.prototype.charCodeAt.__proto__ is Function.prototype PASS String.prototype.indexOf.__proto__ is Function.prototype PASS String.prototype.lastIndexOf.__proto__ is Function.prototype PASS String.prototype.match.__proto__ is Function.prototype +PASS String.prototype.normalize.__proto__ is Function.prototype PASS String.prototype.replace.__proto__ is Function.prototype PASS String.prototype.search.__proto__ is Function.prototype PASS String.prototype.slice.__proto__ is Function.prototype diff --git a/deps/v8/test/webkit/fast/js/kde/inbuilt_function_proto.js b/deps/v8/test/webkit/fast/js/kde/inbuilt_function_proto.js index de13b70855..cd2657a3c5 100644 --- a/deps/v8/test/webkit/fast/js/kde/inbuilt_function_proto.js +++ b/deps/v8/test/webkit/fast/js/kde/inbuilt_function_proto.js @@ -43,6 +43,7 @@ shouldBe("String.prototype.charCodeAt.__proto__","Function.prototype"); shouldBe("String.prototype.indexOf.__proto__","Function.prototype"); shouldBe("String.prototype.lastIndexOf.__proto__","Function.prototype"); shouldBe("String.prototype.match.__proto__","Function.prototype"); +shouldBe("String.prototype.normalize.__proto__","Function.prototype"); shouldBe("String.prototype.replace.__proto__","Function.prototype"); shouldBe("String.prototype.search.__proto__","Function.prototype"); shouldBe("String.prototype.slice.__proto__","Function.prototype"); @@ -114,4 +115,4 @@ shouldBe("Date.prototype.toGMTString.__proto__","Function.prototype"); shouldBe("RegExp.prototype.exec.__proto__","Function.prototype"); shouldBe("RegExp.prototype.test.__proto__","Function.prototype"); shouldBe("RegExp.prototype.toString.__proto__","Function.prototype"); -shouldBe("Error.prototype.toString.__proto__","Function.prototype");
\ No newline at end of file +shouldBe("Error.prototype.toString.__proto__","Function.prototype"); diff --git a/deps/v8/test/webkit/fast/js/kde/iteration.js b/deps/v8/test/webkit/fast/js/kde/iteration.js index 7004be054b..3f76cc180d 100644 --- a/deps/v8/test/webkit/fast/js/kde/iteration.js +++ b/deps/v8/test/webkit/fast/js/kde/iteration.js @@ -76,4 +76,4 @@ list = ""; for (var a = [1,2,3], length = a.length, i = 0; i < length; i++) { list += a[i]; } -shouldBe("list", "'123'");
\ No newline at end of file +shouldBe("list", "'123'"); diff --git a/deps/v8/test/webkit/fast/js/kde/j-comment-3.js b/deps/v8/test/webkit/fast/js/kde/j-comment-3.js index 2cf0a0f5de..e20d83a001 100644 --- a/deps/v8/test/webkit/fast/js/kde/j-comment-3.js +++ b/deps/v8/test/webkit/fast/js/kde/j-comment-3.js @@ -22,4 +22,4 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. description("KDE JS Test"); -<!-- HTML comment (not ECMA)
\ No newline at end of file +<!-- HTML comment (not ECMA) diff --git a/deps/v8/test/webkit/fast/js/kde/j-comment-4.js b/deps/v8/test/webkit/fast/js/kde/j-comment-4.js index 4d23f3bc5b..314493f158 100644 --- a/deps/v8/test/webkit/fast/js/kde/j-comment-4.js +++ b/deps/v8/test/webkit/fast/js/kde/j-comment-4.js @@ -22,4 +22,4 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. description("KDE JS Test"); ---> end of HTML comment (not ECMA)
\ No newline at end of file +--> end of HTML comment (not ECMA) diff --git a/deps/v8/test/webkit/fast/js/kde/literals.js b/deps/v8/test/webkit/fast/js/kde/literals.js index 57cf8cd919..ca6f0544e6 100644 --- a/deps/v8/test/webkit/fast/js/kde/literals.js +++ b/deps/v8/test/webkit/fast/js/kde/literals.js @@ -35,4 +35,4 @@ shouldBe("0xFF", "255"); shouldBe("01", "1"); shouldBe("010", "8"); shouldBe("09", "9"); -shouldBe("019", "19");
\ No newline at end of file +shouldBe("019", "19"); diff --git a/deps/v8/test/webkit/fast/js/kde/lval-exceptions.js b/deps/v8/test/webkit/fast/js/kde/lval-exceptions.js index 32641f8d4d..14012b561d 100644 --- a/deps/v8/test/webkit/fast/js/kde/lval-exceptions.js +++ b/deps/v8/test/webkit/fast/js/kde/lval-exceptions.js @@ -71,4 +71,4 @@ function fnShouldNotThrow(f) } catch (e) { testFailed(f + " threw an exception " + e + " when no exception expected"); } -}
\ No newline at end of file +} diff --git a/deps/v8/test/webkit/fast/js/kde/math.js b/deps/v8/test/webkit/fast/js/kde/math.js index 3cbb1b285a..4f73809397 100644 --- a/deps/v8/test/webkit/fast/js/kde/math.js +++ b/deps/v8/test/webkit/fast/js/kde/math.js @@ -128,4 +128,4 @@ shouldBe("list","''"); Math.myprop=true; // adding a custom property to the math object (why not?) list="" for ( var i in Math ) { list += i + ','; } -shouldBe("list","'myprop,'");
\ No newline at end of file +shouldBe("list","'myprop,'"); diff --git a/deps/v8/test/webkit/fast/js/kde/md5-1.js b/deps/v8/test/webkit/fast/js/kde/md5-1.js index 9c20c550cb..5df7af01f8 100644 --- a/deps/v8/test/webkit/fast/js/kde/md5-1.js +++ b/deps/v8/test/webkit/fast/js/kde/md5-1.js @@ -410,4 +410,4 @@ function MD5(entree) return s; } -shouldBe("MD5('kde')", "'186cf28b76f2264e9fea8fcf91cb4f5d'");
\ No newline at end of file +shouldBe("MD5('kde')", "'186cf28b76f2264e9fea8fcf91cb4f5d'"); diff --git a/deps/v8/test/webkit/fast/js/kde/md5-2.js b/deps/v8/test/webkit/fast/js/kde/md5-2.js index fa591704c8..1b9d4aa628 100644 --- a/deps/v8/test/webkit/fast/js/kde/md5-2.js +++ b/deps/v8/test/webkit/fast/js/kde/md5-2.js @@ -240,4 +240,4 @@ function hexMD5w(str) { return binl2hex(coreMD5(strw2binl(str))) } function b64MD5 (str) { return binl2b64(coreMD5( str2binl(str))) } function b64MD5w(str) { return binl2b64(coreMD5(strw2binl(str))) } /* Backward compatibility */ -function calcMD5(str) { return binl2hex(coreMD5( str2binl(str))) }
\ No newline at end of file +function calcMD5(str) { return binl2hex(coreMD5( str2binl(str))) } diff --git a/deps/v8/test/webkit/fast/js/kde/object_prototype.js b/deps/v8/test/webkit/fast/js/kde/object_prototype.js index 3b17cf6edc..8ffaf14671 100644 --- a/deps/v8/test/webkit/fast/js/kde/object_prototype.js +++ b/deps/v8/test/webkit/fast/js/kde/object_prototype.js @@ -98,4 +98,4 @@ shouldBe("myfunc.someproperty","4"); shouldBe("myfunc.propertyIsEnumerable('length')","false"); shouldBe("myfunc.propertyIsEnumerable('someproperty')","true"); shouldBe("checkEnumerable(myfunc,'length')","false"); -shouldBe("checkEnumerable(myfunc,'someproperty')","true");
\ No newline at end of file +shouldBe("checkEnumerable(myfunc,'someproperty')","true"); diff --git a/deps/v8/test/webkit/fast/js/kde/object_prototype_tostring.js b/deps/v8/test/webkit/fast/js/kde/object_prototype_tostring.js index 9814d8cea3..8b3ce98404 100644 --- a/deps/v8/test/webkit/fast/js/kde/object_prototype_tostring.js +++ b/deps/v8/test/webkit/fast/js/kde/object_prototype_tostring.js @@ -48,4 +48,4 @@ _error.toString = Object.prototype.toString; shouldBe("_error.toString()","\"[object Error]\""); var _function = new Function(); _function.toString = Object.prototype.toString; -shouldBe("_function.toString()","\"[object Function]\"");
\ No newline at end of file +shouldBe("_function.toString()","\"[object Function]\""); diff --git a/deps/v8/test/webkit/fast/js/kde/operators.js b/deps/v8/test/webkit/fast/js/kde/operators.js index 185ae01eab..38e658b2bd 100644 --- a/deps/v8/test/webkit/fast/js/kde/operators.js +++ b/deps/v8/test/webkit/fast/js/kde/operators.js @@ -501,4 +501,4 @@ shouldBeTrue("'a' in { a:1, b:2 }"); // instanceof // Those 2 lines don't parse in Netscape... shouldBe("(new Boolean()) instanceof Boolean", "true"); -shouldBe("(new Boolean()) instanceof Number", "false");
\ No newline at end of file +shouldBe("(new Boolean()) instanceof Number", "false"); diff --git a/deps/v8/test/webkit/fast/js/kde/parse.js b/deps/v8/test/webkit/fast/js/kde/parse.js index ca85e7637c..94467f1061 100644 --- a/deps/v8/test/webkit/fast/js/kde/parse.js +++ b/deps/v8/test/webkit/fast/js/kde/parse.js @@ -63,4 +63,4 @@ shouldThrow("var f\\u00F7;"); shouldThrow("var \\u0030;"); shouldThrow("var test = { }; test.i= 0; test.i\\u002b= 1; test.i;"); -shouldBe("var test = { }; test.i= 0; test.i\u002b= 1; test.i;", "1");
\ No newline at end of file +shouldBe("var test = { }; test.i= 0; test.i\u002b= 1; test.i;", "1"); diff --git a/deps/v8/test/webkit/fast/js/kde/prototype_length.js b/deps/v8/test/webkit/fast/js/kde/prototype_length.js index 2936fa55a9..4eb888c3da 100644 --- a/deps/v8/test/webkit/fast/js/kde/prototype_length.js +++ b/deps/v8/test/webkit/fast/js/kde/prototype_length.js @@ -57,4 +57,4 @@ shouldBe("foundFunctionPrototypeLength","false"); var foundStringPrototypeLength = false; for (i in String.prototype) { if (i == "length") foundStringPrototypeLength = true; } -shouldBe("foundStringPrototypeLength","false");
\ No newline at end of file +shouldBe("foundStringPrototypeLength","false"); diff --git a/deps/v8/test/webkit/fast/js/kde/prototype_proto.js b/deps/v8/test/webkit/fast/js/kde/prototype_proto.js index f956d94cd7..386d503cdd 100644 --- a/deps/v8/test/webkit/fast/js/kde/prototype_proto.js +++ b/deps/v8/test/webkit/fast/js/kde/prototype_proto.js @@ -30,4 +30,4 @@ shouldBe("Boolean.prototype.__proto__","Object.prototype"); shouldBe("Number.prototype.__proto__","Object.prototype"); shouldBe("Date.prototype.__proto__","Object.prototype"); shouldBe("RegExp.prototype.__proto__","Object.prototype"); -shouldBe("Error.prototype.__proto__","Object.prototype");
\ No newline at end of file +shouldBe("Error.prototype.__proto__","Object.prototype"); diff --git a/deps/v8/test/webkit/fast/js/kde/scope.js b/deps/v8/test/webkit/fast/js/kde/scope.js index cead049be8..e628d477fb 100644 --- a/deps/v8/test/webkit/fast/js/kde/scope.js +++ b/deps/v8/test/webkit/fast/js/kde/scope.js @@ -55,4 +55,4 @@ function testForIn() { } testForIn(); -shouldBe("g", "'foo'"); //Before the eval, g was in outer scope, but not after!
\ No newline at end of file +shouldBe("g", "'foo'"); //Before the eval, g was in outer scope, but not after! diff --git a/deps/v8/test/webkit/fast/js/kde/statements.js b/deps/v8/test/webkit/fast/js/kde/statements.js index ecc6c321a4..cf8b2a97fe 100644 --- a/deps/v8/test/webkit/fast/js/kde/statements.js +++ b/deps/v8/test/webkit/fast/js/kde/statements.js @@ -96,4 +96,4 @@ function testSwitch4(v) { return result; }; -shouldBe("testSwitch4(0)", "'ab'");
\ No newline at end of file +shouldBe("testSwitch4(0)", "'ab'"); diff --git a/deps/v8/test/webkit/fast/js/kde/var_decl_init.js b/deps/v8/test/webkit/fast/js/kde/var_decl_init.js index 0bf4a9e273..c72ca4ed9d 100644 --- a/deps/v8/test/webkit/fast/js/kde/var_decl_init.js +++ b/deps/v8/test/webkit/fast/js/kde/var_decl_init.js @@ -181,4 +181,4 @@ shouldBe("overrideVar", "1"); var overrideVar2 = 1; var overrideVar2 = 2; -shouldBe("overrideVar2", "2");
\ No newline at end of file +shouldBe("overrideVar2", "2"); diff --git a/deps/v8/test/webkit/fast/js/object-bad-time-expected.txt b/deps/v8/test/webkit/fast/js/object-bad-time-expected.txt index b282bd8451..7b6b6ea73d 100644 --- a/deps/v8/test/webkit/fast/js/object-bad-time-expected.txt +++ b/deps/v8/test/webkit/fast/js/object-bad-time-expected.txt @@ -977,58 +977,57 @@ PASS "0,1,2,3,4" is "0,1,2,3,4" PASS "0,1,2,3,4" is "0,1,2,3,4" PASS "0,1,2,3,4" is "0,1,2,3,4" Henceforth I will have a bad time. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL ouches should be 50. Was 0. +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS ouches is 50 PASS successfullyParsed is true TEST COMPLETE - diff --git a/deps/v8/test/webkit/fast/js/object-bad-time.js b/deps/v8/test/webkit/fast/js/object-bad-time.js index 2fdb2d17ce..45fb4dd292 100644 --- a/deps/v8/test/webkit/fast/js/object-bad-time.js +++ b/deps/v8/test/webkit/fast/js/object-bad-time.js @@ -36,7 +36,7 @@ function foo(haveABadTime) { for (var i = 0; i < result.length; ++i) { if (i == haveABadTime) { debug("Henceforth I will have a bad time."); - Cons.prototype.__defineSetter__("3", function() { debug("Ouch!"); ouches++; }); + Cons.prototype.__defineSetter__("3", function() { ouches++; }); } result[i] = i; } diff --git a/deps/v8/test/webkit/fast/js/object-slow-put-expected.txt b/deps/v8/test/webkit/fast/js/object-slow-put-expected.txt index 901133b4b7..f20c4a59e8 100644 --- a/deps/v8/test/webkit/fast/js/object-slow-put-expected.txt +++ b/deps/v8/test/webkit/fast/js/object-slow-put-expected.txt @@ -26,108 +26,107 @@ Tests that defining a setter on the prototype of an object used for indexed stor On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL "0,1,2,3,4" should be 0,1,2,,4. Was 0,1,2,3,4. -FAIL ouches should be 100. Was 0. +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS "0,1,2,,4" is "0,1,2,,4" +PASS ouches is 100 PASS successfullyParsed is true TEST COMPLETE - diff --git a/deps/v8/test/webkit/fast/js/object-slow-put.js b/deps/v8/test/webkit/fast/js/object-slow-put.js index bf8234f209..49c20ba210 100644 --- a/deps/v8/test/webkit/fast/js/object-slow-put.js +++ b/deps/v8/test/webkit/fast/js/object-slow-put.js @@ -29,7 +29,7 @@ function Cons() { } var ouches = 0; -Cons.prototype.__defineSetter__("3", function() { debug("Ouch!"); ouches++; }); +Cons.prototype.__defineSetter__("3", function() { ouches++; }); function foo() { var result = new Cons(); diff --git a/deps/v8/test/webkit/fast/js/string-anchor.js b/deps/v8/test/webkit/fast/js/string-anchor.js index f213b89156..d954928acc 100644 --- a/deps/v8/test/webkit/fast/js/string-anchor.js +++ b/deps/v8/test/webkit/fast/js/string-anchor.js @@ -50,4 +50,4 @@ shouldThrow("String.prototype.anchor.call(undefined)", '"TypeError: Type error"' shouldThrow("String.prototype.anchor.call(null)", '"TypeError: Type error"'); // Check anchor.length. -shouldBe("String.prototype.anchor.length", "1");
\ No newline at end of file +shouldBe("String.prototype.anchor.length", "1"); diff --git a/deps/v8/test/webkit/fast/js/string-fontcolor.js b/deps/v8/test/webkit/fast/js/string-fontcolor.js index 67f4ef2e07..17ca62ff5f 100644 --- a/deps/v8/test/webkit/fast/js/string-fontcolor.js +++ b/deps/v8/test/webkit/fast/js/string-fontcolor.js @@ -50,4 +50,4 @@ shouldThrow("String.prototype.fontcolor.call(undefined)", '"TypeError: Type erro shouldThrow("String.prototype.fontcolor.call(null)", '"TypeError: Type error"'); // Check fontcolor.length. -shouldBe("String.prototype.fontcolor.length", "1");
\ No newline at end of file +shouldBe("String.prototype.fontcolor.length", "1"); diff --git a/deps/v8/test/webkit/fast/js/string-fontsize.js b/deps/v8/test/webkit/fast/js/string-fontsize.js index e103e5e6bc..b3b48c5b35 100644 --- a/deps/v8/test/webkit/fast/js/string-fontsize.js +++ b/deps/v8/test/webkit/fast/js/string-fontsize.js @@ -53,4 +53,4 @@ shouldThrow("String.prototype.fontsize.call(undefined)", '"TypeError: Type error shouldThrow("String.prototype.fontsize.call(null)", '"TypeError: Type error"'); // Check fontsize.length. -shouldBe("String.prototype.fontsize.length", "1");
\ No newline at end of file +shouldBe("String.prototype.fontsize.length", "1"); diff --git a/deps/v8/test/webkit/fast/js/string-link.js b/deps/v8/test/webkit/fast/js/string-link.js index 8b96915be1..873e7af3b4 100644 --- a/deps/v8/test/webkit/fast/js/string-link.js +++ b/deps/v8/test/webkit/fast/js/string-link.js @@ -53,4 +53,4 @@ shouldThrow("String.prototype.link.call(undefined)", '"TypeError: Type error"'); shouldThrow("String.prototype.link.call(null)", '"TypeError: Type error"'); // Check link.length. -shouldBe("String.prototype.link.length", "1");
\ No newline at end of file +shouldBe("String.prototype.link.length", "1"); diff --git a/deps/v8/test/webkit/fast/js/toString-number.js b/deps/v8/test/webkit/fast/js/toString-number.js index 2acb3d1d09..6280f41537 100644 --- a/deps/v8/test/webkit/fast/js/toString-number.js +++ b/deps/v8/test/webkit/fast/js/toString-number.js @@ -91,4 +91,4 @@ description("Test the conversion performed by the function Number.prototype.toSt shouldBeEqualToString('Number.prototype.toString.call(' + number + ', 36)', stringBase36); shouldBeEqualToString('Number.prototype.toString.call(new Number(' + number + '), 36)', stringBase36); } - successfullyParsed = true;
\ No newline at end of file + successfullyParsed = true; diff --git a/deps/v8/test/webkit/fast/js/toString-overrides-expected.txt b/deps/v8/test/webkit/fast/js/toString-overrides-expected.txt index 6bf5ae57ba..3e36c70615 100644 --- a/deps/v8/test/webkit/fast/js/toString-overrides-expected.txt +++ b/deps/v8/test/webkit/fast/js/toString-overrides-expected.txt @@ -28,12 +28,13 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE PASS [1].toString() is '1' PASS [1].toLocaleString() is 'toLocaleString' -FAIL [1].toLocaleString() should be 1. Threw exception TypeError: Property 'toLocaleString' of object [object Number] is not a function +FAIL [1].toLocaleString() should be 1. Threw exception TypeError: string is not a function PASS [/r/].toString() is 'toString2' PASS [/r/].toLocaleString() is 'toLocaleString2' -FAIL [/r/].toLocaleString() should be toString2. Threw exception TypeError: Property 'toLocaleString' of object [object RegExp] is not a function +FAIL [/r/].toLocaleString() should be toString2. Threw exception TypeError: string is not a function PASS caught is true PASS successfullyParsed is true + TEST COMPLETE diff --git a/deps/v8/test/webkit/fast/regex/assertion.js b/deps/v8/test/webkit/fast/regex/assertion.js index 3d980ce14d..d4c46f2928 100644 --- a/deps/v8/test/webkit/fast/regex/assertion.js +++ b/deps/v8/test/webkit/fast/regex/assertion.js @@ -107,4 +107,3 @@ shouldBe("regex23.exec('ax')", "null"); var regex24 = /(?=a|b?)c/; shouldBe("regex24.exec('x')", "null"); - diff --git a/deps/v8/test/webkit/fast/regex/constructor.js b/deps/v8/test/webkit/fast/regex/constructor.js index 9d35245286..552d82e3ac 100644 --- a/deps/v8/test/webkit/fast/regex/constructor.js +++ b/deps/v8/test/webkit/fast/regex/constructor.js @@ -29,4 +29,3 @@ shouldBeTrue("re === RegExp(re)"); shouldBeTrue("re !== new RegExp(re)"); shouldThrow("re === RegExp(re,'i')"); shouldThrow("re !== new RegExp(re,'i')"); - diff --git a/deps/v8/test/webkit/fast/regex/dotstar.js b/deps/v8/test/webkit/fast/regex/dotstar.js index 20696377d4..883c4aacfe 100644 --- a/deps/v8/test/webkit/fast/regex/dotstar.js +++ b/deps/v8/test/webkit/fast/regex/dotstar.js @@ -157,4 +157,3 @@ shouldBe("regexp12.exec('first\\nblah2\\nblah3')", "['blah3']"); var regexp13 = /.*\n\d+.*/; shouldBe("regexp13.exec('abc\\n123')", "['abc\\n123']"); - diff --git a/deps/v8/test/webkit/fast/regex/parentheses.js b/deps/v8/test/webkit/fast/regex/parentheses.js index 57a2830fe0..4d7a141d22 100644 --- a/deps/v8/test/webkit/fast/regex/parentheses.js +++ b/deps/v8/test/webkit/fast/regex/parentheses.js @@ -274,4 +274,3 @@ var regexp58 = /a|b(?:[^b])*?c/; shouldBe("regexp58.exec('badbc')", "['a']"); var regexp59 = /(X(?:.(?!X))*?Y)|(Y(?:.(?!Y))*?Z)/g; shouldBe("'Y aaa X Match1 Y aaa Y Match2 Z'.match(regexp59)", "['X Match1 Y','Y Match2 Z']"); - diff --git a/deps/v8/test/webkit/function-dot-apply-replace-base.js b/deps/v8/test/webkit/function-dot-apply-replace-base.js index ed0f84b978..e0494e54db 100644 --- a/deps/v8/test/webkit/function-dot-apply-replace-base.js +++ b/deps/v8/test/webkit/function-dot-apply-replace-base.js @@ -44,6 +44,3 @@ function bar() { } shouldBe("bar()", "3"); - - - diff --git a/deps/v8/test/webkit/get-by-pname-non-final-object.js b/deps/v8/test/webkit/get-by-pname-non-final-object.js index f891af680c..1c798d1d55 100644 --- a/deps/v8/test/webkit/get-by-pname-non-final-object.js +++ b/deps/v8/test/webkit/get-by-pname-non-final-object.js @@ -70,4 +70,3 @@ for (var i = 0; i < 100; ++i) { shouldBe("foo(r)", "113"); shouldBe("foo(s)", "182"); } - diff --git a/deps/v8/test/webkit/get-by-pname-that-looks-like-a-patchable-get-by-val.js b/deps/v8/test/webkit/get-by-pname-that-looks-like-a-patchable-get-by-val.js index d3e69b6dc9..a0b6ccf81e 100644 --- a/deps/v8/test/webkit/get-by-pname-that-looks-like-a-patchable-get-by-val.js +++ b/deps/v8/test/webkit/get-by-pname-that-looks-like-a-patchable-get-by-val.js @@ -40,5 +40,3 @@ function foo() { } shouldBe("foo()", "300"); - - diff --git a/deps/v8/test/webkit/get-by-pname.js b/deps/v8/test/webkit/get-by-pname.js index 13a7c5d4a9..07afa168a4 100644 --- a/deps/v8/test/webkit/get-by-pname.js +++ b/deps/v8/test/webkit/get-by-pname.js @@ -45,4 +45,3 @@ for (var i = 0; i < 100; ++i) { shouldBe("foo(r)", "113"); shouldBe("foo(s)", "182"); } - diff --git a/deps/v8/test/webkit/indexed-setter-on-global-object.js b/deps/v8/test/webkit/indexed-setter-on-global-object.js index 8453206849..20c70c24f5 100644 --- a/deps/v8/test/webkit/indexed-setter-on-global-object.js +++ b/deps/v8/test/webkit/indexed-setter-on-global-object.js @@ -34,4 +34,3 @@ this.__defineSetter__(42, function(value) { this[42] = "foo"; shouldBe("thingy", "\"foo\""); - diff --git a/deps/v8/test/webkit/instance-of-immediates-expected.txt b/deps/v8/test/webkit/instance-of-immediates-expected.txt index a6f6cc5072..db58f00d30 100644 --- a/deps/v8/test/webkit/instance-of-immediates-expected.txt +++ b/deps/v8/test/webkit/instance-of-immediates-expected.txt @@ -27,11 +27,11 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE PASS (1 instanceof 1) threw exception TypeError: Expecting a function in instanceof check, but got 1. -PASS ({} instanceof 1) threw exception TypeError: Expecting a function in instanceof check, but got #<Object>. -PASS (obj instanceof 1) threw exception TypeError: Expecting a function in instanceof check, but got #<Constructor>. -PASS (1 instanceof {}) threw exception TypeError: Expecting a function in instanceof check, but got 1. +PASS ({} instanceof 1) threw exception TypeError: Expecting a function in instanceof check, but got 1. +PASS (obj instanceof 1) threw exception TypeError: Expecting a function in instanceof check, but got 1. +PASS (1 instanceof {}) threw exception TypeError: Expecting a function in instanceof check, but got #<Object>. PASS ({} instanceof {}) threw exception TypeError: Expecting a function in instanceof check, but got #<Object>. -PASS (obj instanceof {}) threw exception TypeError: Expecting a function in instanceof check, but got #<Constructor>. +PASS (obj instanceof {}) threw exception TypeError: Expecting a function in instanceof check, but got #<Object>. PASS (1 instanceof Constructor) is false PASS ({} instanceof Constructor) is false PASS (obj instanceof Constructor) is true diff --git a/deps/v8/test/webkit/new-array-double-with-holes.js b/deps/v8/test/webkit/new-array-double-with-holes.js index 208fc91dbe..faf2bfbf3b 100644 --- a/deps/v8/test/webkit/new-array-double-with-holes.js +++ b/deps/v8/test/webkit/new-array-double-with-holes.js @@ -31,4 +31,3 @@ function foo(array, i) { for (var i = 0; i < 100; ++i) shouldBe("foo([, 1.5], 0)", "void 0"); - diff --git a/deps/v8/test/webkit/regexp-in-and-foreach-handling.js b/deps/v8/test/webkit/regexp-in-and-foreach-handling.js index a2430db7ba..f345c8f544 100644 --- a/deps/v8/test/webkit/regexp-in-and-foreach-handling.js +++ b/deps/v8/test/webkit/regexp-in-and-foreach-handling.js @@ -69,4 +69,3 @@ for (var i in tests) { shouldBe('testInOperator(' + i + ')', tests[i][2]); shouldBe('testForEachFunction(' + i + ')', tests[i][2]); } - diff --git a/deps/v8/test/webkit/regexp-zero-length-alternatives.js b/deps/v8/test/webkit/regexp-zero-length-alternatives.js index 6e18de08c7..c91f1c1217 100644 --- a/deps/v8/test/webkit/regexp-zero-length-alternatives.js +++ b/deps/v8/test/webkit/regexp-zero-length-alternatives.js @@ -272,4 +272,3 @@ shouldBe('emptyStr.match(re34)', '[""]'); shouldBe('s1.match(re34)', '[""]'); shouldBe('s2.match(re34)', '[""]'); shouldBe('s3.match(re34)', '[""]'); - diff --git a/deps/v8/test/webkit/resolve-arguments-from-scope.js b/deps/v8/test/webkit/resolve-arguments-from-scope.js index def71585df..b3900e7772 100644 --- a/deps/v8/test/webkit/resolve-arguments-from-scope.js +++ b/deps/v8/test/webkit/resolve-arguments-from-scope.js @@ -42,4 +42,3 @@ for (var i = 0; i < 100; ++i) { shouldBe("foo(42).length", "1"); shouldBe("foo(42, 23)[1]", "23"); } - diff --git a/deps/v8/test/webkit/sort-with-side-effecting-comparisons.js b/deps/v8/test/webkit/sort-with-side-effecting-comparisons.js index 5dda02fa55..6794e322f5 100644 --- a/deps/v8/test/webkit/sort-with-side-effecting-comparisons.js +++ b/deps/v8/test/webkit/sort-with-side-effecting-comparisons.js @@ -40,5 +40,3 @@ array.sort(function(a, b) { }); testPassed("It worked."); - - diff --git a/deps/v8/test/webkit/stack-unwinding.js b/deps/v8/test/webkit/stack-unwinding.js index 8c737fa00d..0a898274a6 100644 --- a/deps/v8/test/webkit/stack-unwinding.js +++ b/deps/v8/test/webkit/stack-unwinding.js @@ -62,4 +62,3 @@ try { } catch (e) { testPassed("Exception thrown and caught"); } - diff --git a/deps/v8/test/webkit/string-replacement-outofmemory-expected.txt b/deps/v8/test/webkit/string-replacement-outofmemory-expected.txt new file mode 100644 index 0000000000..68ac217966 --- /dev/null +++ b/deps/v8/test/webkit/string-replacement-outofmemory-expected.txt @@ -0,0 +1,23 @@ +# Copyright 2013 the V8 project authors. All rights reserved. +# Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/deps/v8/test/webkit/string-replacement-outofmemory.js b/deps/v8/test/webkit/string-replacement-outofmemory.js new file mode 100644 index 0000000000..2b8e18a854 --- /dev/null +++ b/deps/v8/test/webkit/string-replacement-outofmemory.js @@ -0,0 +1,41 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +description( +'This tests that string replacement with a large replacement string causes an out-of-memory exception. See <a href="https://bugs.webkit.org/show_bug.cgi?id=102956">bug 102956</a> for more details.' +); + +function createStringWithRepeatedChar(c, multiplicity) { + while (c.length < multiplicity) + c += c; + c = c.substring(0, multiplicity); + return c; +} + +var x = "1"; +var y = "2"; +x = createStringWithRepeatedChar(x, 1 << 12); +y = createStringWithRepeatedChar(y, (1 << 20) + 1); + +shouldThrow("x.replace(/\\d/g, y)", '"Error: Out of memory"'); +var successfullyParsed = true; diff --git a/deps/v8/test/webkit/string-trim-expected.txt b/deps/v8/test/webkit/string-trim-expected.txt index 9540f1c8db..6472f89d0b 100644 --- a/deps/v8/test/webkit/string-trim-expected.txt +++ b/deps/v8/test/webkit/string-trim-expected.txt @@ -89,20 +89,38 @@ PASS whitespace[19].s.trimRight() is '' PASS whitespace[20].s.trim() is '' PASS whitespace[20].s.trimLeft() is '' PASS whitespace[20].s.trimRight() is '' -PASS whitespace[21].s.trim() is '' -PASS whitespace[21].s.trimLeft() is '' -PASS whitespace[21].s.trimRight() is '' -PASS wsString.trim() is '' -PASS wsString.trimLeft() is '' -PASS wsString.trimRight() is '' -PASS trimString.trim() is testString -PASS trimString.trimLeft() is leftTrimString -PASS trimString.trimRight() is rightTrimString -PASS leftTrimString.trim() is testString +FAIL whitespace[21].s.trim() should be . Was . +FAIL whitespace[21].s.trimLeft() should be . Was . +FAIL whitespace[21].s.trimRight() should be . Was . +FAIL wsString.trim() should be . Was . +FAIL wsString.trimLeft() should be . Was . +FAIL wsString.trimRight() should be . Was + +
. +FAIL trimString.trim() should be foo bar. Was foo bar + +
. +FAIL trimString.trimLeft() should be foo bar + +
. Was foo bar + +
. +FAIL trimString.trimRight() should be + +
foo bar. Was + +
foo bar + +
. +FAIL leftTrimString.trim() should be foo bar. Was foo bar + +
. PASS leftTrimString.trimLeft() is leftTrimString -PASS leftTrimString.trimRight() is testString -PASS rightTrimString.trim() is testString -PASS rightTrimString.trimLeft() is testString +FAIL leftTrimString.trimRight() should be foo bar. Was foo bar + +
. +FAIL rightTrimString.trim() should be foo bar. Was foo bar. +FAIL rightTrimString.trimLeft() should be foo bar. Was foo bar. PASS rightTrimString.trimRight() is rightTrimString PASS trim.call(0) is '0' PASS trimLeft.call(0) is '0' diff --git a/deps/v8/test/webkit/string-trim.js b/deps/v8/test/webkit/string-trim.js index e644754736..27f99d579a 100644 --- a/deps/v8/test/webkit/string-trim.js +++ b/deps/v8/test/webkit/string-trim.js @@ -92,4 +92,3 @@ for (var i = 0; i < testValues.length; i++) { shouldBe("trimLeft.call("+testValues[i]+")", "'"+eval(testValues[i])+"'"); shouldBe("trimRight.call("+testValues[i]+")", "'"+eval(testValues[i])+"'"); } - diff --git a/deps/v8/test/webkit/throw-from-finally.js b/deps/v8/test/webkit/throw-from-finally.js index baa4ae8f49..183245d8d1 100644 --- a/deps/v8/test/webkit/throw-from-finally.js +++ b/deps/v8/test/webkit/throw-from-finally.js @@ -78,4 +78,3 @@ try { } shouldBe("\"\" + events", "\"1:try,1:finally,2:finally,2:thingy,3:thingy,3:finally,4:thingy,4:finally,4:another thingy,5:hi,5:wat\""); - diff --git a/deps/v8/test/webkit/try-catch-try-try-catch-try-finally-return-catch-finally.js b/deps/v8/test/webkit/try-catch-try-try-catch-try-finally-return-catch-finally.js index 140ba7fcf2..1547bdf0b1 100644 --- a/deps/v8/test/webkit/try-catch-try-try-catch-try-finally-return-catch-finally.js +++ b/deps/v8/test/webkit/try-catch-try-try-catch-try-finally-return-catch-finally.js @@ -50,4 +50,3 @@ try { } catch (e) { testPassed("It worked."); } - diff --git a/deps/v8/test/webkit/try-try-return-finally-finally.js b/deps/v8/test/webkit/try-try-return-finally-finally.js index 8eef64252d..4861824299 100644 --- a/deps/v8/test/webkit/try-try-return-finally-finally.js +++ b/deps/v8/test/webkit/try-try-return-finally-finally.js @@ -45,4 +45,3 @@ try { } catch (e) { testPassed("It worked."); } - diff --git a/deps/v8/test/webkit/var-declarations-zero-width.js b/deps/v8/test/webkit/var-declarations-zero-width.js index 8b5f90f2c9..e7b7c455dc 100644 --- a/deps/v8/test/webkit/var-declarations-zero-width.js +++ b/deps/v8/test/webkit/var-declarations-zero-width.js @@ -25,4 +25,4 @@ description("This page tests if U+200C and U+200D are allowed as part of an iden shouldBe("var x\u200c = 42; x\u200c", "42"); shouldBe("var x\u200d = 43; x\u200d", "43"); -shouldBe("var x\u200c\u200d = 44; x\u200c\u200d", "44");
\ No newline at end of file +shouldBe("var x\u200c\u200d = 44; x\u200c\u200d", "44"); diff --git a/deps/v8/test/webkit/webkit.status b/deps/v8/test/webkit/webkit.status index eba1be3f0f..1c68070d42 100644 --- a/deps/v8/test/webkit/webkit.status +++ b/deps/v8/test/webkit/webkit.status @@ -26,6 +26,18 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [ +[ALWAYS, { + # BUG(237872). TODO(bmeurer): Investigate. + 'string-replacement-outofmemory': [FAIL], + + ############################################################################## + # Flaky tests. + # BUG(v8:2989). + 'dfg-inline-arguments-become-double': [PASS, FAIL], + 'dfg-inline-arguments-become-int32': [PASS, FAIL], + 'dfg-inline-arguments-reset': [PASS, FAIL], + 'dfg-inline-arguments-reset-changetype': [PASS, FAIL], +}], # ALWAYS ['mode == debug', { # Too slow in debug mode. 'dfg-int-overflow-in-loop': [SKIP], @@ -33,4 +45,10 @@ 'reentrant-caching': [SKIP], 'sort-large-array': [SKIP], }], # 'mode == debug' +['simulator', { + 'function-apply-aliased': [SKIP], +}], # 'simulator' +['arch == a64 and simulator_run == True', { + 'dfg-int-overflow-in-loop': [SKIP], +}], # 'arch == a64 and simulator_run == True' ] |