add timeout and memory limit

This commit is contained in:
ekibun
2022-05-20 00:40:44 +08:00
parent 232ea07e89
commit 32aac42c19
8 changed files with 426 additions and 316 deletions

View File

@@ -21,6 +21,12 @@ class FlutterQjs {
/// Max stack size for quickjs.
final int? stackSize;
/// Max stack size for quickjs.
final int? timeout;
/// Max memory for quickjs.
final int? memoryLimit;
/// Message Port for event loop. Close it to stop dispatching event loop.
ReceivePort port = ReceivePort();
@@ -33,6 +39,8 @@ class FlutterQjs {
FlutterQjs({
this.moduleHandler,
this.stackSize,
this.timeout,
this.memoryLimit,
this.hostPromiseRejectionHandler,
});
@@ -104,9 +112,11 @@ class FlutterQjs {
}
return err;
}
}, port);
}, timeout ?? 0, port);
final stackSize = this.stackSize ?? 0;
if (stackSize > 0) jsSetMaxStackSize(rt, stackSize);
final memoryLimit = this.memoryLimit ?? 0;
if (memoryLimit > 0) jsSetMemoryLimit(rt, memoryLimit);
_rt = rt;
_ctx = jsNewContext(rt);
}

View File

@@ -156,11 +156,13 @@ typedef _JSChannelNative = Pointer<JSValue> Function(
/// JSRuntime *jsNewRuntime(JSChannel channel)
final Pointer<JSRuntime> Function(
Pointer<NativeFunction<_JSChannelNative>>,
int,
) _jsNewRuntime = _qjsLib
.lookup<
NativeFunction<
Pointer<JSRuntime> Function(
Pointer<NativeFunction<_JSChannelNative>>,
Int64,
)>>('jsNewRuntime')
.asFunction();
@@ -197,9 +199,10 @@ Pointer<JSValue>? channelDispacher(
Pointer<JSRuntime> jsNewRuntime(
_JSChannel callback,
int timeout,
ReceivePort port,
) {
final rt = _jsNewRuntime(Pointer.fromFunction(channelDispacher));
final rt = _jsNewRuntime(Pointer.fromFunction(channelDispacher), timeout);
runtimeOpaques[rt] = _RuntimeOpaque(callback, port);
return rt;
}
@@ -217,6 +220,19 @@ final void Function(
)>>('jsSetMaxStackSize')
.asFunction();
/// DLLEXPORT void jsSetMemoryLimit(JSRuntime *rt, size_t limit);
final void Function(
Pointer<JSRuntime>,
int,
) jsSetMemoryLimit = _qjsLib
.lookup<
NativeFunction<
Void Function(
Pointer<JSRuntime>,
IntPtr,
)>>('jsSetMemoryLimit')
.asFunction();
/// void jsFreeRuntime(JSRuntime *rt)
final void Function(
Pointer<JSRuntime>,
@@ -282,6 +298,7 @@ final Pointer<JSContext> Function(
Pointer<JSContext> jsNewContext(Pointer<JSRuntime> rt) {
final ctx = _jsNewContext(rt);
if (ctx.address == 0) throw Exception('Context create failed!');
final runtimeOpaque = runtimeOpaques[rt];
if (runtimeOpaque == null) throw Exception('Runtime has been released!');
runtimeOpaque._dartObjectClassId = jsNewClass(ctx, 'DartObject');

View File

@@ -109,6 +109,8 @@ void _runJsIsolate(Map spawnMessage) async {
sendPort.send(port.sendPort);
final qjs = FlutterQjs(
stackSize: spawnMessage[#stackSize],
timeout: spawnMessage[#timeout],
memoryLimit: spawnMessage[#memoryLimit],
hostPromiseRejectionHandler: (reason) {
sendPort.send({
#type: #hostPromiseRejection,
@@ -171,6 +173,12 @@ class IsolateQjs {
/// Max stack size for quickjs.
final int? stackSize;
/// Max stack size for quickjs.
final int? timeout;
/// Max memory for quickjs.
final int? memoryLimit;
/// Asynchronously handler to manage js module.
final _JsAsyncModuleHandler? moduleHandler;
@@ -184,6 +192,8 @@ class IsolateQjs {
IsolateQjs({
this.moduleHandler,
this.stackSize,
this.timeout,
this.memoryLimit,
this.hostPromiseRejectionHandler,
});
@@ -195,6 +205,8 @@ class IsolateQjs {
{
#port: port.sendPort,
#stackSize: stackSize,
#timeout: timeout,
#memoryLimit: memoryLimit,
},
errorsAreFatal: true,
);