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

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

JavaScriptCore:

2008-09-20 Darin Adler <Darin Adler>

Reviewed by Maciej Stachowiak.

This also includes some optimizations that make the change an overall
small speedup. Without those it was a bit of a slowdown.

  • API/JSCallbackConstructor.cpp: (JSC::JSCallbackConstructor::JSCallbackConstructor): Take a structure.
  • API/JSCallbackConstructor.h: Ditto.
  • API/JSCallbackFunction.cpp: (JSC::JSCallbackFunction::JSCallbackFunction): Pass a structure.
  • API/JSCallbackObject.h: Take a structure.
  • API/JSCallbackObjectFunctions.h: (JSC::JSCallbackObject::JSCallbackObject): Ditto.
  • API/JSClassRef.cpp: (OpaqueJSClass::prototype): Pass in a structure. Call setPrototype if there's a custom prototype involved.
  • API/JSObjectRef.cpp: (JSObjectMake): Ditto. (JSObjectMakeConstructor): Pass in a structure.
  • VM/Machine.cpp: (JSC::jsLess): Added a special case for when both arguments are strings. This avoids converting both strings to with UString::toDouble. (JSC::jsLessEq): Ditto. (JSC::Machine::privateExecute): Pass in a structure. (JSC::Machine::cti_op_construct_JSConstruct): Ditto. (JSC::Machine::cti_op_new_regexp): Ditto. (JSC::Machine::cti_op_is_string): Ditto.
  • VM/Machine.h: Made isJSString public so it can be used in the CTI.
  • kjs/Arguments.cpp: (JSC::Arguments::Arguments): Pass in a structure.
  • kjs/JSCell.h: Mark constructor explicit.
  • kjs/JSGlobalObject.cpp: (JSC::markIfNeeded): Added an overload for marking structures. (JSC::JSGlobalObject::reset): Eliminate code to set data members to zero. We now do that in the constructor, and we no longer use this anywhere except in the constructor. Added code to create structures. Pass structures rather than prototypes when creating objects. (JSC::JSGlobalObject::mark): Mark the structures.
  • kjs/JSGlobalObject.h: Removed unneeded class declarations. Added initializers for raw pointers in JSGlobalObjectData so everything starts with a 0. Added structure data and accessor functions.
  • kjs/JSImmediate.cpp: (JSC::JSImmediate::nonInlineNaN): Added.
  • kjs/JSImmediate.h: (JSC::JSImmediate::toDouble): Rewrote to avoid PIC branches.
  • kjs/JSNumberCell.cpp: (JSC::jsNumberCell): Made non-inline to avoid PIC branches in functions that call this one. (JSC::jsNaN): Ditto.
  • kjs/JSNumberCell.h: Ditto.
  • kjs/JSObject.h: Removed constructor that takes a prototype. All callers now pass structures.
  • kjs/ArrayConstructor.cpp: (JSC::ArrayConstructor::ArrayConstructor): (JSC::constructArrayWithSizeQuirk):
  • kjs/ArrayConstructor.h:
  • kjs/ArrayPrototype.cpp: (JSC::ArrayPrototype::ArrayPrototype):
  • kjs/ArrayPrototype.h:
  • kjs/BooleanConstructor.cpp: (JSC::BooleanConstructor::BooleanConstructor): (JSC::constructBoolean): (JSC::constructBooleanFromImmediateBoolean):
  • kjs/BooleanConstructor.h:
  • kjs/BooleanObject.cpp: (JSC::BooleanObject::BooleanObject):
  • kjs/BooleanObject.h:
  • kjs/BooleanPrototype.cpp: (JSC::BooleanPrototype::BooleanPrototype):
  • kjs/BooleanPrototype.h:
  • kjs/DateConstructor.cpp: (JSC::DateConstructor::DateConstructor): (JSC::constructDate):
  • kjs/DateConstructor.h:
  • kjs/DateInstance.cpp: (JSC::DateInstance::DateInstance):
  • kjs/DateInstance.h:
  • kjs/DatePrototype.cpp: (JSC::DatePrototype::DatePrototype):
  • kjs/DatePrototype.h:
  • kjs/ErrorConstructor.cpp: (JSC::ErrorConstructor::ErrorConstructor): (JSC::constructError):
  • kjs/ErrorConstructor.h:
  • kjs/ErrorInstance.cpp: (JSC::ErrorInstance::ErrorInstance):
  • kjs/ErrorInstance.h:
  • kjs/ErrorPrototype.cpp: (JSC::ErrorPrototype::ErrorPrototype):
  • kjs/ErrorPrototype.h:
  • kjs/FunctionConstructor.cpp: (JSC::FunctionConstructor::FunctionConstructor):
  • kjs/FunctionConstructor.h:
  • kjs/FunctionPrototype.cpp: (JSC::FunctionPrototype::FunctionPrototype): (JSC::FunctionPrototype::addFunctionProperties):
  • kjs/FunctionPrototype.h:
  • kjs/GlobalEvalFunction.cpp: (JSC::GlobalEvalFunction::GlobalEvalFunction):
  • kjs/GlobalEvalFunction.h:
  • kjs/InternalFunction.cpp: (JSC::InternalFunction::InternalFunction):
  • kjs/InternalFunction.h: (JSC::InternalFunction::InternalFunction):
  • kjs/JSArray.cpp: (JSC::JSArray::JSArray): (JSC::constructEmptyArray): (JSC::constructArray):
  • kjs/JSArray.h:
  • kjs/JSFunction.cpp: (JSC::JSFunction::JSFunction): (JSC::JSFunction::construct):
  • kjs/JSObject.cpp: (JSC::constructEmptyObject):
  • kjs/JSString.cpp: (JSC::StringObject::create):
  • kjs/JSWrapperObject.h:
  • kjs/MathObject.cpp: (JSC::MathObject::MathObject):
  • kjs/MathObject.h:
  • kjs/NativeErrorConstructor.cpp: (JSC::NativeErrorConstructor::NativeErrorConstructor): (JSC::NativeErrorConstructor::construct):
  • kjs/NativeErrorConstructor.h:
  • kjs/NativeErrorPrototype.cpp: (JSC::NativeErrorPrototype::NativeErrorPrototype):
  • kjs/NativeErrorPrototype.h:
  • kjs/NumberConstructor.cpp: (JSC::NumberConstructor::NumberConstructor): (JSC::constructWithNumberConstructor):
  • kjs/NumberConstructor.h:
  • kjs/NumberObject.cpp: (JSC::NumberObject::NumberObject): (JSC::constructNumber): (JSC::constructNumberFromImmediateNumber):
  • kjs/NumberObject.h:
  • kjs/NumberPrototype.cpp: (JSC::NumberPrototype::NumberPrototype):
  • kjs/NumberPrototype.h:
  • kjs/ObjectConstructor.cpp: (JSC::ObjectConstructor::ObjectConstructor): (JSC::constructObject):
  • kjs/ObjectConstructor.h:
  • kjs/ObjectPrototype.cpp: (JSC::ObjectPrototype::ObjectPrototype):
  • kjs/ObjectPrototype.h:
  • kjs/PrototypeFunction.cpp: (JSC::PrototypeFunction::PrototypeFunction):
  • kjs/PrototypeFunction.h:
  • kjs/RegExpConstructor.cpp: (JSC::RegExpConstructor::RegExpConstructor): (JSC::RegExpMatchesArray::RegExpMatchesArray): (JSC::constructRegExp):
  • kjs/RegExpConstructor.h:
  • kjs/RegExpObject.cpp: (JSC::RegExpObject::RegExpObject):
  • kjs/RegExpObject.h:
  • kjs/RegExpPrototype.cpp: (JSC::RegExpPrototype::RegExpPrototype):
  • kjs/RegExpPrototype.h:
  • kjs/Shell.cpp: (GlobalObject::GlobalObject):
  • kjs/StringConstructor.cpp: (JSC::StringConstructor::StringConstructor): (JSC::constructWithStringConstructor):
  • kjs/StringConstructor.h:
  • kjs/StringObject.cpp: (JSC::StringObject::StringObject):
  • kjs/StringObject.h:
  • kjs/StringObjectThatMasqueradesAsUndefined.h: (JSC::StringObjectThatMasqueradesAsUndefined::StringObjectThatMasqueradesAsUndefined):
  • kjs/StringPrototype.cpp: (JSC::StringPrototype::StringPrototype):
  • kjs/StringPrototype.h: Take and pass structures.

WebCore:

2008-09-20 Darin Adler <Darin Adler>

Reviewed by Maciej Stachowiak.

  • bindings/js/JSCSSStyleDeclarationCustom.cpp: (WebCore::JSCSSStyleDeclaration::nameGetter): Pass in a structure ID. Note that this makes a new structure every time -- we could optimize this slightly be caching and reusing a single one.
  • bridge/runtime_method.cpp: (JSC::RuntimeMethod::RuntimeMethod): Create a unique structure using getDOMStructure.
  • bridge/runtime_method.h: (JSC::RuntimeMethod::createPrototype): Added createPrototype so getDOMStructure will work.
  • bindings/js/JSDOMWindowShell.cpp: (WebCore::JSDOMWindowShell::JSDOMWindowShell): Initialize m_window to 0; needed in case garbage collection happens while creating the JSDOMWindow.
  • 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, 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->parameters().size());
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 Vector<Identifier>& parameters = m_body->parameters();
135
136 if (static_cast<size_t>(index) >= m_body->parameters().size())
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 = parameters.size();
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.