summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-debug.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest/test-debug.cc')
-rw-r--r--deps/v8/test/cctest/test-debug.cc689
1 files changed, 647 insertions, 42 deletions
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 66bef1584a..247bc5d3d0 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -173,7 +173,7 @@ static i::Handle<i::BreakPoint> SetBreakPoint(v8::Local<v8::Function> fun,
const char* condition = nullptr) {
i::Handle<i::JSFunction> function =
i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*fun));
- position += function->shared()->start_position();
+ position += function->shared()->StartPosition();
static int break_point_index = 0;
i::Isolate* isolate = function->GetIsolate();
i::Handle<i::String> condition_string =
@@ -1048,68 +1048,169 @@ TEST(BreakPointReturn) {
CheckDebuggerUnloaded();
}
-// Test that a break point can be set at a return store location.
TEST(BreakPointBuiltin) {
- i::FLAG_allow_natives_syntax = true;
- i::FLAG_block_concurrent_recompilation = true;
- i::FLAG_experimental_inline_promise_constructor = true;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+ v8::Local<v8::Function> builtin;
+ i::Handle<i::BreakPoint> bp;
+
// === Test simple builtin ===
break_point_hit_count = 0;
- v8::Local<v8::Function> builtin =
- CompileRun("String.prototype.repeat").As<v8::Function>();
- CompileRun("'a'.repeat(10)");
- CHECK_EQ(0, break_point_hit_count);
+ builtin = CompileRun("String.prototype.repeat").As<v8::Function>();
// Run with breakpoint.
- i::Handle<i::BreakPoint> bp = SetBreakPoint(builtin, 0);
- CompileRun("'b'.repeat(10)");
+ bp = SetBreakPoint(builtin, 0);
+ ExpectString("'b'.repeat(10)", "bbbbbbbbbb");
CHECK_EQ(1, break_point_hit_count);
+ ExpectString("'b'.repeat(10)", "bbbbbbbbbb");
+ CHECK_EQ(2, break_point_hit_count);
+
// Run without breakpoints.
ClearBreakPoint(bp);
- CompileRun("'b'.repeat(10)");
+ ExpectString("'b'.repeat(10)", "bbbbbbbbbb");
+ CHECK_EQ(2, break_point_hit_count);
+
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+TEST(BreakPointJSBuiltin) {
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ v8::Local<v8::Function> builtin;
+ i::Handle<i::BreakPoint> bp;
+
+ // === Test JS builtin ===
+ break_point_hit_count = 0;
+ builtin = CompileRun("Array.prototype.sort").As<v8::Function>();
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(builtin, 0);
+ CompileRun("[1,2,3].sort()");
CHECK_EQ(1, break_point_hit_count);
+ CompileRun("[1,2,3].sort()");
+ CHECK_EQ(2, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ CompileRun("[1,2,3].sort()");
+ CHECK_EQ(2, break_point_hit_count);
+
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+TEST(BreakPointBoundBuiltin) {
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ v8::Local<v8::Function> builtin;
+ i::Handle<i::BreakPoint> bp;
+
// === Test bound function from a builtin ===
break_point_hit_count = 0;
builtin = CompileRun(
"var boundrepeat = String.prototype.repeat.bind('a');"
"String.prototype.repeat")
.As<v8::Function>();
- CompileRun("boundrepeat(10)");
+ ExpectString("boundrepeat(10)", "aaaaaaaaaa");
CHECK_EQ(0, break_point_hit_count);
// Run with breakpoint.
bp = SetBreakPoint(builtin, 0);
- CompileRun("boundrepeat(10)");
+ ExpectString("boundrepeat(10)", "aaaaaaaaaa");
CHECK_EQ(1, break_point_hit_count);
// Run without breakpoints.
ClearBreakPoint(bp);
- CompileRun("boundrepeat(10)");
+ ExpectString("boundrepeat(10)", "aaaaaaaaaa");
CHECK_EQ(1, break_point_hit_count);
- // === Test constructor builtin (for ones with normal construct stubs) ===
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+TEST(BreakPointConstructorBuiltin) {
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ v8::Local<v8::Function> builtin;
+ i::Handle<i::BreakPoint> bp;
+
+ // === Test Promise constructor ===
break_point_hit_count = 0;
builtin = CompileRun("Promise").As<v8::Function>();
- CompileRun("new Promise(()=>{})");
+ ExpectString("(new Promise(()=>{})).toString()", "[object Promise]");
+ CHECK_EQ(0, break_point_hit_count);
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(builtin, 0);
+ ExpectString("(new Promise(()=>{})).toString()", "[object Promise]");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ ExpectString("(new Promise(()=>{})).toString()", "[object Promise]");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // === Test Object constructor ===
+ break_point_hit_count = 0;
+ builtin = CompileRun("Object").As<v8::Function>();
+ CompileRun("new Object()");
CHECK_EQ(0, break_point_hit_count);
// Run with breakpoint.
bp = SetBreakPoint(builtin, 0);
- CompileRun("new Promise(()=>{})");
+ CompileRun("new Object()");
CHECK_EQ(1, break_point_hit_count);
// Run without breakpoints.
ClearBreakPoint(bp);
- CompileRun("new Promise(()=>{})");
+ CompileRun("new Object()");
CHECK_EQ(1, break_point_hit_count);
+ // === Test Number constructor ===
+ break_point_hit_count = 0;
+ builtin = CompileRun("Number").As<v8::Function>();
+ CompileRun("new Number()");
+ CHECK_EQ(0, break_point_hit_count);
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(builtin, 0);
+ CompileRun("new Number()");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ CompileRun("new Number()");
+ CHECK_EQ(1, break_point_hit_count);
+
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+TEST(BreakPointInlinedBuiltin) {
+ i::FLAG_allow_natives_syntax = true;
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ v8::Local<v8::Function> builtin;
+ i::Handle<i::BreakPoint> bp;
+
// === Test inlined builtin ===
break_point_hit_count = 0;
builtin = CompileRun("Math.sin").As<v8::Function>();
@@ -1128,7 +1229,7 @@ TEST(BreakPointBuiltin) {
// Re-optimize.
CompileRun("%OptimizeFunctionOnNextCall(test);");
- CompileRun("test(0.3);");
+ ExpectBoolean("test(0.3) < 2", true);
CHECK_EQ(3, break_point_hit_count);
// Run without breakpoints.
@@ -1136,9 +1237,27 @@ TEST(BreakPointBuiltin) {
CompileRun("test(0.3);");
CHECK_EQ(3, break_point_hit_count);
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+TEST(BreakPointInlineBoundBuiltin) {
+ i::FLAG_allow_natives_syntax = true;
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ v8::Local<v8::Function> builtin;
+ i::Handle<i::BreakPoint> bp;
+
// === Test inlined bound builtin ===
break_point_hit_count = 0;
- builtin = CompileRun("String.prototype.repeat").As<v8::Function>();
+
+ builtin = CompileRun(
+ "var boundrepeat = String.prototype.repeat.bind('a');"
+ "String.prototype.repeat")
+ .As<v8::Function>();
CompileRun("function test(x) { return 'a' + boundrepeat(x) }");
CompileRun(
"test(4); test(5);"
@@ -1162,6 +1281,21 @@ TEST(BreakPointBuiltin) {
CompileRun("test(9);");
CHECK_EQ(3, break_point_hit_count);
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+TEST(BreakPointInlinedConstructorBuiltin) {
+ i::FLAG_allow_natives_syntax = true;
+ i::FLAG_experimental_inline_promise_constructor = true;
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ v8::Local<v8::Function> builtin;
+ i::Handle<i::BreakPoint> bp;
+
// === Test inlined constructor builtin (regular construct builtin) ===
break_point_hit_count = 0;
builtin = CompileRun("Promise").As<v8::Function>();
@@ -1173,7 +1307,7 @@ TEST(BreakPointBuiltin) {
// Run with breakpoint.
bp = SetBreakPoint(builtin, 0);
- CompileRun("new Promise();");
+ CompileRun("new Promise(()=>{});");
CHECK_EQ(1, break_point_hit_count);
CompileRun("test(7);");
CHECK_EQ(2, break_point_hit_count);
@@ -1188,6 +1322,21 @@ TEST(BreakPointBuiltin) {
CompileRun("test(9);");
CHECK_EQ(3, break_point_hit_count);
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+TEST(BreakPointBuiltinConcurrentOpt) {
+ i::FLAG_allow_natives_syntax = true;
+ i::FLAG_block_concurrent_recompilation = true;
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ v8::Local<v8::Function> builtin;
+ i::Handle<i::BreakPoint> bp;
+
// === Test concurrent optimization ===
break_point_hit_count = 0;
builtin = CompileRun("Math.sin").As<v8::Function>();
@@ -1212,6 +1361,20 @@ TEST(BreakPointBuiltin) {
CompileRun("test(0.3);");
CHECK_EQ(1, break_point_hit_count);
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+TEST(BreakPointBuiltinTFOperator) {
+ i::FLAG_allow_natives_syntax = true;
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ v8::Local<v8::Function> builtin;
+ i::Handle<i::BreakPoint> bp;
+
// === Test builtin represented as operator ===
break_point_hit_count = 0;
builtin = CompileRun("String.prototype.indexOf").As<v8::Function>();
@@ -1242,6 +1405,447 @@ TEST(BreakPointBuiltin) {
CheckDebuggerUnloaded();
}
+TEST(BreakPointBuiltinNewContext) {
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ v8::Local<v8::Function> builtin;
+ i::Handle<i::BreakPoint> bp;
+
+// === Test builtin from a new context ===
+// This does not work with no-snapshot build.
+#ifdef V8_USE_SNAPSHOT
+ break_point_hit_count = 0;
+ builtin = CompileRun("String.prototype.repeat").As<v8::Function>();
+ CompileRun("'a'.repeat(10)");
+ CHECK_EQ(0, break_point_hit_count);
+ // Set breakpoint.
+ bp = SetBreakPoint(builtin, 0);
+
+ {
+ // Create and use new context after breakpoint has been set.
+ v8::HandleScope handle_scope(env->GetIsolate());
+ v8::Local<v8::Context> new_context = v8::Context::New(env->GetIsolate());
+ v8::Context::Scope context_scope(new_context);
+
+ // Run with breakpoint.
+ CompileRun("'b'.repeat(10)");
+ CHECK_EQ(1, break_point_hit_count);
+
+ CompileRun("'b'.repeat(10)");
+ CHECK_EQ(2, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ CompileRun("'b'.repeat(10)");
+ CHECK_EQ(2, break_point_hit_count);
+ }
+#endif
+
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+void NoOpFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ args.GetReturnValue().Set(v8_num(2));
+}
+
+TEST(BreakPointApiFunction) {
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ i::Handle<i::BreakPoint> bp;
+
+ v8::Local<v8::FunctionTemplate> function_template =
+ v8::FunctionTemplate::New(env->GetIsolate(), NoOpFunctionCallback);
+
+ v8::Local<v8::Function> function =
+ function_template->GetFunction(env.context()).ToLocalChecked();
+
+ env->Global()->Set(env.context(), v8_str("f"), function).ToChecked();
+
+ // === Test simple builtin ===
+ break_point_hit_count = 0;
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(function, 0);
+ ExpectInt32("f()", 2);
+ CHECK_EQ(1, break_point_hit_count);
+
+ ExpectInt32("f()", 2);
+ CHECK_EQ(2, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ ExpectInt32("f()", 2);
+ CHECK_EQ(2, break_point_hit_count);
+
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+void GetWrapperCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ args.GetReturnValue().Set(
+ args[0]
+ .As<v8::Object>()
+ ->Get(args.GetIsolate()->GetCurrentContext(), args[1])
+ .ToLocalChecked());
+}
+
+TEST(BreakPointApiGetter) {
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ i::Handle<i::BreakPoint> bp;
+
+ v8::Local<v8::FunctionTemplate> function_template =
+ v8::FunctionTemplate::New(env->GetIsolate(), NoOpFunctionCallback);
+ v8::Local<v8::FunctionTemplate> get_template =
+ v8::FunctionTemplate::New(env->GetIsolate(), GetWrapperCallback);
+
+ v8::Local<v8::Function> function =
+ function_template->GetFunction(env.context()).ToLocalChecked();
+ v8::Local<v8::Function> get =
+ get_template->GetFunction(env.context()).ToLocalChecked();
+
+ env->Global()->Set(env.context(), v8_str("f"), function).ToChecked();
+ env->Global()->Set(env.context(), v8_str("get_wrapper"), get).ToChecked();
+ CompileRun(
+ "var o = {};"
+ "Object.defineProperty(o, 'f', { get: f, enumerable: true });");
+
+ // === Test API builtin as getter ===
+ break_point_hit_count = 0;
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(function, 0);
+ CompileRun("get_wrapper(o, 'f')");
+ CHECK_EQ(1, break_point_hit_count);
+
+ CompileRun("o.f");
+ CHECK_EQ(2, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ CompileRun("get_wrapper(o, 'f', 2)");
+ CHECK_EQ(2, break_point_hit_count);
+
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+void SetWrapperCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ CHECK(args[0]
+ .As<v8::Object>()
+ ->Set(args.GetIsolate()->GetCurrentContext(), args[1], args[2])
+ .FromJust());
+}
+
+TEST(BreakPointApiSetter) {
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ i::Handle<i::BreakPoint> bp;
+
+ v8::Local<v8::FunctionTemplate> function_template =
+ v8::FunctionTemplate::New(env->GetIsolate(), NoOpFunctionCallback);
+ v8::Local<v8::FunctionTemplate> set_template =
+ v8::FunctionTemplate::New(env->GetIsolate(), SetWrapperCallback);
+
+ v8::Local<v8::Function> function =
+ function_template->GetFunction(env.context()).ToLocalChecked();
+ v8::Local<v8::Function> set =
+ set_template->GetFunction(env.context()).ToLocalChecked();
+
+ env->Global()->Set(env.context(), v8_str("f"), function).ToChecked();
+ env->Global()->Set(env.context(), v8_str("set_wrapper"), set).ToChecked();
+
+ CompileRun(
+ "var o = {};"
+ "Object.defineProperty(o, 'f', { set: f, enumerable: true });");
+
+ // === Test API builtin as setter ===
+ break_point_hit_count = 0;
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(function, 0);
+
+ CompileRun("o.f = 3");
+ CHECK_EQ(1, break_point_hit_count);
+
+ CompileRun("set_wrapper(o, 'f', 2)");
+ CHECK_EQ(2, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ CompileRun("o.f = 3");
+ CHECK_EQ(2, break_point_hit_count);
+
+ // === Test API builtin as setter, with condition ===
+ break_point_hit_count = 0;
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(function, 0, "arguments[0] == 3");
+ CompileRun("set_wrapper(o, 'f', 2)");
+ CHECK_EQ(0, break_point_hit_count);
+
+ CompileRun("set_wrapper(o, 'f', 3)");
+ CHECK_EQ(1, break_point_hit_count);
+
+ CompileRun("o.f = 3");
+ CHECK_EQ(2, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ CompileRun("set_wrapper(o, 'f', 2)");
+ CHECK_EQ(2, break_point_hit_count);
+
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+TEST(BreakPointApiAccessor) {
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ i::Handle<i::BreakPoint> bp;
+
+ // Create 'foo' class, with a hidden property.
+ v8::Local<v8::ObjectTemplate> obj_template =
+ v8::ObjectTemplate::New(env->GetIsolate());
+ v8::Local<v8::FunctionTemplate> accessor_template =
+ v8::FunctionTemplate::New(env->GetIsolate(), NoOpFunctionCallback);
+ obj_template->SetAccessorProperty(v8_str("f"), accessor_template,
+ accessor_template);
+ v8::Local<v8::Object> obj =
+ obj_template->NewInstance(env.context()).ToLocalChecked();
+ env->Global()->Set(env.context(), v8_str("o"), obj).ToChecked();
+
+ v8::Local<v8::Function> function =
+ CompileRun("Object.getOwnPropertyDescriptor(o, 'f').set")
+ .As<v8::Function>();
+
+ // === Test API accessor ===
+ break_point_hit_count = 0;
+
+ CompileRun("function get_loop() { for (var i = 0; i < 10; i++) o.f }");
+ CompileRun("function set_loop() { for (var i = 0; i < 10; i++) o.f = 2 }");
+
+ CompileRun("get_loop(); set_loop();"); // Initialize ICs.
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(function, 0);
+
+ CompileRun("o.f = 3");
+ CHECK_EQ(1, break_point_hit_count);
+
+ CompileRun("o.f");
+ CHECK_EQ(2, break_point_hit_count);
+
+ CompileRun("for (var i = 0; i < 10; i++) o.f");
+ CHECK_EQ(12, break_point_hit_count);
+
+ CompileRun("get_loop();");
+ CHECK_EQ(22, break_point_hit_count);
+
+ CompileRun("for (var i = 0; i < 10; i++) o.f = 2");
+ CHECK_EQ(32, break_point_hit_count);
+
+ CompileRun("set_loop();");
+ CHECK_EQ(42, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ CompileRun("o.f = 3");
+ CompileRun("o.f");
+ CHECK_EQ(42, break_point_hit_count);
+
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+TEST(BreakPointInlineApiFunction) {
+ i::FLAG_allow_natives_syntax = true;
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+
+ i::Handle<i::BreakPoint> bp;
+
+ v8::Local<v8::FunctionTemplate> function_template =
+ v8::FunctionTemplate::New(env->GetIsolate(), NoOpFunctionCallback);
+
+ v8::Local<v8::Function> function =
+ function_template->GetFunction(env.context()).ToLocalChecked();
+
+ env->Global()->Set(env.context(), v8_str("f"), function).ToChecked();
+ CompileRun("function g() { return 1 + f(); }");
+
+ // === Test simple builtin ===
+ break_point_hit_count = 0;
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(function, 0);
+ ExpectInt32("g()", 3);
+ CHECK_EQ(1, break_point_hit_count);
+
+ ExpectInt32("g()", 3);
+ CHECK_EQ(2, break_point_hit_count);
+
+ CompileRun("%OptimizeFunctionOnNextCall(g)");
+ ExpectInt32("g()", 3);
+ CHECK_EQ(3, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ ExpectInt32("g()", 3);
+ CHECK_EQ(3, break_point_hit_count);
+
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
+// Test that a break point can be set at a return store location.
+TEST(BreakPointConditionBuiltin) {
+ i::FLAG_allow_natives_syntax = true;
+ i::FLAG_block_concurrent_recompilation = true;
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ SetDebugEventListener(env->GetIsolate(), DebugEventBreakPointHitCount);
+ v8::Local<v8::Function> builtin;
+ i::Handle<i::BreakPoint> bp;
+
+ // === Test global variable ===
+ break_point_hit_count = 0;
+ builtin = CompileRun("String.prototype.repeat").As<v8::Function>();
+ CompileRun("var condition = false");
+ CompileRun("'a'.repeat(10)");
+ CHECK_EQ(0, break_point_hit_count);
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(builtin, 0, "condition == true");
+ CompileRun("'b'.repeat(10)");
+ CHECK_EQ(0, break_point_hit_count);
+
+ CompileRun("condition = true");
+ CompileRun("'b'.repeat(10)");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ CompileRun("'b'.repeat(10)");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // === Test arguments ===
+ break_point_hit_count = 0;
+ builtin = CompileRun("String.prototype.repeat").As<v8::Function>();
+ CompileRun("function f(x) { return 'a'.repeat(x * 2); }");
+ CHECK_EQ(0, break_point_hit_count);
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(builtin, 0, "arguments[0] == 20");
+ ExpectString("f(5)", "aaaaaaaaaa");
+ CHECK_EQ(0, break_point_hit_count);
+
+ ExpectString("f(10)", "aaaaaaaaaaaaaaaaaaaa");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ ExpectString("f(10)", "aaaaaaaaaaaaaaaaaaaa");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // === Test adapted arguments ===
+ break_point_hit_count = 0;
+ builtin = CompileRun("String.prototype.repeat").As<v8::Function>();
+ CompileRun("function f(x) { return 'a'.repeat(x * 2, x); }");
+ CHECK_EQ(0, break_point_hit_count);
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(builtin, 0,
+ "arguments[1] == 10 && arguments[2] == undefined");
+ ExpectString("f(5)", "aaaaaaaaaa");
+ CHECK_EQ(0, break_point_hit_count);
+
+ ExpectString("f(10)", "aaaaaaaaaaaaaaaaaaaa");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ ExpectString("f(10)", "aaaaaaaaaaaaaaaaaaaa");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // === Test var-arg builtins ===
+ break_point_hit_count = 0;
+ builtin = CompileRun("String.fromCharCode").As<v8::Function>();
+ CompileRun("function f() { return String.fromCharCode(1, 2, 3); }");
+ CHECK_EQ(0, break_point_hit_count);
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(builtin, 0, "arguments.length == 3 && arguments[1] == 2");
+ CompileRun("f(1, 2, 3)");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ CompileRun("f(1, 2, 3)");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // === Test rest arguments ===
+ break_point_hit_count = 0;
+ builtin = CompileRun("String.fromCharCode").As<v8::Function>();
+ CompileRun("function f(...args) { return String.fromCharCode(...args); }");
+ CHECK_EQ(0, break_point_hit_count);
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(builtin, 0, "arguments.length == 3 && arguments[1] == 2");
+ CompileRun("f(1, 2, 3)");
+ CHECK_EQ(1, break_point_hit_count);
+
+ ClearBreakPoint(bp);
+ CompileRun("f(1, 3, 3)");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ CompileRun("f(1, 2, 3)");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // === Test receiver ===
+ break_point_hit_count = 0;
+ builtin = CompileRun("String.prototype.repeat").As<v8::Function>();
+ CompileRun("function f(x) { return x.repeat(10); }");
+ CHECK_EQ(0, break_point_hit_count);
+
+ // Run with breakpoint.
+ bp = SetBreakPoint(builtin, 0, "this == 'a'");
+ ExpectString("f('b')", "bbbbbbbbbb");
+ CHECK_EQ(0, break_point_hit_count);
+
+ ExpectString("f('a')", "aaaaaaaaaa");
+ CHECK_EQ(1, break_point_hit_count);
+
+ // Run without breakpoints.
+ ClearBreakPoint(bp);
+ ExpectString("f('a')", "aaaaaaaaaa");
+ CHECK_EQ(1, break_point_hit_count);
+
+ SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
TEST(BreakPointInlining) {
i::FLAG_allow_natives_syntax = true;
break_point_hit_count = 0;
@@ -2851,12 +3455,12 @@ TEST(PauseInScript) {
.ToLocalChecked();
// Set breakpoint in the script.
- i::Handle<i::BreakPoint> break_point =
- isolate->factory()->NewBreakPoint(0, isolate->factory()->empty_string());
- int position = 0;
i::Handle<i::Script> i_script(
i::Script::cast(v8::Utils::OpenHandle(*script)->shared()->script()));
- isolate->debug()->SetBreakPointForScript(i_script, break_point, &position);
+ i::Handle<i::String> condition = isolate->factory()->empty_string();
+ int position = 0;
+ int id;
+ isolate->debug()->SetBreakPointForScript(i_script, condition, &position, &id);
break_point_hit_count = 0;
v8::Local<v8::Value> r = script->Run(context).ToLocalChecked();
@@ -4497,8 +5101,8 @@ TEST(ContextData) {
SetDebugEventListener(isolate, ContextCheckEventListener);
// Default data value is undefined.
- CHECK(context_1->GetEmbedderData(0)->IsUndefined());
- CHECK(context_2->GetEmbedderData(0)->IsUndefined());
+ CHECK_EQ(0, context_1->GetNumberOfEmbedderDataFields());
+ CHECK_EQ(0, context_2->GetNumberOfEmbedderDataFields());
// Set and check different data values.
v8::Local<v8::String> data_1 = v8_str(isolate, "1");
@@ -4667,8 +5271,8 @@ TEST(EvalContextData) {
SetDebugEventListener(CcTest::isolate(), ContextCheckEventListener);
- // Default data value is undefined.
- CHECK(context_1->GetEmbedderData(0)->IsUndefined());
+ // Contexts initially do not have embedder data fields.
+ CHECK_EQ(0, context_1->GetNumberOfEmbedderDataFields());
// Set and check a data value.
v8::Local<v8::String> data_1 = v8_str(CcTest::isolate(), "1");
@@ -5777,6 +6381,7 @@ TEST(BreakLocationIterator) {
EnableDebugger(isolate);
CHECK(i_isolate->debug()->EnsureBreakInfo(shared));
+ i_isolate->debug()->PrepareFunctionForDebugExecution(shared);
Handle<i::DebugInfo> debug_info(shared->GetDebugInfo());
@@ -5836,10 +6441,11 @@ TEST(DebugStepOverFunctionWithCaughtException) {
CHECK_EQ(4, break_point_hit_count);
}
-bool out_of_memory_callback_called = false;
-void OutOfMemoryCallback(void* data) {
- out_of_memory_callback_called = true;
- reinterpret_cast<v8::Isolate*>(data)->IncreaseHeapLimitForDebugging();
+bool near_heap_limit_callback_called = false;
+size_t NearHeapLimitCallback(void* data, size_t current_heap_limit,
+ size_t initial_heap_limit) {
+ near_heap_limit_callback_called = true;
+ return initial_heap_limit + 10u * i::MB;
}
UNINITIALIZED_TEST(DebugSetOutOfMemoryListener) {
@@ -5852,14 +6458,14 @@ UNINITIALIZED_TEST(DebugSetOutOfMemoryListener) {
v8::Isolate::Scope i_scope(isolate);
v8::HandleScope scope(isolate);
LocalContext context(isolate);
- v8::debug::SetOutOfMemoryCallback(isolate, OutOfMemoryCallback,
- reinterpret_cast<void*>(isolate));
- CHECK(!out_of_memory_callback_called);
+ isolate->AddNearHeapLimitCallback(NearHeapLimitCallback, nullptr);
+ CHECK(!near_heap_limit_callback_called);
// The following allocation fails unless the out-of-memory callback
// increases the heap limit.
int length = 10 * i::MB / i::kPointerSize;
i_isolate->factory()->NewFixedArray(length, i::TENURED);
- CHECK(out_of_memory_callback_called);
+ CHECK(near_heap_limit_callback_called);
+ isolate->RemoveNearHeapLimitCallback(NearHeapLimitCallback, 0);
}
isolate->Dispose();
}
@@ -6073,10 +6679,9 @@ TEST(DebugEvaluateNoSideEffect) {
// itself contains additional sanity checks.
for (i::Handle<i::JSFunction> fun : all_functions) {
bool failed = false;
- {
- i::NoSideEffectScope scope(isolate, true);
- failed = !isolate->debug()->PerformSideEffectCheck(fun);
- }
+ isolate->debug()->StartSideEffectCheckMode();
+ failed = !isolate->debug()->PerformSideEffectCheck(fun);
+ isolate->debug()->StopSideEffectCheckMode();
if (failed) isolate->clear_pending_exception();
}
DisableDebugger(env->GetIsolate());