Commit f3b30219 authored by Yang Guo's avatar Yang Guo Committed by Commit Bot

[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/+/1680544Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62437}
parent 13406453
...@@ -4276,10 +4276,10 @@ MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) { ...@@ -4276,10 +4276,10 @@ MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
PREPARE_FOR_EXECUTION(context, Object, ObjectProtoToString, String); PREPARE_FOR_EXECUTION(context, Object, ObjectProtoToString, String);
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
Local<Value> result; Local<Value> result;
has_pending_exception = has_pending_exception = !ToLocal<Value>(
!ToLocal<Value>(i::Execution::Call(isolate, isolate->object_to_string(), i::Execution::CallBuiltin(isolate, isolate->object_to_string(), self, 0,
self, 0, nullptr), nullptr),
&result); &result);
RETURN_ON_FAILED_EXECUTION(String); RETURN_ON_FAILED_EXECUTION(String);
RETURN_ESCAPED(Local<String>::Cast(result)); RETURN_ESCAPED(Local<String>::Cast(result));
} }
...@@ -6616,8 +6616,8 @@ MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) { ...@@ -6616,8 +6616,8 @@ MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
Local<Value> result; Local<Value> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
has_pending_exception = has_pending_exception =
!ToLocal<Value>(i::Execution::Call(isolate, isolate->map_get(), self, !ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->map_get(),
arraysize(argv), argv), self, arraysize(argv), argv),
&result); &result);
RETURN_ON_FAILED_EXECUTION(Value); RETURN_ON_FAILED_EXECUTION(Value);
RETURN_ESCAPED(result); RETURN_ESCAPED(result);
...@@ -6630,9 +6630,10 @@ MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key, ...@@ -6630,9 +6630,10 @@ MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
i::Handle<i::Object> result; i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key), i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
Utils::OpenHandle(*value)}; Utils::OpenHandle(*value)};
has_pending_exception = !i::Execution::Call(isolate, isolate->map_set(), self, has_pending_exception =
arraysize(argv), argv) !i::Execution::CallBuiltin(isolate, isolate->map_set(), self,
.ToHandle(&result); arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Map); RETURN_ON_FAILED_EXECUTION(Map);
RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result))); RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
} }
...@@ -6643,9 +6644,10 @@ Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) { ...@@ -6643,9 +6644,10 @@ Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result; i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
has_pending_exception = !i::Execution::Call(isolate, isolate->map_has(), self, has_pending_exception =
arraysize(argv), argv) !i::Execution::CallBuiltin(isolate, isolate->map_has(), self,
.ToHandle(&result); arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(result->IsTrue(isolate)); return Just(result->IsTrue(isolate));
} }
...@@ -6656,9 +6658,10 @@ Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) { ...@@ -6656,9 +6658,10 @@ Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result; i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
has_pending_exception = !i::Execution::Call(isolate, isolate->map_delete(), has_pending_exception =
self, arraysize(argv), argv) !i::Execution::CallBuiltin(isolate, isolate->map_delete(), self,
.ToHandle(&result); arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(result->IsTrue(isolate)); return Just(result->IsTrue(isolate));
} }
...@@ -6744,9 +6747,10 @@ MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) { ...@@ -6744,9 +6747,10 @@ MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result; i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
has_pending_exception = !i::Execution::Call(isolate, isolate->set_add(), self, has_pending_exception =
arraysize(argv), argv) !i::Execution::CallBuiltin(isolate, isolate->set_add(), self,
.ToHandle(&result); arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Set); RETURN_ON_FAILED_EXECUTION(Set);
RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result))); RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
} }
...@@ -6757,9 +6761,10 @@ Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) { ...@@ -6757,9 +6761,10 @@ Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result; i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
has_pending_exception = !i::Execution::Call(isolate, isolate->set_has(), self, has_pending_exception =
arraysize(argv), argv) !i::Execution::CallBuiltin(isolate, isolate->set_has(), self,
.ToHandle(&result); arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(result->IsTrue(isolate)); return Just(result->IsTrue(isolate));
} }
...@@ -6770,9 +6775,10 @@ Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) { ...@@ -6770,9 +6775,10 @@ Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result; i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
has_pending_exception = !i::Execution::Call(isolate, isolate->set_delete(), has_pending_exception =
self, arraysize(argv), argv) !i::Execution::CallBuiltin(isolate, isolate->set_delete(), self,
.ToHandle(&result); arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(result->IsTrue(isolate)); return Just(result->IsTrue(isolate));
} }
...@@ -6873,9 +6879,10 @@ MaybeLocal<Promise> Promise::Catch(Local<Context> context, ...@@ -6873,9 +6879,10 @@ MaybeLocal<Promise> Promise::Catch(Local<Context> context,
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)}; i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
i::Handle<i::Object> result; i::Handle<i::Object> result;
has_pending_exception = !i::Execution::Call(isolate, isolate->promise_catch(), has_pending_exception =
self, arraysize(argv), argv) !i::Execution::CallBuiltin(isolate, isolate->promise_catch(), self,
.ToHandle(&result); arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Promise); RETURN_ON_FAILED_EXECUTION(Promise);
RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result))); RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
} }
...@@ -6886,9 +6893,10 @@ MaybeLocal<Promise> Promise::Then(Local<Context> context, ...@@ -6886,9 +6893,10 @@ MaybeLocal<Promise> Promise::Then(Local<Context> context,
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)}; i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
i::Handle<i::Object> result; i::Handle<i::Object> result;
has_pending_exception = !i::Execution::Call(isolate, isolate->promise_then(), has_pending_exception =
self, arraysize(argv), argv) !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
.ToHandle(&result); arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Promise); RETURN_ON_FAILED_EXECUTION(Promise);
RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result))); RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
} }
...@@ -6901,9 +6909,10 @@ MaybeLocal<Promise> Promise::Then(Local<Context> context, ...@@ -6901,9 +6909,10 @@ MaybeLocal<Promise> Promise::Then(Local<Context> context,
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*on_fulfilled), i::Handle<i::Object> argv[] = {Utils::OpenHandle(*on_fulfilled),
Utils::OpenHandle(*on_rejected)}; Utils::OpenHandle(*on_rejected)};
i::Handle<i::Object> result; i::Handle<i::Object> result;
has_pending_exception = !i::Execution::Call(isolate, isolate->promise_then(), has_pending_exception =
self, arraysize(argv), argv) !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
.ToHandle(&result); arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Promise); RETURN_ON_FAILED_EXECUTION(Promise);
RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result))); RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
} }
...@@ -9600,8 +9609,8 @@ v8::MaybeLocal<v8::Value> debug::WeakMap::Get(v8::Local<v8::Context> context, ...@@ -9600,8 +9609,8 @@ v8::MaybeLocal<v8::Value> debug::WeakMap::Get(v8::Local<v8::Context> context,
Local<Value> result; Local<Value> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
has_pending_exception = has_pending_exception =
!ToLocal<Value>(i::Execution::Call(isolate, isolate->weakmap_get(), self, !ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->weakmap_get(),
arraysize(argv), argv), self, arraysize(argv), argv),
&result); &result);
RETURN_ON_FAILED_EXECUTION(Value); RETURN_ON_FAILED_EXECUTION(Value);
RETURN_ESCAPED(result); RETURN_ESCAPED(result);
...@@ -9615,9 +9624,10 @@ v8::MaybeLocal<debug::WeakMap> debug::WeakMap::Set( ...@@ -9615,9 +9624,10 @@ v8::MaybeLocal<debug::WeakMap> debug::WeakMap::Set(
i::Handle<i::Object> result; i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key), i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
Utils::OpenHandle(*value)}; Utils::OpenHandle(*value)};
has_pending_exception = !i::Execution::Call(isolate, isolate->weakmap_set(), has_pending_exception =
self, arraysize(argv), argv) !i::Execution::CallBuiltin(isolate, isolate->weakmap_set(), self,
.ToHandle(&result); arraysize(argv), argv)
.ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(WeakMap); RETURN_ON_FAILED_EXECUTION(WeakMap);
RETURN_ESCAPED(Local<WeakMap>::Cast(Utils::ToLocal(result))); RETURN_ESCAPED(Local<WeakMap>::Cast(Utils::ToLocal(result)));
} }
......
...@@ -489,13 +489,13 @@ class PostponeInterruptsScope { ...@@ -489,13 +489,13 @@ class PostponeInterruptsScope {
class WeakMap : public v8::Object { class WeakMap : public v8::Object {
public: 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::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::Context> context, v8::Local<v8::Value> key,
v8::Local<v8::Value> value); 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); V8_INLINE static WeakMap* Cast(Value* obj);
private: private:
......
...@@ -358,6 +358,16 @@ MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable, ...@@ -358,6 +358,16 @@ MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
argc, argv)); 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 // static
MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor, MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor,
int argc, Handle<Object> argv[]) { int argc, Handle<Object> argv[]) {
......
...@@ -31,6 +31,10 @@ class Execution final : public AllStatic { ...@@ -31,6 +31,10 @@ class Execution final : public AllStatic {
Isolate* isolate, Handle<Object> callable, Handle<Object> receiver, Isolate* isolate, Handle<Object> callable, Handle<Object> receiver,
int argc, Handle<Object> argv[]); 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 // Construct object from function, the caller supplies an array of
// arguments. // arguments.
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> New( V8_WARN_UNUSED_RESULT static MaybeHandle<Object> New(
......
...@@ -569,6 +569,110 @@ TEST(BreakPointBuiltin) { ...@@ -569,6 +569,110 @@ TEST(BreakPointBuiltin) {
CheckDebuggerUnloaded(); 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) { TEST(BreakPointJSBuiltin) {
LocalContext env; LocalContext env;
v8::HandleScope scope(env->GetIsolate()); v8::HandleScope scope(env->GetIsolate());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment