evaluateJson method
Evaluate js script and decode the result via a single JSON.stringify
round-trip instead of recursive per-element FFI marshaling.
This is dramatically faster for large arrays/objects, but the result must
be JSON-serializable: functions, Promises and cyclic references are not
supported (they decode to null / are dropped, as with JSON.stringify).
Implementation
@override
dynamic evaluateJson(String command, {String? sourceUrl}) {
_ensureEngine();
final ctx = _ctx!;
final jsval = jsEval(
ctx,
command,
sourceUrl ?? '<eval>',
JSEvalFlag.GLOBAL,
);
if (jsIsException(jsval) != 0) {
jsFreeValue(ctx, jsval);
throw _parseJSException(ctx);
}
final fnStringify = _jsonStringifyFn ??= jsEval(
ctx,
'JSON.stringify',
'<json>',
JSEvalFlag.GLOBAL,
);
final thisObj = jsUNDEFINED();
final jsonVal = jsCall(ctx, fnStringify, thisObj, [jsval]);
jsFreeValue(ctx, thisObj);
jsFreeValue(ctx, jsval);
if (jsIsException(jsonVal) != 0) {
jsFreeValue(ctx, jsonVal);
throw _parseJSException(ctx);
}
if (jsValueGetTag(jsonVal) != JSTag.STRING) {
jsFreeValue(ctx, jsonVal);
return null;
}
final jsonStr = jsToCString(ctx, jsonVal);
jsFreeValue(ctx, jsonVal);
_maybeDrainJobs();
return jsonDecode(jsonStr);
}