|
22 | 22 |
|
23 | 23 | namespace v8_inspector { |
24 | 24 |
|
| 25 | +namespace { |
| 26 | +// Build an 8-bit `StringView` directly over a `std::string`'s storage. |
| 27 | +// V8 inspector messages on this side are ASCII/UTF-8 JSON, so the |
| 28 | +// previous `std::string -> std::vector<uint16_t> -> StringView` path |
| 29 | +// inflated each byte to two and then handed it to a 16-bit constructor. |
| 30 | +// Going straight through the 8-bit constructor avoids that doubling AND |
| 31 | +// dodges the libc++ deprecation that prompted the inspector's |
| 32 | +// `UChar = uint16_t -> char16_t` switch. |
| 33 | +StringView Make8BitStringView(const std::string& value) { |
| 34 | + return StringView(reinterpret_cast<const uint8_t*>(value.data()), |
| 35 | + value.size()); |
| 36 | +} |
| 37 | +} // namespace |
| 38 | + |
25 | 39 | #define NOTIFICATION(name) \ |
26 | 40 | [[NSString stringWithFormat:@"%@:NativeScript.Debug.%s", \ |
27 | 41 | [[NSBundle mainBundle] bundleIdentifier], name] UTF8String] |
|
128 | 142 | dispatch_semaphore_signal(messageArrived_); |
129 | 143 | }); |
130 | 144 |
|
| 145 | + // Debugger.pause needs to interrupt V8 even if the main thread is busy |
| 146 | + // executing JS. RequestInterrupt fires at the next safe bytecode boundary. |
| 147 | + auto parsed = json::parse(message, nullptr, false); |
| 148 | + if (!parsed.is_discarded() && parsed.contains("method") && parsed["method"] == "Debugger.pause") { |
| 149 | + isolate_->RequestInterrupt( |
| 150 | + [](Isolate* isolate, void* data) { |
| 151 | + auto client = static_cast<JsV8InspectorClient*>(data); |
| 152 | + client->session_->schedulePauseOnNextStatement({}, {}); |
| 153 | + }, |
| 154 | + this); |
| 155 | + } |
| 156 | + |
131 | 157 | tns::ExecuteOnMainThread([this, message]() { |
132 | 158 | dispatch_sync(this->messageLoopQueue_, ^{ |
133 | 159 | // prevent execution if we're already pumping messages |
|
257 | 283 | } |
258 | 284 |
|
259 | 285 | void JsV8InspectorClient::dispatchMessage(const std::string& message) { |
260 | | - std::vector<uint16_t> vector = tns::ToVector(message); |
261 | | - StringView messageView(vector.data(), vector.size()); |
| 286 | + StringView messageView = Make8BitStringView(message); |
262 | 287 | Isolate* isolate = isolate_; |
263 | 288 | v8::Locker locker(isolate); |
264 | 289 | Isolate::Scope isolate_scope(isolate); |
|
343 | 368 | auto returnString = GetReturnMessageFromDomainHandlerResult(result, requestId); |
344 | 369 |
|
345 | 370 | if (returnString.size() > 0) { |
346 | | - std::vector<uint16_t> vector = tns::ToVector(returnString); |
347 | | - StringView messageView(vector.data(), vector.size()); |
| 371 | + StringView messageView = Make8BitStringView(returnString); |
348 | 372 | auto msg = StringBuffer::create(messageView); |
349 | 373 | this->sendNotification(std::move(msg)); |
350 | 374 | } |
|
486 | 510 | Local<v8::String> arg = args[0].As<v8::String>(); |
487 | 511 | std::string message = tns::ToString(isolate, arg); |
488 | 512 |
|
489 | | - std::vector<uint16_t> vector = tns::ToVector(message); |
490 | | - StringView messageView(vector.data(), vector.size()); |
| 513 | + StringView messageView = Make8BitStringView(message); |
491 | 514 | auto msg = StringBuffer::create(messageView); |
492 | 515 | client->sendNotification(std::move(msg)); |
493 | 516 | } |
|
0 commit comments