Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Unified Diff: src/ic.cc

Issue 6523052: CallIC and KeyedCallIC not wrapping this. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix Handles Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ic.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index 968b45d0b61f4ac27c102cdc8dae927cc8c51ff2..81b659efa9f89ee01a38e9680b383f11f4944598 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -435,16 +435,25 @@ Object* CallICBase::TryCallAsFunction(Object* object) {
}
-void CallICBase::ReceiverToObject(Handle<Object> object) {
- HandleScope scope;
- Handle<Object> receiver(object);
+void CallICBase::ReceiverToObjectIfRequired(Handle<Object> callee,
+ Handle<Object> object) {
+ if (callee->IsJSFunction()) {
+ JSFunction* function = JSFunction::cast(*callee);
+ if (function->shared()->strict_mode() || function->IsBuiltin()) {
+ // Do not wrap receiver for strict mode functions or for builtins.
+ return;
+ }
+ }
- // Change the receiver to the result of calling ToObject on it.
- const int argc = this->target()->arguments_count();
- StackFrameLocator locator;
- JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
- int index = frame->ComputeExpressionsCount() - (argc + 1);
- frame->SetExpression(index, *Factory::ToObject(object));
+ // And only wrap string, number or boolean.
+ if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
Martin Maly 2011/02/18 00:55:38 I don't understand why the object was double-wrapp
Mads Ager (chromium) 2011/02/18 07:22:48 Yes, there is no reason to rewrap the incoming obj
+ // Change the receiver to the result of calling ToObject on it.
+ const int argc = this->target()->arguments_count();
+ StackFrameLocator locator;
+ JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
+ int index = frame->ComputeExpressionsCount() - (argc + 1);
+ frame->SetExpression(index, *Factory::ToObject(object));
+ }
}
@@ -458,10 +467,6 @@ MaybeObject* CallICBase::LoadFunction(State state,
return TypeError("non_object_property_call", object, name);
}
- if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
- ReceiverToObject(object);
- }
-
// Check if the name is trivially convertible to an index and get
// the element if so.
uint32_t index;
@@ -500,11 +505,20 @@ MaybeObject* CallICBase::LoadFunction(State state,
// Get the property.
PropertyAttributes attr;
- Object* result;
+ HandleScope scope;
+ Handle<Object> result;
Mads Ager (chromium) 2011/02/18 07:22:48 I would move the object_result out here (maybe cal
Martin Maly 2011/02/19 01:26:13 Done.
{ MaybeObject* maybe_result =
object->GetProperty(*object, &lookup, *name, &attr);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ Object* object_result;
+ if (!maybe_result->ToObject(&object_result)) return maybe_result;
+ result = Handle<Object>(object_result);
}
+
+ // Make receiver an object if the callee requires it. Strict mode or builtin
+ // functions do not wrap the receiver, non-strict functions and objects
+ // called as functions do.
+ ReceiverToObjectIfRequired(result, object);
+
if (lookup.type() == INTERCEPTOR) {
Mads Ager (chromium) 2011/02/18 07:22:48 It looks like you can move the wrapping below this
Martin Maly 2011/02/19 01:26:13 Done.
// If the object does not have the requested property, check which
// exception we need to throw.
@@ -516,7 +530,7 @@ MaybeObject* CallICBase::LoadFunction(State state,
}
}
- ASSERT(result != Heap::the_hole_value());
+ ASSERT(*result != Heap::the_hole_value());
Mads Ager (chromium) 2011/02/18 07:22:48 ASSERT(!result->IsTheHole());
Martin Maly 2011/02/19 01:26:13 Done.
if (result->IsJSFunction()) {
#ifdef ENABLE_DEBUGGER_SUPPORT
@@ -524,23 +538,20 @@ MaybeObject* CallICBase::LoadFunction(State state,
if (Debug::StepInActive()) {
// Protect the result in a handle as the debugger can allocate and might
// cause GC.
- HandleScope scope;
- Handle<JSFunction> function(JSFunction::cast(result));
+ Handle<JSFunction> function(JSFunction::cast(*result));
Martin Maly 2011/02/18 00:55:38 No HandleScope needed here, I believe ... the Hand
Mads Ager (chromium) 2011/02/18 07:22:48 Yes, that's fine.
Debug::HandleStepIn(function, object, fp(), false);
return *function;
}
#endif
- return result;
+ return *result;
}
// Try to find a suitable function delegate for the object at hand.
- result = TryCallAsFunction(result);
- MaybeObject* answer = result;
- if (!result->IsJSFunction()) {
- answer = TypeError("property_not_function", object, name);
- }
- return answer;
+ result = Handle<Object>(TryCallAsFunction(*result));
+ if (result->IsJSFunction()) return *result;
Martin Maly 2011/02/18 00:55:38 I am a bit hazy on using "return handle.EscapeFrom
Mads Ager (chromium) 2011/02/18 07:22:48 This method returns a MaybeObject which is a raw o
+
+ return TypeError("property_not_function", object, name);
}
@@ -565,8 +576,8 @@ bool CallICBase::TryUpdateExtraICState(LookupResult* lookup,
case kStringCharAt:
if (object->IsString()) {
String* string = String::cast(*object);
- // Check that there's the right wrapper in the receiver slot.
- ASSERT(string == JSValue::cast(args[0])->value());
+ // Check there's the right string value or wrapper in the receiver slot.
+ ASSERT(string == args[0] || string == JSValue::cast(args[0])->value());
// If we're in the default (fastest) state and the index is
// out of bounds, update the state to record this fact.
if (*extra_ic_state == DEFAULT_STRING_STUB &&
@@ -775,10 +786,6 @@ MaybeObject* KeyedCallIC::LoadFunction(State state,
return TypeError("non_object_property_call", object, key);
}
- if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
- ReceiverToObject(object);
- }
-
if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) {
int argc = target()->arguments_count();
InLoopFlag in_loop = target()->ic_in_loop();
@@ -793,17 +800,25 @@ MaybeObject* KeyedCallIC::LoadFunction(State state,
#endif
}
}
- Object* result;
+
+ HandleScope scope;
+ Handle<Object> result;
Mads Ager (chromium) 2011/02/18 07:22:48 This case can be rewritten to just use handles. Yo
Martin Maly 2011/02/19 01:26:13 Done.
{ MaybeObject* maybe_result = Runtime::GetObjectProperty(object, key);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ Object* object_result;
+ if (!maybe_result->ToObject(&object_result)) return maybe_result;
+ result = Handle<Object>(object_result);
Martin Maly 2011/02/18 00:55:38 Is there an established V8 pattern to export objec
}
- if (result->IsJSFunction()) return result;
- result = TryCallAsFunction(result);
- MaybeObject* answer = result;
- if (!result->IsJSFunction()) {
- answer = TypeError("property_not_function", object, key);
- }
- return answer;
+
+ // Make receiver an object if the callee requires it. Strict mode or builtin
+ // functions do not wrap the receiver, non-strict functions and objects
+ // called as functions do.
+ ReceiverToObjectIfRequired(result, object);
+
+ if (result->IsJSFunction()) return *result;
+ result = Handle<Object>(TryCallAsFunction(*result));
+ if (result->IsJSFunction()) return *result;
+
+ return TypeError("property_not_function", object, key);
Martin Maly 2011/02/18 00:55:38 This sequence seemed cleaner, get rid of "answer"
Mads Ager (chromium) 2011/02/18 07:22:48 Yes, thanks for cleaning that up! The original cod
}
« no previous file with comments | « src/ic.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698