Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX] Only freeze empty array/dict with weakmap #361

Merged
merged 1 commit into from
Jan 5, 2017

Conversation

mixonic
Copy link
Member

@mixonic mixonic commented Dec 17, 2016

When arrays and objects are frozen in JavaScript, it is impossible to attach meta-data (like Ember's own meta) to them without using a WeakMap. Ember does adopt the WeakMap strategy in browsers that support it, however there are still supported environments (IE9, IE10) where Object.freeze is supported but WeakMap is not. But not freezing these empty arrays and object if WeakMap is missing, legacy meta-data strategies are permitted on those instances.

The change here is untested, however I will add upstream tests in Ember for the relevant cases.

See:

The approach here is pretty naive. Some other more complex approaches I considered were:

  • Attach WeakMap support status to the env. This, however, would mean the empty evaluated and compiles positional and named arguments instances could not be eagerly created.
  • Export the HAS_NATIVE_WEAKMAP value from Glimmer's glimmer-runtime package and use that instead of Ember's implementation. This would remove some small duplication, but it feels a bit weird to have HAS_NATIVE_WEAKMAP as a glimmer export.

Happy to make edits in one of those directions.

When arrays and objects are frozen in JavaScript, it is impossible to
attach meta-data (like Ember's own `meta`) to them without using a
WeakMap. Ember does adopt the WeakMap strategy in browsers that support
it, however there are still supported environments (IE9, IE10) where
`Object.freeze` is supported but WeakMap is not. But not freezing these
empty arrays and object if WeakMap is missing, legacy meta-data
strategies are permitted on those instances.

See:

* emberjs/ember.js#14264
* emberjs/ember.js#14244
let instance = new WeakMap();
// use `Object`'s `.toString` directly to prevent us from detecting
// polyfills as native weakmaps
return Object.prototype.toString.call(instance) === '[object WeakMap]';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, core-js monkey patches toString to even emulate ^. Given that, it is unclear to me if we can detect the real thing any better then how you have written it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirm, I did a ton of research around this before settling for it in ember itself. I just don't think there is a better way that isn't more brittle than this check.

@stefanpenner
Copy link
Contributor

:shipit:

@mixonic
Copy link
Member Author

mixonic commented Jan 5, 2017

Merging this.

@rwjblue getting this into Ember release is going to be tricky I presume? We can sync up tomorrow and maybe I can help.

@mixonic mixonic merged commit 1b91f86 into glimmerjs:master Jan 5, 2017
@mixonic mixonic deleted the frozen-helper-args branch January 5, 2017 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants