[inspector] disable debug breaks for builtins when called from API
TBR=luoe@chromium.org Bug: chromium:976713 Change-Id: Ib92c6054a017a94ad23721de240b8a20d87c9f85 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1680544 Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#62437}
This commit is contained in:
parent
1340645339
commit
f3b302193c
@ -4276,10 +4276,10 @@ MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
|
||||
PREPARE_FOR_EXECUTION(context, Object, ObjectProtoToString, String);
|
||||
auto self = Utils::OpenHandle(this);
|
||||
Local<Value> result;
|
||||
has_pending_exception =
|
||||
!ToLocal<Value>(i::Execution::Call(isolate, isolate->object_to_string(),
|
||||
self, 0, nullptr),
|
||||
&result);
|
||||
has_pending_exception = !ToLocal<Value>(
|
||||
i::Execution::CallBuiltin(isolate, isolate->object_to_string(), self, 0,
|
||||
nullptr),
|
||||
&result);
|
||||
RETURN_ON_FAILED_EXECUTION(String);
|
||||
RETURN_ESCAPED(Local<String>::Cast(result));
|
||||
}
|
||||
@ -6616,8 +6616,8 @@ MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
|
||||
Local<Value> result;
|
||||
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
|
||||
has_pending_exception =
|
||||
!ToLocal<Value>(i::Execution::Call(isolate, isolate->map_get(), self,
|
||||
arraysize(argv), argv),
|
||||
!ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->map_get(),
|
||||
self, arraysize(argv), argv),
|
||||
&result);
|
||||
RETURN_ON_FAILED_EXECUTION(Value);
|
||||
RETURN_ESCAPED(result);
|
||||
@ -6630,9 +6630,10 @@ MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
|
||||
i::Handle<i::Object> result;
|
||||
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
|
||||
Utils::OpenHandle(*value)};
|
||||
has_pending_exception = !i::Execution::Call(isolate, isolate->map_set(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
has_pending_exception =
|
||||
!i::Execution::CallBuiltin(isolate, isolate->map_set(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
RETURN_ON_FAILED_EXECUTION(Map);
|
||||
RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
|
||||
}
|
||||
@ -6643,9 +6644,10 @@ Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
|
||||
auto self = Utils::OpenHandle(this);
|
||||
i::Handle<i::Object> result;
|
||||
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
|
||||
has_pending_exception = !i::Execution::Call(isolate, isolate->map_has(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
has_pending_exception =
|
||||
!i::Execution::CallBuiltin(isolate, isolate->map_has(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
||||
return Just(result->IsTrue(isolate));
|
||||
}
|
||||
@ -6656,9 +6658,10 @@ Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
|
||||
auto self = Utils::OpenHandle(this);
|
||||
i::Handle<i::Object> result;
|
||||
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
|
||||
has_pending_exception = !i::Execution::Call(isolate, isolate->map_delete(),
|
||||
self, arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
has_pending_exception =
|
||||
!i::Execution::CallBuiltin(isolate, isolate->map_delete(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
||||
return Just(result->IsTrue(isolate));
|
||||
}
|
||||
@ -6744,9 +6747,10 @@ MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
|
||||
auto self = Utils::OpenHandle(this);
|
||||
i::Handle<i::Object> result;
|
||||
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
|
||||
has_pending_exception = !i::Execution::Call(isolate, isolate->set_add(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
has_pending_exception =
|
||||
!i::Execution::CallBuiltin(isolate, isolate->set_add(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
RETURN_ON_FAILED_EXECUTION(Set);
|
||||
RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
|
||||
}
|
||||
@ -6757,9 +6761,10 @@ Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
|
||||
auto self = Utils::OpenHandle(this);
|
||||
i::Handle<i::Object> result;
|
||||
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
|
||||
has_pending_exception = !i::Execution::Call(isolate, isolate->set_has(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
has_pending_exception =
|
||||
!i::Execution::CallBuiltin(isolate, isolate->set_has(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
||||
return Just(result->IsTrue(isolate));
|
||||
}
|
||||
@ -6770,9 +6775,10 @@ Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
|
||||
auto self = Utils::OpenHandle(this);
|
||||
i::Handle<i::Object> result;
|
||||
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
|
||||
has_pending_exception = !i::Execution::Call(isolate, isolate->set_delete(),
|
||||
self, arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
has_pending_exception =
|
||||
!i::Execution::CallBuiltin(isolate, isolate->set_delete(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
||||
return Just(result->IsTrue(isolate));
|
||||
}
|
||||
@ -6873,9 +6879,10 @@ MaybeLocal<Promise> Promise::Catch(Local<Context> context,
|
||||
auto self = Utils::OpenHandle(this);
|
||||
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
|
||||
i::Handle<i::Object> result;
|
||||
has_pending_exception = !i::Execution::Call(isolate, isolate->promise_catch(),
|
||||
self, arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
has_pending_exception =
|
||||
!i::Execution::CallBuiltin(isolate, isolate->promise_catch(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
RETURN_ON_FAILED_EXECUTION(Promise);
|
||||
RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
|
||||
}
|
||||
@ -6886,9 +6893,10 @@ MaybeLocal<Promise> Promise::Then(Local<Context> context,
|
||||
auto self = Utils::OpenHandle(this);
|
||||
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
|
||||
i::Handle<i::Object> result;
|
||||
has_pending_exception = !i::Execution::Call(isolate, isolate->promise_then(),
|
||||
self, arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
has_pending_exception =
|
||||
!i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
RETURN_ON_FAILED_EXECUTION(Promise);
|
||||
RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
|
||||
}
|
||||
@ -6901,9 +6909,10 @@ MaybeLocal<Promise> Promise::Then(Local<Context> context,
|
||||
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*on_fulfilled),
|
||||
Utils::OpenHandle(*on_rejected)};
|
||||
i::Handle<i::Object> result;
|
||||
has_pending_exception = !i::Execution::Call(isolate, isolate->promise_then(),
|
||||
self, arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
has_pending_exception =
|
||||
!i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
RETURN_ON_FAILED_EXECUTION(Promise);
|
||||
RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
|
||||
}
|
||||
@ -9600,8 +9609,8 @@ v8::MaybeLocal<v8::Value> debug::WeakMap::Get(v8::Local<v8::Context> context,
|
||||
Local<Value> result;
|
||||
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
|
||||
has_pending_exception =
|
||||
!ToLocal<Value>(i::Execution::Call(isolate, isolate->weakmap_get(), self,
|
||||
arraysize(argv), argv),
|
||||
!ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->weakmap_get(),
|
||||
self, arraysize(argv), argv),
|
||||
&result);
|
||||
RETURN_ON_FAILED_EXECUTION(Value);
|
||||
RETURN_ESCAPED(result);
|
||||
@ -9615,9 +9624,10 @@ v8::MaybeLocal<debug::WeakMap> debug::WeakMap::Set(
|
||||
i::Handle<i::Object> result;
|
||||
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
|
||||
Utils::OpenHandle(*value)};
|
||||
has_pending_exception = !i::Execution::Call(isolate, isolate->weakmap_set(),
|
||||
self, arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
has_pending_exception =
|
||||
!i::Execution::CallBuiltin(isolate, isolate->weakmap_set(), self,
|
||||
arraysize(argv), argv)
|
||||
.ToHandle(&result);
|
||||
RETURN_ON_FAILED_EXECUTION(WeakMap);
|
||||
RETURN_ESCAPED(Local<WeakMap>::Cast(Utils::ToLocal(result)));
|
||||
}
|
||||
|
@ -489,13 +489,13 @@ class PostponeInterruptsScope {
|
||||
|
||||
class WeakMap : public v8::Object {
|
||||
public:
|
||||
V8_WARN_UNUSED_RESULT v8::MaybeLocal<v8::Value> Get(
|
||||
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT v8::MaybeLocal<v8::Value> Get(
|
||||
v8::Local<v8::Context> context, v8::Local<v8::Value> key);
|
||||
V8_WARN_UNUSED_RESULT v8::MaybeLocal<WeakMap> Set(
|
||||
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT v8::MaybeLocal<WeakMap> Set(
|
||||
v8::Local<v8::Context> context, v8::Local<v8::Value> key,
|
||||
v8::Local<v8::Value> value);
|
||||
|
||||
static Local<WeakMap> New(v8::Isolate* isolate);
|
||||
V8_EXPORT_PRIVATE static Local<WeakMap> New(v8::Isolate* isolate);
|
||||
V8_INLINE static WeakMap* Cast(Value* obj);
|
||||
|
||||
private:
|
||||
|
@ -358,6 +358,16 @@ MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
|
||||
argc, argv));
|
||||
}
|
||||
|
||||
MaybeHandle<Object> Execution::CallBuiltin(Isolate* isolate,
|
||||
Handle<JSFunction> builtin,
|
||||
Handle<Object> receiver, int argc,
|
||||
Handle<Object> argv[]) {
|
||||
DCHECK(builtin->code().is_builtin());
|
||||
DisableBreak no_break(isolate->debug());
|
||||
return Invoke(isolate, InvokeParams::SetUpForCall(isolate, builtin, receiver,
|
||||
argc, argv));
|
||||
}
|
||||
|
||||
// static
|
||||
MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor,
|
||||
int argc, Handle<Object> argv[]) {
|
||||
|
@ -31,6 +31,10 @@ class Execution final : public AllStatic {
|
||||
Isolate* isolate, Handle<Object> callable, Handle<Object> receiver,
|
||||
int argc, Handle<Object> argv[]);
|
||||
|
||||
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> CallBuiltin(
|
||||
Isolate* isolate, Handle<JSFunction> builtin, Handle<Object> receiver,
|
||||
int argc, Handle<Object> argv[]);
|
||||
|
||||
// Construct object from function, the caller supplies an array of
|
||||
// arguments.
|
||||
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> New(
|
||||
|
@ -569,6 +569,110 @@ TEST(BreakPointBuiltin) {
|
||||
CheckDebuggerUnloaded();
|
||||
}
|
||||
|
||||
TEST(BreakPointApiIntrinsics) {
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
||||
DebugEventCounter delegate;
|
||||
v8::debug::SetDebugDelegate(env->GetIsolate(), &delegate);
|
||||
|
||||
v8::Local<v8::Function> builtin;
|
||||
|
||||
// === Test that using API-exposed functions won't trigger breakpoints ===
|
||||
{
|
||||
v8::Local<v8::Function> weakmap_get =
|
||||
CompileRun("WeakMap.prototype.get").As<v8::Function>();
|
||||
SetBreakPoint(weakmap_get, 0);
|
||||
v8::Local<v8::Function> weakmap_set =
|
||||
CompileRun("WeakMap.prototype.set").As<v8::Function>();
|
||||
SetBreakPoint(weakmap_set, 0);
|
||||
|
||||
// Run with breakpoint.
|
||||
break_point_hit_count = 0;
|
||||
CompileRun("var w = new WeakMap(); w.set(w, 1); w.get(w);");
|
||||
CHECK_EQ(2, break_point_hit_count);
|
||||
|
||||
break_point_hit_count = 0;
|
||||
v8::Local<v8::debug::WeakMap> weakmap =
|
||||
v8::debug::WeakMap::New(env->GetIsolate());
|
||||
CHECK(!weakmap->Set(env.local(), weakmap, v8_num(1)).IsEmpty());
|
||||
CHECK(!weakmap->Get(env.local(), weakmap).IsEmpty());
|
||||
CHECK_EQ(0, break_point_hit_count);
|
||||
}
|
||||
|
||||
{
|
||||
v8::Local<v8::Function> object_to_string =
|
||||
CompileRun("Object.prototype.toString").As<v8::Function>();
|
||||
SetBreakPoint(object_to_string, 0);
|
||||
|
||||
// Run with breakpoint.
|
||||
break_point_hit_count = 0;
|
||||
CompileRun("var o = {}; o.toString();");
|
||||
CHECK_EQ(1, break_point_hit_count);
|
||||
|
||||
break_point_hit_count = 0;
|
||||
v8::Local<v8::Object> object = v8::Object::New(env->GetIsolate());
|
||||
CHECK(!object->ObjectProtoToString(env.local()).IsEmpty());
|
||||
CHECK_EQ(0, break_point_hit_count);
|
||||
}
|
||||
|
||||
{
|
||||
v8::Local<v8::Function> map_set =
|
||||
CompileRun("Map.prototype.set").As<v8::Function>();
|
||||
v8::Local<v8::Function> map_get =
|
||||
CompileRun("Map.prototype.get").As<v8::Function>();
|
||||
v8::Local<v8::Function> map_has =
|
||||
CompileRun("Map.prototype.has").As<v8::Function>();
|
||||
v8::Local<v8::Function> map_delete =
|
||||
CompileRun("Map.prototype.delete").As<v8::Function>();
|
||||
SetBreakPoint(map_set, 0);
|
||||
SetBreakPoint(map_get, 0);
|
||||
SetBreakPoint(map_has, 0);
|
||||
SetBreakPoint(map_delete, 0);
|
||||
|
||||
// Run with breakpoint.
|
||||
break_point_hit_count = 0;
|
||||
CompileRun(
|
||||
"var m = new Map(); m.set(m, 1); m.get(m); m.has(m); m.delete(m);");
|
||||
CHECK_EQ(4, break_point_hit_count);
|
||||
|
||||
break_point_hit_count = 0;
|
||||
v8::Local<v8::Map> map = v8::Map::New(env->GetIsolate());
|
||||
CHECK(!map->Set(env.local(), map, v8_num(1)).IsEmpty());
|
||||
CHECK(!map->Get(env.local(), map).IsEmpty());
|
||||
CHECK(map->Has(env.local(), map).FromJust());
|
||||
CHECK(map->Delete(env.local(), map).FromJust());
|
||||
CHECK_EQ(0, break_point_hit_count);
|
||||
}
|
||||
|
||||
{
|
||||
v8::Local<v8::Function> set_add =
|
||||
CompileRun("Set.prototype.add").As<v8::Function>();
|
||||
v8::Local<v8::Function> set_get =
|
||||
CompileRun("Set.prototype.has").As<v8::Function>();
|
||||
v8::Local<v8::Function> set_delete =
|
||||
CompileRun("Set.prototype.delete").As<v8::Function>();
|
||||
SetBreakPoint(set_add, 0);
|
||||
SetBreakPoint(set_get, 0);
|
||||
SetBreakPoint(set_delete, 0);
|
||||
|
||||
// Run with breakpoint.
|
||||
break_point_hit_count = 0;
|
||||
CompileRun("var s = new Set(); s.add(s); s.has(s); s.delete(s);");
|
||||
CHECK_EQ(3, break_point_hit_count);
|
||||
|
||||
break_point_hit_count = 0;
|
||||
v8::Local<v8::Set> set = v8::Set::New(env->GetIsolate());
|
||||
CHECK(!set->Add(env.local(), set).IsEmpty());
|
||||
CHECK(set->Has(env.local(), set).FromJust());
|
||||
CHECK(set->Delete(env.local(), set).FromJust());
|
||||
CHECK_EQ(0, break_point_hit_count);
|
||||
}
|
||||
|
||||
v8::debug::SetDebugDelegate(env->GetIsolate(), nullptr);
|
||||
CheckDebuggerUnloaded();
|
||||
}
|
||||
|
||||
TEST(BreakPointJSBuiltin) {
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
Loading…
Reference in New Issue
Block a user