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

Side by Side Diff: src/runtime.cc

Issue 7039036: Fix calls of strict mode function with an implicit receiver. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address comments. Created 9 years, 7 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects-inl.h ('k') | src/stub-cache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. 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 7868 matching lines...) Expand 10 before | Expand all | Expand 10 after
7879 7879
7880 static inline MaybeObject* Unhole(Heap* heap, 7880 static inline MaybeObject* Unhole(Heap* heap,
7881 MaybeObject* x, 7881 MaybeObject* x,
7882 PropertyAttributes attributes) { 7882 PropertyAttributes attributes) {
7883 ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0); 7883 ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0);
7884 USE(attributes); 7884 USE(attributes);
7885 return x->IsTheHole() ? heap->undefined_value() : x; 7885 return x->IsTheHole() ? heap->undefined_value() : x;
7886 } 7886 }
7887 7887
7888 7888
7889 static JSObject* ComputeReceiverForNonGlobal(Isolate* isolate, 7889 static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
7890 JSObject* holder) { 7890 JSObject* holder) {
7891 ASSERT(!holder->IsGlobalObject()); 7891 ASSERT(!holder->IsGlobalObject());
7892 Context* top = isolate->context(); 7892 Context* top = isolate->context();
7893 // Get the context extension function. 7893 // Get the context extension function.
7894 JSFunction* context_extension_function = 7894 JSFunction* context_extension_function =
7895 top->global_context()->context_extension_function(); 7895 top->global_context()->context_extension_function();
7896 // If the holder isn't a context extension object, we just return it 7896 // If the holder isn't a context extension object, we just return it
7897 // as the receiver. This allows arguments objects to be used as 7897 // as the receiver. This allows arguments objects to be used as
7898 // receivers, but only if they are put in the context scope chain 7898 // receivers, but only if they are put in the context scope chain
7899 // explicitly via a with-statement. 7899 // explicitly via a with-statement.
7900 Object* constructor = holder->map()->constructor(); 7900 Object* constructor = holder->map()->constructor();
7901 if (constructor != context_extension_function) return holder; 7901 if (constructor != context_extension_function) return holder;
7902 // Fall back to using the global object as the receiver if the 7902 // Fall back to using the global object as the implicit receiver if
7903 // property turns out to be a local variable allocated in a context 7903 // the property turns out to be a local variable allocated in a
7904 // extension object - introduced via eval. 7904 // context extension object - introduced via eval. Implicit global
7905 return top->global()->global_receiver(); 7905 // receivers are indicated with the hole value.
7906 return isolate->heap()->the_hole_value();
7906 } 7907 }
7907 7908
7908 7909
7909 static ObjectPair LoadContextSlotHelper(Arguments args, 7910 static ObjectPair LoadContextSlotHelper(Arguments args,
7910 Isolate* isolate, 7911 Isolate* isolate,
7911 bool throw_error) { 7912 bool throw_error) {
7912 HandleScope scope(isolate); 7913 HandleScope scope(isolate);
7913 ASSERT_EQ(2, args.length()); 7914 ASSERT_EQ(2, args.length());
7914 7915
7915 if (!args[0]->IsContext() || !args[1]->IsString()) { 7916 if (!args[0]->IsContext() || !args[1]->IsString()) {
7916 return MakePair(isolate->ThrowIllegalOperation(), NULL); 7917 return MakePair(isolate->ThrowIllegalOperation(), NULL);
7917 } 7918 }
7918 Handle<Context> context = args.at<Context>(0); 7919 Handle<Context> context = args.at<Context>(0);
7919 Handle<String> name = args.at<String>(1); 7920 Handle<String> name = args.at<String>(1);
7920 7921
7921 int index; 7922 int index;
7922 PropertyAttributes attributes; 7923 PropertyAttributes attributes;
7923 ContextLookupFlags flags = FOLLOW_CHAINS; 7924 ContextLookupFlags flags = FOLLOW_CHAINS;
7924 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); 7925 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes);
7925 7926
7926 // If the index is non-negative, the slot has been found in a local 7927 // If the index is non-negative, the slot has been found in a local
7927 // variable or a parameter. Read it from the context object or the 7928 // variable or a parameter. Read it from the context object or the
7928 // arguments object. 7929 // arguments object.
7929 if (index >= 0) { 7930 if (index >= 0) {
7930 // If the "property" we were looking for is a local variable or an 7931 // If the "property" we were looking for is a local variable or an
7931 // argument in a context, the receiver is the global object; see 7932 // argument in a context, the receiver is the global object; see
7932 // ECMA-262, 3rd., 10.1.6 and 10.2.3. 7933 // ECMA-262, 3rd., 10.1.6 and 10.2.3.
7933 // GetElement below can cause GC. 7934 //
7934 Handle<JSObject> receiver( 7935 // Use the hole as the receiver to signal that the receiver is
7935 isolate->context()->global()->global_receiver()); 7936 // implicit and that the global receiver should be used.
7937 Handle<Object> receiver = isolate->factory()->the_hole_value();
7936 MaybeObject* value = (holder->IsContext()) 7938 MaybeObject* value = (holder->IsContext())
7937 ? Context::cast(*holder)->get(index) 7939 ? Context::cast(*holder)->get(index)
7938 : JSObject::cast(*holder)->GetElement(index); 7940 : JSObject::cast(*holder)->GetElement(index);
7939 return MakePair(Unhole(isolate->heap(), value, attributes), *receiver); 7941 return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
7940 } 7942 }
7941 7943
7942 // If the holder is found, we read the property from it. 7944 // If the holder is found, we read the property from it.
7943 if (!holder.is_null() && holder->IsJSObject()) { 7945 if (!holder.is_null() && holder->IsJSObject()) {
7944 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name)); 7946 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name));
7945 JSObject* object = JSObject::cast(*holder); 7947 JSObject* object = JSObject::cast(*holder);
7946 JSObject* receiver; 7948 Object* receiver;
7947 if (object->IsGlobalObject()) { 7949 if (object->IsGlobalObject()) {
7948 receiver = GlobalObject::cast(object)->global_receiver(); 7950 receiver = GlobalObject::cast(object)->global_receiver();
7949 } else if (context->is_exception_holder(*holder)) { 7951 } else if (context->is_exception_holder(*holder)) {
7950 receiver = isolate->context()->global()->global_receiver(); 7952 // Use the hole as the receiver to signal that the receiver is
7953 // implicit and that the global receiver should be used.
7954 receiver = isolate->heap()->the_hole_value();
7951 } else { 7955 } else {
7952 receiver = ComputeReceiverForNonGlobal(isolate, object); 7956 receiver = ComputeReceiverForNonGlobal(isolate, object);
7953 } 7957 }
7954 7958
7955 // GetProperty below can cause GC. 7959 // GetProperty below can cause GC.
7956 Handle<JSObject> receiver_handle(receiver); 7960 Handle<Object> receiver_handle(receiver);
7957 7961
7958 // No need to unhole the value here. This is taken care of by the 7962 // No need to unhole the value here. This is taken care of by the
7959 // GetProperty function. 7963 // GetProperty function.
7960 MaybeObject* value = object->GetProperty(*name); 7964 MaybeObject* value = object->GetProperty(*name);
7961 return MakePair(value, *receiver_handle); 7965 return MakePair(value, *receiver_handle);
7962 } 7966 }
7963 7967
7964 if (throw_error) { 7968 if (throw_error) {
7965 // The property doesn't exist - throw exception. 7969 // The property doesn't exist - throw exception.
7966 Handle<Object> reference_error = 7970 Handle<Object> reference_error =
7967 isolate->factory()->NewReferenceError("not_defined", 7971 isolate->factory()->NewReferenceError("not_defined",
7968 HandleVector(&name, 1)); 7972 HandleVector(&name, 1));
7969 return MakePair(isolate->Throw(*reference_error), NULL); 7973 return MakePair(isolate->Throw(*reference_error), NULL);
7970 } else { 7974 } else {
7971 // The property doesn't exist - return undefined 7975 // The property doesn't exist - return undefined.
7972 return MakePair(isolate->heap()->undefined_value(), 7976 return MakePair(isolate->heap()->undefined_value(),
7973 isolate->heap()->undefined_value()); 7977 isolate->heap()->undefined_value());
7974 } 7978 }
7975 } 7979 }
7976 7980
7977 7981
7978 RUNTIME_FUNCTION(ObjectPair, Runtime_LoadContextSlot) { 7982 RUNTIME_FUNCTION(ObjectPair, Runtime_LoadContextSlot) {
7979 return LoadContextSlotHelper(args, isolate, true); 7983 return LoadContextSlotHelper(args, isolate, true);
7980 } 7984 }
7981 7985
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
8473 Handle<Object> reference_error = 8477 Handle<Object> reference_error =
8474 isolate->factory()->NewReferenceError("not_defined", 8478 isolate->factory()->NewReferenceError("not_defined",
8475 HandleVector(&name, 1)); 8479 HandleVector(&name, 1));
8476 return MakePair(isolate->Throw(*reference_error), NULL); 8480 return MakePair(isolate->Throw(*reference_error), NULL);
8477 } 8481 }
8478 8482
8479 if (!context->IsGlobalContext()) { 8483 if (!context->IsGlobalContext()) {
8480 // 'eval' is not bound in the global context. Just call the function 8484 // 'eval' is not bound in the global context. Just call the function
8481 // with the given arguments. This is not necessarily the global eval. 8485 // with the given arguments. This is not necessarily the global eval.
8482 if (receiver->IsContext() || receiver->IsJSContextExtensionObject()) { 8486 if (receiver->IsContext() || receiver->IsJSContextExtensionObject()) {
8483 receiver = Handle<JSObject>( 8487 receiver = isolate->factory()->the_hole_value();
8484 isolate->context()->global()->global_receiver(), isolate);
8485 } 8488 }
8486 return MakePair(*callee, *receiver); 8489 return MakePair(*callee, *receiver);
8487 } 8490 }
8488 8491
8489 // 'eval' is bound in the global context, but it may have been overwritten. 8492 // 'eval' is bound in the global context, but it may have been overwritten.
8490 // Compare it to the builtin 'GlobalEval' function to make sure. 8493 // Compare it to the builtin 'GlobalEval' function to make sure.
8491 if (*callee != isolate->global_context()->global_eval_fun() || 8494 if (*callee != isolate->global_context()->global_eval_fun() ||
8492 !args[1]->IsString()) { 8495 !args[1]->IsString()) {
8493 return MakePair(*callee, 8496 return MakePair(*callee, isolate->heap()->the_hole_value());
8494 isolate->context()->global()->global_receiver());
8495 } 8497 }
8496 8498
8497 ASSERT(args[3]->IsSmi()); 8499 ASSERT(args[3]->IsSmi());
8498 return CompileGlobalEval(isolate, 8500 return CompileGlobalEval(isolate,
8499 args.at<String>(1), 8501 args.at<String>(1),
8500 args.at<Object>(2), 8502 args.at<Object>(2),
8501 static_cast<StrictModeFlag>( 8503 static_cast<StrictModeFlag>(
8502 Smi::cast(args[3])->value())); 8504 Smi::cast(args[3])->value()));
8503 } 8505 }
8504 8506
8505 8507
8506 RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) { 8508 RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) {
8507 ASSERT(args.length() == 4); 8509 ASSERT(args.length() == 4);
8508 8510
8509 HandleScope scope(isolate); 8511 HandleScope scope(isolate);
8510 Handle<Object> callee = args.at<Object>(0); 8512 Handle<Object> callee = args.at<Object>(0);
8511 8513
8512 // 'eval' is bound in the global context, but it may have been overwritten. 8514 // 'eval' is bound in the global context, but it may have been overwritten.
8513 // Compare it to the builtin 'GlobalEval' function to make sure. 8515 // Compare it to the builtin 'GlobalEval' function to make sure.
8514 if (*callee != isolate->global_context()->global_eval_fun() || 8516 if (*callee != isolate->global_context()->global_eval_fun() ||
8515 !args[1]->IsString()) { 8517 !args[1]->IsString()) {
8516 return MakePair(*callee, 8518 return MakePair(*callee, isolate->heap()->the_hole_value());
8517 isolate->context()->global()->global_receiver());
8518 } 8519 }
8519 8520
8520 ASSERT(args[3]->IsSmi()); 8521 ASSERT(args[3]->IsSmi());
8521 return CompileGlobalEval(isolate, 8522 return CompileGlobalEval(isolate,
8522 args.at<String>(1), 8523 args.at<String>(1),
8523 args.at<Object>(2), 8524 args.at<Object>(2),
8524 static_cast<StrictModeFlag>( 8525 static_cast<StrictModeFlag>(
8525 Smi::cast(args[3])->value())); 8526 Smi::cast(args[3])->value()));
8526 } 8527 }
8527 8528
(...skipping 3689 matching lines...) Expand 10 before | Expand all | Expand 10 after
12217 } else { 12218 } else {
12218 // Handle last resort GC and make sure to allow future allocations 12219 // Handle last resort GC and make sure to allow future allocations
12219 // to grow the heap without causing GCs (if possible). 12220 // to grow the heap without causing GCs (if possible).
12220 isolate->counters()->gc_last_resort_from_js()->Increment(); 12221 isolate->counters()->gc_last_resort_from_js()->Increment();
12221 isolate->heap()->CollectAllGarbage(false); 12222 isolate->heap()->CollectAllGarbage(false);
12222 } 12223 }
12223 } 12224 }
12224 12225
12225 12226
12226 } } // namespace v8::internal 12227 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects-inl.h ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698