1 module libwasm.types; 2 3 nothrow: 4 5 public import optional; 6 public import libwasm.sumtype; 7 public import libwasm.lodash; 8 public import libwasm.bindings.Console; 9 import memutils.vector; 10 import std.traits : hasMember, isCallable, isBasicType, isSomeString; 11 import libwasm.event : toTuple; 12 import libwasm.bindings.EventHandler; 13 14 version (LDC) 15 { 16 public import ldc.attributes : assumeUsed; 17 } 18 else 19 { 20 enum assumeUsed; 21 } 22 23 alias Handle = uint; 24 version (unittest) 25 { 26 @safe extern (C): 27 Handle libwasm_add__object() 28 { 29 return 0; 30 } 31 32 void libwasm_removeObject(Handle) 33 { 34 } 35 36 void Static_Call_Handle__void(string, string, Handle) 37 { 38 } 39 40 string ldexec_Handle__string(Handle, string, bool delegate(), void delegate(Handle)) 41 { 42 return ""; 43 } 44 45 long ldexec_Handle__long(Handle, string, bool delegate(), void delegate(Handle)) 46 { 47 return 0; 48 } 49 50 double ldexec_Handle__double(Handle, string, bool delegate(), void delegate(Handle)) 51 { 52 return 0; 53 } 54 55 Handle ldexec_Handle__Handle(Handle, string, bool delegate(), void delegate(Handle)) 56 { 57 return Handle.init; 58 } 59 60 string ldexec_string__string(string, string, bool delegate(), void delegate(Handle), bool) 61 { 62 return ""; 63 } 64 65 long ldexec_string__long(string, string, bool delegate(), void delegate(Handle), bool) 66 { 67 return 0; 68 } 69 70 double ldexec_string__double(string, string, bool delegate(), void delegate(Handle), bool) 71 { 72 return 0; 73 } 74 75 Handle ldexec_string__Handle(string, string, bool delegate(), void delegate(Handle), bool) 76 { 77 return Handle.init; 78 } 79 80 long ldexec_long__long(long, string, bool delegate(), void delegate(Handle)) 81 { 82 return 0; 83 } 84 85 double ldexec_long__double(long, string, bool delegate(), void delegate(Handle)) 86 { 87 return 0; 88 } 89 90 string ldexec_long__string(long, string, bool delegate(), void delegate(Handle)) 91 { 92 return ""; 93 } 94 95 Handle ldexec_long__Handle(long, string, bool delegate(), void delegate(Handle)) 96 { 97 return Handle.init; 98 } 99 100 Handle libwasm_add__string(scope ref string) 101 { 102 return Handle.init; 103 } 104 105 int setTimeout(int ctx, int ptr, int ms) 106 { 107 return 0; 108 } 109 110 Handle libwasm_add__bool(bool) 111 { 112 return Handle.init; 113 } 114 115 void Object_VarArgCall__void(Handle, string, string, string) 116 { 117 118 } 119 120 Optional!Handle Object_Getter__OptionalHandle(Handle, string) 121 { 122 return Optional!Handle.init; 123 } 124 125 string Object_Getter__string(Handle, string) 126 { 127 return ""; 128 } 129 130 Handle Object_Getter__Handle(Handle, string) 131 { 132 return Handle.init; 133 } 134 string libwasm_get__string(Handle) { 135 return ""; 136 } 137 138 void libwasm_set__function(string, int ctx, int ptr) {} 139 void Object_Call_EventHandler__void(Handle, string, bool, scope EventHandlerNonNull) {} 140 } 141 else 142 { 143 extern (C) @safe 144 { 145 Handle libwasm_add__object(); 146 Handle libwasm_add__string(string); 147 void libwasm_removeObject(Handle); 148 void Static_Call_Handle__void(string, string, Handle); 149 150 string ldexec_Handle__string(Handle, string, bool delegate(), void delegate(Handle)); 151 long ldexec_Handle__long(Handle, string, bool delegate(), void delegate(Handle)); 152 double ldexec_Handle__double(Handle, string, bool delegate(), void delegate(Handle)); 153 Handle ldexec_Handle__Handle(Handle, string, bool delegate(), void delegate(Handle)); 154 155 string ldexec_string__string(string, string, bool delegate(), void delegate(Handle), bool); 156 long ldexec_string__long(string, string, bool delegate(), void delegate(Handle), bool); 157 double ldexec_string__double(string, string, bool delegate(), void delegate(Handle), bool); 158 Handle ldexec_string__Handle(string, string, bool delegate(), void delegate(Handle), bool); 159 160 long ldexec_long__long(long, string, bool delegate(), void delegate(Handle)); 161 double ldexec_long__double(long, string, bool delegate(), void delegate(Handle)); 162 string ldexec_long__string(long, string, bool delegate(), void delegate(Handle)); 163 Handle ldexec_long__Handle(long, string, bool delegate(), void delegate(Handle)); 164 int setTimeout(int ctx, int ptr, int ms); 165 Handle libwasm_add__bool(bool); 166 void Object_VarArgCall__void(Handle, string, string, string); 167 Optional!Handle Object_Getter__OptionalHandle(Handle, string); 168 string Object_Getter__string(Handle, string); 169 Handle Object_Getter__Handle(Handle, string); 170 string libwasm_get__string(Handle); 171 void libwasm_set__function(string, int ctx, int ptr); 172 void Object_Call_EventHandler__void(Handle, string, bool, scope EventHandlerNonNull); 173 174 } 175 } 176 177 extern (C) 178 { 179 @safe: 180 void doLog(uint val); 181 void libwasm_await__void(Handle); 182 Handle libwasm_add__int(int); 183 Handle libwasm_add__uint(uint); 184 Handle libwasm_add__long(long); 185 Handle libwasm_add__ulong(ulong); 186 Handle libwasm_add__short(short); 187 Handle libwasm_add__ushort(ushort); 188 Handle libwasm_add__float(float); 189 Handle libwasm_add__double(double); 190 Handle libwasm_add__byte(byte); 191 Handle libwasm_add__ubyte(ubyte); 192 Handle libwasm_add__ints(int[]); 193 Handle libwasm_add__uints(uint[]); 194 Handle libwasm_copyObjectRef(Handle); 195 Handle libasync_promise_all__promise(Handle); 196 Handle libasync_promise_any__promise(Handle); 197 Handle libasync_promise_allsettled__promise(Handle); 198 void libwasm_unset__function(string); 199 Handle libwasm_get__field(Handle, string); 200 Handle libwasm_get_idx__field(Handle, uint); 201 bool libwasm_get__bool(Handle); 202 int libwasm_get__int(Handle); 203 uint libwasm_get__uint(Handle); 204 long libwasm_get__long(Handle); 205 ulong libwasm_get__ulong(Handle); 206 short libwasm_get__short(Handle); 207 ushort libwasm_get__ushort(Handle); 208 float libwasm_get__float(Handle); 209 double libwasm_get__double(Handle); 210 byte libwasm_get__byte(Handle); 211 ubyte libwasm_get__ubyte(Handle); 212 void Static_Call_string__void(string, string, string); 213 void Object_Call__void(Handle, string); 214 void Object_Call_string__void(Handle, string, string); 215 void Object_Call_uint__void(Handle, string, uint); 216 void Object_Call_int__void(Handle, string, int); 217 void Object_Call_bool__void(Handle, string, bool); 218 void Object_Call_double__void(Handle, string, double); 219 void Object_Call_float__void(Handle, string, float); 220 void Object_Call_Handle__void(Handle, string, Handle); 221 void Object_Call_string_string__void(Handle, string, string, string); 222 void Object_Call_double_double__void(Handle, string, double, double); 223 Handle Object_Call_string__Handle(Handle, string, string); 224 Handle Object_Call_uint__Handle(Handle, string, uint); 225 Handle Object_Call_int__Handle(Handle, string, int); 226 Handle Object_Call_bool__Handle(Handle, string, bool); 227 Handle Object_Call_Handle__Handle(Handle, string, Handle); 228 Handle Object_Call_string_string__Handle(Handle, string, string, string); 229 Optional!string Object_Getter__OptionalString(Handle, string); 230 Optional!uint Object_Getter__OptionalUint(Handle, string); 231 Optional!double Object_Getter__OptionalDouble(Handle, string); 232 Optional!bool Object_Getter__OptionalBool(Handle, string); 233 Optional!string Object_Call_string__OptionalString(Handle, string, string); 234 EventHandler Object_Getter__EventHandler(Handle, string); 235 Optional!Handle Object_Call_string__OptionalHandle(Handle, string, string); 236 Optional!Handle Object_Call_uint__OptionalHandle(Handle, string, uint); 237 Optional!Handle Object_Call_int__OptionalHandle(Handle, string, int); 238 Optional!Handle Object_Call_bool__OptionalHandle(Handle, string, bool); 239 int Object_Getter__int(Handle, string); 240 uint Object_Getter__uint(Handle, string); 241 ushort Object_Getter__ushort(Handle, string); 242 bool Object_Getter__bool(Handle, string); 243 float Object_Getter__float(Handle, string); 244 double Object_Getter__double(Handle, string); 245 bool Object_Call_string__bool(Handle, string, string); 246 string Object_Call_string__string(Handle, string, string); 247 string Object_Call_uint__string(Handle, string, uint); 248 string Object_Call_uint_uint__string(Handle, string, uint, uint); 249 250 bool Object_VarArgCall__bool(Handle, string, string, string); 251 string Object_VarArgCall__string(Handle, string, string, string); 252 int Object_VarArgCall__int(Handle, string, string, string); 253 uint Object_VarArgCall__uint(Handle, string, string, string); 254 short Object_VarArgCall__short(Handle, string, string, string); 255 ushort Object_VarArgCall__ushort(Handle, string, string, string); 256 Handle Object_VarArgCall__Handle(Handle, string, string, string); 257 float Object_VarArgCall__float(Handle, string, string, string); 258 double Object_VarArgCall__double(Handle, string, string, string); 259 long Object_VarArgCall__long(Handle, string, string, string); 260 ulong Object_VarArgCall__ulong(Handle, string, string, string); 261 long getTimeStamp(); 262 263 Handle JSON_parse_string(string); 264 string JSON_stringify(Handle); 265 266 int setInterval(int ctx, int ptr, int ms); 267 void clearTimeout(int id); 268 void clearInterval(int id); 269 270 } 271 272 int setTimeout(Delegate)(Delegate del, int ms) 273 { 274 return setTimeout(del.toTuple.expand, ms); 275 } 276 277 int setInterval(Delegate)(Delegate del, int ms) 278 { 279 return setInterval(del.toTuple.expand, ms); 280 } 281 282 void exportDelegate()(string name, auto ref void delegate(Handle) del) @trusted 283 { 284 //console.log("exportDelegate(Del)"); 285 return libwasm_set__function(name, del.toTuple.expand); 286 } 287 288 void exportDelegate()(string name, auto ref void function(Handle) fun) @trusted { 289 auto del = (Handle hndl) { 290 fun(hndl); 291 }; 292 //console.log("exportDelegate(Fun)"); 293 return libwasm_set__function(name, del.toTuple.expand); 294 } 295 296 void unexportDelegate()(string name) 297 { 298 return libwasm_unset__function(name); 299 } 300 301 extern (C) 302 export 303 @assumeUsed 304 void jsCallback0(uint ctx, uint fun) @trusted 305 { 306 static struct Handler 307 { 308 nothrow: 309 union 310 { 311 void delegate() handle; 312 struct 313 { 314 void* contextPtr; 315 void* funcPtr; 316 } 317 } 318 } 319 320 Handler c; 321 c.contextPtr = cast(void*) ctx; 322 c.funcPtr = cast(void*) fun; 323 c.handle(); 324 } 325 326 extern (C) 327 export 328 @assumeUsed 329 void jsCallback(uint ctx, uint fun, Handle arg) @trusted 330 { 331 static struct Handler 332 { 333 nothrow: 334 union 335 { 336 void delegate(Handle) handle; 337 struct 338 { 339 void* contextPtr; 340 void* funcPtr; 341 } 342 } 343 } 344 345 Handler c; 346 c.contextPtr = cast(void*) ctx; 347 c.funcPtr = cast(void*) fun; 348 c.handle(arg); 349 } 350 351 @trusted extern (C) export @assumeUsed ubyte* allocString(uint bytes); 352 353 @trusted R Serialize_Object_VarArgCall(R, TupleArgs)(Handle hndl, string method, string argsdef, scope TupleArgs tupleArgs) 354 { 355 import fast.json; 356 import libwasm.rt.allocator; 357 import libwasm.bindings.Console; 358 359 /* 360 console.log("Got args:"); 361 foreach (scope arg; tupleArgs) { 362 import std.traits : isIterable; 363 static if (isIterable!(typeof(arg))) { 364 foreach (scope subarg; arg) { 365 console.log(subarg); 366 } 367 } else { 368 console.log(arg); 369 } 370 }*/ 371 char[] buf = cast(char[]) ThreadMemAllocator.allocate(serializationLength(tupleArgs)); 372 scope (exit) 373 ThreadMemAllocator.deallocate(buf); 374 auto args = cast(string) serializeJSON(buf, tupleArgs); 375 static if (is(R == string)) 376 return Object_VarArgCall__string(hndl, method, argsdef, args); 377 else static if (is(R == void)) 378 Object_VarArgCall__void(hndl, method, argsdef, args); 379 else static if (is(R == int)) 380 return Object_VarArgCall__int(hndl, method, argsdef, args); 381 else static if (is(R == Handle)) 382 return Object_VarArgCall__Handle(hndl, method, argsdef, args); 383 else static if (is(R == uint)) 384 return Object_VarArgCall__uint(hndl, method, argsdef, args); 385 else static if (is(R == long)) 386 return Object_VarArgCall__long(hndl, method, argsdef, args); 387 else static if (is(R == ulong)) 388 return Object_VarArgCall__ulong(hndl, method, argsdef, args); 389 else static if (is(R == double)) 390 return Object_VarArgCall__double(hndl, method, argsdef, args); 391 else static if (is(R == float)) 392 return Object_VarArgCall__float(hndl, method, argsdef, args); 393 else static if (is(R == ushort)) 394 return Object_VarArgCall__ushort(hndl, method, argsdef, args); 395 else static if (is(R == short)) 396 return Object_VarArgCall__short(hndl, method, argsdef, args); 397 else static if (is(R == bool)) 398 return Object_VarArgCall__bool(hndl, method, argsdef, args); 399 } 400 401 Vector!char format(string fmt, ARGS...)(ARGS args) @trusted 402 { 403 import fast.format : formattedWrite, decCharsVal; 404 import std.traits : isIntegral, isSomeString, isFloatingPoint; 405 406 size_t size_estimate = fmt.length + 16; 407 408 foreach (arg; args) 409 { 410 static if (isSomeString!(typeof(arg))) 411 { 412 size_estimate += arg.length; 413 } 414 else static if (isIntegral!(typeof(arg))) 415 { 416 size_estimate += decCharsVal(arg); 417 } 418 else static if (isFloatingPoint!(typeof(arg))) 419 { 420 size_estimate += decChars!(typeof(arg)); 421 } 422 else 423 { 424 static assert(false, "Format argument not implemented: " ~ typeof(arg).stringof); 425 } 426 } 427 428 Vector!char vec = Vector!char(size_estimate); 429 char* buf = vec.ptr; 430 char[] ret = formattedWrite!fmt(buf, args); 431 vec.length = ret.length; 432 433 return vec.move(); 434 } 435 436 @safe: 437 438 struct Eval 439 { 440 string eval_str; 441 } 442 443 // used for lodash 444 Eval eval(string eval_str) 445 { 446 return Eval(eval_str); 447 } 448 449 struct JsHandle 450 { 451 import libwasm.bindings.Console; 452 453 nothrow: 454 public Handle handle; 455 ~this() 456 { 457 if (handle > 2) 458 { 459 libwasm_removeObject(handle); 460 } 461 } 462 463 void opAssign(ref Handle handle) 464 { 465 this.handle = handle; 466 handle = 0; 467 } 468 469 auto lodash()() 470 { 471 return Lodash(this.handle, VarType.handle, 128); 472 } 473 474 this()(typeof(this) rhs) 475 { 476 handle = libwasm_copyObjectRef(rhs.handle); 477 } 478 479 this(int rhs) 480 { 481 handle = rhs; 482 } 483 484 alias handle this; 485 } 486 487 auto ptr(return scope ref JsHandle handle) @system 488 { 489 return &handle.handle; 490 } 491 492 enum JsHandle invalidHandle = JsHandle(0); 493 alias EventHandle = uint; 494 495 enum NodeType 496 { 497 a = 0, 498 abbr = 1, 499 address = 2, 500 area = 3, 501 article = 4, 502 aside = 5, 503 audio = 6, 504 b = 7, 505 base = 8, 506 bdi = 9, 507 bdo = 10, 508 blockquote = 11, 509 body_ = 12, 510 br = 13, 511 button = 14, 512 canvas = 15, 513 caption = 16, 514 cite = 17, 515 code = 18, 516 col = 19, 517 colgroup = 20, 518 data = 21, 519 datalist = 22, 520 dd = 23, 521 del = 24, 522 dfn = 25, 523 div = 26, 524 dl = 27, 525 dt = 28, 526 em = 29, 527 embed = 30, 528 fieldset = 31, 529 figcaption = 32, 530 figure = 33, 531 footer = 34, 532 form = 35, 533 h1 = 36, 534 h2 = 37, 535 h3 = 38, 536 h4 = 39, 537 h5 = 40, 538 h6 = 41, 539 head = 42, 540 header = 43, 541 hr = 44, 542 html = 45, 543 i = 46, 544 iframe = 47, 545 img = 48, 546 input = 49, 547 ins = 50, 548 kbd = 51, 549 keygen = 52, 550 label = 53, 551 legend = 54, 552 li = 55, 553 link = 56, 554 main = 57, 555 map = 58, 556 mark = 59, 557 meta = 60, 558 meter = 61, 559 nav = 62, 560 noscript = 63, 561 object = 64, 562 ol = 65, 563 optgroup = 66, 564 option = 67, 565 output = 68, 566 p = 69, 567 param = 70, 568 pre = 71, 569 progress = 72, 570 q = 73, 571 rb = 74, 572 rp = 75, 573 rt = 76, 574 rtc = 77, 575 ruby = 78, 576 s = 79, 577 samp = 80, 578 script = 81, 579 section = 82, 580 select = 83, 581 small = 84, 582 source = 85, 583 span = 86, 584 strong = 87, 585 style = 88, 586 sub = 89, 587 sup = 90, 588 table = 91, 589 tbody = 92, 590 td = 93, 591 template_ = 94, 592 textarea = 95, 593 tfoot = 96, 594 th = 97, 595 thead = 98, 596 time = 99, 597 title = 100, 598 tr = 101, 599 track = 102, 600 u = 103, 601 ul = 104, 602 var = 105, 603 video = 106, 604 wbr = 107, 605 root = 1024 // Special element used in unittests 606 } 607 608 // deprecated("Use libwasm.types.Child instead") enum child; 609 enum child; 610 enum prop; 611 enum callback; 612 enum attr; 613 struct connect(field...) 614 { 615 }; 616 struct visible(alias condition) 617 { 618 }; 619 struct inject(alias parent_name) 620 { 621 }; 622 struct entering(alias path) 623 { 624 }; 625 struct leaving(alias path) 626 { 627 }; 628 629 template isTOrPointer(T, Target) 630 { 631 enum isTOrPointer = is(T : Target) || is(T : Target*); 632 } 633 634 // TODO: implement others as well 635 enum ListenerType 636 { 637 click = 0, 638 change = 1, 639 input = 2, 640 keydown = 3, 641 keyup = 4, 642 dblclick = 5, 643 blur = 6, 644 mousemove = 7, 645 mouseup = 8, 646 mousedown = 9, 647 keypress = 10, 648 focus = 11 649 } 650 651 enum EventType 652 { 653 animation = 0, 654 audioProcessing = 1, 655 beforeUnload = 2, 656 blob = 3, 657 clipboard = 4, 658 close = 5, 659 composition = 6, 660 custom = 7, 661 deviceLight = 8, 662 deviceMotion = 9, 663 deviceOrientation = 10, 664 deviceProximity = 11, 665 drag = 12, 666 error = 13, 667 fetch = 14, 668 focus = 15, 669 gamepad = 16, 670 hashChange = 17, 671 idbVersionChange = 18, 672 input = 19, 673 keyboard = 20, 674 mediaStream = 21, 675 message = 22, 676 mouse = 23, 677 mutation = 24, 678 offlineAudioCompletion = 25, 679 pageTransition = 26, 680 paymentRequestUpdate = 27, 681 pointer = 28, 682 popState = 29, 683 progress = 30, 684 rtcDataChannel = 31, 685 rtcIdentityError = 32, 686 rtcIdentity = 33, 687 rtcPeerConnectionIce = 34, 688 storage = 35, 689 svg = 36, 690 time = 37, 691 touch = 38, 692 trackTransition = 39, 693 ui = 40, 694 userProximity = 41, 695 webGlContext = 42, 696 wheel = 43, 697 event = 44 698 } 699 700 @safe template as(Target) 701 { 702 static if (isBasicType!Target || is(Target : string)) 703 { 704 auto as(Source)(auto ref Source s) if (hasMember!(Source, "handle")) 705 { 706 mixin("return libwasm_get__" ~ Target.stringof ~ "(s.handle);"); 707 } 708 } 709 else static if (__traits(compiles, "Target.init.handle")) 710 { 711 @safe auto as(Source)(scope return ref Source s) 712 { 713 return cast(Target*)&s; 714 } 715 716 @safe auto as(Source)(Source s) if (hasMember!(Source, "handle")) 717 { 718 Handle h = s.handle; 719 s.handle = 0; 720 return Target(h); 721 } 722 } 723 } 724 725 auto toOpt(T)(return scope ref T item) @trusted 726 { 727 return Optional!(T*)(&item); 728 } 729 730 auto recastOpt(T, U)(Optional!U item) @trusted 731 { 732 if (item.empty()) 733 { 734 return Optional!T(); 735 } 736 else 737 { 738 return Optional!T.construct(item.front); 739 } 740 } 741 742 auto frontRef(T)(return scope ref T t) @trusted 743 { 744 static if (is(T : Optional!(Base*), Base)) 745 return t.front; 746 else 747 return &t.front(); 748 } 749 750 Handle getOrCreateHandle(T)(scope ref T data) @trusted 751 { 752 static if (isBasicType!T || isSomeString!T && T.stringof != "typeof(null)") 753 { 754 static if (isSomeString!T && !is(T : string)) 755 mixin("return libwasm_add__string(*cast(string*)&data);"); 756 else static if (is(T == int[])) 757 mixin("return libwasm_add__ints(data);"); 758 else static if (is(T == uint[])) 759 mixin("return libwasm_add__uints(data);"); 760 else 761 mixin("return libwasm_add__" ~ T.stringof ~ "(data);"); 762 } 763 else static if (is(T : Optional!U, U)) 764 { 765 if (data.empty) 766 return 0; 767 return data.front; 768 } 769 else 770 { 771 return cast(Handle) data; 772 } 773 } 774 775 auto dropHandle(T)(Handle data) 776 { 777 import std.traits : isBasicType; 778 779 static if (isBasicType!T || is(T : string)) 780 { 781 libwasm_removeObject(data); 782 } 783 } 784 785 template libwasmMangle(T) 786 { 787 static if (hasMember!(T, "handle") || hasMember!(T, "_parent")) 788 { 789 enum libwasmMangle = "handle"; 790 } 791 else 792 { 793 enum libwasmMangle = T.mangleof; 794 } 795 } 796 797 template BridgeType(T) 798 { 799 static if (hasMember!(T, "handle") || hasMember!(T, "_parent")) 800 { 801 alias BridgeType = JsHandle; 802 } 803 else 804 { 805 alias BridgeType = T; 806 } 807 } 808 809 mixin template ExternPromiseCallback(string funName, T, U) 810 { 811 nothrow: 812 static if (is(T == void)) 813 { 814 pragma(mangle, funName) 815 mixin("extern(C) Handle " ~ funName ~ "(Handle, U delegate() nothrow);"); 816 } 817 else 818 { 819 pragma(mangle, funName) 820 mixin("extern(C) Handle " ~ funName ~ "(Handle, U delegate(" ~ T.stringof ~ ") nothrow);"); 821 } 822 } 823 824 mixin template ExternPromiseCallback(string funName, T) 825 { 826 nothrow: 827 static if (is(T == void)) 828 { 829 pragma(mangle, funName) 830 mixin("extern(C) Handle " ~ funName ~ "(Handle, void delegate() nothrow);"); 831 } 832 else 833 { 834 pragma(mangle, funName) 835 mixin("extern(C) Handle " ~ funName ~ "(Handle, void delegate(" ~ T.stringof ~ ") nothrow);"); 836 } 837 } 838 839 auto all()(scope JsHandle[] args) { 840 Vector!Handle handles; 841 handles.reserve(args.length); 842 foreach (ref arg; args) { 843 handles ~= arg.handle; 844 } 845 846 auto handle = JsObject(libwasm_add__uints(handles[])); 847 mixin("return JsPromise!Any(libasync_promise_all__promise(handle));"); 848 } 849 auto allSettled()(scope JsHandle[] args) { 850 Vector!Handle handles; 851 handles.reserve(args.length); 852 foreach (ref arg; args) { 853 handles ~= arg.handle; 854 } 855 auto handle = JsObject(libwasm_add__uints(handles[])); 856 mixin("return JsPromise!Any(libasync_promise_allsettled__promise(handle));"); 857 } 858 auto any()(scope JsHandle[] args) { 859 Vector!Handle handles; 860 handles.reserve(args.length); 861 foreach (ref arg; args) { 862 handles ~= arg.handle; 863 } 864 auto handle = JsObject(libwasm_add__uints(handles[])); 865 mixin("return JsPromise!Any(libasync_promise_any__promise(handle));"); 866 } 867 868 struct JsPromise(T = Any) 869 { 870 alias U = Any; 871 nothrow: 872 JsHandle handle; 873 alias handle this; 874 this(Handle h) 875 { 876 this.handle = JsHandle(h); 877 } 878 879 alias JoinedType = BridgeType!T; 880 enum ResultMangled = libwasmMangle!T; 881 static if (is(T == void)) 882 { 883 alias FulfillCallback(P = void) = P delegate() nothrow; 884 alias JoinedCallback(P = void) = extern (C) P delegate() nothrow; 885 alias RejectCallback = extern (C) void delegate(U) nothrow; 886 } 887 else 888 { 889 alias FulfillCallback(P) = P delegate(T) nothrow; 890 alias JoinedCallback(P) = extern (C) P delegate(JoinedType) nothrow; 891 alias RejectCallback = extern (C) void delegate(U) nothrow; 892 } 893 894 auto then(ResultType)(scope ResultType delegate(T) nothrow cb) return scope @trusted 895 { 896 enum TMangled = libwasmMangle!T; 897 enum ResultTypeMangled = libwasmMangle!ResultType; 898 enum funName = "promise_then_" ~ TMangled.length.stringof ~ TMangled ~ ResultTypeMangled; 899 mixin ExternPromiseCallback!(funName, JoinedType, BridgeType!ResultType); 900 mixin( 901 "return JsPromise!(ResultType)(" ~ funName ~ "(handle, cast(JoinedCallback!(BridgeType!ResultType))cb));"); 902 } 903 904 auto error()(scope void delegate(U) nothrow cb) return scope @trusted 905 { 906 enum TMangled = libwasmMangle!U; 907 enum funName = "promise_error_" ~ TMangled.length.stringof ~ TMangled; 908 mixin ExternPromiseCallback!(funName, U); 909 mixin("return JsPromise!(void)(" ~ funName ~ "(handle, cast(RejectCallback)cb));"); 910 } 911 912 // todo: .Finally(()=> 913 // todo: Promise.cancel(), Promise.state() 914 915 } 916 917 /// Waits for the promise to finish 918 void await(T)(auto ref T promise) { 919 libwasm_await__void(promise.handle.handle); 920 } 921 922 struct Sequence(T) 923 { 924 nothrow: 925 JsHandle handle; 926 alias handle this; 927 this(Handle h) 928 { 929 this.handle = JsHandle(h); 930 } 931 } 932 933 struct TypedArray(T) 934 { 935 nothrow: 936 JsHandle handle; 937 alias handle this; 938 this(Handle h) 939 { 940 this.handle = JsHandle(h); 941 } 942 } 943 944 struct Int8Array 945 { 946 nothrow: 947 TypedArray!(byte) _array; 948 alias _array this; 949 this(Handle h) 950 { 951 _array = TypedArray!(byte)(h); 952 } 953 954 static auto create()(const byte[] data) 955 { 956 return Int8Array(Int8Array_Create(data)); 957 } 958 } 959 960 struct Int16Array 961 { 962 nothrow: 963 TypedArray!(short) _array; 964 alias _array this; 965 this(Handle h) 966 { 967 _array = TypedArray!(short)(h); 968 } 969 } 970 971 struct Int32Array 972 { 973 nothrow: 974 TypedArray!(int) _array; 975 alias _array this; 976 this(Handle h) 977 { 978 _array = TypedArray!(int)(h); 979 } 980 981 static auto create()(const int[] data) 982 { 983 return Int32Array(Int32Array_Create(data)); 984 } 985 } 986 987 struct Uint8Array 988 { 989 nothrow: 990 TypedArray!(ubyte) _array; 991 alias _array this; 992 this(Handle h) 993 { 994 _array = TypedArray!(ubyte)(h); 995 } 996 997 static auto create()(const ubyte[] data) 998 { 999 return Uint8Array(Uint8Array_Create(data)); 1000 } 1001 } 1002 1003 struct Uint16Array 1004 { 1005 nothrow: 1006 TypedArray!(ushort) _array; 1007 alias _array this; 1008 this(Handle h) 1009 { 1010 _array = TypedArray!(ushort)(h); 1011 } 1012 } 1013 1014 struct Uint32Array 1015 { 1016 nothrow: 1017 TypedArray!(uint) _array; 1018 alias _array this; 1019 this(Handle h) 1020 { 1021 _array = TypedArray!(uint)(h); 1022 } 1023 } 1024 1025 struct Float32Array 1026 { 1027 nothrow: 1028 TypedArray!(float) _array; 1029 alias _array this; 1030 this(Handle h) 1031 { 1032 _array = TypedArray!(float)(h); 1033 } 1034 1035 static auto create()(const float[] data) 1036 { 1037 return Float32Array(Float32Array_Create(data)); 1038 } 1039 } 1040 1041 struct Float64Array 1042 { 1043 nothrow: 1044 TypedArray!(double) _array; 1045 alias _array this; 1046 this(Handle h) 1047 { 1048 _array = TypedArray!(double)(h); 1049 } 1050 } 1051 1052 struct Uint8ClampedArray 1053 { 1054 nothrow: 1055 JsHandle handle; 1056 alias handle this; 1057 this(Handle h) 1058 { 1059 this.handle = JsHandle(h); 1060 } 1061 } 1062 1063 struct DataView 1064 { 1065 nothrow: 1066 JsHandle handle; 1067 alias handle this; 1068 this(Handle h) 1069 { 1070 this.handle = JsHandle(h); 1071 } 1072 1073 static auto create()(const ubyte[] data) 1074 { 1075 return DataView(DataView_Create(data)); 1076 } 1077 } 1078 1079 struct ArrayBuffer 1080 { 1081 nothrow: 1082 JsHandle handle; 1083 alias handle this; 1084 this(Handle h) 1085 { 1086 this.handle = JsHandle(h); 1087 } 1088 } 1089 1090 struct InputStream 1091 { 1092 nothrow: 1093 JsHandle handle; 1094 alias handle this; 1095 this(Handle h) 1096 { 1097 this.handle = JsHandle(h); 1098 } 1099 } 1100 1101 struct FrozenArray(T) 1102 { 1103 nothrow: 1104 JsHandle handle; 1105 alias handle this; 1106 this(Handle h) 1107 { 1108 this.handle = JsHandle(h); 1109 } 1110 } 1111 1112 struct Iterator(T) 1113 { 1114 nothrow: 1115 JsHandle handle; 1116 alias handle this; 1117 this(Handle h) 1118 { 1119 this.handle = JsHandle(h); 1120 } 1121 } 1122 1123 struct Record(T...) 1124 { 1125 nothrow: 1126 JsHandle handle; 1127 alias handle this; 1128 this(Handle h) 1129 { 1130 this.handle = JsHandle(h); 1131 } 1132 } 1133 1134 struct ArrayPair(T, U) 1135 { 1136 nothrow: 1137 JsHandle handle; 1138 alias handle this; 1139 this(Handle h) 1140 { 1141 this.handle = JsHandle(h); 1142 } 1143 } 1144 1145 struct Any 1146 { 1147 nothrow: 1148 JsHandle handle; 1149 alias handle this; 1150 this(Handle h) 1151 { 1152 this.handle = JsHandle(h); 1153 } 1154 } 1155 1156 struct JsObject 1157 { 1158 nothrow: 1159 JsHandle handle; 1160 alias handle this; 1161 this(Handle h) 1162 { 1163 this.handle = JsHandle(h); 1164 } 1165 1166 auto opDispatch(string name)() 1167 { 1168 return Any(libwasm_get__field(this.handle, name)); 1169 } 1170 // opIndexAssign 1171 } 1172 1173 struct JSON 1174 { 1175 nothrow: 1176 JsHandle handle; 1177 alias handle this; 1178 this(Handle h) 1179 { 1180 this.handle = JsHandle(h); 1181 } 1182 1183 auto opIndex()(string name) 1184 { 1185 return JSON(libwasm_get__field(this.handle, name)); 1186 } 1187 1188 auto opIndex()(uint idx) 1189 { 1190 return JSON(libwasm_get_idx__field(this.handle, idx)); 1191 } 1192 1193 auto as(Target)() @trusted 1194 { 1195 return .as!(Target)(this); 1196 } 1197 1198 static Handle parse()(string json) 1199 { 1200 return JSON_parse_string(json); 1201 } 1202 1203 static string stringify()(ref JSON obj) 1204 { 1205 return JSON_stringify(obj.handle); 1206 } 1207 } 1208 1209 struct BufferSource 1210 { 1211 nothrow: 1212 JsHandle handle; 1213 alias handle this; 1214 this(Handle h) 1215 { 1216 this.handle = JsHandle(h); 1217 } 1218 } 1219 1220 struct MIDIInput 1221 { 1222 nothrow: 1223 JsHandle handle; 1224 alias handle this; 1225 this(Handle h) 1226 { 1227 this.handle = JsHandle(h); 1228 } 1229 } 1230 1231 struct MIDIOutput 1232 { 1233 nothrow: 1234 JsHandle handle; 1235 alias handle this; 1236 this(Handle h) 1237 { 1238 this.handle = JsHandle(h); 1239 } 1240 } 1241 1242 struct nsISupports 1243 { 1244 nothrow: 1245 JsHandle handle; 1246 alias handle this; 1247 this(Handle h) 1248 { 1249 this.handle = JsHandle(h); 1250 } 1251 } 1252 1253 struct nsIVariant 1254 { 1255 nothrow: 1256 JsHandle handle; 1257 alias handle this; 1258 this(Handle h) 1259 { 1260 this.handle = JsHandle(h); 1261 } 1262 } 1263 1264 struct ArrayBufferView 1265 { 1266 nothrow: 1267 JsHandle handle; 1268 alias handle this; 1269 this(Handle h) 1270 { 1271 this.handle = JsHandle(h); 1272 } 1273 } 1274 1275 struct ReadableStream 1276 { 1277 nothrow: 1278 JsHandle handle; 1279 alias handle this; 1280 this(Handle h) 1281 { 1282 this.handle = JsHandle(h); 1283 } 1284 } 1285 1286 struct AudioParam 1287 { 1288 nothrow: 1289 JsHandle handle; 1290 alias handle this; 1291 this(Handle h) 1292 { 1293 this.handle = JsHandle(h); 1294 } 1295 } 1296 1297 import libwasm.bindings.Window : Window; 1298 1299 alias WindowProxy = Window; 1300 1301 extern (C) 1302 { 1303 Handle Int8Array_Create(const byte[]); 1304 Handle Int32Array_Create(const int[]); 1305 Handle Uint8Array_Create(const ubyte[]); 1306 Handle Float32Array_Create(const float[]); 1307 Handle DataView_Create(const ubyte[]); 1308 }