void V8InjectedScriptHost::functionDetailsCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { if (info.Length() < 1 || !info[0]->IsFunction()) return; v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(info[0]); int lineNumber = function->GetScriptLineNumber(); int columnNumber = function->GetScriptColumnNumber(); v8::Isolate* isolate = info.GetIsolate(); v8::Local<v8::Object> location = v8::Object::New(isolate); location->Set(v8AtomicString(isolate, "lineNumber"), v8::Integer::New(isolate, lineNumber)); location->Set(v8AtomicString(isolate, "columnNumber"), v8::Integer::New(isolate, columnNumber)); location->Set(v8AtomicString(isolate, "scriptId"), v8::Integer::New(isolate, function->ScriptId())->ToString(isolate)); v8::Local<v8::Object> result = v8::Object::New(isolate); result->Set(v8AtomicString(isolate, "location"), location); v8::Local<v8::String> name = functionDisplayName(function); result->Set(v8AtomicString(isolate, "functionName"), name.IsEmpty() ? v8AtomicString(isolate, "") : name); result->Set(v8AtomicString(isolate, "isGenerator"), v8::Boolean::New(isolate, function->IsGeneratorFunction())); InjectedScriptHost* host = V8InjectedScriptHost::unwrap(info.GetIsolate()->GetCurrentContext(), info.Holder()); V8DebuggerImpl& debugger = static_cast<V8DebuggerImpl&>(host->debugger()); v8::MaybeLocal<v8::Value> scopes = debugger.functionScopes(function); if (!scopes.IsEmpty() && scopes.ToLocalChecked()->IsArray()) result->Set(v8AtomicString(isolate, "rawScopes"), scopes.ToLocalChecked()); v8SetReturnValue(info, result); }
void V8InjectedScriptHost::collectionEntriesCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { if (info.Length() < 1 || !info[0]->IsObject()) return; v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(info[0]); InjectedScriptHost* host = V8InjectedScriptHost::unwrap(info.GetIsolate()->GetCurrentContext(), info.Holder()); V8DebuggerImpl& debugger = static_cast<V8DebuggerImpl&>(host->debugger()); v8SetReturnValue(info, debugger.collectionEntries(object)); }
void V8InjectedScriptHost::setFunctionVariableValueCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { if (info.Length() < 4 || !info[0]->IsFunction() || !info[1]->IsInt32() || !info[2]->IsString()) return; v8::Local<v8::Value> functionValue = info[0]; int scopeIndex = info[1].As<v8::Int32>()->Value(); String variableName = toCoreStringWithUndefinedOrNullCheck(info[2]); v8::Local<v8::Value> newValue = info[3]; InjectedScriptHost* host = V8InjectedScriptHost::unwrap(info.GetIsolate()->GetCurrentContext(), info.Holder()); V8DebuggerImpl& debugger = static_cast<V8DebuggerImpl&>(host->debugger()); v8SetReturnValue(info, debugger.setFunctionVariableValue(functionValue, scopeIndex, variableName, newValue)); }
void V8InjectedScriptHost::getEventListenersCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { if (info.Length() < 1) return; InjectedScriptHost* host = V8InjectedScriptHost::unwrap(info.GetIsolate()->GetCurrentContext(), info.Holder()); V8DebuggerClient* client = static_cast<V8DebuggerImpl&>(host->debugger()).client(); EventListenerInfoMap listenerInfo; client->eventListeners(info[0], listenerInfo); v8::Local<v8::Object> result = v8::Object::New(info.GetIsolate()); Vector<String> types; for (auto& it : listenerInfo) types.append(it.key); nonCopyingSort(types.begin(), types.end(), WTF::codePointCompareLessThan); for (const String& type : types) { v8::Local<v8::Array> listeners = wrapListenerFunctions(info.GetIsolate(), *listenerInfo.get(type)); if (!listeners->Length()) continue; result->Set(v8String(info.GetIsolate(), type), listeners); } v8SetReturnValue(info, result); }