This commit is contained in:
ekibun
2021-02-22 13:07:53 +08:00
parent 7fe4f5e431
commit 8fb26b20af
12 changed files with 385 additions and 362 deletions

View File

@@ -20,7 +20,6 @@ jobs:
- name: Flutter action - name: Flutter action
uses: subosito/flutter-action@v1 uses: subosito/flutter-action@v1
with: with:
channel: "stable" channel: beta
flutter-version: "1.22.4"
- run: flutter pub get - run: flutter pub get
- run: flutter test test/flutter_qjs_test.dart - run: flutter test test/flutter_qjs_test.dart

View File

@@ -6,6 +6,10 @@
* @LastEditTime: 2020-12-02 11:36:40 * @LastEditTime: 2020-12-02 11:36:40
--> -->
## 0.3.4
* upgrade ffi to 1.0.0.
## 0.3.3 ## 0.3.3
* remove `JSInvokable.call`. * remove `JSInvokable.call`.

View File

@@ -58,7 +58,7 @@ class CodeInputController extends TextEditingController {
String oldText = oldSpan.toPlainText(); String oldText = oldSpan.toPlainText();
String newText = value.text; String newText = value.text;
if (oldText == newText) return oldSpan; if (oldText == newText) return oldSpan;
(spanCall?.timeout(Duration.zero) ?? Future.delayed(Duration.zero)) (spanCall?.timeout(Duration.zero) ?? Future.value())
.then((_) => spanCall = compute(_convert, value.text).then((lsSpan) { .then((_) => spanCall = compute(_convert, value.text).then((lsSpan) {
TextSpan newSpan = TextSpan(style: style, children: lsSpan); TextSpan newSpan = TextSpan(style: style, children: lsSpan);
if (newSpan.toPlainText() == value.text) oldSpan = newSpan; if (newSpan.toPlainText() == value.text) oldSpan = newSpan;

View File

@@ -53,7 +53,6 @@ class _TestPageState extends State<TestPage> {
if (engine != null) return; if (engine != null) return;
engine = IsolateQjs( engine = IsolateQjs(
moduleHandler: (String module) async { moduleHandler: (String module) async {
if (module == "test") return "export default '${new DateTime.now()}'";
return await rootBundle.loadString( return await rootBundle.loadString(
"js/" + module.replaceFirst(new RegExp(r".js$"), "") + ".js"); "js/" + module.replaceFirst(new RegExp(r".js$"), "") + ".js");
}, },

View File

@@ -7,56 +7,56 @@ packages:
name: async name: async
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.5.0-nullsafety.3" version: "2.5.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0-nullsafety.3" version: "2.1.0"
characters: characters:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0-nullsafety.5" version: "1.1.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0-nullsafety.3" version: "1.2.0"
clock: clock:
dependency: transitive dependency: transitive
description: description:
name: clock name: clock
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0-nullsafety.3" version: "1.1.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.15.0-nullsafety.5" version: "1.15.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0-nullsafety.3" version: "1.2.0"
ffi: ffi:
dependency: transitive dependency: transitive
description: description:
name: ffi name: ffi
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.1.3" version: "1.0.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@@ -75,7 +75,7 @@ packages:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "0.3.3" version: "0.3.4"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@@ -94,21 +94,21 @@ packages:
name: matcher name: matcher
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.12.10-nullsafety.3" version: "0.12.10"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.3.0-nullsafety.6" version: "1.3.0"
path: path:
dependency: transitive dependency: transitive
description: description:
name: path name: path
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.0-nullsafety.3" version: "1.8.0"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@@ -120,56 +120,56 @@ packages:
name: source_span name: source_span
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.0-nullsafety.4" version: "1.8.1"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.10.0-nullsafety.6" version: "1.10.0"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0-nullsafety.3" version: "2.1.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0-nullsafety.3" version: "1.1.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0-nullsafety.3" version: "1.2.0"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.2.19-nullsafety.6" version: "0.2.19"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.3.0-nullsafety.5" version: "1.3.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0-nullsafety.5" version: "2.1.0"
sdks: sdks:
dart: ">=2.12.0-0.0 <3.0.0" dart: ">=2.12.0-259.9.beta <3.0.0"
flutter: ">=1.20.0 <2.0.0" flutter: ">=1.20.0"

View File

@@ -15,8 +15,8 @@ typedef _JsHostPromiseRejectionHandler = void Function(dynamic reason);
/// Quickjs engine for flutter. /// Quickjs engine for flutter.
class FlutterQjs { class FlutterQjs {
Pointer _rt; Pointer<JSRuntime> _rt;
Pointer _ctx; Pointer<JSContext> _ctx;
/// Max stack size for quickjs. /// Max stack size for quickjs.
final int stackSize; final int stackSize;
@@ -42,10 +42,10 @@ class FlutterQjs {
try { try {
switch (type) { switch (type) {
case JSChannelType.METHON: case JSChannelType.METHON:
final pdata = ptr.cast<Pointer>(); final pdata = ptr.cast<Pointer<JSValue>>();
final argc = pdata.elementAt(1).value.cast<Int32>().value; final argc = pdata.elementAt(1).value.cast<Int32>().value;
List pargs = []; final pargs = [];
for (int i = 0; i < argc; ++i) { for (var i = 0; i < argc; ++i) {
pargs.add(_jsToDart( pargs.add(_jsToDart(
ctx, ctx,
Pointer.fromAddress( Pointer.fromAddress(
@@ -53,7 +53,10 @@ class FlutterQjs {
), ),
)); ));
} }
JSInvokable func = _jsToDart(ctx, pdata.elementAt(3).value); final JSInvokable func = _jsToDart(
ctx,
pdata.elementAt(3).value,
);
return _dartToJs( return _dartToJs(
ctx, ctx,
func.invoke( func.invoke(
@@ -68,7 +71,7 @@ class FlutterQjs {
Future.microtask(() { Future.microtask(() {
malloc.free(ret); malloc.free(ret);
}); });
return ret; return ret.cast();
case JSChannelType.PROMISE_TRACK: case JSChannelType.PROMISE_TRACK:
final err = _parseJSException(ctx, ptr); final err = _parseJSException(ctx, ptr);
if (hostPromiseRejectionHandler != null) { if (hostPromiseRejectionHandler != null) {
@@ -76,29 +79,29 @@ class FlutterQjs {
} else { } else {
print('unhandled promise rejection: $err'); print('unhandled promise rejection: $err');
} }
return Pointer.fromAddress(0); return nullptr;
case JSChannelType.FREE_OBJECT: case JSChannelType.FREE_OBJECT:
Pointer rt = ctx; final rt = ctx.cast<JSRuntime>();
_DartObject obj = _DartObject.fromAddress(rt, ptr.address); _DartObject obj = _DartObject.fromAddress(rt, ptr.address);
obj?.free(); obj?.free();
return Pointer.fromAddress(0); return nullptr;
} }
throw JSError('call channel with wrong type'); throw JSError('call channel with wrong type');
} catch (e) { } catch (e) {
if (type == JSChannelType.FREE_OBJECT) { if (type == JSChannelType.FREE_OBJECT) {
print('DartObject release error: $e'); print('DartObject release error: $e');
return Pointer.fromAddress(0); return nullptr;
} }
if (type == JSChannelType.MODULE) { if (type == JSChannelType.MODULE) {
print('host Promise Rejection Handler error: $e'); print('host Promise Rejection Handler error: $e');
return Pointer.fromAddress(0); return nullptr;
} }
final throwObj = _dartToJs(ctx, e); final throwObj = _dartToJs(ctx, e);
final err = jsThrow(ctx, throwObj); final err = jsThrow(ctx, throwObj);
jsFreeValue(ctx, throwObj); jsFreeValue(ctx, throwObj);
if (type == JSChannelType.MODULE) { if (type == JSChannelType.MODULE) {
jsFreeValue(ctx, err); jsFreeValue(ctx, err);
return Pointer.fromAddress(0); return nullptr;
} }
return err; return err;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -115,21 +115,19 @@ void _runJsIsolate(Map spawnMessage) async {
}, },
moduleHandler: (name) { moduleHandler: (name) {
final ptr = calloc<Pointer<Utf8>>(); final ptr = calloc<Pointer<Utf8>>();
ptr.value = Pointer.fromAddress(0); ptr.value = Pointer.fromAddress(ptr.address);
sendPort.send({ sendPort.send({
#type: #module, #type: #module,
#name: name, #name: name,
#ptr: ptr.address, #ptr: ptr.address,
}); });
while (ptr.value.address == 0) sleep(Duration.zero); while (ptr.value.address == ptr.address) sleep(Duration(microseconds: 1));
if (ptr.value.address == -1) throw JSError('Module Not found'); final ret = ptr.value;
final ret = ptr.value.toDartString();
sendPort.send({
#type: #release,
#ptr: ptr.value.address,
});
malloc.free(ptr); malloc.free(ptr);
return ret; if (ret.address == -1) throw JSError('Module Not found');
final retString = ret.toDartString();
malloc.free(ret);
return retString;
}, },
); );
port.listen((msg) async { port.listen((msg) async {
@@ -225,9 +223,6 @@ class IsolateQjs {
ptr.value = Pointer.fromAddress(-1); ptr.value = Pointer.fromAddress(-1);
} }
break; break;
case #release:
malloc.free(Pointer.fromAddress(msg[#ptr]));
break;
} }
}, onDone: () { }, onDone: () {
close(); close();

View File

@@ -49,7 +49,7 @@ class _DartFunction extends JSInvokable {
class _DartObject extends JSRef implements JSRefLeakable { class _DartObject extends JSRef implements JSRefLeakable {
Object _obj; Object _obj;
Pointer _ctx; Pointer<JSContext> _ctx;
_DartObject(this._ctx, this._obj) { _DartObject(this._ctx, this._obj) {
if (_obj is JSRef) { if (_obj is JSRef) {
(_obj as JSRef).dup(); (_obj as JSRef).dup();
@@ -57,7 +57,7 @@ class _DartObject extends JSRef implements JSRefLeakable {
runtimeOpaques[jsGetRuntime(_ctx)]?.addRef(this); runtimeOpaques[jsGetRuntime(_ctx)]?.addRef(this);
} }
static _DartObject fromAddress(Pointer rt, int val) { static _DartObject fromAddress(Pointer<JSRuntime> rt, int val) {
return runtimeOpaques[rt]?.getRef((e) => identityHashCode(e) == val); return runtimeOpaques[rt]?.getRef((e) => identityHashCode(e) == val);
} }
@@ -116,12 +116,12 @@ class JSError extends _IsolateEncodable {
/// JS Object reference /// JS Object reference
/// call [release] to release js object. /// call [release] to release js object.
class _JSObject extends JSRef { class _JSObject extends JSRef {
Pointer _val; Pointer<JSValue> _val;
Pointer _ctx; Pointer<JSContext> _ctx;
/// Create /// Create
_JSObject(this._ctx, Pointer _val) { _JSObject(this._ctx, Pointer<JSValue> _val) {
Pointer rt = jsGetRuntime(_ctx); final rt = jsGetRuntime(_ctx);
this._val = jsDupValue(_ctx, _val); this._val = jsDupValue(_ctx, _val);
runtimeOpaques[rt]?.addRef(this); runtimeOpaques[rt]?.addRef(this);
} }
@@ -129,7 +129,7 @@ class _JSObject extends JSRef {
@override @override
void destroy() { void destroy() {
if (_val == null) return; if (_val == null) return;
Pointer rt = jsGetRuntime(_ctx); final rt = jsGetRuntime(_ctx);
runtimeOpaques[rt]?.removeRef(this); runtimeOpaques[rt]?.removeRef(this);
jsFreeValue(_ctx, _val); jsFreeValue(_ctx, _val);
_val = null; _val = null;
@@ -145,11 +145,11 @@ class _JSObject extends JSRef {
/// JS function wrapper /// JS function wrapper
class _JSFunction extends _JSObject implements JSInvokable, _IsolateEncodable { class _JSFunction extends _JSObject implements JSInvokable, _IsolateEncodable {
_JSFunction(Pointer ctx, Pointer val) : super(ctx, val); _JSFunction(Pointer<JSContext> ctx, Pointer<JSValue> val) : super(ctx, val);
@override @override
invoke(List<dynamic> arguments, [dynamic thisVal]) { invoke(List<dynamic> arguments, [dynamic thisVal]) {
Pointer jsRet = _invoke(arguments, thisVal); final jsRet = _invoke(arguments, thisVal);
if (jsRet == null) return; if (jsRet == null) return;
bool isException = jsIsException(jsRet) != 0; bool isException = jsIsException(jsRet) != 0;
if (isException) { if (isException) {
@@ -161,17 +161,17 @@ class _JSFunction extends _JSObject implements JSInvokable, _IsolateEncodable {
return ret; return ret;
} }
Pointer _invoke(List<dynamic> arguments, [dynamic thisVal]) { Pointer<JSValue> _invoke(List<dynamic> arguments, [dynamic thisVal]) {
if (_val == null) throw JSError("InternalError: JSValue released"); if (_val == null) throw JSError("InternalError: JSValue released");
List<Pointer> args = arguments final args = arguments
.map( .map(
(e) => _dartToJs(_ctx, e), (e) => _dartToJs(_ctx, e),
) )
.toList(); .toList();
Pointer jsThis = _dartToJs(_ctx, thisVal); final jsThis = _dartToJs(_ctx, thisVal);
Pointer jsRet = jsCall(_ctx, _val, jsThis, args); final jsRet = jsCall(_ctx, _val, jsThis, args);
jsFreeValue(_ctx, jsThis); jsFreeValue(_ctx, jsThis);
for (Pointer jsArg in args) { for (final jsArg in args) {
jsFreeValue(_ctx, jsArg); jsFreeValue(_ctx, jsArg);
} }
return jsRet; return jsRet;
@@ -255,15 +255,15 @@ class IsolateFunction extends JSInvokable implements _IsolateEncodable {
_destroy(); _destroy();
return null; return null;
} }
List args = _decodeData(msg[#args]); final List args = _decodeData(msg[#args]);
Map thisVal = _decodeData(msg[#thisVal]); final thisVal = _decodeData(msg[#thisVal]);
return _invokable.invoke(args, thisVal); return _invokable.invoke(args, thisVal);
} }
@override @override
Future invoke(List positionalArguments, [thisVal]) async { Future invoke(List positionalArguments, [thisVal]) async {
List dArgs = _encodeData(positionalArguments); final List dArgs = _encodeData(positionalArguments);
Map dThisVal = _encodeData(thisVal); final dThisVal = _encodeData(thisVal);
return _send({ return _send({
#args: dArgs, #args: dArgs,
#thisVal: dThisVal, #thisVal: dThisVal,

View File

@@ -7,7 +7,7 @@
*/ */
part of '../flutter_qjs.dart'; part of '../flutter_qjs.dart';
dynamic _parseJSException(Pointer ctx, [Pointer perr]) { dynamic _parseJSException(Pointer<JSContext> ctx, [Pointer<JSValue> perr]) {
final e = perr ?? jsGetException(ctx); final e = perr ?? jsGetException(ctx);
var err; var err;
try { try {
@@ -20,11 +20,11 @@ dynamic _parseJSException(Pointer ctx, [Pointer perr]) {
} }
void _definePropertyValue( void _definePropertyValue(
Pointer ctx, Pointer<JSContext> ctx,
Pointer obj, Pointer<JSValue> obj,
dynamic key, dynamic key,
dynamic val, { dynamic val, {
Map<dynamic, dynamic> cache, Map<dynamic, Pointer<JSValue>> cache,
}) { }) {
final jsAtomVal = _dartToJs(ctx, key, cache: cache); final jsAtomVal = _dartToJs(ctx, key, cache: cache);
final jsAtom = jsValueToAtom(ctx, jsAtomVal); final jsAtom = jsValueToAtom(ctx, jsAtomVal);
@@ -39,9 +39,9 @@ void _definePropertyValue(
jsFreeValue(ctx, jsAtomVal); jsFreeValue(ctx, jsAtomVal);
} }
Pointer _jsGetPropertyValue( Pointer<JSValue> _jsGetPropertyValue(
Pointer ctx, Pointer<JSContext> ctx,
Pointer obj, Pointer<JSValue> obj,
dynamic key, { dynamic key, {
Map<dynamic, dynamic> cache, Map<dynamic, dynamic> cache,
}) { }) {
@@ -53,7 +53,8 @@ Pointer _jsGetPropertyValue(
return jsProp; return jsProp;
} }
Pointer _dartToJs(Pointer ctx, dynamic val, {Map<dynamic, dynamic> cache}) { Pointer<JSValue> _dartToJs(Pointer<JSContext> ctx, dynamic val,
{Map<dynamic, Pointer<JSValue>> cache}) {
if (val == null) return jsUNDEFINED(); if (val == null) return jsUNDEFINED();
if (val is Error) return _dartToJs(ctx, JSError(val, val.stackTrace)); if (val is Error) return _dartToJs(ctx, JSError(val, val.stackTrace));
if (val is Exception) return _dartToJs(ctx, JSError(val)); if (val is Exception) return _dartToJs(ctx, JSError(val));
@@ -66,17 +67,17 @@ Pointer _dartToJs(Pointer ctx, dynamic val, {Map<dynamic, dynamic> cache}) {
} }
if (val is _JSObject) return jsDupValue(ctx, val._val); if (val is _JSObject) return jsDupValue(ctx, val._val);
if (val is Future) { if (val is Future) {
final resolvingFunc = malloc<Uint8>(sizeOfJSValue * 2); final resolvingFunc = malloc<Uint8>(sizeOfJSValue * 2).cast<JSValue>();
final resolvingFunc2 = final resolvingFunc2 =
Pointer.fromAddress(resolvingFunc.address + sizeOfJSValue); Pointer<JSValue>.fromAddress(resolvingFunc.address + sizeOfJSValue);
final ret = jsNewPromiseCapability(ctx, resolvingFunc); final ret = jsNewPromiseCapability(ctx, resolvingFunc);
_JSFunction res = _jsToDart(ctx, resolvingFunc); final _JSFunction res = _jsToDart(ctx, resolvingFunc);
_JSFunction rej = _jsToDart(ctx, resolvingFunc2); final _JSFunction rej = _jsToDart(ctx, resolvingFunc2);
jsFreeValue(ctx, resolvingFunc, free: false); jsFreeValue(ctx, resolvingFunc, free: false);
jsFreeValue(ctx, resolvingFunc2, free: false); jsFreeValue(ctx, resolvingFunc2, free: false);
malloc.free(resolvingFunc); malloc.free(resolvingFunc);
_DartObject refRes = _DartObject(ctx, res); final refRes = _DartObject(ctx, res);
_DartObject refRej = _DartObject(ctx, rej); final refRej = _DartObject(ctx, rej);
res.free(); res.free();
rej.free(); rej.free();
val.then((value) { val.then((value) {
@@ -106,7 +107,7 @@ Pointer _dartToJs(Pointer ctx, dynamic val, {Map<dynamic, dynamic> cache}) {
return jsDupValue(ctx, cache[val]); return jsDupValue(ctx, cache[val]);
} }
if (val is List) { if (val is List) {
Pointer ret = jsNewArray(ctx); final ret = jsNewArray(ctx);
cache[val] = ret; cache[val] = ret;
for (int i = 0; i < val.length; ++i) { for (int i = 0; i < val.length; ++i) {
_definePropertyValue(ctx, ret, i, val[i], cache: cache); _definePropertyValue(ctx, ret, i, val[i], cache: cache);
@@ -114,7 +115,7 @@ Pointer _dartToJs(Pointer ctx, dynamic val, {Map<dynamic, dynamic> cache}) {
return ret; return ret;
} }
if (val is Map) { if (val is Map) {
Pointer ret = jsNewObject(ctx); final ret = jsNewObject(ctx);
cache[val] = ret; cache[val] = ret;
for (MapEntry<dynamic, dynamic> entry in val.entries) { for (MapEntry<dynamic, dynamic> entry in val.entries) {
_definePropertyValue(ctx, ret, entry.key, entry.value, cache: cache); _definePropertyValue(ctx, ret, entry.key, entry.value, cache: cache);
@@ -123,7 +124,7 @@ Pointer _dartToJs(Pointer ctx, dynamic val, {Map<dynamic, dynamic> cache}) {
} }
// wrap Function to JSInvokable // wrap Function to JSInvokable
final valWrap = JSInvokable._wrap(val); final valWrap = JSInvokable._wrap(val);
int dartObjectClassId = final dartObjectClassId =
runtimeOpaques[jsGetRuntime(ctx)]?.dartObjectClassId ?? 0; runtimeOpaques[jsGetRuntime(ctx)]?.dartObjectClassId ?? 0;
if (dartObjectClassId == 0) return jsUNDEFINED(); if (dartObjectClassId == 0) return jsUNDEFINED();
final dartObject = jsNewObjectClass( final dartObject = jsNewObjectClass(
@@ -139,9 +140,10 @@ Pointer _dartToJs(Pointer ctx, dynamic val, {Map<dynamic, dynamic> cache}) {
return dartObject; return dartObject;
} }
dynamic _jsToDart(Pointer ctx, Pointer val, {Map<int, dynamic> cache}) { dynamic _jsToDart(Pointer<JSContext> ctx, Pointer<JSValue> val,
{Map<int, dynamic> cache}) {
if (cache == null) cache = Map(); if (cache == null) cache = Map();
int tag = jsValueGetTag(val); final tag = jsValueGetTag(val);
if (jsTagIsFloat64(tag) != 0) { if (jsTagIsFloat64(tag) != 0) {
return jsToFloat64(ctx, val); return jsToFloat64(ctx, val);
} }
@@ -160,14 +162,14 @@ dynamic _jsToDart(Pointer ctx, Pointer val, {Map<int, dynamic> cache}) {
rt, jsGetObjectOpaque(val, dartObjectClassId)); rt, jsGetObjectOpaque(val, dartObjectClassId));
if (dartObject != null) return dartObject._obj; if (dartObject != null) return dartObject._obj;
} }
Pointer<IntPtr> psize = malloc<IntPtr>(); final psize = malloc<IntPtr>();
Pointer<Uint8> buf = jsGetArrayBuffer(ctx, psize, val); final buf = jsGetArrayBuffer(ctx, psize, val);
int size = psize.value; final size = psize.value;
malloc.free(psize); malloc.free(psize);
if (buf.address != 0) { if (buf.address != 0) {
return Uint8List.fromList(buf.asTypedList(size)); return Uint8List.fromList(buf.asTypedList(size));
} }
int valptr = jsValueGetPtr(val).address; final valptr = jsValueGetPtr(val);
if (cache.containsKey(valptr)) { if (cache.containsKey(valptr)) {
return cache[valptr]; return cache[valptr];
} }
@@ -181,8 +183,9 @@ dynamic _jsToDart(Pointer ctx, Pointer val, {Map<int, dynamic> cache}) {
jsFreeValue(ctx, pstack); jsFreeValue(ctx, pstack);
return JSError(err, stack); return JSError(err, stack);
} else if (jsIsPromise(ctx, val) != 0) { } else if (jsIsPromise(ctx, val) != 0) {
Pointer jsPromiseThen = _jsGetPropertyValue(ctx, val, 'then'); final jsPromiseThen = _jsGetPropertyValue(ctx, val, 'then');
_JSFunction promiseThen = _jsToDart(ctx, jsPromiseThen, cache: cache); final _JSFunction promiseThen =
_jsToDart(ctx, jsPromiseThen, cache: cache);
jsFreeValue(ctx, jsPromiseThen); jsFreeValue(ctx, jsPromiseThen);
final completer = Completer(); final completer = Completer();
completer.future.catchError((e) {}); completer.future.catchError((e) {});
@@ -199,30 +202,34 @@ dynamic _jsToDart(Pointer ctx, Pointer val, {Map<int, dynamic> cache}) {
], jsPromise); ], jsPromise);
jsPromise.free(); jsPromise.free();
promiseThen.free(); promiseThen.free();
bool isException = jsIsException(jsRet) != 0; final isException = jsIsException(jsRet) != 0;
jsFreeValue(ctx, jsRet); jsFreeValue(ctx, jsRet);
if (isException) throw _parseJSException(ctx); if (isException) throw _parseJSException(ctx);
return completer.future; return completer.future;
} else if (jsIsArray(ctx, val) != 0) { } else if (jsIsArray(ctx, val) != 0) {
Pointer jslength = _jsGetPropertyValue(ctx, val, 'length'); final jslength = _jsGetPropertyValue(ctx, val, 'length');
int length = jsToInt64(ctx, jslength); final length = jsToInt64(ctx, jslength);
List<dynamic> ret = []; final ret = [];
cache[valptr] = ret; cache[valptr] = ret;
for (int i = 0; i < length; ++i) { for (var i = 0; i < length; ++i) {
final jsProp = _jsGetPropertyValue(ctx, val, i); final jsProp = _jsGetPropertyValue(ctx, val, i);
ret.add(_jsToDart(ctx, jsProp, cache: cache)); ret.add(_jsToDart(ctx, jsProp, cache: cache));
jsFreeValue(ctx, jsProp); jsFreeValue(ctx, jsProp);
} }
return ret; return ret;
} else { } else {
Pointer<Pointer> ptab = malloc<Pointer>(); final ptab = malloc<Pointer<JSPropertyEnum>>();
Pointer<Uint32> plen = malloc<Uint32>(); final plen = malloc<Uint32>();
if (jsGetOwnPropertyNames(ctx, ptab, plen, val, -1) != 0) return null; if (jsGetOwnPropertyNames(ctx, ptab, plen, val, -1) != 0) {
int len = plen.value;
malloc.free(plen); malloc.free(plen);
Map<dynamic, dynamic> ret = Map(); malloc.free(ptab);
return null;
}
final len = plen.value;
malloc.free(plen);
final ret = Map();
cache[valptr] = ret; cache[valptr] = ret;
for (int i = 0; i < len; ++i) { for (var i = 0; i < len; ++i) {
final jsAtom = jsPropertyEnumGetAtom(ptab.value, i); final jsAtom = jsPropertyEnumGetAtom(ptab.value, i);
final jsAtomValue = jsAtomToValue(ctx, jsAtom); final jsAtomValue = jsAtomToValue(ctx, jsAtom);
final jsProp = jsGetProperty(ctx, val, jsAtom); final jsProp = jsGetProperty(ctx, val, jsAtom);

View File

@@ -7,56 +7,56 @@ packages:
name: async name: async
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.5.0-nullsafety.3" version: "2.5.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0-nullsafety.3" version: "2.1.0"
characters: characters:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0-nullsafety.5" version: "1.1.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0-nullsafety.3" version: "1.2.0"
clock: clock:
dependency: transitive dependency: transitive
description: description:
name: clock name: clock
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0-nullsafety.3" version: "1.1.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.15.0-nullsafety.5" version: "1.15.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0-nullsafety.3" version: "1.2.0"
ffi: ffi:
dependency: "direct main" dependency: "direct main"
description: description:
name: ffi name: ffi
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.1.3" version: "1.0.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@@ -73,21 +73,21 @@ packages:
name: matcher name: matcher
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.12.10-nullsafety.3" version: "0.12.10"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.3.0-nullsafety.6" version: "1.3.0"
path: path:
dependency: transitive dependency: transitive
description: description:
name: path name: path
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.0-nullsafety.3" version: "1.8.0"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@@ -99,56 +99,56 @@ packages:
name: source_span name: source_span
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.0-nullsafety.4" version: "1.8.1"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.10.0-nullsafety.6" version: "1.10.0"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0-nullsafety.3" version: "2.1.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0-nullsafety.3" version: "1.1.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0-nullsafety.3" version: "1.2.0"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.2.19-nullsafety.6" version: "0.2.19"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.3.0-nullsafety.5" version: "1.3.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0-nullsafety.5" version: "2.1.0"
sdks: sdks:
dart: ">=2.12.0-0.0 <3.0.0" dart: ">=2.12.0-259.9.beta <3.0.0"
flutter: ">=1.20.0" flutter: ">=1.20.0"

View File

@@ -1,6 +1,6 @@
name: flutter_qjs name: flutter_qjs
description: This plugin is a simple js engine for flutter using the `quickjs` project. Plugin currently supports all the platforms except web! description: This plugin is a simple js engine for flutter using the `quickjs` project. Plugin currently supports all the platforms except web!
version: 0.3.3 version: 0.3.4
homepage: https://github.com/ekibun/flutter_qjs homepage: https://github.com/ekibun/flutter_qjs
environment: environment:
@@ -26,6 +26,7 @@ flutter:
# be modified. They are used by the tooling to maintain consistency when # be modified. They are used by the tooling to maintain consistency when
# adding or updating assets for this project. # adding or updating assets for this project.
plugin: plugin:
implements: flutter_qjs
platforms: platforms:
# This plugin project was generated without specifying any # This plugin project was generated without specifying any
# platforms with the `--platform` argument. If you see the `fake_platform` map below, remove it and # platforms with the `--platform` argument. If you see the `fake_platform` map below, remove it and