Index: src/v8natives.js |
diff --git a/src/v8natives.js b/src/v8natives.js |
index a522738b881b9042f4a3cc0a44e3ec76e022229e..f4624f53a2cec13349fde1e721b3757e833f70c3 100644 |
--- a/src/v8natives.js |
+++ b/src/v8natives.js |
@@ -1391,6 +1391,59 @@ function ObjectSetProto(proto) { |
} |
} |
+var kError = { error: UNDEFINED }; |
+function TryCatch3(fn, arg1, arg2, arg3) { |
+ try { |
+ return fn(arg1, arg2, arg3); |
+ } catch (e) { |
+ kError.error = e; |
jsbell
2014/09/08 17:22:41
Wouldn't this "leak" the exception?
(I'm not inti
caitp (gmail)
2014/09/08 17:48:27
Yes, within the sandbox it would be kept alive ---
|
+ return kError; |
+ } |
+} |
+ |
+function CopyEnumerableValue(to, from, p) { |
+ var desc = ObjectGetOwnPropertyDescriptor(from, p); |
+ if (!IS_UNDEFINED(desc) && desc.enumerable) { |
+ // Approximately Put() (7.3.2) |
+ %SetProperty(to, p, from[p], kStrictMode); |
+ } |
+} |
+ |
+ |
+function ObjectAssign(target, sources) { |
+ var to = ToObject(target); |
+ var argsLen = %_ArgumentsLength(); |
+ if (argsLen < 2) return to; |
+ |
+ for (var i = 1; i < argsLen; ++i) { |
+ var nextSource = %_Arguments(i); |
+ if (IS_NULL(nextSource) || IS_UNDEFINED(nextSource)) { |
+ continue; |
+ } |
+ |
+ var from = ToObject(nextSource); |
+ var keysArray = ObjectGetOwnPropertyKeys(from); |
+ var len = keysArray.length; |
+ var pendingException = UNDEFINED; |
+ |
+ for (var j = 0; j < len; ++j) { |
+ // Get "sort of" abrupt completion record for steps 5d i...iii |
+ // TryCatch3 moved out to ensure that ObjectAssign can be optimized |
+ // --- will measure if it makes a meaningful difference, but we've |
+ // seen that Object.assign() is pretty slow already. |
+ var record = TryCatch3(CopyEnumerableValue, to, from, keysArray[j]); |
+ if (record === kError) { |
+ if (IS_UNDEFINED(pendingException)) |
+ pendingException = kError.error; |
+ } |
+ } |
+ |
+ if (!IS_UNDEFINED(pendingException)) |
+ throw pendingException; |
+ } |
+ return to; |
+} |
+ |
function ObjectConstructor(x) { |
if (%_IsConstructCall()) { |
@@ -1447,9 +1500,10 @@ function SetUpObject() { |
"isFrozen", ObjectIsFrozen, |
"isSealed", ObjectIsSealed, |
"preventExtensions", ObjectPreventExtension, |
- "seal", ObjectSeal |
+ "seal", ObjectSeal, |
// deliverChangeRecords, getNotifier, observe and unobserve are added |
// in object-observe.js. |
+ "assign", ObjectAssign |
)); |
} |