@@ -154,8 +154,61 @@ static int RegisterDebugSignalHandler() {
154
154
return 0 ;
155
155
}
156
156
#endif // _WIN32
157
- } // namespace
158
157
158
+ void InspectorConsoleCall (const v8::FunctionCallbackInfo<Value>& info) {
159
+ Isolate* isolate = info.GetIsolate ();
160
+ HandleScope handle_scope (isolate);
161
+ Local<Context> context = isolate->GetCurrentContext ();
162
+ CHECK_LT (2 , info.Length ());
163
+ std::vector<Local<Value>> call_args;
164
+ for (int i = 3 ; i < info.Length (); ++i) {
165
+ call_args.push_back (info[i]);
166
+ }
167
+ Environment* env = Environment::GetCurrent (isolate);
168
+ if (env->inspector_agent ()->enabled ()) {
169
+ Local<Value> inspector_method = info[0 ];
170
+ CHECK (inspector_method->IsFunction ());
171
+ Local<Value> config_value = info[2 ];
172
+ CHECK (config_value->IsObject ());
173
+ Local<Object> config_object = config_value.As <Object>();
174
+ Local<String> in_call_key = FIXED_ONE_BYTE_STRING (isolate, " in_call" );
175
+ if (!config_object->Has (context, in_call_key).FromMaybe (false )) {
176
+ CHECK (config_object->Set (context,
177
+ in_call_key,
178
+ v8::True (isolate)).FromJust ());
179
+ CHECK (!inspector_method.As <Function>()->Call (context,
180
+ info.Holder (),
181
+ call_args.size (),
182
+ call_args.data ()).IsEmpty ());
183
+ }
184
+ CHECK (config_object->Delete (context, in_call_key).FromJust ());
185
+ }
186
+
187
+ Local<Value> node_method = info[1 ];
188
+ CHECK (node_method->IsFunction ());
189
+ static_cast <void >(node_method.As <Function>()->Call (context,
190
+ info.Holder (),
191
+ call_args.size (),
192
+ call_args.data ()));
193
+ }
194
+
195
+ void CallAndPauseOnStart (
196
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
197
+ Environment* env = Environment::GetCurrent (args);
198
+ CHECK_GT (args.Length (), 1 );
199
+ CHECK (args[0 ]->IsFunction ());
200
+ std::vector<v8::Local<v8::Value>> call_args;
201
+ for (int i = 2 ; i < args.Length (); i++) {
202
+ call_args.push_back (args[i]);
203
+ }
204
+
205
+ env->inspector_agent ()->PauseOnNextJavascriptStatement (" Break on start" );
206
+ v8::MaybeLocal<v8::Value> retval =
207
+ args[0 ].As <v8::Function>()->Call (env->context (), args[1 ],
208
+ call_args.size (), call_args.data ());
209
+ args.GetReturnValue ().Set (retval.ToLocalChecked ());
210
+ }
211
+ } // namespace
159
212
160
213
// Used in NodeInspectorClient::currentTimeMS() below.
161
214
const int NANOS_PER_MSEC = 1000000 ;
@@ -263,12 +316,6 @@ class NodeInspectorClient : public v8_inspector::V8InspectorClient {
263
316
channel_->dispatchProtocolMessage (message);
264
317
}
265
318
266
- void schedulePauseOnNextStatement (const std::string& reason) {
267
- if (channel_ != nullptr ) {
268
- channel_->schedulePauseOnNextStatement (reason);
269
- }
270
- }
271
-
272
319
Local<Context> ensureDefaultContextInGroup (int contextGroupId) override {
273
320
return env_->context ();
274
321
}
@@ -302,10 +349,8 @@ class NodeInspectorClient : public v8_inspector::V8InspectorClient {
302
349
script_id);
303
350
}
304
351
305
- InspectorSessionDelegate* delegate () {
306
- if (channel_ == nullptr )
307
- return nullptr ;
308
- return channel_->delegate ();
352
+ ChannelImpl* channel () {
353
+ return channel_.get ();
309
354
}
310
355
311
356
private:
@@ -320,98 +365,22 @@ class NodeInspectorClient : public v8_inspector::V8InspectorClient {
320
365
Agent::Agent (Environment* env) : parent_env_(env),
321
366
inspector_(nullptr ),
322
367
platform_(nullptr ),
323
- inspector_console_ (false ) {}
368
+ enabled_ (false ) {}
324
369
325
- // Header has unique_ptr to some incomplete types - this definition tells
326
- // the compiler to figure out destruction here, were those types are complete
370
+ // Destructor needs to be defined here in implementation file as the header
371
+ // does not have full definition of some classes.
327
372
Agent::~Agent () {
328
373
}
329
374
330
- // static
331
- void Agent::InspectorConsoleCall (const v8::FunctionCallbackInfo<Value>& info) {
332
- Isolate* isolate = info.GetIsolate ();
333
- Local<Context> context = isolate->GetCurrentContext ();
334
-
335
- CHECK (info.Data ()->IsArray ());
336
- Local<v8::Array> args = info.Data ().As <v8::Array>();
337
- CHECK_EQ (args->Length (), 3 );
338
-
339
- std::vector<Local<Value>> call_args (info.Length ());
340
- for (int i = 0 ; i < info.Length (); ++i) {
341
- call_args[i] = info[i];
342
- }
343
-
344
- Environment* env = Environment::GetCurrent (isolate);
345
- if (env->inspector_agent ()->inspector_console_ ) {
346
- Local<Value> inspector_method = args->Get (context, 0 ).ToLocalChecked ();
347
- CHECK (inspector_method->IsFunction ());
348
- Local<Value> config_value = args->Get (context, 2 ).ToLocalChecked ();
349
- CHECK (config_value->IsObject ());
350
- Local<Object> config_object = config_value.As <Object>();
351
- Local<String> in_call_key = FIXED_ONE_BYTE_STRING (isolate, " in_call" );
352
- if (!config_object->Has (context, in_call_key).FromMaybe (false )) {
353
- CHECK (config_object->Set (context,
354
- in_call_key,
355
- v8::True (isolate)).FromJust ());
356
- CHECK (!inspector_method.As <Function>()->Call (context,
357
- info.Holder (),
358
- call_args.size (),
359
- call_args.data ()).IsEmpty ());
360
- }
361
- CHECK (config_object->Delete (context, in_call_key).FromJust ());
362
- }
363
-
364
- Local<Value> node_method =
365
- args->Get (context, 1 ).ToLocalChecked ();
366
- CHECK (node_method->IsFunction ());
367
- static_cast <void >(node_method.As <Function>()->Call (context,
368
- info.Holder (),
369
- call_args.size (),
370
- call_args.data ()));
371
- }
372
-
373
- // static
374
- void Agent::InspectorWrapConsoleCall (const FunctionCallbackInfo<Value>& info) {
375
- Environment* env = Environment::GetCurrent (info);
376
- if (info.Length () != 3 || !info[0 ]->IsFunction () ||
377
- !info[1 ]->IsFunction () || !info[2 ]->IsObject ()) {
378
- return env->ThrowError (" inspector.wrapConsoleCall takes exactly 3 "
379
- " arguments: two functions and an object." );
380
- }
381
-
382
- Local<v8::Array> array = v8::Array::New (env->isolate (), info.Length ());
383
- CHECK (array->Set (env->context (), 0 , info[0 ]).FromJust ());
384
- CHECK (array->Set (env->context (), 1 , info[1 ]).FromJust ());
385
- CHECK (array->Set (env->context (), 2 , info[2 ]).FromJust ());
386
- info.GetReturnValue ().Set (Function::New (env->context (),
387
- InspectorConsoleCall,
388
- array).ToLocalChecked ());
389
- }
390
-
391
375
bool Agent::Start (v8::Platform* platform, const char * path,
392
376
const DebugOptions& options) {
393
377
path_ = path == nullptr ? " " : path;
394
378
debug_options_ = options;
395
- inspector_console_ = false ;
396
379
inspector_ =
397
380
std::unique_ptr<NodeInspectorClient>(
398
381
new NodeInspectorClient (parent_env_, platform));
399
382
platform_ = platform;
400
- Local<Object> process = parent_env_->process_object ();
401
- Local<Object> inspector = Object::New (parent_env_->isolate ());
402
- Local<String> name =
403
- FIXED_ONE_BYTE_STRING (parent_env_->isolate (), " inspector" );
404
- process->DefineOwnProperty (parent_env_->context (),
405
- name,
406
- inspector,
407
- v8::ReadOnly).FromJust ();
408
- parent_env_->SetMethod (inspector, " wrapConsoleCall" ,
409
- InspectorWrapConsoleCall);
410
383
if (options.inspector_enabled ()) {
411
- if (options.wait_for_connect ()) {
412
- parent_env_->SetMethod (inspector, " callAndPauseOnStart" ,
413
- CallAndPauseOnStart);
414
- }
415
384
return StartIoThread ();
416
385
} else {
417
386
CHECK_EQ (0 , uv_async_init (uv_default_loop (),
@@ -431,7 +400,7 @@ bool Agent::StartIoThread() {
431
400
432
401
CHECK_NE (inspector_, nullptr );
433
402
434
- inspector_console_ = true ;
403
+ enabled_ = true ;
435
404
io_ = std::unique_ptr<InspectorIo>(
436
405
new InspectorIo (parent_env_, platform_, path_, debug_options_));
437
406
if (!io_->Start ()) {
@@ -469,7 +438,7 @@ void Agent::Stop() {
469
438
}
470
439
471
440
void Agent::Connect (InspectorSessionDelegate* delegate) {
472
- inspector_console_ = true ;
441
+ enabled_ = true ;
473
442
inspector_->connectFrontend (delegate);
474
443
}
475
444
@@ -481,26 +450,6 @@ bool Agent::IsStarted() {
481
450
return !!inspector_;
482
451
}
483
452
484
- // static
485
- void Agent::CallAndPauseOnStart (
486
- const v8::FunctionCallbackInfo<v8::Value>& args) {
487
- Environment* env = Environment::GetCurrent (args);
488
- CHECK_GT (args.Length (), 1 );
489
- CHECK (args[0 ]->IsFunction ());
490
- std::vector<v8::Local<v8::Value>> call_args;
491
- for (int i = 2 ; i < args.Length (); i++) {
492
- call_args.push_back (args[i]);
493
- }
494
-
495
- Agent* agent = env->inspector_agent ();
496
- agent->inspector_ ->schedulePauseOnNextStatement (" Break on start" );
497
-
498
- v8::MaybeLocal<v8::Value> retval =
499
- args[0 ].As <v8::Function>()->Call (env->context (), args[1 ],
500
- call_args.size (), call_args.data ());
501
- args.GetReturnValue ().Set (retval.ToLocalChecked ());
502
- }
503
-
504
453
void Agent::WaitForDisconnect () {
505
454
if (io_ != nullptr ) {
506
455
io_->WaitForDisconnect ();
@@ -529,5 +478,23 @@ void Agent::RunMessageLoop() {
529
478
inspector_->runMessageLoopOnPause (CONTEXT_GROUP_ID);
530
479
}
531
480
481
+ void Agent::PauseOnNextJavascriptStatement (const std::string& reason) {
482
+ ChannelImpl* channel = inspector_->channel ();
483
+ if (channel != nullptr )
484
+ channel->schedulePauseOnNextStatement (reason);
485
+ }
486
+
487
+ // static
488
+ void Agent::InitJSBindings (Local<Object> target, Local<Value> unused,
489
+ Local<Context> context, void * priv) {
490
+ Environment* env = Environment::GetCurrent (context);
491
+ Agent* agent = env->inspector_agent ();
492
+ env->SetMethod (target, " consoleCall" , InspectorConsoleCall);
493
+ if (agent->debug_options_ .wait_for_connect ())
494
+ env->SetMethod (target, " callAndPauseOnStart" , CallAndPauseOnStart);
495
+ }
532
496
} // namespace inspector
533
497
} // namespace node
498
+
499
+ NODE_MODULE_CONTEXT_AWARE_BUILTIN (inspector,
500
+ node::inspector::Agent::InitJSBindings);
0 commit comments