mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-01 09:23:16 +08:00
Better folly::dynamic ==> JSValue conversion
Reviewed By: lexs Differential Revision: D3347854 fbshipit-source-id: 95b81152d1b0d5fe41e01991c44f5d1110be7ddb
This commit is contained in:
committed by
Facebook Github Bot 0
parent
e1b3bbdb04
commit
654e4bed2e
@@ -6,6 +6,9 @@
|
||||
|
||||
#include "JSCHelpers.h"
|
||||
|
||||
// See the comment under Value::fromDynamic()
|
||||
#define USE_FAST_FOLLY_DYNAMIC_CONVERSION !defined(__APPLE__) && defined(WITH_FB_JSC_TUNING)
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
@@ -51,9 +54,78 @@ Value Value::fromJSON(JSContextRef ctx, const String& json) throw(JSException) {
|
||||
return Value(ctx, result);
|
||||
}
|
||||
|
||||
Value Value::fromDynamic(JSContextRef ctx, folly::dynamic value) throw(JSException) {
|
||||
JSValueRef Value::fromDynamic(JSContextRef ctx, const folly::dynamic& value) {
|
||||
// JavaScriptCore's iOS APIs have their own version of this direct conversion.
|
||||
// In addition, using this requires exposing some of JSC's private APIs,
|
||||
// so it's limited to non-apple platforms and to builds that use the custom JSC.
|
||||
// Otherwise, we use the old way of converting through JSON.
|
||||
#if USE_FAST_FOLLY_DYNAMIC_CONVERSION
|
||||
// Defer GC during the creation of the JSValue, as we don't want
|
||||
// intermediate objects to be collected.
|
||||
// We could use JSValueProtect(), but it will make the process much slower.
|
||||
JSDeferredGCRef deferGC = JSDeferGarbageCollection(ctx);
|
||||
// Set a global lock for the whole process,
|
||||
// instead of re-acquiring the lock for each operation.
|
||||
JSLock(ctx);
|
||||
JSValueRef jsVal = Value::fromDynamicInner(ctx, value);
|
||||
JSUnlock(ctx);
|
||||
JSResumeGarbageCollection(ctx, deferGC);
|
||||
return jsVal;
|
||||
#else
|
||||
auto json = folly::toJson(value);
|
||||
return fromJSON(ctx, String(json.c_str()));
|
||||
#endif
|
||||
}
|
||||
|
||||
JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj) {
|
||||
switch (obj.type()) {
|
||||
// For premitive types (and strings), just create and return an equivalent JSValue
|
||||
case folly::dynamic::Type::NULLT:
|
||||
return JSValueMakeNull(ctx);
|
||||
|
||||
case folly::dynamic::Type::BOOL:
|
||||
return JSValueMakeBoolean(ctx, obj.getBool());
|
||||
|
||||
case folly::dynamic::Type::DOUBLE:
|
||||
return JSValueMakeNumber(ctx, obj.getDouble());
|
||||
|
||||
case folly::dynamic::Type::INT64:
|
||||
return JSValueMakeNumber(ctx, obj.asDouble());
|
||||
|
||||
case folly::dynamic::Type::STRING:
|
||||
return JSValueMakeString(ctx, String(obj.getString().c_str()));
|
||||
|
||||
case folly::dynamic::Type::ARRAY: {
|
||||
// Collect JSValue for every element in the array
|
||||
JSValueRef vals[obj.size()];
|
||||
for (size_t i = 0; i < obj.size(); ++i) {
|
||||
vals[i] = fromDynamicInner(ctx, obj[i]);
|
||||
}
|
||||
// Create a JSArray with the values
|
||||
JSValueRef arr = JSObjectMakeArray(ctx, obj.size(), vals, nullptr);
|
||||
return arr;
|
||||
}
|
||||
|
||||
case folly::dynamic::Type::OBJECT: {
|
||||
// Create an empty object
|
||||
JSObjectRef jsObj = JSObjectMake(ctx, nullptr, nullptr);
|
||||
// Create a JSValue for each of the object's children and set them in the object
|
||||
for (auto it = obj.items().begin(); it != obj.items().end(); ++it) {
|
||||
JSObjectSetProperty(
|
||||
ctx,
|
||||
jsObj,
|
||||
String(it->first.asString().c_str()),
|
||||
fromDynamicInner(ctx, it->second),
|
||||
kJSPropertyAttributeNone,
|
||||
nullptr);
|
||||
}
|
||||
return jsObj;
|
||||
}
|
||||
default:
|
||||
// Assert not reached
|
||||
LOG(FATAL) << "Trying to convert a folly object of unsupported type.";
|
||||
return JSValueMakeNull(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
Object Value::asObject() {
|
||||
|
||||
Reference in New Issue
Block a user