Przeglądaj źródła

Improving get/set implementation

Sebastien Ros 12 lat temu
rodzic
commit
23176c9e6b

+ 37 - 8
Jint/Engine.cs

@@ -331,22 +331,51 @@ namespace Jint
                 return value;
             }
 
+            var baseValue = reference.GetBase();
+
             if (reference.IsUnresolvableReference())
             {
                 throw new JavaScriptException(ReferenceError);
             }
 
-            var baseValue = reference.GetBase();
-
-            var record = baseValue as EnvironmentRecord;
-
-            if (record != null)
+            if (reference.IsPropertyReference())
             {
-                return record.GetBindingValue(reference.GetReferencedName(), reference.IsStrict());
+                if (reference.HasPrimitiveBase() == false)
+                {
+                    var o = TypeConverter.ToObject(this, baseValue);
+                    return o.Get(reference.GetReferencedName());
+                }
+                else
+                {
+                    var o = TypeConverter.ToObject(this, baseValue);
+                    var desc = o.GetProperty(reference.GetReferencedName());
+                    if (desc == PropertyDescriptor.Undefined)
+                    {
+                        return Undefined.Instance;
+                    }
+                    if (desc.IsDataDescriptor())
+                    {
+                        return desc.As<DataDescriptor>().Value;
+                    }
+                    var getter = desc.As<AccessorDescriptor>().Get;
+                    if (getter == null)
+                    {
+                        return Undefined.Instance;
+                    }
+                    return getter.Call(baseValue, Arguments.Empty);
+                }
             }
+            else
+            {
+                var record = baseValue as EnvironmentRecord;
+
+                if (record == null)
+                {
+                    throw new ArgumentException();
+                }
 
-            var o = TypeConverter.ToObject(this, baseValue);
-            return o.Get(reference.GetReferencedName());
+                return record.GetBindingValue(reference.GetReferencedName(), reference.IsStrict());    
+            }
         }
 
         /// <summary>

+ 1 - 1
Jint/Native/Object/ObjectInstance.cs

@@ -452,7 +452,7 @@ namespace Jint.Native.Object
             else if (current.IsAccessorDescriptor() && desc.IsAccessorDescriptor())
             {
                 var ca = current.As<AccessorDescriptor>();
-                var da = current.As<AccessorDescriptor>();
+                var da = desc.As<AccessorDescriptor>();
 
                 if (!current.Configurable)
                 {

+ 0 - 1
Jint/Runtime/Descriptors/AccessorDescriptor.cs

@@ -1,5 +1,4 @@
 using Jint.Native;
-using Jint.Native.Function;
 
 namespace Jint.Runtime.Descriptors
 {

+ 28 - 2
Jint/Runtime/ExpressionIntepreter.cs

@@ -686,9 +686,35 @@ namespace Jint.Runtime
                         throw new JavaScriptException(_engine.SyntaxError);
                     }
 
-                    if (previousIsAccessor && propIsAccessor && ((previous.As<AccessorDescriptor>().Get != null && propDesc.As<AccessorDescriptor>().Get != null) || (previous.As<AccessorDescriptor>().Set != null && propDesc.As<AccessorDescriptor>().Set != null)))
+                    if (previousIsAccessor && propIsAccessor)
                     {
-                        throw new JavaScriptException(_engine.SyntaxError);
+                        var previousAccessor = previous.As<AccessorDescriptor>();
+                        var propAccessor = propDesc.As<AccessorDescriptor>();
+
+                        if (propAccessor.Set != null)
+                        {
+                            if (previousAccessor.Set != null)
+                            {
+                                throw new JavaScriptException(_engine.SyntaxError);
+                            }
+
+                            if (previousAccessor.Get != null)
+                            {
+                                propAccessor.Get = previousAccessor.Get;
+                            }
+                        }
+                        else if (propAccessor.Get != null)
+                        {
+                            if (previousAccessor.Get != null)
+                            {
+                                throw new JavaScriptException(_engine.SyntaxError);
+                            }
+
+                            if (previousAccessor.Set != null)
+                            {
+                                propAccessor.Set = previousAccessor.Set;
+                            }
+                        }
                     }
                 }