react-native-windows 0.71.25 → 0.71.27
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.
- package/Directory.Build.props +0 -5
- package/Microsoft.ReactNative/IReactDispatcher.cpp +0 -4
- package/Microsoft.ReactNative/IReactDispatcher.h +0 -1
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +4 -2
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +11 -31
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +2 -0
- package/Microsoft.ReactNative/Views/DevMenu.cpp +3 -3
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.cpp +2103 -0
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.h +73 -0
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +12 -43
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +6 -17
- package/Microsoft.ReactNative.Managed/packages.lock.json +73 -4
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CSharpApp.targets +1 -1
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppApp.targets +1 -1
- package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.CSharpApp.targets +1 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +4 -4
- package/PropertySheets/React.Cpp.props +0 -1
- package/PropertySheets/Warnings.props +0 -6
- package/ReactCommon/ReactCommon.vcxproj +1 -53
- package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +0 -36
- package/Shared/DevSupportManager.cpp +9 -2
- package/Shared/DevSupportManager.h +6 -2
- package/Shared/HermesRuntimeHolder.cpp +84 -344
- package/Shared/HermesRuntimeHolder.h +21 -32
- package/Shared/HermesSamplingProfiler.cpp +14 -66
- package/Shared/HermesSamplingProfiler.h +3 -5
- package/Shared/HermesShim.cpp +118 -0
- package/Shared/HermesShim.h +21 -0
- package/Shared/InspectorPackagerConnection.cpp +108 -62
- package/Shared/InspectorPackagerConnection.h +21 -9
- package/Shared/JSI/NapiJsiV8RuntimeHolder.cpp +209 -0
- package/Shared/JSI/NapiJsiV8RuntimeHolder.h +44 -0
- package/Shared/JSI/RuntimeHolder.h +2 -2
- package/Shared/JSI/ScriptStore.h +20 -18
- package/Shared/Modules/HttpModule.cpp +10 -23
- package/Shared/Modules/HttpModule.h +0 -1
- package/Shared/Networking/DefaultBlobResource.cpp +6 -1
- package/Shared/Networking/WinRTHttpResource.cpp +9 -0
- package/Shared/OInstance.cpp +48 -52
- package/Shared/Shared.vcxitems +8 -19
- package/Shared/Shared.vcxitems.filters +30 -23
- package/Shared/V8JSIRuntimeHolder.cpp +70 -0
- package/Shared/V8JSIRuntimeHolder.h +53 -0
- package/package.json +2 -2
- package/template/cs-app-WinAppSDK/proj/ExperimentalFeatures.props +1 -1
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiLoader.cpp +0 -16
- package/ReactCommon/cgmanifest.json +0 -15
- package/Shared/JSI/V8RuntimeHolder.cpp +0 -260
- package/Shared/JSI/V8RuntimeHolder.h +0 -37
- package/Shared/SafeLoadLibrary.cpp +0 -41
- package/Shared/SafeLoadLibrary.h +0 -15
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#include "NapiJsiV8RuntimeHolder.h"
|
|
5
|
+
|
|
6
|
+
using namespace facebook::jsi;
|
|
7
|
+
using namespace facebook::react;
|
|
8
|
+
|
|
9
|
+
using std::shared_ptr;
|
|
10
|
+
using std::unique_ptr;
|
|
11
|
+
|
|
12
|
+
namespace Microsoft::JSI {
|
|
13
|
+
|
|
14
|
+
class NapiTask {
|
|
15
|
+
public:
|
|
16
|
+
NapiTask(void *task, v8_task_run_cb onTaskRun, v8_task_release_cb onTaskRelease)
|
|
17
|
+
: task_(task), onTaskRun_(onTaskRun), onTaskRelease_(onTaskRelease) {}
|
|
18
|
+
|
|
19
|
+
NapiTask(NapiTask &&other)
|
|
20
|
+
: task_(std::exchange(other.task_, nullptr)),
|
|
21
|
+
onTaskRun_(std::exchange(other.onTaskRun_, nullptr)),
|
|
22
|
+
onTaskRelease_(std::exchange(other.onTaskRelease_, nullptr)) {}
|
|
23
|
+
|
|
24
|
+
NapiTask &operator=(NapiTask &&other) {
|
|
25
|
+
if (this != &other) {
|
|
26
|
+
NapiTask taskToDelete(std::move(*this));
|
|
27
|
+
task_ = std::exchange(other.task_, nullptr);
|
|
28
|
+
onTaskRun_ = std::exchange(other.onTaskRun_, nullptr);
|
|
29
|
+
onTaskRelease_ = std::exchange(other.onTaskRelease_, nullptr);
|
|
30
|
+
}
|
|
31
|
+
return *this;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
NapiTask(const NapiTask &other) = delete;
|
|
35
|
+
NapiTask &operator=(const NapiTask &other) = delete;
|
|
36
|
+
|
|
37
|
+
~NapiTask() {
|
|
38
|
+
if (task_ != nullptr) {
|
|
39
|
+
onTaskRelease_(task_);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
void Run() const {
|
|
44
|
+
if (task_ != nullptr) {
|
|
45
|
+
onTaskRun_(task_);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private:
|
|
50
|
+
void *task_;
|
|
51
|
+
v8_task_run_cb onTaskRun_;
|
|
52
|
+
v8_task_release_cb onTaskRelease_;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
class NapiTaskRunner {
|
|
56
|
+
public:
|
|
57
|
+
NapiTaskRunner(std::shared_ptr<facebook::react::MessageQueueThread> jsQueue) : m_jsQueue(std::move(jsQueue)) {}
|
|
58
|
+
|
|
59
|
+
static v8_task_runner_t Create(std::shared_ptr<facebook::react::MessageQueueThread> jsQueue) {
|
|
60
|
+
NapiTaskRunner *taskRunner = new NapiTaskRunner(std::move(jsQueue));
|
|
61
|
+
return v8_create_task_runner(reinterpret_cast<void *>(taskRunner), &PostTask, &Release);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private:
|
|
65
|
+
static void __cdecl PostTask(
|
|
66
|
+
void *taskRunner,
|
|
67
|
+
void *task,
|
|
68
|
+
v8_task_run_cb onTaskRun,
|
|
69
|
+
v8_task_release_cb onTaskRelease) {
|
|
70
|
+
auto napiTask = std::make_shared<NapiTask>(task, onTaskRun, onTaskRelease);
|
|
71
|
+
reinterpret_cast<NapiTaskRunner *>(taskRunner)->m_jsQueue->runOnQueue([napiTask = std::move(napiTask)] {
|
|
72
|
+
napiTask->Run();
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static void __cdecl Release(void *taskRunner) {
|
|
77
|
+
delete reinterpret_cast<NapiTaskRunner *>(taskRunner);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private:
|
|
81
|
+
std::shared_ptr<facebook::react::MessageQueueThread> m_jsQueue;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
NapiJsiV8RuntimeHolder::NapiJsiV8RuntimeHolder(
|
|
85
|
+
shared_ptr<DevSettings> devSettings,
|
|
86
|
+
shared_ptr<MessageQueueThread> jsQueue,
|
|
87
|
+
unique_ptr<ScriptStore> &&scriptStore,
|
|
88
|
+
unique_ptr<PreparedScriptStore> &&preparedScriptStore) noexcept
|
|
89
|
+
: m_useDirectDebugger{devSettings->useDirectDebugger},
|
|
90
|
+
m_debuggerBreakOnNextLine{devSettings->debuggerBreakOnNextLine},
|
|
91
|
+
m_debuggerPort{devSettings->debuggerPort},
|
|
92
|
+
m_debuggerRuntimeName{devSettings->debuggerRuntimeName},
|
|
93
|
+
m_jsQueue{jsQueue},
|
|
94
|
+
m_scriptStore{std::move(scriptStore)},
|
|
95
|
+
m_preparedScriptStore{std::move(preparedScriptStore)} {}
|
|
96
|
+
|
|
97
|
+
void NapiJsiV8RuntimeHolder::InitRuntime() noexcept {
|
|
98
|
+
napi_ext_env_settings settings{};
|
|
99
|
+
settings.this_size = sizeof(settings);
|
|
100
|
+
if (m_debuggerPort > 0)
|
|
101
|
+
settings.inspector_port = m_debuggerPort;
|
|
102
|
+
|
|
103
|
+
settings.flags.enable_inspector = m_useDirectDebugger;
|
|
104
|
+
settings.flags.wait_for_debugger = m_debuggerBreakOnNextLine;
|
|
105
|
+
// TODO: args.debuggerRuntimeName = debuggerRuntimeName_;
|
|
106
|
+
settings.foreground_task_runner = NapiTaskRunner::Create(m_jsQueue);
|
|
107
|
+
|
|
108
|
+
napi_ext_script_cache scriptCache = InitScriptCache(std::move(m_preparedScriptStore));
|
|
109
|
+
settings.script_cache = &scriptCache;
|
|
110
|
+
|
|
111
|
+
napi_env env{};
|
|
112
|
+
napi_ext_create_env(&settings, &env);
|
|
113
|
+
// Associate environment to holder.
|
|
114
|
+
napi_set_instance_data(env, this, nullptr /*finalize_cb*/, nullptr /*finalize_hint*/);
|
|
115
|
+
|
|
116
|
+
m_runtime = MakeNodeApiJsiRuntime(env);
|
|
117
|
+
m_ownThreadId = std::this_thread::get_id();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
struct NodeApiJsiBuffer : facebook::jsi::Buffer {
|
|
121
|
+
static std::shared_ptr<const facebook::jsi::Buffer> CreateJsiBuffer(const napi_ext_buffer *buffer) {
|
|
122
|
+
if (buffer && buffer->data) {
|
|
123
|
+
return std::shared_ptr<const facebook::jsi::Buffer>(new NodeApiJsiBuffer(buffer));
|
|
124
|
+
} else {
|
|
125
|
+
return {};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
NodeApiJsiBuffer(const napi_ext_buffer *buffer) noexcept : buffer_(*buffer) {}
|
|
130
|
+
|
|
131
|
+
~NodeApiJsiBuffer() override {
|
|
132
|
+
if (buffer_.buffer_object.finalize_cb) {
|
|
133
|
+
buffer_.buffer_object.finalize_cb(nullptr, buffer_.buffer_object.data, buffer_.buffer_object.finalize_hint);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const uint8_t *data() const override {
|
|
138
|
+
return buffer_.data;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
size_t size() const override {
|
|
142
|
+
return buffer_.byte_size;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private:
|
|
146
|
+
napi_ext_buffer buffer_;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
napi_ext_script_cache NapiJsiV8RuntimeHolder::InitScriptCache(
|
|
150
|
+
unique_ptr<PreparedScriptStore> &&preparedScriptStore) noexcept {
|
|
151
|
+
napi_ext_script_cache scriptCache{};
|
|
152
|
+
scriptCache.cache_object = NativeObjectWrapper<unique_ptr<PreparedScriptStore>>::Wrap(std::move(preparedScriptStore));
|
|
153
|
+
scriptCache.load_cached_script = [](napi_env env,
|
|
154
|
+
napi_ext_script_cache *script_cache,
|
|
155
|
+
napi_ext_cached_script_metadata *script_metadata,
|
|
156
|
+
napi_ext_buffer *result) -> napi_status {
|
|
157
|
+
PreparedScriptStore *scriptStore = reinterpret_cast<PreparedScriptStore *>(script_cache->cache_object.data);
|
|
158
|
+
std::shared_ptr<const facebook::jsi::Buffer> buffer = scriptStore->tryGetPreparedScript(
|
|
159
|
+
ScriptSignature{script_metadata->source_url, script_metadata->source_hash},
|
|
160
|
+
JSRuntimeSignature{script_metadata->runtime_name, script_metadata->runtime_version},
|
|
161
|
+
script_metadata->tag);
|
|
162
|
+
if (buffer) {
|
|
163
|
+
result->buffer_object = NativeObjectWrapper<std::shared_ptr<const facebook::jsi::Buffer>>::Wrap(
|
|
164
|
+
std::shared_ptr<const facebook::jsi::Buffer>{buffer});
|
|
165
|
+
result->data = buffer->data();
|
|
166
|
+
result->byte_size = buffer->size();
|
|
167
|
+
} else {
|
|
168
|
+
*result = napi_ext_buffer{};
|
|
169
|
+
}
|
|
170
|
+
return napi_ok;
|
|
171
|
+
};
|
|
172
|
+
scriptCache.store_cached_script = [](napi_env env,
|
|
173
|
+
napi_ext_script_cache *script_cache,
|
|
174
|
+
napi_ext_cached_script_metadata *script_metadata,
|
|
175
|
+
const napi_ext_buffer *buffer) -> napi_status {
|
|
176
|
+
PreparedScriptStore *scriptStore = reinterpret_cast<PreparedScriptStore *>(script_cache->cache_object.data);
|
|
177
|
+
scriptStore->persistPreparedScript(
|
|
178
|
+
NodeApiJsiBuffer::CreateJsiBuffer(buffer),
|
|
179
|
+
ScriptSignature{script_metadata->source_url, script_metadata->source_hash},
|
|
180
|
+
JSRuntimeSignature{script_metadata->runtime_name, script_metadata->runtime_version},
|
|
181
|
+
script_metadata->tag);
|
|
182
|
+
return napi_ok;
|
|
183
|
+
};
|
|
184
|
+
return scriptCache;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
#pragma region Microsoft::JSI::RuntimeHolderLazyInit
|
|
188
|
+
|
|
189
|
+
facebook::react::JSIEngineOverride NapiJsiV8RuntimeHolder::getRuntimeType() noexcept {
|
|
190
|
+
return facebook::react::JSIEngineOverride::V8NodeApi;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
shared_ptr<Runtime> NapiJsiV8RuntimeHolder::getRuntime() noexcept /*override*/
|
|
194
|
+
{
|
|
195
|
+
std::call_once(m_onceFlag, [this]() { InitRuntime(); });
|
|
196
|
+
|
|
197
|
+
if (!m_runtime)
|
|
198
|
+
std::terminate();
|
|
199
|
+
|
|
200
|
+
// V8 NapiJsiRuntime is not known to be thread safe.
|
|
201
|
+
if (m_ownThreadId != std::this_thread::get_id())
|
|
202
|
+
__fastfail(FAST_FAIL_INVALID_THREAD);
|
|
203
|
+
|
|
204
|
+
return m_runtime;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
#pragma endregion Microsoft::JSI::RuntimeHolderLazyInit
|
|
208
|
+
|
|
209
|
+
} // namespace Microsoft::JSI
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include <DevSettings.h>
|
|
7
|
+
#include <JSI/NodeApiJsiRuntime.h>
|
|
8
|
+
#include "RuntimeHolder.h"
|
|
9
|
+
#include "ScriptStore.h"
|
|
10
|
+
|
|
11
|
+
namespace Microsoft::JSI {
|
|
12
|
+
|
|
13
|
+
class NapiJsiV8RuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
|
|
14
|
+
public:
|
|
15
|
+
std::shared_ptr<facebook::jsi::Runtime> getRuntime() noexcept override;
|
|
16
|
+
facebook::react::JSIEngineOverride getRuntimeType() noexcept override;
|
|
17
|
+
|
|
18
|
+
NapiJsiV8RuntimeHolder(
|
|
19
|
+
std::shared_ptr<facebook::react::DevSettings> devSettings,
|
|
20
|
+
std::shared_ptr<facebook::react::MessageQueueThread> jsQueue,
|
|
21
|
+
std::unique_ptr<facebook::jsi::ScriptStore> &&scriptStore,
|
|
22
|
+
std::unique_ptr<facebook::jsi::PreparedScriptStore> &&preparedScriptStore) noexcept;
|
|
23
|
+
|
|
24
|
+
private:
|
|
25
|
+
void InitRuntime() noexcept;
|
|
26
|
+
napi_ext_script_cache InitScriptCache(
|
|
27
|
+
std::unique_ptr<facebook::jsi::PreparedScriptStore> &&preparedScriptStore) noexcept;
|
|
28
|
+
|
|
29
|
+
std::shared_ptr<facebook::jsi::Runtime> m_runtime;
|
|
30
|
+
std::shared_ptr<facebook::react::MessageQueueThread> m_jsQueue;
|
|
31
|
+
|
|
32
|
+
std::unique_ptr<facebook::jsi::ScriptStore> m_scriptStore;
|
|
33
|
+
std::unique_ptr<facebook::jsi::PreparedScriptStore> m_preparedScriptStore;
|
|
34
|
+
|
|
35
|
+
std::once_flag m_onceFlag;
|
|
36
|
+
std::thread::id m_ownThreadId;
|
|
37
|
+
|
|
38
|
+
uint16_t m_debuggerPort;
|
|
39
|
+
bool m_useDirectDebugger{false};
|
|
40
|
+
bool m_debuggerBreakOnNextLine{false};
|
|
41
|
+
std::string m_debuggerRuntimeName;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
} // namespace Microsoft::JSI
|
|
@@ -11,7 +11,7 @@ namespace Microsoft::JSI {
|
|
|
11
11
|
// a. lazily create a JSI Runtime on the first call to getRuntime
|
|
12
12
|
// b. subsequent calls to getRuntime should return the Runtime created in (a)
|
|
13
13
|
|
|
14
|
-
// Note
|
|
14
|
+
// Note :: All calls to getRuntime() should happen on the same thread unless you are sure that
|
|
15
15
|
// the underlying Runtime instance is thread safe.
|
|
16
16
|
|
|
17
17
|
struct RuntimeHolderLazyInit {
|
|
@@ -21,7 +21,7 @@ struct RuntimeHolderLazyInit {
|
|
|
21
21
|
virtual void teardown() noexcept {};
|
|
22
22
|
|
|
23
23
|
// You can call this when a crash happens to attempt recording additional data
|
|
24
|
-
// The
|
|
24
|
+
// The fd supplied is a raw file stream an implementation might write JSON to
|
|
25
25
|
virtual void crashHandler(int fileDescriptor) noexcept {};
|
|
26
26
|
};
|
|
27
27
|
|
package/Shared/JSI/ScriptStore.h
CHANGED
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
#include <jsi/jsi.h>
|
|
6
6
|
#include <memory>
|
|
7
7
|
|
|
8
|
-
namespace facebook
|
|
8
|
+
namespace facebook {
|
|
9
|
+
namespace jsi {
|
|
9
10
|
|
|
10
|
-
// Integer type as it's persist
|
|
11
|
-
using ScriptVersion_t = uint64_t; // It
|
|
12
|
-
//
|
|
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.
|
|
13
14
|
using JSRuntimeVersion_t = uint64_t; // 0 implies version can't be computed. We assert whenever that happens.
|
|
14
15
|
|
|
15
16
|
struct VersionedBuffer {
|
|
@@ -29,14 +30,14 @@ struct JSRuntimeSignature {
|
|
|
29
30
|
|
|
30
31
|
// Most JSI::Runtime implementation offer some form of prepared JavaScript which offers better performance
|
|
31
32
|
// characteristics when loading comparing to plain JavaScript. Embedders can provide an instance of this interface
|
|
32
|
-
// (through JSI::Runtime implementation's factory method), to enable
|
|
33
|
-
//
|
|
33
|
+
// (through JSI::Runtime implementation's factory method), to enable persistance of the prepared script and retrieval on
|
|
34
|
+
// subsequent evaluation of a script.
|
|
34
35
|
struct PreparedScriptStore {
|
|
35
36
|
virtual ~PreparedScriptStore() = default;
|
|
36
37
|
|
|
37
|
-
// Try to retrieve the prepared
|
|
38
|
-
// scriptSignature :
|
|
39
|
-
// RuntimeSignature :
|
|
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
|
|
40
41
|
// prepareTag : Custom tag to uniquely identify JS engine specific preparation schemes. It is usually useful while
|
|
41
42
|
// experimentation and can be null. It is possible that no prepared script is available for a given script & runtime
|
|
42
43
|
// signature. This method should null if so
|
|
@@ -46,12 +47,12 @@ struct PreparedScriptStore {
|
|
|
46
47
|
const char *prepareTag // Optional tag. For e.g. eagerly evaluated vs lazy cache.
|
|
47
48
|
) noexcept = 0;
|
|
48
49
|
|
|
49
|
-
// Persist the
|
|
50
|
-
// scriptSignature :
|
|
51
|
-
// RuntimeSignature :
|
|
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
|
|
52
53
|
// prepareTag : Custom tag to uniquely identify JS engine specific preparation schemes. It is usually useful while
|
|
53
54
|
// experimentation and can be null. It is possible that no prepared script is available for a given script & runtime
|
|
54
|
-
// signature. This method should null if so Any failure in
|
|
55
|
+
// signature. This method should null if so Any failure in persistance should be identified during the subsequent
|
|
55
56
|
// retrieval through the integrity mechanism which must be put into the storage.
|
|
56
57
|
virtual void persistPreparedScript(
|
|
57
58
|
std::shared_ptr<const facebook::jsi::Buffer> preparedScript,
|
|
@@ -62,16 +63,17 @@ struct PreparedScriptStore {
|
|
|
62
63
|
};
|
|
63
64
|
|
|
64
65
|
// JSI::Runtime implementation must be provided an instance on this interface to enable version sensitive capabilities
|
|
65
|
-
// such as usage of prepared
|
|
66
|
-
//
|
|
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.
|
|
67
68
|
struct ScriptStore {
|
|
68
69
|
virtual ~ScriptStore() = default;
|
|
69
70
|
|
|
70
|
-
// Return the
|
|
71
|
+
// Return the Javascript buffer and version corresponding to a given url.
|
|
71
72
|
virtual VersionedBuffer getVersionedScript(const std::string &url) noexcept = 0;
|
|
72
73
|
|
|
73
|
-
// Return the version of the
|
|
74
|
+
// Return the version of the Javascript buffer corresponding to a given url.
|
|
74
75
|
virtual ScriptVersion_t getScriptVersion(const std::string &url) noexcept = 0;
|
|
75
76
|
};
|
|
76
77
|
|
|
77
|
-
} // namespace
|
|
78
|
+
} // namespace jsi
|
|
79
|
+
} // namespace facebook
|
|
@@ -237,6 +237,8 @@ std::map<string, dynamic> HttpModule::getConstants() {
|
|
|
237
237
|
|
|
238
238
|
// clang-format off
|
|
239
239
|
std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods() {
|
|
240
|
+
// See CxxNativeModule::lazyInit()
|
|
241
|
+
SetUpHttpResource(m_resource, getInstance(), m_inspectableProperties);
|
|
240
242
|
|
|
241
243
|
return
|
|
242
244
|
{
|
|
@@ -249,12 +251,6 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
249
251
|
return;
|
|
250
252
|
}
|
|
251
253
|
|
|
252
|
-
auto resource = holder->Module->m_resource;
|
|
253
|
-
if (!holder->Module->m_isResourceSetup)
|
|
254
|
-
{
|
|
255
|
-
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
256
|
-
holder->Module->m_isResourceSetup = true;
|
|
257
|
-
}
|
|
258
254
|
holder->Module->m_requestId++;
|
|
259
255
|
|
|
260
256
|
auto params = facebook::xplat::jsArgAsObject(args, 0);
|
|
@@ -263,7 +259,7 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
263
259
|
headers.emplace(header.first.getString(), header.second.getString());
|
|
264
260
|
}
|
|
265
261
|
|
|
266
|
-
|
|
262
|
+
holder->Module->m_resource->SendRequest(
|
|
267
263
|
params["method"].asString(),
|
|
268
264
|
params["url"].asString(),
|
|
269
265
|
holder->Module->m_requestId,
|
|
@@ -289,14 +285,7 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
289
285
|
return;
|
|
290
286
|
}
|
|
291
287
|
|
|
292
|
-
|
|
293
|
-
if (!holder->Module->m_isResourceSetup)
|
|
294
|
-
{
|
|
295
|
-
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
296
|
-
holder->Module->m_isResourceSetup = true;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
resource->AbortRequest(facebook::xplat::jsArgAsInt(args, 0));
|
|
288
|
+
holder->Module->m_resource->AbortRequest(facebook::xplat::jsArgAsInt(args, 0));
|
|
300
289
|
}
|
|
301
290
|
},
|
|
302
291
|
{
|
|
@@ -309,14 +298,7 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
309
298
|
return;
|
|
310
299
|
}
|
|
311
300
|
|
|
312
|
-
|
|
313
|
-
if (!holder->Module->m_isResourceSetup)
|
|
314
|
-
{
|
|
315
|
-
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
316
|
-
holder->Module->m_isResourceSetup = true;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
resource->ClearCookies();
|
|
301
|
+
holder->Module->m_resource->ClearCookies();
|
|
320
302
|
}
|
|
321
303
|
}
|
|
322
304
|
};
|
|
@@ -331,6 +313,11 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
331
313
|
return s_moduleName;
|
|
332
314
|
}
|
|
333
315
|
|
|
316
|
+
/*extern*/ std::unique_ptr<facebook::xplat::module::CxxModule> CreateHttpModule(
|
|
317
|
+
IInspectable const &inspectableProperties) noexcept {
|
|
318
|
+
return std::make_unique<HttpModule>(inspectableProperties);
|
|
319
|
+
}
|
|
320
|
+
|
|
334
321
|
/*extern*/ const wchar_t *GetHttpTurboModuleName() noexcept {
|
|
335
322
|
return s_moduleNameW;
|
|
336
323
|
}
|
|
@@ -84,7 +84,6 @@ class HttpModule : public facebook::xplat::module::CxxModule {
|
|
|
84
84
|
|
|
85
85
|
std::shared_ptr<Networking::IHttpResource> m_resource;
|
|
86
86
|
std::shared_ptr<ModuleHolder> m_holder;
|
|
87
|
-
bool m_isResourceSetup{false};
|
|
88
87
|
int64_t m_requestId{0};
|
|
89
88
|
|
|
90
89
|
// Property bag high level reference.
|
|
@@ -145,8 +145,13 @@ void DefaultBlobResource::AddNetworkingHandler() noexcept /*override*/ {
|
|
|
145
145
|
httpHandler->AddRequestBodyHandler(m_requestBodyHandler);
|
|
146
146
|
httpHandler->AddResponseHandler(m_responseHandler);
|
|
147
147
|
}
|
|
148
|
+
} else {
|
|
149
|
+
// #11439 - The absence of HttpModule.Proxy may be caused by a module initialization race condition.
|
|
150
|
+
// Best-effort approach to set up the request/response handlers by exposing this interface to dependents
|
|
151
|
+
// (i.e. IHttpResource).
|
|
152
|
+
auto propId = msrn::ReactPropertyId<msrn::ReactNonAbiValue<weak_ptr<IBlobResource>>>{L"Blob.Resource"};
|
|
153
|
+
m_propertyBag.Set(propId, weak_ptr<IBlobResource>(shared_from_this()));
|
|
148
154
|
}
|
|
149
|
-
// TODO: else emit error?
|
|
150
155
|
}
|
|
151
156
|
|
|
152
157
|
void DefaultBlobResource::AddWebSocketHandler(int64_t id) noexcept /*override*/ {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
#include "WinRTHttpResource.h"
|
|
7
7
|
|
|
8
8
|
#include <CppRuntimeOptions.h>
|
|
9
|
+
#include <Networking/IBlobResource.h>
|
|
9
10
|
#include <ReactPropertyBag.h>
|
|
10
11
|
#include <Utils/CppWinrtLessExceptions.h>
|
|
11
12
|
#include <Utils/WinRTConversions.h>
|
|
@@ -672,6 +673,14 @@ void WinRTHttpResource::AddResponseHandler(shared_ptr<IResponseHandler> response
|
|
|
672
673
|
auto propBag = ReactPropertyBag{inspectableProperties.try_as<IReactPropertyBag>()};
|
|
673
674
|
auto moduleProxy = weak_ptr<IHttpModuleProxy>{result};
|
|
674
675
|
propBag.Set(propId, std::move(moduleProxy));
|
|
676
|
+
|
|
677
|
+
// #11439 - Best-effort attempt to set up the HTTP handler after an initial call to addNetworkingHandler failed.
|
|
678
|
+
auto blobRcPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<Networking::IBlobResource>>>{L"Blob.Resource"};
|
|
679
|
+
if (auto prop = propBag.Get(blobRcPropId)) {
|
|
680
|
+
if (auto blobRc = prop.Value().lock()) {
|
|
681
|
+
blobRc->AddNetworkingHandler();
|
|
682
|
+
}
|
|
683
|
+
}
|
|
675
684
|
}
|
|
676
685
|
|
|
677
686
|
return result;
|
package/Shared/OInstance.cpp
CHANGED
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
#include <cxxreact/ModuleRegistry.h>
|
|
27
27
|
|
|
28
28
|
#include <Modules/ExceptionsManagerModule.h>
|
|
29
|
-
#include <Modules/HttpModule.h>
|
|
30
29
|
#include <Modules/PlatformConstantsModule.h>
|
|
31
30
|
#include <Modules/SourceCodeModule.h>
|
|
32
31
|
#include <Modules/StatusBarManagerModule.h>
|
|
@@ -52,11 +51,13 @@
|
|
|
52
51
|
#include "HermesRuntimeHolder.h"
|
|
53
52
|
|
|
54
53
|
#if defined(USE_V8)
|
|
55
|
-
#include <JSI/
|
|
54
|
+
#include <JSI/NapiJsiV8RuntimeHolder.h>
|
|
55
|
+
|
|
56
|
+
#include "BaseScriptStoreImpl.h"
|
|
57
|
+
#include "V8JSIRuntimeHolder.h"
|
|
56
58
|
#endif
|
|
57
59
|
#include <ReactCommon/CallInvoker.h>
|
|
58
60
|
#include <ReactCommon/TurboModuleBinding.h>
|
|
59
|
-
#include "BaseScriptStoreImpl.h"
|
|
60
61
|
#include "ChakraRuntimeHolder.h"
|
|
61
62
|
|
|
62
63
|
#include <tracing/tracing.h>
|
|
@@ -68,15 +69,6 @@ using namespace Microsoft::JSI;
|
|
|
68
69
|
using std::make_shared;
|
|
69
70
|
using winrt::Microsoft::ReactNative::ReactPropertyBagHelper;
|
|
70
71
|
|
|
71
|
-
namespace Microsoft::React {
|
|
72
|
-
|
|
73
|
-
/*extern*/ std::unique_ptr<facebook::xplat::module::CxxModule> CreateHttpModule(
|
|
74
|
-
winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept {
|
|
75
|
-
return std::make_unique<HttpModule>(inspectableProperties);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
} // namespace Microsoft::React
|
|
79
|
-
|
|
80
72
|
namespace facebook {
|
|
81
73
|
namespace react {
|
|
82
74
|
|
|
@@ -316,32 +308,46 @@ InstanceImpl::InstanceImpl(
|
|
|
316
308
|
} else {
|
|
317
309
|
assert(m_devSettings->jsiEngineOverride != JSIEngineOverride::Default);
|
|
318
310
|
switch (m_devSettings->jsiEngineOverride) {
|
|
319
|
-
case JSIEngineOverride::Hermes:
|
|
320
|
-
std::
|
|
311
|
+
case JSIEngineOverride::Hermes:
|
|
312
|
+
m_devSettings->jsiRuntimeHolder = std::make_shared<HermesRuntimeHolder>(m_devSettings, m_jsThread);
|
|
313
|
+
break;
|
|
314
|
+
case JSIEngineOverride::V8: {
|
|
315
|
+
#if defined(USE_V8)
|
|
316
|
+
std::unique_ptr<facebook::jsi::ScriptStore> scriptStore = nullptr;
|
|
317
|
+
std::unique_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore = nullptr;
|
|
321
318
|
|
|
322
|
-
|
|
323
|
-
if (
|
|
324
|
-
preparedScriptStore =
|
|
325
|
-
std::make_shared<facebook::react::BasePreparedScriptStoreImpl>(winrt::to_string(tempPath));
|
|
319
|
+
char tempPath[MAX_PATH];
|
|
320
|
+
if (GetTempPathA(MAX_PATH, tempPath)) {
|
|
321
|
+
preparedScriptStore = std::make_unique<facebook::react::BasePreparedScriptStoreImpl>(tempPath);
|
|
326
322
|
}
|
|
327
323
|
|
|
328
|
-
m_devSettings->jsiRuntimeHolder = std::make_shared<
|
|
329
|
-
m_devSettings, m_jsThread, std::move(preparedScriptStore));
|
|
324
|
+
m_devSettings->jsiRuntimeHolder = std::make_shared<facebook::react::V8JSIRuntimeHolder>(
|
|
325
|
+
m_devSettings, m_jsThread, std::move(scriptStore), std::move(preparedScriptStore));
|
|
330
326
|
break;
|
|
327
|
+
#else
|
|
328
|
+
assert(false); // V8 is not available in this build, fallthrough
|
|
329
|
+
[[fallthrough]];
|
|
330
|
+
#endif
|
|
331
331
|
}
|
|
332
|
-
case JSIEngineOverride::V8:
|
|
333
332
|
case JSIEngineOverride::V8NodeApi: {
|
|
334
333
|
#if defined(USE_V8)
|
|
335
|
-
std::
|
|
334
|
+
std::unique_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore;
|
|
336
335
|
|
|
337
336
|
wchar_t tempPath[MAX_PATH];
|
|
338
|
-
if (GetTempPathW(
|
|
337
|
+
if (GetTempPathW(static_cast<DWORD>(std::size(tempPath)), tempPath)) {
|
|
339
338
|
preparedScriptStore =
|
|
340
|
-
std::
|
|
339
|
+
std::make_unique<facebook::react::BasePreparedScriptStoreImpl>(winrt::to_string(tempPath));
|
|
341
340
|
}
|
|
342
341
|
|
|
343
|
-
|
|
344
|
-
|
|
342
|
+
if (!preparedScriptStore) {
|
|
343
|
+
if (m_devSettings->errorCallback)
|
|
344
|
+
m_devSettings->errorCallback("Could not initialize prepared script store");
|
|
345
|
+
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
m_devSettings->jsiRuntimeHolder = make_shared<NapiJsiV8RuntimeHolder>(
|
|
350
|
+
m_devSettings, m_jsThread, nullptr /*scriptStore*/, std::move(preparedScriptStore));
|
|
345
351
|
break;
|
|
346
352
|
#else
|
|
347
353
|
if (m_devSettings->errorCallback)
|
|
@@ -543,6 +549,10 @@ std::vector<std::unique_ptr<NativeModule>> InstanceImpl::GetDefaultNativeModules
|
|
|
543
549
|
std::vector<std::unique_ptr<NativeModule>> modules;
|
|
544
550
|
auto transitionalProps{ReactPropertyBagHelper::CreatePropertyBag()};
|
|
545
551
|
|
|
552
|
+
// These modules are instantiated separately in MSRN (Universal Windows).
|
|
553
|
+
// When there are module name collisions, the last one registered is used.
|
|
554
|
+
// If this code is enabled, we will have unused module instances.
|
|
555
|
+
// Also, MSRN has a different property bag mechanism incompatible with this method's transitionalProps variable.
|
|
546
556
|
#if (defined(_MSC_VER) && !defined(WINRT))
|
|
547
557
|
modules.push_back(std::make_unique<CxxNativeModule>(
|
|
548
558
|
m_innerInstance,
|
|
@@ -551,7 +561,6 @@ std::vector<std::unique_ptr<NativeModule>> InstanceImpl::GetDefaultNativeModules
|
|
|
551
561
|
return Microsoft::React::CreateHttpModule(transitionalProps);
|
|
552
562
|
},
|
|
553
563
|
nativeQueue));
|
|
554
|
-
#endif
|
|
555
564
|
|
|
556
565
|
modules.push_back(std::make_unique<CxxNativeModule>(
|
|
557
566
|
m_innerInstance,
|
|
@@ -561,11 +570,18 @@ std::vector<std::unique_ptr<NativeModule>> InstanceImpl::GetDefaultNativeModules
|
|
|
561
570
|
},
|
|
562
571
|
nativeQueue));
|
|
563
572
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
573
|
+
modules.push_back(std::make_unique<CxxNativeModule>(
|
|
574
|
+
m_innerInstance,
|
|
575
|
+
Microsoft::React::GetBlobModuleName(),
|
|
576
|
+
[transitionalProps]() { return Microsoft::React::CreateBlobModule(transitionalProps); },
|
|
577
|
+
nativeQueue));
|
|
578
|
+
|
|
579
|
+
modules.push_back(std::make_unique<CxxNativeModule>(
|
|
580
|
+
m_innerInstance,
|
|
581
|
+
Microsoft::React::GetFileReaderModuleName(),
|
|
582
|
+
[transitionalProps]() { return Microsoft::React::CreateFileReaderModule(transitionalProps); },
|
|
583
|
+
nativeQueue));
|
|
584
|
+
|
|
569
585
|
modules.push_back(std::make_unique<CxxNativeModule>(
|
|
570
586
|
m_innerInstance,
|
|
571
587
|
"Timing",
|
|
@@ -620,26 +636,6 @@ std::vector<std::unique_ptr<NativeModule>> InstanceImpl::GetDefaultNativeModules
|
|
|
620
636
|
[]() { return std::make_unique<StatusBarManagerModule>(); },
|
|
621
637
|
nativeQueue));
|
|
622
638
|
|
|
623
|
-
// These modules are instantiated separately in MSRN (Universal Windows).
|
|
624
|
-
// When there are module name collisions, the last one registered is used.
|
|
625
|
-
// If this code is enabled, we will have unused module instances.
|
|
626
|
-
// Also, MSRN has a different property bag mechanism incompatible with this method's transitionalProps variable.
|
|
627
|
-
#if (defined(_MSC_VER) && !defined(WINRT))
|
|
628
|
-
if (Microsoft::React::GetRuntimeOptionBool("Blob.EnableModule")) {
|
|
629
|
-
modules.push_back(std::make_unique<CxxNativeModule>(
|
|
630
|
-
m_innerInstance,
|
|
631
|
-
Microsoft::React::GetBlobModuleName(),
|
|
632
|
-
[transitionalProps]() { return Microsoft::React::CreateBlobModule(transitionalProps); },
|
|
633
|
-
nativeQueue));
|
|
634
|
-
|
|
635
|
-
modules.push_back(std::make_unique<CxxNativeModule>(
|
|
636
|
-
m_innerInstance,
|
|
637
|
-
Microsoft::React::GetFileReaderModuleName(),
|
|
638
|
-
[transitionalProps]() { return Microsoft::React::CreateFileReaderModule(transitionalProps); },
|
|
639
|
-
nativeQueue));
|
|
640
|
-
}
|
|
641
|
-
#endif
|
|
642
|
-
|
|
643
639
|
return modules;
|
|
644
640
|
}
|
|
645
641
|
|