Re: Question about GetBindingValue
Hello, We found one dead part in ES5 and we're wondering whether we're missing something here. The question is about the 4th step in Section 10.2.1.2.4 GetBindingValue(N, S): 10.2.1.2.4 GetBindingValue(N,S) The concrete Environment Record method GetBindingValue for object environment records returns the value of its associated binding object's property whose name is the String value of the argument identifier N. The property should already exist but if it does not the result depends upon the value of the S argument: 1. Let envRec be the object environment record for which the method was invoked. 2. Let bindings be the binding object for envRec. 3. Let value be the result of calling the [[HasProperty]] internal method of bindings, passing N as the property name. 4. If value is false, then a. If S is false, return the value undefined, otherwise throw a ReferenceError exception. 5. Return the result of calling the [[Get]] internal method of bindings, passing N for the argument. We believe that the 4th step is unreachable. In other words, whenever GetBindingValue(N, S) is called, the result of calling the [[HasProperty]](N) is always true and here's why: Yes, that reasoning looks correct. 10.2.1.1.4 may have a similar problem but we haven't checked it yet. The only immutable bindings present in ES5 are directly initialized before user code can be executed, so yes, step 3 in 10.2.1.1.4 is never reachable in ES5. We checked with the recent ES6 draft but it seems to have the same issue. In ES6 it's actually possible to reach that step (8.1.1.2.6 GetBindingValue, step 5), albeit it's a somewhat tricky and involves doing unusual things with proxy objects: ```javascript with(new Proxy({}, { has: function(t, name) { print(has: +name); return !this.called (this.called = true); }})) { (function(){ use strict; ref })(); } ``` That program will give the following output: --- has: ref has: ref uncaught exception: ReferenceError: cannot resolve reference: ref --- Proxy objects allow you to define your own [[HasProperty]] implementation (the has method in the example above). In this case [[HasProperty]] will return `true` on the first call in order to report a binding is present in HasBinding, but then will return `false` when the binding's presence is checked the second time in GetBindingValue. Best, -- Sukyoung ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Question about GetBindingValue
On Aug 29, 2014, at 4:07 AM, André Bargull wrote: ... We checked with the recent ES6 draft but it seems to have the same issue. In ES6 it's actually possible to reach that step (8.1.1.2.6 GetBindingValue, step 5), albeit it's a somewhat tricky and involves doing unusual things with proxy objects: ,,, Proxy objects allow you to define your own [[HasProperty]] implementation (the has method in the example above). In this case [[HasProperty]] will return `true` on the first call in order to report a binding is present in HasBinding, but then will return `false` when the binding's presence is checked the second time in GetBindingValue. And in ES5, host object have similar capabilities. I believe we put this checks in specifically to make sure everything was well defined in the presence of such host objects. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Question about GetBindingValue
Thank you all for your answers! Your answers were really helpful. Best, -- Sukyoung On Aug 30, 2014, at 12:34 AM, Allen Wirfs-Brock wrote: On Aug 29, 2014, at 4:07 AM, André Bargull wrote: ... We checked with the recent ES6 draft but it seems to have the same issue. In ES6 it's actually possible to reach that step (8.1.1.2.6 GetBindingValue, step 5), albeit it's a somewhat tricky and involves doing unusual things with proxy objects: ,,, Proxy objects allow you to define your own [[HasProperty]] implementation (the has method in the example above). In this case [[HasProperty]] will return `true` on the first call in order to report a binding is present in HasBinding, but then will return `false` when the binding's presence is checked the second time in GetBindingValue. And in ES5, host object have similar capabilities. I believe we put this checks in specifically to make sure everything was well defined in the presence of such host objects. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Question about GetBindingValue
Hello, We found one dead part in ES5 and we're wondering whether we're missing something here. The question is about the 4th step in Section 10.2.1.2.4 GetBindingValue(N, S): 10.2.1.2.4 GetBindingValue(N,S) The concrete Environment Record method GetBindingValue for object environment records returns the value of its associated binding object's property whose name is the String value of the argument identifier N. The property should already exist but if it does not the result depends upon the value of the S argument: 1. Let envRec be the object environment record for which the method was invoked. 2. Let bindings be the binding object for envRec. 3. Let value be the result of calling the [[HasProperty]] internal method of bindings, passing N as the property name. 4. If value is false, then a. If S is false, return the value undefined, otherwise throw a ReferenceError exception. 5. Return the result of calling the [[Get]] internal method of bindings, passing N for the argument. We believe that the 4th step is unreachable. In other words, whenever GetBindingValue(N, S) is called, the result of calling the [[HasProperty]](N) is always true and here's why: Let's assume that we're calling GetBindingValue(N, S) where [[HasProperty]](N) is false. 1) GetBindingValue is called only by GetValue in 8.7.1. 2) 8.7.1 GetValue: Calls GetBindingValue at the 5th step only when its given argument is Reference. Otherwise, it returns the argument at step 1. 3) 8.7 The Reference Specification Type: Reference is a resolved name binding created by evaluation of an identifier in 11.1.2. 4) 11.1.2 Identifier Reference: Evaluation of an identifier is specified in 10.3.1. 5) 10.3.1 Identifier Resolution: Returns the result of calling GetIdentifierReference(lexenv, name, strict) 6) 10.2.2.1 GetIdentifierReference: 6-1) Let's assume that lexenv is not null. 6-2) Then, envRec is lexenv's environment record. 6-3) Let exists be HasBinding(N) of envRec. 6-3-1) 10.2.1.1.2 HasBinding(N): Returns false at the 3rd step. 6-3-1') 10.2.1.2.1 HasBinding(N): Returns [[HasProperty]](N) which is false by our assumption. 6-4) exists is false. 6-5) Calls GetIdentifierReference(outer, N, strict) 6-6) Let's assume that outer is null. 6-7) Returns Reference(undefined, N, strict) 7) Reference values are achieved by calling GetValue in 8.7.1. Let's get the value of the reference by calling GetValue(Reference(undefined, N, strict)). 8) 8.7.1 GetValue: 8-1) Type(Reference(undefined, N, strict)) is Reference. 8-2) base is undefined. 8-3) IsUnresolvableReference(Reference(undefined, N, strict)) is true. Throws a ReferenceError exception. Thus, it does not get to the 5th step to call GetBindingValue. 10.2.1.1.4 may have a similar problem but we haven't checked it yet. We checked with the recent ES6 draft but it seems to have the same issue. Best, -- Sukyoung ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss