Add a way to access the underlying JavaScriptCore context

Summary:
**Motivation**

I'm working on a project that uses React Native and needs to add direct synchronous bindings to native stuff through the JavaScriptCore C API. This is because it's performance-sensitive and would benefit from the quickest JS->C path. It does this using cross-platform C++ code that works on both iOS and Android. Most of the infrastructure for getting access to the JSC context is already in React Native actually, just had to add a few more things.

(lexs you mentioned to tag you in this pull request)

**Test plan**

Modify the JavaScriptCore context through the `JSContextRef` returned (eg. add an object at global scope) and verify that it exists in JavaScript.
Closes https://github.com/facebook/react-native/pull/10399

Differential Revision: D4080945

Pulled By: lexs

fbshipit-source-id: 6659b7a01e09fd84475adde183c1d3aca2d4cf09
This commit is contained in:
Nikhilesh Sigatapu
2016-10-26 03:43:05 -07:00
committed by Facebook Github Bot
parent 0698b2beca
commit c67225818d
9 changed files with 36 additions and 0 deletions

View File

@@ -108,4 +108,9 @@ RCT_EXTERN NSString *const RCTFBJSValueClassKey;
arguments:(NSArray *)args
jsValueCallback:(RCTJavaScriptValueCallback)onComplete;
/**
* Get the JavaScriptCore context associated with this executor instance.
*/
- (JSContext *)jsContext;
@end

View File

@@ -927,6 +927,11 @@ static NSData *loadRAMBundle(NSURL *sourceURL, NSError **error, RandomAccessBund
return [NSData dataWithBytesNoCopy:startupCode.code.release() length:startupCode.size freeWhenDone:YES];
}
- (JSContext *)jsContext
{
return [self context].context;
}
@end
@implementation RCTJSContextProvider

View File

@@ -75,4 +75,9 @@ public interface CatalystInstance extends MemoryPressureListener {
@VisibleForTesting
void setGlobalVariable(String propName, String jsonValue);
/**
* Get the C pointer (as a long) to the JavaScriptCore context associated with this instance.
*/
long getJavaScriptContext();
}

View File

@@ -339,4 +339,11 @@ public class ReactContext extends ContextWrapper {
}
return mCurrentActivity.get();
}
/**
* Get the C pointer (as a long) to the JavaScriptCore context associated with this instance.
*/
public long getJavaScriptContext() {
return mCatalystInstance.getJavaScriptContext();
}
}

View File

@@ -347,6 +347,9 @@ public class CatalystInstanceImpl implements CatalystInstance {
@Override
public native void setGlobalVariable(String propName, String jsonValue);
@Override
public native long getJavaScriptContext();
// TODO mhorowitz: add mDestroyed checks to the next three methods
@Override

View File

@@ -111,6 +111,7 @@ void CatalystInstanceImpl::registerNatives() {
makeNativeMethod("callJSCallback", CatalystInstanceImpl::callJSCallback),
makeNativeMethod("getMainExecutorToken", CatalystInstanceImpl::getMainExecutorToken),
makeNativeMethod("setGlobalVariable", CatalystInstanceImpl::setGlobalVariable),
makeNativeMethod("getJavaScriptContext", CatalystInstanceImpl::getJavaScriptContext),
makeNativeMethod("handleMemoryPressureUiHidden", CatalystInstanceImpl::handleMemoryPressureUiHidden),
makeNativeMethod("handleMemoryPressureModerate", CatalystInstanceImpl::handleMemoryPressureModerate),
makeNativeMethod("handleMemoryPressureCritical", CatalystInstanceImpl::handleMemoryPressureCritical),
@@ -219,6 +220,10 @@ void CatalystInstanceImpl::setGlobalVariable(std::string propName,
folly::make_unique<JSBigStdString>(std::move(jsonValue)));
}
jlong CatalystInstanceImpl::getJavaScriptContext() {
return (jlong) (intptr_t) instance_->getJavaScriptContext();
}
void CatalystInstanceImpl::handleMemoryPressureUiHidden() {
instance_->handleMemoryPressureUiHidden();
}

View File

@@ -55,6 +55,7 @@ class CatalystInstanceImpl : public jni::HybridClass<CatalystInstanceImpl> {
local_ref<JExecutorToken::JavaPart> getMainExecutorToken();
void setGlobalVariable(std::string propName,
std::string&& jsonValue);
jlong getJavaScriptContext();
void handleMemoryPressureUiHidden();
void handleMemoryPressureModerate();
void handleMemoryPressureCritical();

View File

@@ -132,6 +132,10 @@ void Instance::setGlobalVariable(std::string propName,
nativeToJsBridge_->setGlobalVariable(std::move(propName), std::move(jsonValue));
}
void *Instance::getJavaScriptContext() {
return nativeToJsBridge_->getJavaScriptContext();
}
void Instance::callJSFunction(ExecutorToken token, std::string&& module, std::string&& method,
folly::dynamic&& params) {
callback_->incrementPendingJSCalls();

View File

@@ -50,6 +50,7 @@ class Instance {
void startProfiler(const std::string& title);
void stopProfiler(const std::string& title, const std::string& filename);
void setGlobalVariable(std::string propName, std::unique_ptr<const JSBigString> jsonValue);
void *getJavaScriptContext();
void callJSFunction(ExecutorToken token, std::string&& module, std::string&& method,
folly::dynamic&& params);
void callJSCallback(ExecutorToken token, uint64_t callbackId, folly::dynamic&& params);