fix Promise reject cannot get Exception string.

This commit is contained in:
ekibun
2021-01-25 19:27:00 +08:00
parent 6fb2c4776b
commit b790073045
9 changed files with 130 additions and 114 deletions

View File

@@ -6,6 +6,10 @@
* @LastEditTime: 2020-12-02 11:36:40 * @LastEditTime: 2020-12-02 11:36:40
--> -->
## 0.3.2
* fix Promise reject cannot get Exception string.
## 0.3.1 ## 0.3.1
* code clean up. * code clean up.

View File

@@ -100,16 +100,7 @@ To use async function in module handler, try [Run on isolate thread](#Run-on-iso
Create a `IsolateQjs` object, pass handlers to resolving modules. Async function such as `rootBundle.loadString` can be used now to get modules: Create a `IsolateQjs` object, pass handlers to resolving modules. Async function such as `rootBundle.loadString` can be used now to get modules:
```dart ```dart
dynamic methodHandler(String method, List arg) {
switch (method) {
case "http":
return Dio().get(arg[0]).then((response) => response.data);
default:
throw Exception("No such method");
}
}
final engine = IsolateQjs( final engine = IsolateQjs(
methodHandler: methodHandler,
moduleHandler: (String module) async { moduleHandler: (String module) async {
return await rootBundle.loadString( return await rootBundle.loadString(
"js/" + module.replaceFirst(new RegExp(r".js$"), "") + ".js"); "js/" + module.replaceFirst(new RegExp(r".js$"), "") + ".js");
@@ -134,9 +125,9 @@ Method `close` can destroy quickjs runtime that can be recreated again if you ca
Method `bind` can help to pass instance function to isolate: Method `bind` can help to pass instance function to isolate:
```dart ```dart
await setToGlobalObject("func", await engine.bind(({thisVal}) { await jsFunc(await engine.bind(({thisVal}) {
// DO SOMETHING // DO SOMETHING
})) }));
``` ```
[This example](example/lib/main.dart) contains a complete demonstration on how to use this plugin. [This example](example/lib/main.dart) contains a complete demonstration on how to use this plugin.
@@ -148,5 +139,5 @@ Use js function to set dart object globally:
```dart ```dart
final setToGlobalObject = await engine.evaluate("(key, val) => this[key] = val;"); final setToGlobalObject = await engine.evaluate("(key, val) => this[key] = val;");
setToGlobalObject("channel", methodHandler); await setToGlobalObject("channel", methodHandler);
``` ```

View File

@@ -75,7 +75,7 @@ packages:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "0.3.1" version: "0.3.2"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter

View File

@@ -57,14 +57,14 @@ class JSTag {
final DynamicLibrary _qjsLib = Platform.environment['FLUTTER_TEST'] == 'true' final DynamicLibrary _qjsLib = Platform.environment['FLUTTER_TEST'] == 'true'
? (Platform.isWindows ? (Platform.isWindows
? DynamicLibrary.open("test/build/Debug/ffiquickjs.dll") ? DynamicLibrary.open('test/build/Debug/ffiquickjs.dll')
: Platform.isMacOS : Platform.isMacOS
? DynamicLibrary.open("test/build/libffiquickjs.dylib") ? DynamicLibrary.open('test/build/libffiquickjs.dylib')
: DynamicLibrary.open("test/build/libffiquickjs.so")) : DynamicLibrary.open('test/build/libffiquickjs.so'))
: (Platform.isWindows : (Platform.isWindows
? DynamicLibrary.open("flutter_qjs_plugin.dll") ? DynamicLibrary.open('flutter_qjs_plugin.dll')
: Platform.isAndroid : Platform.isAndroid
? DynamicLibrary.open("libqjs.so") ? DynamicLibrary.open('libqjs.so')
: DynamicLibrary.process()); : DynamicLibrary.process());
/// JSValue *jsThrowInternalError(JSContext *ctx, char *message) /// JSValue *jsThrowInternalError(JSContext *ctx, char *message)
@@ -77,7 +77,7 @@ final Pointer Function(
Pointer Function( Pointer Function(
Pointer, Pointer,
Pointer<Utf8>, Pointer<Utf8>,
)>>("jsThrowInternalError") )>>('jsThrowInternalError')
.asFunction(); .asFunction();
Pointer jsThrowInternalError(Pointer ctx, String message) { Pointer jsThrowInternalError(Pointer ctx, String message) {
@@ -89,12 +89,12 @@ Pointer jsThrowInternalError(Pointer ctx, String message) {
/// JSValue *jsEXCEPTION() /// JSValue *jsEXCEPTION()
final Pointer Function() jsEXCEPTION = _qjsLib final Pointer Function() jsEXCEPTION = _qjsLib
.lookup<NativeFunction<Pointer Function()>>("jsEXCEPTION") .lookup<NativeFunction<Pointer Function()>>('jsEXCEPTION')
.asFunction(); .asFunction();
/// JSValue *jsUNDEFINED() /// JSValue *jsUNDEFINED()
final Pointer Function() jsUNDEFINED = _qjsLib final Pointer Function() jsUNDEFINED = _qjsLib
.lookup<NativeFunction<Pointer Function()>>("jsUNDEFINED") .lookup<NativeFunction<Pointer Function()>>('jsUNDEFINED')
.asFunction(); .asFunction();
typedef JSChannel = Pointer Function(Pointer ctx, int method, Pointer argv); typedef JSChannel = Pointer Function(Pointer ctx, int method, Pointer argv);
@@ -109,7 +109,7 @@ final Pointer Function(
NativeFunction< NativeFunction<
Pointer Function( Pointer Function(
Pointer, Pointer,
)>>("jsNewRuntime") )>>('jsNewRuntime')
.asFunction(); .asFunction();
class RuntimeOpaque { class RuntimeOpaque {
@@ -147,7 +147,7 @@ final void Function(
Void Function( Void Function(
Pointer, Pointer,
IntPtr, IntPtr,
)>>("jsSetMaxStackSize") )>>('jsSetMaxStackSize')
.asFunction(); .asFunction();
/// void jsFreeRuntime(JSRuntime *rt) /// void jsFreeRuntime(JSRuntime *rt)
@@ -158,7 +158,7 @@ final void Function(
NativeFunction< NativeFunction<
Void Function( Void Function(
Pointer, Pointer,
)>>("jsFreeRuntime") )>>('jsFreeRuntime')
.asFunction(); .asFunction();
void jsFreeRuntime( void jsFreeRuntime(
@@ -181,7 +181,7 @@ final Pointer Function(
Pointer Function( Pointer Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsNewCFunction") )>>('jsNewCFunction')
.asFunction(); .asFunction();
/// JSContext *jsNewContext(JSRuntime *rt) /// JSContext *jsNewContext(JSRuntime *rt)
@@ -192,14 +192,14 @@ final Pointer Function(
NativeFunction< NativeFunction<
Pointer Function( Pointer Function(
Pointer, Pointer,
)>>("jsNewContext") )>>('jsNewContext')
.asFunction(); .asFunction();
Pointer jsNewContext(Pointer rt) { Pointer jsNewContext(Pointer rt) {
var ctx = _jsNewContext(rt); var ctx = _jsNewContext(rt);
final runtimeOpaque = runtimeOpaques[rt]; final runtimeOpaque = runtimeOpaques[rt];
if (runtimeOpaque == null) throw Exception("Runtime has been released!"); if (runtimeOpaque == null) throw Exception('Runtime has been released!');
runtimeOpaque.dartObjectClassId = jsNewClass(ctx, "DartObject"); runtimeOpaque.dartObjectClassId = jsNewClass(ctx, 'DartObject');
return ctx; return ctx;
} }
@@ -211,7 +211,7 @@ final void Function(
NativeFunction< NativeFunction<
Void Function( Void Function(
Pointer, Pointer,
)>>("jsFreeContext") )>>('jsFreeContext')
.asFunction(); .asFunction();
/// JSRuntime *jsGetRuntime(JSContext *ctx) /// JSRuntime *jsGetRuntime(JSContext *ctx)
@@ -222,7 +222,7 @@ final Pointer Function(
NativeFunction< NativeFunction<
Pointer Function( Pointer Function(
Pointer, Pointer,
)>>("jsGetRuntime") )>>('jsGetRuntime')
.asFunction(); .asFunction();
/// JSValue *jsEval(JSContext *ctx, const char *input, size_t input_len, const char *filename, int eval_flags) /// JSValue *jsEval(JSContext *ctx, const char *input, size_t input_len, const char *filename, int eval_flags)
@@ -241,7 +241,7 @@ final Pointer Function(
IntPtr, IntPtr,
Pointer<Utf8>, Pointer<Utf8>,
Int32, Int32,
)>>("jsEval") )>>('jsEval')
.asFunction(); .asFunction();
Pointer jsEval( Pointer jsEval(
@@ -273,7 +273,7 @@ final int Function(
NativeFunction< NativeFunction<
Int32 Function( Int32 Function(
Pointer, Pointer,
)>>("jsValueGetTag") )>>('jsValueGetTag')
.asFunction(); .asFunction();
/// void *jsValueGetPtr(JSValue *val) /// void *jsValueGetPtr(JSValue *val)
@@ -284,7 +284,7 @@ final Pointer Function(
NativeFunction< NativeFunction<
Pointer Function( Pointer Function(
Pointer, Pointer,
)>>("jsValueGetPtr") )>>('jsValueGetPtr')
.asFunction(); .asFunction();
/// DLLEXPORT bool jsTagIsFloat64(int32_t tag) /// DLLEXPORT bool jsTagIsFloat64(int32_t tag)
@@ -295,7 +295,7 @@ final int Function(
NativeFunction< NativeFunction<
Int32 Function( Int32 Function(
Int32, Int32,
)>>("jsTagIsFloat64") )>>('jsTagIsFloat64')
.asFunction(); .asFunction();
/// JSValue *jsNewBool(JSContext *ctx, int val) /// JSValue *jsNewBool(JSContext *ctx, int val)
@@ -308,7 +308,7 @@ final Pointer Function(
Pointer Function( Pointer Function(
Pointer, Pointer,
Int32, Int32,
)>>("jsNewBool") )>>('jsNewBool')
.asFunction(); .asFunction();
/// JSValue *jsNewInt64(JSContext *ctx, int64_t val) /// JSValue *jsNewInt64(JSContext *ctx, int64_t val)
@@ -321,7 +321,7 @@ final Pointer Function(
Pointer Function( Pointer Function(
Pointer, Pointer,
Int64, Int64,
)>>("jsNewInt64") )>>('jsNewInt64')
.asFunction(); .asFunction();
/// JSValue *jsNewFloat64(JSContext *ctx, double val) /// JSValue *jsNewFloat64(JSContext *ctx, double val)
@@ -334,7 +334,7 @@ final Pointer Function(
Pointer Function( Pointer Function(
Pointer, Pointer,
Double, Double,
)>>("jsNewFloat64") )>>('jsNewFloat64')
.asFunction(); .asFunction();
/// JSValue *jsNewString(JSContext *ctx, const char *str) /// JSValue *jsNewString(JSContext *ctx, const char *str)
@@ -347,7 +347,7 @@ final Pointer Function(
Pointer Function( Pointer Function(
Pointer, Pointer,
Pointer<Utf8>, Pointer<Utf8>,
)>>("jsNewString") )>>('jsNewString')
.asFunction(); .asFunction();
Pointer jsNewString( Pointer jsNewString(
@@ -370,7 +370,7 @@ final Pointer Function(
Pointer, Pointer,
Pointer<Uint8>, Pointer<Uint8>,
IntPtr, IntPtr,
)>>("jsNewArrayBufferCopy") )>>('jsNewArrayBufferCopy')
.asFunction(); .asFunction();
/// JSValue *jsNewArray(JSContext *ctx) /// JSValue *jsNewArray(JSContext *ctx)
@@ -381,7 +381,7 @@ final Pointer Function(
NativeFunction< NativeFunction<
Pointer Function( Pointer Function(
Pointer, Pointer,
)>>("jsNewArray") )>>('jsNewArray')
.asFunction(); .asFunction();
/// JSValue *jsNewObject(JSContext *ctx) /// JSValue *jsNewObject(JSContext *ctx)
@@ -392,7 +392,7 @@ final Pointer Function(
NativeFunction< NativeFunction<
Pointer Function( Pointer Function(
Pointer, Pointer,
)>>("jsNewObject") )>>('jsNewObject')
.asFunction(); .asFunction();
/// void jsFreeValue(JSContext *ctx, JSValue *val, int32_t free) /// void jsFreeValue(JSContext *ctx, JSValue *val, int32_t free)
@@ -407,7 +407,7 @@ final void Function(
Pointer, Pointer,
Pointer, Pointer,
Int32, Int32,
)>>("jsFreeValue") )>>('jsFreeValue')
.asFunction(); .asFunction();
void jsFreeValue( void jsFreeValue(
@@ -430,7 +430,7 @@ final void Function(
Pointer, Pointer,
Pointer, Pointer,
Int32, Int32,
)>>("jsFreeValueRT") )>>('jsFreeValueRT')
.asFunction(); .asFunction();
void jsFreeValueRT( void jsFreeValueRT(
@@ -451,7 +451,7 @@ final Pointer Function(
Pointer Function( Pointer Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsDupValue") )>>('jsDupValue')
.asFunction(); .asFunction();
/// JSValue *jsDupValueRT(JSRuntime *rt, JSValue *v) /// JSValue *jsDupValueRT(JSRuntime *rt, JSValue *v)
@@ -464,7 +464,7 @@ final Pointer Function(
Pointer Function( Pointer Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsDupValueRT") )>>('jsDupValueRT')
.asFunction(); .asFunction();
/// int32_t jsToBool(JSContext *ctx, JSValueConst *val) /// int32_t jsToBool(JSContext *ctx, JSValueConst *val)
@@ -477,7 +477,7 @@ final int Function(
Int32 Function( Int32 Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsToBool") )>>('jsToBool')
.asFunction(); .asFunction();
/// int64_t jsToFloat64(JSContext *ctx, JSValueConst *val) /// int64_t jsToFloat64(JSContext *ctx, JSValueConst *val)
@@ -490,7 +490,7 @@ final int Function(
Int64 Function( Int64 Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsToInt64") )>>('jsToInt64')
.asFunction(); .asFunction();
/// double jsToFloat64(JSContext *ctx, JSValueConst *val) /// double jsToFloat64(JSContext *ctx, JSValueConst *val)
@@ -503,7 +503,7 @@ final double Function(
Double Function( Double Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsToFloat64") )>>('jsToFloat64')
.asFunction(); .asFunction();
/// const char *jsToCString(JSContext *ctx, JSValue *val) /// const char *jsToCString(JSContext *ctx, JSValue *val)
@@ -516,7 +516,7 @@ final Pointer<Utf8> Function(
Pointer<Utf8> Function( Pointer<Utf8> Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsToCString") )>>('jsToCString')
.asFunction(); .asFunction();
/// void jsFreeCString(JSContext *ctx, const char *ptr) /// void jsFreeCString(JSContext *ctx, const char *ptr)
@@ -529,7 +529,7 @@ final void Function(
Void Function( Void Function(
Pointer, Pointer,
Pointer<Utf8>, Pointer<Utf8>,
)>>("jsFreeCString") )>>('jsFreeCString')
.asFunction(); .asFunction();
String jsToCString( String jsToCString(
@@ -537,7 +537,7 @@ String jsToCString(
Pointer val, Pointer val,
) { ) {
var ptr = _jsToCString(ctx, val); var ptr = _jsToCString(ctx, val);
if (ptr.address == 0) throw Exception("JSValue cannot convert to string"); if (ptr.address == 0) throw Exception('JSValue cannot convert to string');
var str = Utf8.fromUtf8(ptr); var str = Utf8.fromUtf8(ptr);
jsFreeCString(ctx, ptr); jsFreeCString(ctx, ptr);
return str; return str;
@@ -553,7 +553,7 @@ final int Function(
Uint32 Function( Uint32 Function(
Pointer, Pointer,
Pointer<Utf8>, Pointer<Utf8>,
)>>("jsNewClass") )>>('jsNewClass')
.asFunction(); .asFunction();
int jsNewClass( int jsNewClass(
@@ -581,7 +581,7 @@ final Pointer Function(
Pointer, Pointer,
Uint32, Uint32,
IntPtr, IntPtr,
)>>("jsNewObjectClass") )>>('jsNewObjectClass')
.asFunction(); .asFunction();
/// DLLEXPORT void *jsGetObjectOpaque(JSValue *obj, uint32_t classid) /// DLLEXPORT void *jsGetObjectOpaque(JSValue *obj, uint32_t classid)
@@ -594,7 +594,7 @@ final int Function(
IntPtr Function( IntPtr Function(
Pointer, Pointer,
Uint32, Uint32,
)>>("jsGetObjectOpaque") )>>('jsGetObjectOpaque')
.asFunction(); .asFunction();
/// uint8_t *jsGetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst *obj) /// uint8_t *jsGetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst *obj)
@@ -609,7 +609,7 @@ final Pointer<Uint8> Function(
Pointer, Pointer,
Pointer<IntPtr>, Pointer<IntPtr>,
Pointer, Pointer,
)>>("jsGetArrayBuffer") )>>('jsGetArrayBuffer')
.asFunction(); .asFunction();
/// int32_t jsIsFunction(JSContext *ctx, JSValueConst *val) /// int32_t jsIsFunction(JSContext *ctx, JSValueConst *val)
@@ -622,7 +622,7 @@ final int Function(
Int32 Function( Int32 Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsIsFunction") )>>('jsIsFunction')
.asFunction(); .asFunction();
/// int32_t jsIsPromise(JSContext *ctx, JSValueConst *val) /// int32_t jsIsPromise(JSContext *ctx, JSValueConst *val)
@@ -635,7 +635,7 @@ final int Function(
Int32 Function( Int32 Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsIsPromise") )>>('jsIsPromise')
.asFunction(); .asFunction();
/// int32_t jsIsArray(JSContext *ctx, JSValueConst *val) /// int32_t jsIsArray(JSContext *ctx, JSValueConst *val)
@@ -648,7 +648,7 @@ final int Function(
Int32 Function( Int32 Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsIsArray") )>>('jsIsArray')
.asFunction(); .asFunction();
/// JSValue *jsGetProperty(JSContext *ctx, JSValueConst *this_obj, /// JSValue *jsGetProperty(JSContext *ctx, JSValueConst *this_obj,
@@ -664,7 +664,7 @@ final Pointer Function(
Pointer, Pointer,
Pointer, Pointer,
Uint32, Uint32,
)>>("jsGetProperty") )>>('jsGetProperty')
.asFunction(); .asFunction();
/// int jsDefinePropertyValue(JSContext *ctx, JSValueConst *this_obj, /// int jsDefinePropertyValue(JSContext *ctx, JSValueConst *this_obj,
@@ -684,7 +684,7 @@ final int Function(
Uint32, Uint32,
Pointer, Pointer,
Int32, Int32,
)>>("jsDefinePropertyValue") )>>('jsDefinePropertyValue')
.asFunction(); .asFunction();
/// void jsFreeAtom(JSContext *ctx, JSAtom v) /// void jsFreeAtom(JSContext *ctx, JSAtom v)
@@ -697,7 +697,7 @@ final Pointer Function(
Pointer Function( Pointer Function(
Pointer, Pointer,
Uint32, Uint32,
)>>("jsFreeAtom") )>>('jsFreeAtom')
.asFunction(); .asFunction();
/// JSAtom jsValueToAtom(JSContext *ctx, JSValueConst *val) /// JSAtom jsValueToAtom(JSContext *ctx, JSValueConst *val)
@@ -710,7 +710,7 @@ final int Function(
Uint32 Function( Uint32 Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsValueToAtom") )>>('jsValueToAtom')
.asFunction(); .asFunction();
/// JSValue *jsAtomToValue(JSContext *ctx, JSAtom val) /// JSValue *jsAtomToValue(JSContext *ctx, JSAtom val)
@@ -723,7 +723,7 @@ final Pointer Function(
Pointer Function( Pointer Function(
Pointer, Pointer,
Uint32, Uint32,
)>>("jsAtomToValue") )>>('jsAtomToValue')
.asFunction(); .asFunction();
/// int jsGetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab, /// int jsGetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab,
@@ -743,7 +743,7 @@ final int Function(
Pointer<Uint32>, Pointer<Uint32>,
Pointer, Pointer,
Int32, Int32,
)>>("jsGetOwnPropertyNames") )>>('jsGetOwnPropertyNames')
.asFunction(); .asFunction();
/// JSAtom jsPropertyEnumGetAtom(JSPropertyEnum *ptab, int i) /// JSAtom jsPropertyEnumGetAtom(JSPropertyEnum *ptab, int i)
@@ -756,12 +756,12 @@ final int Function(
Uint32 Function( Uint32 Function(
Pointer, Pointer,
Int32, Int32,
)>>("jsPropertyEnumGetAtom") )>>('jsPropertyEnumGetAtom')
.asFunction(); .asFunction();
/// uint32_t sizeOfJSValue() /// uint32_t sizeOfJSValue()
final int Function() _sizeOfJSValue = _qjsLib final int Function() _sizeOfJSValue = _qjsLib
.lookup<NativeFunction<Uint32 Function()>>("sizeOfJSValue") .lookup<NativeFunction<Uint32 Function()>>('sizeOfJSValue')
.asFunction(); .asFunction();
final sizeOfJSValue = _sizeOfJSValue(); final sizeOfJSValue = _sizeOfJSValue();
@@ -778,7 +778,7 @@ final void Function(
Pointer, Pointer,
Uint32, Uint32,
Pointer, Pointer,
)>>("setJSValueList") )>>('setJSValueList')
.asFunction(); .asFunction();
/// JSValue *jsCall(JSContext *ctx, JSValueConst *func_obj, JSValueConst *this_obj, /// JSValue *jsCall(JSContext *ctx, JSValueConst *func_obj, JSValueConst *this_obj,
@@ -798,7 +798,7 @@ final Pointer Function(
Pointer, Pointer,
Int32, Int32,
Pointer, Pointer,
)>>("jsCall") )>>('jsCall')
.asFunction(); .asFunction();
Pointer jsCall( Pointer jsCall(
@@ -834,7 +834,7 @@ final int Function(
NativeFunction< NativeFunction<
Int32 Function( Int32 Function(
Pointer, Pointer,
)>>("jsIsException") )>>('jsIsException')
.asFunction(); .asFunction();
/// JSValue *jsGetException(JSContext *ctx) /// JSValue *jsGetException(JSContext *ctx)
@@ -845,7 +845,7 @@ final Pointer Function(
NativeFunction< NativeFunction<
Pointer Function( Pointer Function(
Pointer, Pointer,
)>>("jsGetException") )>>('jsGetException')
.asFunction(); .asFunction();
/// int jsExecutePendingJob(JSRuntime *rt) /// int jsExecutePendingJob(JSRuntime *rt)
@@ -856,7 +856,7 @@ final int Function(
NativeFunction< NativeFunction<
Int32 Function( Int32 Function(
Pointer, Pointer,
)>>("jsExecutePendingJob") )>>('jsExecutePendingJob')
.asFunction(); .asFunction();
/// JSValue *jsNewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs) /// JSValue *jsNewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs)
@@ -869,7 +869,7 @@ final Pointer Function(
Pointer Function( Pointer Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsNewPromiseCapability") )>>('jsNewPromiseCapability')
.asFunction(); .asFunction();
/// void jsFree(JSContext *ctx, void *ptab) /// void jsFree(JSContext *ctx, void *ptab)
@@ -882,5 +882,5 @@ final void Function(
Void Function( Void Function(
Pointer, Pointer,
Pointer, Pointer,
)>>("jsFree") )>>('jsFree')
.asFunction(); .asFunction();

View File

@@ -50,20 +50,25 @@ class FlutterQjs {
case JSChannelType.METHON: case JSChannelType.METHON:
final pdata = ptr.cast<Pointer>(); final pdata = ptr.cast<Pointer>();
final argc = pdata.elementAt(1).value.cast<Int32>().value; final argc = pdata.elementAt(1).value.cast<Int32>().value;
List args = []; List pargs = <Pointer>[];
for (var i = 0; i < argc; i++) { for (var i = 0; i < argc; i++) {
args.add(jsToDart( pargs.add(Pointer.fromAddress(
ctx, pdata.elementAt(2).value.address + sizeOfJSValue * i,
Pointer.fromAddress( ));
pdata.elementAt(2).value.address + sizeOfJSValue * i,
)));
} }
final thisVal = jsToDart(ctx, pdata.elementAt(0).value); final pThis = pdata.elementAt(0).value;
JSInvokable func = jsToDart(ctx, pdata.elementAt(3).value); JSInvokable func = jsToDart(ctx, pdata.elementAt(3).value);
final ret = func.invoke(args, thisVal); if (func is NativeJSInvokable) {
return dartToJs(ctx, ret); return dartToJs(ctx, func.invokeNative(ctx, pThis, pargs));
}
return dartToJs(
ctx,
func.invoke(
pargs.map((e) => jsToDart(ctx, e)).toList(),
jsToDart(ctx, pThis),
));
case JSChannelType.MODULE: case JSChannelType.MODULE:
if (moduleHandler == null) throw Exception("No ModuleHandler"); if (moduleHandler == null) throw Exception('No ModuleHandler');
var ret = Utf8.toUtf8(moduleHandler( var ret = Utf8.toUtf8(moduleHandler(
Utf8.fromUtf8(ptr.cast<Utf8>()), Utf8.fromUtf8(ptr.cast<Utf8>()),
)); ));
@@ -72,11 +77,11 @@ class FlutterQjs {
}); });
return ret; return ret;
case JSChannelType.PROMISE_TRACK: case JSChannelType.PROMISE_TRACK:
final errStr = parseJSException(ctx, perr: ptr); final errStr = parseJSException(ctx, ptr);
if (hostPromiseRejectionHandler != null) { if (hostPromiseRejectionHandler != null) {
hostPromiseRejectionHandler(errStr); hostPromiseRejectionHandler(errStr);
} else { } else {
print("unhandled promise rejection: $errStr"); print('unhandled promise rejection: $errStr');
} }
return Pointer.fromAddress(0); return Pointer.fromAddress(0);
case JSChannelType.FREE_OBJECT: case JSChannelType.FREE_OBJECT:
@@ -86,15 +91,15 @@ class FlutterQjs {
runtimeOpaques[rt]?.ref?.remove(obj); runtimeOpaques[rt]?.ref?.remove(obj);
return Pointer.fromAddress(0); return Pointer.fromAddress(0);
} }
throw Exception("call channel with wrong type"); throw Exception('call channel with wrong type');
} catch (e, stack) { } catch (e, stack) {
final errStr = e.toString() + "\n" + stack.toString(); final errStr = e.toString() + '\n' + stack.toString();
if (type == JSChannelType.FREE_OBJECT) { if (type == JSChannelType.FREE_OBJECT) {
print("DartObject release error: " + errStr); print('DartObject release error: ' + errStr);
return Pointer.fromAddress(0); return Pointer.fromAddress(0);
} }
if (type == JSChannelType.MODULE) { if (type == JSChannelType.MODULE) {
print("host Promise Rejection Handler error: " + errStr); print('host Promise Rejection Handler error: ' + errStr);
return Pointer.fromAddress(0); return Pointer.fromAddress(0);
} }
var err = jsThrowInternalError( var err = jsThrowInternalError(
@@ -143,12 +148,12 @@ class FlutterQjs {
var jsval = jsEval( var jsval = jsEval(
_ctx, _ctx,
command, command,
name ?? "<eval>", name ?? '<eval>',
evalFlags ?? JSEvalFlag.GLOBAL, evalFlags ?? JSEvalFlag.GLOBAL,
); );
if (jsIsException(jsval) != 0) { if (jsIsException(jsval) != 0) {
jsFreeValue(_ctx, jsval); jsFreeValue(_ctx, jsval);
throw Exception(parseJSException(_ctx)); throw parseJSException(_ctx);
} }
var result = jsToDart(_ctx, jsval); var result = jsToDart(_ctx, jsval);
jsFreeValue(_ctx, jsval); jsFreeValue(_ctx, jsval);

View File

@@ -35,7 +35,7 @@ void _runJsIsolate(Map spawnMessage) async {
'ptr': ptr.address, 'ptr': ptr.address,
}); });
while (ptr.value.address == 0) sleep(Duration.zero); while (ptr.value.address == 0) sleep(Duration.zero);
if (ptr.value.address == -1) throw Exception("Module Not found"); if (ptr.value.address == -1) throw Exception('Module Not found');
var ret = Utf8.fromUtf8(ptr.value); var ret = Utf8.fromUtf8(ptr.value);
sendPort.send({ sendPort.send({
'type': 'release', 'type': 'release',
@@ -58,7 +58,7 @@ void _runJsIsolate(Map spawnMessage) async {
); );
break; break;
case 'call': case 'call':
data = JSFunction.fromAddress( data = await JSFunction.fromAddress(
Pointer.fromAddress(msg['ctx']), Pointer.fromAddress(msg['ctx']),
Pointer.fromAddress(msg['val']), Pointer.fromAddress(msg['val']),
).invoke( ).invoke(
@@ -79,7 +79,7 @@ void _runJsIsolate(Map spawnMessage) async {
} catch (e, stack) { } catch (e, stack) {
if (msgPort != null) if (msgPort != null)
msgPort.send({ msgPort.send({
'error': e.toString() + "\n" + stack.toString(), 'error': e.toString() + '\n' + stack.toString(),
}); });
} }
}); });
@@ -135,12 +135,12 @@ class IsolateQjs {
if (hostPromiseRejectionHandler != null) { if (hostPromiseRejectionHandler != null) {
hostPromiseRejectionHandler(errStr); hostPromiseRejectionHandler(errStr);
} else { } else {
print("unhandled promise rejection: $errStr"); print('unhandled promise rejection: $errStr');
} }
} catch (e, stack) { } catch (e, stack) {
print("host Promise Rejection Handler error: " + print('host Promise Rejection Handler error: ' +
e.toString() + e.toString() +
"\n" + '\n' +
stack.toString()); stack.toString());
} }
break; break;

View File

@@ -32,6 +32,20 @@ abstract class JSInvokable {
} }
} }
class NativeJSInvokable extends JSInvokable {
dynamic Function(Pointer ctx, Pointer thisVal, List<Pointer> args) _func;
NativeJSInvokable(this._func);
@override
dynamic invoke(List args, [dynamic thisVal]) {
throw UnimplementedError('use invokeNative instead.');
}
invokeNative(Pointer ctx, Pointer thisVal, List<Pointer> args) {
_func(ctx, thisVal, args);
}
}
class _DartFunction extends JSInvokable { class _DartFunction extends JSInvokable {
Function _func; Function _func;
_DartFunction(this._func); _DartFunction(this._func);
@@ -40,7 +54,7 @@ class _DartFunction extends JSInvokable {
invoke(List args, [thisVal]) { invoke(List args, [thisVal]) {
/// wrap this into function /// wrap this into function
final passThis = final passThis =
RegExp("{.*thisVal.*}").hasMatch(_func.runtimeType.toString()); RegExp('{.*thisVal.*}').hasMatch(_func.runtimeType.toString());
return Function.apply(_func, args, passThis ? {#thisVal: thisVal} : null); return Function.apply(_func, args, passThis ? {#thisVal: thisVal} : null);
} }
} }
@@ -112,7 +126,7 @@ class JSFunction extends JSObject implements JSInvokable {
bool isException = jsIsException(jsRet) != 0; bool isException = jsIsException(jsRet) != 0;
if (isException) { if (isException) {
jsFreeValue(_ctx, jsRet); jsFreeValue(_ctx, jsRet);
throw Exception(parseJSException(_ctx)); throw parseJSException(_ctx);
} }
var ret = jsToDart(_ctx, jsRet); var ret = jsToDart(_ctx, jsRet);
jsFreeValue(_ctx, jsRet); jsFreeValue(_ctx, jsRet);
@@ -180,7 +194,7 @@ class IsolateFunction extends JSInvokable implements DartReleasable {
final JSInvokable invokable = JSInvokable.wrap(func); final JSInvokable invokable = JSInvokable.wrap(func);
final funcPort = ReceivePort(); final funcPort = ReceivePort();
funcPort.listen((msg) async { funcPort.listen((msg) async {
if (msg == "close") return funcPort.close(); if (msg == 'close') return funcPort.close();
var data; var data;
SendPort msgPort = msg['port']; SendPort msgPort = msg['port'];
try { try {
@@ -194,7 +208,7 @@ class IsolateFunction extends JSInvokable implements DartReleasable {
} catch (e, stack) { } catch (e, stack) {
if (msgPort != null) if (msgPort != null)
msgPort.send({ msgPort.send({
'error': e.toString() + "\n" + stack.toString(), 'error': e.toString() + '\n' + stack.toString(),
}); });
} }
}); });
@@ -221,7 +235,7 @@ class IsolateFunction extends JSInvokable implements DartReleasable {
@override @override
void release() { void release() {
if (func == null) return; if (func == null) return;
func.send("close"); func.send('close');
func = null; func = null;
} }
} }
@@ -275,7 +289,7 @@ dynamic encodeData(dynamic data, {Map<dynamic, dynamic> cache}) {
futurePort.first.then((port) { futurePort.first.then((port) {
futurePort.close(); futurePort.close();
(port as SendPort) (port as SendPort)
.send({'error': e.toString() + "\n" + stack.toString()}); .send({'error': e.toString() + '\n' + stack.toString()});
}); });
}); });
return { return {
@@ -344,12 +358,12 @@ dynamic decodeData(dynamic data, SendPort port, {Map<dynamic, dynamic> cache}) {
return data; return data;
} }
String parseJSException(Pointer ctx, {Pointer perr}) { String parseJSException(Pointer ctx, [Pointer perr]) {
final e = perr ?? jsGetException(ctx); final e = perr ?? jsGetException(ctx);
var err = jsToCString(ctx, e); var err = jsToCString(ctx, e);
if (jsValueGetTag(e) == JSTag.OBJECT) { if (jsValueGetTag(e) == JSTag.OBJECT) {
Pointer stack = jsGetPropertyValue(ctx, e, "stack"); Pointer stack = jsGetPropertyValue(ctx, e, 'stack');
if (jsToBool(ctx, stack) != 0) { if (jsToBool(ctx, stack) != 0) {
err += '\n' + jsToCString(ctx, stack); err += '\n' + jsToCString(ctx, stack);
} }
@@ -409,7 +423,7 @@ Pointer dartToJs(Pointer ctx, dynamic val, {Map<dynamic, dynamic> cache}) {
val.then((value) { val.then((value) {
res(value); res(value);
}, onError: (e, stack) { }, onError: (e, stack) {
rej(e.toString() + "\n" + stack.toString()); rej(e.toString() + '\n' + stack.toString());
}); });
return ret; return ret;
} }
@@ -498,7 +512,7 @@ dynamic jsToDart(Pointer ctx, Pointer val, {Map<int, dynamic> cache}) {
if (jsIsFunction(ctx, val) != 0) { if (jsIsFunction(ctx, val) != 0) {
return JSFunction(ctx, val); return JSFunction(ctx, val);
} else if (jsIsPromise(ctx, val) != 0) { } else if (jsIsPromise(ctx, val) != 0) {
Pointer jsPromiseThen = jsGetPropertyValue(ctx, val, "then"); Pointer jsPromiseThen = jsGetPropertyValue(ctx, val, 'then');
JSFunction promiseThen = jsToDart(ctx, jsPromiseThen, cache: cache); JSFunction promiseThen = jsToDart(ctx, jsPromiseThen, cache: cache);
jsFreeValue(ctx, jsPromiseThen); jsFreeValue(ctx, jsPromiseThen);
var completer = Completer(); var completer = Completer();
@@ -507,16 +521,18 @@ dynamic jsToDart(Pointer ctx, Pointer val, {Map<int, dynamic> cache}) {
(v) { (v) {
if (!completer.isCompleted) completer.complete(v); if (!completer.isCompleted) completer.complete(v);
}, },
(e) { NativeJSInvokable((ctx, thisVal, args) {
if (!completer.isCompleted) completer.completeError(e); if (!completer.isCompleted)
}, completer
.completeError(parseJSException(ctx, args[0]));
}),
], JSObject.fromAddress(ctx, val)); ], JSObject.fromAddress(ctx, val));
bool isException = jsIsException(jsRet) != 0; bool isException = jsIsException(jsRet) != 0;
jsFreeValue(ctx, jsRet); jsFreeValue(ctx, jsRet);
if (isException) throw Exception(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"); Pointer jslength = jsGetPropertyValue(ctx, val, 'length');
int length = jsToInt64(ctx, jslength); int length = jsToInt64(ctx, jslength);
List<dynamic> ret = []; List<dynamic> ret = [];
cache[valptr] = ret; cache[valptr] = ret;

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.1 version: 0.3.2
homepage: https://github.com/ekibun/flutter_qjs homepage: https://github.com/ekibun/flutter_qjs
environment: environment:

View File

@@ -158,7 +158,7 @@ void main() async {
qjs.evaluate("a=()=>a();a();", name: "<eval>"); qjs.evaluate("a=()=>a();a();", name: "<eval>");
} catch (e) { } catch (e) {
expect( expect(
e.toString(), startsWith('Exception: InternalError: stack overflow'), e.toString(), startsWith('InternalError: stack overflow'),
reason: "throw stack overflow"); reason: "throw stack overflow");
} }
qjs.close(); qjs.close();