Skip to content

Commit 305c281

Browse files
motiz88facebook-github-bot
authored andcommitted
Implement native console object in RuntimeTarget (#43456)
Summary: Pull Request resolved: #43456 Changelog: [Internal] Implements the [WHATWG `console` spec](https://console.spec.whatwg.org/) directly in `RuntimeTarget`, based on the Hermes-powered `addConsoleMessage` method first used in D54494298. Benefits: * This allows the console API to work independently of the polyfill shipped in RN, including very early during JS execution. * It also opens the door to better stack traces (once we start reporting those) and richer functionality in the `console` object itself. Reviewed By: robhogan Differential Revision: D54826073 fbshipit-source-id: d5b0bd004bf35c2fce91742ae84ea86225ec1c61
1 parent eca4d76 commit 305c281

File tree

3 files changed

+451
-68
lines changed

3 files changed

+451
-68
lines changed

packages/react-native/ReactCommon/hermes/inspector-modern/chrome/HermesRuntimeTargetDelegate.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ class HermesRuntimeTargetDelegate::Impl final : public RuntimeTargetDelegate {
125125
case ConsoleAPIType::kTimeEnd:
126126
type = HermesConsoleAPIType::kTimeEnd;
127127
break;
128+
case ConsoleAPIType::kCount:
129+
type = HermesConsoleAPIType::kCount;
130+
break;
128131
default:
129132
throw std::logic_error{"Unknown console message type"};
130133
}

packages/react-native/ReactCommon/jsinspector-modern/RuntimeTarget.cpp

Lines changed: 1 addition & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -34,77 +34,10 @@ RuntimeTarget::RuntimeTarget(
3434
jsExecutor_(jsExecutor) {}
3535

3636
void RuntimeTarget::installGlobals() {
37+
// NOTE: RuntimeTarget::installConsoleHandler is in RuntimeTargetConsole.cpp
3738
installConsoleHandler();
3839
}
3940

40-
void RuntimeTarget::installConsoleHandler() {
41-
jsExecutor_([selfWeak = weak_from_this(),
42-
selfExecutor = executorFromThis()](jsi::Runtime& runtime) {
43-
// TODO(moti): Switch from implementing __inspectorLog to directly
44-
// installing a `console` object.
45-
runtime.global().setProperty(
46-
runtime,
47-
"__inspectorLog",
48-
jsi::Function::createFromHostFunction(
49-
runtime,
50-
jsi::PropNameID::forAscii(runtime, "__inspectorLog"),
51-
4,
52-
[selfWeak, selfExecutor](
53-
jsi::Runtime& rt,
54-
const jsi::Value& /*thisVal*/,
55-
const jsi::Value* args,
56-
size_t count) {
57-
if (count < 4) {
58-
throw jsi::JSError(
59-
rt,
60-
"__inspectorLog requires at least 4 arguments: logLevel, str, args, framesToSkip");
61-
}
62-
std::chrono::time_point<std::chrono::system_clock> timestamp =
63-
std::chrono::system_clock::now();
64-
std::string level = args[0].asString(rt).utf8(rt);
65-
ConsoleAPIType type = ConsoleAPIType::kLog;
66-
if (level == "debug") {
67-
type = ConsoleAPIType::kDebug;
68-
} else if (level == "log") {
69-
type = ConsoleAPIType::kLog;
70-
} else if (level == "warning") {
71-
type = ConsoleAPIType::kWarning;
72-
} else if (level == "error") {
73-
type = ConsoleAPIType::kError;
74-
}
75-
// NOTE: args[1] is the processed string message - ignore it.
76-
jsi::Array argsArray = args[2].asObject(rt).asArray(rt);
77-
std::vector<jsi::Value> argsVec;
78-
for (size_t i = 0, length = argsArray.length(rt); i != length;
79-
++i) {
80-
argsVec.emplace_back(argsArray.getValueAtIndex(rt, i));
81-
}
82-
// TODO(moti): Handle framesToSkip in some way. Note that the
83-
// runtime doesn't even capture a stack trace at the moment.
84-
ConsoleMessage consoleMessage{
85-
std::chrono::duration_cast<
86-
std::chrono::duration<double, std::milli>>(
87-
timestamp.time_since_epoch())
88-
.count(),
89-
type,
90-
std::move(argsVec)};
91-
if (auto self = selfWeak.lock()) {
92-
// Q: Why is it safe to use self->delegate_ here?
93-
// A: Because the caller of InspectorTarget::registerRuntime
94-
// is explicitly required to guarantee that the delegate not
95-
// only outlives the target, but also outlives all JS code
96-
// execution that occurs on the JS thread.
97-
self->delegate_.addConsoleMessage(
98-
rt, std::move(consoleMessage));
99-
// To ensure we never destroy `self` on the JS thread, send
100-
// our shared_ptr back to the inspector thread.
101-
selfExecutor([self = std::move(self)](auto&) { (void)self; });
102-
}
103-
return jsi::Value::undefined();
104-
}));
105-
});
106-
}
107-
10841
std::shared_ptr<RuntimeAgent> RuntimeTarget::createAgent(
10942
FrontendChannel channel,
11043
SessionState& sessionState) {

0 commit comments

Comments
 (0)