diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2009-11-18 15:25:58 +0100 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2009-11-18 15:28:54 +0100 |
commit | 728d8a37f471afaeaa6af19823f9da8c41f1f65a (patch) | |
tree | 21e014089ff0bfb7d493691620ab9eee51176d28 /deps/v8/test/cctest | |
parent | 8195e0f7232fed3d6a3a2cc8464fec5e36f4433c (diff) | |
download | node-728d8a37f471afaeaa6af19823f9da8c41f1f65a.tar.gz |
Upgrade v8 to 2.0
(With just one change: remove -Werror)
Diffstat (limited to 'deps/v8/test/cctest')
23 files changed, 1321 insertions, 781 deletions
diff --git a/deps/v8/test/cctest/SConscript b/deps/v8/test/cctest/SConscript index f041041c1..e6c81d80e 100644 --- a/deps/v8/test/cctest/SConscript +++ b/deps/v8/test/cctest/SConscript @@ -34,6 +34,7 @@ Import('context object_files') SOURCES = { 'all': [ + 'test-accessors.cc', 'test-alloc.cc', 'test-api.cc', 'test-ast.cc', @@ -51,6 +52,7 @@ SOURCES = { 'test-log.cc', 'test-log-utils.cc', 'test-mark-compact.cc', + 'test-parsing.cc', 'test-regexp.cc', 'test-serialize.cc', 'test-sockets.cc', diff --git a/deps/v8/test/cctest/cctest.cc b/deps/v8/test/cctest/cctest.cc index 82a33e6da..f638ed480 100644 --- a/deps/v8/test/cctest/cctest.cc +++ b/deps/v8/test/cctest/cctest.cc @@ -121,3 +121,6 @@ int main(int argc, char* argv[]) { v8::V8::Dispose(); return 0; } + +RegisterThreadedTest *RegisterThreadedTest::first_ = NULL; +int RegisterThreadedTest::count_ = 0; diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h index a95645e01..404b692b2 100644 --- a/deps/v8/test/cctest/cctest.h +++ b/deps/v8/test/cctest/cctest.h @@ -28,6 +28,8 @@ #ifndef CCTEST_H_ #define CCTEST_H_ +#include "v8.h" + #ifndef TEST #define TEST(Name) \ static void Test##Name(); \ @@ -72,4 +74,138 @@ class CcTest { CcTest* prev_; }; +// Switches between all the Api tests using the threading support. +// In order to get a surprising but repeatable pattern of thread +// switching it has extra semaphores to control the order in which +// the tests alternate, not relying solely on the big V8 lock. +// +// A test is augmented with calls to ApiTestFuzzer::Fuzz() in its +// callbacks. This will have no effect when we are not running the +// thread fuzzing test. In the thread fuzzing test it will +// pseudorandomly select a successor thread and switch execution +// to that thread, suspending the current test. +class ApiTestFuzzer: public v8::internal::Thread { + public: + void CallTest(); + explicit ApiTestFuzzer(int num) + : test_number_(num), + gate_(v8::internal::OS::CreateSemaphore(0)), + active_(true) { + } + ~ApiTestFuzzer() { delete gate_; } + + // The ApiTestFuzzer is also a Thread, so it has a Run method. + virtual void Run(); + + enum PartOfTest { FIRST_PART, SECOND_PART }; + + static void Setup(PartOfTest part); + static void RunAllTests(); + static void TearDown(); + // This method switches threads if we are running the Threading test. + // Otherwise it does nothing. + static void Fuzz(); + private: + static bool fuzzing_; + static int tests_being_run_; + static int current_; + static int active_tests_; + static bool NextThread(); + int test_number_; + v8::internal::Semaphore* gate_; + bool active_; + void ContextSwitch(); + static int GetNextTestNumber(); + static v8::internal::Semaphore* all_tests_done_; +}; + + +#define THREADED_TEST(Name) \ + static void Test##Name(); \ + RegisterThreadedTest register_##Name(Test##Name, #Name); \ + /* */ TEST(Name) + + +class RegisterThreadedTest { + public: + explicit RegisterThreadedTest(CcTest::TestFunction* callback, + const char* name) + : fuzzer_(NULL), callback_(callback), name_(name) { + prev_ = first_; + first_ = this; + count_++; + } + static int count() { return count_; } + static RegisterThreadedTest* nth(int i) { + CHECK(i < count()); + RegisterThreadedTest* current = first_; + while (i > 0) { + i--; + current = current->prev_; + } + return current; + } + CcTest::TestFunction* callback() { return callback_; } + ApiTestFuzzer* fuzzer_; + const char* name() { return name_; } + + private: + static RegisterThreadedTest* first_; + static int count_; + CcTest::TestFunction* callback_; + RegisterThreadedTest* prev_; + const char* name_; +}; + + +// A LocalContext holds a reference to a v8::Context. +class LocalContext { + public: + LocalContext(v8::ExtensionConfiguration* extensions = 0, + v8::Handle<v8::ObjectTemplate> global_template = + v8::Handle<v8::ObjectTemplate>(), + v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) + : context_(v8::Context::New(extensions, global_template, global_object)) { + context_->Enter(); + } + + virtual ~LocalContext() { + context_->Exit(); + context_.Dispose(); + } + + v8::Context* operator->() { return *context_; } + v8::Context* operator*() { return *context_; } + bool IsReady() { return !context_.IsEmpty(); } + + v8::Local<v8::Context> local() { + return v8::Local<v8::Context>::New(context_); + } + + private: + v8::Persistent<v8::Context> context_; +}; + + +static inline v8::Local<v8::Value> v8_num(double x) { + return v8::Number::New(x); +} + + +static inline v8::Local<v8::String> v8_str(const char* x) { + return v8::String::New(x); +} + + +static inline v8::Local<v8::Script> v8_compile(const char* x) { + return v8::Script::Compile(v8_str(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(); +} + + #endif // ifndef CCTEST_H_ diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status index 6ce241ff1..a143cbdab 100644 --- a/deps/v8/test/cctest/cctest.status +++ b/deps/v8/test/cctest/cctest.status @@ -33,12 +33,6 @@ test-debug/DebuggerAgent: PASS, (PASS || FAIL) if $system == linux # BUG(382): Weird test. Can't guarantee that it never times out. test-api/ApplyInterruption: PASS || TIMEOUT -# This is about to go away anyway since new snapshot code is on the way. -test-serialize/Deserialize: FAIL -test-serialize/DeserializeAndRunScript: FAIL -test-serialize/DeserializeNatives: FAIL -test-serialize/DeserializeExtensions: FAIL - # These tests always fail. They are here to test test.py. If # they don't fail then test.py has failed. test-serialize/TestThatAlwaysFails: FAIL @@ -47,13 +41,6 @@ test-serialize/DependentTestThatAlwaysFails: FAIL [ $arch == arm ] -# New serialization doesn't work on ARM yet. -test-serialize/Deserialize2: SKIP -test-serialize/DeserializeAndRunScript2: SKIP - -# BUG(113): Test seems flaky on ARM. -test-spaces/LargeObjectSpace: PASS || FAIL - # BUG(240): Test seems flaky on ARM. test-api/RegExpInterruption: SKIP @@ -65,11 +52,3 @@ test-api/OutOfMemoryNested: SKIP # BUG(355): Test crashes on ARM. test-log/ProfLazyMode: SKIP - -[ $simulator == arm ] - -# BUG(271): During exception propagation, we compare pointers into the -# stack. These tests fail on the ARM simulator because the C++ and -# the JavaScript stacks are separate. -test-api/ExceptionOrder: FAIL -test-api/TryCatchInTryFinally: FAIL diff --git a/deps/v8/test/cctest/test-accessors.cc b/deps/v8/test/cctest/test-accessors.cc new file mode 100644 index 000000000..25f5c3951 --- /dev/null +++ b/deps/v8/test/cctest/test-accessors.cc @@ -0,0 +1,450 @@ +// Copyright 2009 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 "api.h" +#include "cctest.h" +#include "frames-inl.h" +#include "string-stream.h" + +using ::v8::ObjectTemplate; +using ::v8::Value; +using ::v8::Context; +using ::v8::Local; +using ::v8::String; +using ::v8::Script; +using ::v8::Function; +using ::v8::AccessorInfo; +using ::v8::Extension; + +namespace i = ::v8::internal; + +static v8::Handle<Value> handle_property(Local<String> name, + const AccessorInfo&) { + ApiTestFuzzer::Fuzz(); + return v8_num(900); +} + + +THREADED_TEST(PropertyHandler) { + v8::HandleScope scope; + Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); + fun_templ->InstanceTemplate()->SetAccessor(v8_str("foo"), handle_property); + LocalContext env; + Local<Function> fun = fun_templ->GetFunction(); + env->Global()->Set(v8_str("Fun"), fun); + Local<Script> getter = v8_compile("var obj = new Fun(); obj.foo;"); + CHECK_EQ(900, getter->Run()->Int32Value()); + Local<Script> setter = v8_compile("obj.foo = 901;"); + CHECK_EQ(901, setter->Run()->Int32Value()); +} + + +static v8::Handle<Value> GetIntValue(Local<String> property, + const AccessorInfo& info) { + ApiTestFuzzer::Fuzz(); + int* value = + static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); + return v8_num(*value); +} + + +static void SetIntValue(Local<String> property, + Local<Value> value, + const AccessorInfo& info) { + int* field = + static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); + *field = value->Int32Value(); +} + +int foo, bar, baz; + +THREADED_TEST(GlobalVariableAccess) { + foo = 0; + bar = -4; + baz = 10; + v8::HandleScope scope; + 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)); + LocalContext env(0, templ->InstanceTemplate()); + v8_compile("foo = (++bar) + baz")->Run(); + CHECK_EQ(bar, -3); + CHECK_EQ(foo, 7); +} + + +static int x_register = 0; +static v8::Handle<v8::Object> x_receiver; +static v8::Handle<v8::Object> x_holder; + + +static v8::Handle<Value> XGetter(Local<String> name, const AccessorInfo& info) { + ApiTestFuzzer::Fuzz(); + CHECK_EQ(x_receiver, info.This()); + CHECK_EQ(x_holder, info.Holder()); + return v8_num(x_register); +} + + +static void XSetter(Local<String> name, + Local<Value> value, + const AccessorInfo& info) { + CHECK_EQ(x_holder, info.This()); + CHECK_EQ(x_holder, info.Holder()); + x_register = value->Int32Value(); +} + + +THREADED_TEST(AccessorIC) { + v8::HandleScope scope; + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + obj->SetAccessor(v8_str("x"), XGetter, XSetter); + LocalContext context; + x_holder = obj->NewInstance(); + context->Global()->Set(v8_str("holder"), x_holder); + x_receiver = v8::Object::New(); + context->Global()->Set(v8_str("obj"), x_receiver); + v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(CompileRun( + "obj.__proto__ = holder;" + "var result = [];" + "for (var i = 0; i < 10; i++) {" + " holder.x = i;" + " result.push(obj.x);" + "}" + "result")); + CHECK_EQ(10, array->Length()); + for (int i = 0; i < 10; i++) { + v8::Handle<Value> entry = array->Get(v8::Integer::New(i)); + CHECK_EQ(v8::Integer::New(i), entry); + } +} + + +static v8::Handle<Value> AccessorProhibitsOverwritingGetter( + Local<String> name, + const AccessorInfo& info) { + ApiTestFuzzer::Fuzz(); + return v8::True(); +} + + +THREADED_TEST(AccessorProhibitsOverwriting) { + v8::HandleScope scope; + LocalContext context; + Local<ObjectTemplate> templ = ObjectTemplate::New(); + templ->SetAccessor(v8_str("x"), + AccessorProhibitsOverwritingGetter, + 0, + v8::Handle<Value>(), + v8::PROHIBITS_OVERWRITING, + v8::ReadOnly); + Local<v8::Object> instance = templ->NewInstance(); + context->Global()->Set(v8_str("obj"), instance); + Local<Value> value = CompileRun( + "obj.__defineGetter__('x', function() { return false; });" + "obj.x"); + CHECK(value->BooleanValue()); + value = CompileRun( + "var setter_called = false;" + "obj.__defineSetter__('x', function() { setter_called = true; });" + "obj.x = 42;" + "setter_called"); + CHECK(!value->BooleanValue()); + value = CompileRun( + "obj2 = {};" + "obj2.__proto__ = obj;" + "obj2.__defineGetter__('x', function() { return false; });" + "obj2.x"); + CHECK(value->BooleanValue()); + value = CompileRun( + "var setter_called = false;" + "obj2 = {};" + "obj2.__proto__ = obj;" + "obj2.__defineSetter__('x', function() { setter_called = true; });" + "obj2.x = 42;" + "setter_called"); + CHECK(!value->BooleanValue()); +} + + +template <int C> +static v8::Handle<Value> HandleAllocatingGetter(Local<String> name, + const AccessorInfo& info) { + ApiTestFuzzer::Fuzz(); + for (int i = 0; i < C; i++) + v8::String::New("foo"); + return v8::String::New("foo"); +} + + +THREADED_TEST(HandleScopePop) { + v8::HandleScope scope; + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + obj->SetAccessor(v8_str("one"), HandleAllocatingGetter<1>); + obj->SetAccessor(v8_str("many"), HandleAllocatingGetter<1024>); + LocalContext context; + v8::Handle<v8::Object> inst = obj->NewInstance(); + context->Global()->Set(v8::String::New("obj"), inst); + int count_before = i::HandleScope::NumberOfHandles(); + { + v8::HandleScope scope; + CompileRun( + "for (var i = 0; i < 1000; i++) {" + " obj.one;" + " obj.many;" + "}"); + } + int count_after = i::HandleScope::NumberOfHandles(); + CHECK_EQ(count_before, count_after); +} + +static v8::Handle<Value> CheckAccessorArgsCorrect(Local<String> name, + const AccessorInfo& info) { + CHECK(info.This() == info.Holder()); + CHECK(info.Data()->Equals(v8::String::New("data"))); + ApiTestFuzzer::Fuzz(); + CHECK(info.This() == info.Holder()); + CHECK(info.Data()->Equals(v8::String::New("data"))); + i::Heap::CollectAllGarbage(true); + CHECK(info.This() == info.Holder()); + CHECK(info.Data()->Equals(v8::String::New("data"))); + return v8::Integer::New(17); +} + +THREADED_TEST(DirectCall) { + v8::HandleScope scope; + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + obj->SetAccessor(v8_str("xxx"), + CheckAccessorArgsCorrect, + NULL, + v8::String::New("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")); + for (int i = 0; i < 10; i++) { + Local<Value> result = scr->Run(); + CHECK(!result.IsEmpty()); + CHECK_EQ(17, result->Int32Value()); + } +} + +static v8::Handle<Value> EmptyGetter(Local<String> name, + const AccessorInfo& info) { + CheckAccessorArgsCorrect(name, info); + ApiTestFuzzer::Fuzz(); + CheckAccessorArgsCorrect(name, info); + return v8::Handle<v8::Value>(); +} + +THREADED_TEST(EmptyResult) { + v8::HandleScope scope; + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("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")); + for (int i = 0; i < 10; i++) { + Local<Value> result = scr->Run(); + CHECK(result == v8::Undefined()); + } +} + + +THREADED_TEST(NoReuseRegress) { + // Check that the IC generated for the one test doesn't get reused + // for the other. + v8::HandleScope scope; + { + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("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")); + for (int i = 0; i < 2; i++) { + Local<Value> result = scr->Run(); + CHECK(result == v8::Undefined()); + } + } + { + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + obj->SetAccessor(v8_str("xxx"), + CheckAccessorArgsCorrect, + NULL, + v8::String::New("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")); + for (int i = 0; i < 10; i++) { + Local<Value> result = scr->Run(); + CHECK(!result.IsEmpty()); + CHECK_EQ(17, result->Int32Value()); + } + } +} + +static v8::Handle<Value> ThrowingGetAccessor(Local<String> name, + const AccessorInfo& info) { + ApiTestFuzzer::Fuzz(); + return v8::ThrowException(v8_str("g")); +} + + +static void ThrowingSetAccessor(Local<String> name, + Local<Value> value, + const AccessorInfo& info) { + v8::ThrowException(value); +} + + +THREADED_TEST(Regress1054726) { + v8::HandleScope scope; + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + obj->SetAccessor(v8_str("x"), + ThrowingGetAccessor, + ThrowingSetAccessor, + Local<Value>()); + + LocalContext env; + env->Global()->Set(v8_str("obj"), obj->NewInstance()); + + // Use the throwing property setter/getter in a loop to force + // the accessor ICs to be initialized. + v8::Handle<Value> result; + result = Script::Compile(v8_str( + "var result = '';" + "for (var i = 0; i < 5; i++) {" + " try { obj.x; } catch (e) { result += e; }" + "}; result"))->Run(); + CHECK_EQ(v8_str("ggggg"), result); + + result = Script::Compile(String::New( + "var result = '';" + "for (var i = 0; i < 5; i++) {" + " try { obj.x = i; } catch (e) { result += e; }" + "}; result"))->Run(); + CHECK_EQ(v8_str("01234"), result); +} + + +static v8::Handle<Value> AllocGetter(Local<String> name, + const AccessorInfo& info) { + ApiTestFuzzer::Fuzz(); + return v8::Array::New(1000); +} + + +THREADED_TEST(Gc) { + v8::HandleScope scope; + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + obj->SetAccessor(v8_str("xxx"), AllocGetter); + LocalContext env; + env->Global()->Set(v8_str("obj"), obj->NewInstance()); + Script::Compile(String::New( + "var last = [];" + "for (var i = 0; i < 2048; i++) {" + " var result = obj.xxx;" + " result[0] = last;" + " last = result;" + "}"))->Run(); +} + + +static v8::Handle<Value> StackCheck(Local<String> name, + const AccessorInfo& info) { + i::StackFrameIterator iter; + for (int i = 0; !iter.done(); i++) { + i::StackFrame* frame = iter.frame(); + CHECK(i != 0 || (frame->type() == i::StackFrame::EXIT)); + CHECK(frame->code()->IsCode()); + i::Address pc = frame->pc(); + i::Code* code = frame->code(); + CHECK(code->contains(pc)); + iter.Advance(); + } + return v8::Undefined(); +} + + +THREADED_TEST(StackIteration) { + v8::HandleScope scope; + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + i::StringStream::ClearMentionedObjectCache(); + obj->SetAccessor(v8_str("xxx"), StackCheck); + LocalContext env; + env->Global()->Set(v8_str("obj"), obj->NewInstance()); + Script::Compile(String::New( + "function foo() {" + " return obj.xxx;" + "}" + "for (var i = 0; i < 100; i++) {" + " foo();" + "}"))->Run(); +} + + +static v8::Handle<Value> AllocateHandles(Local<String> name, + const AccessorInfo& info) { + for (int i = 0; i < i::kHandleBlockSize + 1; i++) { + v8::Local<v8::Value>::New(name); + } + return v8::Integer::New(100); +} + + +THREADED_TEST(HandleScopeSegment) { + // Check that we can return values past popping of handle scope + // segments. + v8::HandleScope scope; + v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); + obj->SetAccessor(v8_str("xxx"), AllocateHandles); + LocalContext env; + env->Global()->Set(v8_str("obj"), obj->NewInstance()); + v8::Handle<v8::Value> result = Script::Compile(String::New( + "var result;" + "for (var i = 0; i < 4; i++)" + " result = obj.xxx;" + "result;"))->Run(); + CHECK_EQ(100, result->Int32Value()); +} diff --git a/deps/v8/test/cctest/test-alloc.cc b/deps/v8/test/cctest/test-alloc.cc index 1235b13b2..7921d2abe 100644 --- a/deps/v8/test/cctest/test-alloc.cc +++ b/deps/v8/test/cctest/test-alloc.cc @@ -195,9 +195,9 @@ TEST(CodeRange) { Pseudorandom() % 5000 + 1; size_t allocated = 0; void* base = CodeRange::AllocateRawMemory(requested, &allocated); - blocks.Add(Block(base, allocated)); - current_allocated += allocated; - total_allocated += allocated; + blocks.Add(Block(base, static_cast<int>(allocated))); + current_allocated += static_cast<int>(allocated); + total_allocated += static_cast<int>(allocated); } else { // Free a block. int index = Pseudorandom() % blocks.length(); diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index 1d4b2c34c..6791685e1 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -38,6 +38,8 @@ #include "utils.h" #include "cctest.h" +static const bool kLogThreading = false; + static bool IsNaN(double x) { #ifdef WIN32 return _isnan(x); @@ -58,131 +60,6 @@ using ::v8::Extension; namespace i = ::v8::internal; -static Local<Value> v8_num(double x) { - return v8::Number::New(x); -} - - -static Local<String> v8_str(const char* x) { - return String::New(x); -} - - -static Local<Script> v8_compile(const char* x) { - return Script::Compile(v8_str(x)); -} - - -// A LocalContext holds a reference to a v8::Context. -class LocalContext { - public: - LocalContext(v8::ExtensionConfiguration* extensions = 0, - v8::Handle<ObjectTemplate> global_template = - v8::Handle<ObjectTemplate>(), - v8::Handle<Value> global_object = v8::Handle<Value>()) - : context_(Context::New(extensions, global_template, global_object)) { - context_->Enter(); - } - - virtual ~LocalContext() { - context_->Exit(); - context_.Dispose(); - } - - Context* operator->() { return *context_; } - Context* operator*() { return *context_; } - Local<Context> local() { return Local<Context>::New(context_); } - bool IsReady() { return !context_.IsEmpty(); } - - private: - v8::Persistent<Context> context_; -}; - - -// Switches between all the Api tests using the threading support. -// In order to get a surprising but repeatable pattern of thread -// switching it has extra semaphores to control the order in which -// the tests alternate, not relying solely on the big V8 lock. -// -// A test is augmented with calls to ApiTestFuzzer::Fuzz() in its -// callbacks. This will have no effect when we are not running the -// thread fuzzing test. In the thread fuzzing test it will -// pseudorandomly select a successor thread and switch execution -// to that thread, suspending the current test. -class ApiTestFuzzer: public v8::internal::Thread { - public: - void CallTest(); - explicit ApiTestFuzzer(int num) - : test_number_(num), - gate_(v8::internal::OS::CreateSemaphore(0)), - active_(true) { - } - ~ApiTestFuzzer() { delete gate_; } - - // The ApiTestFuzzer is also a Thread, so it has a Run method. - virtual void Run(); - - enum PartOfTest { FIRST_PART, SECOND_PART }; - - static void Setup(PartOfTest part); - static void RunAllTests(); - static void TearDown(); - // This method switches threads if we are running the Threading test. - // Otherwise it does nothing. - static void Fuzz(); - private: - static bool fuzzing_; - static int tests_being_run_; - static int current_; - static int active_tests_; - static bool NextThread(); - int test_number_; - v8::internal::Semaphore* gate_; - bool active_; - void ContextSwitch(); - static int GetNextTestNumber(); - static v8::internal::Semaphore* all_tests_done_; -}; - - -#define THREADED_TEST(Name) \ - static void Test##Name(); \ - RegisterThreadedTest register_##Name(Test##Name); \ - /* */ TEST(Name) - - -class RegisterThreadedTest { - public: - explicit RegisterThreadedTest(CcTest::TestFunction* callback) - : fuzzer_(NULL), callback_(callback) { - prev_ = first_; - first_ = this; - count_++; - } - static int count() { return count_; } - static RegisterThreadedTest* nth(int i) { - CHECK(i < count()); - RegisterThreadedTest* current = first_; - while (i > 0) { - i--; - current = current->prev_; - } - return current; - } - CcTest::TestFunction* callback() { return callback_; } - ApiTestFuzzer* fuzzer_; - - private: - static RegisterThreadedTest* first_; - static int count_; - CcTest::TestFunction* callback_; - RegisterThreadedTest* prev_; -}; - - -RegisterThreadedTest *RegisterThreadedTest::first_ = NULL; -int RegisterThreadedTest::count_ = 0; - static int signature_callback_count; static v8::Handle<Value> IncrementingSignatureCallback( @@ -231,11 +108,6 @@ THREADED_TEST(Handles) { } -// Helper function that compiles and runs the source. -static Local<Value> CompileRun(const char* source) { - return Script::Compile(String::New(source))->Run(); -} - THREADED_TEST(ReceiverSignature) { v8::HandleScope scope; LocalContext env; @@ -382,9 +254,9 @@ THREADED_TEST(Script) { static uint16_t* AsciiToTwoByteString(const char* source) { - size_t array_length = strlen(source) + 1; + int array_length = i::StrLength(source) + 1; uint16_t* converted = i::NewArray<uint16_t>(array_length); - for (size_t i = 0; i < array_length; i++) converted[i] = source[i]; + for (int i = 0; i < array_length; i++) converted[i] = source[i]; return converted; } @@ -720,27 +592,6 @@ THREADED_TEST(FindInstanceInPrototypeChain) { } -static v8::Handle<Value> handle_property(Local<String> name, - const AccessorInfo&) { - ApiTestFuzzer::Fuzz(); - return v8_num(900); -} - - -THREADED_TEST(PropertyHandler) { - v8::HandleScope scope; - Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); - fun_templ->InstanceTemplate()->SetAccessor(v8_str("foo"), handle_property); - LocalContext env; - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("Fun"), fun); - Local<Script> getter = v8_compile("var obj = new Fun(); obj.foo;"); - CHECK_EQ(900, getter->Run()->Int32Value()); - Local<Script> setter = v8_compile("obj.foo = 901;"); - CHECK_EQ(901, setter->Run()->Int32Value()); -} - - THREADED_TEST(TinyInteger) { v8::HandleScope scope; LocalContext env; @@ -907,49 +758,6 @@ THREADED_TEST(GlobalPrototype) { } -static v8::Handle<Value> GetIntValue(Local<String> property, - const AccessorInfo& info) { - ApiTestFuzzer::Fuzz(); - int* value = - static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); - return v8_num(*value); -} - -static void SetIntValue(Local<String> property, - Local<Value> value, - const AccessorInfo& info) { - int* field = - static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); - *field = value->Int32Value(); -} - -int foo, bar, baz; - -THREADED_TEST(GlobalVariableAccess) { - foo = 0; - bar = -4; - baz = 10; - v8::HandleScope scope; - 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)); - LocalContext env(0, templ->InstanceTemplate()); - v8_compile("foo = (++bar) + baz")->Run(); - CHECK_EQ(bar, -3); - CHECK_EQ(foo, 7); -} - - THREADED_TEST(ObjectTemplate) { v8::HandleScope scope; Local<ObjectTemplate> templ1 = ObjectTemplate::New(); @@ -1365,50 +1173,6 @@ THREADED_TEST(CallbackExceptionRegression) { } -static v8::Handle<Value> ThrowingGetAccessor(Local<String> name, - const AccessorInfo& info) { - ApiTestFuzzer::Fuzz(); - return v8::ThrowException(v8_str("g")); -} - - -static void ThrowingSetAccessor(Local<String> name, - Local<Value> value, - const AccessorInfo& info) { - v8::ThrowException(value); -} - - -THREADED_TEST(Regress1054726) { - v8::HandleScope scope; - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); - obj->SetAccessor(v8_str("x"), - ThrowingGetAccessor, - ThrowingSetAccessor, - Local<Value>()); - - LocalContext env; - env->Global()->Set(v8_str("obj"), obj->NewInstance()); - - // Use the throwing property setter/getter in a loop to force - // the accessor ICs to be initialized. - v8::Handle<Value> result; - result = Script::Compile(v8_str( - "var result = '';" - "for (var i = 0; i < 5; i++) {" - " try { obj.x; } catch (e) { result += e; }" - "}; result"))->Run(); - CHECK_EQ(v8_str("ggggg"), result); - - result = Script::Compile(String::New( - "var result = '';" - "for (var i = 0; i < 5; i++) {" - " try { obj.x = i; } catch (e) { result += e; }" - "}; result"))->Run(); - CHECK_EQ(v8_str("01234"), result); -} - - THREADED_TEST(FunctionPrototype) { v8::HandleScope scope; Local<v8::FunctionTemplate> Foo = v8::FunctionTemplate::New(); @@ -1580,17 +1344,10 @@ THREADED_TEST(HiddenProperties) { } +static bool interceptor_for_hidden_properties_called; static v8::Handle<Value> InterceptorForHiddenProperties( Local<String> name, const AccessorInfo& info) { - // Make sure objects move. - bool saved_always_compact = i::FLAG_always_compact; - if (!i::FLAG_never_compact) { - i::FLAG_always_compact = true; - } - // The whole goal of this interceptor is to cause a GC during local property - // lookup. - i::Heap::CollectAllGarbage(false); - i::FLAG_always_compact = saved_always_compact; + interceptor_for_hidden_properties_called = true; return v8::Handle<Value>(); } @@ -1599,6 +1356,8 @@ THREADED_TEST(HiddenPropertiesWithInterceptors) { v8::HandleScope scope; LocalContext context; + 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. @@ -1609,6 +1368,7 @@ THREADED_TEST(HiddenPropertiesWithInterceptors) { Local<v8::Object> obj = function->NewInstance(); CHECK(obj->SetHiddenValue(key, v8::Integer::New(2302))); CHECK_EQ(2302, obj->GetHiddenValue(key)->Int32Value()); + CHECK(!interceptor_for_hidden_properties_called); } @@ -3157,6 +2917,58 @@ THREADED_TEST(WeakReference) { } +static bool in_scavenge = false; +static int last = -1; + +static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { + CHECK_EQ(-1, last); + last = 0; + obj.Dispose(); + obj.Clear(); + in_scavenge = true; + i::Heap::PerformScavenge(); + in_scavenge = false; + *(reinterpret_cast<bool*>(data)) = true; +} + +static void CheckIsNotInvokedInScavenge(v8::Persistent<v8::Value> obj, + void* data) { + CHECK_EQ(0, last); + last = 1; + *(reinterpret_cast<bool*>(data)) = in_scavenge; + obj.Dispose(); + obj.Clear(); +} + +THREADED_TEST(NoWeakRefCallbacksInScavenge) { + // Test verifies that scavenge cannot invoke WeakReferenceCallbacks. + // Calling callbacks from scavenges is unsafe as objects held by those + // handlers might have become strongly reachable, but scavenge doesn't + // check that. + v8::Persistent<Context> context = Context::New(); + Context::Scope context_scope(context); + + v8::Persistent<v8::Object> object_a; + v8::Persistent<v8::Object> object_b; + + { + v8::HandleScope handle_scope; + object_b = v8::Persistent<v8::Object>::New(v8::Object::New()); + object_a = v8::Persistent<v8::Object>::New(v8::Object::New()); + } + + bool object_a_disposed = false; + object_a.MakeWeak(&object_a_disposed, &ForceScavenge); + bool released_in_scavenge = false; + object_b.MakeWeak(&released_in_scavenge, &CheckIsNotInvokedInScavenge); + + while (!object_a_disposed) { + i::Heap::CollectAllGarbage(false); + } + CHECK(!released_in_scavenge); +} + + v8::Handle<Function> args_fun; @@ -3184,53 +2996,6 @@ THREADED_TEST(Arguments) { } -static int x_register = 0; -static v8::Handle<v8::Object> x_receiver; -static v8::Handle<v8::Object> x_holder; - - -static v8::Handle<Value> XGetter(Local<String> name, const AccessorInfo& info) { - ApiTestFuzzer::Fuzz(); - CHECK_EQ(x_receiver, info.This()); - CHECK_EQ(x_holder, info.Holder()); - return v8_num(x_register); -} - - -static void XSetter(Local<String> name, - Local<Value> value, - const AccessorInfo& info) { - CHECK_EQ(x_holder, info.This()); - CHECK_EQ(x_holder, info.Holder()); - x_register = value->Int32Value(); -} - - -THREADED_TEST(AccessorIC) { - v8::HandleScope scope; - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); - obj->SetAccessor(v8_str("x"), XGetter, XSetter); - LocalContext context; - x_holder = obj->NewInstance(); - context->Global()->Set(v8_str("holder"), x_holder); - x_receiver = v8::Object::New(); - context->Global()->Set(v8_str("obj"), x_receiver); - v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(CompileRun( - "obj.__proto__ = holder;" - "var result = [];" - "for (var i = 0; i < 10; i++) {" - " holder.x = i;" - " result.push(obj.x);" - "}" - "result")); - CHECK_EQ(10, array->Length()); - for (int i = 0; i < 10; i++) { - v8::Handle<Value> entry = array->Get(v8::Integer::New(i)); - CHECK_EQ(v8::Integer::New(i), entry); - } -} - - static v8::Handle<Value> NoBlockGetterX(Local<String> name, const AccessorInfo&) { return v8::Handle<Value>(); @@ -6094,13 +5859,17 @@ void ApiTestFuzzer::Fuzz() { // not start immediately. bool ApiTestFuzzer::NextThread() { int test_position = GetNextTestNumber(); - int test_number = RegisterThreadedTest::nth(current_)->fuzzer_->test_number_; + const char* test_name = RegisterThreadedTest::nth(current_)->name(); if (test_position == current_) { - printf("Stay with %d\n", test_number); + if (kLogThreading) + printf("Stay with %s\n", test_name); return false; } - printf("Switch from %d to %d\n", - current_ < 0 ? 0 : test_number, test_position < 0 ? 0 : test_number); + if (kLogThreading) { + printf("Switch from %s to %s\n", + test_name, + RegisterThreadedTest::nth(test_position)->name()); + } current_ = test_position; RegisterThreadedTest::nth(current_)->fuzzer_->gate_->Signal(); return true; @@ -6209,9 +5978,11 @@ TEST(Threading2) { void ApiTestFuzzer::CallTest() { - printf("Start test %d\n", test_number_); + if (kLogThreading) + printf("Start test %d\n", test_number_); CallTestNumber(test_number_); - printf("End test %d\n", test_number_); + if (kLogThreading) + printf("End test %d\n", test_number_); } @@ -6455,6 +6226,31 @@ THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { i::Heap::CollectAllGarbage(false); } +void DisposingCallback(v8::Persistent<v8::Value> handle, void*) { + handle.Dispose(); +} + +void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) { + v8::HandleScope scope; + v8::Persistent<v8::Object>::New(v8::Object::New()); +} + + +THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { + LocalContext context; + + v8::Persistent<v8::Object> handle1, handle2, handle3; + { + v8::HandleScope scope; + handle3 = v8::Persistent<v8::Object>::New(v8::Object::New()); + handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); + handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); + } + handle2.MakeWeak(NULL, DisposingCallback); + handle3.MakeWeak(NULL, HandleCreatingCallback); + i::Heap::CollectAllGarbage(false); +} + THREADED_TEST(CheckForCrossContextObjectLiterals) { v8::V8::Initialize(); @@ -6699,53 +6495,6 @@ THREADED_TEST(PropertyEnumeration) { } -static v8::Handle<Value> AccessorProhibitsOverwritingGetter( - Local<String> name, - const AccessorInfo& info) { - ApiTestFuzzer::Fuzz(); - return v8::True(); -} - - -THREADED_TEST(AccessorProhibitsOverwriting) { - v8::HandleScope scope; - LocalContext context; - Local<ObjectTemplate> templ = ObjectTemplate::New(); - templ->SetAccessor(v8_str("x"), - AccessorProhibitsOverwritingGetter, - 0, - v8::Handle<Value>(), - v8::PROHIBITS_OVERWRITING, - v8::ReadOnly); - Local<v8::Object> instance = templ->NewInstance(); - context->Global()->Set(v8_str("obj"), instance); - Local<Value> value = CompileRun( - "obj.__defineGetter__('x', function() { return false; });" - "obj.x"); - CHECK(value->BooleanValue()); - value = CompileRun( - "var setter_called = false;" - "obj.__defineSetter__('x', function() { setter_called = true; });" - "obj.x = 42;" - "setter_called"); - CHECK(!value->BooleanValue()); - value = CompileRun( - "obj2 = {};" - "obj2.__proto__ = obj;" - "obj2.__defineGetter__('x', function() { return false; });" - "obj2.x"); - CHECK(value->BooleanValue()); - value = CompileRun( - "var setter_called = false;" - "obj2 = {};" - "obj2.__proto__ = obj;" - "obj2.__defineSetter__('x', function() { setter_called = true; });" - "obj2.x = 42;" - "setter_called"); - CHECK(!value->BooleanValue()); -} - - static bool NamedSetAccessBlocker(Local<v8::Object> obj, Local<Value> name, v8::AccessType type, @@ -6921,7 +6670,8 @@ TEST(PreCompile) { // a workaround for now to make this test not fail. v8::V8::Initialize(); const char *script = "function foo(a) { return a+1; }"; - v8::ScriptData *sd = v8::ScriptData::PreCompile(script, strlen(script)); + v8::ScriptData *sd = + v8::ScriptData::PreCompile(script, i::StrLength(script)); CHECK_NE(sd->Length(), 0); CHECK_NE(sd->Data(), NULL); delete sd; @@ -7317,9 +7067,10 @@ THREADED_TEST(MorphCompositeStringTest) { v8::HandleScope scope; LocalContext env; AsciiVectorResource ascii_resource( - i::Vector<const char>(c_string, strlen(c_string))); + i::Vector<const char>(c_string, i::StrLength(c_string))); UC16VectorResource uc16_resource( - i::Vector<const uint16_t>(two_byte_string, strlen(c_string))); + i::Vector<const uint16_t>(two_byte_string, + i::StrLength(c_string))); Local<String> lhs(v8::Utils::ToLocal( i::Factory::NewExternalStringFromAscii(&ascii_resource))); @@ -7377,7 +7128,8 @@ TEST(CompileExternalTwoByteSource) { 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, strlen(ascii_sources[i]))); + i::Vector<const uint16_t>(two_byte_string, + i::StrLength(ascii_sources[i]))); v8::Local<v8::String> source = v8::String::NewExternal(&uc16_resource); v8::Script::Compile(source); } @@ -7863,18 +7615,18 @@ THREADED_TEST(Regress16276) { THREADED_TEST(PixelArray) { v8::HandleScope scope; LocalContext context; - const int kElementCount = 40; + const int kElementCount = 260; uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); i::Handle<i::PixelArray> pixels = i::Factory::NewPixelArray(kElementCount, pixel_data); i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. for (int i = 0; i < kElementCount; i++) { - pixels->set(i, i); + pixels->set(i, i % 256); } i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. for (int i = 0; i < kElementCount; i++) { - CHECK_EQ(i, pixels->get(i)); - CHECK_EQ(i, pixel_data[i]); + CHECK_EQ(i % 256, pixels->get(i)); + CHECK_EQ(i % 256, pixel_data[i]); } v8::Handle<v8::Object> obj = v8::Object::New(); @@ -8038,6 +7790,15 @@ THREADED_TEST(PixelArray) { result = CompileRun("pixels[1] = 23;"); CHECK_EQ(23, result->Int32Value()); + // Test for index greater than 255. Regression test for: + // http://code.google.com/p/chromium/issues/detail?id=26337. + result = CompileRun("pixels[256] = 255;"); + CHECK_EQ(255, result->Int32Value()); + result = CompileRun("var i = 0;" + "for (var j = 0; j < 8; j++) { i = pixels[256]; }" + "i"); + CHECK_EQ(255, result->Int32Value()); + free(pixel_data); } @@ -8489,11 +8250,11 @@ THREADED_TEST(GetHeapStatistics) { v8::HandleScope scope; LocalContext c1; v8::HeapStatistics heap_statistics; - CHECK_EQ(heap_statistics.total_heap_size(), 0); - CHECK_EQ(heap_statistics.used_heap_size(), 0); + CHECK_EQ(static_cast<int>(heap_statistics.total_heap_size()), 0); + CHECK_EQ(static_cast<int>(heap_statistics.used_heap_size()), 0); v8::V8::GetHeapStatistics(&heap_statistics); - CHECK_NE(heap_statistics.total_heap_size(), 0); - CHECK_NE(heap_statistics.used_heap_size(), 0); + CHECK_NE(static_cast<int>(heap_statistics.total_heap_size()), 0); + CHECK_NE(static_cast<int>(heap_statistics.used_heap_size()), 0); } @@ -8610,3 +8371,41 @@ THREADED_TEST(QuietSignalingNaNs) { } } } + + +static v8::Handle<Value> SpaghettiIncident(const v8::Arguments& args) { + v8::HandleScope scope; + v8::TryCatch tc; + v8::Handle<v8::String> str = args[0]->ToString(); + if (tc.HasCaught()) + return tc.ReThrow(); + return v8::Undefined(); +} + + +// Test that an exception can be propagated down through a spaghetti +// stack using ReThrow. +THREADED_TEST(SpaghettiStackReThrow) { + v8::HandleScope scope; + LocalContext context; + context->Global()->Set( + v8::String::New("s"), + v8::FunctionTemplate::New(SpaghettiIncident)->GetFunction()); + v8::TryCatch try_catch; + CompileRun( + "var i = 0;" + "var o = {" + " toString: function () {" + " if (i == 10) {" + " throw 'Hey!';" + " } else {" + " i++;" + " return s(o);" + " }" + " }" + "};" + "s(o);"); + CHECK(try_catch.HasCaught()); + v8::String::Utf8Value value(try_catch.Exception()); + CHECK_EQ(0, strcmp(*value, "Hey!")); +} diff --git a/deps/v8/test/cctest/test-assembler-ia32.cc b/deps/v8/test/cctest/test-assembler-ia32.cc index 9ad7c76f1..76eb6bb3f 100644 --- a/deps/v8/test/cctest/test-assembler-ia32.cc +++ b/deps/v8/test/cctest/test-assembler-ia32.cc @@ -173,8 +173,8 @@ TEST(AssemblerIa323) { v8::internal::byte buffer[256]; Assembler assm(buffer, sizeof buffer); - CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2)); - { CpuFeatures::Scope fscope(CpuFeatures::SSE2); + CHECK(CpuFeatures::IsSupported(SSE2)); + { CpuFeatures::Scope fscope(SSE2); __ cvttss2si(eax, Operand(esp, 4)); __ ret(0); } @@ -207,8 +207,8 @@ TEST(AssemblerIa324) { v8::internal::byte buffer[256]; Assembler assm(buffer, sizeof buffer); - CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2)); - CpuFeatures::Scope fscope(CpuFeatures::SSE2); + CHECK(CpuFeatures::IsSupported(SSE2)); + CpuFeatures::Scope fscope(SSE2); __ cvttsd2si(eax, Operand(esp, 4)); __ ret(0); @@ -260,8 +260,8 @@ typedef double (*F5)(double x, double y); TEST(AssemblerIa326) { InitializeVM(); v8::HandleScope scope; - CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2)); - CpuFeatures::Scope fscope(CpuFeatures::SSE2); + CHECK(CpuFeatures::IsSupported(SSE2)); + CpuFeatures::Scope fscope(SSE2); v8::internal::byte buffer[256]; Assembler assm(buffer, sizeof buffer); @@ -305,8 +305,8 @@ typedef double (*F6)(int x); TEST(AssemblerIa328) { InitializeVM(); v8::HandleScope scope; - CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2)); - CpuFeatures::Scope fscope(CpuFeatures::SSE2); + CHECK(CpuFeatures::IsSupported(SSE2)); + CpuFeatures::Scope fscope(SSE2); v8::internal::byte buffer[256]; Assembler assm(buffer, sizeof buffer); __ mov(eax, Operand(esp, 4)); diff --git a/deps/v8/test/cctest/test-assembler-x64.cc b/deps/v8/test/cctest/test-assembler-x64.cc index 81aa973db..f100b7348 100644 --- a/deps/v8/test/cctest/test-assembler-x64.cc +++ b/deps/v8/test/cctest/test-assembler-x64.cc @@ -86,7 +86,7 @@ TEST(AssemblerX64ReturnOperation) { &actual_size, true)); CHECK(buffer); - Assembler assm(buffer, actual_size); + Assembler assm(buffer, static_cast<int>(actual_size)); // Assemble a simple function that copies argument 2 and returns it. __ movq(rax, arg2); @@ -107,7 +107,7 @@ TEST(AssemblerX64StackOperations) { &actual_size, true)); CHECK(buffer); - Assembler assm(buffer, actual_size); + Assembler assm(buffer, static_cast<int>(actual_size)); // Assemble a simple function that copies argument 2 and returns it. // We compile without stack frame pointers, so the gdb debugger shows @@ -138,7 +138,7 @@ TEST(AssemblerX64ArithmeticOperations) { &actual_size, true)); CHECK(buffer); - Assembler assm(buffer, actual_size); + Assembler assm(buffer, static_cast<int>(actual_size)); // Assemble a simple function that adds arguments returning the sum. __ movq(rax, arg2); @@ -159,7 +159,7 @@ TEST(AssemblerX64ImulOperation) { &actual_size, true)); CHECK(buffer); - Assembler assm(buffer, actual_size); + Assembler assm(buffer, static_cast<int>(actual_size)); // Assemble a simple function that multiplies arguments returning the high // word. @@ -186,7 +186,7 @@ TEST(AssemblerX64MemoryOperands) { &actual_size, true)); CHECK(buffer); - Assembler assm(buffer, actual_size); + Assembler assm(buffer, static_cast<int>(actual_size)); // Assemble a simple function that copies argument 2 and returns it. __ push(rbp); @@ -219,7 +219,7 @@ TEST(AssemblerX64ControlFlow) { &actual_size, true)); CHECK(buffer); - Assembler assm(buffer, actual_size); + Assembler assm(buffer, static_cast<int>(actual_size)); // Assemble a simple function that copies argument 1 and returns it. __ push(rbp); @@ -247,7 +247,7 @@ TEST(AssemblerX64LoopImmediates) { &actual_size, true)); CHECK(buffer); - Assembler assm(buffer, actual_size); + Assembler assm(buffer, static_cast<int>(actual_size)); // Assemble two loops using rax as counter, and verify the ending counts. Label Fail; __ movq(rax, Immediate(-3)); diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc index 4ffcee3db..d938174e7 100644 --- a/deps/v8/test/cctest/test-debug.cc +++ b/deps/v8/test/cctest/test-debug.cc @@ -53,7 +53,7 @@ using ::v8::internal::StepIn; // From StepAction enum using ::v8::internal::StepNext; // From StepAction enum using ::v8::internal::StepOut; // From StepAction enum using ::v8::internal::Vector; - +using ::v8::internal::StrLength; // Size of temp buffer for formatting small strings. #define SMALL_STRING_BUFFER_SIZE 80 @@ -178,12 +178,6 @@ static v8::Local<v8::Function> CompileFunction(const char* source, } -// Helper function that compiles and runs the source. -static v8::Local<v8::Value> CompileRun(const char* source) { - return v8::Script::Compile(v8::String::New(source))->Run(); -} - - // Is there any debug info for the function? static bool HasDebugInfo(v8::Handle<v8::Function> fun) { Handle<v8::internal::JSFunction> f = v8::Utils::OpenHandle(*fun); @@ -806,14 +800,14 @@ static void DebugEventStepSequence(v8::DebugEvent event, if (event == v8::Break || event == v8::Exception) { // Check that the current function is the expected. CHECK(break_point_hit_count < - static_cast<int>(strlen(expected_step_sequence))); + StrLength(expected_step_sequence)); const int argc = 1; v8::Handle<v8::Value> argv[argc] = { exec_state }; v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, argc, argv); CHECK(result->IsString()); v8::String::AsciiValue function_name(result->ToString()); - CHECK_EQ(1, strlen(*function_name)); + CHECK_EQ(1, StrLength(*function_name)); CHECK_EQ((*function_name)[0], expected_step_sequence[break_point_hit_count]); @@ -872,6 +866,26 @@ static void DebugEventBreak(v8::DebugEvent event, } +// Debug event handler which re-issues a debug break until a limit has been +// reached. +int max_break_point_hit_count = 0; +static void DebugEventBreakMax(v8::DebugEvent event, + v8::Handle<v8::Object> exec_state, + v8::Handle<v8::Object> event_data, + v8::Handle<v8::Value> data) { + // When hitting a debug event listener there must be a break set. + CHECK_NE(v8::internal::Debug::break_id(), 0); + + if (event == v8::Break && break_point_hit_count < max_break_point_hit_count) { + // Count the number of breaks. + break_point_hit_count++; + + // Set the break flag again to come back here as soon as possible. + v8::Debug::DebugBreak(); + } +} + + // --- M e s s a g e C a l l b a c k @@ -1917,7 +1931,7 @@ TEST(ScriptBreakPointLine) { // Chesk that a break point was hit when the script was run. CHECK_EQ(1, break_point_hit_count); - CHECK_EQ(0, strlen(last_function_hit)); + CHECK_EQ(0, StrLength(last_function_hit)); // Call f and check that the script break point. f->Call(env->Global(), 0, NULL); @@ -1953,7 +1967,7 @@ TEST(ScriptBreakPointLine) { break_point_hit_count = 0; v8::Script::Compile(script, &origin)->Run(); CHECK_EQ(2, break_point_hit_count); - CHECK_EQ(0, strlen(last_function_hit)); + 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); @@ -1962,7 +1976,7 @@ TEST(ScriptBreakPointLine) { break_point_hit_count = 0; v8::Script::Compile(script, &origin)->Run(); CHECK_EQ(3, break_point_hit_count); - CHECK_EQ(0, strlen(last_function_hit)); + CHECK_EQ(0, StrLength(last_function_hit)); // Clear the last break points, and reload the script which should not hit any // break points. @@ -2478,21 +2492,24 @@ TEST(StepInOutSimple) { break_point_hit_count = 0; expected_step_sequence = "abcbaca"; a->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Step through invocation of a with step next. step_action = StepNext; break_point_hit_count = 0; expected_step_sequence = "aaa"; a->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Step through invocation of a with step out. step_action = StepOut; break_point_hit_count = 0; expected_step_sequence = "a"; a->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Get rid of the debug event listener. v8::Debug::SetDebugEventListener(NULL); @@ -2525,21 +2542,24 @@ TEST(StepInOutTree) { break_point_hit_count = 0; expected_step_sequence = "adacadabcbadacada"; a->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Step through invocation of a with step next. step_action = StepNext; break_point_hit_count = 0; expected_step_sequence = "aaaa"; a->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Step through invocation of a with step out. step_action = StepOut; break_point_hit_count = 0; expected_step_sequence = "a"; a->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Get rid of the debug event listener. v8::Debug::SetDebugEventListener(NULL); @@ -2571,7 +2591,8 @@ TEST(StepInOutBranch) { break_point_hit_count = 0; expected_step_sequence = "abaca"; a->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Get rid of the debug event listener. v8::Debug::SetDebugEventListener(NULL); @@ -2707,6 +2728,37 @@ TEST(DebugStepFunctionCall) { } +// Tests that breakpoint will be hit if it's set in script. +TEST(PauseInScript) { + v8::HandleScope scope; + DebugLocalContext env; + env.ExposeDebug(); + + // Register a debug event listener which counts. + v8::Debug::SetDebugEventListener(DebugEventCounter); + + // Create a script that returns a function. + const char* src = "(function (evt) {})"; + const char* script_name = "StepInHandlerTest"; + + // Set breakpoint in the script. + SetScriptBreakPointByNameFromJS(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::Local<v8::Value> r = script->Run(); + + CHECK(r->IsFunction()); + CHECK_EQ(1, break_point_hit_count); + + // Get rid of the debug event listener. + v8::Debug::SetDebugEventListener(NULL); + CheckDebuggerUnloaded(); +} + + // Test break on exceptions. For each exception break combination the number // of debug event exception callbacks and message callbacks are collected. The // number of debug event exception callbacks are used to check that the @@ -2938,7 +2990,8 @@ TEST(StepWithException) { break_point_hit_count = 0; expected_step_sequence = "aa"; a->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Step through invocation of b + c. v8::Local<v8::Function> b = CompileFunction(&env, src, "b"); @@ -2947,7 +3000,8 @@ TEST(StepWithException) { break_point_hit_count = 0; expected_step_sequence = "bcc"; b->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Step through invocation of d + e. v8::Local<v8::Function> d = CompileFunction(&env, src, "d"); @@ -2957,7 +3011,8 @@ TEST(StepWithException) { break_point_hit_count = 0; expected_step_sequence = "dded"; d->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Step through invocation of d + e now with break on caught exceptions. ChangeBreakOnException(true, true); @@ -2965,7 +3020,8 @@ TEST(StepWithException) { break_point_hit_count = 0; expected_step_sequence = "ddeed"; d->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Step through invocation of f + g + h. v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); @@ -2975,7 +3031,8 @@ TEST(StepWithException) { break_point_hit_count = 0; expected_step_sequence = "ffghf"; f->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Step through invocation of f + g + h now with break on caught exceptions. ChangeBreakOnException(true, true); @@ -2983,7 +3040,8 @@ TEST(StepWithException) { break_point_hit_count = 0; expected_step_sequence = "ffghhf"; f->Call(env->Global(), 0, NULL); - CHECK_EQ(strlen(expected_step_sequence), break_point_hit_count); + CHECK_EQ(StrLength(expected_step_sequence), + break_point_hit_count); // Get rid of the debug event listener. v8::Debug::SetDebugEventListener(NULL); @@ -3425,6 +3483,75 @@ TEST(NativeGetterThrowingErrorPropertyMirror) { } +// Test that hidden properties object is not returned as an unnamed property +// among regular properties. +// See http://crbug.com/26491 +TEST(NoHiddenProperties) { + // Create a V8 environment with debug access. + v8::HandleScope scope; + DebugLocalContext env; + 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::Local<v8::Object> obj = v8::Local<v8::Object>::Cast( + env->Global()->Get(v8::String::New("obj"))); + // Set a hidden property on the object. + obj->SetHiddenValue(v8::String::New("v8::test-debug::a"), + v8::Int32::New(11)); + + // Get mirror for the object with property getter. + CompileRun("var obj_mirror = debug.MakeMirror(obj);"); + CHECK(CompileRun( + "obj_mirror instanceof debug.ObjectMirror")->BooleanValue()); + CompileRun("var named_names = obj_mirror.propertyNames();"); + // There should be exactly one property. But there is also an unnamed + // property whose value is hidden properties dictionary. The latter + // property should not be in the list of reguar properties. + CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); + CHECK(CompileRun("named_names[0] == 'a'")->BooleanValue()); + CHECK(CompileRun( + "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)); + t0->SetHiddenPrototype(true); + v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(); + t1->InstanceTemplate()->Set(v8::String::New("c"), v8::Number::New(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); + 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); + + // Setting prototypes: obj->protoObj->grandProtoObj + protoObj->Set(v8::String::New("__proto__"), grandProtoObj); + obj->Set(v8::String::New("__proto__"), protoObj); + + // Get mirror for the object with property getter. + CompileRun("var obj_mirror = debug.MakeMirror(obj);"); + CHECK(CompileRun( + "obj_mirror instanceof debug.ObjectMirror")->BooleanValue()); + CompileRun("var named_names = obj_mirror.propertyNames();"); + // There should be exactly two properties - one from the object itself and + // another from its hidden prototype. + CHECK_EQ(2, CompileRun("named_names.length")->Int32Value()); + CHECK(CompileRun("named_names.sort(); named_names[0] == 'a' &&" + "named_names[1] == 'b'")->BooleanValue()); + CHECK(CompileRun( + "obj_mirror.property('a').value().value() == 1")->BooleanValue()); + CHECK(CompileRun( + "obj_mirror.property('b').value().value() == 2")->BooleanValue()); +} + // Multithreaded tests of JSON debugger protocol @@ -4564,6 +4691,71 @@ TEST(DebuggerHostDispatch) { } +/* Test DebugMessageDispatch */ +/* In this test, the V8 thread waits for a message from the debug thread. + * The DebugMessageDispatchHandler is executed from the debugger thread + * which signals the V8 thread to wake up. + */ + +class DebugMessageDispatchV8Thread : public v8::internal::Thread { + public: + void Run(); +}; + +class DebugMessageDispatchDebuggerThread : public v8::internal::Thread { + public: + void Run(); +}; + +Barriers* debug_message_dispatch_barriers; + + +static void DebugMessageHandler() { + debug_message_dispatch_barriers->semaphore_1->Signal(); +} + + +void DebugMessageDispatchV8Thread::Run() { + v8::HandleScope scope; + DebugLocalContext env; + + // Setup debug message dispatch handler. + v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler); + + CompileRun("var y = 1 + 2;\n"); + debug_message_dispatch_barriers->barrier_1.Wait(); + debug_message_dispatch_barriers->semaphore_1->Wait(); + debug_message_dispatch_barriers->barrier_2.Wait(); +} + + +void DebugMessageDispatchDebuggerThread::Run() { + debug_message_dispatch_barriers->barrier_1.Wait(); + SendContinueCommand(); + debug_message_dispatch_barriers->barrier_2.Wait(); +} + +DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread; +DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread; + + +TEST(DebuggerDebugMessageDispatch) { + i::FLAG_debugger_auto_break = true; + + // Create a V8 environment + Barriers stack_allocated_debug_message_dispatch_barriers; + stack_allocated_debug_message_dispatch_barriers.Initialize(); + debug_message_dispatch_barriers = + &stack_allocated_debug_message_dispatch_barriers; + + debug_message_dispatch_v8_thread.Start(); + debug_message_dispatch_debugger_thread.Start(); + + debug_message_dispatch_v8_thread.Join(); + debug_message_dispatch_debugger_thread.Join(); +} + + TEST(DebuggerAgent) { // Make sure these ports is not used by other tests to allow tests to run in // parallel. @@ -4709,7 +4901,8 @@ TEST(DebuggerAgentProtocolOverflowHeader) { // Add empty body to request. const char* content_length_zero_header = "Content-Length:0\r\n"; - client->Send(content_length_zero_header, strlen(content_length_zero_header)); + client->Send(content_length_zero_header, + StrLength(content_length_zero_header)); client->Send("\r\n", 2); // Wait until data is received. @@ -5444,3 +5637,119 @@ TEST(GetMirror) { v8::Handle<v8::Value> result = run_test->Call(env->Global(), 1, &obj); CHECK(result->IsTrue()); } + + +// Test that the debug break flag works with function.apply. +TEST(DebugBreakFunctionApply) { + v8::HandleScope scope; + DebugLocalContext env; + + // Create a function for testing breaking in apply. + v8::Local<v8::Function> foo = CompileFunction( + &env, + "function baz(x) { }" + "function bar(x) { baz(); }" + "function foo(){ bar.apply(this, [1]); }", + "foo"); + + // Register a debug event listener which steps and counts. + v8::Debug::SetDebugEventListener(DebugEventBreakMax); + + // Set the debug break flag before calling the code using function.apply. + v8::Debug::DebugBreak(); + + // Limit the number of debug breaks. This is a regression test for issue 493 + // where this test would enter an infinite loop. + break_point_hit_count = 0; + max_break_point_hit_count = 10000; // 10000 => infinite loop. + foo->Call(env->Global(), 0, NULL); + + // When keeping the debug break several break will happen. + CHECK_EQ(3, break_point_hit_count); + + v8::Debug::SetDebugEventListener(NULL); + CheckDebuggerUnloaded(); +} + + +v8::Handle<v8::Context> debugee_context; +v8::Handle<v8::Context> debugger_context; + + +// Property getter that checks that current and calling contexts +// are both the debugee contexts. +static v8::Handle<v8::Value> NamedGetterWithCallingContextCheck( + v8::Local<v8::String> name, + const v8::AccessorInfo& info) { + CHECK_EQ(0, strcmp(*v8::String::AsciiValue(name), "a")); + v8::Handle<v8::Context> current = v8::Context::GetCurrent(); + CHECK(current == debugee_context); + CHECK(current != debugger_context); + v8::Handle<v8::Context> calling = v8::Context::GetCalling(); + CHECK(calling == debugee_context); + CHECK(calling != debugger_context); + return v8::Int32::New(1); +} + + +// Debug event listener that checks if the first argument of a function is +// an object with property 'a' == 1. If the property has custom accessor +// this handler will eventually invoke it. +static void DebugEventGetAtgumentPropertyValue( + v8::DebugEvent event, + v8::Handle<v8::Object> exec_state, + v8::Handle<v8::Object> event_data, + v8::Handle<v8::Value> data) { + if (event == v8::Break) { + break_point_hit_count++; + CHECK(debugger_context == v8::Context::GetCurrent()); + v8::Handle<v8::Function> func(v8::Function::Cast(*CompileRun( + "(function(exec_state) {\n" + " return (exec_state.frame(0).argumentValue(0).property('a').\n" + " value().value() == 1);\n" + "})"))); + const int argc = 1; + v8::Handle<v8::Value> argv[argc] = { exec_state }; + v8::Handle<v8::Value> result = func->Call(exec_state, argc, argv); + CHECK(result->IsTrue()); + } +} + + +TEST(CallingContextIsNotDebugContext) { + // Create and enter a debugee context. + v8::HandleScope scope; + DebugLocalContext env; + env.ExposeDebug(); + + // Save handles to the debugger and debugee contexts to be used in + // NamedGetterWithCallingContextCheck. + debugee_context = v8::Local<v8::Context>(*env); + 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"), + NamedGetterWithCallingContextCheck); + env->Global()->Set(v8::String::New("obj"), + named->NewInstance()); + + // Register the debug event listener + v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue); + + // Create a function that invokes debugger. + v8::Local<v8::Function> foo = CompileFunction( + &env, + "function bar(x) { debugger; }" + "function foo(){ bar(obj); }", + "foo"); + + break_point_hit_count = 0; + foo->Call(env->Global(), 0, NULL); + CHECK_EQ(1, break_point_hit_count); + + v8::Debug::SetDebugEventListener(NULL); + debugee_context = v8::Handle<v8::Context>(); + debugger_context = v8::Handle<v8::Context>(); + CheckDebuggerUnloaded(); +} diff --git a/deps/v8/test/cctest/test-disasm-ia32.cc b/deps/v8/test/cctest/test-disasm-ia32.cc index 74db23463..b8b3364ac 100644 --- a/deps/v8/test/cctest/test-disasm-ia32.cc +++ b/deps/v8/test/cctest/test-disasm-ia32.cc @@ -105,13 +105,13 @@ TEST(DisasmIa320) { __ xor_(edx, 3); __ nop(); { - CHECK(CpuFeatures::IsSupported(CpuFeatures::CPUID)); - CpuFeatures::Scope fscope(CpuFeatures::CPUID); + CHECK(CpuFeatures::IsSupported(CPUID)); + CpuFeatures::Scope fscope(CPUID); __ cpuid(); } { - CHECK(CpuFeatures::IsSupported(CpuFeatures::RDTSC)); - CpuFeatures::Scope fscope(CpuFeatures::RDTSC); + CHECK(CpuFeatures::IsSupported(RDTSC)); + CpuFeatures::Scope fscope(RDTSC); __ rdtsc(); } __ movsx_b(edx, Operand(ecx)); @@ -194,15 +194,16 @@ TEST(DisasmIa320) { __ rcl(edx, 7); __ sar(edx, 1); __ sar(edx, 6); - __ sar(edx); + __ sar_cl(edx); __ sbb(edx, Operand(ebx, ecx, times_4, 10000)); __ shld(edx, Operand(ebx, ecx, times_4, 10000)); __ shl(edx, 1); __ shl(edx, 6); - __ shl(edx); + __ shl_cl(edx); __ shrd(edx, Operand(ebx, ecx, times_4, 10000)); + __ shr(edx, 1); __ shr(edx, 7); - __ shr(edx); + __ shr_cl(edx); // Immediates @@ -353,8 +354,8 @@ TEST(DisasmIa320) { __ fwait(); __ nop(); { - CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2)); - CpuFeatures::Scope fscope(CpuFeatures::SSE2); + CHECK(CpuFeatures::IsSupported(SSE2)); + CpuFeatures::Scope fscope(SSE2); __ cvttss2si(edx, Operand(ebx, ecx, times_4, 10000)); __ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000)); __ addsd(xmm1, xmm0); @@ -368,8 +369,8 @@ TEST(DisasmIa320) { // cmov. { - CHECK(CpuFeatures::IsSupported(CpuFeatures::CMOV)); - CpuFeatures::Scope use_cmov(CpuFeatures::CMOV); + CHECK(CpuFeatures::IsSupported(CMOV)); + CpuFeatures::Scope use_cmov(CMOV); __ cmov(overflow, eax, Operand(eax, 0)); __ cmov(no_overflow, eax, Operand(eax, 1)); __ cmov(below, eax, Operand(eax, 2)); diff --git a/deps/v8/test/cctest/test-flags.cc b/deps/v8/test/cctest/test-flags.cc index 9019a89ef..32f1264f7 100644 --- a/deps/v8/test/cctest/test-flags.cc +++ b/deps/v8/test/cctest/test-flags.cc @@ -75,7 +75,7 @@ TEST(Flags2b) { " -notesting-bool-flag notaflag --testing_int_flag=77 " "-testing_float_flag=.25 " "--testing_string_flag no_way! "; - CHECK_EQ(0, FlagList::SetFlagsFromString(str, strlen(str))); + CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str))); CHECK(!FLAG_testing_bool_flag); CHECK_EQ(77, FLAG_testing_int_flag); CHECK_EQ(.25, FLAG_testing_float_flag); @@ -107,7 +107,7 @@ TEST(Flags3b) { "--testing_bool_flag notaflag --testing_int_flag -666 " "--testing_float_flag -12E10 " "-testing-string-flag=foo-bar"; - CHECK_EQ(0, FlagList::SetFlagsFromString(str, strlen(str))); + CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str))); CHECK(FLAG_testing_bool_flag); CHECK_EQ(-666, FLAG_testing_int_flag); CHECK_EQ(-12E10, FLAG_testing_float_flag); @@ -129,7 +129,7 @@ TEST(Flags4) { TEST(Flags4b) { SetFlagsToDefault(); const char* str = "--testing_bool_flag --foo"; - CHECK_EQ(2, FlagList::SetFlagsFromString(str, strlen(str))); + CHECK_EQ(2, FlagList::SetFlagsFromString(str, StrLength(str))); } @@ -147,7 +147,7 @@ TEST(Flags5) { TEST(Flags5b) { SetFlagsToDefault(); const char* str = " --testing_int_flag=\"foobar\""; - CHECK_EQ(1, FlagList::SetFlagsFromString(str, strlen(str))); + CHECK_EQ(1, FlagList::SetFlagsFromString(str, StrLength(str))); } @@ -166,7 +166,7 @@ TEST(Flags6) { TEST(Flags6b) { SetFlagsToDefault(); const char* str = " --testing-int-flag 0 --testing_float_flag "; - CHECK_EQ(3, FlagList::SetFlagsFromString(str, strlen(str))); + CHECK_EQ(3, FlagList::SetFlagsFromString(str, StrLength(str))); } @@ -191,7 +191,7 @@ TEST(FlagsJSArguments1) { TEST(FlagsJSArguments1b) { SetFlagsToDefault(); const char* str = "--testing-int-flag 42 -- testing-float-flag 7"; - CHECK_EQ(0, FlagList::SetFlagsFromString(str, strlen(str))); + CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str))); CHECK_EQ(42, FLAG_testing_int_flag); CHECK_EQ(2.5, FLAG_testing_float_flag); CHECK_EQ(2, FLAG_js_arguments.argc()); @@ -203,7 +203,7 @@ TEST(FlagsJSArguments1b) { TEST(FlagsJSArguments2) { SetFlagsToDefault(); const char* str = "--testing-int-flag 42 --js-arguments testing-float-flag 7"; - CHECK_EQ(0, FlagList::SetFlagsFromString(str, strlen(str))); + CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str))); CHECK_EQ(42, FLAG_testing_int_flag); CHECK_EQ(2.5, FLAG_testing_float_flag); CHECK_EQ(2, FLAG_js_arguments.argc()); @@ -215,7 +215,7 @@ TEST(FlagsJSArguments2) { TEST(FlagsJSArguments3) { SetFlagsToDefault(); const char* str = "--testing-int-flag 42 --js-arguments=testing-float-flag 7"; - CHECK_EQ(0, FlagList::SetFlagsFromString(str, strlen(str))); + CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str))); CHECK_EQ(42, FLAG_testing_int_flag); CHECK_EQ(2.5, FLAG_testing_float_flag); CHECK_EQ(2, FLAG_js_arguments.argc()); @@ -227,7 +227,7 @@ TEST(FlagsJSArguments3) { TEST(FlagsJSArguments4) { SetFlagsToDefault(); const char* str = "--testing-int-flag 42 --"; - CHECK_EQ(0, FlagList::SetFlagsFromString(str, strlen(str))); + CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str))); CHECK_EQ(42, FLAG_testing_int_flag); CHECK_EQ(0, FLAG_js_arguments.argc()); } diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index b199507d7..04e0037b0 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -384,8 +384,8 @@ TEST(RetainerProfile) { const char* retainers_of_a = printer.GetRetainers("A"); // The order of retainers is unspecified, so we check string length, and // verify each retainer separately. - CHECK_EQ(static_cast<int>(strlen("(global property);1,B;2,C;2")), - static_cast<int>(strlen(retainers_of_a))); + CHECK_EQ(i::StrLength("(global property);1,B;2,C;2"), + i::StrLength(retainers_of_a)); CHECK(strstr(retainers_of_a, "(global property);1") != NULL); CHECK(strstr(retainers_of_a, "B;2") != NULL); CHECK(strstr(retainers_of_a, "C;2") != NULL); diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc index 9911ce42b..fb9a48e79 100644 --- a/deps/v8/test/cctest/test-heap.cc +++ b/deps/v8/test/cctest/test-heap.cc @@ -262,7 +262,7 @@ TEST(GarbageCollection) { static void VerifyStringAllocation(const char* string) { String* s = String::cast(Heap::AllocateStringFromUtf8(CStrVector(string))); - CHECK_EQ(static_cast<int>(strlen(string)), s->length()); + CHECK_EQ(StrLength(string), s->length()); for (int index = 0; index < s->length(); index++) { CHECK_EQ(static_cast<uint16_t>(string[index]), s->Get(index)); } } @@ -285,7 +285,7 @@ TEST(LocalHandles) { v8::HandleScope scope; const char* name = "Kasper the spunky"; Handle<String> string = Factory::NewStringFromAscii(CStrVector(name)); - CHECK_EQ(static_cast<int>(strlen(name)), string->length()); + CHECK_EQ(StrLength(name), string->length()); } diff --git a/deps/v8/test/cctest/test-log-stack-tracer.cc b/deps/v8/test/cctest/test-log-stack-tracer.cc index 39f90647e..68cbc2619 100644 --- a/deps/v8/test/cctest/test-log-stack-tracer.cc +++ b/deps/v8/test/cctest/test-log-stack-tracer.cc @@ -163,11 +163,6 @@ v8::Handle<v8::Value> TraceExtension::JSEntrySP(const v8::Arguments& args) { } -static void CompileRun(const char* source) { - Script::Compile(String::New(source))->Run(); -} - - v8::Handle<v8::Value> TraceExtension::JSEntrySPLevel2( const v8::Arguments& args) { v8::HandleScope scope; diff --git a/deps/v8/test/cctest/test-log-utils.cc b/deps/v8/test/cctest/test-log-utils.cc index a08a0a110..c99d770d4 100644 --- a/deps/v8/test/cctest/test-log-utils.cc +++ b/deps/v8/test/cctest/test-log-utils.cc @@ -16,6 +16,7 @@ using v8::internal::LogRecordCompressor; using v8::internal::MutableCStrVector; using v8::internal::ScopedVector; using v8::internal::Vector; +using v8::internal::StrLength; // Fills 'ref_buffer' with test data: a sequence of two-digit // hex numbers: '0001020304...'. Then writes 'ref_buffer' contents to 'dynabuf'. @@ -118,7 +119,7 @@ TEST(DynaBufReadTruncation) { TEST(DynaBufSealing) { const char* seal = "Sealed"; - const int seal_size = strlen(seal); + const int seal_size = StrLength(seal); LogDynamicBuffer dynabuf(32, 128, seal, seal_size); EmbeddedVector<char, 100> ref_buf; WriteData(&dynabuf, &ref_buf); diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc index b1cb63c63..57004d7c8 100644 --- a/deps/v8/test/cctest/test-log.cc +++ b/deps/v8/test/cctest/test-log.cc @@ -19,6 +19,7 @@ using v8::internal::Address; using v8::internal::EmbeddedVector; using v8::internal::Logger; +using v8::internal::StrLength; namespace i = v8::internal; @@ -55,7 +56,7 @@ TEST(GetMessages) { CHECK_EQ(0, Logger::GetLogLines(0, log_lines, 3)); // See Logger::StringEvent. const char* line_1 = "aaa,\"bbb\"\n"; - const int line_1_len = strlen(line_1); + const int line_1_len = StrLength(line_1); // Still smaller than log message length. CHECK_EQ(0, Logger::GetLogLines(0, log_lines, line_1_len - 1)); // The exact size. @@ -68,7 +69,7 @@ TEST(GetMessages) { CHECK_EQ(line_1, log_lines); memset(log_lines, 0, sizeof(log_lines)); const char* line_2 = "cccc,\"dddd\"\n"; - const int line_2_len = strlen(line_2); + const int line_2_len = StrLength(line_2); // Now start with line_2 beginning. CHECK_EQ(0, Logger::GetLogLines(line_1_len, log_lines, 0)); CHECK_EQ(0, Logger::GetLogLines(line_1_len, log_lines, 3)); @@ -82,7 +83,7 @@ TEST(GetMessages) { memset(log_lines, 0, sizeof(log_lines)); // Now get entire buffer contents. const char* all_lines = "aaa,\"bbb\"\ncccc,\"dddd\"\n"; - const int all_lines_len = strlen(all_lines); + const int all_lines_len = StrLength(all_lines); CHECK_EQ(all_lines_len, Logger::GetLogLines(0, log_lines, all_lines_len)); CHECK_EQ(all_lines, log_lines); memset(log_lines, 0, sizeof(log_lines)); @@ -104,7 +105,7 @@ TEST(BeyondWritePosition) { Logger::StringEvent("cccc", "dddd"); // See Logger::StringEvent. const char* all_lines = "aaa,\"bbb\"\ncccc,\"dddd\"\n"; - const int all_lines_len = strlen(all_lines); + const int all_lines_len = StrLength(all_lines); EmbeddedVector<char, 100> buffer; const int beyond_write_pos = all_lines_len; CHECK_EQ(0, Logger::GetLogLines(beyond_write_pos, buffer.start(), 1)); @@ -437,7 +438,7 @@ namespace { class SimpleExternalString : public v8::String::ExternalStringResource { public: explicit SimpleExternalString(const char* source) - : utf_source_(strlen(source)) { + : utf_source_(StrLength(source)) { for (int i = 0; i < utf_source_.length(); ++i) utf_source_[i] = source[i]; } @@ -592,7 +593,7 @@ class ParseLogResult { entities[i] = NULL; } const size_t map_length = bounds.Length(); - entities_map = i::NewArray<int>(map_length); + entities_map = i::NewArray<int>(static_cast<int>(map_length)); for (size_t i = 0; i < map_length; ++i) { entities_map[i] = -1; } @@ -768,7 +769,7 @@ static inline void PrintCodeEntityInfo(CodeEntityInfo entity) { const int max_len = 50; if (entity != NULL) { char* eol = strchr(entity, '\n'); - int len = eol - entity; + int len = static_cast<int>(eol - entity); len = len <= max_len ? len : max_len; printf("%-*.*s ", max_len, len, entity); } else { @@ -788,7 +789,7 @@ static void PrintCodeEntitiesInfo( static inline int StrChrLen(const char* s, char c) { - return strchr(s, c) - s; + return static_cast<int>(strchr(s, c) - s); } diff --git a/deps/v8/test/cctest/test-macro-assembler-x64.cc b/deps/v8/test/cctest/test-macro-assembler-x64.cc index f344ac864..511b933a5 100755 --- a/deps/v8/test/cctest/test-macro-assembler-x64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-x64.cc @@ -133,7 +133,7 @@ TEST(SmiMove) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. masm->set_allow_stub_calls(false); Label exit; @@ -218,7 +218,7 @@ TEST(SmiCompare) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -265,7 +265,7 @@ TEST(Integer32ToSmi) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -364,7 +364,7 @@ void TestI64PlusConstantToSmi(MacroAssembler* masm, int64_t result = x + y; ASSERT(Smi::IsValid(result)); __ movl(rax, Immediate(id)); - __ Move(r8, Smi::FromInt(result)); + __ Move(r8, Smi::FromInt(static_cast<int>(result))); __ movq(rcx, x, RelocInfo::NONE); __ movq(r11, rcx); __ Integer64PlusConstantToSmi(rdx, rcx, y); @@ -390,7 +390,7 @@ TEST(Integer64PlusConstantToSmi) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -431,7 +431,7 @@ TEST(SmiCheck) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -676,7 +676,7 @@ TEST(SmiNeg) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -761,7 +761,7 @@ TEST(SmiAdd) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -948,7 +948,7 @@ TEST(SmiSub) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -1035,7 +1035,7 @@ TEST(SmiMul) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -1138,7 +1138,7 @@ TEST(SmiDiv) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -1245,7 +1245,7 @@ TEST(SmiMod) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -1338,7 +1338,7 @@ TEST(SmiIndex) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -1404,7 +1404,7 @@ TEST(SmiSelectNonSmi) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); // Avoid inline checks. @@ -1480,7 +1480,7 @@ TEST(SmiAnd) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -1558,7 +1558,7 @@ TEST(SmiOr) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -1638,7 +1638,7 @@ TEST(SmiXor) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -1702,7 +1702,7 @@ TEST(SmiNot) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -1843,7 +1843,7 @@ TEST(SmiShiftLeft) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -1880,7 +1880,7 @@ void TestSmiShiftLogicalRight(MacroAssembler* masm, int shift = shifts[i]; intptr_t result = static_cast<unsigned int>(x) >> shift; if (Smi::IsValid(result)) { - __ Move(r8, Smi::FromInt(result)); + __ Move(r8, Smi::FromInt(static_cast<int>(result))); __ Move(rcx, Smi::FromInt(x)); __ SmiShiftLogicalRightConstant(r9, rcx, shift, exit); @@ -1946,7 +1946,7 @@ TEST(SmiShiftLogicalRight) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -2012,7 +2012,7 @@ TEST(SmiShiftArithmeticRight) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); @@ -2073,7 +2073,7 @@ TEST(PositiveSmiTimesPowerOfTwoToInteger64) { true)); CHECK(buffer); HandleScope handles; - MacroAssembler assembler(buffer, actual_size); + MacroAssembler assembler(buffer, static_cast<int>(actual_size)); MacroAssembler* masm = &assembler; masm->set_allow_stub_calls(false); diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc new file mode 100644 index 000000000..d62b6a5d5 --- /dev/null +++ b/deps/v8/test/cctest/test-parsing.cc @@ -0,0 +1,129 @@ +// Copyright 2006-2009 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 "token.h" +#include "scanner.h" +#include "utils.h" + +#include "cctest.h" + +namespace i = ::v8::internal; + +TEST(KeywordMatcher) { + struct KeywordToken { + const char* keyword; + i::Token::Value token; + }; + + static const KeywordToken keywords[] = { +#define KEYWORD(t, s, d) { s, i::Token::t }, +#define IGNORE(t, s, d) /* */ + TOKEN_LIST(IGNORE, KEYWORD, IGNORE) +#undef KEYWORD + { NULL, i::Token::IDENTIFIER } + }; + + static const char* future_keywords[] = { +#define FUTURE(t, s, d) s, + TOKEN_LIST(IGNORE, IGNORE, FUTURE) +#undef FUTURE +#undef IGNORE + NULL + }; + + KeywordToken key_token; + for (int i = 0; (key_token = keywords[i]).keyword != NULL; i++) { + i::KeywordMatcher matcher; + const char* keyword = key_token.keyword; + int length = i::StrLength(keyword); + for (int j = 0; j < length; j++) { + if (key_token.token == i::Token::INSTANCEOF && j == 2) { + // "in" is a prefix of "instanceof". It's the only keyword + // that is a prefix of another. + CHECK_EQ(i::Token::IN, matcher.token()); + } else { + CHECK_EQ(i::Token::IDENTIFIER, matcher.token()); + } + matcher.AddChar(keyword[j]); + } + CHECK_EQ(key_token.token, matcher.token()); + // Adding more characters will make keyword matching fail. + matcher.AddChar('z'); + CHECK_EQ(i::Token::IDENTIFIER, matcher.token()); + // Adding a keyword later will not make it match again. + matcher.AddChar('i'); + matcher.AddChar('f'); + CHECK_EQ(i::Token::IDENTIFIER, matcher.token()); + } + + // Future keywords are not recognized. + const char* future_keyword; + for (int i = 0; (future_keyword = future_keywords[i]) != NULL; i++) { + i::KeywordMatcher matcher; + int length = i::StrLength(future_keyword); + for (int j = 0; j < length; j++) { + matcher.AddChar(future_keyword[j]); + } + CHECK_EQ(i::Token::IDENTIFIER, matcher.token()); + } + + // Zero isn't ignored at first. + i::KeywordMatcher bad_start; + bad_start.AddChar(0); + CHECK_EQ(i::Token::IDENTIFIER, bad_start.token()); + bad_start.AddChar('i'); + bad_start.AddChar('f'); + CHECK_EQ(i::Token::IDENTIFIER, bad_start.token()); + + // Zero isn't ignored at end. + i::KeywordMatcher bad_end; + bad_end.AddChar('i'); + bad_end.AddChar('f'); + CHECK_EQ(i::Token::IF, bad_end.token()); + bad_end.AddChar(0); + CHECK_EQ(i::Token::IDENTIFIER, bad_end.token()); + + // Case isn't ignored. + i::KeywordMatcher bad_case; + bad_case.AddChar('i'); + bad_case.AddChar('F'); + CHECK_EQ(i::Token::IDENTIFIER, bad_case.token()); + + // If we mark it as failure, continuing won't help. + i::KeywordMatcher full_stop; + full_stop.AddChar('i'); + CHECK_EQ(i::Token::IDENTIFIER, full_stop.token()); + full_stop.Fail(); + CHECK_EQ(i::Token::IDENTIFIER, full_stop.token()); + full_stop.AddChar('f'); + CHECK_EQ(i::Token::IDENTIFIER, full_stop.token()); +} + diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc index 81c220520..6aa0730c0 100644 --- a/deps/v8/test/cctest/test-regexp.cc +++ b/deps/v8/test/cctest/test-regexp.cc @@ -74,7 +74,7 @@ static SmartPointer<const char> Parse(const char* input) { static bool CheckSimple(const char* input) { V8::Initialize(NULL); v8::HandleScope scope; - unibrow::Utf8InputBuffer<> buffer(input, strlen(input)); + unibrow::Utf8InputBuffer<> buffer(input, StrLength(input)); ZoneScope zone_scope(DELETE_ON_EXIT); FlatStringReader reader(CStrVector(input)); RegExpCompileData result; @@ -92,7 +92,7 @@ struct MinMaxPair { static MinMaxPair CheckMinMaxMatch(const char* input) { V8::Initialize(NULL); v8::HandleScope scope; - unibrow::Utf8InputBuffer<> buffer(input, strlen(input)); + unibrow::Utf8InputBuffer<> buffer(input, StrLength(input)); ZoneScope zone_scope(DELETE_ON_EXIT); FlatStringReader reader(CStrVector(input)); RegExpCompileData result; @@ -1466,7 +1466,7 @@ static void TestRangeCaseIndependence(CharacterRange input, ZoneScope zone_scope(DELETE_ON_EXIT); int count = expected.length(); ZoneList<CharacterRange>* list = new ZoneList<CharacterRange>(count); - input.AddCaseEquivalents(list); + input.AddCaseEquivalents(list, false); CHECK_EQ(count, list->length()); for (int i = 0; i < list->length(); i++) { CHECK_EQ(expected[i].from(), list->at(i).from()); diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index 01e07157a..9ed487450 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -123,13 +123,17 @@ TEST(ExternalReferenceEncoder) { ExternalReference::the_hole_value_location(); CHECK_EQ(make_code(UNCLASSIFIED, 2), encoder.Encode(the_hole_value_location.address())); - ExternalReference stack_guard_limit_address = - ExternalReference::address_of_stack_guard_limit(); + ExternalReference stack_limit_address = + ExternalReference::address_of_stack_limit(); CHECK_EQ(make_code(UNCLASSIFIED, 4), - encoder.Encode(stack_guard_limit_address.address())); - CHECK_EQ(make_code(UNCLASSIFIED, 10), + encoder.Encode(stack_limit_address.address())); + ExternalReference real_stack_limit_address = + ExternalReference::address_of_real_stack_limit(); + CHECK_EQ(make_code(UNCLASSIFIED, 5), + encoder.Encode(real_stack_limit_address.address())); + CHECK_EQ(make_code(UNCLASSIFIED, 11), encoder.Encode(ExternalReference::debug_break().address())); - CHECK_EQ(make_code(UNCLASSIFIED, 6), + CHECK_EQ(make_code(UNCLASSIFIED, 7), encoder.Encode(ExternalReference::new_space_start().address())); CHECK_EQ(make_code(UNCLASSIFIED, 3), encoder.Encode(ExternalReference::roots_address().address())); @@ -158,102 +162,44 @@ TEST(ExternalReferenceDecoder) { decoder.Decode(make_code(UNCLASSIFIED, 1))); CHECK_EQ(ExternalReference::the_hole_value_location().address(), decoder.Decode(make_code(UNCLASSIFIED, 2))); - CHECK_EQ(ExternalReference::address_of_stack_guard_limit().address(), + CHECK_EQ(ExternalReference::address_of_stack_limit().address(), decoder.Decode(make_code(UNCLASSIFIED, 4))); + CHECK_EQ(ExternalReference::address_of_real_stack_limit().address(), + decoder.Decode(make_code(UNCLASSIFIED, 5))); CHECK_EQ(ExternalReference::debug_break().address(), - decoder.Decode(make_code(UNCLASSIFIED, 10))); + decoder.Decode(make_code(UNCLASSIFIED, 11))); CHECK_EQ(ExternalReference::new_space_start().address(), - decoder.Decode(make_code(UNCLASSIFIED, 6))); + decoder.Decode(make_code(UNCLASSIFIED, 7))); } static void Serialize() { -#ifdef DEBUG - FLAG_debug_serialization = true; -#endif - StatsTable::SetCounterFunction(counter_function); - - v8::HandleScope scope; - const int kExtensionCount = 1; - const char* extension_list[kExtensionCount] = { "v8/gc" }; - v8::ExtensionConfiguration extensions(kExtensionCount, extension_list); - Serializer::Enable(); - v8::Persistent<v8::Context> env = v8::Context::New(&extensions); - env->Enter(); - - Snapshot::WriteToFile(FLAG_testing_serialization_file); -} - - -static void Serialize2() { - Serializer::Enable(); // We have to create one context. One reason for this is so that the builtins // can be loaded from v8natives.js and their addresses can be processed. This // will clear the pending fixups array, which would otherwise contain GC roots // that would confuse the serialization/deserialization process. v8::Persistent<v8::Context> env = v8::Context::New(); env.Dispose(); - Snapshot::WriteToFile2(FLAG_testing_serialization_file); -} - - -// Test that the whole heap can be serialized when running from the -// internal snapshot. -// (Smoke test.) -TEST(SerializeInternal) { - Snapshot::Initialize(NULL); - Serialize(); -} - - -// Test that the whole heap can be serialized when running from a -// bootstrapped heap. -// (Smoke test.) -TEST(Serialize) { - if (Snapshot::IsEnabled()) return; - Serialize(); + Snapshot::WriteToFile(FLAG_testing_serialization_file); } // Test that the whole heap can be serialized. -TEST(Serialize2) { +TEST(Serialize) { + Serializer::Enable(); v8::V8::Initialize(); - Serialize2(); + Serialize(); } -// Test that the heap isn't destroyed after a serialization. -TEST(SerializeNondestructive) { - if (Snapshot::IsEnabled()) return; - StatsTable::SetCounterFunction(counter_function); - v8::HandleScope scope; - Serializer::Enable(); - v8::Persistent<v8::Context> env = v8::Context::New(); - v8::Context::Scope context_scope(env); - Serializer().Serialize(); - const char* c_source = "\"abcd\".charAt(2) == 'c'"; - v8::Local<v8::String> source = v8::String::New(c_source); - v8::Local<v8::Script> script = v8::Script::Compile(source); - v8::Local<v8::Value> value = script->Run(); - CHECK(value->BooleanValue()); -} - //---------------------------------------------------------------------------- // Tests that the heap can be deserialized. static void Deserialize() { -#ifdef DEBUG - FLAG_debug_serialization = true; -#endif CHECK(Snapshot::Initialize(FLAG_testing_serialization_file)); } -static void Deserialize2() { - CHECK(Snapshot::Initialize2(FLAG_testing_serialization_file)); -} - - static void SanityCheck() { v8::HandleScope scope; #ifdef DEBUG @@ -272,15 +218,6 @@ DEPENDENT_TEST(Deserialize, Serialize) { Deserialize(); - SanityCheck(); -} - - -DEPENDENT_TEST(Deserialize2, Serialize2) { - v8::HandleScope scope; - - Deserialize2(); - fflush(stdout); v8::Persistent<v8::Context> env = v8::Context::New(); @@ -290,23 +227,11 @@ DEPENDENT_TEST(Deserialize2, Serialize2) { } -DEPENDENT_TEST(DeserializeAndRunScript, Serialize) { +DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) { v8::HandleScope scope; Deserialize(); - const char* c_source = "\"1234\".length"; - v8::Local<v8::String> source = v8::String::New(c_source); - v8::Local<v8::Script> script = v8::Script::Compile(source); - CHECK_EQ(4, script->Run()->Int32Value()); -} - - -DEPENDENT_TEST(DeserializeAndRunScript2, Serialize2) { - v8::HandleScope scope; - - Deserialize2(); - v8::Persistent<v8::Context> env = v8::Context::New(); env->Enter(); @@ -317,31 +242,6 @@ DEPENDENT_TEST(DeserializeAndRunScript2, Serialize2) { } -DEPENDENT_TEST(DeserializeNatives, Serialize) { - v8::HandleScope scope; - - Deserialize(); - - const char* c_source = "\"abcd\".charAt(2) == 'c'"; - v8::Local<v8::String> source = v8::String::New(c_source); - v8::Local<v8::Script> script = v8::Script::Compile(source); - v8::Local<v8::Value> value = script->Run(); - CHECK(value->BooleanValue()); -} - - -DEPENDENT_TEST(DeserializeExtensions, Serialize) { - v8::HandleScope scope; - - Deserialize(); - const char* c_source = "gc();"; - v8::Local<v8::String> source = v8::String::New(c_source); - v8::Local<v8::Script> script = v8::Script::Compile(source); - v8::Local<v8::Value> value = script->Run(); - CHECK(value->IsUndefined()); -} - - TEST(TestThatAlwaysSucceeds) { } diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc index bb9a6f99a..0e9bf7a06 100644 --- a/deps/v8/test/cctest/test-strings.cc +++ b/deps/v8/test/cctest/test-strings.cc @@ -241,17 +241,6 @@ TEST(Traverse) { printf("6\n"); TraverseFirst(left_asymmetric, right_deep_asymmetric, 65536); printf("7\n"); - Handle<String> right_deep_slice = - Factory::NewStringSlice(left_deep_asymmetric, - left_deep_asymmetric->length() - 1050, - left_deep_asymmetric->length() - 50); - Handle<String> left_deep_slice = - Factory::NewStringSlice(right_deep_asymmetric, - right_deep_asymmetric->length() - 1050, - right_deep_asymmetric->length() - 50); - printf("8\n"); - Traverse(right_deep_slice, left_deep_slice); - printf("9\n"); FlattenString(left_asymmetric); printf("10\n"); Traverse(flat, left_asymmetric); @@ -269,60 +258,6 @@ TEST(Traverse) { } -static Handle<String> SliceOf(Handle<String> underlying) { - int start = gen() % underlying->length(); - int end = start + gen() % (underlying->length() - start); - return Factory::NewStringSlice(underlying, - start, - end); -} - - -static Handle<String> ConstructSliceTree( - Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS], - int from, - int to) { - CHECK(to > from); - if (to - from <= 1) - return SliceOf(building_blocks[from % NUMBER_OF_BUILDING_BLOCKS]); - if (to - from == 2) { - Handle<String> lhs = building_blocks[from % NUMBER_OF_BUILDING_BLOCKS]; - if (gen() % 2 == 0) - lhs = SliceOf(lhs); - Handle<String> rhs = building_blocks[(from+1) % NUMBER_OF_BUILDING_BLOCKS]; - if (gen() % 2 == 0) - rhs = SliceOf(rhs); - return Factory::NewConsString(lhs, rhs); - } - Handle<String> part1 = - ConstructBalancedHelper(building_blocks, from, from + ((to - from) / 2)); - Handle<String> part2 = - ConstructBalancedHelper(building_blocks, from + ((to - from) / 2), to); - Handle<String> branch = Factory::NewConsString(part1, part2); - if (gen() % 2 == 0) - return branch; - return(SliceOf(branch)); -} - - -TEST(Slice) { - printf("TestSlice\n"); - InitializeVM(); - v8::HandleScope scope; - Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS]; - ZoneScope zone(DELETE_ON_EXIT); - InitializeBuildingBlocks(building_blocks); - - seed = 42; - Handle<String> slice_tree = - ConstructSliceTree(building_blocks, 0, DEEP_DEPTH); - seed = 42; - Handle<String> flat_slice_tree = - ConstructSliceTree(building_blocks, 0, DEEP_DEPTH); - FlattenString(flat_slice_tree); - Traverse(flat_slice_tree, slice_tree); -} - static const int DEEP_ASCII_DEPTH = 100000; @@ -357,8 +292,10 @@ TEST(Utf8Conversion) { v8::HandleScope handle_scope; // A simple ascii string const char* ascii_string = "abcdef12345"; - int len = v8::String::New(ascii_string, strlen(ascii_string))->Utf8Length(); - CHECK_EQ(strlen(ascii_string), len); + int len = + v8::String::New(ascii_string, + StrLength(ascii_string))->Utf8Length(); + CHECK_EQ(StrLength(ascii_string), len); // A mixed ascii and non-ascii string // U+02E4 -> CB A4 // U+0064 -> 64 @@ -414,105 +351,3 @@ class TwoByteResource: public v8::String::ExternalStringResource { size_t length_; bool* destructed_; }; - - -// Regression test case for http://crbug.com/9746. The problem was -// that when we marked objects reachable only through weak pointers, -// we ended up keeping a sliced symbol alive, even though we already -// invoked the weak callback on the underlying external string thus -// deleting its resource. -TEST(Regress9746) { - InitializeVM(); - - // Setup lengths that guarantee we'll get slices instead of simple - // flat strings. - static const int kFullStringLength = String::kMinNonFlatLength * 2; - static const int kSliceStringLength = String::kMinNonFlatLength + 1; - - uint16_t* source = new uint16_t[kFullStringLength]; - for (int i = 0; i < kFullStringLength; i++) source[i] = '1'; - char* key = new char[kSliceStringLength]; - for (int i = 0; i < kSliceStringLength; i++) key[i] = '1'; - Vector<const char> key_vector(key, kSliceStringLength); - - // Allocate an external string resource that keeps track of when it - // is destructed. - bool resource_destructed = false; - TwoByteResource* resource = - new TwoByteResource(source, kFullStringLength, &resource_destructed); - - { - v8::HandleScope scope; - - // Allocate an external string resource and external string. We - // have to go through the API to get the weak handle and the - // automatic destruction going. - Handle<String> string = - v8::Utils::OpenHandle(*v8::String::NewExternal(resource)); - - // Create a slice of the external string. - Handle<String> slice = - Factory::NewStringSlice(string, 0, kSliceStringLength); - CHECK_EQ(kSliceStringLength, slice->length()); - CHECK(StringShape(*slice).IsSliced()); - - // Make sure the slice ends up in old space so we can morph it - // into a symbol. - while (Heap::InNewSpace(*slice)) { - Heap::PerformScavenge(); - } - - // Force the slice into the symbol table. - slice = Factory::SymbolFromString(slice); - CHECK(slice->IsSymbol()); - CHECK(StringShape(*slice).IsSliced()); - - Handle<String> buffer(Handle<SlicedString>::cast(slice)->buffer()); - CHECK(StringShape(*buffer).IsExternal()); - CHECK(buffer->IsTwoByteRepresentation()); - - // Finally, base a script on the slice of the external string and - // get its wrapper. This allocates yet another weak handle that - // indirectly refers to the external string. - Handle<Script> script = Factory::NewScript(slice); - Handle<JSObject> wrapper = GetScriptWrapper(script); - } - - // When we collect all garbage, we cannot get rid of the sliced - // symbol entry in the symbol table because it is used by the script - // kept alive by the weak wrapper. Make sure we don't destruct the - // external string. - Heap::CollectAllGarbage(false); - CHECK(!resource_destructed); - - { - v8::HandleScope scope; - - // Make sure the sliced symbol is still in the table. - Handle<String> symbol = Factory::LookupSymbol(key_vector); - CHECK(StringShape(*symbol).IsSliced()); - - // Make sure the buffer is still a two-byte external string. - Handle<String> buffer(Handle<SlicedString>::cast(symbol)->buffer()); - CHECK(StringShape(*buffer).IsExternal()); - CHECK(buffer->IsTwoByteRepresentation()); - } - - // Forcing another garbage collection should let us get rid of the - // slice from the symbol table. The external string remains in the - // heap until the next GC. - Heap::CollectAllGarbage(false); - CHECK(!resource_destructed); - v8::HandleScope scope; - Handle<String> key_string = Factory::NewStringFromAscii(key_vector); - String* out; - CHECK(!Heap::LookupSymbolIfExists(*key_string, &out)); - - // Forcing yet another garbage collection must allow us to finally - // get rid of the external string. - Heap::CollectAllGarbage(false); - CHECK(resource_destructed); - - delete[] source; - delete[] key; -} diff --git a/deps/v8/test/cctest/test-utils.cc b/deps/v8/test/cctest/test-utils.cc index ffcaf8abc..1d65e686e 100644 --- a/deps/v8/test/cctest/test-utils.cc +++ b/deps/v8/test/cctest/test-utils.cc @@ -166,7 +166,7 @@ TEST(SNPrintF) { // Make sure that strings that are truncated because of too small // buffers are zero-terminated anyway. const char* s = "the quick lazy .... oh forget it!"; - int length = strlen(s); + int length = StrLength(s); for (int i = 1; i < length * 2; i++) { static const char kMarker = static_cast<char>(42); Vector<char> buffer = Vector<char>::New(i + 1); @@ -177,9 +177,9 @@ TEST(SNPrintF) { CHECK_EQ(0, strncmp(buffer.start(), s, i - 1)); CHECK_EQ(kMarker, buffer[i]); if (i <= length) { - CHECK_EQ(i - 1, strlen(buffer.start())); + CHECK_EQ(i - 1, StrLength(buffer.start())); } else { - CHECK_EQ(length, strlen(buffer.start())); + CHECK_EQ(length, StrLength(buffer.start())); } buffer.Dispose(); } |