-
- Line data Source code
-
- 1 : /*
- 2 : * @Description: ffi
- 3 : * @Author: ekibun
- 4 : * @Date: 2020-09-19 10:29:04
- 5 : * @LastEditors: ekibun
- 6 : * @LastEditTime: 2020-12-02 11:14:35
- 7 : */
- 8 : import 'dart:ffi';
- 9 : import 'dart:io';
- 10 : import 'dart:isolate';
- 11 : import 'package:ffi/ffi.dart';
- 12 :
- 13 : extension ListFirstWhere<T> on Iterable<T> {
- 14 3 : T? firstWhereOrNull(bool Function(T) test) {
- 15 : try {
- 16 3 : return firstWhere(test);
- 17 3 : } on StateError {
- 18 : return null;
- 19 : }
- 20 : }
- 21 : }
- 22 :
- 23 : abstract class JSRef {
- 24 : int _refCount = 0;
- 25 3 : void dup() {
- 26 6 : _refCount++;
- 27 : }
- 28 :
- 29 3 : void free() {
- 30 6 : _refCount--;
- 31 9 : if (_refCount < 0) destroy();
- 32 : }
- 33 :
- 34 : void destroy();
- 35 :
- 36 3 : static void freeRecursive(dynamic obj) {
- 37 7 : _callRecursive(obj, (ref) => ref.free());
- 38 : }
- 39 :
- 40 3 : static void dupRecursive(dynamic obj) {
- 41 7 : _callRecursive(obj, (ref) => ref.dup());
- 42 : }
- 43 :
- 44 3 : static void _callRecursive(
- 45 : dynamic obj,
- 46 : void Function(JSRef) cb, [
- 47 : Set? cache,
- 48 : ]) {
- 49 : if (obj == null) return;
- 50 : if (cache == null) cache = Set();
- 51 3 : if (cache.contains(obj)) return;
- 52 3 : if (obj is List) {
- 53 3 : cache.add(obj);
- 54 12 : List.from(obj).forEach((e) => _callRecursive(e, cb, cache));
- 55 : }
- 56 3 : if (obj is Map) {
- 57 2 : cache.add(obj);
- 58 10 : obj.values.toList().forEach((e) => _callRecursive(e, cb, cache));
- 59 : }
- 60 3 : if (obj is JSRef) {
- 61 2 : cb(obj);
- 62 : }
- 63 : }
- 64 : }
- 65 :
- 66 : abstract class JSRefLeakable {}
- 67 :
- 68 : class JSEvalFlag {
- 69 : static const GLOBAL = 0 << 0;
- 70 : static const MODULE = 1 << 0;
- 71 : }
- 72 :
- 73 : class JSChannelType {
- 74 : static const METHON = 0;
- 75 : static const MODULE = 1;
- 76 : static const PROMISE_TRACK = 2;
- 77 : static const FREE_OBJECT = 3;
- 78 : }
- 79 :
- 80 : class JSProp {
- 81 : static const CONFIGURABLE = (1 << 0);
- 82 : static const WRITABLE = (1 << 1);
- 83 : static const ENUMERABLE = (1 << 2);
- 84 : static const C_W_E = (CONFIGURABLE | WRITABLE | ENUMERABLE);
- 85 : }
- 86 :
- 87 : class JSTag {
- 88 : static const FIRST = -11; /* first negative tag */
- 89 : static const BIG_DECIMAL = -11;
- 90 : static const BIG_INT = -10;
- 91 : static const BIG_FLOAT = -9;
- 92 : static const SYMBOL = -8;
- 93 : static const STRING = -7;
- 94 : static const MODULE = -3; /* used internally */
- 95 : static const FUNCTION_BYTECODE = -2; /* used internally */
- 96 : static const OBJECT = -1;
- 97 :
- 98 : static const INT = 0;
- 99 : static const BOOL = 1;
- 100 : static const NULL = 2;
- 101 : static const UNDEFINED = 3;
- 102 : static const UNINITIALIZED = 4;
- 103 : static const CATCH_OFFSET = 5;
- 104 : static const EXCEPTION = 6;
- 105 : static const FLOAT64 = 7;
- 106 : }
- 107 :
- 108 : abstract class JSValue extends Opaque {}
- 109 :
- 110 : abstract class JSContext extends Opaque {}
- 111 :
- 112 : abstract class JSRuntime extends Opaque {}
- 113 :
- 114 : abstract class JSPropertyEnum extends Opaque {}
- 115 :
- 116 15 : final DynamicLibrary _qjsLib = Platform.environment['FLUTTER_TEST'] == 'true'
- 117 3 : ? (Platform.isWindows
- 118 3 : ? DynamicLibrary.open('test/build/Debug/ffiquickjs.dll')
- 119 0 : : Platform.isMacOS
- 120 0 : ? DynamicLibrary.open('test/build/libffiquickjs.dylib')
- 121 0 : : DynamicLibrary.open('test/build/libffiquickjs.so'))
- 122 0 : : (Platform.isWindows
- 123 0 : ? DynamicLibrary.open('flutter_qjs_plugin.dll')
- 124 0 : : Platform.isAndroid
- 125 0 : ? DynamicLibrary.open('libqjs.so')
- 126 0 : : DynamicLibrary.process());
- 127 :
- 128 : /// DLLEXPORT JSValue *jsThrow(JSContext *ctx, JSValue *obj)
- 129 : final Pointer<JSValue> Function(
- 130 : Pointer<JSContext> ctx,
- 131 : Pointer<JSValue> obj,
- 132 0 : ) jsThrow = _qjsLib
- 133 : .lookup<
- 134 : NativeFunction<
- 135 : Pointer<JSValue> Function(
- 136 : Pointer<JSContext>,
- 137 : Pointer<JSValue>,
- 138 : )>>('jsThrow')
- 139 : .asFunction();
- 140 :
- 141 : /// JSValue *jsEXCEPTION()
- 142 0 : final Pointer<JSValue> Function() jsEXCEPTION = _qjsLib
- 143 : .lookup<NativeFunction<Pointer<JSValue> Function()>>('jsEXCEPTION')
- 144 : .asFunction();
- 145 :
- 146 : /// JSValue *jsUNDEFINED()
- 147 9 : final Pointer<JSValue> Function() jsUNDEFINED = _qjsLib
- 148 3 : .lookup<NativeFunction<Pointer<JSValue> Function()>>('jsUNDEFINED')
- 149 : .asFunction();
- 150 :
- 151 : typedef _JSChannel = Pointer<JSValue> Function(
- 152 : Pointer<JSContext> ctx, int method, Pointer<JSValue> argv);
- 153 : typedef _JSChannelNative = Pointer<JSValue> Function(
- 154 : Pointer<JSContext> ctx, IntPtr method, Pointer<JSValue> argv);
- 155 :
- 156 : /// JSRuntime *jsNewRuntime(JSChannel channel)
- 157 : final Pointer<JSRuntime> Function(
- 158 : Pointer<NativeFunction<_JSChannelNative>>,
- 159 9 : ) _jsNewRuntime = _qjsLib
- 160 3 : .lookup<
- 161 : NativeFunction<
- 162 : Pointer<JSRuntime> Function(
- 163 : Pointer<NativeFunction<_JSChannelNative>>,
- 164 : )>>('jsNewRuntime')
- 165 : .asFunction();
- 166 :
- 167 : class _RuntimeOpaque {
- 168 : final _JSChannel _channel;
- 169 : List<JSRef> _ref = [];
- 170 : final ReceivePort _port;
- 171 : int? _dartObjectClassId;
- 172 3 : _RuntimeOpaque(this._channel, this._port);
- 173 :
- 174 6 : int? get dartObjectClassId => _dartObjectClassId;
- 175 :
- 176 9 : void addRef(JSRef ref) => _ref.add(ref);
- 177 :
- 178 9 : bool removeRef(JSRef ref) => _ref.remove(ref);
- 179 :
- 180 3 : JSRef? getRef(bool Function(JSRef ref) test) {
- 181 6 : return _ref.firstWhereOrNull(test);
- 182 : }
- 183 : }
- 184 :
- 185 9 : final Map<Pointer<JSRuntime>, _RuntimeOpaque> runtimeOpaques = Map();
- 186 :
- 187 3 : Pointer<JSValue>? channelDispacher(
- 188 : Pointer<JSContext> ctx,
- 189 : int type,
- 190 : Pointer<JSValue> argv,
- 191 : ) {
- 192 3 : final rt = type == JSChannelType.FREE_OBJECT
- 193 3 : ? ctx.cast<JSRuntime>()
- 194 6 : : jsGetRuntime(ctx);
- 195 12 : return runtimeOpaques[rt]?._channel(ctx, type, argv);
- 196 : }
- 197 :
- 198 3 : Pointer<JSRuntime> jsNewRuntime(
- 199 : _JSChannel callback,
- 200 : ReceivePort port,
- 201 : ) {
- 202 6 : final rt = _jsNewRuntime(Pointer.fromFunction(channelDispacher));
- 203 9 : runtimeOpaques[rt] = _RuntimeOpaque(callback, port);
- 204 : return rt;
- 205 : }
- 206 :
- 207 : /// DLLEXPORT void jsSetMaxStackSize(JSRuntime *rt, size_t stack_size)
- 208 : final void Function(
- 209 : Pointer<JSRuntime>,
- 210 : int,
- 211 0 : ) jsSetMaxStackSize = _qjsLib
- 212 : .lookup<
- 213 : NativeFunction<
- 214 : Void Function(
- 215 : Pointer<JSRuntime>,
- 216 : IntPtr,
- 217 : )>>('jsSetMaxStackSize')
- 218 : .asFunction();
- 219 :
- 220 : /// void jsFreeRuntime(JSRuntime *rt)
- 221 : final void Function(
- 222 : Pointer<JSRuntime>,
- 223 9 : ) _jsFreeRuntime = _qjsLib
- 224 3 : .lookup<
- 225 : NativeFunction<
- 226 : Void Function(
- 227 : Pointer<JSRuntime>,
- 228 : )>>('jsFreeRuntime')
- 229 : .asFunction();
- 230 :
- 231 3 : void jsFreeRuntime(
- 232 : Pointer<JSRuntime> rt,
- 233 : ) {
- 234 3 : final referenceleak = <String>[];
- 235 6 : final opaque = runtimeOpaques[rt];
- 236 : if (opaque != null) {
- 237 : while (true) {
- 238 12 : final ref = opaque._ref.firstWhereOrNull((ref) => ref is JSRefLeakable);
- 239 : if (ref == null) break;
- 240 3 : ref.destroy();
- 241 12 : runtimeOpaques[rt]?._ref.remove(ref);
- 242 : }
- 243 6 : while (opaque._ref.isNotEmpty) {
- 244 2 : final ref = opaque._ref.first;
- 245 2 : final objStrs = ref.toString().split('\n');
- 246 4 : final objStr = objStrs.length > 0 ? objStrs[0] + " ..." : objStrs[0];
- 247 1 : referenceleak.add(
- 248 6 : " ${identityHashCode(ref)}\t${ref._refCount + 1}\t${ref.runtimeType.toString()}\t$objStr");
- 249 1 : ref.destroy();
- 250 : }
- 251 : }
- 252 6 : _jsFreeRuntime(rt);
- 253 6 : if (referenceleak.length > 0) {
- 254 1 : throw ('reference leak:\n ADDR\tREF\tTYPE\tPROP\n' +
- 255 1 : referenceleak.join('\n'));
- 256 : }
- 257 : }
- 258 :
- 259 : /// JSValue *jsNewCFunction(JSContext *ctx, JSValue *funcData)
- 260 : final Pointer<JSValue> Function(
- 261 : Pointer<JSContext> ctx,
- 262 : Pointer<JSValue> funcData,
- 263 9 : ) jsNewCFunction = _qjsLib
- 264 3 : .lookup<
- 265 : NativeFunction<
- 266 : Pointer<JSValue> Function(
- 267 : Pointer<JSContext>,
- 268 : Pointer<JSValue>,
- 269 : )>>('jsNewCFunction')
- 270 : .asFunction();
- 271 :
- 272 : /// JSContext *jsNewContext(JSRuntime *rt)
- 273 : final Pointer<JSContext> Function(
- 274 : Pointer<JSRuntime> rt,
- 275 9 : ) _jsNewContext = _qjsLib
- 276 3 : .lookup<
- 277 : NativeFunction<
- 278 : Pointer<JSContext> Function(
- 279 : Pointer<JSRuntime>,
- 280 : )>>('jsNewContext')
- 281 : .asFunction();
- 282 :
- 283 3 : Pointer<JSContext> jsNewContext(Pointer<JSRuntime> rt) {
- 284 6 : final ctx = _jsNewContext(rt);
- 285 6 : final runtimeOpaque = runtimeOpaques[rt];
- 286 0 : if (runtimeOpaque == null) throw Exception('Runtime has been released!');
- 287 6 : runtimeOpaque._dartObjectClassId = jsNewClass(ctx, 'DartObject');
- 288 : return ctx;
- 289 : }
- 290 :
- 291 : /// void jsFreeContext(JSContext *ctx)
- 292 : final void Function(
- 293 : Pointer<JSContext>,
- 294 9 : ) jsFreeContext = _qjsLib
- 295 3 : .lookup<
- 296 : NativeFunction<
- 297 : Void Function(
- 298 : Pointer<JSContext>,
- 299 : )>>('jsFreeContext')
- 300 : .asFunction();
- 301 :
- 302 : /// JSRuntime *jsGetRuntime(JSContext *ctx)
- 303 : final Pointer<JSRuntime> Function(
- 304 : Pointer<JSContext>,
- 305 9 : ) jsGetRuntime = _qjsLib
- 306 3 : .lookup<
- 307 : NativeFunction<
- 308 : Pointer<JSRuntime> Function(
- 309 : Pointer<JSContext>,
- 310 : )>>('jsGetRuntime')
- 311 : .asFunction();
- 312 :
- 313 : /// JSValue *jsEval(JSContext *ctx, const char *input, size_t input_len, const char *filename, int eval_flags)
- 314 : final Pointer<JSValue> Function(
- 315 : Pointer<JSContext> ctx,
- 316 : Pointer<Utf8> input,
- 317 : int inputLen,
- 318 : Pointer<Utf8> filename,
- 319 : int evalFlags,
- 320 9 : ) _jsEval = _qjsLib
- 321 3 : .lookup<
- 322 : NativeFunction<
- 323 : Pointer<JSValue> Function(
- 324 : Pointer<JSContext>,
- 325 : Pointer<Utf8>,
- 326 : IntPtr,
- 327 : Pointer<Utf8>,
- 328 : Int32,
- 329 : )>>('jsEval')
- 330 : .asFunction();
- 331 :
- 332 3 : Pointer<JSValue> jsEval(
- 333 : Pointer<JSContext> ctx,
- 334 : String input,
- 335 : String filename,
- 336 : int evalFlags,
- 337 : ) {
- 338 3 : final utf8input = input.toNativeUtf8();
- 339 3 : final utf8filename = filename.toNativeUtf8();
- 340 6 : final val = _jsEval(
- 341 : ctx,
- 342 : utf8input,
- 343 3 : utf8input.length,
- 344 : utf8filename,
- 345 : evalFlags,
- 346 : );
- 347 3 : malloc.free(utf8input);
- 348 3 : malloc.free(utf8filename);
- 349 21 : runtimeOpaques[jsGetRuntime(ctx)]?._port.sendPort.send(#eval);
- 350 : return val;
- 351 : }
- 352 :
- 353 : /// DLLEXPORT int32_t jsValueGetTag(JSValue *val)
- 354 : final int Function(
- 355 : Pointer<JSValue> val,
- 356 9 : ) jsValueGetTag = _qjsLib
- 357 3 : .lookup<
- 358 : NativeFunction<
- 359 : Int32 Function(
- 360 : Pointer<JSValue>,
- 361 : )>>('jsValueGetTag')
- 362 : .asFunction();
- 363 :
- 364 : /// void *jsValueGetPtr(JSValue *val)
- 365 : final int Function(
- 366 : Pointer<JSValue> val,
- 367 9 : ) jsValueGetPtr = _qjsLib
- 368 3 : .lookup<
- 369 : NativeFunction<
- 370 : IntPtr Function(
- 371 : Pointer<JSValue>,
- 372 : )>>('jsValueGetPtr')
- 373 : .asFunction();
- 374 :
- 375 : /// DLLEXPORT bool jsTagIsFloat64(int32_t tag)
- 376 : final int Function(
- 377 : int val,
- 378 9 : ) jsTagIsFloat64 = _qjsLib
- 379 3 : .lookup<
- 380 : NativeFunction<
- 381 : Int32 Function(
- 382 : Int32,
- 383 : )>>('jsTagIsFloat64')
- 384 : .asFunction();
- 385 :
- 386 : /// JSValue *jsNewBool(JSContext *ctx, int val)
- 387 : final Pointer<JSValue> Function(
- 388 : Pointer<JSContext> ctx,
- 389 : int val,
- 390 6 : ) jsNewBool = _qjsLib
- 391 2 : .lookup<
- 392 : NativeFunction<
- 393 : Pointer<JSValue> Function(
- 394 : Pointer<JSContext>,
- 395 : Int32,
- 396 : )>>('jsNewBool')
- 397 : .asFunction();
- 398 :
- 399 : /// JSValue *jsNewInt64(JSContext *ctx, int64_t val)
- 400 : final Pointer<JSValue> Function(
- 401 : Pointer<JSContext> ctx,
- 402 : int val,
- 403 6 : ) jsNewInt64 = _qjsLib
- 404 2 : .lookup<
- 405 : NativeFunction<
- 406 : Pointer<JSValue> Function(
- 407 : Pointer<JSContext>,
- 408 : Int64,
- 409 : )>>('jsNewInt64')
- 410 : .asFunction();
- 411 :
- 412 : /// JSValue *jsNewFloat64(JSContext *ctx, double val)
- 413 : final Pointer<JSValue> Function(
- 414 : Pointer<JSContext> ctx,
- 415 : double val,
- 416 6 : ) jsNewFloat64 = _qjsLib
- 417 2 : .lookup<
- 418 : NativeFunction<
- 419 : Pointer<JSValue> Function(
- 420 : Pointer<JSContext>,
- 421 : Double,
- 422 : )>>('jsNewFloat64')
- 423 : .asFunction();
- 424 :
- 425 : /// JSValue *jsNewString(JSContext *ctx, const char *str)
- 426 : final Pointer<JSValue> Function(
- 427 : Pointer<JSContext> ctx,
- 428 : Pointer<Utf8> str,
- 429 9 : ) _jsNewString = _qjsLib
- 430 3 : .lookup<
- 431 : NativeFunction<
- 432 : Pointer<JSValue> Function(
- 433 : Pointer<JSContext>,
- 434 : Pointer<Utf8>,
- 435 : )>>('jsNewString')
- 436 : .asFunction();
- 437 :
- 438 3 : Pointer<JSValue> jsNewString(
- 439 : Pointer<JSContext> ctx,
- 440 : String str,
- 441 : ) {
- 442 3 : final utf8str = str.toNativeUtf8();
- 443 6 : final jsStr = _jsNewString(ctx, utf8str);
- 444 3 : malloc.free(utf8str);
- 445 : return jsStr;
- 446 : }
- 447 :
- 448 : /// JSValue *jsNewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len)
- 449 : final Pointer<JSValue> Function(
- 450 : Pointer<JSContext> ctx,
- 451 : Pointer<Uint8> buf,
- 452 : int len,
- 453 0 : ) jsNewArrayBufferCopy = _qjsLib
- 454 : .lookup<
- 455 : NativeFunction<
- 456 : Pointer<JSValue> Function(
- 457 : Pointer<JSContext>,
- 458 : Pointer<Uint8>,
- 459 : IntPtr,
- 460 : )>>('jsNewArrayBufferCopy')
- 461 : .asFunction();
- 462 :
- 463 : /// JSValue *jsNewArray(JSContext *ctx)
- 464 : final Pointer<JSValue> Function(
- 465 : Pointer<JSContext> ctx,
- 466 6 : ) jsNewArray = _qjsLib
- 467 2 : .lookup<
- 468 : NativeFunction<
- 469 : Pointer<JSValue> Function(
- 470 : Pointer<JSContext>,
- 471 : )>>('jsNewArray')
- 472 : .asFunction();
- 473 :
- 474 : /// JSValue *jsNewObject(JSContext *ctx)
- 475 : final Pointer<JSValue> Function(
- 476 : Pointer<JSContext> ctx,
- 477 6 : ) jsNewObject = _qjsLib
- 478 2 : .lookup<
- 479 : NativeFunction<
- 480 : Pointer<JSValue> Function(
- 481 : Pointer<JSContext>,
- 482 : )>>('jsNewObject')
- 483 : .asFunction();
- 484 :
- 485 : /// void jsFreeValue(JSContext *ctx, JSValue *val, int32_t free)
- 486 : final void Function(
- 487 : Pointer<JSContext> ctx,
- 488 : Pointer<JSValue> val,
- 489 : int free,
- 490 9 : ) _jsFreeValue = _qjsLib
- 491 3 : .lookup<
- 492 : NativeFunction<
- 493 : Void Function(
- 494 : Pointer<JSContext>,
- 495 : Pointer<JSValue>,
- 496 : Int32,
- 497 : )>>('jsFreeValue')
- 498 : .asFunction();
- 499 :
- 500 3 : void jsFreeValue(
- 501 : Pointer<JSContext> ctx,
- 502 : Pointer<JSValue> val, {
- 503 : bool free = true,
- 504 : }) {
- 505 6 : _jsFreeValue(ctx, val, free ? 1 : 0);
- 506 : }
- 507 :
- 508 : /// void jsFreeValue(JSRuntime *rt, JSValue *val, int32_t free)
- 509 : final void Function(
- 510 : Pointer<JSRuntime> rt,
- 511 : Pointer<JSValue> val,
- 512 : int free,
- 513 0 : ) _jsFreeValueRT = _qjsLib
- 514 : .lookup<
- 515 : NativeFunction<
- 516 : Void Function(
- 517 : Pointer<JSRuntime>,
- 518 : Pointer<JSValue>,
- 519 : Int32,
- 520 : )>>('jsFreeValueRT')
- 521 : .asFunction();
- 522 :
- 523 0 : void jsFreeValueRT(
- 524 : Pointer<JSRuntime> rt,
- 525 : Pointer<JSValue> val, {
- 526 : bool free = true,
- 527 : }) {
- 528 0 : _jsFreeValueRT(rt, val, free ? 1 : 0);
- 529 : }
- 530 :
- 531 : /// JSValue *jsDupValue(JSContext *ctx, JSValueConst *v)
- 532 : final Pointer<JSValue> Function(
- 533 : Pointer<JSContext> ctx,
- 534 : Pointer<JSValue> val,
- 535 9 : ) jsDupValue = _qjsLib
- 536 3 : .lookup<
- 537 : NativeFunction<
- 538 : Pointer<JSValue> Function(
- 539 : Pointer<JSContext>,
- 540 : Pointer<JSValue>,
- 541 : )>>('jsDupValue')
- 542 : .asFunction();
- 543 :
- 544 : /// JSValue *jsDupValueRT(JSRuntime *rt, JSValue *v)
- 545 : final Pointer<JSValue> Function(
- 546 : Pointer<JSRuntime> rt,
- 547 : Pointer<JSValue> val,
- 548 0 : ) jsDupValueRT = _qjsLib
- 549 : .lookup<
- 550 : NativeFunction<
- 551 : Pointer<JSValue> Function(
- 552 : Pointer<JSRuntime>,
- 553 : Pointer<JSValue>,
- 554 : )>>('jsDupValueRT')
- 555 : .asFunction();
- 556 :
- 557 : /// int32_t jsToBool(JSContext *ctx, JSValueConst *val)
- 558 : final int Function(
- 559 : Pointer<JSContext> ctx,
- 560 : Pointer<JSValue> val,
- 561 6 : ) jsToBool = _qjsLib
- 562 2 : .lookup<
- 563 : NativeFunction<
- 564 : Int32 Function(
- 565 : Pointer<JSContext>,
- 566 : Pointer<JSValue>,
- 567 : )>>('jsToBool')
- 568 : .asFunction();
- 569 :
- 570 : /// int64_t jsToFloat64(JSContext *ctx, JSValueConst *val)
- 571 : final int Function(
- 572 : Pointer<JSContext> ctx,
- 573 : Pointer<JSValue> val,
- 574 6 : ) jsToInt64 = _qjsLib
- 575 2 : .lookup<
- 576 : NativeFunction<
- 577 : Int64 Function(
- 578 : Pointer<JSContext>,
- 579 : Pointer<JSValue>,
- 580 : )>>('jsToInt64')
- 581 : .asFunction();
- 582 :
- 583 : /// double jsToFloat64(JSContext *ctx, JSValueConst *val)
- 584 : final double Function(
- 585 : Pointer<JSContext> ctx,
- 586 : Pointer<JSValue> val,
- 587 6 : ) jsToFloat64 = _qjsLib
- 588 2 : .lookup<
- 589 : NativeFunction<
- 590 : Double Function(
- 591 : Pointer<JSContext>,
- 592 : Pointer<JSValue>,
- 593 : )>>('jsToFloat64')
- 594 : .asFunction();
- 595 :
- 596 : /// const char *jsToCString(JSContext *ctx, JSValue *val)
- 597 : final Pointer<Utf8> Function(
- 598 : Pointer<JSContext> ctx,
- 599 : Pointer<JSValue> val,
- 600 9 : ) _jsToCString = _qjsLib
- 601 3 : .lookup<
- 602 : NativeFunction<
- 603 : Pointer<Utf8> Function(
- 604 : Pointer<JSContext>,
- 605 : Pointer<JSValue>,
- 606 : )>>('jsToCString')
- 607 : .asFunction();
- 608 :
- 609 : /// void jsFreeCString(JSContext *ctx, const char *ptr)
- 610 : final void Function(
- 611 : Pointer<JSContext> ctx,
- 612 : Pointer<Utf8> val,
- 613 9 : ) jsFreeCString = _qjsLib
- 614 3 : .lookup<
- 615 : NativeFunction<
- 616 : Void Function(
- 617 : Pointer<JSContext>,
- 618 : Pointer<Utf8>,
- 619 : )>>('jsFreeCString')
- 620 : .asFunction();
- 621 :
- 622 3 : String jsToCString(
- 623 : Pointer<JSContext> ctx,
- 624 : Pointer<JSValue> val,
- 625 : ) {
- 626 6 : final ptr = _jsToCString(ctx, val);
- 627 6 : if (ptr.address == 0) throw Exception('JSValue cannot convert to string');
- 628 3 : final str = ptr.toDartString();
- 629 6 : jsFreeCString(ctx, ptr);
- 630 : return str;
- 631 : }
- 632 :
- 633 : /// DLLEXPORT uint32_t jsNewClass(JSContext *ctx, const char *name)
- 634 : final int Function(
- 635 : Pointer<JSContext> ctx,
- 636 : Pointer<Utf8> name,
- 637 9 : ) _jsNewClass = _qjsLib
- 638 3 : .lookup<
- 639 : NativeFunction<
- 640 : Uint32 Function(
- 641 : Pointer<JSContext>,
- 642 : Pointer<Utf8>,
- 643 : )>>('jsNewClass')
- 644 : .asFunction();
- 645 :
- 646 3 : int jsNewClass(
- 647 : Pointer<JSContext> ctx,
- 648 : String name,
- 649 : ) {
- 650 3 : final utf8name = name.toNativeUtf8();
- 651 6 : final val = _jsNewClass(
- 652 : ctx,
- 653 : utf8name,
- 654 : );
- 655 3 : malloc.free(utf8name);
- 656 : return val;
- 657 : }
- 658 :
- 659 : /// DLLEXPORT JSValue *jsNewObjectClass(JSContext *ctx, uint32_t QJSClassId, void *opaque)
- 660 : final Pointer<JSValue> Function(
- 661 : Pointer<JSContext> ctx,
- 662 : int classId,
- 663 : int opaque,
- 664 9 : ) jsNewObjectClass = _qjsLib
- 665 3 : .lookup<
- 666 : NativeFunction<
- 667 : Pointer<JSValue> Function(
- 668 : Pointer<JSContext>,
- 669 : Uint32,
- 670 : IntPtr,
- 671 : )>>('jsNewObjectClass')
- 672 : .asFunction();
- 673 :
- 674 : /// DLLEXPORT void *jsGetObjectOpaque(JSValue *obj, uint32_t classid)
- 675 : final int Function(
- 676 : Pointer<JSValue> obj,
- 677 : int classid,
- 678 9 : ) jsGetObjectOpaque = _qjsLib
- 679 3 : .lookup<
- 680 : NativeFunction<
- 681 : IntPtr Function(
- 682 : Pointer<JSValue>,
- 683 : Uint32,
- 684 : )>>('jsGetObjectOpaque')
- 685 : .asFunction();
- 686 :
- 687 : /// uint8_t *jsGetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst *obj)
- 688 : final Pointer<Uint8> Function(
- 689 : Pointer<JSContext> ctx,
- 690 : Pointer<IntPtr> psize,
- 691 : Pointer<JSValue> val,
- 692 9 : ) jsGetArrayBuffer = _qjsLib
- 693 3 : .lookup<
- 694 : NativeFunction<
- 695 : Pointer<Uint8> Function(
- 696 : Pointer<JSContext>,
- 697 : Pointer<IntPtr>,
- 698 : Pointer<JSValue>,
- 699 : )>>('jsGetArrayBuffer')
- 700 : .asFunction();
- 701 :
- 702 : /// int32_t jsIsFunction(JSContext *ctx, JSValueConst *val)
- 703 : final int Function(
- 704 : Pointer<JSContext> ctx,
- 705 : Pointer<JSValue> val,
- 706 9 : ) jsIsFunction = _qjsLib
- 707 3 : .lookup<
- 708 : NativeFunction<
- 709 : Int32 Function(
- 710 : Pointer<JSContext>,
- 711 : Pointer<JSValue>,
- 712 : )>>('jsIsFunction')
- 713 : .asFunction();
- 714 :
- 715 : /// int32_t jsIsPromise(JSContext *ctx, JSValueConst *val)
- 716 : final int Function(
- 717 : Pointer<JSContext> ctx,
- 718 : Pointer<JSValue> val,
- 719 9 : ) jsIsPromise = _qjsLib
- 720 3 : .lookup<
- 721 : NativeFunction<
- 722 : Int32 Function(
- 723 : Pointer<JSContext>,
- 724 : Pointer<JSValue>,
- 725 : )>>('jsIsPromise')
- 726 : .asFunction();
- 727 :
- 728 : /// int32_t jsIsArray(JSContext *ctx, JSValueConst *val)
- 729 : final int Function(
- 730 : Pointer<JSContext> ctx,
- 731 : Pointer<JSValue> val,
- 732 6 : ) jsIsArray = _qjsLib
- 733 2 : .lookup<
- 734 : NativeFunction<
- 735 : Int32 Function(
- 736 : Pointer<JSContext>,
- 737 : Pointer<JSValue>,
- 738 : )>>('jsIsArray')
- 739 : .asFunction();
- 740 :
- 741 : /// DLLEXPORT int32_t jsIsError(JSContext *ctx, JSValueConst *val);
- 742 : final int Function(
- 743 : Pointer<JSContext> ctx,
- 744 : Pointer<JSValue> val,
- 745 9 : ) jsIsError = _qjsLib
- 746 3 : .lookup<
- 747 : NativeFunction<
- 748 : Int32 Function(
- 749 : Pointer<JSContext>,
- 750 : Pointer<JSValue>,
- 751 : )>>('jsIsError')
- 752 : .asFunction();
- 753 :
- 754 : /// DLLEXPORT JSValue *jsNewError(JSContext *ctx);
- 755 : final Pointer<JSValue> Function(
- 756 : Pointer<JSContext> ctx,
- 757 6 : ) jsNewError = _qjsLib
- 758 2 : .lookup<
- 759 : NativeFunction<
- 760 : Pointer<JSValue> Function(
- 761 : Pointer<JSContext>,
- 762 : )>>('jsNewError')
- 763 : .asFunction();
- 764 :
- 765 : /// JSValue *jsGetProperty(JSContext *ctx, JSValueConst *this_obj,
- 766 : /// JSAtom prop)
- 767 : final Pointer<JSValue> Function(
- 768 : Pointer<JSContext> ctx,
- 769 : Pointer<JSValue> thisObj,
- 770 : int prop,
- 771 9 : ) jsGetProperty = _qjsLib
- 772 3 : .lookup<
- 773 : NativeFunction<
- 774 : Pointer<JSValue> Function(
- 775 : Pointer<JSContext>,
- 776 : Pointer<JSValue>,
- 777 : Uint32,
- 778 : )>>('jsGetProperty')
- 779 : .asFunction();
- 780 :
- 781 : /// int jsDefinePropertyValue(JSContext *ctx, JSValueConst *this_obj,
- 782 : /// JSAtom prop, JSValue *val, int flags)
- 783 : final int Function(
- 784 : Pointer<JSContext> ctx,
- 785 : Pointer<JSValue> thisObj,
- 786 : int prop,
- 787 : Pointer<JSValue> val,
- 788 : int flag,
- 789 6 : ) jsDefinePropertyValue = _qjsLib
- 790 2 : .lookup<
- 791 : NativeFunction<
- 792 : Int32 Function(
- 793 : Pointer<JSContext>,
- 794 : Pointer<JSValue>,
- 795 : Uint32,
- 796 : Pointer<JSValue>,
- 797 : Int32,
- 798 : )>>('jsDefinePropertyValue')
- 799 : .asFunction();
- 800 :
- 801 : /// void jsFreeAtom(JSContext *ctx, JSAtom v)
- 802 : final void Function(
- 803 : Pointer<JSContext> ctx,
- 804 : int v,
- 805 9 : ) jsFreeAtom = _qjsLib
- 806 3 : .lookup<
- 807 : NativeFunction<
- 808 : Void Function(
- 809 : Pointer<JSContext>,
- 810 : Uint32,
- 811 : )>>('jsFreeAtom')
- 812 : .asFunction();
- 813 :
- 814 : /// JSAtom jsValueToAtom(JSContext *ctx, JSValueConst *val)
- 815 : final int Function(
- 816 : Pointer<JSContext> ctx,
- 817 : Pointer<JSValue> val,
- 818 9 : ) jsValueToAtom = _qjsLib
- 819 3 : .lookup<
- 820 : NativeFunction<
- 821 : Uint32 Function(
- 822 : Pointer<JSContext>,
- 823 : Pointer<JSValue>,
- 824 : )>>('jsValueToAtom')
- 825 : .asFunction();
- 826 :
- 827 : /// JSValue *jsAtomToValue(JSContext *ctx, JSAtom val)
- 828 : final Pointer<JSValue> Function(
- 829 : Pointer<JSContext> ctx,
- 830 : int val,
- 831 6 : ) jsAtomToValue = _qjsLib
- 832 2 : .lookup<
- 833 : NativeFunction<
- 834 : Pointer<JSValue> Function(
- 835 : Pointer<JSContext>,
- 836 : Uint32,
- 837 : )>>('jsAtomToValue')
- 838 : .asFunction();
- 839 :
- 840 : /// int jsGetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab,
- 841 : /// uint32_t *plen, JSValueConst *obj, int flags)
- 842 : final int Function(
- 843 : Pointer<JSContext> ctx,
- 844 : Pointer<Pointer<JSPropertyEnum>> ptab,
- 845 : Pointer<Uint32> plen,
- 846 : Pointer<JSValue> obj,
- 847 : int flags,
- 848 6 : ) jsGetOwnPropertyNames = _qjsLib
- 849 2 : .lookup<
- 850 : NativeFunction<
- 851 : Int32 Function(
- 852 : Pointer<JSContext>,
- 853 : Pointer<Pointer<JSPropertyEnum>>,
- 854 : Pointer<Uint32>,
- 855 : Pointer<JSValue>,
- 856 : Int32,
- 857 : )>>('jsGetOwnPropertyNames')
- 858 : .asFunction();
- 859 :
- 860 : /// JSAtom jsPropertyEnumGetAtom(JSPropertyEnum *ptab, int i)
- 861 : final int Function(
- 862 : Pointer<JSPropertyEnum> ptab,
- 863 : int i,
- 864 6 : ) jsPropertyEnumGetAtom = _qjsLib
- 865 2 : .lookup<
- 866 : NativeFunction<
- 867 : Uint32 Function(
- 868 : Pointer<JSPropertyEnum>,
- 869 : Int32,
- 870 : )>>('jsPropertyEnumGetAtom')
- 871 : .asFunction();
- 872 :
- 873 : /// uint32_t sizeOfJSValue()
- 874 9 : final int Function() _sizeOfJSValue = _qjsLib
- 875 3 : .lookup<NativeFunction<Uint32 Function()>>('sizeOfJSValue')
- 876 : .asFunction();
- 877 :
- 878 12 : final sizeOfJSValue = _sizeOfJSValue();
- 879 :
- 880 : /// void setJSValueList(JSValue *list, int i, JSValue *val)
- 881 : final void Function(
- 882 : Pointer<JSValue> list,
- 883 : int i,
- 884 : Pointer<JSValue> val,
- 885 9 : ) setJSValueList = _qjsLib
- 886 3 : .lookup<
- 887 : NativeFunction<
- 888 : Void Function(
- 889 : Pointer<JSValue>,
- 890 : Uint32,
- 891 : Pointer<JSValue>,
- 892 : )>>('setJSValueList')
- 893 : .asFunction();
- 894 :
- 895 : /// JSValue *jsCall(JSContext *ctx, JSValueConst *func_obj, JSValueConst *this_obj,
- 896 : /// int argc, JSValueConst *argv)
- 897 : final Pointer<JSValue> Function(
- 898 : Pointer<JSContext> ctx,
- 899 : Pointer<JSValue> funcObj,
- 900 : Pointer<JSValue> thisObj,
- 901 : int argc,
- 902 : Pointer<JSValue> argv,
- 903 9 : ) _jsCall = _qjsLib
- 904 3 : .lookup<
- 905 : NativeFunction<
- 906 : Pointer<JSValue> Function(
- 907 : Pointer<JSContext>,
- 908 : Pointer<JSValue>,
- 909 : Pointer<JSValue>,
- 910 : Int32,
- 911 : Pointer<JSValue>,
- 912 : )>>('jsCall')
- 913 : .asFunction();
- 914 :
- 915 3 : Pointer<JSValue> jsCall(
- 916 : Pointer<JSContext> ctx,
- 917 : Pointer<JSValue> funcObj,
- 918 : Pointer<JSValue> thisObj,
- 919 : List<Pointer<JSValue>> argv,
- 920 : ) {
- 921 : final jsArgs = calloc<Uint8>(
- 922 15 : argv.length > 0 ? sizeOfJSValue * argv.length : 1,
- 923 3 : ).cast<JSValue>();
- 924 9 : for (int i = 0; i < argv.length; ++i) {
- 925 3 : Pointer<JSValue> jsArg = argv[i];
- 926 6 : setJSValueList(jsArgs, i, jsArg);
- 927 : }
- 928 6 : final func1 = jsDupValue(ctx, funcObj);
- 929 : final _thisObj = thisObj;
- 930 9 : final jsRet = _jsCall(ctx, funcObj, _thisObj, argv.length, jsArgs);
- 931 3 : jsFreeValue(ctx, func1);
- 932 3 : malloc.free(jsArgs);
- 933 21 : runtimeOpaques[jsGetRuntime(ctx)]?._port.sendPort.send(#call);
- 934 : return jsRet;
- 935 : }
- 936 :
- 937 : /// int jsIsException(JSValueConst *val)
- 938 : final int Function(
- 939 : Pointer<JSValue> val,
- 940 9 : ) jsIsException = _qjsLib
- 941 3 : .lookup<
- 942 : NativeFunction<
- 943 : Int32 Function(
- 944 : Pointer<JSValue>,
- 945 : )>>('jsIsException')
- 946 : .asFunction();
- 947 :
- 948 : /// JSValue *jsGetException(JSContext *ctx)
- 949 : final Pointer<JSValue> Function(
- 950 : Pointer<JSContext> ctx,
- 951 3 : ) jsGetException = _qjsLib
- 952 1 : .lookup<
- 953 : NativeFunction<
- 954 : Pointer<JSValue> Function(
- 955 : Pointer<JSContext>,
- 956 : )>>('jsGetException')
- 957 : .asFunction();
- 958 :
- 959 : /// int jsExecutePendingJob(JSRuntime *rt)
- 960 : final int Function(
- 961 : Pointer<JSRuntime> ctx,
- 962 9 : ) jsExecutePendingJob = _qjsLib
- 963 3 : .lookup<
- 964 : NativeFunction<
- 965 : Int32 Function(
- 966 : Pointer<JSRuntime>,
- 967 : )>>('jsExecutePendingJob')
- 968 : .asFunction();
- 969 :
- 970 : /// JSValue *jsNewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs)
- 971 : final Pointer<JSValue> Function(
- 972 : Pointer<JSContext> ctx,
- 973 : Pointer<JSValue> resolvingFuncs,
- 974 9 : ) jsNewPromiseCapability = _qjsLib
- 975 3 : .lookup<
- 976 : NativeFunction<
- 977 : Pointer<JSValue> Function(
- 978 : Pointer<JSContext>,
- 979 : Pointer<JSValue>,
- 980 : )>>('jsNewPromiseCapability')
- 981 : .asFunction();
- 982 :
- 983 : /// void jsFree(JSContext *ctx, void *ptab)
- 984 : final void Function(
- 985 : Pointer<JSContext> ctx,
- 986 : Pointer<JSPropertyEnum> ptab,
- 987 6 : ) jsFree = _qjsLib
- 988 2 : .lookup<
- 989 : NativeFunction<
- 990 : Void Function(
- 991 : Pointer<JSContext>,
- 992 : Pointer<JSPropertyEnum>,
- 993 : )>>('jsFree')
- 994 : .asFunction();
-
- |
-
-