Subclassing ES6 objects with ES5 syntax.

Mark S. Miller erights at
Wed Apr 29 17:00:45 UTC 2015

I have not responded on list yet because I haven't yet been able to find
the time to absorb this thread. But since Allen mentioned it, what I wrote

The invariant I am interested in:

In a realm where we (the trusted defender who runs first) make Promise
defensive as follows

* Freeze everything primordial, as SES does

* Make a DefensivePromise subclass of Promise that differs minimally,
hopefully only by ensuring that its instances are frozen.

* "Promise = DefensivePromise;" do "Promise" below refers to

* Freezing whitelisted global properties, as SES currently does for ES5
globals, but for ES6 including "Promise"

then it must be the case that


for an anything provided by a potential attacker, when executed in the
middle of a turn does not call callback during that turn. If it calls
anycallback at all, it calls it back *as* a later turn, i.e., in a later
turn starting from an empty stack.

On Wed, Apr 29, 2015 at 9:49 AM, Allen Wirfs-Brock <allen at>

> On Apr 29, 2015, at 8:44 AM, C. Scott Ananian wrote:
> On Wed, Apr 29, 2015 at 1:06 AM, Brendan Eich <brendan at> wrote:
>> Kevin Smith wrote:
>>> So what would the ideal Promise.resolve semantics do?  I'm not sure,
>>> maybe use SpeciesConstructor instead of [[PromiseConstructor]]?
>> This removes the wart in my view, has no less integrity. C. Scott?
> Making this concrete, here would be the new text for
> Promise.resolve(x):
>> The resolve function returns either a new promise resolved with the
>> passed argument, or the argument itself if the argument is a promise
>> produced by this constructor.
>> 1. Let C be the this value.
>> 2. If IsPromise(x) is true,
>>     a. Let constructor be the value of SpeciesConstructor(x, %Promise%)
>     b. If SameValue(constructor, C) is true, return x.
>> 3. If Type(C) is not Object, throw a TypeError exception.
>> 4. Let S be Get(C, @@species).
>> 5. ReturnIfAbrupt(S).
>> 6. If S is neither undefined nor null, let C be S.
>> 7. Let promiseCapability be NewPromiseCapability(C)
> [...remainer elided...]
> Step 2a is the only change.  (It was previously "Let constructor be the
> value of x's [[PromiseConstructor]] internal slot.")
> But SpeciesConstructor (or any access to x's @@species) goes through
> `x.constructor` and my recollection is that the motivation for adding
> [[PromiseConstructor]] was that 'constructor'  was not sufficiently tamper
> proof.  From that perspective, it seems that SpeciesConstructor is actually
> worse than just accessing `x.constructor`.
> Also, in a private message Mark Miller mentioned that the primarily
>  security invariant he's concerned about really relates to the behavior of
> the `then` method of the object returned by `Promise.resolve(x)`.  Neither
> testing `construct` or SpeciesConstructor really tells you anything about
> `then`.   It seems that the root problem here is trying to apply nominal
> type based reasoning to JS.
> Allen

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list