mirror of https://github.com/svaarala/duktape.git
Browse Source
Add some more polyfills: Object.assign() and Performance.now(). The RegExp.prototype.compile() polyfill cannot be implemented at the moment because it needs to overwrite some RegExp instance properties which are currently protected.v1.0-maintenance
Sami Vaarala
10 years ago
8 changed files with 151 additions and 0 deletions
@ -0,0 +1,45 @@ |
|||
/* |
|||
* Object.assign(), described in E6 Section 19.1.2.1 |
|||
* |
|||
* https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign
|
|||
*/ |
|||
|
|||
if (typeof Object.assign === 'undefined') { |
|||
Object.defineProperty(Object, 'assign', { |
|||
value: function (target) { |
|||
var i, n, j, m, k; |
|||
var source, keys; |
|||
var gotError; |
|||
var pendingError; |
|||
|
|||
if (target == null) { |
|||
throw new Exception('target null or undefined'); |
|||
} |
|||
|
|||
for (i = 1, n = arguments.length; i < n; i++) { |
|||
source = arguments[i]; |
|||
if (source == null) { |
|||
continue; // null or undefined
|
|||
} |
|||
source = Object(source); |
|||
keys = Object.keys(source); // enumerable own keys
|
|||
|
|||
for (j = 0, m = keys.length; j < m; j++) { |
|||
k = keys[j]; |
|||
try { |
|||
target[k] = source[k]; |
|||
} catch (e) { |
|||
if (!gotError) { |
|||
gotError = true; |
|||
pendingError = e; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (gotError) { |
|||
throw pendingError; |
|||
} |
|||
}, writable: true, enumerable: false, configurable: true |
|||
}); |
|||
} |
@ -0,0 +1,25 @@ |
|||
/* |
|||
* Performance.now() polyfill |
|||
* |
|||
* http://www.w3.org/TR/hr-time/#sec-high-resolution-time
|
|||
* |
|||
* Dummy implementation which uses the Date built-in and has no higher |
|||
* resolution. If/when Duktape has a built-in high resolution timer |
|||
* interface, reimplement this. |
|||
*/ |
|||
|
|||
var _perfNowZeroTime = Date.now(); |
|||
|
|||
if (typeof Performance === 'undefined') { |
|||
Object.defineProperty(this, 'Performance', { |
|||
value: {}, |
|||
writable: true, enumerable: false, configurable: true |
|||
}); |
|||
} |
|||
if (typeof Performance.now === 'undefined') { |
|||
Object.defineProperty(Performance, 'now', { |
|||
value: function () { |
|||
return Date.now() - _perfNowZeroTime; |
|||
}, writable: true, enumerable: false, configurable: true |
|||
}); |
|||
} |
@ -0,0 +1,65 @@ |
|||
/* |
|||
* RegExp.prototype.compile() polyfill, described in E6 Annex B: |
|||
* |
|||
* https://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.compile
|
|||
* |
|||
* See also: |
|||
* |
|||
* http://mozilla.6506.n7.nabble.com/RegExp-prototype-compile-and-RegExp-instance-properties-td270408.html
|
|||
* |
|||
* This polyfill cannot be implemented in terms of standard E5 because it |
|||
* needs to reinitialize the internal state of a RegExp instance. To do |
|||
* that, we access the Duktape internal properties directly, which is |
|||
* quite fragile. |
|||
* |
|||
* Avoid storing a public copy of Duktape or some internal property name in |
|||
* the global object. This could subvert user sandboxing. |
|||
*/ |
|||
|
|||
(function () { |
|||
var propBytecode = Duktape.dec('hex', 'ff62797465636f6465'); // \xFFbytecode
|
|||
|
|||
if (typeof RegExp.prototype.compile !== 'undefined') { |
|||
return; |
|||
} |
|||
|
|||
Object.defineProperty(RegExp.prototype, 'compile', { |
|||
value: function (pattern, flags) { |
|||
var newBytecode, tmpRegexp; |
|||
if (typeof this !== 'object' || !(propBytecode in this)) { |
|||
throw new TypeError('invalid this binding'); |
|||
} |
|||
|
|||
// FIXME: property attributes prevent this approach from working
|
|||
// right now. The properties we'd need to modify are non-writable
|
|||
// and non-configurable:
|
|||
//
|
|||
// \xffbytecode
|
|||
// source
|
|||
// global
|
|||
// ignoreCase
|
|||
// multiline
|
|||
//
|
|||
// The property attributes can be relaxed, or the properties can
|
|||
// be made accessors backing to the regexp bytecode, see Ditz
|
|||
// issues: 0f2c246cadbb3b3913b75dc7e890ee4e7d336a1a and
|
|||
// f8396fbcc36db4610fec5ad5a7d7a8f471d084a4.
|
|||
|
|||
if (typeof pattern === 'object' && (propBytecode in pattern)) { |
|||
this[propBytecode] = pattern[propBytecode]; |
|||
} else { |
|||
tmpRegexp = new RegExp(pattern, flags); |
|||
this[propBytecode] = tmpRegexp[propBytecode]; |
|||
} |
|||
|
|||
//this.source
|
|||
//this.global
|
|||
//this.ignoreCase
|
|||
//this.multiline
|
|||
this.lastIndex = 0; |
|||
return this; |
|||
}, writable: true, enumerable: false, configurable: true |
|||
}); |
|||
|
|||
throw new Error('RegExp.prototype.compile() polyfill incomplete'); |
|||
})(); |
Loading…
Reference in new issue