Reverted commit D3207541
Reviewed By: michalgr Differential Revision: D3207541 fbshipit-source-id: 36366188b7cb74c51d4aa974abd4a648498bcf78
This commit is contained in:
parent
6565edc9ed
commit
80c23ae324
|
@ -412,12 +412,9 @@ import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recreateReactContextInBackgroundFromBundleFile() {
|
private void recreateReactContextInBackgroundFromBundleFile() {
|
||||||
boolean useLazyBundle = mJSCConfig.getConfigMap().hasKey("useLazyBundle") ?
|
|
||||||
mJSCConfig.getConfigMap().getBoolean("useLazyBundle") : false;
|
|
||||||
|
|
||||||
recreateReactContextInBackground(
|
recreateReactContextInBackground(
|
||||||
new JSCJavaScriptExecutor.Factory(mJSCConfig.getConfigMap()),
|
new JSCJavaScriptExecutor.Factory(mJSCConfig.getConfigMap()),
|
||||||
JSBundleLoader.createFileLoader(mApplicationContext, mJSBundleFile, useLazyBundle));
|
JSBundleLoader.createFileLoader(mApplicationContext, mJSBundleFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -161,7 +161,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||||
MessageQueueThread moduleQueue,
|
MessageQueueThread moduleQueue,
|
||||||
ModuleRegistryHolder registryHolder);
|
ModuleRegistryHolder registryHolder);
|
||||||
|
|
||||||
/* package */ native void loadScriptFromAssets(AssetManager assetManager, String assetURL, boolean useLazyBundle);
|
/* package */ native void loadScriptFromAssets(AssetManager assetManager, String assetURL);
|
||||||
/* package */ native void loadScriptFromFile(String fileName, String sourceURL);
|
/* package */ native void loadScriptFromFile(String fileName, String sourceURL);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -28,18 +28,11 @@ public abstract class JSBundleLoader {
|
||||||
public static JSBundleLoader createFileLoader(
|
public static JSBundleLoader createFileLoader(
|
||||||
final Context context,
|
final Context context,
|
||||||
final String fileName) {
|
final String fileName) {
|
||||||
return createFileLoader(context, fileName, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JSBundleLoader createFileLoader(
|
|
||||||
final Context context,
|
|
||||||
final String fileName,
|
|
||||||
final boolean useLazyBundle) {
|
|
||||||
return new JSBundleLoader() {
|
return new JSBundleLoader() {
|
||||||
@Override
|
@Override
|
||||||
public void loadScript(CatalystInstanceImpl instance) {
|
public void loadScript(CatalystInstanceImpl instance) {
|
||||||
if (fileName.startsWith("assets://")) {
|
if (fileName.startsWith("assets://")) {
|
||||||
instance.loadScriptFromAssets(context.getAssets(), fileName, useLazyBundle);
|
instance.loadScriptFromAssets(context.getAssets(), fileName);
|
||||||
} else {
|
} else {
|
||||||
instance.loadScriptFromFile(fileName, fileName);
|
instance.loadScriptFromFile(fileName, fileName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,6 @@
|
||||||
#include <jni/Countable.h>
|
#include <jni/Countable.h>
|
||||||
#include <jni/LocalReference.h>
|
#include <jni/LocalReference.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <cxxreact/Instance.h>
|
#include <cxxreact/Instance.h>
|
||||||
#include <cxxreact/MethodCall.h>
|
#include <cxxreact/MethodCall.h>
|
||||||
#include <cxxreact/ModuleRegistry.h>
|
#include <cxxreact/ModuleRegistry.h>
|
||||||
|
@ -25,7 +23,6 @@
|
||||||
#include "ModuleRegistryHolder.h"
|
#include "ModuleRegistryHolder.h"
|
||||||
#include "NativeArray.h"
|
#include "NativeArray.h"
|
||||||
#include "JNativeRunnable.h"
|
#include "JNativeRunnable.h"
|
||||||
#include "OnLoad.h"
|
|
||||||
|
|
||||||
using namespace facebook::jni;
|
using namespace facebook::jni;
|
||||||
|
|
||||||
|
@ -101,7 +98,7 @@ void CatalystInstanceImpl::registerNatives() {
|
||||||
makeNativeMethod("initHybrid", CatalystInstanceImpl::initHybrid),
|
makeNativeMethod("initHybrid", CatalystInstanceImpl::initHybrid),
|
||||||
makeNativeMethod("initializeBridge", CatalystInstanceImpl::initializeBridge),
|
makeNativeMethod("initializeBridge", CatalystInstanceImpl::initializeBridge),
|
||||||
makeNativeMethod("loadScriptFromAssets",
|
makeNativeMethod("loadScriptFromAssets",
|
||||||
"(Landroid/content/res/AssetManager;Ljava/lang/String;Z)V",
|
"(Landroid/content/res/AssetManager;Ljava/lang/String;)V",
|
||||||
CatalystInstanceImpl::loadScriptFromAssets),
|
CatalystInstanceImpl::loadScriptFromAssets),
|
||||||
makeNativeMethod("loadScriptFromFile", CatalystInstanceImpl::loadScriptFromFile),
|
makeNativeMethod("loadScriptFromFile", CatalystInstanceImpl::loadScriptFromFile),
|
||||||
makeNativeMethod("callJSFunction", CatalystInstanceImpl::callJSFunction),
|
makeNativeMethod("callJSFunction", CatalystInstanceImpl::callJSFunction),
|
||||||
|
@ -152,132 +149,20 @@ void CatalystInstanceImpl::initializeBridge(
|
||||||
mrh->getModuleRegistry());
|
mrh->getModuleRegistry());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_FBJSCEXTENSIONS
|
|
||||||
static std::unique_ptr<const JSBigString> loadScriptFromCache(
|
|
||||||
AAssetManager* manager,
|
|
||||||
std::string& sourceURL) {
|
|
||||||
|
|
||||||
// 20-byte sha1 as hex
|
|
||||||
static const size_t HASH_STR_SIZE = 40;
|
|
||||||
|
|
||||||
// load bundle hash from the metadata file in the APK
|
|
||||||
auto hash = react::loadScriptFromAssets(manager, sourceURL + ".meta");
|
|
||||||
auto cacheDir = getApplicationCacheDir() + "/rn-bundle";
|
|
||||||
auto encoding = static_cast<JSBigMmapString::Encoding>(hash->c_str()[20]);
|
|
||||||
|
|
||||||
if (mkdir(cacheDir.c_str(), 0755) == -1 && errno != EEXIST) {
|
|
||||||
throw std::runtime_error("Can't create cache directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (encoding != JSBigMmapString::Encoding::Ascii) {
|
|
||||||
throw std::runtime_error("Can't use mmap fastpath for non-ascii bundles");
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert hash to string
|
|
||||||
char hashStr[HASH_STR_SIZE + 1];
|
|
||||||
for (size_t i = 0; i < HASH_STR_SIZE; i += 2) {
|
|
||||||
snprintf(hashStr + i, 3, "%02hhx", hash->c_str()[i / 2] & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
// the name of the cached bundle file should be the hash
|
|
||||||
std::string cachePath = cacheDir + "/" + hashStr;
|
|
||||||
FILE *cache = fopen(cachePath.c_str(), "r");
|
|
||||||
SCOPE_EXIT { if (cache) fclose(cache); };
|
|
||||||
|
|
||||||
size_t size = 0;
|
|
||||||
if (cache == NULL) {
|
|
||||||
// delete old bundle, if there was one.
|
|
||||||
std::string metaPath = cacheDir + "/meta";
|
|
||||||
if (auto meta = fopen(metaPath.c_str(), "r")) {
|
|
||||||
char oldBundleHash[HASH_STR_SIZE + 1];
|
|
||||||
if (fread(oldBundleHash, HASH_STR_SIZE, 1, meta) == HASH_STR_SIZE) {
|
|
||||||
remove((cacheDir + "/" + oldBundleHash).c_str());
|
|
||||||
remove(metaPath.c_str());
|
|
||||||
}
|
|
||||||
fclose(meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
// load script from the APK and write to temporary file
|
|
||||||
auto script = react::loadScriptFromAssets(manager, sourceURL);
|
|
||||||
auto tmpPath = cachePath + "_";
|
|
||||||
cache = fopen(tmpPath.c_str(), "w");
|
|
||||||
if (!cache) {
|
|
||||||
throw std::runtime_error("Can't open cache, errno: " + errno);
|
|
||||||
}
|
|
||||||
if (fwrite(script->c_str(), 1, script->size(), cache) != size) {
|
|
||||||
remove(tmpPath.c_str());
|
|
||||||
throw std::runtime_error("Failed to unpack bundle");
|
|
||||||
}
|
|
||||||
|
|
||||||
// force data to be written to disk
|
|
||||||
fsync(fileno(cache));
|
|
||||||
fclose(cache);
|
|
||||||
|
|
||||||
// move script to final path - atomic operation
|
|
||||||
if (rename(tmpPath.c_str(), cachePath.c_str())) {
|
|
||||||
throw std::runtime_error("Failed to update cache, errno: " + errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
// store the bundle hash in a metadata file
|
|
||||||
auto meta = fopen(metaPath.c_str(), "w");
|
|
||||||
if (!meta) {
|
|
||||||
throw std::runtime_error("Failed to open metadata file to store bundle hash");
|
|
||||||
}
|
|
||||||
if (fwrite(hashStr, HASH_STR_SIZE, 1, meta) != HASH_STR_SIZE) {
|
|
||||||
throw std::runtime_error("Failed to write bundle hash to metadata file");
|
|
||||||
}
|
|
||||||
fsync(fileno(meta));
|
|
||||||
fclose(meta);
|
|
||||||
|
|
||||||
// return the final written cache
|
|
||||||
cache = fopen(cachePath.c_str(), "r");
|
|
||||||
if (!cache) {
|
|
||||||
throw std::runtime_error("Cache has been cleared");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
struct stat fileInfo = {0};
|
|
||||||
if (fstat(fileno(cache), &fileInfo)) {
|
|
||||||
throw std::runtime_error("Failed to get cache stats, errno: " + errno);
|
|
||||||
}
|
|
||||||
size = fileInfo.st_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return folly::make_unique<const JSBigMmapString>(
|
|
||||||
dup(fileno(cache)),
|
|
||||||
size,
|
|
||||||
reinterpret_cast<const uint8_t*>(hash->c_str()),
|
|
||||||
encoding);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void CatalystInstanceImpl::loadScriptFromAssets(jobject assetManager,
|
void CatalystInstanceImpl::loadScriptFromAssets(jobject assetManager,
|
||||||
const std::string& assetURL,
|
const std::string& assetURL) {
|
||||||
bool useLazyBundle) {
|
|
||||||
const int kAssetsLength = 9; // strlen("assets://");
|
const int kAssetsLength = 9; // strlen("assets://");
|
||||||
auto sourceURL = assetURL.substr(kAssetsLength);
|
auto sourceURL = assetURL.substr(kAssetsLength);
|
||||||
auto manager = react::extractAssetManager(assetManager);
|
|
||||||
|
|
||||||
|
auto manager = react::extractAssetManager(assetManager);
|
||||||
|
auto script = react::loadScriptFromAssets(manager, sourceURL);
|
||||||
if (JniJSModulesUnbundle::isUnbundle(manager, sourceURL)) {
|
if (JniJSModulesUnbundle::isUnbundle(manager, sourceURL)) {
|
||||||
auto script = react::loadScriptFromAssets(manager, sourceURL);
|
|
||||||
instance_->loadUnbundle(
|
instance_->loadUnbundle(
|
||||||
folly::make_unique<JniJSModulesUnbundle>(manager, sourceURL),
|
folly::make_unique<JniJSModulesUnbundle>(manager, sourceURL),
|
||||||
std::move(script),
|
std::move(script),
|
||||||
sourceURL);
|
sourceURL);
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
#ifdef WITH_FBJSCEXTENSIONS
|
instance_->loadScriptFromString(std::move(script), std::move(sourceURL));
|
||||||
if (useLazyBundle) {
|
|
||||||
try {
|
|
||||||
auto script = loadScriptFromCache(manager, sourceURL);
|
|
||||||
instance_->loadScriptFromString(std::move(script), sourceURL);
|
|
||||||
return;
|
|
||||||
} catch (...) {
|
|
||||||
LOG(WARNING) << "Failed to load bundle as Source Code";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
auto script = react::loadScriptFromAssets(manager, sourceURL);
|
|
||||||
instance_->loadScriptFromString(std::move(script), sourceURL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ class CatalystInstanceImpl : public jni::HybridClass<CatalystInstanceImpl> {
|
||||||
jni::alias_ref<JavaMessageQueueThread::javaobject> jsQueue,
|
jni::alias_ref<JavaMessageQueueThread::javaobject> jsQueue,
|
||||||
jni::alias_ref<JavaMessageQueueThread::javaobject> moduleQueue,
|
jni::alias_ref<JavaMessageQueueThread::javaobject> moduleQueue,
|
||||||
ModuleRegistryHolder* mrh);
|
ModuleRegistryHolder* mrh);
|
||||||
void loadScriptFromAssets(jobject assetManager, const std::string& assetURL, bool useLazyBundle);
|
void loadScriptFromAssets(jobject assetManager, const std::string& assetURL);
|
||||||
void loadScriptFromFile(jni::alias_ref<jstring> fileName, const std::string& sourceURL);
|
void loadScriptFromFile(jni::alias_ref<jstring> fileName, const std::string& sourceURL);
|
||||||
void callJSFunction(JExecutorToken* token, std::string module, std::string method, NativeArray* arguments);
|
void callJSFunction(JExecutorToken* token, std::string module, std::string method, NativeArray* arguments);
|
||||||
void callJSCallback(JExecutorToken* token, jint callbackId, NativeArray* arguments);
|
void callJSCallback(JExecutorToken* token, jint callbackId, NativeArray* arguments);
|
||||||
|
|
|
@ -51,6 +51,10 @@ static std::string getApplicationDir(const char* methodName) {
|
||||||
return getAbsolutePathMethod(dirObj)->toStdString();
|
return getAbsolutePathMethod(dirObj)->toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string getApplicationCacheDir() {
|
||||||
|
return getApplicationDir("getCacheDir");
|
||||||
|
}
|
||||||
|
|
||||||
static std::string getApplicationPersistentDir() {
|
static std::string getApplicationPersistentDir() {
|
||||||
return getApplicationDir("getFilesDir");
|
return getApplicationDir("getFilesDir");
|
||||||
}
|
}
|
||||||
|
@ -158,10 +162,6 @@ class JReactMarker : public JavaClass<JReactMarker> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getApplicationCacheDir() {
|
|
||||||
return getApplicationDir("getCacheDir");
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||||
return initialize(vm, [] {
|
return initialize(vm, [] {
|
||||||
// Inject some behavior into react/
|
// Inject some behavior into react/
|
||||||
|
|
|
@ -10,6 +10,5 @@ namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
jmethodID getLogMarkerMethod();
|
jmethodID getLogMarkerMethod();
|
||||||
std::string getApplicationCacheDir();
|
|
||||||
} // namespace react
|
} // namespace react
|
||||||
} // namespace facebook
|
} // namespace facebook
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include <folly/dynamic.h>
|
#include <folly/dynamic.h>
|
||||||
|
|
||||||
#include "JSModulesUnbundle.h"
|
#include "JSModulesUnbundle.h"
|
||||||
|
@ -136,68 +134,6 @@ private:
|
||||||
size_t m_size;
|
size_t m_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
class JSBigMmapString : public JSBigString {
|
|
||||||
public:
|
|
||||||
enum class Encoding {
|
|
||||||
Unknown,
|
|
||||||
Ascii,
|
|
||||||
Utf8,
|
|
||||||
Utf16,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
JSBigMmapString(int fd, size_t size, const uint8_t sha1[20], Encoding encoding) :
|
|
||||||
m_fd(fd),
|
|
||||||
m_size(size),
|
|
||||||
m_encoding(encoding),
|
|
||||||
m_str(nullptr)
|
|
||||||
{
|
|
||||||
memcpy(m_hash, sha1, 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
~JSBigMmapString() {
|
|
||||||
if (m_str) {
|
|
||||||
CHECK(munmap((void *)m_str, m_size) != -1);
|
|
||||||
}
|
|
||||||
close(m_fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isAscii() const override {
|
|
||||||
return m_encoding == Encoding::Ascii;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* c_str() const override {
|
|
||||||
if (!m_str) {
|
|
||||||
m_str = (const char *)mmap(0, m_size, PROT_READ, MAP_SHARED, m_fd, 0);
|
|
||||||
CHECK(m_str != MAP_FAILED);
|
|
||||||
}
|
|
||||||
return m_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const override {
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fd() const {
|
|
||||||
return m_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t* hash() const {
|
|
||||||
return m_hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
Encoding encoding() const {
|
|
||||||
return m_encoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_fd;
|
|
||||||
size_t m_size;
|
|
||||||
uint8_t m_hash[20];
|
|
||||||
Encoding m_encoding;
|
|
||||||
mutable const char *m_str;
|
|
||||||
};
|
|
||||||
|
|
||||||
class JSExecutor {
|
class JSExecutor {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -253,33 +253,10 @@ void JSCExecutor::terminateOnJSVMThread() {
|
||||||
m_context = nullptr;
|
m_context = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_FBJSCEXTENSIONS
|
|
||||||
static void loadApplicationSource(
|
|
||||||
const JSGlobalContextRef context,
|
|
||||||
const JSBigMmapString* script,
|
|
||||||
const std::string& sourceURL) {
|
|
||||||
String jsSourceURL(sourceURL.c_str());
|
|
||||||
bool is8bit = script->encoding() == JSBigMmapString::Encoding::Ascii || script->encoding() == JSBigMmapString::Encoding::Utf8;
|
|
||||||
JSSourceCodeRef sourceCode = JSCreateSourceCode(script->fd(), script->size(), jsSourceURL, script->hash(), is8bit);
|
|
||||||
evaluateSourceCode(context, sourceCode, jsSourceURL);
|
|
||||||
JSReleaseSourceCode(sourceCode);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void JSCExecutor::loadApplicationScript(std::unique_ptr<const JSBigString> script, std::string sourceURL) throw(JSException) {
|
void JSCExecutor::loadApplicationScript(std::unique_ptr<const JSBigString> script, std::string sourceURL) throw(JSException) {
|
||||||
SystraceSection s("JSCExecutor::loadApplicationScript",
|
SystraceSection s("JSCExecutor::loadApplicationScript",
|
||||||
"sourceURL", sourceURL);
|
"sourceURL", sourceURL);
|
||||||
|
|
||||||
#ifdef WITH_FBJSCEXTENSIONS
|
|
||||||
if (auto source = dynamic_cast<const JSBigMmapString *>(script.get())) {
|
|
||||||
loadApplicationSource(m_context, source, sourceURL);
|
|
||||||
bindBridge();
|
|
||||||
flush();
|
|
||||||
ReactMarker::logMarker("CREATE_REACT_CONTEXT_END");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WITH_FBSYSTRACE
|
#ifdef WITH_FBSYSTRACE
|
||||||
fbsystrace_begin_section(
|
fbsystrace_begin_section(
|
||||||
TRACE_TAG_REACT_CXX_BRIDGE,
|
TRACE_TAG_REACT_CXX_BRIDGE,
|
||||||
|
|
|
@ -44,63 +44,47 @@ JSValueRef evaluateScript(JSContextRef context, JSStringRef script, JSStringRef
|
||||||
JSValueRef exn, result;
|
JSValueRef exn, result;
|
||||||
result = JSEvaluateScript(context, script, NULL, source, 0, &exn);
|
result = JSEvaluateScript(context, script, NULL, source, 0, &exn);
|
||||||
if (result == nullptr) {
|
if (result == nullptr) {
|
||||||
formatAndThrowJSException(context, exn, source);
|
Value exception = Value(context, exn);
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if WITH_FBJSCEXTENSIONS
|
std::string exceptionText = exception.toString().str();
|
||||||
JSValueRef evaluateSourceCode(JSContextRef context, JSSourceCodeRef source, JSStringRef sourceURL) {
|
|
||||||
JSValueRef exn, result;
|
|
||||||
result = JSEvaluateSourceCode(context, source, NULL, &exn);
|
|
||||||
if (result == nullptr) {
|
|
||||||
formatAndThrowJSException(context, exn, sourceURL);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void formatAndThrowJSException(JSContextRef context, JSValueRef exn, JSStringRef source) {
|
// The null/empty-ness of source tells us if the JS came from a
|
||||||
Value exception = Value(context, exn);
|
// file/resource, or was a constructed statement. The location
|
||||||
|
// info will include that source, if any.
|
||||||
|
std::string locationInfo = source != nullptr ? String::ref(source).str() : "";
|
||||||
|
Object exObject = exception.asObject();
|
||||||
|
auto line = exObject.getProperty("line");
|
||||||
|
if (line != nullptr && line.isNumber()) {
|
||||||
|
if (locationInfo.empty() && line.asInteger() != 1) {
|
||||||
|
// If there is a non-trivial line number, but there was no
|
||||||
|
// location info, we include a placeholder, and the line
|
||||||
|
// number.
|
||||||
|
locationInfo = folly::to<std::string>("<unknown file>:", line.asInteger());
|
||||||
|
} else if (!locationInfo.empty()) {
|
||||||
|
// If there is location info, we always include the line
|
||||||
|
// number, regardless of its value.
|
||||||
|
locationInfo += folly::to<std::string>(":", line.asInteger());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string exceptionText = exception.toString().str();
|
if (!locationInfo.empty()) {
|
||||||
|
exceptionText += " (" + locationInfo + ")";
|
||||||
|
}
|
||||||
|
|
||||||
// The null/empty-ness of source tells us if the JS came from a
|
LOG(ERROR) << "Got JS Exception: " << exceptionText;
|
||||||
// file/resource, or was a constructed statement. The location
|
|
||||||
// info will include that source, if any.
|
Value jsStack = exObject.getProperty("stack");
|
||||||
std::string locationInfo = source != nullptr ? String::ref(source).str() : "";
|
if (jsStack.isNull() || !jsStack.isString()) {
|
||||||
Object exObject = exception.asObject();
|
throwJSExecutionException("%s", exceptionText.c_str());
|
||||||
auto line = exObject.getProperty("line");
|
} else {
|
||||||
if (line != nullptr && line.isNumber()) {
|
LOG(ERROR) << "Got JS Stack: " << jsStack.toString().str();
|
||||||
if (locationInfo.empty() && line.asInteger() != 1) {
|
throwJSExecutionExceptionWithStack(
|
||||||
// If there is a non-trivial line number, but there was no
|
exceptionText.c_str(), jsStack.toString().str().c_str());
|
||||||
// location info, we include a placeholder, and the line
|
|
||||||
// number.
|
|
||||||
locationInfo = folly::to<std::string>("<unknown file>:", line.asInteger());
|
|
||||||
} else if (!locationInfo.empty()) {
|
|
||||||
// If there is location info, we always include the line
|
|
||||||
// number, regardless of its value.
|
|
||||||
locationInfo += folly::to<std::string>(":", line.asInteger());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
if (!locationInfo.empty()) {
|
|
||||||
exceptionText += " (" + locationInfo + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(ERROR) << "Got JS Exception: " << exceptionText;
|
|
||||||
|
|
||||||
Value jsStack = exObject.getProperty("stack");
|
|
||||||
if (jsStack.isNull() || !jsStack.isString()) {
|
|
||||||
throwJSExecutionException("%s", exceptionText.c_str());
|
|
||||||
} else {
|
|
||||||
LOG(ERROR) << "Got JS Stack: " << jsStack.toString().str();
|
|
||||||
throwJSExecutionExceptionWithStack(
|
|
||||||
exceptionText.c_str(), jsStack.toString().str().c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JSValueRef makeJSError(JSContextRef ctx, const char *error) {
|
JSValueRef makeJSError(JSContextRef ctx, const char *error) {
|
||||||
JSValueRef nestedException = nullptr;
|
JSValueRef nestedException = nullptr;
|
||||||
JSValueRef args[] = { Value(ctx, String(error)) };
|
JSValueRef args[] = { Value(ctx, String(error)) };
|
||||||
|
|
|
@ -49,18 +49,6 @@ JSValueRef evaluateScript(
|
||||||
JSStringRef script,
|
JSStringRef script,
|
||||||
JSStringRef sourceURL);
|
JSStringRef sourceURL);
|
||||||
|
|
||||||
#if WITH_FBJSCEXTENSIONS
|
|
||||||
JSValueRef evaluateSourceCode(
|
|
||||||
JSContextRef ctx,
|
|
||||||
JSSourceCodeRef source,
|
|
||||||
JSStringRef sourceURL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void formatAndThrowJSException(
|
|
||||||
JSContextRef ctx,
|
|
||||||
JSValueRef exn,
|
|
||||||
JSStringRef sourceURL);
|
|
||||||
|
|
||||||
JSValueRef makeJSError(JSContextRef ctx, const char *error);
|
JSValueRef makeJSError(JSContextRef ctx, const char *error);
|
||||||
|
|
||||||
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, const char *exceptionLocation);
|
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, const char *exceptionLocation);
|
||||||
|
|
Loading…
Reference in New Issue