OLD | NEW |
---|---|
1 // Copyright 2006-2008 Google Inc. All Rights Reserved. | 1 // Copyright 2006-2008 Google Inc. All Rights Reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
243 SetTargetAtAddress(address, initialize_stub()); | 243 SetTargetAtAddress(address, initialize_stub()); |
244 } | 244 } |
245 | 245 |
246 | 246 |
247 void KeyedStoreIC::Clear(Address address, Code* target) { | 247 void KeyedStoreIC::Clear(Address address, Code* target) { |
248 if (target->ic_state() == UNINITIALIZED) return; | 248 if (target->ic_state() == UNINITIALIZED) return; |
249 SetTargetAtAddress(address, initialize_stub()); | 249 SetTargetAtAddress(address, initialize_stub()); |
250 } | 250 } |
251 | 251 |
252 | 252 |
253 Object* CallIC::TryCallAsFunction(Object* object) { | |
254 HandleScope scope; | |
255 Handle<Object> target(object); | |
256 Handle<Object> delegate = Execution::GetFunctionDelegate(target); | |
257 | |
258 if (delegate->IsJSFunction()) { | |
259 // Patch the receiver and use the delegate as the function to | |
260 // invoke. This is used for invoking objects as if they were | |
261 // functions. | |
262 const int argc = this->target()->arguments_count(); | |
263 StackFrameLocator locator; | |
264 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | |
265 int index = frame->ComputeExpressionsCount() - (argc + 1); | |
266 frame->SetExpression(index, *target); | |
267 } | |
268 | |
269 return *delegate; | |
270 } | |
271 | |
272 | |
253 Object* CallIC::LoadFunction(State state, | 273 Object* CallIC::LoadFunction(State state, |
254 Handle<Object> object, | 274 Handle<Object> object, |
255 Handle<String> name) { | 275 Handle<String> name) { |
256 // If the object is undefined or null it's illegal to try to get any | 276 // If the object is undefined or null it's illegal to try to get any |
257 // of its properties; throw a TypeError in that case. | 277 // of its properties; throw a TypeError in that case. |
258 if (object->IsUndefined() || object->IsNull()) { | 278 if (object->IsUndefined() || object->IsNull()) { |
259 return TypeError("non_object_property_call", object, name); | 279 return TypeError("non_object_property_call", object, name); |
260 } | 280 } |
261 | 281 |
282 Object* result = Heap::the_hole_value(); | |
283 | |
284 // Check if the name is trivially convertible to an index and get | |
285 // the element if so. | |
286 uint32_t index; | |
287 if (name->AsArrayIndex(&index)) { | |
288 result = object->GetElement(index); | |
289 if (result->IsJSFunction()) return result; | |
290 | |
291 // Try to find a suitable function delegate for the object at hand. | |
292 result = TryCallAsFunction(result); | |
293 if (result->IsJSFunction()) return result; | |
Kasper Lund
2008/09/08 05:27:21
Do you really want to continue with a doing a norm
Feng Qian
2008/09/08 18:58:48
It will fail in lookup step, a comment is sufficie
| |
294 } | |
295 | |
262 // Lookup the property in the object. | 296 // Lookup the property in the object. |
263 LookupResult lookup; | 297 LookupResult lookup; |
264 object->Lookup(*name, &lookup); | 298 object->Lookup(*name, &lookup); |
265 | 299 |
266 Object* result = Heap::the_hole_value(); | |
267 | |
268 if (!lookup.IsValid()) { | 300 if (!lookup.IsValid()) { |
269 // If the object does not have the requested property, check which | 301 // If the object does not have the requested property, check which |
270 // exception we need to throw. | 302 // exception we need to throw. |
271 if (is_contextual()) { | 303 if (is_contextual()) { |
272 return ReferenceError("not_defined", name); | 304 return ReferenceError("not_defined", name); |
273 } | 305 } |
274 return TypeError("undefined_method", object, name); | 306 return TypeError("undefined_method", object, name); |
275 } | 307 } |
276 | 308 |
277 // Lookup is valid: Update inline cache and stub cache. | 309 // Lookup is valid: Update inline cache and stub cache. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
321 Top::context()->builtins()) { | 353 Top::context()->builtins()) { |
322 HandleScope scope; | 354 HandleScope scope; |
323 Handle<SharedFunctionInfo> shared(JSFunction::cast(result)->shared()); | 355 Handle<SharedFunctionInfo> shared(JSFunction::cast(result)->shared()); |
324 Debug::FloodWithOneShot(shared); | 356 Debug::FloodWithOneShot(shared); |
325 } | 357 } |
326 } | 358 } |
327 return result; | 359 return result; |
328 } | 360 } |
329 | 361 |
330 // Try to find a suitable function delegate for the object at hand. | 362 // Try to find a suitable function delegate for the object at hand. |
331 HandleScope scope; | 363 result = TryCallAsFunction(result); |
332 Handle<Object> target(result); | 364 return result->IsJSFunction() ? |
333 Handle<Object> delegate = Execution::GetFunctionDelegate(target); | 365 result : TypeError("property_not_function", object, name); |
Kasper Lund
2008/09/08 05:27:21
Isn't this usually indented with 4 spaces? I can't
Feng Qian
2008/09/08 18:58:48
Done.
| |
334 | |
335 if (delegate->IsJSFunction()) { | |
336 // Patch the receiver and use the delegate as the function to | |
337 // invoke. This is used for invoking objects as if they were | |
338 // functions. | |
339 const int argc = this->target()->arguments_count(); | |
340 StackFrameLocator locator; | |
341 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | |
342 int index = frame->ComputeExpressionsCount() - (argc + 1); | |
343 frame->SetExpression(index, *target); | |
344 return *delegate; | |
345 } else { | |
346 return TypeError("property_not_function", object, name); | |
347 } | |
348 } | 366 } |
349 | 367 |
350 | 368 |
351 void CallIC::UpdateCaches(LookupResult* lookup, | 369 void CallIC::UpdateCaches(LookupResult* lookup, |
352 State state, | 370 State state, |
353 Handle<Object> object, | 371 Handle<Object> object, |
354 Handle<String> name) { | 372 Handle<String> name) { |
355 ASSERT(lookup->IsLoaded()); | 373 ASSERT(lookup->IsLoaded()); |
356 // Bail out if we didn't find a result. | 374 // Bail out if we didn't find a result. |
357 if (!lookup->IsValid() || !lookup->IsCacheable()) return; | 375 if (!lookup->IsValid() || !lookup->IsCacheable()) return; |
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1130 #undef ADDR | 1148 #undef ADDR |
1131 }; | 1149 }; |
1132 | 1150 |
1133 | 1151 |
1134 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 1152 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
1135 return IC_utilities[id]; | 1153 return IC_utilities[id]; |
1136 } | 1154 } |
1137 | 1155 |
1138 | 1156 |
1139 } } // namespace v8::internal | 1157 } } // namespace v8::internal |
OLD | NEW |