18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2007 Maks Orlovich
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is free software; you can redistribute it and/or
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  modify it under the terms of the GNU Library General Public
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License as published by the Free Software Foundation; either
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is distributed in the hope that it will be useful,
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Library General Public License for more details.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  You should have received a copy of the GNU Library General Public License
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  along with this library; see the file COPYING.LIB.  If not, write to
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Boston, MA 02110-1301, USA.
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSFunction.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CodeBlock.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CommonIdentifiers.h"
30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "CallFrame.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FunctionPrototype.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSGlobalObject.h"
33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Interpreter.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ObjectPrototype.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Parser.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PropertyNameArray.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ScopeChainMark.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WTF;
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace Unicode;
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC {
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectASSERT_CLASS_FITS_IN_CELL(JSFunction);
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectconst ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 };
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool JSFunction::isHostFunctionNonInline() const
49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return isHostFunction();
51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
52231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockJSFunction::JSFunction(NonNullPassRefPtr<Structure> structure)
54231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    : Base(structure)
55231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_executable(adoptRef(new VPtrHackExecutable()))
56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
57231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
58231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockJSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    : Base(&exec->globalData(), structure, name)
615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(JIT)
62231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_executable(adoptRef(new NativeExecutable(exec)))
635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(JIT)
665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    setNativeFunction(func);
675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum);
685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#else
695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    UNUSED_PARAM(length);
705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    UNUSED_PARAM(func);
715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT_NOT_REACHED();
725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
75231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockJSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<FunctionExecutable> executable, ScopeChainNode* scopeChainNode)
76231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), executable->name())
77231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_executable(executable)
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    setScopeChain(scopeChainNode);
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectJSFunction::~JSFunction()
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
84d0825bca7fe65beaee391d30da42e937db621564Steve Block    ASSERT(vptr() == JSGlobalData::jsFunctionVPtr);
85d0825bca7fe65beaee391d30da42e937db621564Steve Block
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // JIT code for other functions may have had calls linked directly to the code for this function; these links
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // this memory is freed and may be reused (potentially for another, different JSFunction).
89231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!isHostFunction()) {
900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if ENABLE(JIT_OPTIMIZE_CALL)
91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ASSERT(m_executable);
92231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (jsExecutable()->isGenerated())
93231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            jsExecutable()->generatedBytecode().unlinkCallers();
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        scopeChain().~ScopeChain(); // FIXME: Don't we need to do this in the interpreter too?
96231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid JSFunction::markChildren(MarkStack& markStack)
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    Base::markChildren(markStack);
102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!isHostFunction()) {
103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        jsExecutable()->markAggregate(markStack);
1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        scopeChain().markAggregate(markStack);
105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCallType JSFunction::getCallData(CallData& callData)
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (isHostFunction()) {
1115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        callData.native.function = nativeFunction();
1125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return CallTypeHost;
1135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    callData.js.functionExecutable = jsExecutable();
1155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    callData.js.scopeChain = scopeChain().node();
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return CallTypeJS;
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1195f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue JSFunction::call(ExecState* exec, JSValue thisValue, const ArgList& args)
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(!isHostFunction());
122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return exec->interpreter()->execute(jsExecutable(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot());
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1255f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSFunction* thisObj = asFunction(slot.slotBase());
1285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(!thisObj->isHostFunction());
129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return exec->interpreter()->retrieveArguments(exec, thisObj);
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1325f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSFunction* thisObj = asFunction(slot.slotBase());
1355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(!thisObj->isHostFunction());
136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return exec->interpreter()->retrieveCaller(exec, thisObj);
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1395f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSFunction* thisObj = asFunction(slot.slotBase());
1425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(!thisObj->isHostFunction());
143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return jsNumber(exec, thisObj->jsExecutable()->parameterCount());
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (isHostFunction())
1495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return Base::getOwnPropertySlot(exec, propertyName, slot);
1505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (propertyName == exec->propertyNames().prototype) {
1525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        JSValue* location = getDirectLocation(propertyName);
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!location) {
1555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSObject* prototype = new (exec) JSObject(scopeChain().globalObject()->emptyObjectStructure());
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            prototype->putDirect(exec->propertyNames().constructor, this, DontEnum);
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            putDirect(exec->propertyNames().prototype, prototype, DontDelete);
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            location = getDirectLocation(propertyName);
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        slot.setValueSlot(this, location, offsetForLocation(location));
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (propertyName == exec->propertyNames().arguments) {
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        slot.setCustom(this, argumentsGetter);
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (propertyName == exec->propertyNames().length) {
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        slot.setCustom(this, lengthGetter);
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (propertyName == exec->propertyNames().caller) {
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        slot.setCustom(this, callerGetter);
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::getOwnPropertySlot(exec, propertyName, slot);
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
182231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
183231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
184231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (isHostFunction())
185231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
186231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (propertyName == exec->propertyNames().prototype) {
188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            PropertySlot slot;
189231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            getOwnPropertySlot(exec, propertyName, slot);
190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (propertyName == exec->propertyNames().arguments) {
194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete);
195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return true;
196231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
198231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (propertyName == exec->propertyNames().length) {
199231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            descriptor.setDescriptor(jsNumber(exec, jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete);
200231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return true;
201231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
202231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
203231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (propertyName == exec->propertyNames().caller) {
204231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete);
205231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return true;
206231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
207231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
208231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
209231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
210231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
211d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid JSFunction::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
212d0825bca7fe65beaee391d30da42e937db621564Steve Block{
213d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!isHostFunction() && (mode == IncludeDontEnumProperties)) {
214d0825bca7fe65beaee391d30da42e937db621564Steve Block        propertyNames.add(exec->propertyNames().arguments);
215d0825bca7fe65beaee391d30da42e937db621564Steve Block        propertyNames.add(exec->propertyNames().callee);
216d0825bca7fe65beaee391d30da42e937db621564Steve Block        propertyNames.add(exec->propertyNames().caller);
217d0825bca7fe65beaee391d30da42e937db621564Steve Block        propertyNames.add(exec->propertyNames().length);
218d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
219d0825bca7fe65beaee391d30da42e937db621564Steve Block    Base::getOwnPropertyNames(exec, propertyNames, mode);
220d0825bca7fe65beaee391d30da42e937db621564Steve Block}
221d0825bca7fe65beaee391d30da42e937db621564Steve Block
2225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (isHostFunction()) {
2255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        Base::put(exec, propertyName, value, slot);
2265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return;
2275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Base::put(exec, propertyName, value, slot);
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (isHostFunction())
2365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return Base::deleteProperty(exec, propertyName);
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::deleteProperty(exec, propertyName);
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// ECMA 13.2.2 [[Construct]]
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectConstructType JSFunction::getConstructData(ConstructData& constructData)
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (isHostFunction())
2465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return ConstructTypeNone;
247231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    constructData.js.functionExecutable = jsExecutable();
2485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    constructData.js.scopeChain = scopeChain().node();
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return ConstructTypeJS;
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectJSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(!isHostFunction());
255635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    Structure* structure;
2565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSValue prototype = get(exec, exec->propertyNames().prototype);
257635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (prototype.isObject())
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        structure = asObject(prototype)->inheritorID();
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        structure = exec->lexicalGlobalObject()->emptyObjectStructure();
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObject* thisObj = new (exec) JSObject(structure);
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
263231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    JSValue result = exec->interpreter()->execute(jsExecutable(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot());
264635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (exec->hadException() || !result.isObject())
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return thisObj;
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return asObject(result);
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC
270