Chromium Code Reviews| Index: lib/runtime/js_utils.js |
| diff --git a/lib/runtime/js_utils.js b/lib/runtime/js_utils.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..a7d6c9d46514d3a393405f6874380c5ac9cbbd9f |
| --- /dev/null |
| +++ b/lib/runtime/js_utils.js |
| @@ -0,0 +1,116 @@ |
| +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +/* This library defines a set of general javascript utilities for us |
| + * by the Dart runtime. |
| +*/ |
| + |
| +var js_utils; |
| +(function (js_utils) { |
| + 'use strict'; |
| + |
| + const defineProperty = Object.defineProperty; |
| + js_utils.defineProperty = defineProperty; |
| + const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; |
| + js_utils.getOwnPropertyDescriptor = getOwnPropertyDescriptor; |
| + const getOwnPropertyNames = Object.getOwnPropertyNames; |
| + js_utils.getOwnPropertyNames = getOwnPropertyNames; |
| + const getOwnPropertySymbols = Object.getOwnPropertySymbols; |
| + js_utils.getOwnPropertySymbols = getOwnPropertySymbols; |
| + const hasOwnProperty = Object.prototype.hasOwnProperty; |
| + js_utils.hasOwnProperty = hasOwnProperty; |
| + const slice = [].slice; |
| + js_utils.slice = [].slice; |
| + |
| + /* This error indicates a bug in the runtime or the compiler. |
| + */ |
| + function throwRuntimeError(message) { |
| + throw Error(message); |
| + } |
| + js_utils.throwRuntimeError = throwRuntimeError; |
| + |
| + function assert(condition) { |
| + if (!condition) throwRuntimeError("The compiler is broken: failed assert"); |
| + } |
| + js_utils.assert = assert; |
| + |
| + function getOwnNamesAndSymbols(obj) { |
| + return getOwnPropertyNames(obj).concat(getOwnPropertySymbols(obj)); |
| + } |
| + js_utils.getOwnNamesAndSymbols = getOwnNamesAndSymbols; |
| + |
| + function safeGetOwnProperty(obj, name) { |
| + let desc = getOwnPropertyDescriptor(obj, name); |
| + if (desc) return desc.value; |
| + } |
| + js_utils.safeGetOwnProperty = safeGetOwnProperty; |
| + |
| + /** |
| + * Defines a lazy property. |
| + * After initial get or set, it will replace itself with a value property. |
| + */ |
| + // TODO(jmesserly): is this the best implementation for JS engines? |
| + // TODO(jmesserly): reusing descriptor objects has been shown to improve |
| + // performance in other projects (e.g. webcomponents.js ShadowDOM polyfill). |
| + function defineLazyProperty(to, name, desc) { |
| + let init = desc.get; |
| + let writable = !!desc.set; |
| + function lazySetter(value) { |
| + defineProperty(to, name, { value: value, writable: writable }); |
| + } |
| + function lazyGetter() { |
| + // Clear the init function to detect circular initialization. |
| + let f = init; |
| + if (f === null) throwRuntimeError('circular initialization for field ' + name); |
|
vsm
2015/06/12 15:50:32
length
Leaf
2015/06/12 19:52:13
Done.
|
| + init = null; |
| + |
| + // Compute and store the value. |
| + let value = f(); |
| + lazySetter(value); |
| + return value; |
| + } |
| + desc.get = lazyGetter; |
| + desc.configurable = true; |
| + if (writable) desc.set = lazySetter; |
| + defineProperty(to, name, desc); |
| + } |
| + js_utils.defineLazyProperty = defineLazyProperty; |
| + |
| + function defineLazy(to, from) { |
| + for (let name of getOwnNamesAndSymbols(from)) { |
| + defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name)); |
| + } |
| + } |
| + js_utils.defineLazy = defineLazy; |
| + |
| + function defineMemoizedGetter(obj, name, get) { |
| + let cache = null; |
| + function getter() { |
| + if (cache != null) return cache; |
| + cache = get(); |
| + get = null; |
| + return cache; |
| + } |
| + defineProperty(obj, name, {get: getter, configurable: true}); |
| + } |
| + js_utils.defineMemoizedGetter = defineMemoizedGetter; |
| + |
| + function copyTheseProperties(to, from, names) { |
| + for (let name of names) { |
| + defineProperty(to, name, getOwnPropertyDescriptor(from, name)); |
| + } |
| + return to; |
| + } |
| + js_utils.copyTheseProperties = copyTheseProperties; |
| + |
| + /** |
| + * Copy properties from source to destination object. |
| + * This operation is commonly called `mixin` in JS. |
| + */ |
| + function copyProperties(to, from) { |
| + return copyTheseProperties(to, from, getOwnNamesAndSymbols(from)); |
| + } |
| + js_utils.copyProperties = copyProperties; |
| + |
| +})(js_utils || (js_utils = {})); |