HI Mark,

The fix of allowing primitive Reference base type is ok for implementations such as SpiderMonkey, which already does this for the built-in methods on String.prototype, Number.prototype, and Boolean.prototype to avoid the overhead of wrappers when calling native methods on string, number, and boolean primitive values.

Practical implementations do not use anything like a Reference type, instead specializing lvalue and rvalue contexts to preserve reference bases in VM registers.

FWIW, this is what ES4 did too. Types string and String shared a prototype object; calls on a primitive |this| to methods inherited from the shared prototype entailed no coercion or wrapping. ES4 did not use Reference internal types with non-primitive bases to specify this binding. So the fix is harmonious from the start.


 On Jan 8, 2009, at 7:43 PM, Mark S. Miller wrote:

We'd change the spec of GetValue and delete to do a ToObject() on its base in order to look up the property. However, this coercion of the base is ephemeral. The wrapper cannot escape, and ToObject has no observable side effects, so it is just an explanatory device equivalent to saying: "If the base is a string, we lookup the property on String.prototype. If it's a number, ..."

In the face of multiple global objects, the spec must say *which* original value of String, e.g., is used, or really, how the right global object is found. It should be found by following the scope chain to the last object, the global for the currently active code (not the same as the global for the caller or grand caller or top level script that's being evaluated).

Web browser embedding example:

* Window A script source:

String.prototype.trim = function () { return this.replace(/^\s*(\S*)\s* $/, "$1"); }

function wraptrim(s) { return s.trim(); }


* Window B script source (assume window A is denoted by winA here):

alert(winA.wraptrim(" hello   "));


Ok, what it there is no inherited accessor? In ES3.1-nonstrict, this should remain a no op. However, there are two equivalent means of explaining this no op behavior: 1) mutating an unobservable wrapper, or 2) a failed assignment. Recall that nonstrict failed assignments are silent, so either explanation suffices. However, if we use explanation #2, we give ourselves license to have this fail with a thrown error in strict code.

A strict error for attempting to set an ad-hoc property could be helpful. All else equal, when using primitives and objects interchangeably in generic code, the silent case is less likely to be helpful in my experience.

Generic programming with primtiives more often wants to *read* undefined when getting a non-existent property, and "object detect" without having to try/catch. This common use case is not served by strict mode in ES3.1, right? You'd have to change code to try/catch around such probes.

/be
_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to