GetterSetter.cpp
1 /* 2 * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) 3 * Copyright (C) 2001 Peter Kelly (pmk@post.com) 4 * Copyright (C) 2004-2017 Apple Inc. All rights reserved. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public License 17 * along with this library; see the file COPYING.LIB. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #include "config.h" 24 #include "GetterSetter.h" 25 26 #include "Exception.h" 27 #include "JSObjectInlines.h" 28 #include <wtf/Assertions.h> 29 30 namespace JSC { 31 32 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(GetterSetter); 33 34 const ClassInfo GetterSetter::s_info = { "GetterSetter", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(GetterSetter) }; 35 36 void GetterSetter::visitChildren(JSCell* cell, SlotVisitor& visitor) 37 { 38 GetterSetter* thisObject = jsCast<GetterSetter*>(cell); 39 ASSERT_GC_OBJECT_INHERITS(thisObject, info()); 40 Base::visitChildren(thisObject, visitor); 41 42 visitor.append(thisObject->m_getter); 43 visitor.append(thisObject->m_setter); 44 } 45 46 JSValue callGetter(JSGlobalObject* globalObject, JSValue base, JSValue getterSetter) 47 { 48 VM& vm = globalObject->vm(); 49 auto scope = DECLARE_THROW_SCOPE(vm); 50 // FIXME: Some callers may invoke get() without checking for an exception first. 51 // We work around that by checking here. 52 RETURN_IF_EXCEPTION(scope, scope.exception()->value()); 53 54 JSObject* getter = jsCast<GetterSetter*>(getterSetter)->getter(); 55 56 auto callData = getCallData(vm, getter); 57 RELEASE_AND_RETURN(scope, call(globalObject, getter, callData, base, ArgList())); 58 } 59 60 bool callSetter(JSGlobalObject* globalObject, JSValue base, JSValue getterSetter, JSValue value, ECMAMode ecmaMode) 61 { 62 VM& vm = globalObject->vm(); 63 auto scope = DECLARE_THROW_SCOPE(vm); 64 65 GetterSetter* getterSetterObj = jsCast<GetterSetter*>(getterSetter); 66 67 if (getterSetterObj->isSetterNull()) 68 return typeError(globalObject, scope, ecmaMode.isStrict(), ReadonlyPropertyWriteError); 69 70 JSObject* setter = getterSetterObj->setter(); 71 72 MarkedArgumentBuffer args; 73 args.append(value); 74 ASSERT(!args.hasOverflowed()); 75 76 auto callData = getCallData(vm, setter); 77 scope.release(); 78 call(globalObject, setter, callData, base, args); 79 return true; 80 } 81 82 } // namespace JSC