react-native-windows 0.72.0-preview.7 → 0.72.0-preview.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/Directory.Build.props +24 -19
  2. package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +0 -1
  3. package/Libraries/Components/TextInput/TextInput.d.ts +121 -86
  4. package/Libraries/Components/TextInput/TextInput.flow.js +121 -135
  5. package/Libraries/Components/TextInput/TextInput.js +126 -155
  6. package/Libraries/Components/TextInput/TextInput.windows.js +126 -155
  7. package/Libraries/Core/ReactNativeVersion.js +1 -1
  8. package/Libraries/PermissionsAndroid/PermissionsAndroid.js +0 -2
  9. package/Libraries/StyleSheet/StyleSheetTypes.d.ts +1 -13
  10. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +2 -4
  11. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +2 -57
  12. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +22 -17
  13. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +0 -2
  14. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiLoader.cpp +16 -0
  15. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +41 -12
  16. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +17 -6
  17. package/Microsoft.ReactNative.Managed/packages.lock.json +6 -6
  18. package/PropertySheets/External/Microsoft.ReactNative.Uwp.CSharpApp.targets +1 -1
  19. package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppApp.targets +1 -1
  20. package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.CSharpApp.targets +1 -1
  21. package/PropertySheets/Generated/PackageVersion.g.props +2 -2
  22. package/PropertySheets/JSEngine.props +4 -4
  23. package/PropertySheets/Warnings.props +6 -0
  24. package/ReactCommon/ReactCommon.vcxproj +53 -1
  25. package/ReactCommon/cgmanifest.json +15 -0
  26. package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +36 -0
  27. package/Shared/DevSupportManager.cpp +2 -9
  28. package/Shared/DevSupportManager.h +2 -6
  29. package/Shared/HermesRuntimeHolder.cpp +318 -81
  30. package/Shared/HermesRuntimeHolder.h +15 -19
  31. package/Shared/HermesSamplingProfiler.cpp +5 -6
  32. package/Shared/InspectorPackagerConnection.cpp +62 -108
  33. package/Shared/InspectorPackagerConnection.h +9 -21
  34. package/Shared/JSI/ScriptStore.h +18 -20
  35. package/Shared/JSI/V8RuntimeHolder.cpp +262 -0
  36. package/Shared/JSI/V8RuntimeHolder.h +37 -0
  37. package/Shared/OInstance.cpp +16 -36
  38. package/Shared/SafeLoadLibrary.cpp +41 -0
  39. package/Shared/SafeLoadLibrary.h +15 -0
  40. package/Shared/Shared.vcxitems +21 -10
  41. package/Shared/Shared.vcxitems.filters +23 -30
  42. package/codegen/rnwcoreJSI.h +2 -2
  43. package/package.json +15 -14
  44. package/template/cs-app-WinAppSDK/proj/ExperimentalFeatures.props +1 -1
  45. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.cpp +0 -2105
  46. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.h +0 -73
  47. package/Shared/HermesShim.cpp +0 -122
  48. package/Shared/HermesShim.h +0 -41
  49. package/Shared/JSI/NapiJsiV8RuntimeHolder.cpp +0 -209
  50. package/Shared/JSI/NapiJsiV8RuntimeHolder.h +0 -46
  51. package/Shared/V8JSIRuntimeHolder.cpp +0 -71
  52. package/Shared/V8JSIRuntimeHolder.h +0 -58
@@ -3,18 +3,10 @@
3
3
 
4
4
  #include "pch.h"
5
5
 
6
- #ifdef HERMES_ENABLE_DEBUGGER
7
-
8
6
  #include <folly/json.h>
9
7
  #include <tracing/tracing.h>
10
8
  #include "InspectorPackagerConnection.h"
11
9
 
12
- namespace facebook {
13
- namespace react {
14
- IDestructible::~IDestructible() {}
15
- } // namespace react
16
- } // namespace facebook
17
-
18
10
  namespace Microsoft::ReactNative {
19
11
 
20
12
  namespace {
@@ -80,35 +72,16 @@ struct InspectorProtocol {
80
72
  }
81
73
 
82
74
  static folly::dynamic constructGetPagesResponsePayloadForPackager(
83
- const std::vector<facebook::react::InspectorPage2> &pages,
84
- InspectorPackagerConnection::BundleStatus bundleStatus) {
85
- folly::dynamic payload = folly::dynamic::array;
86
- for (const facebook::react::InspectorPage2 &page : pages) {
87
- folly::dynamic pageDyn = folly::dynamic::object;
88
- pageDyn["id"] = page.id;
89
- pageDyn["title"] = page.title;
90
- pageDyn["vm"] = page.vm;
91
-
92
- pageDyn["isLastBundleDownloadSuccess"] = bundleStatus.m_isLastDownloadSucess;
93
- pageDyn["bundleUpdateTimestamp"] = bundleStatus.m_updateTimestamp;
94
-
95
- payload.push_back(pageDyn);
96
- }
97
- return payload;
98
- }
99
-
100
- static folly::dynamic constructGetPagesResponsePayloadForPackager(
101
- std::unique_ptr<facebook::react::IInspectorPages> pages,
75
+ const std::vector<facebook::react::InspectorPage> &pages,
102
76
  InspectorPackagerConnection::BundleStatus bundleStatus) {
103
77
  folly::dynamic payload = folly::dynamic::array;
104
- for (int p = 0; p < pages->size(); p++) {
105
- const facebook::react::InspectorPage2 page = pages->getPage(p);
78
+ for (const facebook::react::InspectorPage &page : pages) {
106
79
  folly::dynamic pageDyn = folly::dynamic::object;
107
80
  pageDyn["id"] = page.id;
108
81
  pageDyn["title"] = page.title;
109
82
  pageDyn["vm"] = page.vm;
110
83
 
111
- pageDyn["isLastBundleDownloadSuccess"] = bundleStatus.m_isLastDownloadSucess;
84
+ pageDyn["isLastBundleDownloadSuccess"] = bundleStatus.m_isLastDownloadSuccess;
112
85
  pageDyn["bundleUpdateTimestamp"] = bundleStatus.m_updateTimestamp;
113
86
 
114
87
  payload.push_back(pageDyn);
@@ -116,14 +89,14 @@ struct InspectorProtocol {
116
89
  return payload;
117
90
  }
118
91
 
119
- static folly::dynamic constructVMResponsePayloadForPackager(int64_t pageId, std::string &&messageFromVM) {
92
+ static folly::dynamic constructVMResponsePayloadForPackager(int32_t pageId, std::string &&messageFromVM) {
120
93
  folly::dynamic payload = folly::dynamic::object;
121
94
  payload[InspectorProtocol::Message_eventName_wrappedEvent] = messageFromVM;
122
95
  payload[InspectorProtocol::Message_PAGEID] = pageId;
123
96
  return payload;
124
97
  }
125
98
 
126
- static folly::dynamic constructVMResponsePayloadOnDisconnectForPackager(int64_t pageId) {
99
+ static folly::dynamic constructVMResponsePayloadOnDisconnectForPackager(int32_t pageId) {
127
100
  folly::dynamic payload = folly::dynamic::object;
128
101
  payload[InspectorProtocol::Message_PAGEID] = pageId;
129
102
  return payload;
@@ -132,7 +105,7 @@ struct InspectorProtocol {
132
105
 
133
106
  } // namespace
134
107
 
135
- RemoteConnection::RemoteConnection(int64_t pageId, const InspectorPackagerConnection &packagerConnection)
108
+ RemoteConnection::RemoteConnection(int32_t pageId, const InspectorPackagerConnection &packagerConnection)
136
109
  : m_packagerConnection(packagerConnection), m_pageId(pageId) {}
137
110
 
138
111
  void RemoteConnection::onMessage(std::string message) {
@@ -152,26 +125,6 @@ void RemoteConnection::onDisconnect() {
152
125
  m_packagerConnection.sendMessageToPackager(std::move(responsestr));
153
126
  }
154
127
 
155
- RemoteConnection2::RemoteConnection2(int64_t pageId, const InspectorPackagerConnection &packagerConnection)
156
- : m_packagerConnection(packagerConnection), m_pageId(pageId) {}
157
-
158
- void RemoteConnection2::onMessage(std::string message) {
159
- folly::dynamic response = InspectorProtocol::constructResponseForPackager(
160
- InspectorProtocol::EventType::WrappedEvent,
161
- InspectorProtocol::constructVMResponsePayloadForPackager(m_pageId, std::move(message)));
162
- std::string responsestr = folly::toJson(response);
163
- m_packagerConnection.sendMessageToPackager(std::move(responsestr));
164
- }
165
-
166
- void RemoteConnection2::onDisconnect() {
167
- folly::dynamic response = InspectorProtocol::constructResponseForPackager(
168
- InspectorProtocol::EventType::Disconnect,
169
- InspectorProtocol::constructVMResponsePayloadOnDisconnectForPackager(m_pageId));
170
-
171
- std::string responsestr = folly::toJson(response);
172
- m_packagerConnection.sendMessageToPackager(std::move(responsestr));
173
- }
174
-
175
128
  winrt::fire_and_forget InspectorPackagerConnection::sendMessageToPackagerAsync(std::string &&message) const {
176
129
  std::string message_(std::move(message));
177
130
  co_await winrt::resume_background();
@@ -183,7 +136,7 @@ void InspectorPackagerConnection::sendMessageToPackager(std::string &&message) c
183
136
  sendMessageToPackagerAsync(std::move(message));
184
137
  }
185
138
 
186
- void InspectorPackagerConnection::sendMessageToVM(int64_t pageId, std::string &&message) {
139
+ void InspectorPackagerConnection::sendMessageToVM(int32_t pageId, std::string &&message) {
187
140
  m_localConnections[pageId]->sendMessage(std::move(message));
188
141
  }
189
142
 
@@ -214,59 +167,62 @@ winrt::fire_and_forget InspectorPackagerConnection::connectAsync() {
214
167
  m_packagerWebSocketConnection->SetOnConnect(
215
168
  []() { facebook::react::tracing::log("Inspector: Websocket connection succeeded."); });
216
169
 
217
- m_packagerWebSocketConnection->SetOnMessage(
218
- [self = shared_from_this()](size_t /*length*/, const std::string &message, bool isBinary) {
219
- assert(!isBinary && "We don't expect any binary messages !");
220
- folly::dynamic messageDyn = folly::parseJson(message);
221
-
222
- InspectorProtocol::EventType eventType = InspectorProtocol::getEventType(messageDyn);
223
- switch (eventType) {
224
- case InspectorProtocol::EventType::GetPages: {
225
- std::unique_ptr<facebook::react::IInspectorPages> inspectorPages = facebook::react::getInspectorPages();
226
- folly::dynamic response = InspectorProtocol::constructResponseForPackager(
227
- InspectorProtocol::EventType::GetPages,
228
- InspectorProtocol::constructGetPagesResponsePayloadForPackager(
229
- std::move(inspectorPages), self->m_bundleStatusProvider->getBundleStatus()));
230
-
231
- std::string responsestr = folly::toJson(response);
232
- self->sendMessageToPackager(std::move(responsestr));
233
- } break;
234
-
235
- case InspectorProtocol::EventType::WrappedEvent: {
236
- folly::dynamic payload = messageDyn[InspectorProtocol::Message_PAYLOAD];
237
- int64_t pageId = payload[InspectorProtocol::Message_PAGEID].asInt();
238
-
239
- if (self->m_localConnections.find(pageId) == self->m_localConnections.end()) {
240
- break;
241
- }
242
-
243
- std::string wrappedEvent = payload[InspectorProtocol::Message_eventName_wrappedEvent].getString();
244
- self->sendMessageToVM(pageId, std::move(wrappedEvent));
245
- } break;
246
-
247
- case InspectorProtocol::EventType::Connect: {
248
- folly::dynamic payload = messageDyn[InspectorProtocol::Message_PAYLOAD];
249
- int64_t pageId = payload[InspectorProtocol::Message_PAGEID].asInt();
250
-
251
- if (self->m_localConnections.find(pageId) != self->m_localConnections.end()) {
252
- break;
253
- }
254
-
255
- self->m_localConnections[pageId] = facebook::react::connectInspectorPage(
256
- static_cast<int>(pageId), std::make_unique<RemoteConnection2>(pageId, *self));
257
- } break;
258
-
259
- case InspectorProtocol::EventType::Disconnect: {
260
- folly::dynamic payload = messageDyn[InspectorProtocol::Message_PAYLOAD];
261
- int64_t pageId = payload[InspectorProtocol::Message_PAGEID].asInt();
262
- if (self->m_localConnections.find(pageId) != self->m_localConnections.end()) {
263
- self->m_localConnections[pageId]->disconnect();
264
- self->m_localConnections.erase(pageId);
265
- }
266
-
267
- } break;
170
+ m_packagerWebSocketConnection->SetOnMessage([self = shared_from_this()](
171
+ size_t /*length*/, const std::string &message, bool isBinary) {
172
+ assert(!isBinary && "We don't expect any binary messages !");
173
+ folly::dynamic messageDyn = folly::parseJson(message);
174
+
175
+ InspectorProtocol::EventType eventType = InspectorProtocol::getEventType(messageDyn);
176
+ switch (eventType) {
177
+ case InspectorProtocol::EventType::GetPages: {
178
+ std::vector<facebook::react::InspectorPage> inspectorPages = facebook::react::getInspectorInstance().getPages();
179
+ folly::dynamic response = InspectorProtocol::constructResponseForPackager(
180
+ InspectorProtocol::EventType::GetPages,
181
+ InspectorProtocol::constructGetPagesResponsePayloadForPackager(
182
+ inspectorPages, self->m_bundleStatusProvider->getBundleStatus()));
183
+
184
+ std::string responsestr = folly::toJson(response);
185
+ self->sendMessageToPackager(std::move(responsestr));
186
+ break;
187
+ }
188
+
189
+ case InspectorProtocol::EventType::WrappedEvent: {
190
+ folly::dynamic payload = messageDyn[InspectorProtocol::Message_PAYLOAD];
191
+ int32_t pageId = static_cast<int32_t>(payload[InspectorProtocol::Message_PAGEID].asInt());
192
+
193
+ if (self->m_localConnections.find(pageId) == self->m_localConnections.end()) {
194
+ break;
268
195
  }
269
- });
196
+
197
+ std::string wrappedEvent = payload[InspectorProtocol::Message_eventName_wrappedEvent].getString();
198
+ self->sendMessageToVM(pageId, std::move(wrappedEvent));
199
+ break;
200
+ }
201
+
202
+ case InspectorProtocol::EventType::Connect: {
203
+ folly::dynamic payload = messageDyn[InspectorProtocol::Message_PAYLOAD];
204
+ int32_t pageId = static_cast<int32_t>(payload[InspectorProtocol::Message_PAGEID].asInt());
205
+
206
+ if (self->m_localConnections.find(pageId) != self->m_localConnections.end()) {
207
+ break;
208
+ }
209
+
210
+ self->m_localConnections[pageId] =
211
+ facebook::react::getInspectorInstance().connect(pageId, std::make_unique<RemoteConnection>(pageId, *self));
212
+ break;
213
+ }
214
+
215
+ case InspectorProtocol::EventType::Disconnect: {
216
+ folly::dynamic payload = messageDyn[InspectorProtocol::Message_PAYLOAD];
217
+ int32_t pageId = static_cast<int32_t>(payload[InspectorProtocol::Message_PAGEID].asInt());
218
+ if (self->m_localConnections.find(pageId) != self->m_localConnections.end()) {
219
+ self->m_localConnections[pageId]->disconnect();
220
+ self->m_localConnections.erase(pageId);
221
+ }
222
+ break;
223
+ }
224
+ }
225
+ });
270
226
 
271
227
  Microsoft::React::Networking::IWebSocketResource::Protocols protocols;
272
228
  Microsoft::React::Networking::IWebSocketResource::Options options;
@@ -276,5 +232,3 @@ winrt::fire_and_forget InspectorPackagerConnection::connectAsync() {
276
232
  }
277
233
 
278
234
  } // namespace Microsoft::ReactNative
279
-
280
- #endif
@@ -3,7 +3,6 @@
3
3
 
4
4
  #pragma once
5
5
 
6
- #include <InspectorProxy.h>
7
6
  #include <Networking/WinRTWebSocketResource.h>
8
7
  #include <jsinspector/InspectorInterfaces.h>
9
8
 
@@ -16,12 +15,12 @@ class InspectorPackagerConnection final : public std::enable_shared_from_this<In
16
15
 
17
16
  class BundleStatus {
18
17
  public:
19
- bool m_isLastDownloadSucess;
18
+ bool m_isLastDownloadSuccess;
20
19
  int64_t m_updateTimestamp = -1;
21
20
 
22
21
  BundleStatus(bool isLastDownloadSucess, long updateTimestamp)
23
- : m_isLastDownloadSucess(isLastDownloadSucess), m_updateTimestamp(updateTimestamp) {}
24
- BundleStatus() : m_isLastDownloadSucess(false), m_updateTimestamp(-1) {}
22
+ : m_isLastDownloadSuccess(isLastDownloadSucess), m_updateTimestamp(updateTimestamp) {}
23
+ BundleStatus() : m_isLastDownloadSuccess(false), m_updateTimestamp(-1) {}
25
24
  };
26
25
 
27
26
  struct IBundleStatusProvider {
@@ -32,16 +31,16 @@ class InspectorPackagerConnection final : public std::enable_shared_from_this<In
32
31
 
33
32
  private:
34
33
  friend class RemoteConnection;
35
- friend class RemoteConnection2;
36
34
 
37
35
  winrt::fire_and_forget sendMessageToPackagerAsync(std::string &&message) const;
38
36
  void sendMessageToPackager(std::string &&message) const;
39
37
 
40
- // Note:: VM side Inspector processes the messages asynchronousely in a sequential executor with dedicated thread.
38
+ // Note:: VM side Inspector processes the messages asynchronously in a sequential executor with dedicated thread.
41
39
  // Hence, we don't bother invoking the inspector asynchronously.
42
- void sendMessageToVM(int64_t pageId, std::string &&message);
40
+ void sendMessageToVM(int32_t pageId, std::string &&message);
43
41
 
44
- std::unordered_map<int64_t, std::unique_ptr<facebook::react::ILocalConnection>> m_localConnections;
42
+ private:
43
+ std::unordered_map<int32_t, std::unique_ptr<facebook::react::ILocalConnection>> m_localConnections;
45
44
  std::shared_ptr<Microsoft::React::Networking::WinRTWebSocketResource> m_packagerWebSocketConnection;
46
45
  std::shared_ptr<IBundleStatusProvider> m_bundleStatusProvider;
47
46
  std::string m_url;
@@ -49,23 +48,12 @@ class InspectorPackagerConnection final : public std::enable_shared_from_this<In
49
48
 
50
49
  class RemoteConnection final : public facebook::react::IRemoteConnection {
51
50
  public:
52
- RemoteConnection(int64_t pageId, const InspectorPackagerConnection &packagerConnection);
53
- void onMessage(std::string message) override;
54
- void onDisconnect() override;
55
-
56
- private:
57
- int64_t m_pageId;
58
- const InspectorPackagerConnection &m_packagerConnection;
59
- };
60
-
61
- class RemoteConnection2 final : public facebook::react::IRemoteConnection2 {
62
- public:
63
- RemoteConnection2(int64_t pageId, const InspectorPackagerConnection &packagerConnection);
51
+ RemoteConnection(int32_t pageId, const InspectorPackagerConnection &packagerConnection);
64
52
  void onMessage(std::string message) override;
65
53
  void onDisconnect() override;
66
54
 
67
55
  private:
68
- int64_t m_pageId;
56
+ int32_t m_pageId;
69
57
  const InspectorPackagerConnection &m_packagerConnection;
70
58
  };
71
59
 
@@ -5,12 +5,11 @@
5
5
  #include <jsi/jsi.h>
6
6
  #include <memory>
7
7
 
8
- namespace facebook {
9
- namespace jsi {
8
+ namespace facebook::jsi {
10
9
 
11
- // Integer type as it's persist friently.
12
- using ScriptVersion_t = uint64_t; // It shouldbe std::optional<uint64_t> once we have c++17 available everywhere. Until
13
- // then, 0 implies versioning not available.
10
+ // Integer type as it's persist friendly.
11
+ using ScriptVersion_t = uint64_t; // It should be std::optional<uint64_t> once we have c++17 available everywhere.
12
+ // Until then, 0 implies versioning not available.
14
13
  using JSRuntimeVersion_t = uint64_t; // 0 implies version can't be computed. We assert whenever that happens.
15
14
 
16
15
  struct VersionedBuffer {
@@ -30,14 +29,14 @@ struct JSRuntimeSignature {
30
29
 
31
30
  // Most JSI::Runtime implementation offer some form of prepared JavaScript which offers better performance
32
31
  // characteristics when loading comparing to plain JavaScript. Embedders can provide an instance of this interface
33
- // (through JSI::Runtime implementation's factory method), to enable persistance of the prepared script and retrieval on
34
- // subsequent evaluation of a script.
32
+ // (through JSI::Runtime implementation's factory method), to enable persistence of the prepared script
33
+ // and retrieval on subsequent evaluation of a script.
35
34
  struct PreparedScriptStore {
36
35
  virtual ~PreparedScriptStore() = default;
37
36
 
38
- // Try to retrieve the prepared javascript for a given combination of script & runtime.
39
- // scriptSignature : Javascript url and version
40
- // RuntimeSignature : Javascript engine type and version
37
+ // Try to retrieve the prepared JavaScript for a given combination of script & runtime.
38
+ // scriptSignature : JavaScript URL and version
39
+ // RuntimeSignature : JavaScript engine type and version
41
40
  // prepareTag : Custom tag to uniquely identify JS engine specific preparation schemes. It is usually useful while
42
41
  // experimentation and can be null. It is possible that no prepared script is available for a given script & runtime
43
42
  // signature. This method should null if so
@@ -47,12 +46,12 @@ struct PreparedScriptStore {
47
46
  const char *prepareTag // Optional tag. For e.g. eagerly evaluated vs lazy cache.
48
47
  ) noexcept = 0;
49
48
 
50
- // Persist the perpared javascript for a given combination of script & runtime.
51
- // scriptSignature : Javascript url and version
52
- // RuntimeSignature : Javascript engine type and version
49
+ // Persist the prepared JavaScript for a given combination of script & runtime.
50
+ // scriptSignature : JavaScript URL and version
51
+ // RuntimeSignature : JavaScript engine type and version
53
52
  // prepareTag : Custom tag to uniquely identify JS engine specific preparation schemes. It is usually useful while
54
53
  // experimentation and can be null. It is possible that no prepared script is available for a given script & runtime
55
- // signature. This method should null if so Any failure in persistance should be identified during the subsequent
54
+ // signature. This method should null if so Any failure in persistence should be identified during the subsequent
56
55
  // retrieval through the integrity mechanism which must be put into the storage.
57
56
  virtual void persistPreparedScript(
58
57
  std::shared_ptr<const facebook::jsi::Buffer> preparedScript,
@@ -63,17 +62,16 @@ struct PreparedScriptStore {
63
62
  };
64
63
 
65
64
  // JSI::Runtime implementation must be provided an instance on this interface to enable version sensitive capabilities
66
- // such as usage of pre-prepared javascript script. Alternatively, this entity can be used to directly provide the
67
- // Javascript buffer and rich metadata to the JSI::Runtime instance.
65
+ // such as usage of prepared JavaScript script. Alternatively, this entity can be used to directly provide the
66
+ // JavaScript buffer and rich meta data to the JSI::Runtime instance.
68
67
  struct ScriptStore {
69
68
  virtual ~ScriptStore() = default;
70
69
 
71
- // Return the Javascript buffer and version corresponding to a given url.
70
+ // Return the JavaScript buffer and version corresponding to a given URL.
72
71
  virtual VersionedBuffer getVersionedScript(const std::string &url) noexcept = 0;
73
72
 
74
- // Return the version of the Javascript buffer corresponding to a given url.
73
+ // Return the version of the JavaScript buffer corresponding to a given URL.
75
74
  virtual ScriptVersion_t getScriptVersion(const std::string &url) noexcept = 0;
76
75
  };
77
76
 
78
- } // namespace jsi
79
- } // namespace facebook
77
+ } // namespace facebook::jsi
@@ -0,0 +1,262 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "V8RuntimeHolder.h"
5
+ #include <ApiLoaders/V8Api.h>
6
+ #include <NodeApiJsiRuntime.h>
7
+ #include <crash/verifyElseCrash.h>
8
+ #include "SafeLoadLibrary.h"
9
+
10
+ using namespace Microsoft::NodeApiJsi;
11
+
12
+ #define CRASH_ON_ERROR(result) VerifyElseCrash(result == napi_ok);
13
+
14
+ namespace Microsoft::ReactNative {
15
+ namespace {
16
+
17
+ class V8FuncResolver : public IFuncResolver {
18
+ public:
19
+ V8FuncResolver() : libHandle_(SafeLoadLibrary(L"v8jsi.dll")) {}
20
+
21
+ FuncPtr getFuncPtr(const char *funcName) override {
22
+ return reinterpret_cast<FuncPtr>(GetProcAddress(libHandle_, funcName));
23
+ }
24
+
25
+ private:
26
+ HMODULE libHandle_;
27
+ };
28
+
29
+ V8Api &initV8Api() noexcept {
30
+ static V8FuncResolver funcResolver;
31
+ static V8Api s_v8Api(&funcResolver);
32
+ V8Api::setCurrent(&s_v8Api);
33
+ return s_v8Api;
34
+ }
35
+
36
+ V8Api &getV8Api() noexcept {
37
+ static V8Api &s_v8Api = initV8Api();
38
+ return s_v8Api;
39
+ }
40
+
41
+ class V8Task {
42
+ public:
43
+ V8Task(void *taskData, jsr_task_run_cb taskRunCallback, jsr_data_delete_cb taskDataDeleteCallback, void *deleterData)
44
+ : taskData_(taskData),
45
+ taskRunCallback_(taskRunCallback),
46
+ taskDataDeleteCallback_(taskDataDeleteCallback),
47
+ deleterData_(deleterData) {}
48
+
49
+ V8Task(const V8Task &other) = delete;
50
+ V8Task &operator=(const V8Task &other) = delete;
51
+
52
+ ~V8Task() {
53
+ if (taskDataDeleteCallback_ != nullptr) {
54
+ taskDataDeleteCallback_(taskData_, deleterData_);
55
+ }
56
+ }
57
+
58
+ void Run() const {
59
+ if (taskRunCallback_ != nullptr) {
60
+ taskRunCallback_(taskData_);
61
+ }
62
+ }
63
+
64
+ private:
65
+ void *taskData_;
66
+ jsr_task_run_cb taskRunCallback_;
67
+ jsr_data_delete_cb taskDataDeleteCallback_;
68
+ void *deleterData_;
69
+ };
70
+
71
+ class V8TaskRunner {
72
+ public:
73
+ static void Create(jsr_config config, std::shared_ptr<facebook::react::MessageQueueThread> queue) {
74
+ CRASH_ON_ERROR(
75
+ getV8Api().jsr_config_set_task_runner(config, new V8TaskRunner(std::move(queue)), &PostTask, &Delete, nullptr));
76
+ }
77
+
78
+ private:
79
+ V8TaskRunner(std::shared_ptr<facebook::react::MessageQueueThread> queue) : queue_(std::move(queue)) {}
80
+
81
+ static void NAPI_CDECL PostTask(
82
+ void *taskRunnerData,
83
+ void *taskData,
84
+ jsr_task_run_cb taskRunCallback,
85
+ jsr_data_delete_cb taskDataDeleteCallback,
86
+ void *deleterData) {
87
+ auto task = std::make_shared<V8Task>(taskData, taskRunCallback, taskDataDeleteCallback, deleterData);
88
+ reinterpret_cast<V8TaskRunner *>(taskRunnerData)->queue_->runOnQueue([task = std::move(task)] { task->Run(); });
89
+ }
90
+
91
+ static void NAPI_CDECL Delete(void *taskRunner, void * /*deleterData*/) {
92
+ delete reinterpret_cast<V8TaskRunner *>(taskRunner);
93
+ }
94
+
95
+ private:
96
+ std::shared_ptr<facebook::react::MessageQueueThread> queue_;
97
+ };
98
+
99
+ struct V8JsiBuffer : facebook::jsi::Buffer {
100
+ static std::shared_ptr<const facebook::jsi::Buffer>
101
+ Create(const uint8_t *buffer, size_t bufferSize, jsr_data_delete_cb bufferDeleteCallback, void *deleterData) {
102
+ return std::shared_ptr<const facebook::jsi::Buffer>(
103
+ new V8JsiBuffer(buffer, bufferSize, bufferDeleteCallback, deleterData));
104
+ }
105
+
106
+ V8JsiBuffer(
107
+ const uint8_t *buffer,
108
+ size_t bufferSize,
109
+ jsr_data_delete_cb bufferDeleteCallback,
110
+ void *deleterData) noexcept
111
+ : buffer_(buffer),
112
+ bufferSize_(bufferSize),
113
+ bufferDeleteCallback_(bufferDeleteCallback),
114
+ deleterData_(deleterData) {}
115
+
116
+ ~V8JsiBuffer() override {
117
+ if (bufferDeleteCallback_) {
118
+ bufferDeleteCallback_(const_cast<uint8_t *>(buffer_), deleterData_);
119
+ }
120
+ }
121
+
122
+ const uint8_t *data() const override {
123
+ return buffer_;
124
+ }
125
+
126
+ size_t size() const override {
127
+ return bufferSize_;
128
+ }
129
+
130
+ private:
131
+ const uint8_t *buffer_;
132
+ size_t bufferSize_;
133
+ jsr_data_delete_cb bufferDeleteCallback_;
134
+ void *deleterData_;
135
+ };
136
+
137
+ class V8ScriptCache {
138
+ public:
139
+ static void Create(jsr_config config, std::shared_ptr<facebook::jsi::PreparedScriptStore> scriptStore) {
140
+ CRASH_ON_ERROR(getV8Api().jsr_config_set_script_cache(
141
+ config, new V8ScriptCache(std::move(scriptStore)), &LoadScript, &StoreScript, &Delete, nullptr));
142
+ }
143
+
144
+ private:
145
+ V8ScriptCache(std::shared_ptr<facebook::jsi::PreparedScriptStore> scriptStore)
146
+ : scriptStore_(std::move(scriptStore)) {}
147
+
148
+ static void NAPI_CDECL LoadScript(
149
+ void *scriptCache,
150
+ const char *sourceUrl,
151
+ uint64_t sourceHash,
152
+ const char *runtimeName,
153
+ uint64_t runtimeVersion,
154
+ const char *cacheTag,
155
+ const uint8_t **buffer,
156
+ size_t *bufferSize,
157
+ jsr_data_delete_cb *bufferDeleteCallback,
158
+ void **deleterData) {
159
+ auto &scriptStore = reinterpret_cast<V8ScriptCache *>(scriptCache)->scriptStore_;
160
+ std::shared_ptr<const facebook::jsi::Buffer> preparedScript = scriptStore->tryGetPreparedScript(
161
+ facebook::jsi::ScriptSignature{sourceUrl, sourceHash},
162
+ facebook::jsi::JSRuntimeSignature{runtimeName, runtimeVersion},
163
+ cacheTag);
164
+ if (preparedScript) {
165
+ *buffer = preparedScript->data();
166
+ *bufferSize = preparedScript->size();
167
+ *bufferDeleteCallback = [](void * /*data*/, void *deleterData) noexcept {
168
+ delete reinterpret_cast<std::shared_ptr<const facebook::jsi::Buffer> *>(deleterData);
169
+ };
170
+ *deleterData = new std::shared_ptr<const facebook::jsi::Buffer>(std::move(preparedScript));
171
+ } else {
172
+ *buffer = nullptr;
173
+ *bufferSize = 0;
174
+ *bufferDeleteCallback = nullptr;
175
+ *deleterData = nullptr;
176
+ }
177
+ }
178
+
179
+ static void NAPI_CDECL StoreScript(
180
+ void *scriptCache,
181
+ const char *sourceUrl,
182
+ uint64_t sourceHash,
183
+ const char *runtimeName,
184
+ uint64_t runtimeVersion,
185
+ const char *cacheTag,
186
+ const uint8_t *buffer,
187
+ size_t bufferSize,
188
+ jsr_data_delete_cb bufferDeleteCallback,
189
+ void *deleterData) {
190
+ auto &scriptStore = reinterpret_cast<V8ScriptCache *>(scriptCache)->scriptStore_;
191
+ scriptStore->persistPreparedScript(
192
+ V8JsiBuffer::Create(buffer, bufferSize, bufferDeleteCallback, deleterData),
193
+ facebook::jsi::ScriptSignature{sourceUrl, sourceHash},
194
+ facebook::jsi::JSRuntimeSignature{runtimeName, runtimeVersion},
195
+ cacheTag);
196
+ }
197
+
198
+ static void NAPI_CDECL Delete(void *scriptCache, void * /*deleterData*/) {
199
+ delete reinterpret_cast<V8ScriptCache *>(scriptCache);
200
+ }
201
+
202
+ private:
203
+ std::shared_ptr<facebook::jsi::PreparedScriptStore> scriptStore_;
204
+ };
205
+
206
+ } // namespace
207
+
208
+ V8RuntimeHolder::V8RuntimeHolder(
209
+ std::shared_ptr<facebook::react::DevSettings> devSettings,
210
+ std::shared_ptr<facebook::react::MessageQueueThread> jsQueue,
211
+ std::shared_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore,
212
+ bool enableMultiThreadingSupport) noexcept
213
+ : m_weakDevSettings(devSettings),
214
+ m_jsQueue(std::move(jsQueue)),
215
+ m_preparedScriptStore(std::move(preparedScriptStore)),
216
+ m_enableMultiThreadingSupport(enableMultiThreadingSupport) {}
217
+
218
+ void V8RuntimeHolder::initRuntime() noexcept {
219
+ std::shared_ptr<facebook::react::DevSettings> devSettings = m_weakDevSettings.lock();
220
+ VerifyElseCrash(devSettings);
221
+
222
+ V8Api &api = getV8Api();
223
+ V8Api::setCurrent(&api);
224
+ jsr_config config{};
225
+ CRASH_ON_ERROR(api.jsr_create_config(&config));
226
+ CRASH_ON_ERROR(api.jsr_config_enable_inspector(config, devSettings->useDirectDebugger));
227
+ CRASH_ON_ERROR(api.jsr_config_set_inspector_runtime_name(config, devSettings->debuggerRuntimeName.c_str()));
228
+ CRASH_ON_ERROR(api.jsr_config_set_inspector_port(config, devSettings->debuggerPort));
229
+ CRASH_ON_ERROR(api.jsr_config_set_inspector_break_on_start(config, devSettings->debuggerBreakOnNextLine));
230
+ CRASH_ON_ERROR(api.v8_config_enable_multithreading(config, m_enableMultiThreadingSupport));
231
+
232
+ if (m_jsQueue) {
233
+ V8TaskRunner::Create(config, m_jsQueue);
234
+ }
235
+ if (m_preparedScriptStore) {
236
+ V8ScriptCache::Create(config, m_preparedScriptStore);
237
+ }
238
+ jsr_runtime runtime{};
239
+ CRASH_ON_ERROR(api.jsr_create_runtime(config, &runtime));
240
+ CRASH_ON_ERROR(api.jsr_delete_config(config));
241
+
242
+ CRASH_ON_ERROR(api.jsr_create_runtime(config, &runtime));
243
+
244
+ napi_env env{};
245
+ CRASH_ON_ERROR(api.jsr_runtime_get_node_api_env(runtime, &env));
246
+
247
+ m_jsiRuntime =
248
+ makeNodeApiJsiRuntime(env, &api, [runtime]() { CRASH_ON_ERROR(V8Api::current()->jsr_delete_runtime(runtime)); });
249
+ m_ownThreadId = std::this_thread::get_id();
250
+ }
251
+
252
+ facebook::react::JSIEngineOverride V8RuntimeHolder::getRuntimeType() noexcept {
253
+ return facebook::react::JSIEngineOverride::V8NodeApi;
254
+ }
255
+
256
+ std::shared_ptr<facebook::jsi::Runtime> V8RuntimeHolder::getRuntime() noexcept {
257
+ std::call_once(m_onceFlag, [this]() { initRuntime(); });
258
+ VerifyElseCrash(m_jsiRuntime);
259
+ return m_jsiRuntime;
260
+ }
261
+
262
+ } // namespace Microsoft::ReactNative