Pārlūkot izejas kodu

Make LazyPropertyDescriptor generic and some prototypes more lazy (#1868)

Marko Lahma 1 gadu atpakaļ
vecāks
revīzija
1093b815af

+ 5 - 1
Jint.Tests/Runtime/PropertyDescriptorTests.cs

@@ -1,4 +1,5 @@
 using Jint.Native;
+using Jint.Native.Global;
 using Jint.Runtime.Descriptors;
 using Jint.Runtime.Descriptors.Specialized;
 using Jint.Runtime.Interop;
@@ -101,7 +102,10 @@ public class PropertyDescriptorTests
     public void LazyPropertyDescriptor()
     {
         var pd = _engine.Evaluate("globalThis").AsObject().GetOwnProperty("decodeURI");
-        if (checkType) Assert.IsType<LazyPropertyDescriptor>(pd);
+        if (checkType)
+        {
+            Assert.IsType<LazyPropertyDescriptor<GlobalObject>>(pd);
+        }
         Assert.Equal(false, pd.IsAccessorDescriptor());
         Assert.Equal(true, pd.IsDataDescriptor());
     }

+ 41 - 41
Jint/Native/Array/ArrayPrototype.cs

@@ -42,54 +42,54 @@ namespace Jint.Native.Array
             {
                 ["constructor"] = new PropertyDescriptor(_constructor, PropertyFlag.NonEnumerable),
 
-                ["at"] = new PropertyDescriptor(new ClrFunction(Engine, "at", At, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["concat"] = new PropertyDescriptor(new ClrFunction(Engine, "concat", Concat, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["copyWithin"] = new PropertyDescriptor(new ClrFunction(Engine, "copyWithin", CopyWithin, 2, PropertyFlag.Configurable), PropertyFlags),
-                ["entries"] = new PropertyDescriptor(new ClrFunction(Engine, "entries", Entries, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["every"] = new PropertyDescriptor(new ClrFunction(Engine, "every", Every, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["fill"] = new PropertyDescriptor(new ClrFunction(Engine, "fill", Fill, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["filter"] = new PropertyDescriptor(new ClrFunction(Engine, "filter", Filter, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["find"] = new PropertyDescriptor(new ClrFunction(Engine, "find", Find, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["findIndex"] = new PropertyDescriptor(new ClrFunction(Engine, "findIndex", FindIndex, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["findLast"] = new PropertyDescriptor(new ClrFunction(Engine, "findLast", FindLast, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["findLastIndex"] = new PropertyDescriptor(new ClrFunction(Engine, "findLastIndex", FindLastIndex, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["flat"] = new PropertyDescriptor(new ClrFunction(Engine, "flat", Flat, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["flatMap"] = new PropertyDescriptor(new ClrFunction(Engine, "flatMap", FlatMap, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["forEach"] = new PropertyDescriptor(new ClrFunction(Engine, "forEach", ForEach, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["includes"] = new PropertyDescriptor(new ClrFunction(Engine, "includes", Includes, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["indexOf"] = new PropertyDescriptor(new ClrFunction(Engine, "indexOf", IndexOf, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["join"] = new PropertyDescriptor(new ClrFunction(Engine, "join", Join, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["keys"] = new PropertyDescriptor(new ClrFunction(Engine, "keys", Keys, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["lastIndexOf"] = new PropertyDescriptor(new ClrFunction(Engine, "lastIndexOf", LastIndexOf, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["map"] = new PropertyDescriptor(new ClrFunction(Engine, "map", Map, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["pop"] = new PropertyDescriptor(new ClrFunction(Engine, "pop", Pop, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["push"] = new PropertyDescriptor(new ClrFunction(Engine, "push", Push, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["reduce"] = new PropertyDescriptor(new ClrFunction(Engine, "reduce", Reduce, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["reduceRight"] = new PropertyDescriptor(new ClrFunction(Engine, "reduceRight", ReduceRight, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["reverse"] = new PropertyDescriptor(new ClrFunction(Engine, "reverse", Reverse, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["shift"] = new PropertyDescriptor(new ClrFunction(Engine, "shift", Shift, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["slice"] = new PropertyDescriptor(new ClrFunction(Engine, "slice", Slice, 2, PropertyFlag.Configurable), PropertyFlags),
-                ["some"] = new PropertyDescriptor(new ClrFunction(Engine, "some", Some, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["sort"] = new PropertyDescriptor(new ClrFunction(Engine, "sort", Sort, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["splice"] = new PropertyDescriptor(new ClrFunction(Engine, "splice", Splice, 2, PropertyFlag.Configurable), PropertyFlags),
-                ["toLocaleString"] = new PropertyDescriptor(new ClrFunction(Engine, "toLocaleString", ToLocaleString, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["toReversed"] = new PropertyDescriptor(new ClrFunction(Engine, "toReversed", ToReversed, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["toSorted"] = new PropertyDescriptor(new ClrFunction(Engine, "toSorted", ToSorted, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["toSpliced"] = new PropertyDescriptor(new ClrFunction(Engine, "toSpliced", ToSpliced, 2, PropertyFlag.Configurable), PropertyFlags),
-                ["toString"] = new PropertyDescriptor(new ClrFunction(Engine, "toString", ToString, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["unshift"] = new PropertyDescriptor(new ClrFunction(Engine, "unshift", Unshift, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["values"] = new PropertyDescriptor(new ClrFunction(Engine, "values", Values, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["with"] = new PropertyDescriptor(new ClrFunction(Engine, "with", With, 2, PropertyFlag.Configurable), PropertyFlags),
+                ["at"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "at", prototype.At, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["concat"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "concat", prototype.Concat, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["copyWithin"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "copyWithin", prototype.CopyWithin, 2, PropertyFlag.Configurable), PropertyFlags),
+                ["entries"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "entries", prototype.Entries, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["every"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "every", prototype.Every, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["fill"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "fill", prototype.Fill, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["filter"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "filter", prototype.Filter, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["find"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "find", prototype.Find, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["findIndex"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "findIndex", prototype.FindIndex, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["findLast"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "findLast", prototype.FindLast, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["findLastIndex"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "findLastIndex", prototype.FindLastIndex, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["flat"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "flat", prototype.Flat, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["flatMap"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "flatMap", prototype.FlatMap, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["forEach"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "forEach", prototype.ForEach, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["includes"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "includes", prototype.Includes, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["indexOf"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "indexOf", prototype.IndexOf, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["join"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "join", prototype.Join, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["keys"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "keys", prototype.Keys, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["lastIndexOf"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "lastIndexOf", prototype.LastIndexOf, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["map"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "map", prototype.Map, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["pop"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "pop", prototype.Pop, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["push"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "push", prototype.Push, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["reduce"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "reduce", prototype.Reduce, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["reduceRight"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "reduceRight", prototype.ReduceRight, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["reverse"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "reverse", prototype.Reverse, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["shift"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "shift",prototype. Shift, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["slice"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "slice", prototype.Slice, 2, PropertyFlag.Configurable), PropertyFlags),
+                ["some"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "some", prototype.Some, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["sort"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "sort", prototype.Sort, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["splice"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "splice", prototype.Splice, 2, PropertyFlag.Configurable), PropertyFlags),
+                ["toLocaleString"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toLocaleString", prototype.ToLocaleString, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["toReversed"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toReversed", prototype.ToReversed, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["toSorted"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toSorted", prototype.ToSorted, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["toSpliced"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toSpliced", prototype.ToSpliced, 2, PropertyFlag.Configurable), PropertyFlags),
+                ["toString"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toString", prototype.ToString, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["unshift"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "unshift", prototype.Unshift, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["values"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "values", prototype.Values, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["with"] = new LazyPropertyDescriptor<ArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "with", prototype.With, 2, PropertyFlag.Configurable), PropertyFlags),
             };
             SetProperties(properties);
 
-            _originalIteratorFunction = new ClrFunction(Engine, "iterator", Values, 1);
+            _originalIteratorFunction = new ClrFunction(_engine, "iterator", Values, 1);
             var symbols = new SymbolDictionary(2)
             {
                 [GlobalSymbolRegistry.Iterator] = new PropertyDescriptor(_originalIteratorFunction, PropertyFlags),
-                [GlobalSymbolRegistry.Unscopables] = new LazyPropertyDescriptor(_engine, static state =>
+                [GlobalSymbolRegistry.Unscopables] = new LazyPropertyDescriptor<Engine>(_engine, static engine =>
                 {
-                    var unscopables = new JsObject((Engine) state!)
+                    var unscopables = new JsObject(engine)
                     {
                         _prototype = null
                     };

+ 8 - 7
Jint/Native/Function/FunctionPrototype.cs

@@ -6,6 +6,7 @@ using Jint.Native.Object;
 using Jint.Native.Symbol;
 using Jint.Runtime;
 using Jint.Runtime.Descriptors;
+using Jint.Runtime.Descriptors.Specialized;
 using Jint.Runtime.Interop;
 
 namespace Jint.Native.Function
@@ -27,15 +28,15 @@ namespace Jint.Native.Function
 
         protected override void Initialize()
         {
-            const PropertyFlag propertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
-            const PropertyFlag lengthFlags = PropertyFlag.Configurable;
+            const PropertyFlag PropertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
+            const PropertyFlag LengthFlags = PropertyFlag.Configurable;
             var properties = new PropertyDictionary(7, checkExistingKeys: false)
             {
-                ["constructor"] = new PropertyDescriptor(_realm.Intrinsics.Function, PropertyFlag.NonEnumerable),
-                ["toString"] = new PropertyDescriptor(new ClrFunction(_engine, "toString", ToString, 0, lengthFlags), propertyFlags),
-                ["apply"] = new PropertyDescriptor(new ClrFunction(_engine, "apply", Apply, 2, lengthFlags), propertyFlags),
-                ["call"] = new PropertyDescriptor(new ClrFunction(_engine, "call", CallImpl, 1, lengthFlags), propertyFlags),
-                ["bind"] = new PropertyDescriptor(new ClrFunction(_engine, "bind", Bind, 1, lengthFlags), propertyFlags),
+                ["constructor"] = new LazyPropertyDescriptor<FunctionPrototype>(this, static prototype => prototype._realm.Intrinsics.Function, PropertyFlag.NonEnumerable),
+                ["toString"] = new LazyPropertyDescriptor<FunctionPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toString", prototype.ToString, 0, LengthFlags), PropertyFlags),
+                ["apply"] = new LazyPropertyDescriptor<FunctionPrototype>(this, static prototype => new ClrFunction(prototype._engine, "apply", prototype.Apply, 2, LengthFlags), PropertyFlags),
+                ["call"] = new LazyPropertyDescriptor<FunctionPrototype>(this, static prototype => new ClrFunction(prototype._engine, "call", prototype.CallImpl, 1, LengthFlags), PropertyFlags),
+                ["bind"] = new LazyPropertyDescriptor<FunctionPrototype>(this, static prototype => new ClrFunction(prototype._engine, "bind", prototype.Bind, 1, LengthFlags), PropertyFlags),
                 ["arguments"] = new GetSetPropertyDescriptor.ThrowerPropertyDescriptor(_engine, PropertyFlag.Configurable),
                 ["caller"] = new GetSetPropertyDescriptor.ThrowerPropertyDescriptor(_engine, PropertyFlag.Configurable)
             };

+ 1 - 1
Jint/Native/Function/ScriptFunction.cs

@@ -42,7 +42,7 @@ namespace Jint.Native.Function
             : base(engine, engine.Realm, function, env, thisMode)
         {
             _prototype = proto ?? _engine.Realm.Intrinsics.Function.PrototypeObject;
-            _length = new LazyPropertyDescriptor(null, _ => JsNumber.Create(function.Initialize().Length), PropertyFlag.Configurable);
+            _length = new LazyPropertyDescriptor<JintFunctionDefinition>(function, static function => JsNumber.Create(function.Initialize().Length), PropertyFlag.Configurable);
 
             if (!function.Strict
                 && function.Function is not ArrowFunctionExpression

+ 59 - 94
Jint/Native/Global/GlobalObject.Properties.cs

@@ -83,109 +83,74 @@ public partial class GlobalObject
         const PropertyFlag PropertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
 
         var properties = new StringDictionarySlim<PropertyDescriptor>(65);
-        properties.AddDangerous(propertyAggregateError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.AggregateError, PropertyFlags));
-        properties.AddDangerous(propertyArray, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Array, PropertyFlags));
-        properties.AddDangerous(propertyArrayBuffer, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.ArrayBuffer, PropertyFlags));
-        properties.AddDangerous(propertyAtomics, new LazyPropertyDescriptor(this, static state => Undefined, PropertyFlags));
-        properties.AddDangerous(propertyBigInt, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.BigInt, PropertyFlags));
-        properties.AddDangerous(propertyBigInt64Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.BigInt64Array, PropertyFlags));
-        properties.AddDangerous(propertyBigUint64Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.BigUint64Array, PropertyFlags));
-        properties.AddDangerous(propertyBoolean, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Boolean, PropertyFlags));
-        properties.AddDangerous(propertyDataView, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.DataView, PropertyFlags));
-        properties.AddDangerous(propertyDate, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Date, PropertyFlags));
-        properties.AddDangerous(propertyError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Error, PropertyFlags));
-        properties.AddDangerous(propertyEvalError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.EvalError, PropertyFlags));
-        properties.AddDangerous(propertyFinalizationRegistry, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.FinalizationRegistry, PropertyFlags));
-        properties.AddDangerous(propertyFloat16Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Float16Array, PropertyFlags));
-        properties.AddDangerous(propertyFloat32Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Float32Array, PropertyFlags));
-        properties.AddDangerous(propertyFloat64Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Float64Array, PropertyFlags));
+        properties.AddDangerous(propertyAggregateError, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.AggregateError, PropertyFlags));
+        properties.AddDangerous(propertyArray, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Array, PropertyFlags));
+        properties.AddDangerous(propertyArrayBuffer, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.ArrayBuffer, PropertyFlags));
+        properties.AddDangerous(propertyAtomics, new LazyPropertyDescriptor<GlobalObject>(this, static _ => Undefined, PropertyFlags));
+        properties.AddDangerous(propertyBigInt, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.BigInt, PropertyFlags));
+        properties.AddDangerous(propertyBigInt64Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.BigInt64Array, PropertyFlags));
+        properties.AddDangerous(propertyBigUint64Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.BigUint64Array, PropertyFlags));
+        properties.AddDangerous(propertyBoolean, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Boolean, PropertyFlags));
+        properties.AddDangerous(propertyDataView, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.DataView, PropertyFlags));
+        properties.AddDangerous(propertyDate, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Date, PropertyFlags));
+        properties.AddDangerous(propertyError, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Error, PropertyFlags));
+        properties.AddDangerous(propertyEvalError, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.EvalError, PropertyFlags));
+        properties.AddDangerous(propertyFinalizationRegistry, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.FinalizationRegistry, PropertyFlags));
+        properties.AddDangerous(propertyFloat16Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Float16Array, PropertyFlags));
+        properties.AddDangerous(propertyFloat32Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Float32Array, PropertyFlags));
+        properties.AddDangerous(propertyFloat64Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Float64Array, PropertyFlags));
         properties.AddDangerous(propertyFunction, new PropertyDescriptor(_realm.Intrinsics.Function, PropertyFlags));
-        properties.AddDangerous(propertyGeneratorFunction, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.GeneratorFunction, PropertyFlags));
-        properties.AddDangerous(propertyInt16Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Int16Array, PropertyFlags));
-        properties.AddDangerous(propertyInt32Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Int32Array, PropertyFlags));
-        properties.AddDangerous(propertyInt8Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Int8Array, PropertyFlags));
-        // TODO properties.AddDapropertygerous(propertyIntl, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Intl, propertyFlags));
-        properties.AddDangerous(propertyJSON, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Json, PropertyFlags));
-        properties.AddDangerous(propertyMap, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Map, PropertyFlags));
-        properties.AddDangerous(propertyMath, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Math, PropertyFlags));
-        properties.AddDangerous(propertyNumber, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Number, PropertyFlags));
+        properties.AddDangerous(propertyGeneratorFunction, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.GeneratorFunction, PropertyFlags));
+        properties.AddDangerous(propertyInt16Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Int16Array, PropertyFlags));
+        properties.AddDangerous(propertyInt32Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Int32Array, PropertyFlags));
+        properties.AddDangerous(propertyInt8Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Int8Array, PropertyFlags));
+        // TODO properties.AddDapropertygerous(propertyIntl, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Intl, propertyFlags));
+        properties.AddDangerous(propertyJSON, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Json, PropertyFlags));
+        properties.AddDangerous(propertyMap, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Map, PropertyFlags));
+        properties.AddDangerous(propertyMath, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Math, PropertyFlags));
+        properties.AddDangerous(propertyNumber, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Number, PropertyFlags));
         properties.AddDangerous(propertyObject, new PropertyDescriptor(_realm.Intrinsics.Object, PropertyFlags));
-        properties.AddDangerous(propertyPromise, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Promise, PropertyFlags));
-        properties.AddDangerous(propertyProxy, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Proxy, PropertyFlags));
-        properties.AddDangerous(propertyRangeError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.RangeError, PropertyFlags));
-        properties.AddDangerous(propertyReferenceError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.ReferenceError, PropertyFlags));
-        properties.AddDangerous(propertyReflect, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Reflect, PropertyFlags));
-        properties.AddDangerous(propertyRegExp, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.RegExp, PropertyFlags));
-        properties.AddDangerous(propertySet, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Set, PropertyFlags));
-        properties.AddDangerous(propertyShadowRealm, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.ShadowRealm, PropertyFlags));
-        properties.AddDangerous(propertySharedArrayBuffer, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.SharedArrayBuffer, PropertyFlags));
-        properties.AddDangerous(propertyString, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.String, PropertyFlags));
-        properties.AddDangerous(propertySymbol, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Symbol, PropertyFlags));
-        properties.AddDangerous(propertySyntaxError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.SyntaxError, PropertyFlags));
-        properties.AddDangerous(propertyTypeError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.TypeError, PropertyFlags));
-        properties.AddDangerous(propertyTypedArray, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.TypedArray, PropertyFlags));
-        properties.AddDangerous(propertyURIError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.UriError, PropertyFlags));
-        properties.AddDangerous(propertyUint16Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Uint16Array, PropertyFlags));
-        properties.AddDangerous(propertyUint32Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Uint32Array, PropertyFlags));
-        properties.AddDangerous(propertyUint8Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Uint8Array, PropertyFlags));
-        properties.AddDangerous(propertyUint8ClampedArray, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Uint8ClampedArray, PropertyFlags));
-        properties.AddDangerous(propertyWeakMap, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.WeakMap, PropertyFlags));
-        properties.AddDangerous(propertyWeakRef, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.WeakRef, PropertyFlags));
-        properties.AddDangerous(propertyWeakSet, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.WeakSet, PropertyFlags));
+        properties.AddDangerous(propertyPromise, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Promise, PropertyFlags));
+        properties.AddDangerous(propertyProxy, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Proxy, PropertyFlags));
+        properties.AddDangerous(propertyRangeError, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.RangeError, PropertyFlags));
+        properties.AddDangerous(propertyReferenceError, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.ReferenceError, PropertyFlags));
+        properties.AddDangerous(propertyReflect, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Reflect, PropertyFlags));
+        properties.AddDangerous(propertyRegExp, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.RegExp, PropertyFlags));
+        properties.AddDangerous(propertySet, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Set, PropertyFlags));
+        properties.AddDangerous(propertyShadowRealm, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.ShadowRealm, PropertyFlags));
+        properties.AddDangerous(propertySharedArrayBuffer, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.SharedArrayBuffer, PropertyFlags));
+        properties.AddDangerous(propertyString, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.String, PropertyFlags));
+        properties.AddDangerous(propertySymbol, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Symbol, PropertyFlags));
+        properties.AddDangerous(propertySyntaxError, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.SyntaxError, PropertyFlags));
+        properties.AddDangerous(propertyTypeError, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.TypeError, PropertyFlags));
+        properties.AddDangerous(propertyTypedArray, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.TypedArray, PropertyFlags));
+        properties.AddDangerous(propertyURIError, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.UriError, PropertyFlags));
+        properties.AddDangerous(propertyUint16Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Uint16Array, PropertyFlags));
+        properties.AddDangerous(propertyUint32Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Uint32Array, PropertyFlags));
+        properties.AddDangerous(propertyUint8Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Uint8Array, PropertyFlags));
+        properties.AddDangerous(propertyUint8ClampedArray, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Uint8ClampedArray, PropertyFlags));
+        properties.AddDangerous(propertyWeakMap, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.WeakMap, PropertyFlags));
+        properties.AddDangerous(propertyWeakRef, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.WeakRef, PropertyFlags));
+        properties.AddDangerous(propertyWeakSet, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.WeakSet, PropertyFlags));
 
         properties.AddDangerous(propertyNaN, _propertyDescriptorNan);
         properties.AddDangerous(propertyInfinity, _propertyDescriptorPositiveInfinity);
         properties.AddDangerous(propertyUndefined, _propertyDescriptorUndefined);
-        properties.AddDangerous(propertyParseInt, new LazyPropertyDescriptor(this, static state => new ClrFunction(((GlobalObject) state!)._engine, "parseInt", ParseInt, 2, LengthFlags), PropertyFlags));
-        properties.AddDangerous(propertyParseFloat, new LazyPropertyDescriptor(this, static state => new ClrFunction(((GlobalObject) state!)._engine, "parseFloat", ParseFloat, 1, LengthFlags), PropertyFlags));
-        properties.AddDangerous(propertyIsNaN, new LazyPropertyDescriptor(this, static state => new ClrFunction(((GlobalObject) state!)._engine, "isNaN", IsNaN, 1, LengthFlags), PropertyFlags));
-        properties.AddDangerous(propertyIsFinite, new LazyPropertyDescriptor(this, static state => new ClrFunction(((GlobalObject) state!)._engine, "isFinite", IsFinite, 1, LengthFlags), PropertyFlags));
-
-        properties.AddDangerous(propertyDecodeURI, new LazyPropertyDescriptor(this, static state =>
-        {
-            var global = (GlobalObject) state!;
-            return new ClrFunction(global._engine, "decodeURI", global.DecodeUri, 1, LengthFlags);
-        }, PropertyFlags));
-
-        properties.AddDangerous(propertyDecodeURIComponent, new LazyPropertyDescriptor(this, static state =>
-        {
-            var global = (GlobalObject) state!;
-            return new ClrFunction(global._engine, "decodeURIComponent", global.DecodeUriComponent, 1, LengthFlags);
-        }, PropertyFlags));
-
-        properties.AddDangerous(propertyEncodeURI, new LazyPropertyDescriptor(this, static state =>
-        {
-            var global = (GlobalObject) state!;
-            return new ClrFunction(global._engine, "encodeURI", global.EncodeUri, 1, LengthFlags);
-        }, PropertyFlags));
-
-        properties.AddDangerous(propertyEncodeURIComponent, new LazyPropertyDescriptor(this, static state =>
-        {
-            var global = (GlobalObject) state!;
-            return new ClrFunction(global._engine, "encodeURIComponent", global.EncodeUriComponent, 1, LengthFlags);
-        }, PropertyFlags));
-
-        properties.AddDangerous(propertyEscape, new LazyPropertyDescriptor(this, static state =>
-        {
-            var global = (GlobalObject) state!;
-            return new ClrFunction(global._engine, "escape", global.Escape, 1, LengthFlags);
-        }, PropertyFlags));
-
-        properties.AddDangerous(propertyUnescape, new LazyPropertyDescriptor(this, static state =>
-        {
-            var global = (GlobalObject) state!;
-            return new ClrFunction(global._engine, "unescape", global.Unescape, 1, LengthFlags);
-        }, PropertyFlags));
-
+        properties.AddDangerous(propertyParseInt, new LazyPropertyDescriptor<GlobalObject>(this, static global => new ClrFunction(global._engine, "parseInt", ParseInt, 2, LengthFlags), PropertyFlags));
+        properties.AddDangerous(propertyParseFloat, new LazyPropertyDescriptor<GlobalObject>(this, static global => new ClrFunction(global._engine, "parseFloat", ParseFloat, 1, LengthFlags), PropertyFlags));
+        properties.AddDangerous(propertyIsNaN, new LazyPropertyDescriptor<GlobalObject>(this, static global => new ClrFunction(global._engine, "isNaN", IsNaN, 1, LengthFlags), PropertyFlags));
+        properties.AddDangerous(propertyIsFinite, new LazyPropertyDescriptor<GlobalObject>(this, static global => new ClrFunction(global._engine, "isFinite", IsFinite, 1, LengthFlags), PropertyFlags));
+        properties.AddDangerous(propertyDecodeURI, new LazyPropertyDescriptor<GlobalObject>(this, static global => new ClrFunction(global._engine, "decodeURI", global.DecodeUri, 1, LengthFlags), PropertyFlags));
+        properties.AddDangerous(propertyDecodeURIComponent, new LazyPropertyDescriptor<GlobalObject>(this, static global => new ClrFunction(global._engine, "decodeURIComponent", global.DecodeUriComponent, 1, LengthFlags), PropertyFlags));
+        properties.AddDangerous(propertyEncodeURI, new LazyPropertyDescriptor<GlobalObject>(this, static global => new ClrFunction(global._engine, "encodeURI", global.EncodeUri, 1, LengthFlags), PropertyFlags));
+        properties.AddDangerous(propertyEncodeURIComponent, new LazyPropertyDescriptor<GlobalObject>(this, static global => new ClrFunction(global._engine, "encodeURIComponent", global.EncodeUriComponent, 1, LengthFlags), PropertyFlags));
+        properties.AddDangerous(propertyEscape, new LazyPropertyDescriptor<GlobalObject>(this, static global => new ClrFunction(global._engine, "escape", global.Escape, 1, LengthFlags), PropertyFlags));
+        properties.AddDangerous(propertyUnescape, new LazyPropertyDescriptor<GlobalObject>(this, static global => new ClrFunction(global._engine, "unescape", global.Unescape, 1, LengthFlags), PropertyFlags));
         properties.AddDangerous(propertyGlobalThis, new PropertyDescriptor(this, PropertyFlags));
-        properties.AddDangerous(propertyEval, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Eval, PropertyFlag.Configurable | PropertyFlag.Writable));
+        properties.AddDangerous(propertyEval, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Eval, PropertyFlag.Configurable | PropertyFlag.Writable));
 
         // toString is not mentioned or actually required in spec, but some tests rely on it
-        properties.AddDangerous(propertyToString, new LazyPropertyDescriptor(this, static state =>
-        {
-            var global = (GlobalObject) state!;
-            return new ClrFunction(global._engine, "toString", global.ToStringString, 1);
-        }, PropertyFlags));
+        properties.AddDangerous(propertyToString, new LazyPropertyDescriptor<GlobalObject>(this, static global => new ClrFunction(global._engine, "toString", global.ToStringString, 1), PropertyFlags));
 
         SetProperties(properties);
     }

+ 16 - 15
Jint/Native/Object/ObjectPrototype.cs

@@ -5,6 +5,7 @@ using Jint.Native.Array;
 using Jint.Native.Symbol;
 using Jint.Runtime;
 using Jint.Runtime.Descriptors;
+using Jint.Runtime.Descriptors.Specialized;
 using Jint.Runtime.Interop;
 
 namespace Jint.Native.Object
@@ -24,17 +25,17 @@ namespace Jint.Native.Object
 
         protected override void Initialize()
         {
-            const PropertyFlag propertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
-            const PropertyFlag lengthFlags = PropertyFlag.Configurable;
+            const PropertyFlag PropertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
+            const PropertyFlag LengthFlags = PropertyFlag.Configurable;
             var properties = new PropertyDictionary(12, checkExistingKeys: false)
             {
-                ["constructor"] = new PropertyDescriptor(_constructor, propertyFlags),
-                ["__defineGetter__"] = new PropertyDescriptor(new ClrFunction(Engine, "__defineGetter__", DefineGetter, 2, lengthFlags), propertyFlags),
-                ["__defineSetter__"] = new PropertyDescriptor(new ClrFunction(Engine, "__defineSetter__", DefineSetter, 2, lengthFlags), propertyFlags),
-                ["__lookupGetter__"] = new PropertyDescriptor(new ClrFunction(Engine, "__lookupGetter__", LookupGetter, 1, lengthFlags), propertyFlags),
-                ["__lookupSetter__"] = new PropertyDescriptor(new ClrFunction(Engine, "__lookupSetter__", LookupSetter, 1, lengthFlags), propertyFlags),
+                ["constructor"] = new PropertyDescriptor(_constructor, PropertyFlags),
+                ["__defineGetter__"] = new LazyPropertyDescriptor<ObjectPrototype>(this, static prototype => new ClrFunction(prototype._engine, "__defineGetter__", prototype.DefineGetter, 2, LengthFlags), PropertyFlags),
+                ["__defineSetter__"] = new LazyPropertyDescriptor<ObjectPrototype>(this, static prototype => new ClrFunction(prototype._engine, "__defineSetter__", prototype.DefineSetter, 2, LengthFlags), PropertyFlags),
+                ["__lookupGetter__"] = new LazyPropertyDescriptor<ObjectPrototype>(this, static prototype => new ClrFunction(prototype._engine, "__lookupGetter__", prototype.LookupGetter, 1, LengthFlags), PropertyFlags),
+                ["__lookupSetter__"] = new LazyPropertyDescriptor<ObjectPrototype>(this, static prototype => new ClrFunction(prototype._engine, "__lookupSetter__", prototype.LookupSetter, 1, LengthFlags), PropertyFlags),
                 ["__proto__"] = new GetSetPropertyDescriptor(
-                    new ClrFunction(Engine, "get __proto__", (thisObject, _) => TypeConverter.ToObject(_realm, thisObject).GetPrototypeOf() ?? Null, 0, lengthFlags),
+                    new ClrFunction(Engine, "get __proto__", (thisObject, _) => TypeConverter.ToObject(_realm, thisObject).GetPrototypeOf() ?? Null, 0, LengthFlags),
                     new ClrFunction(Engine, "set __proto__", (thisObject, arguments) =>
                     {
                         TypeConverter.CheckObjectCoercible(_engine, thisObject);
@@ -51,14 +52,14 @@ namespace Jint.Native.Object
                         }
 
                         return Undefined;
-                    }, 0, lengthFlags),
+                    }, 0, LengthFlags),
                     enumerable: false, configurable: true),
-                ["toString"] = new PropertyDescriptor(new ClrFunction(Engine, "toString", ToObjectString, 0, lengthFlags), propertyFlags),
-                ["toLocaleString"] = new PropertyDescriptor(new ClrFunction(Engine, "toLocaleString", ToLocaleString, 0, lengthFlags), propertyFlags),
-                ["valueOf"] = new PropertyDescriptor(new ClrFunction(Engine, "valueOf", ValueOf, 0, lengthFlags), propertyFlags),
-                ["hasOwnProperty"] = new PropertyDescriptor(new ClrFunction(Engine, "hasOwnProperty", HasOwnProperty, 1, lengthFlags), propertyFlags),
-                ["isPrototypeOf"] = new PropertyDescriptor(new ClrFunction(Engine, "isPrototypeOf", IsPrototypeOf, 1, lengthFlags), propertyFlags),
-                ["propertyIsEnumerable"] = new PropertyDescriptor(new ClrFunction(Engine, "propertyIsEnumerable", PropertyIsEnumerable, 1, lengthFlags), propertyFlags)
+                ["toString"] = new LazyPropertyDescriptor<ObjectPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toString", prototype.ToObjectString, 0, LengthFlags), PropertyFlags),
+                ["toLocaleString"] = new LazyPropertyDescriptor<ObjectPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toLocaleString", prototype.ToLocaleString, 0, LengthFlags), PropertyFlags),
+                ["valueOf"] = new LazyPropertyDescriptor<ObjectPrototype>(this, static prototype => new ClrFunction(prototype._engine, "valueOf", prototype.ValueOf, 0, LengthFlags), PropertyFlags),
+                ["hasOwnProperty"] = new LazyPropertyDescriptor<ObjectPrototype>(this, static prototype => new ClrFunction(prototype._engine, "hasOwnProperty",prototype. HasOwnProperty, 1, LengthFlags), PropertyFlags),
+                ["isPrototypeOf"] = new LazyPropertyDescriptor<ObjectPrototype>(this, static prototype => new ClrFunction(prototype._engine, "isPrototypeOf", prototype.IsPrototypeOf, 1, LengthFlags), PropertyFlags),
+                ["propertyIsEnumerable"] = new LazyPropertyDescriptor<ObjectPrototype>(this, static prototype => new ClrFunction(prototype._engine, "propertyIsEnumerable", prototype.PropertyIsEnumerable, 1, LengthFlags), PropertyFlags)
             };
             SetProperties(properties);
         }

+ 37 - 36
Jint/Native/String/StringPrototype.cs

@@ -11,6 +11,7 @@ using Jint.Native.RegExp;
 using Jint.Native.Symbol;
 using Jint.Runtime;
 using Jint.Runtime.Descriptors;
+using Jint.Runtime.Descriptors.Specialized;
 using Jint.Runtime.Interop;
 
 namespace Jint.Native.String
@@ -42,52 +43,52 @@ namespace Jint.Native.String
             const PropertyFlag lengthFlags = PropertyFlag.Configurable;
             const PropertyFlag propertyFlags = lengthFlags | PropertyFlag.Writable;
 
-            var trimStart = new PropertyDescriptor(new ClrFunction(Engine, "trimStart", TrimStart, 0, lengthFlags), propertyFlags);
-            var trimEnd = new PropertyDescriptor(new ClrFunction(Engine, "trimEnd", TrimEnd, 0, lengthFlags), propertyFlags);
+            var trimStart = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "trimStart", prototype.TrimStart, 0, lengthFlags), propertyFlags);
+            var trimEnd = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "trimEnd", prototype.TrimEnd, 0, lengthFlags), propertyFlags);
             var properties = new PropertyDictionary(37, checkExistingKeys: false)
             {
                 ["constructor"] = new PropertyDescriptor(_constructor, PropertyFlag.NonEnumerable),
-                ["toString"] = new PropertyDescriptor(new ClrFunction(Engine, "toString", ToStringString, 0, lengthFlags), propertyFlags),
-                ["valueOf"] = new PropertyDescriptor(new ClrFunction(Engine, "valueOf", ValueOf, 0, lengthFlags), propertyFlags),
-                ["charAt"] = new PropertyDescriptor(new ClrFunction(Engine, "charAt", CharAt, 1, lengthFlags), propertyFlags),
-                ["charCodeAt"] = new PropertyDescriptor(new ClrFunction(Engine, "charCodeAt", CharCodeAt, 1, lengthFlags), propertyFlags),
-                ["codePointAt"] = new PropertyDescriptor(new ClrFunction(Engine, "codePointAt", CodePointAt, 1, lengthFlags), propertyFlags),
-                ["concat"] = new PropertyDescriptor(new ClrFunction(Engine, "concat", Concat, 1, lengthFlags), propertyFlags),
-                ["indexOf"] = new PropertyDescriptor(new ClrFunction(Engine, "indexOf", IndexOf, 1, lengthFlags), propertyFlags),
-                ["endsWith"] = new PropertyDescriptor(new ClrFunction(Engine, "endsWith", EndsWith, 1, lengthFlags), propertyFlags),
-                ["startsWith"] = new PropertyDescriptor(new ClrFunction(Engine, "startsWith", StartsWith, 1, lengthFlags), propertyFlags),
-                ["lastIndexOf"] = new PropertyDescriptor(new ClrFunction(Engine, "lastIndexOf", LastIndexOf, 1, lengthFlags), propertyFlags),
-                ["localeCompare"] = new PropertyDescriptor(new ClrFunction(Engine, "localeCompare", LocaleCompare, 1, lengthFlags), propertyFlags),
-                ["match"] = new PropertyDescriptor(new ClrFunction(Engine, "match", Match, 1, lengthFlags), propertyFlags),
-                ["matchAll"] = new PropertyDescriptor(new ClrFunction(Engine, "matchAll", MatchAll, 1, lengthFlags), propertyFlags),
-                ["replace"] = new PropertyDescriptor(new ClrFunction(Engine, "replace", Replace, 2, lengthFlags), propertyFlags),
-                ["replaceAll"] = new PropertyDescriptor(new ClrFunction(Engine, "replaceAll", ReplaceAll, 2, lengthFlags), propertyFlags),
-                ["search"] = new PropertyDescriptor(new ClrFunction(Engine, "search", Search, 1, lengthFlags), propertyFlags),
-                ["slice"] = new PropertyDescriptor(new ClrFunction(Engine, "slice", Slice, 2, lengthFlags), propertyFlags),
-                ["split"] = new PropertyDescriptor(new ClrFunction(Engine, "split", Split, 2, lengthFlags), propertyFlags),
-                ["substr"] = new PropertyDescriptor(new ClrFunction(Engine, "substr", Substr, 2), propertyFlags),
-                ["substring"] = new PropertyDescriptor(new ClrFunction(Engine, "substring", Substring, 2, lengthFlags), propertyFlags),
-                ["toLowerCase"] = new PropertyDescriptor(new ClrFunction(Engine, "toLowerCase", ToLowerCase, 0, lengthFlags), propertyFlags),
-                ["toLocaleLowerCase"] = new PropertyDescriptor(new ClrFunction(Engine, "toLocaleLowerCase", ToLocaleLowerCase, 0, lengthFlags), propertyFlags),
-                ["toUpperCase"] = new PropertyDescriptor(new ClrFunction(Engine, "toUpperCase", ToUpperCase, 0, lengthFlags), propertyFlags),
-                ["toLocaleUpperCase"] = new PropertyDescriptor(new ClrFunction(Engine, "toLocaleUpperCase", ToLocaleUpperCase, 0, lengthFlags), propertyFlags),
-                ["trim"] = new PropertyDescriptor(new ClrFunction(Engine, "trim", Trim, 0, lengthFlags), propertyFlags),
+                ["toString"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toString", prototype.ToStringString, 0, lengthFlags), propertyFlags),
+                ["valueOf"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "valueOf", prototype.ValueOf, 0, lengthFlags), propertyFlags),
+                ["charAt"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "charAt", prototype.CharAt, 1, lengthFlags), propertyFlags),
+                ["charCodeAt"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "charCodeAt", prototype.CharCodeAt, 1, lengthFlags), propertyFlags),
+                ["codePointAt"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "codePointAt", prototype.CodePointAt, 1, lengthFlags), propertyFlags),
+                ["concat"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "concat", prototype.Concat, 1, lengthFlags), propertyFlags),
+                ["indexOf"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "indexOf", prototype.IndexOf, 1, lengthFlags), propertyFlags),
+                ["endsWith"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "endsWith", prototype.EndsWith, 1, lengthFlags), propertyFlags),
+                ["startsWith"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "startsWith", prototype.StartsWith, 1, lengthFlags), propertyFlags),
+                ["lastIndexOf"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "lastIndexOf", prototype.LastIndexOf, 1, lengthFlags), propertyFlags),
+                ["localeCompare"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "localeCompare", prototype.LocaleCompare, 1, lengthFlags), propertyFlags),
+                ["match"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "match", prototype.Match, 1, lengthFlags), propertyFlags),
+                ["matchAll"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "matchAll", prototype.MatchAll, 1, lengthFlags), propertyFlags),
+                ["replace"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "replace", prototype.Replace, 2, lengthFlags), propertyFlags),
+                ["replaceAll"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "replaceAll", prototype.ReplaceAll, 2, lengthFlags), propertyFlags),
+                ["search"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "search", prototype.Search, 1, lengthFlags), propertyFlags),
+                ["slice"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "slice", prototype.Slice, 2, lengthFlags), propertyFlags),
+                ["split"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "split", prototype.Split, 2, lengthFlags), propertyFlags),
+                ["substr"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "substr", Substr, 2), propertyFlags),
+                ["substring"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "substring", prototype.Substring, 2, lengthFlags), propertyFlags),
+                ["toLowerCase"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toLowerCase", prototype.ToLowerCase, 0, lengthFlags), propertyFlags),
+                ["toLocaleLowerCase"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toLocaleLowerCase", prototype.ToLocaleLowerCase, 0, lengthFlags), propertyFlags),
+                ["toUpperCase"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toUpperCase", prototype.ToUpperCase, 0, lengthFlags), propertyFlags),
+                ["toLocaleUpperCase"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toLocaleUpperCase", prototype.ToLocaleUpperCase, 0, lengthFlags), propertyFlags),
+                ["trim"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "trim", prototype.Trim, 0, lengthFlags), propertyFlags),
                 ["trimStart"] = trimStart,
                 ["trimEnd"] = trimEnd,
                 ["trimLeft"] = trimStart,
                 ["trimRight"] = trimEnd,
-                ["padStart"] = new PropertyDescriptor(new ClrFunction(Engine, "padStart", PadStart, 1, lengthFlags), propertyFlags),
-                ["padEnd"] = new PropertyDescriptor(new ClrFunction(Engine, "padEnd", PadEnd, 1, lengthFlags), propertyFlags),
-                ["includes"] = new PropertyDescriptor(new ClrFunction(Engine, "includes", Includes, 1, lengthFlags), propertyFlags),
-                ["normalize"] = new PropertyDescriptor(new ClrFunction(Engine, "normalize", Normalize, 0, lengthFlags), propertyFlags),
-                ["repeat"] = new PropertyDescriptor(new ClrFunction(Engine, "repeat", Repeat, 1, lengthFlags), propertyFlags),
-                ["at"] = new PropertyDescriptor(new ClrFunction(Engine, "at", At, 1, lengthFlags), propertyFlags),
-                ["isWellFormed"] = new PropertyDescriptor(new ClrFunction(Engine, "isWellFormed", IsWellFormed, 0, lengthFlags), propertyFlags),
-                ["toWellFormed"] = new PropertyDescriptor(new ClrFunction(Engine, "toWellFormed", ToWellFormed, 0, lengthFlags), propertyFlags),
+                ["padStart"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "padStart", prototype.PadStart, 1, lengthFlags), propertyFlags),
+                ["padEnd"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "padEnd", prototype.PadEnd, 1, lengthFlags), propertyFlags),
+                ["includes"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "includes", prototype.Includes, 1, lengthFlags), propertyFlags),
+                ["normalize"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "normalize", prototype.Normalize, 0, lengthFlags), propertyFlags),
+                ["repeat"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "repeat", prototype.Repeat, 1, lengthFlags), propertyFlags),
+                ["at"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "at", prototype.At, 1, lengthFlags), propertyFlags),
+                ["isWellFormed"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "isWellFormed", prototype.IsWellFormed, 0, lengthFlags), propertyFlags),
+                ["toWellFormed"] = new LazyPropertyDescriptor<StringPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toWellFormed", prototype.ToWellFormed, 0, lengthFlags), propertyFlags),
             };
             SetProperties(properties);
 
-            _originalIteratorFunction = new ClrFunction(Engine, "[Symbol.iterator]", Iterator, 0, lengthFlags);
+            _originalIteratorFunction = new ClrFunction(_engine, "[Symbol.iterator]", Iterator, 0, lengthFlags);
             var symbols = new SymbolDictionary(1)
             {
                 [GlobalSymbolRegistry.Iterator] = new PropertyDescriptor(_originalIteratorFunction, propertyFlags)

+ 36 - 35
Jint/Native/TypedArray/IntrinsicTypedArrayPrototype.cs

@@ -11,6 +11,7 @@ using Jint.Native.Object;
 using Jint.Native.Symbol;
 using Jint.Runtime;
 using Jint.Runtime.Descriptors;
+using Jint.Runtime.Descriptors.Specialized;
 using Jint.Runtime.Interop;
 
 namespace Jint.Native.TypedArray
@@ -38,50 +39,50 @@ namespace Jint.Native.TypedArray
             const PropertyFlag PropertyFlags = PropertyFlag.Writable | PropertyFlag.Configurable;
             var properties = new PropertyDictionary(36, false)
             {
-                ["at"] = new(new ClrFunction(Engine, "at", At, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["at"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "at", prototype.At, 1, PropertyFlag.Configurable), PropertyFlags),
                 ["buffer"] = new GetSetPropertyDescriptor(new ClrFunction(_engine, "get buffer", Buffer, 0, LengthFlags), Undefined, PropertyFlag.Configurable),
                 ["byteLength"] = new GetSetPropertyDescriptor(new ClrFunction(_engine, "get byteLength", ByteLength, 0, LengthFlags), Undefined, PropertyFlag.Configurable),
-                ["byteOffset"] = new GetSetPropertyDescriptor(new ClrFunction(Engine, "get byteOffset", ByteOffset, 0, LengthFlags), Undefined, PropertyFlag.Configurable),
+                ["byteOffset"] = new GetSetPropertyDescriptor(new ClrFunction(_engine, "get byteOffset", ByteOffset, 0, LengthFlags), Undefined, PropertyFlag.Configurable),
                 ["constructor"] = new(_constructor, PropertyFlag.NonEnumerable),
-                ["copyWithin"] = new(new ClrFunction(Engine, "copyWithin", CopyWithin, 2, PropertyFlag.Configurable), PropertyFlags),
-                ["entries"] = new(new ClrFunction(Engine, "entries", Entries, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["every"] = new(new ClrFunction(Engine, "every", Every, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["fill"] = new(new ClrFunction(Engine, "fill", Fill, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["filter"] = new(new ClrFunction(Engine, "filter", Filter, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["find"] = new(new ClrFunction(Engine, "find", Find, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["findIndex"] = new(new ClrFunction(Engine, "findIndex", FindIndex, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["findLast"] = new(new ClrFunction(Engine, "findLast", FindLast, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["findLastIndex"] = new(new ClrFunction(Engine, "findLastIndex", FindLastIndex, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["forEach"] = new(new ClrFunction(Engine, "forEach", ForEach, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["includes"] = new(new ClrFunction(Engine, "includes", Includes, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["indexOf"] = new(new ClrFunction(Engine, "indexOf", IndexOf, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["join"] = new(new ClrFunction(Engine, "join", Join, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["keys"] = new(new ClrFunction(Engine, "keys", Keys, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["lastIndexOf"] = new(new ClrFunction(Engine, "lastIndexOf", LastIndexOf, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["length"] = new GetSetPropertyDescriptor(new ClrFunction(Engine, "get length", GetLength, 0, LengthFlags), Undefined, PropertyFlag.Configurable),
-                ["map"] = new(new ClrFunction(Engine, "map", Map, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["reduce"] = new(new ClrFunction(Engine, "reduce", Reduce, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["reduceRight"] = new(new ClrFunction(Engine, "reduceRight", ReduceRight, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["reverse"] = new(new ClrFunction(Engine, "reverse", Reverse, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["set"] = new(new ClrFunction(Engine, "set", Set, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["slice"] = new(new ClrFunction(Engine, "slice", Slice, 2, PropertyFlag.Configurable), PropertyFlags),
-                ["some"] = new(new ClrFunction(Engine, "some", Some, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["sort"] = new(new ClrFunction(Engine, "sort", Sort, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["subarray"] = new(new ClrFunction(Engine, "subarray", Subarray, 2, PropertyFlag.Configurable), PropertyFlags),
-                ["toLocaleString"] = new(new ClrFunction(Engine, "toLocaleString", ToLocaleString, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["toReversed"] = new PropertyDescriptor(new ClrFunction(Engine, "toReversed", ToReversed, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["toSorted"] = new PropertyDescriptor(new ClrFunction(Engine, "toSorted", ToSorted, 1, PropertyFlag.Configurable), PropertyFlags),
-                ["toString"] = new(new ClrFunction(Engine, "toLocaleString", _realm.Intrinsics.Array.PrototypeObject.ToString, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["values"] = new(new ClrFunction(Engine, "values", Values, 0, PropertyFlag.Configurable), PropertyFlags),
-                ["with"] = new PropertyDescriptor(new ClrFunction(Engine, "with", With, 2, PropertyFlag.Configurable), PropertyFlags),
+                ["copyWithin"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "copyWithin", prototype.CopyWithin, 2, PropertyFlag.Configurable), PropertyFlags),
+                ["entries"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "entries", prototype.Entries, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["every"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "every", prototype.Every, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["fill"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "fill", prototype.Fill, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["filter"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "filter", prototype.Filter, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["find"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "find", prototype.Find, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["findIndex"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "findIndex",prototype. FindIndex, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["findLast"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "findLast", prototype.FindLast, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["findLastIndex"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "findLastIndex", prototype.FindLastIndex, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["forEach"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "forEach", prototype.ForEach, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["includes"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "includes", prototype.Includes, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["indexOf"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "indexOf", prototype.IndexOf, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["join"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "join", prototype.Join, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["keys"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "keys", prototype.Keys, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["lastIndexOf"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "lastIndexOf", prototype.LastIndexOf, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["length"] = new GetSetPropertyDescriptor(new ClrFunction(_engine, "get length", GetLength, 0, LengthFlags), Undefined, PropertyFlag.Configurable),
+                ["map"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "map", prototype.Map, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["reduce"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "reduce", prototype.Reduce, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["reduceRight"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "reduceRight", prototype.ReduceRight, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["reverse"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "reverse", prototype.Reverse, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["set"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "set", prototype.Set, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["slice"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "slice", prototype.Slice, 2, PropertyFlag.Configurable), PropertyFlags),
+                ["some"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "some", prototype.Some, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["sort"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "sort", prototype.Sort, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["subarray"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "subarray", prototype.Subarray, 2, PropertyFlag.Configurable), PropertyFlags),
+                ["toLocaleString"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toLocaleString", prototype.ToLocaleString, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["toReversed"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toReversed", prototype.ToReversed, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["toSorted"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toSorted", prototype.ToSorted, 1, PropertyFlag.Configurable), PropertyFlags),
+                ["toString"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "toLocaleString", prototype._realm.Intrinsics.Array.PrototypeObject.ToString, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["values"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "values", prototype.Values, 0, PropertyFlag.Configurable), PropertyFlags),
+                ["with"] = new LazyPropertyDescriptor<IntrinsicTypedArrayPrototype>(this, static prototype => new ClrFunction(prototype._engine, "with", prototype.With, 2, PropertyFlag.Configurable), PropertyFlags),
             };
             SetProperties(properties);
 
-            _originalIteratorFunction = new ClrFunction(Engine, "iterator", Values, 1);
+            _originalIteratorFunction = new ClrFunction(_engine, "iterator", Values, 1);
             var symbols = new SymbolDictionary(2)
             {
                 [GlobalSymbolRegistry.Iterator] = new(_originalIteratorFunction, PropertyFlags),
-                [GlobalSymbolRegistry.ToStringTag] = new GetSetPropertyDescriptor(new ClrFunction(Engine, "get [Symbol.toStringTag]", ToStringTag, 0, PropertyFlag.Configurable), Undefined, PropertyFlag.Configurable)
+                [GlobalSymbolRegistry.ToStringTag] = new GetSetPropertyDescriptor(new ClrFunction(_engine, "get [Symbol.toStringTag]", ToStringTag, 0, PropertyFlag.Configurable), Undefined, PropertyFlag.Configurable)
             };
             SetSymbols(symbols);
         }

+ 17 - 18
Jint/Runtime/Descriptors/Specialized/LazyPropertyDescriptor.cs

@@ -1,26 +1,25 @@
 using System.Runtime.CompilerServices;
 using Jint.Native;
 
-namespace Jint.Runtime.Descriptors.Specialized
+namespace Jint.Runtime.Descriptors.Specialized;
+
+internal sealed class LazyPropertyDescriptor<T> : PropertyDescriptor
 {
-    internal sealed class LazyPropertyDescriptor : PropertyDescriptor
-    {
-        private readonly object? _state;
-        private readonly Func<object?, JsValue> _resolver;
+    private readonly T _state;
+    private readonly Func<T, JsValue> _resolver;
 
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        internal LazyPropertyDescriptor(object? state, Func<object?, JsValue> resolver, PropertyFlag flags)
-            : base(null, flags | PropertyFlag.CustomJsValue)
-        {
-            _flags &= ~PropertyFlag.NonData;
-            _state = state;
-            _resolver = resolver;
-        }
+    [MethodImpl(MethodImplOptions.AggressiveInlining)]
+    internal LazyPropertyDescriptor(T state, Func<T, JsValue> resolver, PropertyFlag flags)
+        : base(null, flags | PropertyFlag.CustomJsValue)
+    {
+        _flags &= ~PropertyFlag.NonData;
+        _state = state;
+        _resolver = resolver;
+    }
 
-        protected internal override JsValue? CustomValue
-        {
-            get => _value ??= _resolver(_state);
-            set => _value = value;
-        }
+    protected internal override JsValue? CustomValue
+    {
+        get => _value ??= _resolver(_state);
+        set => _value = value;
     }
 }