Skip to content

Commit

Permalink
Allow creating JS functions from std::function
Browse files Browse the repository at this point in the history
Reviewed By: mhorowitz

Differential Revision: D4043376

fbshipit-source-id: 65b4f025835dbae34e764015743c2616d9eb9379
  • Loading branch information
lexs authored and Facebook Github Bot committed Nov 1, 2016
1 parent ddb8cb7 commit a0c550d
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
62 changes: 62 additions & 0 deletions ReactCommon/jschelpers/JSCHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,68 @@
namespace facebook {
namespace react {

namespace {

JSValueRef functionCaller(
JSContextRef ctx,
JSObjectRef function,
JSObjectRef thisObject,
size_t argumentCount,
const JSValueRef arguments[],
JSValueRef* exception) {
auto* f = static_cast<JSFunction*>(JSObjectGetPrivate(function));
return (*f)(ctx, thisObject, argumentCount, arguments);
}

JSClassRef createFuncClass() {
auto definition = kJSClassDefinitionEmpty;
definition.finalize = [](JSObjectRef object) {
auto* function = static_cast<JSFunction*>(JSObjectGetPrivate(object));
delete function;
};
definition.callAsFunction = exceptionWrapMethod<&functionCaller>();

return JSClassCreate(&definition);
}

JSObjectRef makeFunction(
JSContextRef ctx,
JSStringRef name,
JSFunction function) {
static auto kClassDef = createFuncClass();
auto functionObject = Object(ctx, JSObjectMake(ctx, kClassDef, new JSFunction(std::move(function))));
functionObject.setProperty("name", Value(ctx, name));
return functionObject;
}

}

JSObjectRef makeFunction(
JSContextRef ctx,
const char* name,
JSFunction function) {
return makeFunction(ctx, JSStringCreateWithUTF8CString(name), std::move(function));
}

void installGlobalFunction(
JSGlobalContextRef ctx,
const char* name,
JSFunction function) {
auto jsName = JSStringCreateWithUTF8CString(name);
auto functionObj = makeFunction(ctx, jsName, std::move(function));
JSObjectRef globalObject = JSContextGetGlobalObject(ctx);
JSObjectSetProperty(ctx, globalObject, jsName, functionObj, 0, NULL);
JSStringRelease(jsName);
}

JSObjectRef makeFunction(
JSGlobalContextRef ctx,
const char* name,
JSObjectCallAsFunctionCallback callback) {
auto jsName = String(name);
return JSObjectMakeFunctionWithCallback(ctx, jsName, callback);
}

void installGlobalFunction(
JSGlobalContextRef ctx,
const char* name,
Expand Down
18 changes: 18 additions & 0 deletions ReactCommon/jschelpers/JSCHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <stdexcept>
#include <algorithm>
#include <functional>

namespace facebook {
namespace react {
Expand All @@ -32,6 +33,23 @@ inline void throwJSExecutionExceptionWithStack(const char* msg, const char* stac
throw JSException(msg, stack);
}

using JSFunction = std::function<JSValueRef(JSContextRef, JSObjectRef, size_t, const JSValueRef[])>;

JSObjectRef makeFunction(
JSContextRef ctx,
const char* name,
JSFunction function);

void installGlobalFunction(
JSGlobalContextRef ctx,
const char* name,
JSFunction function);

JSObjectRef makeFunction(
JSGlobalContextRef ctx,
const char* name,
JSObjectCallAsFunctionCallback callback);

void installGlobalFunction(
JSGlobalContextRef ctx,
const char* name,
Expand Down

0 comments on commit a0c550d

Please sign in to comment.