Chromium Code Reviews| 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 |