@@ -21,24 +21,31 @@ use super::{
2121 property_builder:: { self , PropertyBuilder } ,
2222} ;
2323
24+ #[ doc( hidden) ]
2425#[ derive( Default , Clone , Copy ) ]
2526pub struct NoLength ;
2627
28+ #[ doc( hidden) ]
2729#[ derive( Clone , Copy ) ]
2830pub struct CreatorLength ( u8 ) ;
2931
32+ #[ doc( hidden) ]
3033#[ derive( Default , Clone , Copy ) ]
3134pub struct NoName ;
3235
36+ #[ doc( hidden) ]
3337#[ derive( Clone , Copy ) ]
3438pub struct CreatorName ( String < ' static > ) ;
3539
40+ #[ doc( hidden) ]
3641#[ derive( Default , Clone , Copy ) ]
3742pub struct NoBehaviour ;
3843
44+ #[ doc( hidden) ]
3945#[ derive( Clone , Copy ) ]
4046pub struct CreatorBehaviour ( Behaviour ) ;
4147
48+ /// Builder struct for creating builtin functions in embedders.
4249pub struct BuiltinFunctionBuilder < ' agent , P , L , N , B , Pr > {
4350 pub ( crate ) agent : & ' agent mut Agent ,
4451 this : BuiltinFunction < ' static > ,
@@ -54,6 +61,7 @@ pub struct BuiltinFunctionBuilder<'agent, P, L, N, B, Pr> {
5461impl < ' agent >
5562 BuiltinFunctionBuilder < ' agent , NoPrototype , NoLength , NoName , NoBehaviour , NoProperties >
5663{
64+ /// Create a new builtin function builder.
5765 #[ must_use]
5866 pub fn new < T : Builtin > (
5967 agent : & ' agent mut Agent ,
@@ -80,6 +88,7 @@ impl<'agent>
8088 }
8189 }
8290
91+ /// Create a new builtin getter function builder.
8392 #[ must_use]
8493 pub fn new_getter < T : BuiltinGetter > (
8594 agent : & ' agent mut Agent ,
@@ -106,6 +115,7 @@ impl<'agent>
106115 }
107116 }
108117
118+ /// Create a new builtin setter function builder.
109119 #[ must_use]
110120 pub fn new_setter < T : BuiltinSetter > (
111121 agent : & ' agent mut Agent ,
@@ -192,27 +202,8 @@ impl<'agent>
192202 }
193203}
194204
195- impl < ' agent , P , L , N , Pr > BuiltinFunctionBuilder < ' agent , P , L , N , NoBehaviour , Pr > {
196- #[ must_use]
197- pub fn with_behaviour (
198- self ,
199- behaviour : Behaviour ,
200- ) -> BuiltinFunctionBuilder < ' agent , P , L , N , CreatorBehaviour , Pr > {
201- BuiltinFunctionBuilder {
202- agent : self . agent ,
203- this : self . this ,
204- backing_object : self . backing_object ,
205- realm : self . realm ,
206- prototype : self . prototype ,
207- length : self . length ,
208- name : self . name ,
209- behaviour : CreatorBehaviour ( behaviour) ,
210- properties : self . properties ,
211- }
212- }
213- }
214-
215205impl < ' agent , L , N , B , Pr > BuiltinFunctionBuilder < ' agent , NoPrototype , L , N , B , Pr > {
206+ /// Set the function's prototype.
216207 #[ must_use]
217208 pub fn with_prototype < T : Copy + Into < Object < ' static > > > (
218209 self ,
@@ -244,6 +235,7 @@ impl<'agent, L, N, B, Pr> BuiltinFunctionBuilder<'agent, NoPrototype, L, N, B, P
244235 }
245236 }
246237
238+ /// Set the function's prototype into `null`.
247239 #[ must_use]
248240 pub fn with_null_prototype ( self ) -> BuiltinFunctionBuilder < ' agent , NoPrototype , L , N , B , Pr > {
249241 let backing_object = if self . backing_object . is_none ( ) {
@@ -265,53 +257,19 @@ impl<'agent, L, N, B, Pr> BuiltinFunctionBuilder<'agent, NoPrototype, L, N, B, P
265257 }
266258}
267259
268- impl < ' agent , P , N , B , Pr > BuiltinFunctionBuilder < ' agent , P , NoLength , N , B , Pr > {
269- #[ must_use]
270- pub fn with_length (
271- self ,
272- length : u8 ,
273- ) -> BuiltinFunctionBuilder < ' agent , P , CreatorLength , N , B , Pr > {
274- BuiltinFunctionBuilder {
275- agent : self . agent ,
276- this : self . this ,
277- backing_object : self . backing_object ,
278- realm : self . realm ,
279- prototype : self . prototype ,
280- length : CreatorLength ( length) ,
281- name : self . name ,
282- behaviour : self . behaviour ,
283- properties : self . properties ,
284- }
285- }
286- }
287-
288- impl < ' agent , P , L , B , Pr > BuiltinFunctionBuilder < ' agent , P , L , NoName , B , Pr > {
289- #[ must_use]
290- pub fn with_name (
291- self ,
292- name : String < ' static > ,
293- ) -> BuiltinFunctionBuilder < ' agent , P , L , CreatorName , B , Pr > {
294- BuiltinFunctionBuilder {
295- agent : self . agent ,
296- this : self . this ,
297- backing_object : self . backing_object ,
298- realm : self . realm ,
299- prototype : self . prototype ,
300- length : self . length ,
301- name : CreatorName ( name) ,
302- behaviour : self . behaviour ,
303- properties : self . properties ,
304- }
305- }
306- }
307-
308260impl < P , L , B , Pr > BuiltinFunctionBuilder < ' _ , P , L , CreatorName , B , Pr > {
309261 pub ( crate ) fn get_name ( & self ) -> String < ' static > {
310262 self . name . 0
311263 }
312264}
313265
314266impl < ' agent , P , B > BuiltinFunctionBuilder < ' agent , P , CreatorLength , CreatorName , B , NoProperties > {
267+ /// Set the property capacity of the builder.
268+ ///
269+ /// # Panics
270+ ///
271+ /// The builder panics if the number of properties set is less or more than
272+ /// the set capacity.
315273 #[ must_use]
316274 pub fn with_property_capacity (
317275 self ,
@@ -321,7 +279,8 @@ impl<'agent, P, B> BuiltinFunctionBuilder<'agent, P, CreatorLength, CreatorName,
321279 self . backing_object
322280 . unwrap_or_else ( || OrdinaryObject :: new_uninitialised ( self . agent ) ) ,
323281 ) ;
324- let mut property_vector = Vec :: with_capacity ( cap + 2 ) ;
282+ let mut property_vector = vec ! [ ] ;
283+ property_vector. reserve_exact ( cap + 2 ) ;
325284 property_vector. push ( (
326285 PropertyKey :: from ( BUILTIN_STRING_MEMORY . length ) ,
327286 Some ( ElementDescriptor :: ReadOnlyUnenumerableConfigurableData ) ,
@@ -344,96 +303,25 @@ impl<'agent, P, B> BuiltinFunctionBuilder<'agent, P, CreatorLength, CreatorName,
344303 properties : CreatorProperties ( property_vector) ,
345304 }
346305 }
347-
348- #[ must_use]
349- pub fn with_data_property (
350- self ,
351- key : PropertyKey < ' static > ,
352- value : Value < ' static > ,
353- ) -> BuiltinFunctionBuilder < ' agent , P , CreatorLength , CreatorName , B , CreatorProperties > {
354- let backing_object = Some (
355- self . backing_object
356- . unwrap_or_else ( || OrdinaryObject :: new_uninitialised ( self . agent ) ) ,
357- ) ;
358- let property_vector = vec ! [
359- (
360- PropertyKey :: from( BUILTIN_STRING_MEMORY . length) ,
361- Some ( ElementDescriptor :: ReadOnlyUnenumerableConfigurableData ) ,
362- Some ( self . length. 0 . into( ) ) ,
363- ) ,
364- (
365- PropertyKey :: from( BUILTIN_STRING_MEMORY . name) ,
366- Some ( ElementDescriptor :: ReadOnlyUnenumerableConfigurableData ) ,
367- Some ( self . name. 0 . unbind( ) . into( ) ) ,
368- ) ,
369- ( key. unbind( ) , None , Some ( value. unbind( ) ) ) ,
370- ] ;
371- BuiltinFunctionBuilder {
372- agent : self . agent ,
373- this : self . this ,
374- backing_object,
375- realm : self . realm ,
376- prototype : self . prototype ,
377- length : self . length ,
378- name : self . name ,
379- behaviour : self . behaviour ,
380- properties : CreatorProperties ( property_vector) ,
381- }
382- }
383-
384- #[ must_use]
385- pub fn with_property (
386- self ,
387- creator : impl FnOnce (
388- PropertyBuilder < ' _ , property_builder:: NoKey , property_builder:: NoDefinition > ,
389- ) -> (
390- PropertyKey < ' static > ,
391- Option < ElementDescriptor < ' static > > ,
392- Option < Value < ' static > > ,
393- ) ,
394- ) -> BuiltinFunctionBuilder < ' agent , P , CreatorLength , CreatorName , B , CreatorProperties > {
395- let backing_object = Some (
396- self . backing_object
397- . unwrap_or_else ( || OrdinaryObject :: new_uninitialised ( self . agent ) ) ,
398- ) ;
399- let property = {
400- let builder = PropertyBuilder :: new ( self . agent ) ;
401- creator ( builder)
402- } ;
403- let property_vector = vec ! [
404- (
405- PropertyKey :: from( BUILTIN_STRING_MEMORY . length) ,
406- Some ( ElementDescriptor :: ReadOnlyUnenumerableConfigurableData ) ,
407- Some ( self . length. 0 . into( ) ) ,
408- ) ,
409- (
410- PropertyKey :: from( BUILTIN_STRING_MEMORY . name) ,
411- Some ( ElementDescriptor :: ReadOnlyUnenumerableConfigurableData ) ,
412- Some ( self . name. 0 . unbind( ) . into( ) ) ,
413- ) ,
414- property,
415- ] ;
416- BuiltinFunctionBuilder {
417- agent : self . agent ,
418- this : self . this ,
419- backing_object,
420- realm : self . realm ,
421- prototype : self . prototype ,
422- length : self . length ,
423- name : self . name ,
424- behaviour : self . behaviour ,
425- properties : CreatorProperties ( property_vector) ,
426- }
427- }
428306}
429307
430308impl < ' agent , P , L , N , B > BuiltinFunctionBuilder < ' agent , P , L , N , B , CreatorProperties > {
309+ /// Adds a [data property] to the builtin function.
310+ ///
311+ /// # Panics
312+ ///
313+ /// Panics if the number of properties set is more than the set capacity.
314+ ///
315+ /// [data property]: https://tc39.es/ecma262/#sec-object-type
431316 #[ must_use]
432317 pub fn with_data_property (
433318 mut self ,
434319 key : PropertyKey < ' static > ,
435320 value : Value < ' static > ,
436321 ) -> BuiltinFunctionBuilder < ' agent , P , L , N , B , CreatorProperties > {
322+ if self . properties . 0 . spare_capacity_mut ( ) . is_empty ( ) {
323+ panic ! ( "BuiltinFunctionBuilder::with_property_capacity value exceeded" ) ;
324+ }
437325 self . properties . 0 . push ( ( key, None , Some ( value. unbind ( ) ) ) ) ;
438326 BuiltinFunctionBuilder {
439327 agent : self . agent ,
@@ -448,6 +336,11 @@ impl<'agent, P, L, N, B> BuiltinFunctionBuilder<'agent, P, L, N, B, CreatorPrope
448336 }
449337 }
450338
339+ /// Builds a property to the builtin function.
340+ ///
341+ /// # Panics
342+ ///
343+ /// Panics if the number of properties set is more than the set capacity.
451344 #[ must_use]
452345 pub fn with_property (
453346 mut self ,
@@ -459,6 +352,9 @@ impl<'agent, P, L, N, B> BuiltinFunctionBuilder<'agent, P, L, N, B, CreatorPrope
459352 Option < Value < ' static > > ,
460353 ) ,
461354 ) -> BuiltinFunctionBuilder < ' agent , P , L , N , B , CreatorProperties > {
355+ if self . properties . 0 . spare_capacity_mut ( ) . is_empty ( ) {
356+ panic ! ( "BuiltinFunctionBuilder::with_property_capacity value exceeded" ) ;
357+ }
462358 let builder = PropertyBuilder :: new ( self . agent ) ;
463359 let property = creator ( builder) ;
464360 self . properties . 0 . push ( property) ;
@@ -475,8 +371,17 @@ impl<'agent, P, L, N, B> BuiltinFunctionBuilder<'agent, P, L, N, B, CreatorPrope
475371 }
476372 }
477373
374+ /// Adds an unconfigurable, unenumerable, read-only `prototype` property on
375+ /// the builtin function.
376+ ///
377+ /// # Panics
378+ ///
379+ /// Panics if the number of properties set is more than the set capacity.
478380 #[ must_use]
479381 pub fn with_prototype_property ( mut self , prototype : Object < ' static > ) -> Self {
382+ if self . properties . 0 . spare_capacity_mut ( ) . is_empty ( ) {
383+ panic ! ( "BuiltinFunctionBuilder::with_property_capacity value exceeded" ) ;
384+ }
480385 let property = PropertyBuilder :: new ( self . agent )
481386 . with_configurable ( false )
482387 . with_enumerable ( false )
@@ -497,8 +402,16 @@ impl<'agent, P, L, N, B> BuiltinFunctionBuilder<'agent, P, L, N, B, CreatorPrope
497402 }
498403 }
499404
405+ /// Adds a builtin function as a property on this builtin function.
406+ ///
407+ /// # Panics
408+ ///
409+ /// Panics if the number of properties set is more than the set capacity.
500410 #[ must_use]
501411 pub fn with_builtin_function_property < T : Builtin > ( mut self ) -> Self {
412+ if self . properties . 0 . spare_capacity_mut ( ) . is_empty ( ) {
413+ panic ! ( "BuiltinFunctionBuilder::with_property_capacity value exceeded" ) ;
414+ }
502415 let ( value, key) = {
503416 let mut builder = BuiltinFunctionBuilder :: new :: < T > ( self . agent , self . realm ) ;
504417 let name = T :: KEY . unwrap_or_else ( || PropertyKey :: from ( builder. get_name ( ) ) ) ;
@@ -527,8 +440,16 @@ impl<'agent, P, L, N, B> BuiltinFunctionBuilder<'agent, P, L, N, B, CreatorPrope
527440 }
528441 }
529442
443+ /// Adds a builtin getter function as a property on this builtin function.
444+ ///
445+ /// # Panics
446+ ///
447+ /// Panics if the number of properties set is more than the set capacity.
530448 #[ must_use]
531449 pub fn with_builtin_function_getter_property < T : BuiltinGetter > ( mut self ) -> Self {
450+ if self . properties . 0 . spare_capacity_mut ( ) . is_empty ( ) {
451+ panic ! ( "BuiltinFunctionBuilder::with_property_capacity value exceeded" ) ;
452+ }
532453 let getter_function = BuiltinFunctionBuilder :: new :: < T > ( self . agent , self . realm )
533454 . build ( )
534455 . into ( ) ;
563484 NoProperties ,
564485 >
565486{
487+ /// Builds the builtin function.
566488 pub fn build ( & mut self ) -> BuiltinFunction < ' static > {
567489 let data = BuiltinFunctionHeapData {
568490 object_index : None ,
593515 CreatorProperties ,
594516 >
595517{
518+ /// Builds the builtin function.
596519 pub fn build ( self ) -> BuiltinFunction < ' static > {
597520 let Self {
598521 agent,
@@ -645,6 +568,7 @@ impl<T: Into<Object<'static>>>
645568 CreatorProperties ,
646569 >
647570{
571+ /// Builds the builtin function.
648572 pub fn build ( self ) -> BuiltinFunction < ' static > {
649573 let Self {
650574 agent,
0 commit comments