source: webkit/trunk/JavaScriptCore/kjs/JSFunction.cpp@ 37337

Last change on this file since 37337 was 37257, checked in by Darin Adler, 17 years ago

JavaScriptCore:

2008-10-03 Darin Adler <Darin Adler>

Reviewed by Geoff Garen.

Remove m_globalObject and m_globalData from ExecState.

SunSpider says this is a wash (slightly faster but not statistically
significant); which is good enough since it's a preparation step and
not supposed to be a spedup.

  • API/JSCallbackFunction.cpp: (JSC::JSCallbackFunction::JSCallbackFunction):
  • kjs/ArrayConstructor.cpp: (JSC::ArrayConstructor::ArrayConstructor):
  • kjs/BooleanConstructor.cpp: (JSC::BooleanConstructor::BooleanConstructor):
  • kjs/DateConstructor.cpp: (JSC::DateConstructor::DateConstructor):
  • kjs/ErrorConstructor.cpp: (JSC::ErrorConstructor::ErrorConstructor):
  • kjs/FunctionPrototype.cpp: (JSC::FunctionPrototype::FunctionPrototype):
  • kjs/JSFunction.cpp: (JSC::JSFunction::JSFunction):
  • kjs/NativeErrorConstructor.cpp: (JSC::NativeErrorConstructor::NativeErrorConstructor):
  • kjs/NumberConstructor.cpp: (JSC::NumberConstructor::NumberConstructor):
  • kjs/ObjectConstructor.cpp: (JSC::ObjectConstructor::ObjectConstructor):
  • kjs/PrototypeFunction.cpp: (JSC::PrototypeFunction::PrototypeFunction):
  • kjs/RegExpConstructor.cpp: (JSC::RegExpConstructor::RegExpConstructor):
  • kjs/StringConstructor.cpp: (JSC::StringConstructor::StringConstructor): Pass JSGlobalData* instead of ExecState* to the InternalFunction constructor.
  • API/OpaqueJSString.cpp: Added now-needed include.
  • VM/CTI.cpp: (JSC::CTI::emitSlowScriptCheck): Changed to use ARGS_globalData instead of ARGS_exec.
  • VM/CTI.h: Added a new argument to the CTI, the global data pointer. While it's possible to get to the global data pointer using the ExecState pointer, it's slow enough that it's better to just keep it around in the CTI arguments.
  • VM/CodeBlock.h: Moved the CodeType enum here from ExecState.h.
  • VM/Machine.cpp: (JSC::Machine::execute): Pass fewer arguments when constructing ExecState, and pass the global data pointer when invoking CTI. (JSC::Machine::firstCallFrame): Added. Used to get the dynamic global object, which is in the scope chain of the first call frame. (JSC::Machine::cti_op_add): Use globalData instead of exec when possible, to keep fast cases fast, since it's now more expensive to get to it through the exec pointer. (JSC::Machine::cti_timeout_check): Ditto. (JSC::Machine::cti_op_put_by_id_second): Ditto. (JSC::Machine::cti_op_get_by_id_second): Ditto. (JSC::Machine::cti_op_mul): Ditto. (JSC::Machine::cti_vm_compile): Ditto. (JSC::Machine::cti_op_get_by_val): Ditto. (JSC::Machine::cti_op_sub): Ditto. (JSC::Machine::cti_op_put_by_val): Ditto. (JSC::Machine::cti_op_put_by_val_array): Ditto. (JSC::Machine::cti_op_negate): Ditto. (JSC::Machine::cti_op_div): Ditto. (JSC::Machine::cti_op_pre_dec): Ditto. (JSC::Machine::cti_op_post_inc): Ditto. (JSC::Machine::cti_op_lshift): Ditto. (JSC::Machine::cti_op_bitand): Ditto. (JSC::Machine::cti_op_rshift): Ditto. (JSC::Machine::cti_op_bitnot): Ditto. (JSC::Machine::cti_op_mod): Ditto. (JSC::Machine::cti_op_post_dec): Ditto. (JSC::Machine::cti_op_urshift): Ditto. (JSC::Machine::cti_op_bitxor): Ditto. (JSC::Machine::cti_op_bitor): Ditto. (JSC::Machine::cti_op_call_eval): Ditto. (JSC::Machine::cti_op_throw): Ditto. (JSC::Machine::cti_op_is_string): Ditto. (JSC::Machine::cti_op_debug): Ditto. (JSC::Machine::cti_vm_throw): Ditto.
  • VM/Machine.h: Added firstCallFrame.
  • kjs/DebuggerCallFrame.cpp: (JSC::DebuggerCallFrame::evaluate): Pass fewer arguments when constructing ExecState.
  • kjs/ExecState.cpp: Deleted contents. Later we'll remove the file altogether.
  • kjs/ExecState.h: Removed m_globalObject and m_globalData. Moved CodeType into another header. (JSC::ExecState::ExecState): Take only a single argument, a call frame pointer. (JSC::ExecState::dynamicGlobalObject): Get the object from the first call frame since it's no longer stored. (JSC::ExecState::globalData): Get the global data from the scope chain, since we no longer store a pointer to it here. (JSC::ExecState::identifierTable): Ditto. (JSC::ExecState::propertyNames): Ditto. (JSC::ExecState::emptyList): Ditto. (JSC::ExecState::lexer): Ditto. (JSC::ExecState::parser): Ditto. (JSC::ExecState::machine): Ditto. (JSC::ExecState::arrayTable): Ditto. (JSC::ExecState::dateTable): Ditto. (JSC::ExecState::mathTable): Ditto. (JSC::ExecState::numberTable): Ditto. (JSC::ExecState::regExpTable): Ditto. (JSC::ExecState::regExpConstructorTable): Ditto. (JSC::ExecState::stringTable): Ditto. (JSC::ExecState::heap): Ditto.
  • kjs/FunctionConstructor.cpp: (JSC::FunctionConstructor::FunctionConstructor): Pass JSGlobalData* instead of ExecState* to the InternalFunction constructor. (JSC::constructFunction): Pass the global data pointer when constructing a new scope chain.
  • kjs/InternalFunction.cpp: (JSC::InternalFunction::InternalFunction): Take a JSGlobalData* instead of an ExecState*. Later we can change more places to work this way -- it's more efficient to take the type you need since the caller might already have it.
  • kjs/InternalFunction.h: Ditto.
  • kjs/JSCell.h: (JSC::JSCell::operator new): Added an overload that takes a JSGlobalData* so you can construct without an ExecState*.
  • kjs/JSGlobalObject.cpp: (JSC::JSGlobalObject::init): Moved creation of the global scope chain in here, since it now requires a pointer to the global data. Moved the initialization of the call frame in here since it requires the global scope chain node. Removed the extra argument to ExecState when creating the global ExecState*.
  • kjs/JSGlobalObject.h: Removed initialization of globalScopeChain and the call frame from the JSGlobalObjectData constructor. Added a thisValue argument to the init function.
  • kjs/JSNumberCell.cpp: Added versions of jsNumberCell that take JSGlobalData* rather than ExecState*.
  • kjs/JSNumberCell.h: (JSC::JSNumberCell::operator new): Added a version that takes JSGlobalData*. (JSC::JSNumberCell::JSNumberCell): Ditto. (JSC::jsNumber): Ditto.
  • kjs/JSString.cpp: (JSC::jsString): Ditto. (JSC::jsSubstring): Ditto. (JSC::jsOwnedString): Ditto.
  • kjs/JSString.h: (JSC::JSString::JSString): Changed to take JSGlobalData*. (JSC::jsEmptyString): Added a version that takes JSGlobalData*. (JSC::jsSingleCharacterString): Ditto. (JSC::jsSingleCharacterSubstring): Ditto. (JSC::jsNontrivialString): Ditto. (JSC::JSString::getIndex): Ditto. (JSC::jsString): Ditto. (JSC::jsSubstring): Ditto. (JSC::jsOwnedString): Ditto.
  • kjs/ScopeChain.h: Added a globalData pointer to each node. (JSC::ScopeChainNode::ScopeChainNode): Initialize the globalData pointer. (JSC::ScopeChainNode::push): Set the global data pointer in the new node. (JSC::ScopeChain::ScopeChain): Take a globalData argument.
  • kjs/SmallStrings.cpp: (JSC::SmallStrings::createEmptyString): Take JSGlobalData* instead of ExecState*. (JSC::SmallStrings::createSingleCharacterString): Ditto.
  • kjs/SmallStrings.h: (JSC::SmallStrings::emptyString): Ditto. (JSC::SmallStrings::singleCharacterString): Ditto.

WebCore:

2008-10-03 Darin Adler <Darin Adler>

Reviewed by Geoff Garen.

Remove m_globalObject and m_globalData from ExecState.

  • bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::JSDOMWindowBaseData::JSDOMWindowBaseData): Removed an argument now that JSGlobalObject doesn't need it any more. (WebCore::JSDOMWindowBase::JSDOMWindowBase): Removed the argument from the JSDOMWindowBaseData constructor, and added the this argument to the JSGlobalObject constructor. This is because a couple key bits of initialization moved from the data constructor to the JSGlobalObject constructor.
  • bindings/js/JSDOMWindowBase.h: Ditto.
  • bridge/qt/qt_runtime.cpp: (JSC::Bindings::QtRuntimeMethod::QtRuntimeMethod):
  • bridge/runtime_method.cpp: (JSC::RuntimeMethod::RuntimeMethod): Pass JSGlobalData* instead of ExecState* to the InternalFunction constructor.
  • Property svn:eol-style set to native
File size: 5.8 KB
Line 
1/*
2 * Copyright (C) 1999-2002 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Cameron Zwarich ([email protected])
6 * Copyright (C) 2007 Maks Orlovich
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
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#include "config.h"
26#include "JSFunction.h"
27
28#include "CommonIdentifiers.h"
29#include "ExecState.h"
30#include "FunctionPrototype.h"
31#include "JSGlobalObject.h"
32#include "Machine.h"
33#include "ObjectPrototype.h"
34#include "Parser.h"
35#include "PropertyNameArray.h"
36#include "ScopeChainMark.h"
37
38using namespace WTF;
39using namespace Unicode;
40
41namespace JSC {
42
43ASSERT_CLASS_FITS_IN_CELL(JSFunction);
44
45const ClassInfo JSFunction::info = { "Function", 0, 0, 0 };
46
47JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* body, ScopeChainNode* scopeChainNode)
48 : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), name)
49 , m_body(body)
50 , m_scopeChain(scopeChainNode)
51{
52}
53
54void JSFunction::mark()
55{
56 Base::mark();
57 m_body->mark();
58 m_scopeChain.mark();
59}
60
61CallType JSFunction::getCallData(CallData& callData)
62{
63 callData.js.functionBody = m_body.get();
64 callData.js.scopeChain = m_scopeChain.node();
65 return CallTypeJS;
66}
67
68JSValue* JSFunction::call(ExecState* exec, JSValue* thisValue, const ArgList& args)
69{
70 return exec->machine()->execute(m_body.get(), exec, this, thisValue->toThisObject(exec), args, m_scopeChain.node(), exec->exceptionSlot());
71}
72
73JSValue* JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
74{
75 JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
76 return exec->machine()->retrieveArguments(exec, thisObj);
77}
78
79JSValue* JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
80{
81 JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
82 return exec->machine()->retrieveCaller(exec, thisObj);
83}
84
85JSValue* JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
86{
87 JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
88 return jsNumber(exec, thisObj->m_body->parameterCount());
89}
90
91bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
92{
93 if (propertyName == exec->propertyNames().arguments) {
94 slot.setCustom(this, argumentsGetter);
95 return true;
96 }
97
98 if (propertyName == exec->propertyNames().length) {
99 slot.setCustom(this, lengthGetter);
100 return true;
101 }
102
103 if (propertyName == exec->propertyNames().caller) {
104 slot.setCustom(this, callerGetter);
105 return true;
106 }
107
108 return Base::getOwnPropertySlot(exec, propertyName, slot);
109}
110
111void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
112{
113 if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
114 return;
115 Base::put(exec, propertyName, value, slot);
116}
117
118bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
119{
120 if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
121 return false;
122 return Base::deleteProperty(exec, propertyName);
123}
124
125/* Returns the parameter name corresponding to the given index. eg:
126 * function f1(x, y, z): getParameterName(0) --> x
127 *
128 * If a name appears more than once, only the last index at which
129 * it appears associates with it. eg:
130 * function f2(x, x): getParameterName(0) --> null
131 */
132const Identifier& JSFunction::getParameterName(int index)
133{
134 const Identifier* parameters = m_body->parameters();
135
136 if (static_cast<size_t>(index) >= m_body->parameterCount())
137 return m_scopeChain.globalObject()->globalData()->propertyNames->nullIdentifier;
138
139 const Identifier& name = parameters[index];
140
141 // Are there any subsequent parameters with the same name?
142 size_t size = m_body->parameterCount();
143 for (size_t i = index + 1; i < size; ++i) {
144 if (parameters[i] == name)
145 return m_scopeChain.globalObject()->globalData()->propertyNames->nullIdentifier;
146 }
147
148 return name;
149}
150
151// ECMA 13.2.2 [[Construct]]
152ConstructType JSFunction::getConstructData(ConstructData& constructData)
153{
154 constructData.js.functionBody = m_body.get();
155 constructData.js.scopeChain = m_scopeChain.node();
156 return ConstructTypeJS;
157}
158
159JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
160{
161 StructureID* structure;
162 JSValue* prototype = get(exec, exec->propertyNames().prototype);
163 if (prototype->isObject())
164 structure = static_cast<JSObject*>(prototype)->inheritorID();
165 else
166 structure = exec->lexicalGlobalObject()->emptyObjectStructure();
167 JSObject* thisObj = new (exec) JSObject(structure);
168
169 JSValue* result = exec->machine()->execute(m_body.get(), exec, this, thisObj, args, m_scopeChain.node(), exec->exceptionSlot());
170 if (exec->hadException() || !result->isObject())
171 return thisObj;
172 return static_cast<JSObject*>(result);
173}
174
175} // namespace JSC
Note: See TracBrowser for help on using the repository browser.