11cb0ef41Sopenharmony_ci// Copyright 2019 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include 'src/builtins/builtins-proxy-gen.h' 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_cinamespace proxy { 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci// ES #sec-proxy-object-internal-methods-and-internal-slots-preventextensions 101cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-preventextensions 111cb0ef41Sopenharmony_citransitioning builtin 121cb0ef41Sopenharmony_ciProxyPreventExtensions(implicit context: Context)( 131cb0ef41Sopenharmony_ci proxy: JSProxy, doThrow: Boolean): JSAny { 141cb0ef41Sopenharmony_ci PerformStackCheck(); 151cb0ef41Sopenharmony_ci const kTrapName: constexpr string = 'preventExtensions'; 161cb0ef41Sopenharmony_ci try { 171cb0ef41Sopenharmony_ci // 1. Let handler be O.[[ProxyHandler]]. 181cb0ef41Sopenharmony_ci // 2. If handler is null, throw a TypeError exception. 191cb0ef41Sopenharmony_ci // 3. Assert: Type(handler) is Object. 201cb0ef41Sopenharmony_ci dcheck(proxy.handler == Null || Is<JSReceiver>(proxy.handler)); 211cb0ef41Sopenharmony_ci const handler = 221cb0ef41Sopenharmony_ci Cast<JSReceiver>(proxy.handler) otherwise ThrowProxyHandlerRevoked; 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ci // 4. Let target be O.[[ProxyTarget]]. 251cb0ef41Sopenharmony_ci const target = proxy.target; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci // 5. Let trap be ? GetMethod(handler, "preventExtensions"). 281cb0ef41Sopenharmony_ci // 6. If trap is undefined, then (see 6.a below). 291cb0ef41Sopenharmony_ci const trap: Callable = GetMethod(handler, kTrapName) 301cb0ef41Sopenharmony_ci otherwise goto TrapUndefined(target); 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « 331cb0ef41Sopenharmony_ci // target»)). 341cb0ef41Sopenharmony_ci const trapResult = Call(context, trap, handler, target); 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci // 8. If booleanTrapResult is true, then 371cb0ef41Sopenharmony_ci // 8.a. Let extensibleTarget be ? IsExtensible(target). 381cb0ef41Sopenharmony_ci // 8.b If extensibleTarget is true, throw a TypeError exception. 391cb0ef41Sopenharmony_ci if (ToBoolean(trapResult)) { 401cb0ef41Sopenharmony_ci const extensibleTarget: JSAny = object::ObjectIsExtensibleImpl(target); 411cb0ef41Sopenharmony_ci dcheck(extensibleTarget == True || extensibleTarget == False); 421cb0ef41Sopenharmony_ci if (extensibleTarget == True) { 431cb0ef41Sopenharmony_ci ThrowTypeError(MessageTemplate::kProxyPreventExtensionsExtensible); 441cb0ef41Sopenharmony_ci } 451cb0ef41Sopenharmony_ci } else { 461cb0ef41Sopenharmony_ci if (doThrow == True) { 471cb0ef41Sopenharmony_ci ThrowTypeError(MessageTemplate::kProxyTrapReturnedFalsish, kTrapName); 481cb0ef41Sopenharmony_ci } 491cb0ef41Sopenharmony_ci return False; 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci // 9. Return booleanTrapResult. 531cb0ef41Sopenharmony_ci return True; 541cb0ef41Sopenharmony_ci } label TrapUndefined(target: JSAny) { 551cb0ef41Sopenharmony_ci // 6.a. Return ? target.[[PreventExtensions]](). 561cb0ef41Sopenharmony_ci if (doThrow == True) { 571cb0ef41Sopenharmony_ci return object::ObjectPreventExtensionsThrow(target); 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci return object::ObjectPreventExtensionsDontThrow(target); 601cb0ef41Sopenharmony_ci } label ThrowProxyHandlerRevoked deferred { 611cb0ef41Sopenharmony_ci ThrowTypeError(MessageTemplate::kProxyRevoked, kTrapName); 621cb0ef41Sopenharmony_ci } 631cb0ef41Sopenharmony_ci} 641cb0ef41Sopenharmony_ci} // namespace proxy 65