1
1
#include " inspector_agent.h"
2
2
3
3
#include " inspector_io.h"
4
+ #include " base-object.h"
5
+ #include " base-object-inl.h"
4
6
#include " env.h"
5
7
#include " env-inl.h"
6
8
#include " node.h"
@@ -27,6 +29,7 @@ using v8::Context;
27
29
using v8::External;
28
30
using v8::Function;
29
31
using v8::FunctionCallbackInfo;
32
+ using v8::FunctionTemplate;
30
33
using v8::HandleScope;
31
34
using v8::Isolate;
32
35
using v8::Local;
@@ -250,79 +253,81 @@ class JsBindingsSessionDelegate : public InspectorSessionDelegate {
250
253
Persistent<Function> callback_;
251
254
};
252
255
253
- void SetDelegate (Environment* env, Local<Object> inspector,
254
- JsBindingsSessionDelegate* delegate) {
255
- inspector->SetPrivate (env->context (),
256
- env->inspector_delegate_private_symbol (),
257
- v8::External::New (env->isolate (), delegate));
258
- }
259
-
260
- Maybe<JsBindingsSessionDelegate*> GetDelegate (
261
- const FunctionCallbackInfo<Value>& info) {
262
- Environment* env = Environment::GetCurrent (info);
263
- Local<Value> delegate;
264
- MaybeLocal<Value> maybe_delegate =
265
- info.This ()->GetPrivate (env->context (),
266
- env->inspector_delegate_private_symbol ());
267
-
268
- if (maybe_delegate.ToLocal (&delegate)) {
269
- CHECK (delegate->IsExternal ());
270
- void * value = delegate.As <External>()->Value ();
271
- if (value != nullptr ) {
272
- return v8::Just (static_cast <JsBindingsSessionDelegate*>(value));
256
+ class JSBindingsConnection : public BaseObject {
257
+ public:
258
+ JSBindingsConnection (Environment* env,
259
+ Local<Object> wrap,
260
+ Local<Object> receiver,
261
+ Local<Function> callback)
262
+ : BaseObject(env, wrap) {
263
+ MakeWeak<JSBindingsConnection>(this );
264
+ Wrap (wrap, this );
265
+
266
+ Agent* inspector = env->inspector_agent ();
267
+ if (inspector->delegate () != nullptr ) {
268
+ env->ThrowTypeError (" Session is already attached" );
269
+ return ;
273
270
}
271
+ delegate_ = new JsBindingsSessionDelegate (env, wrap, receiver, callback);
272
+ inspector->Connect (delegate_);
274
273
}
275
- env->ThrowError (" Inspector is not connected" );
276
- return v8::Nothing<JsBindingsSessionDelegate*>();
277
- }
278
274
279
- void Dispatch (const FunctionCallbackInfo<Value>& info) {
280
- Environment* env = Environment::GetCurrent (info);
281
- if (!info[0 ]->IsString ()) {
282
- env->ThrowError (" Inspector message must be a string" );
283
- return ;
275
+ ~JSBindingsConnection () override {
276
+ Disconnect ();
284
277
}
285
- Maybe<JsBindingsSessionDelegate*> maybe_delegate = GetDelegate (info);
286
- if (maybe_delegate.IsNothing ())
287
- return ;
288
- Agent* inspector = env->inspector_agent ();
289
- CHECK_EQ (maybe_delegate.ToChecked (), inspector->delegate ());
290
- inspector->Dispatch (ToProtocolString (env->isolate (), info[0 ])->string ());
291
- }
292
278
293
- void Disconnect (const FunctionCallbackInfo<Value>& info) {
294
- Environment* env = Environment::GetCurrent (info);
295
- Maybe<JsBindingsSessionDelegate*> delegate = GetDelegate (info);
296
- if (delegate.IsNothing ()) {
297
- return ;
279
+ JsBindingsSessionDelegate* delegate () {
280
+ return delegate_;
298
281
}
299
- delegate.ToChecked ()->Disconnect ();
300
- SetDelegate (env, info.This (), nullptr );
301
- delete delegate.ToChecked ();
302
- }
303
282
304
- void ConnectJSBindingsSession (const FunctionCallbackInfo<Value>& info) {
305
- Environment* env = Environment::GetCurrent (info);
306
- if (!info[0 ]->IsFunction ()) {
307
- env->ThrowError (" Message callback is required" );
308
- return ;
283
+ static void New (const FunctionCallbackInfo<Value>& info) {
284
+ Environment* env = Environment::GetCurrent (info);
285
+ if (!info[0 ]->IsFunction ()) {
286
+ env->ThrowTypeError (" Message callback is required" );
287
+ return ;
288
+ }
289
+ Local<Function> callback = info[0 ].As <Function>();
290
+ Local<Object> receiver =
291
+ info[1 ]->IsObject () ? info[1 ].As <Object>() : info.This ();
292
+ new JSBindingsConnection (env, info.This (), receiver, callback);
309
293
}
310
- Agent* inspector = env->inspector_agent ();
311
- if (inspector->delegate () != nullptr ) {
312
- env->ThrowError (" Session is already attached" );
313
- return ;
294
+
295
+ void Disconnect () {
296
+ if (!delegate_)
297
+ return ;
298
+ delegate_->Disconnect ();
299
+ delete delegate_;
300
+ delegate_ = nullptr ;
314
301
}
315
- Local<Object> session = Object::New (env->isolate ());
316
- env->SetMethod (session, " dispatch" , Dispatch);
317
- env->SetMethod (session, " disconnect" , Disconnect);
318
- info.GetReturnValue ().Set (session);
319
302
320
- JsBindingsSessionDelegate* delegate =
321
- new JsBindingsSessionDelegate (env, session, info.Holder (),
322
- info[0 ].As <Function>());
323
- inspector->Connect (delegate);
324
- SetDelegate (env, session, delegate);
325
- }
303
+ static void Disconnect (const FunctionCallbackInfo<Value>& info) {
304
+ JSBindingsConnection* session;
305
+ ASSIGN_OR_RETURN_UNWRAP (&session, info.Holder ());
306
+ session->Disconnect ();
307
+ }
308
+
309
+ static void Dispatch (const FunctionCallbackInfo<Value>& info) {
310
+ Environment* env = Environment::GetCurrent (info);
311
+ JSBindingsConnection* session;
312
+ ASSIGN_OR_RETURN_UNWRAP (&session, info.Holder ());
313
+ if (!info[0 ]->IsString ()) {
314
+ env->ThrowTypeError (" Inspector message must be a string" );
315
+ return ;
316
+ }
317
+
318
+ auto delegate = session->delegate ();
319
+ if (!delegate) {
320
+ env->ThrowTypeError (" Inspector is not connected" );
321
+ return ;
322
+ }
323
+ Agent* inspector = env->inspector_agent ();
324
+ CHECK_EQ (delegate, inspector->delegate ());
325
+ inspector->Dispatch (ToProtocolString (env->isolate (), info[0 ])->string ());
326
+ }
327
+
328
+ private:
329
+ JsBindingsSessionDelegate* delegate_;
330
+ };
326
331
327
332
void InspectorConsoleCall (const v8::FunctionCallbackInfo<Value>& info) {
328
333
Isolate* isolate = info.GetIsolate ();
@@ -825,9 +830,17 @@ void Agent::InitInspector(Local<Object> target, Local<Value> unused,
825
830
env->SetMethod (target, " addCommandLineAPI" , AddCommandLineAPI);
826
831
if (agent->debug_options_ .wait_for_connect ())
827
832
env->SetMethod (target, " callAndPauseOnStart" , CallAndPauseOnStart);
828
- env->SetMethod (target, " connect" , ConnectJSBindingsSession);
829
833
env->SetMethod (target, " open" , Open);
830
834
env->SetMethod (target, " url" , Url);
835
+
836
+ auto conn_str = FIXED_ONE_BYTE_STRING (env->isolate (), " Connection" );
837
+ Local<FunctionTemplate> tmpl =
838
+ env->NewFunctionTemplate (JSBindingsConnection::New);
839
+ tmpl->InstanceTemplate ()->SetInternalFieldCount (1 );
840
+ env->SetProtoMethod (tmpl, " dispatch" , JSBindingsConnection::Dispatch);
841
+ env->SetProtoMethod (tmpl, " disconnect" , JSBindingsConnection::Disconnect);
842
+ tmpl->SetClassName (conn_str);
843
+ target->Set (env->context (), conn_str, tmpl->GetFunction ()).ToChecked ();
831
844
}
832
845
833
846
void Agent::RequestIoThreadStart () {
0 commit comments