kocienda | 66a6d36 | 2001-08-24 14:24:45 +0000 | [diff] [blame] | 1 | /* |
darin | 74f6ed6 | 2002-07-22 05:38:39 +0000 | [diff] [blame] | 2 | * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) |
mjs | 6f821c8 | 2002-03-22 00:31:57 +0000 | [diff] [blame] | 3 | * Copyright (C) 2001 Peter Kelly (pmk@post.com) |
oliver@apple.com | 5fca29f | 2009-08-11 04:35:02 +0000 | [diff] [blame] | 4 | * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
darin | 5769f31 | 2007-07-18 02:25:38 +0000 | [diff] [blame] | 5 | * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) |
ggaren | 6c0384f | 2007-10-29 05:32:23 +0000 | [diff] [blame] | 6 | * Copyright (C) 2007 Maks Orlovich |
kocienda | 66a6d36 | 2001-08-24 14:24:45 +0000 | [diff] [blame] | 7 | * |
| 8 | * This library is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU Library General Public |
| 10 | * License as published by the Free Software Foundation; either |
| 11 | * version 2 of the License, or (at your option) any later version. |
| 12 | * |
| 13 | * This library is distributed in the hope that it will be useful, |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 | * Library General Public License for more details. |
| 17 | * |
| 18 | * You should have received a copy of the GNU Library General Public License |
| 19 | * along with this library; see the file COPYING.LIB. If not, write to |
mjs | cdff33b | 2006-01-23 21:41:36 +0000 | [diff] [blame] | 20 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
ggaren | 07d4ce6 | 2005-07-14 18:27:04 +0000 | [diff] [blame] | 21 | * Boston, MA 02110-1301, USA. |
mjs | 6f821c8 | 2002-03-22 00:31:57 +0000 | [diff] [blame] | 22 | * |
kocienda | 66a6d36 | 2001-08-24 14:24:45 +0000 | [diff] [blame] | 23 | */ |
| 24 | |
mjs | b64c50a | 2005-10-03 21:13:12 +0000 | [diff] [blame] | 25 | #include "config.h" |
darin@apple.com | 3dcb636 | 2008-06-16 04:00:19 +0000 | [diff] [blame] | 26 | #include "JSFunction.h" |
kocienda | 66a6d36 | 2001-08-24 14:24:45 +0000 | [diff] [blame] | 27 | |
barraclough@apple.com | 3a4eb9b | 2008-10-18 02:51:52 +0000 | [diff] [blame] | 28 | #include "CodeBlock.h" |
ggaren@apple.com | fea4353 | 2008-08-17 20:23:49 +0000 | [diff] [blame] | 29 | #include "CommonIdentifiers.h" |
ggaren@apple.com | 5169fc9 | 2008-11-17 22:11:26 +0000 | [diff] [blame] | 30 | #include "CallFrame.h" |
barraclough@apple.com | fd8c28a | 2010-05-25 03:04:43 +0000 | [diff] [blame] | 31 | #include "ExceptionHelpers.h" |
weinig@apple.com | 2ce2a7f | 2008-06-28 21:22:01 +0000 | [diff] [blame] | 32 | #include "FunctionPrototype.h" |
barraclough@apple.com | 81aa89f | 2012-02-06 08:56:02 +0000 | [diff] [blame] | 33 | #include "GetterSetter.h" |
barraclough@apple.com | 2221566 | 2011-09-22 21:22:17 +0000 | [diff] [blame] | 34 | #include "JSArray.h" |
ggaren@apple.com | 8e93f05 | 2007-11-26 23:48:14 +0000 | [diff] [blame] | 35 | #include "JSGlobalObject.h" |
ggaren@apple.com | fea29f1 | 2010-05-29 06:33:05 +0000 | [diff] [blame] | 36 | #include "JSNotAnObject.h" |
ggaren@apple.com | 901a8a2 | 2008-11-17 20:57:18 +0000 | [diff] [blame] | 37 | #include "Interpreter.h" |
weinig@apple.com | 2ce2a7f | 2008-06-28 21:22:01 +0000 | [diff] [blame] | 38 | #include "ObjectPrototype.h" |
ggaren@apple.com | 979382c | 2007-12-08 00:01:13 +0000 | [diff] [blame] | 39 | #include "Parser.h" |
ggaren@apple.com | 8e93f05 | 2007-11-26 23:48:14 +0000 | [diff] [blame] | 40 | #include "PropertyNameArray.h" |
darin | bceb27f | 2004-08-12 17:21:29 +0000 | [diff] [blame] | 41 | |
darin | f9e5d6c | 2007-01-09 14:54:26 +0000 | [diff] [blame] | 42 | using namespace WTF; |
| 43 | using namespace Unicode; |
| 44 | |
cwzwarich@webkit.org | 3f782f6 | 2008-09-08 01:28:33 +0000 | [diff] [blame] | 45 | namespace JSC { |
barraclough@apple.com | 99ff343 | 2010-06-03 20:00:18 +0000 | [diff] [blame] | 46 | EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState* exec) |
barraclough@apple.com | fd8c28a | 2010-05-25 03:04:43 +0000 | [diff] [blame] | 47 | { |
barraclough@apple.com | e979a65 | 2010-11-16 01:30:25 +0000 | [diff] [blame] | 48 | return throwVMError(exec, createNotAConstructorError(exec, exec->callee())); |
barraclough@apple.com | fd8c28a | 2010-05-25 03:04:43 +0000 | [diff] [blame] | 49 | } |
| 50 | |
mhahnenberg@apple.com | 3e08466 | 2011-09-26 07:05:28 +0000 | [diff] [blame] | 51 | const ClassInfo JSFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSFunction) }; |
kocienda | 66a6d36 | 2001-08-24 14:24:45 +0000 | [diff] [blame] | 52 | |
darin@apple.com | cbc8617 | 2009-08-13 21:51:50 +0000 | [diff] [blame] | 53 | bool JSFunction::isHostFunctionNonInline() const |
| 54 | { |
| 55 | return isHostFunction(); |
| 56 | } |
| 57 | |
benjamin@webkit.org | cff06e4 | 2012-08-30 21:23:51 +0000 | [diff] [blame] | 58 | JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, int length, const String& name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor) |
barraclough@apple.com | 2221566 | 2011-09-22 21:22:17 +0000 | [diff] [blame] | 59 | { |
barraclough@apple.com | 077fdd4 | 2012-03-18 01:08:16 +0000 | [diff] [blame] | 60 | NativeExecutable* executable; |
psolanki@apple.com | 8c31b97 | 2012-03-27 18:06:21 +0000 | [diff] [blame] | 61 | #if !ENABLE(JIT) |
| 62 | UNUSED_PARAM(intrinsic); |
| 63 | #else |
barraclough@apple.com | 077fdd4 | 2012-03-18 01:08:16 +0000 | [diff] [blame] | 64 | if (intrinsic != NoIntrinsic && exec->globalData().canUseJIT()) { |
| 65 | ASSERT(nativeConstructor == callHostFunctionAsConstructor); |
| 66 | executable = exec->globalData().getHostFunction(nativeFunction, intrinsic); |
| 67 | } else |
| 68 | #endif |
| 69 | executable = exec->globalData().getHostFunction(nativeFunction, nativeConstructor); |
| 70 | |
ggaren@apple.com | 215589e | 2011-12-19 17:45:13 +0000 | [diff] [blame] | 71 | JSFunction* function = new (NotNull, allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, globalObject, globalObject->functionStructure()); |
barraclough@apple.com | 2221566 | 2011-09-22 21:22:17 +0000 | [diff] [blame] | 72 | // Can't do this during initialization because getHostFunction might do a GC allocation. |
| 73 | function->finishCreation(exec, executable, length, name); |
| 74 | return function; |
| 75 | } |
| 76 | |
fpizlo@apple.com | 243788c | 2012-11-13 19:58:18 +0000 | [diff] [blame] | 77 | void JSFunction::destroy(JSCell* cell) |
| 78 | { |
| 79 | static_cast<JSFunction*>(cell)->JSFunction::~JSFunction(); |
| 80 | } |
| 81 | |
commit-queue@webkit.org | 6e5671b | 2011-09-01 23:49:23 +0000 | [diff] [blame] | 82 | JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure) |
oliver@apple.com | 2346a3e | 2011-09-07 19:40:41 +0000 | [diff] [blame] | 83 | : Base(exec->globalData(), structure) |
commit-queue@webkit.org | 53aecd2 | 2011-08-19 00:58:34 +0000 | [diff] [blame] | 84 | , m_executable() |
ggaren@apple.com | b11e787 | 2012-08-30 22:50:00 +0000 | [diff] [blame] | 85 | , m_scope(exec->globalData(), this, globalObject) |
fpizlo@apple.com | f5db15e | 2012-11-14 07:22:57 +0000 | [diff] [blame] | 86 | // We initialize blind so that changes to the prototype after function creation but before |
| 87 | // the optimizer kicks in don't disable optimizations. Once the optimizer kicks in, the |
| 88 | // watchpoint will start watching and any changes will both force deoptimization and disable |
| 89 | // future attempts to optimize. This is necessary because we are guaranteed that the |
| 90 | // inheritorID is changed exactly once prior to optimizations kicking in. We could be |
| 91 | // smarter and count the number of times the prototype is clobbered and only optimize if it |
| 92 | // was clobbered exactly once, but that seems like overkill. In almost all cases it will be |
| 93 | // clobbered once, and if it's clobbered more than once, that will probably only occur |
| 94 | // before we started optimizing, anyway. |
| 95 | , m_inheritorIDWatchpoint(InitializedBlind) |
oliver@apple.com | 8e293b7 | 2010-04-27 04:22:46 +0000 | [diff] [blame] | 96 | { |
oliver@apple.com | e79807b | 2009-05-05 11:34:23 +0000 | [diff] [blame] | 97 | } |
| 98 | |
benjamin@webkit.org | cff06e4 | 2012-08-30 21:23:51 +0000 | [diff] [blame] | 99 | void JSFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const String& name) |
commit-queue@webkit.org | 53aecd2 | 2011-08-19 00:58:34 +0000 | [diff] [blame] | 100 | { |
oliver@apple.com | 2346a3e | 2011-09-07 19:40:41 +0000 | [diff] [blame] | 101 | Base::finishCreation(exec->globalData()); |
commit-queue@webkit.org | 53aecd2 | 2011-08-19 00:58:34 +0000 | [diff] [blame] | 102 | ASSERT(inherits(&s_info)); |
| 103 | m_executable.set(exec->globalData(), this, executable); |
benjamin@webkit.org | 762e2c6 | 2012-09-04 21:19:25 +0000 | [diff] [blame] | 104 | putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name), DontDelete | ReadOnly | DontEnum); |
commit-queue@webkit.org | 53aecd2 | 2011-08-19 00:58:34 +0000 | [diff] [blame] | 105 | putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum); |
| 106 | } |
| 107 | |
barraclough@apple.com | cef11dc | 2012-05-10 18:40:29 +0000 | [diff] [blame] | 108 | Structure* JSFunction::cacheInheritorID(ExecState* exec) |
| 109 | { |
| 110 | JSValue prototype = get(exec, exec->globalData().propertyNames->prototype); |
| 111 | if (prototype.isObject()) |
| 112 | m_cachedInheritorID.set(exec->globalData(), this, asObject(prototype)->inheritorID(exec->globalData())); |
| 113 | else |
| 114 | m_cachedInheritorID.set(exec->globalData(), this, globalObject()->emptyObjectStructure()); |
| 115 | return m_cachedInheritorID.get(); |
| 116 | } |
| 117 | |
ggaren@apple.com | 0030e13 | 2012-09-12 06:14:56 +0000 | [diff] [blame] | 118 | String JSFunction::name(ExecState* exec) |
barraclough@apple.com | 4be541c | 2010-05-20 02:38:01 +0000 | [diff] [blame] | 119 | { |
ggaren@apple.com | 0030e13 | 2012-09-12 06:14:56 +0000 | [diff] [blame] | 120 | return get(exec, exec->globalData().propertyNames->name).toWTFString(exec); |
barraclough@apple.com | 4be541c | 2010-05-20 02:38:01 +0000 | [diff] [blame] | 121 | } |
| 122 | |
ggaren@apple.com | 0030e13 | 2012-09-12 06:14:56 +0000 | [diff] [blame] | 123 | String JSFunction::displayName(ExecState* exec) |
barraclough@apple.com | 4be541c | 2010-05-20 02:38:01 +0000 | [diff] [blame] | 124 | { |
oliver@apple.com | af134a7 | 2011-04-13 18:48:22 +0000 | [diff] [blame] | 125 | JSValue displayName = getDirect(exec->globalData(), exec->globalData().propertyNames->displayName); |
barraclough@apple.com | 4be541c | 2010-05-20 02:38:01 +0000 | [diff] [blame] | 126 | |
mhahnenberg@apple.com | c58d54d | 2011-12-16 19:06:44 +0000 | [diff] [blame] | 127 | if (displayName && isJSString(displayName)) |
barraclough@apple.com | 550b0d8 | 2010-05-21 23:49:48 +0000 | [diff] [blame] | 128 | return asString(displayName)->tryGetValue(); |
barraclough@apple.com | 4be541c | 2010-05-20 02:38:01 +0000 | [diff] [blame] | 129 | |
benjamin@webkit.org | cff06e4 | 2012-08-30 21:23:51 +0000 | [diff] [blame] | 130 | return String(); |
barraclough@apple.com | 4be541c | 2010-05-20 02:38:01 +0000 | [diff] [blame] | 131 | } |
| 132 | |
benjamin@webkit.org | cff06e4 | 2012-08-30 21:23:51 +0000 | [diff] [blame] | 133 | const String JSFunction::calculatedDisplayName(ExecState* exec) |
barraclough@apple.com | 4be541c | 2010-05-20 02:38:01 +0000 | [diff] [blame] | 134 | { |
benjamin@webkit.org | cff06e4 | 2012-08-30 21:23:51 +0000 | [diff] [blame] | 135 | const String explicitName = displayName(exec); |
barraclough@apple.com | 4be541c | 2010-05-20 02:38:01 +0000 | [diff] [blame] | 136 | |
| 137 | if (!explicitName.isEmpty()) |
| 138 | return explicitName; |
| 139 | |
benjamin@webkit.org | cff06e4 | 2012-08-30 21:23:51 +0000 | [diff] [blame] | 140 | const String actualName = name(exec); |
oliver@apple.com | f7190bf | 2012-02-01 23:23:30 +0000 | [diff] [blame] | 141 | if (!actualName.isEmpty() || isHostFunction()) |
| 142 | return actualName; |
| 143 | |
benjamin@webkit.org | c9b7a20 | 2012-09-08 05:46:29 +0000 | [diff] [blame] | 144 | return jsExecutable()->inferredName().string(); |
barraclough@apple.com | 4be541c | 2010-05-20 02:38:01 +0000 | [diff] [blame] | 145 | } |
| 146 | |
yurys@chromium.org | 0114f05 | 2011-11-14 09:27:25 +0000 | [diff] [blame] | 147 | const SourceCode* JSFunction::sourceCode() const |
| 148 | { |
| 149 | if (isHostFunction()) |
| 150 | return 0; |
| 151 | return &jsExecutable()->source(); |
| 152 | } |
| 153 | |
mhahnenberg@apple.com | 982c9ea | 2011-09-23 19:40:09 +0000 | [diff] [blame] | 154 | void JSFunction::visitChildren(JSCell* cell, SlotVisitor& visitor) |
| 155 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 156 | JSFunction* thisObject = jsCast<JSFunction*>(cell); |
mhahnenberg@apple.com | 982c9ea | 2011-09-23 19:40:09 +0000 | [diff] [blame] | 157 | ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); |
| 158 | COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); |
| 159 | ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); |
| 160 | Base::visitChildren(thisObject, visitor); |
| 161 | |
ggaren@apple.com | b11e787 | 2012-08-30 22:50:00 +0000 | [diff] [blame] | 162 | visitor.append(&thisObject->m_scope); |
ggaren@apple.com | acb40df | 2012-08-27 03:57:02 +0000 | [diff] [blame] | 163 | visitor.append(&thisObject->m_executable); |
mjs | 308be5a | 2006-08-14 03:06:14 +0000 | [diff] [blame] | 164 | } |
| 165 | |
mhahnenberg@apple.com | 2413eb8 | 2011-09-27 22:46:51 +0000 | [diff] [blame] | 166 | CallType JSFunction::getCallData(JSCell* cell, CallData& callData) |
| 167 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 168 | JSFunction* thisObject = jsCast<JSFunction*>(cell); |
mhahnenberg@apple.com | 2413eb8 | 2011-09-27 22:46:51 +0000 | [diff] [blame] | 169 | if (thisObject->isHostFunction()) { |
| 170 | callData.native.function = thisObject->nativeFunction(); |
oliver@apple.com | e79807b | 2009-05-05 11:34:23 +0000 | [diff] [blame] | 171 | return CallTypeHost; |
| 172 | } |
mhahnenberg@apple.com | 2413eb8 | 2011-09-27 22:46:51 +0000 | [diff] [blame] | 173 | callData.js.functionExecutable = thisObject->jsExecutable(); |
ggaren@apple.com | b11e787 | 2012-08-30 22:50:00 +0000 | [diff] [blame] | 174 | callData.js.scope = thisObject->scope(); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 175 | return CallTypeJS; |
| 176 | } |
| 177 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 178 | JSValue JSFunction::argumentsGetter(ExecState* exec, JSValue slotBase, PropertyName) |
mjs | 70d7421 | 2005-08-07 06:17:49 +0000 | [diff] [blame] | 179 | { |
barraclough@apple.com | 484a9d3 | 2012-03-22 18:54:50 +0000 | [diff] [blame] | 180 | JSFunction* thisObj = jsCast<JSFunction*>(slotBase); |
oliver@apple.com | e79807b | 2009-05-05 11:34:23 +0000 | [diff] [blame] | 181 | ASSERT(!thisObj->isHostFunction()); |
fpizlo@apple.com | e8a38be | 2012-01-27 01:15:16 +0000 | [diff] [blame] | 182 | return exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObj); |
mjs | 70d7421 | 2005-08-07 06:17:49 +0000 | [diff] [blame] | 183 | } |
| 184 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 185 | JSValue JSFunction::callerGetter(ExecState* exec, JSValue slotBase, PropertyName) |
mjs | 70d7421 | 2005-08-07 06:17:49 +0000 | [diff] [blame] | 186 | { |
barraclough@apple.com | 484a9d3 | 2012-03-22 18:54:50 +0000 | [diff] [blame] | 187 | JSFunction* thisObj = jsCast<JSFunction*>(slotBase); |
oliver@apple.com | e79807b | 2009-05-05 11:34:23 +0000 | [diff] [blame] | 188 | ASSERT(!thisObj->isHostFunction()); |
barraclough@apple.com | 4f1d0a5 | 2012-03-02 00:12:58 +0000 | [diff] [blame] | 189 | JSValue caller = exec->interpreter()->retrieveCallerFromVMCode(exec, thisObj); |
| 190 | |
| 191 | // See ES5.1 15.3.5.4 - Function.caller may not be used to retrieve a strict caller. |
| 192 | if (!caller.isObject() || !asObject(caller)->inherits(&JSFunction::s_info)) |
| 193 | return caller; |
barraclough@apple.com | 484a9d3 | 2012-03-22 18:54:50 +0000 | [diff] [blame] | 194 | JSFunction* function = jsCast<JSFunction*>(caller); |
barraclough@apple.com | 4f1d0a5 | 2012-03-02 00:12:58 +0000 | [diff] [blame] | 195 | if (function->isHostFunction() || !function->jsExecutable()->isStrictMode()) |
| 196 | return caller; |
benjamin@webkit.org | 762e2c6 | 2012-09-04 21:19:25 +0000 | [diff] [blame] | 197 | return throwTypeError(exec, ASCIILiteral("Function.caller used to retrieve strict caller")); |
ap | 3d61914 | 2006-10-31 18:16:08 +0000 | [diff] [blame] | 198 | } |
| 199 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 200 | JSValue JSFunction::lengthGetter(ExecState*, JSValue slotBase, PropertyName) |
ap | 3d61914 | 2006-10-31 18:16:08 +0000 | [diff] [blame] | 201 | { |
barraclough@apple.com | 484a9d3 | 2012-03-22 18:54:50 +0000 | [diff] [blame] | 202 | JSFunction* thisObj = jsCast<JSFunction*>(slotBase); |
oliver@apple.com | e79807b | 2009-05-05 11:34:23 +0000 | [diff] [blame] | 203 | ASSERT(!thisObj->isHostFunction()); |
oliver@apple.com | 5b67d9e | 2010-10-25 22:40:53 +0000 | [diff] [blame] | 204 | return jsNumber(thisObj->jsExecutable()->parameterCount()); |
mjs | 70d7421 | 2005-08-07 06:17:49 +0000 | [diff] [blame] | 205 | } |
| 206 | |
ggaren@apple.com | 0030e13 | 2012-09-12 06:14:56 +0000 | [diff] [blame] | 207 | JSValue JSFunction::nameGetter(ExecState*, JSValue slotBase, PropertyName) |
| 208 | { |
| 209 | JSFunction* thisObj = jsCast<JSFunction*>(slotBase); |
| 210 | ASSERT(!thisObj->isHostFunction()); |
| 211 | return thisObj->jsExecutable()->nameValue(); |
| 212 | } |
| 213 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 214 | bool JSFunction::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 215 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 216 | JSFunction* thisObject = jsCast<JSFunction*>(cell); |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 217 | if (thisObject->isHostFunction()) |
| 218 | return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); |
oliver@apple.com | e79807b | 2009-05-05 11:34:23 +0000 | [diff] [blame] | 219 | |
cwzwarich@webkit.org | de65b9e | 2008-10-24 20:44:58 +0000 | [diff] [blame] | 220 | if (propertyName == exec->propertyNames().prototype) { |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 221 | WriteBarrierBase<Unknown>* location = thisObject->getDirectLocation(exec->globalData(), propertyName); |
cwzwarich@webkit.org | de65b9e | 2008-10-24 20:44:58 +0000 | [diff] [blame] | 222 | |
barraclough@apple.com | 00d4c0e | 2011-09-15 18:47:20 +0000 | [diff] [blame] | 223 | if (!location) { |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 224 | JSObject* prototype = constructEmptyObject(exec, thisObject->globalObject()->emptyObjectStructure()); |
| 225 | prototype->putDirect(exec->globalData(), exec->propertyNames().constructor, thisObject, DontEnum); |
barraclough@apple.com | 4cc9551 | 2012-01-13 01:40:22 +0000 | [diff] [blame] | 226 | thisObject->putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | DontEnum); |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 227 | location = thisObject->getDirectLocation(exec->globalData(), exec->propertyNames().prototype); |
barraclough@apple.com | 00d4c0e | 2011-09-15 18:47:20 +0000 | [diff] [blame] | 228 | } |
cwzwarich@webkit.org | de65b9e | 2008-10-24 20:44:58 +0000 | [diff] [blame] | 229 | |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 230 | slot.setValue(thisObject, location->get(), thisObject->offsetForLocation(location)); |
cwzwarich@webkit.org | de65b9e | 2008-10-24 20:44:58 +0000 | [diff] [blame] | 231 | } |
| 232 | |
mjs | 23fc88d | 2007-03-19 05:43:47 +0000 | [diff] [blame] | 233 | if (propertyName == exec->propertyNames().arguments) { |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 234 | if (thisObject->jsExecutable()->isStrictMode()) { |
barraclough@apple.com | 69e904a | 2011-10-20 01:18:03 +0000 | [diff] [blame] | 235 | bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); |
| 236 | if (!result) { |
fpizlo@apple.com | d8dd053 | 2012-09-13 04:18:52 +0000 | [diff] [blame] | 237 | thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor); |
barraclough@apple.com | 69e904a | 2011-10-20 01:18:03 +0000 | [diff] [blame] | 238 | result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); |
| 239 | ASSERT(result); |
| 240 | } |
| 241 | return result; |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 242 | } |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 243 | slot.setCacheableCustom(thisObject, argumentsGetter); |
mjs | 234d8b1 | 2005-07-25 22:17:20 +0000 | [diff] [blame] | 244 | return true; |
darin | 0210a25 | 2002-11-20 09:11:43 +0000 | [diff] [blame] | 245 | } |
ap | 3d61914 | 2006-10-31 18:16:08 +0000 | [diff] [blame] | 246 | |
mjs | 23fc88d | 2007-03-19 05:43:47 +0000 | [diff] [blame] | 247 | if (propertyName == exec->propertyNames().length) { |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 248 | slot.setCacheableCustom(thisObject, lengthGetter); |
mjs | 234d8b1 | 2005-07-25 22:17:20 +0000 | [diff] [blame] | 249 | return true; |
darin | 0210a25 | 2002-11-20 09:11:43 +0000 | [diff] [blame] | 250 | } |
ap | 3d61914 | 2006-10-31 18:16:08 +0000 | [diff] [blame] | 251 | |
ggaren@apple.com | 0030e13 | 2012-09-12 06:14:56 +0000 | [diff] [blame] | 252 | if (propertyName == exec->propertyNames().name) { |
| 253 | slot.setCacheableCustom(thisObject, nameGetter); |
| 254 | return true; |
| 255 | } |
| 256 | |
mjs | 23fc88d | 2007-03-19 05:43:47 +0000 | [diff] [blame] | 257 | if (propertyName == exec->propertyNames().caller) { |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 258 | if (thisObject->jsExecutable()->isStrictMode()) { |
barraclough@apple.com | 69e904a | 2011-10-20 01:18:03 +0000 | [diff] [blame] | 259 | bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); |
| 260 | if (!result) { |
fpizlo@apple.com | d8dd053 | 2012-09-13 04:18:52 +0000 | [diff] [blame] | 261 | thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor); |
barraclough@apple.com | 69e904a | 2011-10-20 01:18:03 +0000 | [diff] [blame] | 262 | result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); |
| 263 | ASSERT(result); |
| 264 | } |
| 265 | return result; |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 266 | } |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 267 | slot.setCacheableCustom(thisObject, callerGetter); |
ap | 3d61914 | 2006-10-31 18:16:08 +0000 | [diff] [blame] | 268 | return true; |
| 269 | } |
| 270 | |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 271 | return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); |
darin | 0210a25 | 2002-11-20 09:11:43 +0000 | [diff] [blame] | 272 | } |
| 273 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 274 | bool JSFunction::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 275 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 276 | JSFunction* thisObject = jsCast<JSFunction*>(object); |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 277 | if (thisObject->isHostFunction()) |
| 278 | return Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 279 | |
| 280 | if (propertyName == exec->propertyNames().prototype) { |
| 281 | PropertySlot slot; |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 282 | thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot); |
| 283 | return Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); |
oliver@apple.com | 4b4f785 | 2009-08-26 16:52:15 +0000 | [diff] [blame] | 284 | } |
| 285 | |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 286 | if (propertyName == exec->propertyNames().arguments) { |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 287 | if (thisObject->jsExecutable()->isStrictMode()) { |
| 288 | bool result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); |
barraclough@apple.com | 69e904a | 2011-10-20 01:18:03 +0000 | [diff] [blame] | 289 | if (!result) { |
fpizlo@apple.com | d8dd053 | 2012-09-13 04:18:52 +0000 | [diff] [blame] | 290 | thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor); |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 291 | result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); |
barraclough@apple.com | 69e904a | 2011-10-20 01:18:03 +0000 | [diff] [blame] | 292 | ASSERT(result); |
| 293 | } |
| 294 | return result; |
| 295 | } |
fpizlo@apple.com | e8a38be | 2012-01-27 01:15:16 +0000 | [diff] [blame] | 296 | descriptor.setDescriptor(exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObject), ReadOnly | DontEnum | DontDelete); |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 297 | return true; |
| 298 | } |
| 299 | |
| 300 | if (propertyName == exec->propertyNames().length) { |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 301 | descriptor.setDescriptor(jsNumber(thisObject->jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete); |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 302 | return true; |
| 303 | } |
| 304 | |
ggaren@apple.com | 0030e13 | 2012-09-12 06:14:56 +0000 | [diff] [blame] | 305 | if (propertyName == exec->propertyNames().name) { |
| 306 | descriptor.setDescriptor(thisObject->jsExecutable()->nameValue(), ReadOnly | DontEnum | DontDelete); |
| 307 | return true; |
| 308 | } |
| 309 | |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 310 | if (propertyName == exec->propertyNames().caller) { |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 311 | if (thisObject->jsExecutable()->isStrictMode()) { |
| 312 | bool result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); |
barraclough@apple.com | 69e904a | 2011-10-20 01:18:03 +0000 | [diff] [blame] | 313 | if (!result) { |
fpizlo@apple.com | d8dd053 | 2012-09-13 04:18:52 +0000 | [diff] [blame] | 314 | thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor); |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 315 | result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); |
barraclough@apple.com | 69e904a | 2011-10-20 01:18:03 +0000 | [diff] [blame] | 316 | ASSERT(result); |
| 317 | } |
| 318 | return result; |
| 319 | } |
fpizlo@apple.com | e8a38be | 2012-01-27 01:15:16 +0000 | [diff] [blame] | 320 | descriptor.setDescriptor(exec->interpreter()->retrieveCallerFromVMCode(exec, thisObject), ReadOnly | DontEnum | DontDelete); |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 321 | return true; |
| 322 | } |
| 323 | |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 324 | return Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 325 | } |
| 326 | |
fpizlo@apple.com | d8dd053 | 2012-09-13 04:18:52 +0000 | [diff] [blame] | 327 | void JSFunction::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) |
eric@webkit.org | c293f4c | 2010-01-13 00:58:21 +0000 | [diff] [blame] | 328 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 329 | JSFunction* thisObject = jsCast<JSFunction*>(object); |
mhahnenberg@apple.com | 5726238 | 2011-11-03 00:25:45 +0000 | [diff] [blame] | 330 | if (!thisObject->isHostFunction() && (mode == IncludeDontEnumProperties)) { |
barraclough@apple.com | 74aa1c9 | 2010-11-16 06:05:38 +0000 | [diff] [blame] | 331 | // Make sure prototype has been reified. |
| 332 | PropertySlot slot; |
mhahnenberg@apple.com | 5726238 | 2011-11-03 00:25:45 +0000 | [diff] [blame] | 333 | thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, exec->propertyNames().prototype, slot); |
barraclough@apple.com | 74aa1c9 | 2010-11-16 06:05:38 +0000 | [diff] [blame] | 334 | |
eric@webkit.org | c293f4c | 2010-01-13 00:58:21 +0000 | [diff] [blame] | 335 | propertyNames.add(exec->propertyNames().arguments); |
eric@webkit.org | c293f4c | 2010-01-13 00:58:21 +0000 | [diff] [blame] | 336 | propertyNames.add(exec->propertyNames().caller); |
| 337 | propertyNames.add(exec->propertyNames().length); |
ggaren@apple.com | 0030e13 | 2012-09-12 06:14:56 +0000 | [diff] [blame] | 338 | propertyNames.add(exec->propertyNames().name); |
eric@webkit.org | c293f4c | 2010-01-13 00:58:21 +0000 | [diff] [blame] | 339 | } |
fpizlo@apple.com | d8dd053 | 2012-09-13 04:18:52 +0000 | [diff] [blame] | 340 | Base::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode); |
eric@webkit.org | c293f4c | 2010-01-13 00:58:21 +0000 | [diff] [blame] | 341 | } |
| 342 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 343 | void JSFunction::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) |
mhahnenberg@apple.com | 5e2b712 | 2011-10-08 00:06:07 +0000 | [diff] [blame] | 344 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 345 | JSFunction* thisObject = jsCast<JSFunction*>(cell); |
mhahnenberg@apple.com | 5e2b712 | 2011-10-08 00:06:07 +0000 | [diff] [blame] | 346 | if (thisObject->isHostFunction()) { |
| 347 | Base::put(thisObject, exec, propertyName, value, slot); |
oliver@apple.com | e79807b | 2009-05-05 11:34:23 +0000 | [diff] [blame] | 348 | return; |
| 349 | } |
barraclough@apple.com | 74aa1c9 | 2010-11-16 06:05:38 +0000 | [diff] [blame] | 350 | if (propertyName == exec->propertyNames().prototype) { |
| 351 | // Make sure prototype has been reified, such that it can only be overwritten |
| 352 | // following the rules set out in ECMA-262 8.12.9. |
| 353 | PropertySlot slot; |
mhahnenberg@apple.com | 5c103b0 | 2011-10-26 17:55:34 +0000 | [diff] [blame] | 354 | thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot); |
barraclough@apple.com | cef11dc | 2012-05-10 18:40:29 +0000 | [diff] [blame] | 355 | thisObject->m_cachedInheritorID.clear(); |
fpizlo@apple.com | f5db15e | 2012-11-14 07:22:57 +0000 | [diff] [blame] | 356 | thisObject->m_inheritorIDWatchpoint.notifyWrite(); |
barraclough@apple.com | 266a537 | 2012-05-15 03:43:54 +0000 | [diff] [blame] | 357 | // Don't allow this to be cached, since a [[Put]] must clear m_cachedInheritorID. |
| 358 | PutPropertySlot dontCache; |
| 359 | Base::put(thisObject, exec, propertyName, value, dontCache); |
| 360 | return; |
barraclough@apple.com | 74aa1c9 | 2010-11-16 06:05:38 +0000 | [diff] [blame] | 361 | } |
barraclough@apple.com | 69e904a | 2011-10-20 01:18:03 +0000 | [diff] [blame] | 362 | if (thisObject->jsExecutable()->isStrictMode() && (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().caller)) { |
| 363 | // This will trigger the property to be reified, if this is not already the case! |
| 364 | bool okay = thisObject->hasProperty(exec, propertyName); |
| 365 | ASSERT_UNUSED(okay, okay); |
| 366 | Base::put(thisObject, exec, propertyName, value, slot); |
| 367 | return; |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 368 | } |
ggaren@apple.com | 0030e13 | 2012-09-12 06:14:56 +0000 | [diff] [blame] | 369 | if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length || propertyName == exec->propertyNames().name || propertyName == exec->propertyNames().caller) { |
barraclough@apple.com | eb88e08 | 2012-03-06 20:20:04 +0000 | [diff] [blame] | 370 | if (slot.isStrictMode()) |
| 371 | throwTypeError(exec, StrictModeReadonlyPropertyWriteError); |
darin | 0210a25 | 2002-11-20 09:11:43 +0000 | [diff] [blame] | 372 | return; |
barraclough@apple.com | eb88e08 | 2012-03-06 20:20:04 +0000 | [diff] [blame] | 373 | } |
mhahnenberg@apple.com | 5e2b712 | 2011-10-08 00:06:07 +0000 | [diff] [blame] | 374 | Base::put(thisObject, exec, propertyName, value, slot); |
darin | 0210a25 | 2002-11-20 09:11:43 +0000 | [diff] [blame] | 375 | } |
| 376 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 377 | bool JSFunction::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 378 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 379 | JSFunction* thisObject = jsCast<JSFunction*>(cell); |
barraclough@apple.com | 9ce855c | 2012-03-11 18:58:04 +0000 | [diff] [blame] | 380 | // For non-host functions, don't let these properties by deleted - except by DefineOwnProperty. |
| 381 | if (!thisObject->isHostFunction() && !exec->globalData().isInDefineOwnProperty() |
| 382 | && (propertyName == exec->propertyNames().arguments |
| 383 | || propertyName == exec->propertyNames().length |
ggaren@apple.com | 0030e13 | 2012-09-12 06:14:56 +0000 | [diff] [blame] | 384 | || propertyName == exec->propertyNames().name |
barraclough@apple.com | 9ce855c | 2012-03-11 18:58:04 +0000 | [diff] [blame] | 385 | || propertyName == exec->propertyNames().prototype |
| 386 | || propertyName == exec->propertyNames().caller)) |
darin | 0210a25 | 2002-11-20 09:11:43 +0000 | [diff] [blame] | 387 | return false; |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 388 | return Base::deleteProperty(thisObject, exec, propertyName); |
darin | 0210a25 | 2002-11-20 09:11:43 +0000 | [diff] [blame] | 389 | } |
| 390 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 391 | bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor, bool throwException) |
barraclough@apple.com | eb88e08 | 2012-03-06 20:20:04 +0000 | [diff] [blame] | 392 | { |
| 393 | JSFunction* thisObject = jsCast<JSFunction*>(object); |
| 394 | if (thisObject->isHostFunction()) |
| 395 | return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); |
| 396 | |
| 397 | if (propertyName == exec->propertyNames().prototype) { |
| 398 | // Make sure prototype has been reified, such that it can only be overwritten |
| 399 | // following the rules set out in ECMA-262 8.12.9. |
| 400 | PropertySlot slot; |
| 401 | thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot); |
barraclough@apple.com | cef11dc | 2012-05-10 18:40:29 +0000 | [diff] [blame] | 402 | thisObject->m_cachedInheritorID.clear(); |
fpizlo@apple.com | f5db15e | 2012-11-14 07:22:57 +0000 | [diff] [blame] | 403 | thisObject->m_inheritorIDWatchpoint.notifyWrite(); |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 404 | return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); |
| 405 | } |
| 406 | |
| 407 | bool valueCheck; |
| 408 | if (propertyName == exec->propertyNames().arguments) { |
| 409 | if (thisObject->jsExecutable()->isStrictMode()) { |
| 410 | if (!Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor)) |
fpizlo@apple.com | d8dd053 | 2012-09-13 04:18:52 +0000 | [diff] [blame] | 411 | thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor); |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 412 | return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); |
barraclough@apple.com | 921cd1f | 2012-03-19 19:59:03 +0000 | [diff] [blame] | 413 | } |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 414 | valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObject)); |
| 415 | } else if (propertyName == exec->propertyNames().caller) { |
| 416 | if (thisObject->jsExecutable()->isStrictMode()) { |
| 417 | if (!Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor)) |
fpizlo@apple.com | d8dd053 | 2012-09-13 04:18:52 +0000 | [diff] [blame] | 418 | thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor); |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 419 | return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); |
barraclough@apple.com | eb88e08 | 2012-03-06 20:20:04 +0000 | [diff] [blame] | 420 | } |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 421 | valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), exec->interpreter()->retrieveCallerFromVMCode(exec, thisObject)); |
| 422 | } else if (propertyName == exec->propertyNames().length) |
| 423 | valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), jsNumber(thisObject->jsExecutable()->parameterCount())); |
ggaren@apple.com | 0030e13 | 2012-09-12 06:14:56 +0000 | [diff] [blame] | 424 | else if (propertyName == exec->propertyNames().name) |
| 425 | valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), thisObject->jsExecutable()->nameValue()); |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 426 | else |
| 427 | return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); |
| 428 | |
| 429 | if (descriptor.configurablePresent() && descriptor.configurable()) { |
| 430 | if (throwException) |
benjamin@webkit.org | 762e2c6 | 2012-09-04 21:19:25 +0000 | [diff] [blame] | 431 | throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property."))); |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 432 | return false; |
| 433 | } |
| 434 | if (descriptor.enumerablePresent() && descriptor.enumerable()) { |
| 435 | if (throwException) |
benjamin@webkit.org | 762e2c6 | 2012-09-04 21:19:25 +0000 | [diff] [blame] | 436 | throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property."))); |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 437 | return false; |
| 438 | } |
| 439 | if (descriptor.isAccessorDescriptor()) { |
| 440 | if (throwException) |
benjamin@webkit.org | 762e2c6 | 2012-09-04 21:19:25 +0000 | [diff] [blame] | 441 | throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property."))); |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 442 | return false; |
| 443 | } |
| 444 | if (descriptor.writablePresent() && descriptor.writable()) { |
| 445 | if (throwException) |
benjamin@webkit.org | 762e2c6 | 2012-09-04 21:19:25 +0000 | [diff] [blame] | 446 | throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property."))); |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 447 | return false; |
| 448 | } |
| 449 | if (!valueCheck) { |
barraclough@apple.com | eb88e08 | 2012-03-06 20:20:04 +0000 | [diff] [blame] | 450 | if (throwException) |
benjamin@webkit.org | 762e2c6 | 2012-09-04 21:19:25 +0000 | [diff] [blame] | 451 | throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property."))); |
barraclough@apple.com | eb88e08 | 2012-03-06 20:20:04 +0000 | [diff] [blame] | 452 | return false; |
| 453 | } |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 454 | return true; |
barraclough@apple.com | eb88e08 | 2012-03-06 20:20:04 +0000 | [diff] [blame] | 455 | } |
| 456 | |
mhahnenberg@apple.com | 79c8e6e | 2011-10-08 23:26:41 +0000 | [diff] [blame] | 457 | // ECMA 13.2.2 [[Construct]] |
| 458 | ConstructType JSFunction::getConstructData(JSCell* cell, ConstructData& constructData) |
| 459 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 460 | JSFunction* thisObject = jsCast<JSFunction*>(cell); |
mhahnenberg@apple.com | 79c8e6e | 2011-10-08 23:26:41 +0000 | [diff] [blame] | 461 | if (thisObject->isHostFunction()) { |
| 462 | constructData.native.function = thisObject->nativeConstructor(); |
barraclough@apple.com | 2221566 | 2011-09-22 21:22:17 +0000 | [diff] [blame] | 463 | return ConstructTypeHost; |
| 464 | } |
mhahnenberg@apple.com | 79c8e6e | 2011-10-08 23:26:41 +0000 | [diff] [blame] | 465 | constructData.js.functionExecutable = thisObject->jsExecutable(); |
ggaren@apple.com | b11e787 | 2012-08-30 22:50:00 +0000 | [diff] [blame] | 466 | constructData.js.scope = thisObject->scope(); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 467 | return ConstructTypeJS; |
| 468 | } |
oliver@apple.com | f7190bf | 2012-02-01 23:23:30 +0000 | [diff] [blame] | 469 | |
| 470 | |
benjamin@webkit.org | cff06e4 | 2012-08-30 21:23:51 +0000 | [diff] [blame] | 471 | String getCalculatedDisplayName(CallFrame* callFrame, JSObject* object) |
oliver@apple.com | f7190bf | 2012-02-01 23:23:30 +0000 | [diff] [blame] | 472 | { |
| 473 | if (JSFunction* function = jsDynamicCast<JSFunction*>(object)) |
| 474 | return function->calculatedDisplayName(callFrame); |
| 475 | if (InternalFunction* function = jsDynamicCast<InternalFunction*>(object)) |
| 476 | return function->calculatedDisplayName(callFrame); |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 477 | return ""; |
oliver@apple.com | f7190bf | 2012-02-01 23:23:30 +0000 | [diff] [blame] | 478 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 479 | |
cwzwarich@webkit.org | 3f782f6 | 2008-09-08 01:28:33 +0000 | [diff] [blame] | 480 | } // namespace JSC |