Add some more helper methods to Value

Reviewed By: mhorowitz

Differential Revision: D4197278

fbshipit-source-id: 9a538ff2747d32a54d42627a9f78e4a348dce639
This commit is contained in:
Pieter De Baets 2016-11-18 06:25:24 -08:00 committed by Facebook Github Bot
parent 1604f10889
commit 674d86cdcb
13 changed files with 121 additions and 133 deletions

View File

@ -73,12 +73,11 @@ inline JSObjectCallAsFunctionCallback exceptionWrapMethod() {
const JSValueRef arguments[],
JSValueRef *exception) {
try {
auto globalObj = JSContextGetGlobalObject(ctx);
auto executor = static_cast<JSCExecutor*>(JSObjectGetPrivate(globalObj));
auto executor = Object::getGlobalObject(ctx).getPrivate<JSCExecutor>();
return (executor->*method)(argumentCount, arguments);
} catch (...) {
*exception = translatePendingCppExceptionToJSError(ctx, function);
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
}
};
@ -95,12 +94,11 @@ inline JSObjectGetPropertyCallback exceptionWrapMethod() {
JSStringRef propertyName,
JSValueRef *exception) {
try {
auto globalObj = JSContextGetGlobalObject(ctx);
auto executor = static_cast<JSCExecutor*>(JSObjectGetPrivate(globalObj));
auto executor = Object::getGlobalObject(ctx).getPrivate<JSCExecutor>();
return (executor->*method)(object, propertyName);
} catch (...) {
*exception = translatePendingCppExceptionToJSError(ctx, object);
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
}
};
@ -121,7 +119,7 @@ static JSValueRef nativeInjectHMRUpdate(
String execJSString = Value(ctx, arguments[0]).toString();
String jsURL = Value(ctx, arguments[1]).toString();
evaluateScript(ctx, execJSString, jsURL);
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
#endif
@ -235,7 +233,7 @@ void JSCExecutor::initOnJSVMThread() throw(JSException) {
JSClassRelease(globalClass);
// Add a pointer to ourselves so we can retrieve it later in our hooks
JSObjectSetPrivate(JSContextGetGlobalObject(m_context), this);
Object::getGlobalObject(m_context).setPrivate(this);
#ifdef WITH_INSPECTOR
Inspector::instance().registerGlobalContext("main", m_context);
@ -493,7 +491,7 @@ void JSCExecutor::invokeCallback(const double callbackId, const folly::dynamic&
auto result = [&] {
try {
return m_invokeCallbackAndReturnFlushedQueueJS->callAsFunction({
JSValueMakeNumber(m_context, callbackId),
Value::makeNumber(m_context, callbackId),
Value::fromDynamic(m_context, std::move(arguments))
});
} catch (...) {
@ -530,13 +528,8 @@ void JSCExecutor::setGlobalVariable(std::string propName, std::unique_ptr<const
SystraceSection s("JSCExecutor.setGlobalVariable",
"propName", propName);
auto globalObject = JSContextGetGlobalObject(m_context);
String jsPropertyName(propName.c_str());
String jsValueJSON = jsStringFromBigString(*jsonValue);
auto valueToInject = JSValueMakeFromJSONString(m_context, jsValueJSON);
JSObjectSetProperty(m_context, globalObject, jsPropertyName, valueToInject, 0, NULL);
auto valueToInject = Value::fromJSON(m_context, jsStringFromBigString(*jsonValue));
Object::getGlobalObject(m_context).setProperty(propName.c_str(), valueToInject);
} catch (...) {
std::throw_with_nested(std::runtime_error("Error setting global variable: " + propName));
}
@ -736,7 +729,7 @@ JSValueRef JSCExecutor::nativePostMessage(
JSValueRef msg = arguments[0];
postMessageToOwner(msg);
return JSValueMakeUndefined(m_context);
return Value::makeUndefined(m_context);
}
JSValueRef JSCExecutor::nativeRequire(
@ -754,7 +747,7 @@ JSValueRef JSCExecutor::nativeRequire(
}
loadModule(moduleId);
return JSValueMakeUndefined(m_context);
return Value::makeUndefined(m_context);
}
JSValueRef JSCExecutor::nativeFlushQueueImmediate(
@ -765,7 +758,7 @@ JSValueRef JSCExecutor::nativeFlushQueueImmediate(
}
flushQueueImmediate(Value(m_context, arguments[0]));
return JSValueMakeUndefined(m_context);
return Value::makeUndefined(m_context);
}
JSValueRef JSCExecutor::nativeStartWorker(
@ -782,7 +775,7 @@ JSValueRef JSCExecutor::nativeStartWorker(
int workerId = addWebWorker(scriptFile, worker, globalObj);
return JSValueMakeNumber(m_context, workerId);
return Value::makeNumber(m_context, workerId);
}
JSValueRef JSCExecutor::nativePostMessageToWorker(
@ -799,7 +792,7 @@ JSValueRef JSCExecutor::nativePostMessageToWorker(
postMessageToOwnedWebWorker((int) workerDouble, arguments[1]);
return JSValueMakeUndefined(m_context);
return Value::makeUndefined(m_context);
}
JSValueRef JSCExecutor::nativeTerminateWorker(
@ -816,7 +809,7 @@ JSValueRef JSCExecutor::nativeTerminateWorker(
terminateOwnedWebWorker((int) workerDouble);
return JSValueMakeUndefined(m_context);
return Value::makeUndefined(m_context);
}
JSValueRef JSCExecutor::nativeCallSyncHook(
@ -836,7 +829,7 @@ JSValueRef JSCExecutor::nativeCallSyncHook(
methodId,
argsJson);
if (result.isUndefined) {
return JSValueMakeUndefined(m_context);
return Value::makeUndefined(m_context);
}
return Value::fromDynamic(m_context, result.result);
}

View File

@ -11,6 +11,8 @@
#include <jschelpers/Value.h>
#include "JSCLegacyProfiler.h"
using namespace facebook::react;
static JSValueRef nativeProfilerStart(
JSContextRef ctx,
JSObjectRef function,
@ -20,11 +22,11 @@ static JSValueRef nativeProfilerStart(
JSValueRef* exception) {
if (argumentCount < 1) {
if (exception) {
*exception = facebook::react::makeJSCException(
*exception = Value::makeError(
ctx,
"nativeProfilerStart: requires at least 1 argument");
}
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
JSStringRef title = JSValueToStringCopy(ctx, arguments[0], exception);
@ -34,7 +36,7 @@ static JSValueRef nativeProfilerStart(
JSStartProfiling(ctx, title);
#endif
JSStringRelease(title);
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
static JSValueRef nativeProfilerEnd(
@ -46,11 +48,11 @@ static JSValueRef nativeProfilerEnd(
JSValueRef* exception) {
if (argumentCount < 1) {
if (exception) {
*exception = facebook::react::makeJSCException(
*exception = Value::makeError(
ctx,
"nativeProfilerEnd: requires at least 1 argument");
}
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
std::string writeLocation("/sdcard/");
@ -64,7 +66,7 @@ static JSValueRef nativeProfilerEnd(
JSStringRef title = JSValueToStringCopy(ctx, arguments[0], exception);
JSEndProfilingAndRender(ctx, title, writeLocation.c_str());
JSStringRelease(title);
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
namespace facebook {

View File

@ -10,11 +10,14 @@
#include <fbsystrace.h>
#include <jschelpers/JSCHelpers.h>
#include <jschelpers/Value.h>
#include "JSCTracing.h"
static const char *ENABLED_FBSYSTRACE_PROFILE_NAME = "__fbsystrace__";
using namespace facebook::react;
static JSValueRef nativeTraceBeginLegacy(
JSContextRef ctx,
JSObjectRef function,
@ -23,9 +26,9 @@ static JSValueRef nativeTraceBeginLegacy(
const JSValueRef arguments[],
JSValueRef* exception) {
if (FBSYSTRACE_LIKELY(argumentCount >= 1)) {
uint64_t tag = facebook::react::tracingTagFromJSValue(ctx, arguments[0], exception);
uint64_t tag = tracingTagFromJSValue(ctx, arguments[0], exception);
if (!fbsystrace_is_tracing(tag)) {
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
}
@ -37,7 +40,7 @@ static JSValueRef nativeTraceBeginLegacy(
#endif
JSStringRelease(title);
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
static JSValueRef nativeTraceEndLegacy(
@ -48,9 +51,9 @@ static JSValueRef nativeTraceEndLegacy(
const JSValueRef arguments[],
JSValueRef* exception) {
if (FBSYSTRACE_LIKELY(argumentCount >= 1)) {
uint64_t tag = facebook::react::tracingTagFromJSValue(ctx, arguments[0], exception);
uint64_t tag = tracingTagFromJSValue(ctx, arguments[0], exception);
if (!fbsystrace_is_tracing(tag)) {
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
}
@ -58,7 +61,7 @@ static JSValueRef nativeTraceEndLegacy(
JSEndProfiling(ctx, title);
JSStringRelease(title);
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
namespace facebook {

View File

@ -10,6 +10,8 @@
#include <jschelpers/JSCHelpers.h>
#include <jschelpers/Value.h>
using namespace facebook::react;
static JSValueRef nativeCaptureHeap(
JSContextRef ctx,
JSObjectRef function,
@ -19,18 +21,18 @@ static JSValueRef nativeCaptureHeap(
JSValueRef* exception) {
if (argumentCount < 1) {
if (exception) {
*exception = facebook::react::makeJSCException(
*exception = Value::makeError(
ctx,
"nativeCaptureHeap requires the path to save the capture");
}
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
JSStringRef outputFilename = JSValueToStringCopy(ctx, arguments[0], exception);
std::string finalFilename = facebook::react::String::ref(outputFilename).str();
JSCaptureHeap(ctx, finalFilename.c_str(), exception);
JSStringRelease(outputFilename);
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
#endif // WITH_FB_MEMORY_PROFILING

View File

@ -20,7 +20,7 @@ JSValueRef JSCNativeModules::getModule(JSContextRef context, JSStringRef jsName)
auto module = createModule(moduleName, context);
if (!module.hasValue()) {
return JSValueMakeUndefined(context);
return Value::makeUndefined(context);
}
// Protect since we'll be holding on to this value, even though JS may not
@ -53,7 +53,7 @@ folly::Optional<Object> JSCNativeModules::createModule(const std::string& name,
Value moduleInfo = m_genNativeModuleJS->callAsFunction({
Value::fromDynamic(context, result->config),
JSValueMakeNumber(context, result->index)
Value::makeNumber(context, result->index)
});
CHECK(!moduleInfo.isNull()) << "Module returned from genNativeModule is null";

View File

@ -10,6 +10,8 @@
#include <jschelpers/JSCHelpers.h>
#include <jschelpers/Value.h>
using namespace facebook::react;
static JSValueRef nativeGetHeapStats(
JSContextRef ctx,
JSObjectRef function,
@ -21,10 +23,10 @@ static JSValueRef nativeGetHeapStats(
JSGetHeapStats(ctx, &heapStats);
auto result = facebook::react::Object::create(ctx);
result.setProperty("size", {ctx, JSValueMakeNumber(ctx, heapStats.size)});
result.setProperty("extra_size", {ctx, JSValueMakeNumber(ctx, heapStats.extraSize)});
result.setProperty("capacity", {ctx, JSValueMakeNumber(ctx, heapStats.capacity)});
result.setProperty("object_count", {ctx, JSValueMakeNumber(ctx, heapStats.objectCount)});
result.setProperty("size", {ctx, Value::makeNumber(ctx, heapStats.size)});
result.setProperty("extra_size", {ctx, Value::makeNumber(ctx, heapStats.extraSize)});
result.setProperty("capacity", {ctx, Value::makeNumber(ctx, heapStats.capacity)});
result.setProperty("object_count", {ctx, Value::makeNumber(ctx, heapStats.objectCount)});
return (JSObjectRef) result;
}
@ -42,10 +44,10 @@ static JSValueRef nativeGetGCStats(
auto result = facebook::react::Object::create(ctx);
result.setProperty(
"last_full_gc_length",
{ctx, JSValueMakeNumber(ctx, gcStats.lastFullGCLength)});
{ctx, Value::makeNumber(ctx, gcStats.lastFullGCLength)});
result.setProperty(
"last_eden_gc_length",
{ctx, JSValueMakeNumber(ctx, gcStats.lastEdenGCLength)});
{ctx, Value::makeNumber(ctx, gcStats.lastEdenGCLength)});
return (JSObjectRef) result;
}

View File

@ -10,8 +10,10 @@
#include <sys/types.h>
#include <unistd.h>
#include <jschelpers/JSCHelpers.h>
#include <jschelpers/Value.h>
using std::min;
using namespace facebook::react;
static int64_t int64FromJSValue(
JSContextRef ctx,
@ -85,16 +87,16 @@ static JSValueRef nativeTraceBeginSection(
JSValueRef* exception) {
if (FBSYSTRACE_UNLIKELY(argumentCount < 2)) {
if (exception) {
*exception = facebook::react::makeJSCException(
*exception = Value::makeError(
ctx,
"nativeTraceBeginSection: requires at least 2 arguments");
}
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
uint64_t tag = facebook::react::tracingTagFromJSValue(ctx, arguments[0], exception);
if (!fbsystrace_is_tracing(tag)) {
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
char buf[FBSYSTRACE_MAX_MESSAGE_LENGTH];
@ -113,7 +115,7 @@ static JSValueRef nativeTraceBeginSection(
flush:
fbsystrace_trace_raw(buf, min(pos, sizeof(buf)-1));
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
static JSValueRef nativeTraceEndSection(
@ -125,16 +127,16 @@ static JSValueRef nativeTraceEndSection(
JSValueRef* exception) {
if (FBSYSTRACE_UNLIKELY(argumentCount < 1)) {
if (exception) {
*exception = facebook::react::makeJSCException(
*exception = Value::makeError(
ctx,
"nativeTraceEndSection: requires at least 1 argument");
}
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
uint64_t tag = facebook::react::tracingTagFromJSValue(ctx, arguments[0], exception);
if (!fbsystrace_is_tracing(tag)) {
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
if (FBSYSTRACE_LIKELY(argumentCount == 1)) {
@ -155,7 +157,7 @@ flush:
fbsystrace_trace_raw(buf, min(pos, sizeof(buf)-1));
}
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
static JSValueRef beginOrEndAsync(
@ -169,16 +171,16 @@ static JSValueRef beginOrEndAsync(
JSValueRef* exception) {
if (FBSYSTRACE_UNLIKELY(argumentCount < 3)) {
if (exception) {
*exception = facebook::react::makeJSCException(
*exception = Value::makeError(
ctx,
"beginOrEndAsync: requires at least 3 arguments");
}
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
uint64_t tag = facebook::react::tracingTagFromJSValue(ctx, arguments[0], exception);
if (!fbsystrace_is_tracing(tag)) {
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
char buf[FBSYSTRACE_MAX_MESSAGE_LENGTH];
@ -219,7 +221,7 @@ static JSValueRef beginOrEndAsync(
flush:
fbsystrace_trace_raw(buf, min(pos, sizeof(buf)-1));
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
static JSValueRef stageAsync(
@ -232,16 +234,16 @@ static JSValueRef stageAsync(
JSValueRef* exception) {
if (FBSYSTRACE_UNLIKELY(argumentCount < 4)) {
if (exception) {
*exception = facebook::react::makeJSCException(
*exception = Value::makeError(
ctx,
"stageAsync: requires at least 4 arguments");
}
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
uint64_t tag = facebook::react::tracingTagFromJSValue(ctx, arguments[0], exception);
if (!fbsystrace_is_tracing(tag)) {
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
char buf[FBSYSTRACE_MAX_MESSAGE_LENGTH];
@ -260,7 +262,7 @@ static JSValueRef stageAsync(
fbsystrace_trace_raw(buf, min(pos, sizeof(buf)-1));
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
static JSValueRef nativeTraceBeginAsyncSection(
@ -378,16 +380,16 @@ static JSValueRef nativeTraceCounter(
JSValueRef* exception) {
if (FBSYSTRACE_UNLIKELY(argumentCount < 3)) {
if (exception) {
*exception = facebook::react::makeJSCException(
*exception = Value::makeError(
ctx,
"nativeTraceCounter: requires at least 3 arguments");
}
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
uint64_t tag = facebook::react::tracingTagFromJSValue(ctx, arguments[0], exception);
if (!fbsystrace_is_tracing(tag)) {
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
char buf[FBSYSTRACE_MAX_MESSAGE_LENGTH];
@ -398,7 +400,7 @@ static JSValueRef nativeTraceCounter(
fbsystrace_counter(tag, buf, value);
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
namespace facebook {
@ -411,9 +413,7 @@ uint64_t tracingTagFromJSValue(
// XXX validate that this is a lossless conversion.
// XXX should we just have separate functions for bridge, infra, and apps,
// then drop this argument to save time?
(void)exception;
uint64_t tag = (uint64_t) JSValueToNumber(ctx, value, NULL);
return tag;
return static_cast<uint64_t>(Value(ctx, value).asNumber());
}
void addNativeTracingHooks(JSGlobalContextRef ctx) {

View File

@ -112,19 +112,17 @@ JSValueRef JSCWebWorker::nativePostMessage(
const JSValueRef arguments[],
JSValueRef *exception) {
if (argumentCount != 1) {
*exception = makeJSCException(ctx, "postMessage got wrong number of arguments");
return JSValueMakeUndefined(ctx);
*exception = Value::makeError(ctx, "postMessage got wrong number of arguments");
return Value::makeUndefined(ctx);
}
JSValueRef msg = arguments[0];
JSCWebWorker *webWorker = s_globalContextRefToJSCWebWorker.at(JSContextGetGlobalContext(ctx));
if (webWorker->isTerminated()) {
return JSValueMakeUndefined(ctx);
if (!webWorker->isTerminated()) {
webWorker->postMessageToOwner(msg);
}
webWorker->postMessageToOwner(msg);
return JSValueMakeUndefined(ctx);
return Value::makeUndefined(ctx);
}
/*static*/

View File

@ -28,8 +28,8 @@ static void prepare() {
TEST(Value, Undefined) {
prepare();
JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(nullptr, nullptr);
Value v(ctx, JSValueMakeUndefined(ctx));
auto s = react::String::adopt(JSValueToStringCopy(ctx, v, nullptr));
auto v = Value::makeUndefined(ctx);
auto s = String::adopt(JSValueToStringCopy(ctx, v, nullptr));
EXPECT_EQ("undefined", s.str());
JSGlobalContextRelease(ctx);
}

View File

@ -55,18 +55,16 @@ JSObjectRef makeFunction(
JSContextRef ctx,
const char* name,
JSFunction function) {
return makeFunction(ctx, JSStringCreateWithUTF8CString(name), std::move(function));
return makeFunction(ctx, String(name), std::move(function));
}
void installGlobalFunction(
JSGlobalContextRef ctx,
const char* name,
JSFunction function) {
auto jsName = JSStringCreateWithUTF8CString(name);
auto jsName = String(name);
auto functionObj = makeFunction(ctx, jsName, std::move(function));
JSObjectRef globalObject = JSContextGetGlobalObject(ctx);
JSObjectSetProperty(ctx, globalObject, jsName, functionObj, 0, NULL);
JSStringRelease(jsName);
Object::getGlobalObject(ctx).setProperty(jsName, Value(ctx, functionObj));
}
JSObjectRef makeFunction(
@ -81,12 +79,10 @@ void installGlobalFunction(
JSGlobalContextRef ctx,
const char* name,
JSObjectCallAsFunctionCallback callback) {
JSStringRef jsName = JSStringCreateWithUTF8CString(name);
String jsName(name);
JSObjectRef functionObj = JSObjectMakeFunctionWithCallback(
ctx, jsName, callback);
JSObjectRef globalObject = JSContextGetGlobalObject(ctx);
JSObjectSetProperty(ctx, globalObject, jsName, functionObj, 0, NULL);
JSStringRelease(jsName);
Object::getGlobalObject(ctx).setProperty(jsName, Value(ctx, functionObj));
}
void installGlobalProxy(
@ -96,38 +92,22 @@ void installGlobalProxy(
JSClassDefinition proxyClassDefintion = kJSClassDefinitionEmpty;
proxyClassDefintion.className = "_FBProxyClass";
proxyClassDefintion.getProperty = callback;
JSClassRef proxyClass = JSClassCreate(&proxyClassDefintion);
JSObjectRef proxyObj = JSObjectMake(ctx, proxyClass, nullptr);
JSObjectRef globalObject = JSContextGetGlobalObject(ctx);
JSStringRef jsName = JSStringCreateWithUTF8CString(name);
JSObjectSetProperty(ctx, globalObject, jsName, proxyObj, 0, NULL);
JSStringRelease(jsName);
JSClassRelease(proxyClass);
Object::getGlobalObject(ctx).setProperty(name, Value(ctx, proxyObj));
}
void removeGlobal(JSGlobalContextRef ctx, const char* name) {
JSStringRef jsName = JSStringCreateWithUTF8CString(name);
JSObjectRef globalObject = JSContextGetGlobalObject(ctx);
JSObjectSetProperty(ctx, globalObject, jsName, nullptr, 0, nullptr);
JSStringRelease(jsName);
}
JSValueRef makeJSCException(
JSContextRef ctx,
const char* exception_text) {
JSStringRef message = JSStringCreateWithUTF8CString(exception_text);
JSValueRef exceptionString = JSValueMakeString(ctx, message);
JSStringRelease(message);
return JSValueToObject(ctx, exceptionString, NULL);
Object::getGlobalObject(ctx).setProperty(name, Value::makeUndefined(ctx));
}
JSValueRef evaluateScript(JSContextRef context, JSStringRef script, JSStringRef source) {
#ifdef WITH_FBSYSTRACE
#ifdef WITH_FBSYSTRACE
fbsystrace::FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "evaluateScript");
#endif
#endif
JSValueRef exn, result;
result = JSEvaluateScript(context, script, NULL, source, 0, &exn);
if (result == nullptr) {
@ -149,7 +129,6 @@ JSValueRef evaluateSourceCode(JSContextRef context, JSSourceCodeRef source, JSSt
void formatAndThrowJSException(JSContextRef context, JSValueRef exn, JSStringRef source) {
Value exception = Value(context, exn);
std::string exceptionText = exception.toString().str();
// The null/empty-ness of source tells us if the JS came from a
@ -187,17 +166,6 @@ void formatAndThrowJSException(JSContextRef context, JSValueRef exn, JSStringRef
}
}
JSValueRef makeJSError(JSContextRef ctx, const char *error) {
JSValueRef nestedException = nullptr;
JSValueRef args[] = { Value(ctx, String(error)) };
JSObjectRef errorObj = JSObjectMakeError(ctx, 1, args, &nestedException);
if (nestedException != nullptr) {
return std::move(args[0]);
}
return errorObj;
}
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, const char *exceptionLocation) {
std::ostringstream msg;
try {
@ -206,13 +174,13 @@ JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, const char *e
throw; // We probably shouldn't try to handle this in JS
} catch (const std::exception& ex) {
msg << "C++ Exception in '" << exceptionLocation << "': " << ex.what();
return makeJSError(ctx, msg.str().c_str());
return Value::makeError(ctx, msg.str().c_str());
} catch (const char* ex) {
msg << "C++ Exception (thrown as a char*) in '" << exceptionLocation << "': " << ex;
return makeJSError(ctx, msg.str().c_str());
return Value::makeError(ctx, msg.str().c_str());
} catch (...) {
msg << "Unknown C++ Exception in '" << exceptionLocation << "'";
return makeJSError(ctx, msg.str().c_str());
return Value::makeError(ctx, msg.str().c_str());
}
}
@ -221,7 +189,7 @@ JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, JSObjectRef j
auto functionName = Object(ctx, jsFunctionCause).getProperty("name").toString().str();
return translatePendingCppExceptionToJSError(ctx, functionName.c_str());
} catch (...) {
return makeJSError(ctx, "Failed to get function name while handling exception");
return Value::makeError(ctx, "Failed to get function name while handling exception");
}
}

View File

@ -62,10 +62,6 @@ void installGlobalProxy(
void removeGlobal(JSGlobalContextRef ctx, const char* name);
JSValueRef makeJSCException(
JSContextRef ctx,
const char* exception_text);
JSValueRef evaluateScript(
JSContextRef ctx,
JSStringRef script,
@ -83,8 +79,6 @@ void formatAndThrowJSException(
JSValueRef exn,
JSStringRef sourceURL);
JSValueRef makeJSError(JSContextRef ctx, const char *error);
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, const char *exceptionLocation);
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, JSObjectRef jsFunctionCause);

View File

@ -144,6 +144,18 @@ Object Value::asObject() {
return ret;
}
Value Value::makeError(JSContextRef ctx, const char *error)
{
JSValueRef exn;
JSValueRef args[] = { Value(ctx, String(error)) };
JSObjectRef errorObj = JSObjectMakeError(ctx, 1, args, &exn);
if (!errorObj) {
std::string exceptionText = Value(ctx, exn).toString().str();
throwJSExecutionException("Exception calling object as function: %s", exceptionText.c_str());
}
return Value(ctx, errorObj);
}
Object::operator Value() const {
return Value(m_context, m_obj);
}
@ -153,7 +165,7 @@ Value Object::callAsFunction(std::initializer_list<JSValueRef> args) const {
}
Value Object::callAsFunction(const Object& thisObj, std::initializer_list<JSValueRef> args) const {
return callAsFunction((JSObjectRef) thisObj, args.size(), args.begin());
return callAsFunction((JSObjectRef)thisObj, args.size(), args.begin());
}
Value Object::callAsFunction(int nArgs, const JSValueRef args[]) const {
@ -161,7 +173,7 @@ Value Object::callAsFunction(int nArgs, const JSValueRef args[]) const {
}
Value Object::callAsFunction(const Object& thisObj, int nArgs, const JSValueRef args[]) const {
return callAsFunction((JSObjectRef) thisObj, nArgs, args);
return callAsFunction(static_cast<JSObjectRef>(thisObj), nArgs, args);
}
Value Object::callAsFunction(JSObjectRef thisObj, int nArgs, const JSValueRef args[]) const {

View File

@ -208,6 +208,10 @@ public:
return static_cast<ReturnType*>(JSObjectGetPrivate(m_obj));
}
void setPrivate(void* data) const {
JSObjectSetPrivate(m_obj, data);
}
JSContextRef context() const {
return m_context;
}
@ -294,6 +298,16 @@ public:
return String::adopt(JSValueToStringCopy(context(), m_value, nullptr));
}
static Value makeError(JSContextRef ctx, const char *error);
static Value makeNumber(JSContextRef ctx, double value) {
return Value(ctx, JSValueMakeNumber(ctx, value));
}
static Value makeUndefined(JSContextRef ctx) {
return Value(ctx, JSValueMakeUndefined(ctx));
}
std::string toJSONString(unsigned indent = 0) const;
static Value fromJSON(JSContextRef ctx, const String& json);
static JSValueRef fromDynamic(JSContextRef ctx, const folly::dynamic& value);