10.5.9 [[Set]] (P, V, Receiver)
(String name, Scriptable start, Object value)
| 536 | * [[Set]] (P, V, Receiver)</a> |
| 537 | */ |
| 538 | @Override |
| 539 | public void put(String name, Scriptable start, Object value) { |
| 540 | /* |
| 541 | * 1. Assert: IsPropertyKey(P) is true. |
| 542 | * 2. Let handler be O.[[ProxyHandler]]. |
| 543 | * 3. If handler is null, throw a TypeError exception. |
| 544 | * 4. Assert: Type(handler) is Object. |
| 545 | * 5. Let target be O.[[ProxyTarget]]. |
| 546 | * 6. Let trap be ? GetMethod(handler, "set"). |
| 547 | * 7. If trap is undefined, then |
| 548 | * a. Return ? target.[[Set]](P, V, Receiver). |
| 549 | * 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)). |
| 550 | * 9. If booleanTrapResult is false, return false. |
| 551 | * 10. Let targetDesc be ? target.[[GetOwnProperty]](P). |
| 552 | * 11. If targetDesc is not undefined and targetDesc.[[Configurable]] is false, then |
| 553 | * a. If IsDataDescriptor(targetDesc) is true and targetDesc.[[Writable]] is false, then |
| 554 | * i. If SameValue(V, targetDesc.[[Value]]) is false, throw a TypeError exception. |
| 555 | * b. If IsAccessorDescriptor(targetDesc) is true, then |
| 556 | * i. If targetDesc.[[Set]] is undefined, throw a TypeError exception. |
| 557 | * 12. Return true. |
| 558 | */ |
| 559 | ScriptableObject target = getTargetThrowIfRevoked(); |
| 560 | |
| 561 | Function trap = getTrap(TRAP_SET); |
| 562 | if (trap != null) { |
| 563 | boolean booleanTrapResult = |
| 564 | ScriptRuntime.toBoolean( |
| 565 | callTrap(trap, new Object[] {target, name, value, start})); |
| 566 | if (!booleanTrapResult) { |
| 567 | return; // false |
| 568 | } |
| 569 | |
| 570 | DescriptorInfo targetDesc = target.getOwnPropertyDescriptor(Context.getContext(), name); |
| 571 | if (targetDesc != null |
| 572 | && !Undefined.isUndefined(targetDesc) |
| 573 | && targetDesc.isConfigurable(false)) { |
| 574 | if (targetDesc.isDataDescriptor() && targetDesc.isWritable(false)) { |
| 575 | if (!Objects.equals(value, targetDesc.value)) { |
| 576 | throw ScriptRuntime.typeError( |
| 577 | "proxy set has to use the same value as the plain call"); |
| 578 | } |
| 579 | } |
| 580 | if (targetDesc.isAccessorDescriptor() && Undefined.isUndefined(targetDesc.setter)) { |
| 581 | throw ScriptRuntime.typeError("proxy set has to be available"); |
| 582 | } |
| 583 | } |
| 584 | return; // true |
| 585 | } |
| 586 | |
| 587 | if (start == this) { |
| 588 | start = target; |
| 589 | } |
| 590 | target.put(name, start, value); |
| 591 | } |
| 592 | |
| 593 | /** |
| 594 | * <a |
nothing calls this directly
no test coverage detected