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