1// Copyright 2019 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include 'src/builtins/builtins-proxy-gen.h' 6 7namespace proxy { 8 9// ES #sec-proxy-object-internal-methods-and-internal-slots-preventextensions 10// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-preventextensions 11transitioning builtin 12ProxyPreventExtensions(implicit context: Context)( 13 proxy: JSProxy, doThrow: Boolean): JSAny { 14 PerformStackCheck(); 15 const kTrapName: constexpr string = 'preventExtensions'; 16 try { 17 // 1. Let handler be O.[[ProxyHandler]]. 18 // 2. If handler is null, throw a TypeError exception. 19 // 3. Assert: Type(handler) is Object. 20 dcheck(proxy.handler == Null || Is<JSReceiver>(proxy.handler)); 21 const handler = 22 Cast<JSReceiver>(proxy.handler) otherwise ThrowProxyHandlerRevoked; 23 24 // 4. Let target be O.[[ProxyTarget]]. 25 const target = proxy.target; 26 27 // 5. Let trap be ? GetMethod(handler, "preventExtensions"). 28 // 6. If trap is undefined, then (see 6.a below). 29 const trap: Callable = GetMethod(handler, kTrapName) 30 otherwise goto TrapUndefined(target); 31 32 // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « 33 // target»)). 34 const trapResult = Call(context, trap, handler, target); 35 36 // 8. If booleanTrapResult is true, then 37 // 8.a. Let extensibleTarget be ? IsExtensible(target). 38 // 8.b If extensibleTarget is true, throw a TypeError exception. 39 if (ToBoolean(trapResult)) { 40 const extensibleTarget: JSAny = object::ObjectIsExtensibleImpl(target); 41 dcheck(extensibleTarget == True || extensibleTarget == False); 42 if (extensibleTarget == True) { 43 ThrowTypeError(MessageTemplate::kProxyPreventExtensionsExtensible); 44 } 45 } else { 46 if (doThrow == True) { 47 ThrowTypeError(MessageTemplate::kProxyTrapReturnedFalsish, kTrapName); 48 } 49 return False; 50 } 51 52 // 9. Return booleanTrapResult. 53 return True; 54 } label TrapUndefined(target: JSAny) { 55 // 6.a. Return ? target.[[PreventExtensions]](). 56 if (doThrow == True) { 57 return object::ObjectPreventExtensionsThrow(target); 58 } 59 return object::ObjectPreventExtensionsDontThrow(target); 60 } label ThrowProxyHandlerRevoked deferred { 61 ThrowTypeError(MessageTemplate::kProxyRevoked, kTrapName); 62 } 63} 64} // namespace proxy 65