فهرست منبع

Support caching of string instances in script preparation (#1678)

Marko Lahma 1 سال پیش
والد
کامیت
675ad495ce

+ 4 - 1
Jint.Benchmark/EngineComparisonBenchmark.cs

@@ -93,6 +93,9 @@ public class EngineComparisonBenchmark
     public void YantraJS()
     {
         var engine = new YantraJS.Core.JSContext();
-        engine.Eval(_files[FileName]);
+        // By default YantraJS is strict mode only, in strict mode
+        // we need to pass `this` explicitly in global context
+        // if script is expecting global context as `this`
+        engine.Eval(_files[FileName], null, engine);
     }
 }

+ 5 - 1
Jint/Engine.Ast.cs

@@ -1,5 +1,6 @@
 using Esprima;
 using Esprima.Ast;
+using Jint.Native;
 using Jint.Runtime.Environments;
 using Jint.Runtime.Interpreter;
 using Jint.Runtime.Interpreter.Expressions;
@@ -54,7 +55,7 @@ public partial class Engine
 
                         if (!_bindingNames.TryGetValue(name, out var bindingName))
                         {
-                            _bindingNames[name] = bindingName = new EnvironmentRecord.BindingName(name);
+                            _bindingNames[name] = bindingName = new EnvironmentRecord.BindingName(JsString.CachedCreate(name));
                         }
 
                         node.AssociatedData = bindingName;
@@ -63,6 +64,9 @@ public partial class Engine
                 case Nodes.Literal:
                     node.AssociatedData = JintLiteralExpression.ConvertToJsValue((Literal) node);
                     break;
+                case Nodes.MemberExpression:
+                    node.AssociatedData = JintMemberExpression.InitializeDeterminedProperty((MemberExpression) node, cache: true);
+                    break;
                 case Nodes.ArrowFunctionExpression:
                 case Nodes.FunctionDeclaration:
                 case Nodes.FunctionExpression:

+ 1 - 1
Jint/Engine.cs

@@ -641,7 +641,7 @@ namespace Jint
 
         private bool TryHandleStringValue(JsValue property, JsString s, ref ObjectInstance? o, out JsValue jsValue)
         {
-            if (property == CommonProperties.Length)
+            if (CommonProperties.Length.Equals(property))
             {
                 jsValue = JsNumber.Create((uint) s.Length);
                 return true;

+ 15 - 15
Jint/Native/Array/ArrayInstance.cs

@@ -107,7 +107,7 @@ namespace Jint.Native.Array
 
         public sealed override bool DefineOwnProperty(JsValue property, PropertyDescriptor desc)
         {
-            if (property == CommonProperties.Length)
+            if (CommonProperties.Length.Equals(property))
             {
                 return DefineLength(desc);
             }
@@ -296,7 +296,7 @@ namespace Jint.Native.Array
 
         protected sealed override void AddProperty(JsValue property, PropertyDescriptor descriptor)
         {
-            if (property == CommonProperties.Length)
+            if (CommonProperties.Length.Equals(property ))
             {
                 _length = descriptor;
                 return;
@@ -307,7 +307,7 @@ namespace Jint.Native.Array
 
         protected sealed override bool TryGetProperty(JsValue property, [NotNullWhen(true)] out PropertyDescriptor? descriptor)
         {
-            if (property == CommonProperties.Length)
+            if (CommonProperties.Length.Equals(property))
             {
                 descriptor = _length;
                 return _length != null;
@@ -416,7 +416,7 @@ namespace Jint.Native.Array
 
         public sealed override PropertyDescriptor GetOwnProperty(JsValue property)
         {
-            if (property == CommonProperties.Length)
+            if (CommonProperties.Length.Equals(property))
             {
                 return _length ?? PropertyDescriptor.Undefined;
             }
@@ -451,7 +451,7 @@ namespace Jint.Native.Array
                 return value;
             }
 
-            if (property == CommonProperties.Length)
+            if (CommonProperties.Length.Equals(property))
             {
                 var length = _length?._value;
                 if (length is not null)
@@ -468,13 +468,13 @@ namespace Jint.Native.Array
             var isSafeSelfTarget = IsSafeSelfTarget(receiver);
             if (isSafeSelfTarget && CanUseFastAccess)
             {
-                if (IsArrayIndex(property, out var index))
+                if (!ReferenceEquals(property, CommonProperties.Length) && IsArrayIndex(property, out var index))
                 {
                     SetIndexValue(index, value, updateLength: true);
                     return true;
                 }
 
-                if (property == CommonProperties.Length
+                if (CommonProperties.Length.Equals(property)
                     && _length is { Writable: true }
                     && value is JsNumber jsNumber
                     && jsNumber.IsInteger()
@@ -532,7 +532,7 @@ namespace Jint.Native.Array
             {
                 WriteArrayValue(index, desc);
             }
-            else if (property == CommonProperties.Length)
+            else if (CommonProperties.Length.Equals(property))
             {
                 _length = desc;
             }
@@ -564,33 +564,33 @@ namespace Jint.Native.Array
             }
         }
 
-        public sealed override void RemoveOwnProperty(JsValue p)
+        public sealed override void RemoveOwnProperty(JsValue property)
         {
-            if (IsArrayIndex(p, out var index))
+            if (IsArrayIndex(property, out var index))
             {
                 Delete(index);
             }
 
-            if (p == CommonProperties.Length)
+            if (CommonProperties.Length.Equals(property))
             {
                 _length = null;
             }
 
-            base.RemoveOwnProperty(p);
+            base.RemoveOwnProperty(property);
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal static bool IsArrayIndex(JsValue p, out uint index)
         {
-            if (p is JsNumber number)
+            if (p.IsNumber())
             {
-                var value = number._value;
+                var value = ((JsNumber) p)._value;
                 var intValue = (uint) value;
                 index = intValue;
                 return value == intValue && intValue != uint.MaxValue;
             }
 
-            index = ParseArrayIndex(p.ToString());
+            index = !p.IsSymbol() ? ParseArrayIndex(p.ToString()) : uint.MaxValue;
             return index != uint.MaxValue;
 
             // 15.4 - Use an optimized version of the specification

+ 12 - 12
Jint/Native/Function/FunctionInstance.cs

@@ -126,15 +126,15 @@ namespace Jint.Native.Function
 
         public override PropertyDescriptor GetOwnProperty(JsValue property)
         {
-            if (property == CommonProperties.Prototype)
+            if (CommonProperties.Prototype.Equals(property))
             {
                 return _prototypeDescriptor ?? PropertyDescriptor.Undefined;
             }
-            if (property == CommonProperties.Length)
+            if (CommonProperties.Length.Equals(property))
             {
                 return _length ?? PropertyDescriptor.Undefined;
             }
-            if (property == CommonProperties.Name)
+            if (CommonProperties.Name.Equals(property))
             {
                 return _nameDescriptor ?? PropertyDescriptor.Undefined;
             }
@@ -144,15 +144,15 @@ namespace Jint.Native.Function
 
         protected internal override void SetOwnProperty(JsValue property, PropertyDescriptor desc)
         {
-            if (property == CommonProperties.Prototype)
+            if (CommonProperties.Prototype.Equals(property))
             {
                 _prototypeDescriptor = desc;
             }
-            else if (property == CommonProperties.Length)
+            else if (CommonProperties.Length.Equals(property))
             {
                 _length = desc;
             }
-            else if (property == CommonProperties.Name)
+            else if (CommonProperties.Name.Equals(property))
             {
                 _nameDescriptor = desc;
             }
@@ -164,15 +164,15 @@ namespace Jint.Native.Function
 
         public override void RemoveOwnProperty(JsValue property)
         {
-            if (property == CommonProperties.Prototype)
+            if (CommonProperties.Prototype.Equals(property))
             {
                 _prototypeDescriptor = null;
             }
-            if (property == CommonProperties.Length)
+            if (CommonProperties.Length.Equals(property))
             {
                 _length = null;
             }
-            if (property == CommonProperties.Name)
+            if (CommonProperties.Name.Equals(property))
             {
                 _nameDescriptor = null;
             }
@@ -401,7 +401,7 @@ namespace Jint.Native.Function
 
             public override PropertyDescriptor GetOwnProperty(JsValue property)
             {
-                if (property == CommonProperties.Constructor)
+                if (CommonProperties.Constructor.Equals(property))
                 {
                     return _constructor ?? PropertyDescriptor.Undefined;
                 }
@@ -411,7 +411,7 @@ namespace Jint.Native.Function
 
             protected internal override void SetOwnProperty(JsValue property, PropertyDescriptor desc)
             {
-                if (property == CommonProperties.Constructor)
+                if (CommonProperties.Constructor.Equals(property))
                 {
                     _constructor = desc;
                 }
@@ -423,7 +423,7 @@ namespace Jint.Native.Function
 
             public override void RemoveOwnProperty(JsValue property)
             {
-                if (property == CommonProperties.Constructor)
+                if (CommonProperties.Constructor.Equals(property))
                 {
                     _constructor = null;
                 }

+ 2 - 2
Jint/Native/Iterator/IteratorResult.cs

@@ -32,12 +32,12 @@ internal sealed class IteratorResult : ObjectInstance
 
     public override JsValue Get(JsValue property, JsValue receiver)
     {
-        if (property == CommonProperties.Value)
+        if (CommonProperties.Value.Equals(property))
         {
             return _value;
         }
 
-        if (property == CommonProperties.Done)
+        if (CommonProperties.Done.Equals(property))
         {
             return _done;
         }

+ 50 - 17
Jint/Native/JsString.cs

@@ -1,3 +1,4 @@
+using System.Collections.Concurrent;
 using System.Diagnostics;
 using System.Text;
 using Jint.Runtime;
@@ -12,27 +13,29 @@ public class JsString : JsValue, IEquatable<JsString>, IEquatable<string>
     private static readonly JsString[] _charToStringJsValue;
     private static readonly JsString[] _intToStringJsValue;
 
-    public static readonly JsString Empty = new JsString("");
-    internal static readonly JsString NullString = new JsString("null");
-    internal static readonly JsString UndefinedString = new JsString("undefined");
-    internal static readonly JsString ObjectString = new JsString("object");
-    internal static readonly JsString FunctionString = new JsString("function");
-    internal static readonly JsString BooleanString = new JsString("boolean");
-    internal static readonly JsString StringString = new JsString("string");
-    internal static readonly JsString NumberString = new JsString("number");
-    internal static readonly JsString BigIntString = new JsString("bigint");
-    internal static readonly JsString SymbolString = new JsString("symbol");
-    internal static readonly JsString DefaultString = new JsString("default");
-    internal static readonly JsString NumberZeroString = new JsString("0");
-    internal static readonly JsString NumberOneString = new JsString("1");
-    internal static readonly JsString TrueString = new JsString("true");
-    internal static readonly JsString FalseString = new JsString("false");
-    internal static readonly JsString LengthString = new JsString("length");
-    internal static readonly JsValue CommaString = new JsString(",");
+    public static readonly JsString Empty;
+    internal static readonly JsString NullString;
+    internal static readonly JsString UndefinedString;
+    internal static readonly JsString ObjectString;
+    internal static readonly JsString FunctionString;
+    internal static readonly JsString BooleanString;
+    internal static readonly JsString StringString;
+    internal static readonly JsString NumberString;
+    internal static readonly JsString BigIntString;
+    internal static readonly JsString SymbolString;
+    internal static readonly JsString DefaultString;
+    internal static readonly JsString NumberZeroString;
+    internal static readonly JsString NumberOneString;
+    internal static readonly JsString TrueString;
+    internal static readonly JsString FalseString;
+    internal static readonly JsString LengthString;
+    internal static readonly JsValue CommaString;
 
     [DebuggerBrowsable(DebuggerBrowsableState.Never)]
     internal string _value;
 
+    private static ConcurrentDictionary<string, JsString> _stringCache;
+
     static JsString()
     {
         _charToJsValue = new JsString[AsciiMax + 1];
@@ -49,6 +52,26 @@ public class JsString : JsValue, IEquatable<JsString>, IEquatable<string>
         {
             _intToStringJsValue[i] = new JsString(TypeConverter.ToString(i));
         }
+
+
+        _stringCache = new ConcurrentDictionary<string, JsString>();
+        Empty = new JsString("", InternalTypes.String);
+        NullString = CachedCreate("null");
+        UndefinedString = CachedCreate("undefined");
+        ObjectString = CachedCreate("object");
+        FunctionString = CachedCreate("function");
+        BooleanString = CachedCreate("boolean");
+        StringString = CachedCreate("string");
+        NumberString = CachedCreate("number");
+        BigIntString = CachedCreate("bigint");
+        SymbolString = CachedCreate("symbol");
+        DefaultString = CachedCreate("default");
+        NumberZeroString = CachedCreate("0");
+        NumberOneString = CachedCreate("1");
+        TrueString = CachedCreate("true");
+        FalseString = CachedCreate("false");
+        LengthString = CachedCreate("length");
+        CommaString = CachedCreate(",");
     }
 
     public JsString(string value) : this(value, InternalTypes.String)
@@ -146,6 +169,16 @@ public class JsString : JsValue, IEquatable<JsString>, IEquatable<string>
         return new JsString(value);
     }
 
+    internal static JsString CachedCreate(string value)
+    {
+        if (value.Length < 2)
+        {
+            return Create(value);
+        }
+
+        return _stringCache.GetOrAdd(value, static x => new JsString(x));
+    }
+
     internal static JsString Create(char value)
     {
         var temp = _charToJsValue;

+ 2 - 2
Jint/Native/Map/JsMap.cs

@@ -18,7 +18,7 @@ internal sealed class JsMap : ObjectInstance
 
     public override PropertyDescriptor GetOwnProperty(JsValue property)
     {
-        if (property == CommonProperties.Size)
+        if (CommonProperties.Size.Equals(property))
         {
             return new PropertyDescriptor(_map.Count, PropertyFlag.AllForbidden);
         }
@@ -28,7 +28,7 @@ internal sealed class JsMap : ObjectInstance
 
     protected override bool TryGetProperty(JsValue property, [NotNullWhen(true)] out PropertyDescriptor? descriptor)
     {
-        if (property == CommonProperties.Size)
+        if (CommonProperties.Size.Equals(property))
         {
             descriptor = new PropertyDescriptor(_map.Count, PropertyFlag.AllForbidden);
             return true;

+ 1 - 1
Jint/Native/Proxy/JsProxy.cs

@@ -128,7 +128,7 @@ namespace Jint.Native.Proxy
             AssertTargetNotRevoked(property);
             var target = _target;
 
-            if (property == KeyFunctionRevoke || !TryCallHandler(TrapGet, new[] { target, TypeConverter.ToPropertyKey(property), receiver }, out var result))
+            if (KeyFunctionRevoke.Equals(property) || !TryCallHandler(TrapGet, new[] { target, TypeConverter.ToPropertyKey(property), receiver }, out var result))
             {
                 return target.Get(property, receiver);
             }

+ 2 - 2
Jint/Native/RegExp/JsRegExp.cs

@@ -78,7 +78,7 @@ namespace Jint.Native.RegExp
 
         public override PropertyDescriptor GetOwnProperty(JsValue property)
         {
-            if (property == PropertyLastIndex)
+            if (PropertyLastIndex.Equals(property))
             {
                 return _prototypeDescriptor ?? PropertyDescriptor.Undefined;
             }
@@ -88,7 +88,7 @@ namespace Jint.Native.RegExp
 
         protected internal override void SetOwnProperty(JsValue property, PropertyDescriptor desc)
         {
-            if (property == PropertyLastIndex)
+            if (PropertyLastIndex.Equals(property))
             {
                 _prototypeDescriptor = desc;
                 return;

+ 2 - 2
Jint/Native/Set/JsSet.cs

@@ -16,7 +16,7 @@ internal sealed class JsSet : ObjectInstance
 
     public override PropertyDescriptor GetOwnProperty(JsValue property)
     {
-        if (property == CommonProperties.Size)
+        if (CommonProperties.Size.Equals(property))
         {
             return new PropertyDescriptor(_set.Count, PropertyFlag.AllForbidden);
         }
@@ -26,7 +26,7 @@ internal sealed class JsSet : ObjectInstance
 
     protected override bool TryGetProperty(JsValue property, [NotNullWhen(true)] out PropertyDescriptor? descriptor)
     {
-        if (property == CommonProperties.Size)
+        if (CommonProperties.Size.Equals(property))
         {
             descriptor = new PropertyDescriptor(_set.Count, PropertyFlag.AllForbidden);
             return true;

+ 4 - 4
Jint/Native/String/StringInstance.cs

@@ -35,12 +35,12 @@ internal class StringInstance : ObjectInstance, IPrimitiveInstance
 
     public sealed override PropertyDescriptor GetOwnProperty(JsValue property)
     {
-        if (property == CommonProperties.Infinity)
+        if (CommonProperties.Infinity.Equals(property))
         {
             return PropertyDescriptor.Undefined;
         }
 
-        if (property == CommonProperties.Length)
+        if (CommonProperties.Length.Equals(property))
         {
             return _length ?? PropertyDescriptor.Undefined;
         }
@@ -107,7 +107,7 @@ internal class StringInstance : ObjectInstance, IPrimitiveInstance
 
     protected internal sealed override void SetOwnProperty(JsValue property, PropertyDescriptor desc)
     {
-        if (property == CommonProperties.Length)
+        if (CommonProperties.Length.Equals(property))
         {
             _length = desc;
         }
@@ -119,7 +119,7 @@ internal class StringInstance : ObjectInstance, IPrimitiveInstance
 
     public sealed override void RemoveOwnProperty(JsValue property)
     {
-        if (property == CommonProperties.Length)
+        if (CommonProperties.Length.Equals(property))
         {
             _length = null;
         }

+ 21 - 21
Jint/Runtime/CommonProperties.cs

@@ -4,26 +4,26 @@ namespace Jint.Runtime
 {
     internal static class CommonProperties
     {
-        internal static readonly JsString Arguments = new JsString("arguments");
-        internal static readonly JsString Caller = new JsString("caller");
-        internal static readonly JsString Callee = new JsString("callee");
-        internal static readonly JsString Constructor = new JsString("constructor");
-        internal static readonly JsString Eval = new JsString("eval");
-        internal static readonly JsString Infinity = new JsString("Infinity");
-        internal static readonly JsString Length = new JsString("length");
-        internal static readonly JsString Name = new JsString("name");
-        internal static readonly JsString Prototype = new JsString("prototype");
-        internal static readonly JsString Size = new JsString("size");
-        internal static readonly JsString Next = new JsString("next");
-        internal static readonly JsString Done = new JsString("done");
-        internal static readonly JsString Value = new JsString("value");
-        internal static readonly JsString Return = new JsString("return");
-        internal static readonly JsString Set = new JsString("set");
-        internal static readonly JsString Get = new JsString("get");
-        internal static readonly JsString Writable = new JsString("writable");
-        internal static readonly JsString Enumerable = new JsString("enumerable");
-        internal static readonly JsString Configurable = new JsString("configurable");
-        internal static readonly JsString Stack = new JsString("stack");
-        internal static readonly JsString Message = new JsString("message");
+        internal static readonly JsString Arguments = JsString.CachedCreate("arguments");
+        internal static readonly JsString Caller = JsString.CachedCreate("caller");
+        internal static readonly JsString Callee = JsString.CachedCreate("callee");
+        internal static readonly JsString Constructor = JsString.CachedCreate("constructor");
+        internal static readonly JsString Eval = JsString.CachedCreate("eval");
+        internal static readonly JsString Infinity = JsString.CachedCreate("Infinity");
+        internal static readonly JsString Length = JsString.CachedCreate("length");
+        internal static readonly JsString Name = JsString.CachedCreate("name");
+        internal static readonly JsString Prototype = JsString.CachedCreate("prototype");
+        internal static readonly JsString Size = JsString.CachedCreate("size");
+        internal static readonly JsString Next = JsString.CachedCreate("next");
+        internal static readonly JsString Done = JsString.CachedCreate("done");
+        internal static readonly JsString Value = JsString.CachedCreate("value");
+        internal static readonly JsString Return = JsString.CachedCreate("return");
+        internal static readonly JsString Set = JsString.CachedCreate("set");
+        internal static readonly JsString Get = JsString.CachedCreate("get");
+        internal static readonly JsString Writable = JsString.CachedCreate("writable");
+        internal static readonly JsString Enumerable = JsString.CachedCreate("enumerable");
+        internal static readonly JsString Configurable = JsString.CachedCreate("configurable");
+        internal static readonly JsString Stack = JsString.CachedCreate("stack");
+        internal static readonly JsString Message = JsString.CachedCreate("message");
     }
 }

+ 11 - 0
Jint/Runtime/Environments/EnvironmentRecord.cs

@@ -130,6 +130,17 @@ namespace Jint.Runtime.Environments
                     CalculatedValue = Undefined;
                 }
             }
+
+            public BindingName(JsString value)
+            {
+                var key = (Key) value.ToString();
+                Key = key;
+                Value = value;
+                if (key == KnownKeys.Undefined)
+                {
+                    CalculatedValue = Undefined;
+                }
+            }
         }
 
         private sealed class EnvironmentRecordDebugView

+ 1 - 1
Jint/Runtime/Interpreter/Expressions/JintCallExpression.cs

@@ -115,7 +115,7 @@ namespace Jint.Runtime.Interpreter.Expressions
             if (ReferenceEquals(func, engine.Realm.Intrinsics.Eval)
                 && referenceRecord != null
                 && !referenceRecord.IsPropertyReference
-                && referenceRecord.ReferencedName == CommonProperties.Eval)
+                && CommonProperties.Eval.Equals(referenceRecord.ReferencedName))
             {
                 return HandleEval(context, func, engine, referenceRecord);
             }

+ 1 - 1
Jint/Runtime/Interpreter/Expressions/JintIdentifierExpression.cs

@@ -109,6 +109,6 @@ internal sealed class JintIdentifierExpression : JintExpression
     [MethodImpl(MethodImplOptions.NoInlining)]
     private void ThrowNotInitialized(Engine engine)
     {
-        ExceptionHelper.ThrowReferenceError(engine.Realm, _identifier.Key.Name + " has not been initialized");
+        ExceptionHelper.ThrowReferenceError(engine.Realm, $"{_identifier.Key.Name} has not been initialized");
     }
 }

+ 20 - 13
Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs

@@ -16,38 +16,45 @@ namespace Jint.Runtime.Interpreter.Expressions
         private JsValue? _determinedProperty;
         private bool _initialized;
 
+        private static readonly JsValue _nullMarker = new JsString("NULL MARKER");
+
         public JintMemberExpression(MemberExpression expression) : base(expression)
         {
             _memberExpression = (MemberExpression) _expression;
         }
 
-        private void Initialize()
+        internal static JsValue InitializeDeterminedProperty(MemberExpression expression, bool cache)
         {
-            _objectExpression = Build(_memberExpression.Object);
-
-            if (!_memberExpression.Computed)
+            JsValue? property = null;
+            if (!expression.Computed)
             {
-                if (_memberExpression.Property is Identifier identifier)
+                if (expression.Property is Identifier identifier)
                 {
-                    _determinedProperty = identifier.Name;
+                    property = cache ? JsString.CachedCreate(identifier.Name) : JsString.Create(identifier.Name);
                 }
             }
-            else if (_memberExpression.Property.Type == Nodes.Literal)
+            else if (expression.Property.Type == Nodes.Literal)
             {
-                _determinedProperty = JintLiteralExpression.ConvertToJsValue((Literal) _memberExpression.Property);
+                property = JintLiteralExpression.ConvertToJsValue((Literal) expression.Property);
             }
 
-            if (_determinedProperty is null)
-            {
-                _propertyExpression = Build(_memberExpression.Property);
-            }
+            return property ?? _nullMarker;
         }
 
         protected override object EvaluateInternal(EvaluationContext context)
         {
             if (!_initialized)
             {
-                Initialize();
+                _objectExpression = Build(_memberExpression.Object);
+
+                _determinedProperty ??= _expression.AssociatedData as JsValue ?? InitializeDeterminedProperty(_memberExpression, cache: false);
+
+                if (ReferenceEquals(_determinedProperty, _nullMarker))
+                {
+                    _propertyExpression = Build(_memberExpression.Property);
+                    _determinedProperty = null;
+                }
+
                 _initialized = true;
             }
 

+ 1 - 1
Jint/Runtime/References/Reference.cs

@@ -97,7 +97,7 @@ public sealed class Reference
     {
         if (_strict
             && (_base._type & InternalTypes.ObjectEnvironmentRecord) != 0
-            && (_referencedName == CommonProperties.Eval || _referencedName == CommonProperties.Arguments))
+            && (CommonProperties.Eval.Equals(_referencedName) || CommonProperties.Arguments.Equals(_referencedName)))
         {
             ExceptionHelper.ThrowSyntaxError(realm);
         }