@@ -542,7 +542,146 @@ console.log(counter.get()); // 1
542
542
543
543
## Declarative Prototype Initialization
544
544
545
- TODO
545
+ We expect toolchains to need to configure thousands of JS prototypes and tens of thousands of methods,
546
+ so we expect there to be startup latency problems
547
+ if all the configuration is done directly via the raw ` DescriptorOptions ` API
548
+ and JS glue code as shown above.
549
+
550
+ The proposed solution is to provide a declarative method of constructing, importing,
551
+ and populating the ` DescriptorOptions ` objects.
552
+
553
+ The declarative API must support these features:
554
+
555
+ - Constructing new prototype objects
556
+ - Using existing prototype objects provided at instantiation time
557
+ - Creating prototype chains
558
+ - Synthesizing and attaching methods (including getters and setters) to prototypes
559
+
560
+ Furthermore, the design goals are to be:
561
+
562
+ - Polyfillable by generated JS glue using the underlying ` DescriptorOptions ` JS API,
563
+ i.e. to not introduce any new expressivity.
564
+
565
+ We define such an API in the form of a new custom section to be specified as part of the JS embedding.
566
+ This custom section will be used in the constructor of ` WebAssembly.Instance `
567
+ to populate the imports with additional ` DescriptorOptions ` before core instantiation
568
+ and to populate the prototypes using exported functions after core instantiation.
569
+
570
+ ### Custom Section
571
+
572
+ ```
573
+ descindex ::= u32
574
+
575
+ descriptorsec ::= section_0(descriptordata)
576
+
577
+ descriptordata ::= n:name (if n = 'descriptors')
578
+ modulename:name
579
+ vec(descriptorentry)
580
+
581
+ descriptorentry ::= 0x00 importentry
582
+ | 0x01 declentry
583
+
584
+ importentry ::= importname:name descconfig
585
+
586
+ declentry ::= protoconfig descconfig
587
+
588
+ protoconfig ::= v:vec(descindex) (if |v| <= 1)
589
+
590
+ descconfig ::= exportnames vec(methodconfig)
591
+
592
+ exportnames ::= vec(name)
593
+
594
+ methodconfig ::= kind:methodkind
595
+ methodname:name
596
+ exportname:name
597
+
598
+ methodkind ::= 0x00 => method
599
+ | 0x01 => getter
600
+ | 0x02 => setter
601
+ | 0x03 => constructor
602
+ ```
603
+
604
+ The descriptors custom section starts with ` modulename ` ,
605
+ which is the module name from which the configured ` DescriptorOptions ` values
606
+ will be imported by the Wasm module.
607
+ A module may import configured ` DescriptorOptions ` values
608
+ from multiple different module names
609
+ by including multiple descriptors sections.
610
+
611
+ Following the ` modulename ` is a sequence of ` descriptorentry ` ,
612
+ each of which describes a single ` DescriptorOptions ` value.
613
+ Each value can either be imported,
614
+ meaning that it is provided as an argument to instantiation,
615
+ or it is declared,
616
+ meaning that the instantiation procedure will create it.
617
+ A declared value can optionally specify the index of a previous value
618
+ to serve as the parent in the configured prototype chain.
619
+ Imported values are assumed to already have their prototype chain configured.
620
+
621
+ Each configured descriptor has a vector of export names.
622
+ These are the names from which the Wasm module will import the descriptor values.
623
+
624
+ Whether imported or declared,
625
+ each ` descriptorentry ` contains a vector of ` methodconfig `
626
+ describing the methods that should be attached to the prototype
627
+ after instantiation.
628
+ Each configured method can be either a
629
+ normal method, a getter, a setter, or a constructor.
630
+ Methods also have two associated names: the first their property name
631
+ in the configured prototype and the second
632
+ the name of the exported function they wrap.
633
+
634
+ All methods pass the receiver as the first argument:
635
+
636
+ ``` js
637
+ function methodname () { return exports [exportname](this , ... arguments ); }
638
+ ```
639
+
640
+ Getters and setters are additionally configured as getters and setters
641
+ when they are attached to the prototype.
642
+
643
+ Constructors are a little different.
644
+ They do not pass the receiver as a parameter to the exported function:
645
+
646
+ ``` js
647
+ function methodname () { return exports [exportname](... arguments ); }
648
+ ```
649
+
650
+ Furthermore, they are not installed on the configured prototype.
651
+ Instead, they are added to the ` exports ` object.
652
+ The configured prototype is added as the ` prototype ` property of the generated function
653
+ and the generated function is added as the ` constructor ` property of the configured prototype.
654
+
655
+ ### Instantiation
656
+
657
+ When constructing a WebAssembly instance,
658
+ the descriptors sections are first processed
659
+ to create any new declared ` DescriptorOptions ` .
660
+ Descriptor values imported by these sections are read from the main imports
661
+ argument passed to instantiation using the module names
662
+ given at the beginning of the sections.
663
+
664
+ The imports for core Wasm instantiation are then determined,
665
+ giving precedence to the exports from the descriptors sections.
666
+
667
+ After core instantiation,
668
+ the methods are populated based on the core exports.
669
+ Since this does not happen until after core instantiation,
670
+ when the exports have been made available,
671
+ imports called by the start function will be able to observe
672
+ the unpopulated prototypes that do not yet have the method properties.
673
+
674
+ If there is a decoding error in a descriptors section
675
+ or if at any point a required import or export is missing,
676
+ an error will be thrown.
677
+
678
+ > TODO: Describe the effect of the descriptors section on Module.imports and Module.exports.
679
+
680
+ > TODO: Make sure the prototypes can be read from the exports for further manual configuration.
681
+
682
+ > TODO: Consider supporting declarative static methods attached to constructors instead of methods.
683
+
684
+ > TODO: Declarative support for installing Symbol.hasInstance methods to support instanceof.
546
685
547
686
## Type Section Field Deduplication
548
687
0 commit comments