@@ -19,7 +19,7 @@ use crate::{
19
19
internal_methods:: get_prototype_from_constructor, JsObject , NativeObject , Object ,
20
20
ObjectData ,
21
21
} ,
22
- object:: { ConstructorBuilder , FunctionBuilder , Ref , RefMut } ,
22
+ object:: { ConstructorBuilder , FunctionBuilder , JsFunction , PrivateElement , Ref , RefMut } ,
23
23
property:: { Attribute , PropertyDescriptor , PropertyKey } ,
24
24
symbol:: WellKnownSymbols ,
25
25
syntax:: { ast:: node:: FormalParameterList , Parser } ,
@@ -108,7 +108,13 @@ impl ThisMode {
108
108
}
109
109
}
110
110
111
- #[ derive( Debug , Trace , Finalize , PartialEq , Clone ) ]
111
+ /// Represents the `[[ConstructorKind]]` internal slot of function objects.
112
+ ///
113
+ /// More information:
114
+ /// - [ECMAScript specification][spec]
115
+ ///
116
+ /// [spec]: https://tc39.es/ecma262/#sec-ecmascript-function-objects
117
+ #[ derive( Clone , Copy , Debug , PartialEq ) ]
112
118
pub enum ConstructorKind {
113
119
Base ,
114
120
Derived ,
@@ -126,6 +132,18 @@ impl ConstructorKind {
126
132
}
127
133
}
128
134
135
+ /// Record containing the field definition of classes.
136
+ ///
137
+ /// More information:
138
+ /// - [ECMAScript specification][spec]
139
+ ///
140
+ /// [spec]: https://tc39.es/ecma262/#sec-classfielddefinition-record-specification-type
141
+ #[ derive( Clone , Debug , Trace , Finalize ) ]
142
+ pub enum ClassFieldDefinition {
143
+ Public ( PropertyKey , JsFunction ) ,
144
+ Private ( Sym , JsFunction ) ,
145
+ }
146
+
129
147
/// Wrapper for `Gc<GcCell<dyn NativeObject>>` that allows passing additional
130
148
/// captures through a `Copy` closure.
131
149
///
@@ -189,6 +207,19 @@ pub enum Function {
189
207
Ordinary {
190
208
code : Gc < crate :: vm:: CodeBlock > ,
191
209
environments : DeclarativeEnvironmentStack ,
210
+
211
+ /// The `[[ConstructorKind]]` internal slot.
212
+ #[ unsafe_ignore_trace]
213
+ constructor_kind : ConstructorKind ,
214
+
215
+ /// The `[[HomeObject]]` internal slot.
216
+ home_object : Option < JsObject > ,
217
+
218
+ /// The `[[Fields]]` internal slot.
219
+ fields : Vec < ClassFieldDefinition > ,
220
+
221
+ /// The `[[PrivateMethods]]` internal slot.
222
+ private_methods : Vec < ( Sym , PrivateElement ) > ,
192
223
} ,
193
224
Generator {
194
225
code : Gc < crate :: vm:: CodeBlock > ,
@@ -210,6 +241,79 @@ impl Function {
210
241
Self :: Ordinary { code, .. } | Self :: Generator { code, .. } => code. constructor ,
211
242
}
212
243
}
244
+
245
+ /// Returns true if the function object is a derived constructor.
246
+ pub ( crate ) fn is_derived_constructor ( & self ) -> bool {
247
+ if let Self :: Ordinary {
248
+ constructor_kind, ..
249
+ } = self
250
+ {
251
+ constructor_kind. is_derived ( )
252
+ } else {
253
+ false
254
+ }
255
+ }
256
+
257
+ /// Returns a reference to the function `[[HomeObject]]` slot if present.
258
+ pub ( crate ) fn get_home_object ( & self ) -> Option < & JsObject > {
259
+ if let Self :: Ordinary { home_object, .. } = self {
260
+ home_object. as_ref ( )
261
+ } else {
262
+ None
263
+ }
264
+ }
265
+
266
+ /// Sets the `[[HomeObject]]` slot if present.
267
+ pub ( crate ) fn set_home_object ( & mut self , object : JsObject ) {
268
+ if let Self :: Ordinary { home_object, .. } = self {
269
+ * home_object = Some ( object) ;
270
+ }
271
+ }
272
+
273
+ /// Returns the values of the `[[Fields]]` internal slot.
274
+ pub ( crate ) fn get_fields ( & self ) -> & [ ClassFieldDefinition ] {
275
+ if let Self :: Ordinary { fields, .. } = self {
276
+ fields
277
+ } else {
278
+ & [ ]
279
+ }
280
+ }
281
+
282
+ /// Pushes a value to the `[[Fields]]` internal slot if present.
283
+ pub ( crate ) fn push_field ( & mut self , key : PropertyKey , value : JsFunction ) {
284
+ if let Self :: Ordinary { fields, .. } = self {
285
+ fields. push ( ClassFieldDefinition :: Public ( key, value) ) ;
286
+ }
287
+ }
288
+
289
+ /// Pushes a private value to the `[[Fields]]` internal slot if present.
290
+ pub ( crate ) fn push_field_private ( & mut self , key : Sym , value : JsFunction ) {
291
+ if let Self :: Ordinary { fields, .. } = self {
292
+ fields. push ( ClassFieldDefinition :: Private ( key, value) ) ;
293
+ }
294
+ }
295
+
296
+ /// Returns the values of the `[[PrivateMethods]]` internal slot.
297
+ pub ( crate ) fn get_private_methods ( & self ) -> & [ ( Sym , PrivateElement ) ] {
298
+ if let Self :: Ordinary {
299
+ private_methods, ..
300
+ } = self
301
+ {
302
+ private_methods
303
+ } else {
304
+ & [ ]
305
+ }
306
+ }
307
+
308
+ /// Pushes a private method to the `[[PrivateMethods]]` internal slot if present.
309
+ pub ( crate ) fn push_private_method ( & mut self , name : Sym , method : PrivateElement ) {
310
+ if let Self :: Ordinary {
311
+ private_methods, ..
312
+ } = self
313
+ {
314
+ private_methods. push ( ( name, method) ) ;
315
+ }
316
+ }
213
317
}
214
318
215
319
/// Creates a new member function of a `Object` or `prototype`.
0 commit comments