Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/object-observe.js

Issue 71163006: Merge bleeding_edge r17376:17693. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Fix all.gyp Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mksnapshot.cc ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 121
122 for (var type in typeMap1) { 122 for (var type in typeMap1) {
123 if (TypeMapHasType(typeMap1, type) && TypeMapHasType(typeMap2, type)) 123 if (TypeMapHasType(typeMap1, type) && TypeMapHasType(typeMap2, type))
124 return false; 124 return false;
125 } 125 }
126 126
127 return true; 127 return true;
128 } 128 }
129 129
130 var defaultAcceptTypes = TypeMapCreateFromList([ 130 var defaultAcceptTypes = TypeMapCreateFromList([
131 'new', 131 'add',
132 'updated', 132 'update',
133 'deleted', 133 'delete',
134 'prototype', 134 'setPrototype',
135 'reconfigured' 135 'reconfigure',
136 'preventExtensions'
136 ]); 137 ]);
137 138
138 // An Observer is a registration to observe an object by a callback with 139 // An Observer is a registration to observe an object by a callback with
139 // a given set of accept types. If the set of accept types is the default 140 // a given set of accept types. If the set of accept types is the default
140 // set for Object.observe, the observer is represented as a direct reference 141 // set for Object.observe, the observer is represented as a direct reference
141 // to the callback. An observer never changes its accept types and thus never 142 // to the callback. An observer never changes its accept types and thus never
142 // needs to "normalize". 143 // needs to "normalize".
143 function ObserverCreate(callback, acceptList) { 144 function ObserverCreate(callback, acceptList) {
144 return IS_UNDEFINED(acceptList) ? callback : { 145 return IS_UNDEFINED(acceptList) ? callback : {
145 __proto__: null, 146 __proto__: null,
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 346
346 var objectInfo = objectInfoMap.get(object); 347 var objectInfo = objectInfoMap.get(object);
347 if (IS_UNDEFINED(objectInfo)) 348 if (IS_UNDEFINED(objectInfo))
348 return object; 349 return object;
349 350
350 ObjectInfoRemoveObserver(objectInfo, callback); 351 ObjectInfoRemoveObserver(objectInfo, callback);
351 return object; 352 return object;
352 } 353 }
353 354
354 function ArrayObserve(object, callback) { 355 function ArrayObserve(object, callback) {
355 return ObjectObserve(object, callback, ['new', 356 return ObjectObserve(object, callback, ['add',
356 'updated', 357 'update',
357 'deleted', 358 'delete',
358 'splice']); 359 'splice']);
359 } 360 }
360 361
361 function ArrayUnobserve(object, callback) { 362 function ArrayUnobserve(object, callback) {
362 return ObjectUnobserve(object, callback); 363 return ObjectUnobserve(object, callback);
363 } 364 }
364 365
365 function ObserverEnqueueIfActive(observer, objectInfo, changeRecord, 366 function ObserverEnqueueIfActive(observer, objectInfo, changeRecord,
366 needsAccessCheck) { 367 needsAccessCheck) {
367 if (!ObserverIsActive(observer, objectInfo) || 368 if (!ObserverIsActive(observer, objectInfo) ||
(...skipping 11 matching lines...) Expand all
379 } 380 }
380 381
381 var callbackInfo = CallbackInfoNormalize(callback); 382 var callbackInfo = CallbackInfoNormalize(callback);
382 if (!observationState.pendingObservers) 383 if (!observationState.pendingObservers)
383 observationState.pendingObservers = { __proto__: null }; 384 observationState.pendingObservers = { __proto__: null };
384 observationState.pendingObservers[callbackInfo.priority] = callback; 385 observationState.pendingObservers[callbackInfo.priority] = callback;
385 callbackInfo.push(changeRecord); 386 callbackInfo.push(changeRecord);
386 %SetObserverDeliveryPending(); 387 %SetObserverDeliveryPending();
387 } 388 }
388 389
389 function ObjectInfoEnqueueChangeRecord(objectInfo, changeRecord, 390 function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) {
390 skipAccessCheck) { 391 if (!ObjectInfoHasActiveObservers(objectInfo))
392 return;
393
394 var hasType = !IS_UNDEFINED(type);
395 var newRecord = hasType ?
396 { object: ObjectInfoGetObject(objectInfo), type: type } :
397 { object: ObjectInfoGetObject(objectInfo) };
398
399 for (var prop in changeRecord) {
400 if (prop === 'object' || (hasType && prop === 'type')) continue;
401 %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop],
402 READ_ONLY + DONT_DELETE);
403 }
404 ObjectFreeze(newRecord);
405
406 ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord,
407 true /* skip access check */);
408 }
409
410 function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord,
411 skipAccessCheck) {
391 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 412 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
392 if (IS_SYMBOL(changeRecord.name)) return; 413 if (IS_SYMBOL(changeRecord.name)) return;
393 414
394 var needsAccessCheck = !skipAccessCheck && 415 var needsAccessCheck = !skipAccessCheck &&
395 %IsAccessCheckNeeded(changeRecord.object); 416 %IsAccessCheckNeeded(changeRecord.object);
396 417
397 if (ChangeObserversIsOptimized(objectInfo.changeObservers)) { 418 if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
398 var observer = objectInfo.changeObservers; 419 var observer = objectInfo.changeObservers;
399 ObserverEnqueueIfActive(observer, objectInfo, changeRecord, 420 ObserverEnqueueIfActive(observer, objectInfo, changeRecord,
400 needsAccessCheck); 421 needsAccessCheck);
(...skipping 27 matching lines...) Expand all
428 var changeRecord = { 449 var changeRecord = {
429 type: 'splice', 450 type: 'splice',
430 object: array, 451 object: array,
431 index: index, 452 index: index,
432 removed: removed, 453 removed: removed,
433 addedCount: addedCount 454 addedCount: addedCount
434 }; 455 };
435 456
436 ObjectFreeze(changeRecord); 457 ObjectFreeze(changeRecord);
437 ObjectFreeze(changeRecord.removed); 458 ObjectFreeze(changeRecord.removed);
438 ObjectInfoEnqueueChangeRecord(objectInfo, changeRecord); 459 ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord);
439 } 460 }
440 461
441 function NotifyChange(type, object, name, oldValue) { 462 function NotifyChange(type, object, name, oldValue) {
442 var objectInfo = objectInfoMap.get(object); 463 var objectInfo = objectInfoMap.get(object);
443 if (!ObjectInfoHasActiveObservers(objectInfo)) 464 if (!ObjectInfoHasActiveObservers(objectInfo))
444 return; 465 return;
445 466
446 var changeRecord = (arguments.length < 4) ? 467 var changeRecord;
447 { type: type, object: object, name: name } : 468 if (arguments.length == 2) {
448 { type: type, object: object, name: name, oldValue: oldValue }; 469 changeRecord = { type: type, object: object };
470 } else if (arguments.length == 3) {
471 changeRecord = { type: type, object: object, name: name };
472 } else {
473 changeRecord = {
474 type: type,
475 object: object,
476 name: name,
477 oldValue: oldValue
478 };
479 }
480
449 ObjectFreeze(changeRecord); 481 ObjectFreeze(changeRecord);
450 ObjectInfoEnqueueChangeRecord(objectInfo, changeRecord); 482 ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord);
451 } 483 }
452 484
453 var notifierPrototype = {}; 485 var notifierPrototype = {};
454 486
455 function ObjectNotifierNotify(changeRecord) { 487 function ObjectNotifierNotify(changeRecord) {
456 if (!IS_SPEC_OBJECT(this)) 488 if (!IS_SPEC_OBJECT(this))
457 throw MakeTypeError("called_on_non_object", ["notify"]); 489 throw MakeTypeError("called_on_non_object", ["notify"]);
458 490
459 var objectInfo = ObjectInfoGetFromNotifier(this); 491 var objectInfo = ObjectInfoGetFromNotifier(this);
460 if (IS_UNDEFINED(objectInfo)) 492 if (IS_UNDEFINED(objectInfo))
461 throw MakeTypeError("observe_notify_non_notifier"); 493 throw MakeTypeError("observe_notify_non_notifier");
462 if (!IS_STRING(changeRecord.type)) 494 if (!IS_STRING(changeRecord.type))
463 throw MakeTypeError("observe_type_non_string"); 495 throw MakeTypeError("observe_type_non_string");
464 496
465 if (!ObjectInfoHasActiveObservers(objectInfo)) 497 ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord);
466 return;
467
468 var newRecord = { object: ObjectInfoGetObject(objectInfo) };
469 for (var prop in changeRecord) {
470 if (prop === 'object') continue;
471 %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop],
472 READ_ONLY + DONT_DELETE);
473 }
474 ObjectFreeze(newRecord);
475
476 ObjectInfoEnqueueChangeRecord(objectInfo, newRecord,
477 true /* skip access check */);
478 } 498 }
479 499
480 function ObjectNotifierPerformChange(changeType, changeFn) { 500 function ObjectNotifierPerformChange(changeType, changeFn) {
481 if (!IS_SPEC_OBJECT(this)) 501 if (!IS_SPEC_OBJECT(this))
482 throw MakeTypeError("called_on_non_object", ["performChange"]); 502 throw MakeTypeError("called_on_non_object", ["performChange"]);
483 503
484 var objectInfo = ObjectInfoGetFromNotifier(this); 504 var objectInfo = ObjectInfoGetFromNotifier(this);
485 505
486 if (IS_UNDEFINED(objectInfo)) 506 if (IS_UNDEFINED(objectInfo))
487 throw MakeTypeError("observe_notify_non_notifier"); 507 throw MakeTypeError("observe_notify_non_notifier");
488 if (!IS_STRING(changeType)) 508 if (!IS_STRING(changeType))
489 throw MakeTypeError("observe_perform_non_string"); 509 throw MakeTypeError("observe_perform_non_string");
490 if (!IS_SPEC_FUNCTION(changeFn)) 510 if (!IS_SPEC_FUNCTION(changeFn))
491 throw MakeTypeError("observe_perform_non_function"); 511 throw MakeTypeError("observe_perform_non_function");
492 512
493 ObjectInfoAddPerformingType(objectInfo, changeType); 513 ObjectInfoAddPerformingType(objectInfo, changeType);
514
515 var changeRecord;
494 try { 516 try {
495 %_CallFunction(UNDEFINED, changeFn); 517 changeRecord = %_CallFunction(UNDEFINED, changeFn);
496 } finally { 518 } finally {
497 ObjectInfoRemovePerformingType(objectInfo, changeType); 519 ObjectInfoRemovePerformingType(objectInfo, changeType);
498 } 520 }
521
522 if (IS_SPEC_OBJECT(changeRecord))
523 ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType);
499 } 524 }
500 525
501 function ObjectGetNotifier(object) { 526 function ObjectGetNotifier(object) {
502 if (!IS_SPEC_OBJECT(object)) 527 if (!IS_SPEC_OBJECT(object))
503 throw MakeTypeError("observe_non_object", ["getNotifier"]); 528 throw MakeTypeError("observe_non_object", ["getNotifier"]);
504 529
505 if (ObjectIsFrozen(object)) return null; 530 if (ObjectIsFrozen(object)) return null;
506 531
507 var objectInfo = ObjectInfoGet(object); 532 var objectInfo = ObjectInfoGet(object);
508 return ObjectInfoGetNotifier(objectInfo); 533 return ObjectInfoGetNotifier(objectInfo);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 "observe", ArrayObserve, 584 "observe", ArrayObserve,
560 "unobserve", ArrayUnobserve 585 "unobserve", ArrayUnobserve
561 )); 586 ));
562 InstallFunctions(notifierPrototype, DONT_ENUM, $Array( 587 InstallFunctions(notifierPrototype, DONT_ENUM, $Array(
563 "notify", ObjectNotifierNotify, 588 "notify", ObjectNotifierNotify,
564 "performChange", ObjectNotifierPerformChange 589 "performChange", ObjectNotifierPerformChange
565 )); 590 ));
566 } 591 }
567 592
568 SetupObjectObserve(); 593 SetupObjectObserve();
OLDNEW
« no previous file with comments | « src/mksnapshot.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698