mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-03-30 23:22:41 +08:00
Introduce non-copyable JSBigString for managing large strings efficiently
Reviewed By: astreet Differential Revision: D3234836 fbshipit-source-id: 2b95b585dc1215988b88cf0d609c778a95b362a1
This commit is contained in:
committed by
Facebook Github Bot 8
parent
f433ed716c
commit
9e9dfd2ac9
@@ -37,22 +37,26 @@ Bridge::~Bridge() {
|
||||
CHECK(*m_destroyed) << "Bridge::destroy() must be called before deallocating the Bridge!";
|
||||
}
|
||||
|
||||
void Bridge::loadApplicationScript(const std::string& script, const std::string& sourceURL) {
|
||||
void Bridge::loadApplicationScript(std::unique_ptr<const JSBigString> script,
|
||||
std::string sourceURL) {
|
||||
// TODO(t11144533): Add assert that we are on the correct thread
|
||||
m_mainExecutor->loadApplicationScript(script, sourceURL);
|
||||
m_mainExecutor->loadApplicationScript(std::move(script), std::move(sourceURL));
|
||||
}
|
||||
|
||||
void Bridge::loadApplicationUnbundle(
|
||||
std::unique_ptr<JSModulesUnbundle> unbundle,
|
||||
const std::string& startupScript,
|
||||
const std::string& startupScriptSourceURL) {
|
||||
std::unique_ptr<const JSBigString> startupScript,
|
||||
std::string startupScriptSourceURL) {
|
||||
runOnExecutorQueue(
|
||||
*m_mainExecutorToken,
|
||||
[unbundle=folly::makeMoveWrapper(std::move(unbundle)), startupScript, startupScriptSourceURL]
|
||||
[unbundle=folly::makeMoveWrapper(std::move(unbundle)),
|
||||
startupScript=folly::makeMoveWrapper(std::move(startupScript)),
|
||||
startupScriptSourceURL=std::move(startupScriptSourceURL)]
|
||||
(JSExecutor* executor) mutable {
|
||||
|
||||
executor->setJSModulesUnbundle(unbundle.move());
|
||||
executor->loadApplicationScript(startupScript, startupScriptSourceURL);
|
||||
executor->loadApplicationScript(std::move(*startupScript),
|
||||
std::move(startupScriptSourceURL));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -108,10 +112,14 @@ void Bridge::invokeCallback(ExecutorToken executorToken, const double callbackId
|
||||
});
|
||||
}
|
||||
|
||||
void Bridge::setGlobalVariable(const std::string& propName, const std::string& jsonValue) {
|
||||
runOnExecutorQueue(*m_mainExecutorToken, [=] (JSExecutor* executor) {
|
||||
executor->setGlobalVariable(propName, jsonValue);
|
||||
});
|
||||
void Bridge::setGlobalVariable(std::string propName,
|
||||
std::unique_ptr<const JSBigString> jsonValue) {
|
||||
runOnExecutorQueue(
|
||||
*m_mainExecutorToken,
|
||||
[propName=std::move(propName), jsonValue=folly::makeMoveWrapper(std::move(jsonValue))]
|
||||
(JSExecutor* executor) mutable {
|
||||
executor->setGlobalVariable(propName, jsonValue.move());
|
||||
});
|
||||
}
|
||||
|
||||
void* Bridge::getJavaScriptContext() {
|
||||
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
* contains code for all modules and a runtime that resolves and
|
||||
* executes modules.
|
||||
*/
|
||||
void loadApplicationScript(const std::string& script, const std::string& sourceURL);
|
||||
void loadApplicationScript(std::unique_ptr<const JSBigString> script, std::string sourceURL);
|
||||
|
||||
/**
|
||||
* An "unbundle" is a backend that stores and injects JavaScript modules as
|
||||
@@ -98,9 +98,9 @@ public:
|
||||
*/
|
||||
void loadApplicationUnbundle(
|
||||
std::unique_ptr<JSModulesUnbundle> unbundle,
|
||||
const std::string& startupCode,
|
||||
const std::string& sourceURL);
|
||||
void setGlobalVariable(const std::string& propName, const std::string& jsonValue);
|
||||
std::unique_ptr<const JSBigString> startupCode,
|
||||
std::string sourceURL);
|
||||
void setGlobalVariable(std::string propName, std::unique_ptr<const JSBigString> jsonValue);
|
||||
void* getJavaScriptContext();
|
||||
bool supportsProfiling();
|
||||
void startProfiler(const std::string& title);
|
||||
|
||||
@@ -29,14 +29,95 @@ public:
|
||||
virtual ~JSExecutorFactory() {};
|
||||
};
|
||||
|
||||
// JSExecutor functions sometimes take large strings, on the order of
|
||||
// megabytes. Copying these can be expensive. Introducing a
|
||||
// move-only, non-CopyConstructible type will let the compiler ensure
|
||||
// that no copies occur. folly::MoveWrapper should be used when a
|
||||
// large string needs to be curried into a std::function<>, which must
|
||||
// by CopyConstructible.
|
||||
|
||||
class JSBigString {
|
||||
public:
|
||||
JSBigString() = default;
|
||||
|
||||
// Not copyable
|
||||
JSBigString(const JSBigString&) = delete;
|
||||
JSBigString& operator=(const JSBigString&) = delete;
|
||||
|
||||
virtual ~JSBigString() {}
|
||||
|
||||
virtual bool isAscii() const = 0;
|
||||
virtual const char* c_str() const = 0;
|
||||
virtual size_t size() const = 0;
|
||||
};
|
||||
|
||||
// Concrete JSBigString implementation which holds a std::string
|
||||
// instance.
|
||||
class JSBigStdString : public JSBigString {
|
||||
public:
|
||||
JSBigStdString(std::string str, bool isAscii=false)
|
||||
: m_isAscii(isAscii)
|
||||
, m_str(std::move(str)) {}
|
||||
|
||||
bool isAscii() const override {
|
||||
return m_isAscii;
|
||||
}
|
||||
|
||||
const char* c_str() const override {
|
||||
return m_str.c_str();
|
||||
}
|
||||
|
||||
size_t size() const override {
|
||||
return m_str.size();
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_isAscii;
|
||||
std::string m_str;
|
||||
};
|
||||
|
||||
// Concrete JSBigString implementation which holds a heap-allocated
|
||||
// buffer, and provides an accessor for writing to it. This can be
|
||||
// used to construct a JSBigString in place, such as by reading from a
|
||||
// file.
|
||||
class JSBigBufferString : public facebook::react::JSBigString {
|
||||
public:
|
||||
JSBigBufferString(size_t size)
|
||||
: m_data(new char[size])
|
||||
, m_size(size) {}
|
||||
|
||||
~JSBigBufferString() {
|
||||
delete[] m_data;
|
||||
}
|
||||
|
||||
bool isAscii() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* c_str() const override {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
size_t size() const override {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
char* data() {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
private:
|
||||
char* m_data;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
class JSExecutor {
|
||||
public:
|
||||
/**
|
||||
* Execute an application script bundle in the JS context.
|
||||
*/
|
||||
virtual void loadApplicationScript(
|
||||
const std::string& script,
|
||||
const std::string& sourceURL) = 0;
|
||||
virtual void loadApplicationScript(std::unique_ptr<const JSBigString> script,
|
||||
std::string sourceURL) = 0;
|
||||
|
||||
/**
|
||||
* Add an application "unbundle" file
|
||||
@@ -58,9 +139,8 @@ public:
|
||||
*/
|
||||
virtual void invokeCallback(const double callbackId, const folly::dynamic& arguments) = 0;
|
||||
|
||||
virtual void setGlobalVariable(
|
||||
const std::string& propName,
|
||||
const std::string& jsonValue) = 0;
|
||||
virtual void setGlobalVariable(std::string propName,
|
||||
std::unique_ptr<const JSBigString> jsonValue) = 0;
|
||||
virtual void* getJavaScriptContext() {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
@@ -90,22 +90,22 @@ void Instance::initializeBridge(
|
||||
SystraceSection t("setGlobalVariable");
|
||||
setGlobalVariable(
|
||||
"__fbBatchedBridgeConfig",
|
||||
folly::toJson(config));
|
||||
folly::make_unique<JSBigStdString>(folly::toJson(config)));
|
||||
}
|
||||
|
||||
void Instance::loadScriptFromString(const std::string& string,
|
||||
const std::string& sourceURL) {
|
||||
void Instance::loadScriptFromString(std::unique_ptr<const JSBigString> string,
|
||||
std::string sourceURL) {
|
||||
callback_->incrementPendingJSCalls();
|
||||
SystraceSection s("reactbridge_xplat_loadScriptFromString",
|
||||
"sourceURL", sourceURL);
|
||||
// TODO mhorowitz: ReactMarker around loadApplicationScript
|
||||
bridge_->loadApplicationScript(string, sourceURL);
|
||||
bridge_->loadApplicationScript(std::move(string), std::move(sourceURL));
|
||||
}
|
||||
|
||||
void Instance::loadScriptFromFile(const std::string& filename,
|
||||
const std::string& sourceURL) {
|
||||
// TODO mhorowitz: ReactMarker around file read
|
||||
std::string script;
|
||||
std::unique_ptr<JSBigBufferString> buf;
|
||||
{
|
||||
SystraceSection s("reactbridge_xplat_loadScriptFromFile",
|
||||
"fileName", filename);
|
||||
@@ -115,23 +115,22 @@ void Instance::loadScriptFromFile(const std::string& filename,
|
||||
LOG(ERROR) << "Unable to load script from file" << filename;
|
||||
} else {
|
||||
jsfile.seekg(0, std::ios::end);
|
||||
script.reserve(jsfile.tellg());
|
||||
buf.reset(new JSBigBufferString(jsfile.tellg()));
|
||||
jsfile.seekg(0, std::ios::beg);
|
||||
script.assign(
|
||||
std::istreambuf_iterator<char>(jsfile),
|
||||
std::istreambuf_iterator<char>());
|
||||
jsfile.read(buf->data(), buf->size());
|
||||
}
|
||||
}
|
||||
|
||||
loadScriptFromString(script, sourceURL);
|
||||
loadScriptFromString(std::move(buf), sourceURL);
|
||||
}
|
||||
|
||||
void Instance::loadUnbundle(std::unique_ptr<JSModulesUnbundle> unbundle,
|
||||
const std::string& startupScript,
|
||||
const std::string& startupScriptSourceURL) {
|
||||
std::unique_ptr<const JSBigString> startupScript,
|
||||
std::string startupScriptSourceURL) {
|
||||
callback_->incrementPendingJSCalls();
|
||||
SystraceSection s("reactbridge_xplat_setJSModulesUnbundle");
|
||||
bridge_->loadApplicationUnbundle(std::move(unbundle), startupScript, startupScriptSourceURL);
|
||||
bridge_->loadApplicationUnbundle(std::move(unbundle), std::move(startupScript),
|
||||
std::move(startupScriptSourceURL));
|
||||
}
|
||||
|
||||
bool Instance::supportsProfiling() {
|
||||
@@ -146,9 +145,9 @@ void Instance::stopProfiler(const std::string& title, const std::string& filenam
|
||||
return bridge_->stopProfiler(title, filename);
|
||||
}
|
||||
|
||||
void Instance::setGlobalVariable(const std::string& propName,
|
||||
const std::string& jsonValue) {
|
||||
bridge_->setGlobalVariable(propName, jsonValue);
|
||||
void Instance::setGlobalVariable(std::string propName,
|
||||
std::unique_ptr<const JSBigString> jsonValue) {
|
||||
bridge_->setGlobalVariable(std::move(propName), std::move(jsonValue));
|
||||
}
|
||||
|
||||
void Instance::callJSFunction(ExecutorToken token, const std::string& module, const std::string& method,
|
||||
|
||||
@@ -33,16 +33,16 @@ class Instance {
|
||||
std::shared_ptr<MessageQueueThread> jsQueue,
|
||||
std::unique_ptr<MessageQueueThread> nativeQueue,
|
||||
std::shared_ptr<ModuleRegistry> moduleRegistry);
|
||||
void loadScriptFromString(const std::string& string, const std::string& sourceURL);
|
||||
void loadScriptFromString(std::unique_ptr<const JSBigString> string, std::string sourceURL);
|
||||
void loadScriptFromFile(const std::string& filename, const std::string& sourceURL);
|
||||
void loadUnbundle(
|
||||
std::unique_ptr<JSModulesUnbundle> unbundle,
|
||||
const std::string& startupScript,
|
||||
const std::string& startupScriptSourceURL);
|
||||
std::unique_ptr<const JSBigString> startupScript,
|
||||
std::string startupScriptSourceURL);
|
||||
bool supportsProfiling();
|
||||
void startProfiler(const std::string& title);
|
||||
void stopProfiler(const std::string& title, const std::string& filename);
|
||||
void setGlobalVariable(const std::string& propName, const std::string& jsonValue);
|
||||
void setGlobalVariable(std::string propName, std::unique_ptr<const JSBigString> jsonValue);
|
||||
void callJSFunction(ExecutorToken token, const std::string& module, const std::string& method,
|
||||
folly::dynamic&& params, const std::string& tracingName);
|
||||
void callJSCallback(ExecutorToken token, uint64_t callbackId, folly::dynamic&& params);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
#include <glog/logging.h>
|
||||
#include <folly/json.h>
|
||||
#include <folly/Memory.h>
|
||||
#include <folly/String.h>
|
||||
#include <folly/Conv.h>
|
||||
#include <sys/time.h>
|
||||
@@ -125,8 +126,8 @@ JSCExecutor::JSCExecutor(
|
||||
std::shared_ptr<MessageQueueThread> messageQueueThread,
|
||||
int workerId,
|
||||
JSCExecutor *owner,
|
||||
const std::string& script,
|
||||
const std::unordered_map<std::string, std::string>& globalObjAsJSON,
|
||||
std::string scriptURL,
|
||||
std::unordered_map<std::string, std::string> globalObjAsJSON,
|
||||
const folly::dynamic& jscConfig) :
|
||||
m_bridge(bridge),
|
||||
m_workerId(workerId),
|
||||
@@ -136,29 +137,32 @@ JSCExecutor::JSCExecutor(
|
||||
m_jscConfig(jscConfig) {
|
||||
// We post initOnJSVMThread here so that the owner doesn't have to wait for
|
||||
// initialization on its own thread
|
||||
m_messageQueueThread->runOnQueue([this, script, globalObjAsJSON] () {
|
||||
m_messageQueueThread->runOnQueue([this, scriptURL,
|
||||
globalObjAsJSON=std::move(globalObjAsJSON)] () {
|
||||
initOnJSVMThread();
|
||||
|
||||
installNativeHook<&JSCExecutor::nativePostMessage>("postMessage");
|
||||
|
||||
for (auto& it : globalObjAsJSON) {
|
||||
setGlobalVariable(it.first, it.second);
|
||||
setGlobalVariable(std::move(it.first),
|
||||
folly::make_unique<JSBigStdString>(std::move(it.second)));
|
||||
}
|
||||
|
||||
// Try to load the script from the network if script is a URL
|
||||
// NB: For security, this will only work in debug builds
|
||||
std::string scriptSrc;
|
||||
if (script.find("http://") == 0 || script.find("https://") == 0) {
|
||||
std::unique_ptr<const JSBigString> script;
|
||||
if (scriptURL.find("http://") == 0 || scriptURL.find("https://") == 0) {
|
||||
std::stringstream outfileBuilder;
|
||||
outfileBuilder << m_deviceCacheDir << "/workerScript" << m_workerId << ".js";
|
||||
scriptSrc = WebWorkerUtil::loadScriptFromNetworkSync(script, outfileBuilder.str());
|
||||
script = folly::make_unique<JSBigStdString>(
|
||||
WebWorkerUtil::loadScriptFromNetworkSync(scriptURL, outfileBuilder.str()));
|
||||
} else {
|
||||
// TODO(9604438): Protect against script does not exist
|
||||
scriptSrc = WebWorkerUtil::loadScriptFromAssets(script);
|
||||
script = WebWorkerUtil::loadScriptFromAssets(scriptURL);
|
||||
}
|
||||
|
||||
// TODO(9994180): Throw on error
|
||||
loadApplicationScript(scriptSrc, script);
|
||||
loadApplicationScript(std::move(script), std::move(scriptURL));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -236,9 +240,7 @@ void JSCExecutor::terminateOnJSVMThread() {
|
||||
m_context = nullptr;
|
||||
}
|
||||
|
||||
void JSCExecutor::loadApplicationScript(
|
||||
const std::string& script,
|
||||
const std::string& sourceURL) {
|
||||
void JSCExecutor::loadApplicationScript(std::unique_ptr<const JSBigString> script, std::string sourceURL) {
|
||||
SystraceSection s("JSCExecutor::loadApplicationScript",
|
||||
"sourceURL", sourceURL);
|
||||
|
||||
@@ -249,7 +251,7 @@ void JSCExecutor::loadApplicationScript(
|
||||
#endif
|
||||
|
||||
ReactMarker::logMarker("loadApplicationScript_startStringConvert");
|
||||
String jsScript = String::createExpectingAscii(script);
|
||||
String jsScript = jsStringFromBigString(*script);
|
||||
ReactMarker::logMarker("loadApplicationScript_endStringConvert");
|
||||
|
||||
#ifdef WITH_FBSYSTRACE
|
||||
@@ -296,13 +298,14 @@ void JSCExecutor::invokeCallback(const double callbackId, const folly::dynamic&
|
||||
m_bridge->callNativeModules(*this, calls, true);
|
||||
}
|
||||
|
||||
void JSCExecutor::setGlobalVariable(const std::string& propName, const std::string& jsonValue) {
|
||||
// TODO mhorowitz: systrace this.
|
||||
void JSCExecutor::setGlobalVariable(std::string propName, std::unique_ptr<const JSBigString> jsonValue) {
|
||||
SystraceSection s("JSCExecutor.setGlobalVariable",
|
||||
"propName", propName);
|
||||
|
||||
auto globalObject = JSContextGetGlobalObject(m_context);
|
||||
String jsPropertyName(propName.c_str());
|
||||
|
||||
String jsValueJSON(jsonValue.c_str());
|
||||
String jsValueJSON = jsStringFromBigString(*jsonValue);
|
||||
auto valueToInject = JSValueMakeFromJSONString(m_context, jsValueJSON);
|
||||
|
||||
JSObjectSetProperty(m_context, globalObject, jsPropertyName, valueToInject, 0, NULL);
|
||||
@@ -364,7 +367,7 @@ void JSCExecutor::loadModule(uint32_t moduleId) {
|
||||
}
|
||||
|
||||
int JSCExecutor::addWebWorker(
|
||||
const std::string& script,
|
||||
std::string scriptURL,
|
||||
JSValueRef workerRef,
|
||||
JSValueRef globalObjRef) {
|
||||
static std::atomic_int nextWorkerId(1);
|
||||
@@ -378,8 +381,8 @@ int JSCExecutor::addWebWorker(
|
||||
std::shared_ptr<MessageQueueThread> workerMQT =
|
||||
WebWorkerUtil::createWebWorkerThread(workerId, m_messageQueueThread.get());
|
||||
std::unique_ptr<JSCExecutor> worker;
|
||||
workerMQT->runOnQueueSync([this, &worker, &workerMQT, &script, &globalObj, workerId, &workerJscConfig] () {
|
||||
worker.reset(new JSCExecutor(m_bridge, workerMQT, workerId, this, script,
|
||||
workerMQT->runOnQueueSync([this, &worker, &workerMQT, &scriptURL, &globalObj, workerId, &workerJscConfig] () {
|
||||
worker.reset(new JSCExecutor(m_bridge, workerMQT, workerId, this, scriptURL,
|
||||
globalObj.toJSONMap(), workerJscConfig));
|
||||
});
|
||||
|
||||
|
||||
@@ -55,8 +55,8 @@ public:
|
||||
~JSCExecutor() override;
|
||||
|
||||
virtual void loadApplicationScript(
|
||||
const std::string& script,
|
||||
const std::string& sourceURL) override;
|
||||
std::unique_ptr<const JSBigString> script,
|
||||
std::string sourceURL) override;
|
||||
virtual void setJSModulesUnbundle(
|
||||
std::unique_ptr<JSModulesUnbundle> unbundle) override;
|
||||
virtual void callFunction(
|
||||
@@ -67,8 +67,8 @@ public:
|
||||
const double callbackId,
|
||||
const folly::dynamic& arguments) override;
|
||||
virtual void setGlobalVariable(
|
||||
const std::string& propName,
|
||||
const std::string& jsonValue) override;
|
||||
std::string propName,
|
||||
std::unique_ptr<const JSBigString> jsonValue) override;
|
||||
virtual void* getJavaScriptContext() override;
|
||||
virtual bool supportsProfiling() override;
|
||||
virtual void startProfiler(const std::string &titleString) override;
|
||||
@@ -97,8 +97,8 @@ private:
|
||||
std::shared_ptr<MessageQueueThread> messageQueueThread,
|
||||
int workerId,
|
||||
JSCExecutor *owner,
|
||||
const std::string& script,
|
||||
const std::unordered_map<std::string, std::string>& globalObjAsJSON,
|
||||
std::string scriptURL,
|
||||
std::unordered_map<std::string, std::string> globalObjAsJSON,
|
||||
const folly::dynamic& jscConfig);
|
||||
|
||||
void initOnJSVMThread();
|
||||
@@ -107,7 +107,7 @@ private:
|
||||
void flushQueueImmediate(std::string queueJSON);
|
||||
void loadModule(uint32_t moduleId);
|
||||
|
||||
int addWebWorker(const std::string& script, JSValueRef workerRef, JSValueRef globalObjRef);
|
||||
int addWebWorker(std::string scriptURL, JSValueRef workerRef, JSValueRef globalObjRef);
|
||||
void postMessageToOwnedWebWorker(int worker, JSValueRef message);
|
||||
void postMessageToOwner(JSValueRef result);
|
||||
void receiveMessageFromOwnedWebWorker(int workerId, const std::string& message);
|
||||
|
||||
@@ -32,6 +32,14 @@ JSValueRef makeJSCException(
|
||||
return JSValueToObject(ctx, exceptionString, NULL);
|
||||
}
|
||||
|
||||
String jsStringFromBigString(const JSBigString& bigstr) {
|
||||
if (bigstr.isAscii()) {
|
||||
return String::createExpectingAscii(bigstr.c_str(), bigstr.size());
|
||||
} else {
|
||||
return String(bigstr.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
JSValueRef evaluateScript(JSContextRef context, JSStringRef script, JSStringRef source) {
|
||||
JSValueRef exn, result;
|
||||
result = JSEvaluateScript(context, script, NULL, source, 0, &exn);
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Executor.h"
|
||||
#include "Value.h"
|
||||
|
||||
#include <JavaScriptCore/JSContextRef.h>
|
||||
#include <JavaScriptCore/JSObjectRef.h>
|
||||
#include <JavaScriptCore/JSValueRef.h>
|
||||
@@ -40,6 +43,8 @@ JSValueRef makeJSCException(
|
||||
JSContextRef ctx,
|
||||
const char* exception_text);
|
||||
|
||||
String jsStringFromBigString(const JSBigString& bigstr);
|
||||
|
||||
JSValueRef evaluateScript(
|
||||
JSContextRef ctx,
|
||||
JSStringRef script,
|
||||
|
||||
@@ -89,8 +89,8 @@ void JSCWebWorker::initJSVMAndLoadScript() {
|
||||
s_globalContextRefToJSCWebWorker[context_] = this;
|
||||
|
||||
// TODO(9604438): Protect against script does not exist
|
||||
std::string script = WebWorkerUtil::loadScriptFromAssets(scriptName_);
|
||||
evaluateScript(context_, String(script.c_str()), String(scriptName_.c_str()));
|
||||
std::unique_ptr<const JSBigString> script = WebWorkerUtil::loadScriptFromAssets(scriptName_);
|
||||
evaluateScript(context_, jsStringFromBigString(*script), String(scriptName_.c_str()));
|
||||
|
||||
installGlobalFunction(context_, "postMessage", nativePostMessage);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <JavaScriptCore/JSContextRef.h>
|
||||
|
||||
#include "Executor.h"
|
||||
#include "MessageQueueThread.h"
|
||||
|
||||
namespace facebook {
|
||||
@@ -22,7 +23,7 @@ namespace WebWorkerUtil {
|
||||
using WebWorkerQueueFactory = std::function<std::unique_ptr<MessageQueueThread>(int id, MessageQueueThread* ownerMessageQueue)>;
|
||||
extern WebWorkerQueueFactory createWebWorkerThread;
|
||||
|
||||
using LoadScriptFromAssets = std::function<std::string(const std::string& assetName)>;
|
||||
using LoadScriptFromAssets = std::function<std::unique_ptr<const JSBigString>(const std::string& assetName)>;
|
||||
extern LoadScriptFromAssets loadScriptFromAssets;
|
||||
|
||||
using LoadScriptFromNetworkSync = std::function<std::string(const std::string& url, const std::string& tempfileName)>;
|
||||
|
||||
@@ -75,15 +75,19 @@ public:
|
||||
return JSStringIsEqualToUTF8CString(m_string, utf8);
|
||||
}
|
||||
|
||||
static String createExpectingAscii(std::string const &utf8) {
|
||||
static String createExpectingAscii(const char* utf8, size_t len) {
|
||||
#if WITH_FBJSCEXTENSIONS
|
||||
return String(
|
||||
JSStringCreateWithUTF8CStringExpectAscii(utf8.c_str(), utf8.size()), true);
|
||||
JSStringCreateWithUTF8CStringExpectAscii(utf8, len), true);
|
||||
#else
|
||||
return String(JSStringCreateWithUTF8CString(utf8.c_str()), true);
|
||||
return String(JSStringCreateWithUTF8CString(utf8), true);
|
||||
#endif
|
||||
}
|
||||
|
||||
static String createExpectingAscii(std::string const &utf8) {
|
||||
return String::createExpectingAscii(utf8.c_str(), utf8.size());
|
||||
}
|
||||
|
||||
static String ref(JSStringRef string) {
|
||||
return String(string, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user