~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3
3
 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4
 
 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
 
4
 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5
5
 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6
6
 *  Copyright (C) 2007 Maks Orlovich
7
7
 *
45
45
 
46
46
const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 };
47
47
 
48
 
JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* body, ScopeChainNode* scopeChainNode)
49
 
    : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), name)
50
 
    , m_body(body)
51
 
    , m_scopeChain(scopeChainNode)
52
 
{
 
48
bool JSFunction::isHostFunctionNonInline() const
 
49
{
 
50
    return isHostFunction();
 
51
}
 
52
 
 
53
JSFunction::JSFunction(NonNullPassRefPtr<Structure> structure)
 
54
    : Base(structure)
 
55
    , m_executable(adoptRef(new VPtrHackExecutable()))
 
56
{
 
57
}
 
58
 
 
59
JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
 
60
    : Base(&exec->globalData(), structure, name)
 
61
#if ENABLE(JIT)
 
62
    , m_executable(adoptRef(new NativeExecutable(exec)))
 
63
#endif
 
64
{
 
65
#if ENABLE(JIT)
 
66
    setNativeFunction(func);
 
67
    putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum);
 
68
#else
 
69
    UNUSED_PARAM(length);
 
70
    UNUSED_PARAM(func);
 
71
    ASSERT_NOT_REACHED();
 
72
#endif
 
73
}
 
74
 
 
75
JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<FunctionExecutable> executable, ScopeChainNode* scopeChainNode)
 
76
    : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), executable->name())
 
77
    , m_executable(executable)
 
78
{
 
79
    setScopeChain(scopeChainNode);
53
80
}
54
81
 
55
82
JSFunction::~JSFunction()
56
83
{
57
 
#if ENABLE(JIT) 
58
84
    // JIT code for other functions may have had calls linked directly to the code for this function; these links
59
85
    // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
60
86
    // this memory is freed and may be reused (potentially for another, different JSFunction).
61
 
    if (m_body && m_body->isGenerated())
62
 
        m_body->generatedBytecode().unlinkCallers();
 
87
    if (!isHostFunction()) {
 
88
#if ENABLE(JIT_OPTIMIZE_CALL)
 
89
        ASSERT(m_executable);
 
90
        if (jsExecutable()->isGenerated())
 
91
            jsExecutable()->generatedBytecode().unlinkCallers();
63
92
#endif
 
93
        scopeChain().~ScopeChain(); // FIXME: Don't we need to do this in the interpreter too?
 
94
    }
64
95
}
65
96
 
66
 
void JSFunction::mark()
 
97
void JSFunction::markChildren(MarkStack& markStack)
67
98
{
68
 
    Base::mark();
69
 
    m_body->mark();
70
 
    m_scopeChain.mark();
 
99
    Base::markChildren(markStack);
 
100
    if (!isHostFunction()) {
 
101
        jsExecutable()->markAggregate(markStack);
 
102
        scopeChain().markAggregate(markStack);
 
103
    }
71
104
}
72
105
 
73
106
CallType JSFunction::getCallData(CallData& callData)
74
107
{
75
 
    callData.js.functionBody = m_body.get();
76
 
    callData.js.scopeChain = m_scopeChain.node();
 
108
    if (isHostFunction()) {
 
109
        callData.native.function = nativeFunction();
 
110
        return CallTypeHost;
 
111
    }
 
112
    callData.js.functionExecutable = jsExecutable();
 
113
    callData.js.scopeChain = scopeChain().node();
77
114
    return CallTypeJS;
78
115
}
79
116
 
80
 
JSValuePtr JSFunction::call(ExecState* exec, JSValuePtr thisValue, const ArgList& args)
 
117
JSValue JSFunction::call(ExecState* exec, JSValue thisValue, const ArgList& args)
81
118
{
82
 
    return exec->interpreter()->execute(m_body.get(), exec, this, thisValue->toThisObject(exec), args, m_scopeChain.node(), exec->exceptionSlot());
 
119
    ASSERT(!isHostFunction());
 
120
    return exec->interpreter()->execute(jsExecutable(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot());
83
121
}
84
122
 
85
 
JSValuePtr JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 
123
JSValue JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
86
124
{
87
125
    JSFunction* thisObj = asFunction(slot.slotBase());
 
126
    ASSERT(!thisObj->isHostFunction());
88
127
    return exec->interpreter()->retrieveArguments(exec, thisObj);
89
128
}
90
129
 
91
 
JSValuePtr JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 
130
JSValue JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
92
131
{
93
132
    JSFunction* thisObj = asFunction(slot.slotBase());
 
133
    ASSERT(!thisObj->isHostFunction());
94
134
    return exec->interpreter()->retrieveCaller(exec, thisObj);
95
135
}
96
136
 
97
 
JSValuePtr JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 
137
JSValue JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
98
138
{
99
139
    JSFunction* thisObj = asFunction(slot.slotBase());
100
 
    return jsNumber(exec, thisObj->m_body->parameterCount());
 
140
    ASSERT(!thisObj->isHostFunction());
 
141
    return jsNumber(exec, thisObj->jsExecutable()->parameterCount());
101
142
}
102
143
 
103
144
bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
104
145
{
 
146
    if (isHostFunction())
 
147
        return Base::getOwnPropertySlot(exec, propertyName, slot);
 
148
 
105
149
    if (propertyName == exec->propertyNames().prototype) {
106
 
        JSValuePtr* location = getDirectLocation(propertyName);
 
150
        JSValue* location = getDirectLocation(propertyName);
107
151
 
108
152
        if (!location) {
109
 
            JSObject* prototype = new (exec) JSObject(m_scopeChain.globalObject()->emptyObjectStructure());
 
153
            JSObject* prototype = new (exec) JSObject(scopeChain().globalObject()->emptyObjectStructure());
110
154
            prototype->putDirect(exec->propertyNames().constructor, this, DontEnum);
111
155
            putDirect(exec->propertyNames().prototype, prototype, DontDelete);
112
156
            location = getDirectLocation(propertyName);
133
177
    return Base::getOwnPropertySlot(exec, propertyName, slot);
134
178
}
135
179
 
136
 
void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
 
180
    bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
 
181
    {
 
182
        if (isHostFunction())
 
183
            return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
 
184
        
 
185
        if (propertyName == exec->propertyNames().prototype) {
 
186
            PropertySlot slot;
 
187
            getOwnPropertySlot(exec, propertyName, slot);
 
188
            return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
 
189
        }
 
190
        
 
191
        if (propertyName == exec->propertyNames().arguments) {
 
192
            descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete);
 
193
            return true;
 
194
        }
 
195
        
 
196
        if (propertyName == exec->propertyNames().length) {
 
197
            descriptor.setDescriptor(jsNumber(exec, jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete);
 
198
            return true;
 
199
        }
 
200
        
 
201
        if (propertyName == exec->propertyNames().caller) {
 
202
            descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete);
 
203
            return true;
 
204
        }
 
205
        
 
206
        return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
 
207
    }
 
208
    
 
209
void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
137
210
{
 
211
    if (isHostFunction()) {
 
212
        Base::put(exec, propertyName, value, slot);
 
213
        return;
 
214
    }
138
215
    if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
139
216
        return;
140
217
    Base::put(exec, propertyName, value, slot);
142
219
 
143
220
bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
144
221
{
 
222
    if (isHostFunction())
 
223
        return Base::deleteProperty(exec, propertyName);
145
224
    if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
146
225
        return false;
147
226
    return Base::deleteProperty(exec, propertyName);
150
229
// ECMA 13.2.2 [[Construct]]
151
230
ConstructType JSFunction::getConstructData(ConstructData& constructData)
152
231
{
153
 
    constructData.js.functionBody = m_body.get();
154
 
    constructData.js.scopeChain = m_scopeChain.node();
 
232
    if (isHostFunction())
 
233
        return ConstructTypeNone;
 
234
    constructData.js.functionExecutable = jsExecutable();
 
235
    constructData.js.scopeChain = scopeChain().node();
155
236
    return ConstructTypeJS;
156
237
}
157
238
 
158
239
JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
159
240
{
 
241
    ASSERT(!isHostFunction());
160
242
    Structure* structure;
161
 
    JSValuePtr prototype = get(exec, exec->propertyNames().prototype);
162
 
    if (prototype->isObject())
 
243
    JSValue prototype = get(exec, exec->propertyNames().prototype);
 
244
    if (prototype.isObject())
163
245
        structure = asObject(prototype)->inheritorID();
164
246
    else
165
247
        structure = exec->lexicalGlobalObject()->emptyObjectStructure();
166
248
    JSObject* thisObj = new (exec) JSObject(structure);
167
249
 
168
 
    JSValuePtr result = exec->interpreter()->execute(m_body.get(), exec, this, thisObj, args, m_scopeChain.node(), exec->exceptionSlot());
169
 
    if (exec->hadException() || !result->isObject())
 
250
    JSValue result = exec->interpreter()->execute(jsExecutable(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot());
 
251
    if (exec->hadException() || !result.isObject())
170
252
        return thisObj;
171
253
    return asObject(result);
172
254
}