JSCWebWorker::JSCWebWorker(int id, JSCWebWorkerOwner *owner, std::string scriptSrc) :
    id_(id),
    scriptName_(std::move(scriptSrc)),
    owner_(owner) {
  ownerMessageQueueThread_ = owner->getMessageQueueThread();
  FBASSERTMSGF(ownerMessageQueueThread_, "Owner MessageQueueThread must not be null");
  workerMessageQueueThread_ = WebWorkers::createWebWorkerThread(id, ownerMessageQueueThread_.get());
  FBASSERTMSGF(workerMessageQueueThread_, "Failed to create worker thread");

  workerMessageQueueThread_->runOnQueue([this] () {
    initJSVMAndLoadScript();
  });
}
Example #2
0
std::unique_ptr<JSExecutor> ProxyExecutorOneTimeFactory::createJSExecutor(FlushImmediateCallback ignoredCallback) {
  FBASSERTMSGF(
    m_executor.get() != nullptr,
    "Proxy instance should not be null. Did you attempt to call createJSExecutor() on this factory "
    "instance more than once?");
  return std::unique_ptr<JSExecutor>(new ProxyExecutor(std::move(m_executor)));
}
void assertIfExceptionsNotInitialized() {
  // Use relaxed memory order because we don't need memory barriers.
  // The real init-once enforcement is done by the compiler for the
  // "static" in initExceptionHelpers.
  FBASSERTMSGF(gIsInitialized.load(std::memory_order_relaxed),
               "initExceptionHelpers was never called!");
}
Example #4
0
std::unique_ptr<JSExecutor> ProxyExecutorOneTimeFactory::createJSExecutor(Bridge *bridge) {
  FBASSERTMSGF(
    m_executor.get() != nullptr,
    "Proxy instance should not be null. Did you attempt to call createJSExecutor() on this factory "
    "instance more than once?");
  return std::unique_ptr<JSExecutor>(new ProxyExecutor(std::move(m_executor), bridge));
}
void JSCWebWorker::initJSVMAndLoadScript() {
  FBASSERTMSGF(!isTerminated(), "Worker was already finished!");
  FBASSERTMSGF(!context_, "Worker JS VM was already created!");

  context_ = JSGlobalContextCreateInGroup(
      NULL, // use default JS 'global' object
      NULL // create new group (i.e. new VM)
  ); 
  s_globalContextRefToJSCWebWorker[context_] = this;
  
  // TODO(9604438): Protect against script does not exist
  std::string script = loadScriptFromAssets(scriptName_);
  evaluateScript(context_, String(script.c_str()), String(scriptName_.c_str()));

  installGlobalFunction(context_, "postMessage", nativePostMessage);
}
Example #6
0
void setCountableForJava(JNIEnv* env, jobject obj, RefPtr<Countable>&& countable) {
  int oldValue = env->GetLongField(obj, gCountableNativePtr);
  FBASSERTMSGF(oldValue == 0, "Cannot reinitialize object; expected nullptr, got %x", oldValue);

  FBASSERT(countable);
  uintptr_t fieldValue = (uintptr_t) new RefPtr<Countable>(std::move(countable));
  env->SetLongField(obj, gCountableNativePtr, fieldValue);
}
void CommonJniExceptions::init() {
  JNIEnv* env = internal::getEnv();
  FBASSERTMSGF(env, "Could not get JNI Environment");

  // Throwable class
  jclass localThrowableClass = env->FindClass("java/lang/Throwable");
  FBASSERT(localThrowableClass);
  throwableClass_ = static_cast<jclass>(env->NewGlobalRef(localThrowableClass));
  FBASSERT(throwableClass_);
  env->DeleteLocalRef(localThrowableClass);

  // UnknownCppException class
  jclass localUnknownCppExceptionClass = env->FindClass("com/facebook/jni/UnknownCppException");
  FBASSERT(localUnknownCppExceptionClass);
  jmethodID unknownCppExceptionConstructorMID = env->GetMethodID(
      localUnknownCppExceptionClass,
      "<init>",
      "()V");
  FBASSERT(unknownCppExceptionConstructorMID);
  unknownCppExceptionClass_ = static_cast<jclass>(env->NewGlobalRef(localUnknownCppExceptionClass));
  FBASSERT(unknownCppExceptionClass_);
  env->DeleteLocalRef(localUnknownCppExceptionClass);

  // UnknownCppException object
  jthrowable localUnknownCppExceptionObject = static_cast<jthrowable>(env->NewObject(
      unknownCppExceptionClass_,
      unknownCppExceptionConstructorMID));
  FBASSERT(localUnknownCppExceptionObject);
  unknownCppExceptionObject_ = static_cast<jthrowable>(env->NewGlobalRef(
      localUnknownCppExceptionObject));
  FBASSERT(unknownCppExceptionObject_);
  env->DeleteLocalRef(localUnknownCppExceptionObject);

  // RuntimeException object
  jclass localRuntimeExceptionClass = env->FindClass("java/lang/RuntimeException");
  FBASSERT(localRuntimeExceptionClass);

  jmethodID runtimeExceptionConstructorMID = env->GetMethodID(
      localRuntimeExceptionClass,
      "<init>",
      "()V");
  FBASSERT(runtimeExceptionConstructorMID);
  jthrowable localRuntimeExceptionObject = static_cast<jthrowable>(env->NewObject(
      localRuntimeExceptionClass,
      runtimeExceptionConstructorMID));
  FBASSERT(localRuntimeExceptionObject);
  runtimeExceptionObject_ = static_cast<jthrowable>(env->NewGlobalRef(localRuntimeExceptionObject));
  FBASSERT(runtimeExceptionObject_);

  env->DeleteLocalRef(localRuntimeExceptionClass);
  env->DeleteLocalRef(localRuntimeExceptionObject);
}
Example #8
0
void HybridData::setNativePointer(std::unique_ptr<BaseHybridClass> new_value) {
  static auto pointerField = getClass()->getField<jlong>("mNativePointer");
  auto* old_value = reinterpret_cast<BaseHybridClass*>(getFieldValue(pointerField));
  if (new_value) {
    // Modify should only ever be called once with a non-null
    // new_value.  If this happens again it's a programmer error, so
    // blow up.
    FBASSERTMSGF(old_value == 0, "Attempt to set C++ native pointer twice");
  } else if (old_value == 0) {
    return;
  }
  // delete on a null pointer is defined to be a noop.
  delete old_value;
  // This releases ownership from the unique_ptr, and passes the pointer, and
  // ownership of it, to HybridData which is managed by the java GC.  The
  // finalizer on hybridData calls resetNative which will delete the object, if
  // resetNative has not already been called.
  setFieldValue(pointerField, reinterpret_cast<jlong>(new_value.release()));
}
JSModulesUnbundle::Module JniJSModulesUnbundle::getModule(uint32_t moduleId) const {
  // can be nullptr for default constructor.
  FBASSERTMSGF(m_assetManager != nullptr, "Unbundle has not been initialized with an asset manager");

  std::ostringstream sourceUrlBuilder;
  sourceUrlBuilder << moduleId << ".js";
  auto sourceUrl = sourceUrlBuilder.str();

  auto fileName = m_moduleDirectory + sourceUrl;
  auto asset = openAsset(m_assetManager, fileName, AASSET_MODE_BUFFER);

  const char *buffer = nullptr;
  if (asset != nullptr) {
    buffer = static_cast<const char *>(AAsset_getBuffer(asset.get()));
  }
  if (buffer == nullptr) {
    throw ModuleNotFound(moduleId);
  }
  return {sourceUrl, std::string(buffer, AAsset_getLength(asset.get()))};
}
Example #10
0
WeakReference::~WeakReference() {
  auto env = Environment::current();
  FBASSERTMSGF(env, "Attempt to delete jni::WeakReference from non-JNI thread");
  env->DeleteWeakGlobalRef(m_weakReference);
}
JSCWebWorker::~JSCWebWorker() {
  FBASSERTMSGF(isTerminated(), "Didn't terminate the web worker before releasing it!");
}