summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2009-11-18 15:25:58 +0100
committerRyan Dahl <ry@tinyclouds.org>2009-11-18 15:28:54 +0100
commit728d8a37f471afaeaa6af19823f9da8c41f1f65a (patch)
tree21e014089ff0bfb7d493691620ab9eee51176d28 /deps/v8/test/cctest
parent8195e0f7232fed3d6a3a2cc8464fec5e36f4433c (diff)
downloadnode-728d8a37f471afaeaa6af19823f9da8c41f1f65a.tar.gz
Upgrade v8 to 2.0
(With just one change: remove -Werror)
Diffstat (limited to 'deps/v8/test/cctest')
-rw-r--r--deps/v8/test/cctest/SConscript2
-rw-r--r--deps/v8/test/cctest/cctest.cc3
-rw-r--r--deps/v8/test/cctest/cctest.h136
-rw-r--r--deps/v8/test/cctest/cctest.status21
-rw-r--r--deps/v8/test/cctest/test-accessors.cc450
-rw-r--r--deps/v8/test/cctest/test-alloc.cc6
-rw-r--r--deps/v8/test/cctest/test-api.cc521
-rw-r--r--deps/v8/test/cctest/test-assembler-ia32.cc16
-rw-r--r--deps/v8/test/cctest/test-assembler-x64.cc14
-rw-r--r--deps/v8/test/cctest/test-debug.cc361
-rw-r--r--deps/v8/test/cctest/test-disasm-ia32.cc23
-rw-r--r--deps/v8/test/cctest/test-flags.cc18
-rw-r--r--deps/v8/test/cctest/test-heap-profiler.cc4
-rw-r--r--deps/v8/test/cctest/test-heap.cc4
-rw-r--r--deps/v8/test/cctest/test-log-stack-tracer.cc5
-rw-r--r--deps/v8/test/cctest/test-log-utils.cc3
-rw-r--r--deps/v8/test/cctest/test-log.cc17
-rwxr-xr-xdeps/v8/test/cctest/test-macro-assembler-x64.cc46
-rw-r--r--deps/v8/test/cctest/test-parsing.cc129
-rw-r--r--deps/v8/test/cctest/test-regexp.cc6
-rw-r--r--deps/v8/test/cctest/test-serialize.cc138
-rw-r--r--deps/v8/test/cctest/test-strings.cc173
-rw-r--r--deps/v8/test/cctest/test-utils.cc6
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();
}