WebWorkers: Add APIs for working with JSObjectRef

Reviewed By: lexs

Differential Revision: D2779267

fb-gh-sync-id: 5c5a49988a1d501f15e5033b2dd5b528d97d96ed
This commit is contained in:
Andy Street
2015-12-29 19:47:20 -08:00
committed by facebook-github-bot-5
parent e75e861116
commit a68f8f4224
3 changed files with 108 additions and 7 deletions

View File

@@ -5,6 +5,8 @@
#include <JavaScriptCore/JSContextRef.h>
#include <JavaScriptCore/JSObjectRef.h>
#define throwJSExecutionException(...) jni::throwNewJavaException("com/facebook/react/bridge/JSExecutionException", __VA_ARGS__)
namespace facebook {
namespace react {

View File

@@ -5,6 +5,8 @@
#include <jni/fbjni.h>
#include <fb/log.h>
#include "JSCHelpers.h"
namespace facebook {
namespace react {
@@ -37,17 +39,54 @@ std::string Value::toJSONString(unsigned indent) const {
if (stringToAdopt == nullptr) {
JSValueProtect(m_context, exn);
std::string exceptionText = Value(m_context, exn).toString().str();
jni::throwNewJavaException(
"java/lang/IllegalArgumentException",
"Exception creating JSON string: %s",
exceptionText.c_str());
throwJSExecutionException("Exception creating JSON string: %s", exceptionText.c_str());
}
return String::adopt(stringToAdopt).str();
}
/* static */
Value Value::fromJSON(JSContextRef& ctx, const String& json) {
return Value(ctx, JSValueMakeFromJSONString(ctx, json));
Value Value::fromJSON(JSContextRef ctx, const String& json) {
auto result = JSValueMakeFromJSONString(ctx, json);
if (!result) {
throwJSExecutionException("Failed to create String from JSON");
}
return Value(ctx, result);
}
Object Value::asObject() {
JSValueRef exn;
JSObjectRef jsObj = JSValueToObject(context(), m_value, &exn);
if (!jsObj) {
std::string exceptionText = Value(m_context, exn).toString().str();
throwJSExecutionException("Failed to convert to object: %s", exceptionText.c_str());
}
Object ret = Object(context(), jsObj);
m_value = nullptr;
return std::move(ret);
}
Value Object::callAsFunction(int nArgs, JSValueRef args[]) {
JSValueRef exn;
JSValueRef result = JSObjectCallAsFunction(m_context, m_obj, NULL, nArgs, args, &exn);
if (!result) {
std::string exceptionText = Value(m_context, exn).toString().str();
throwJSExecutionException("Exception calling JS function: %s", exceptionText.c_str());
}
return Value(m_context, result);
}
Value Object::getProperty(String propName) const {
JSValueRef exn;
JSValueRef property = JSObjectGetProperty(m_context, m_obj, propName, &exn);
if (!property) {
std::string exceptionText = Value(m_context, exn).toString().str();
throwJSExecutionException("Failed to get property: %s", exceptionText.c_str());
}
return Value(m_context, property);
}
Value Object::getProperty(const char *propName) const {
return getProperty(String(propName));
}
} }

View File

@@ -4,6 +4,7 @@
#include <memory>
#include <sstream>
#include <JavaScriptCore/JSObjectRef.h>
#include <JavaScriptCore/JSRetainPtr.h>
#include <JavaScriptCore/JSStringRef.h>
#include <JavaScriptCore/JSValueRef.h>
@@ -15,6 +16,7 @@
namespace facebook {
namespace react {
class Value;
class Context;
class String : public noncopyable {
@@ -84,6 +86,58 @@ private:
JSRetainPtr<JSStringRef> m_string;
};
class Object : public noncopyable {
public:
Object(JSContextRef context, JSObjectRef obj) :
m_context(context),
m_obj(obj)
{}
Object(Object&& other) :
m_context(other.m_context),
m_obj(other.m_obj),
m_isProtected(other.m_isProtected) {
other.m_obj = nullptr;
other.m_isProtected = false;
}
~Object() {
if (m_isProtected && m_obj) {
JSValueUnprotect(m_context, m_obj);
}
}
operator JSObjectRef() const {
return m_obj;
}
bool isFunction() const {
return JSObjectIsFunction(m_context, m_obj);
}
Value callAsFunction(int nArgs, JSValueRef args[]);
Value getProperty(String propName) const;
Value getProperty(const char *propName) const;
void makeProtected() {
if (!m_isProtected && m_obj) {
JSValueProtect(m_context, m_obj);
m_isProtected = true;
}
}
static Object getGlobalObject(JSContextRef ctx) {
auto globalObj = JSContextGetGlobalObject(ctx);
return Object(ctx, globalObj);
}
private:
JSContextRef m_context;
JSObjectRef m_obj;
bool m_isProtected = false;
};
class Value : public noncopyable {
public:
Value(JSContextRef context, JSValueRef value);
@@ -110,6 +164,10 @@ public:
return JSValueIsNull(context(), m_value);
}
bool isUndefined() const {
return JSValueIsUndefined(context(), m_value);
}
double asNumber() const {
if (isNumber()) {
return JSValueToNumber(context(), m_value, nullptr);
@@ -130,6 +188,8 @@ public:
return JSValueIsObject(context(), m_value);
}
Object asObject();
bool isString() const {
return JSValueIsString(context(), m_value);
}
@@ -139,7 +199,7 @@ public:
}
std::string toJSONString(unsigned indent = 0) const;
static Value fromJSON(JSContextRef& ctx, const String& json);
static Value fromJSON(JSContextRef ctx, const String& json);
protected:
JSContextRef context() const;
JSContextRef m_context;