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

Side by Side Diff: src/runtime/runtime-scopes.cc

Issue 1683103002: [compiler] Sanitize entry points to LookupSlot access. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix REBASE error. Created 4 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/runtime/runtime-utils.h" 5 #include "src/runtime/runtime-utils.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/arguments.h" 8 #include "src/arguments.h"
9 #include "src/ast/scopeinfo.h" 9 #include "src/ast/scopeinfo.h"
10 #include "src/ast/scopes.h" 10 #include "src/ast/scopes.h"
(...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 958
959 // The slot was found in a JSReceiver, either a context extension object, 959 // The slot was found in a JSReceiver, either a context extension object,
960 // the global object, or the subject of a with. Try to delete it 960 // the global object, or the subject of a with. Try to delete it
961 // (respecting DONT_DELETE). 961 // (respecting DONT_DELETE).
962 Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); 962 Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
963 Maybe<bool> result = JSReceiver::DeleteProperty(object, name); 963 Maybe<bool> result = JSReceiver::DeleteProperty(object, name);
964 MAYBE_RETURN(result, isolate->heap()->exception()); 964 MAYBE_RETURN(result, isolate->heap()->exception());
965 return isolate->heap()->ToBoolean(result.FromJust()); 965 return isolate->heap()->ToBoolean(result.FromJust());
966 } 966 }
967 967
968 namespace {
968 969
969 static Object* ComputeReceiverForNonGlobal(Isolate* isolate, JSObject* holder) { 970 MaybeHandle<Object> LoadLookupSlot(Handle<String> name,
970 DCHECK(!holder->IsJSGlobalObject()); 971 Object::ShouldThrow should_throw,
971 972 Handle<Object>* receiver_return = nullptr) {
972 // If the holder isn't a context extension object, we just return it 973 Isolate* const isolate = name->GetIsolate();
973 // as the receiver. This allows arguments objects to be used as
974 // receivers, but only if they are put in the context scope chain
975 // explicitly via a with-statement.
976 if (holder->map()->instance_type() != JS_CONTEXT_EXTENSION_OBJECT_TYPE) {
977 return holder;
978 }
979 // Fall back to using the global object as the implicit receiver if
980 // the property turns out to be a local variable allocated in a
981 // context extension object - introduced via eval.
982 return isolate->heap()->undefined_value();
983 }
984
985
986 static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate,
987 bool throw_error) {
988 HandleScope scope(isolate);
989 DCHECK_EQ(2, args.length());
990
991 if (!args[0]->IsContext() || !args[1]->IsString()) {
992 return MakePair(isolate->ThrowIllegalOperation(), NULL);
993 }
994 Handle<Context> context = args.at<Context>(0);
995 Handle<String> name = args.at<String>(1);
996 974
997 int index; 975 int index;
998 PropertyAttributes attributes; 976 PropertyAttributes attributes;
999 ContextLookupFlags flags = FOLLOW_CHAINS; 977 BindingFlags flags;
1000 BindingFlags binding_flags; 978 Handle<Object> holder = isolate->context()->Lookup(
1001 Handle<Object> holder = 979 name, FOLLOW_CHAINS, &index, &attributes, &flags);
1002 context->Lookup(name, flags, &index, &attributes, &binding_flags); 980 if (isolate->has_pending_exception()) return MaybeHandle<Object>();
1003 if (isolate->has_pending_exception()) {
1004 return MakePair(isolate->heap()->exception(), NULL);
1005 }
1006 981
1007 if (index != Context::kNotFound) { 982 if (index != Context::kNotFound) {
1008 DCHECK(holder->IsContext()); 983 DCHECK(holder->IsContext());
1009 // If the "property" we were looking for is a local variable, the 984 // If the "property" we were looking for is a local variable, the
1010 // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3. 985 // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
1011 Handle<Object> receiver = isolate->factory()->undefined_value(); 986 Handle<Object> receiver = isolate->factory()->undefined_value();
1012 Object* value = Context::cast(*holder)->get(index); 987 Handle<Object> value = handle(Context::cast(*holder)->get(index), isolate);
1013 // Check for uninitialized bindings. 988 // Check for uninitialized bindings.
1014 switch (binding_flags) { 989 switch (flags) {
1015 case MUTABLE_CHECK_INITIALIZED: 990 case MUTABLE_CHECK_INITIALIZED:
1016 case IMMUTABLE_CHECK_INITIALIZED_HARMONY: 991 case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
1017 if (value->IsTheHole()) { 992 if (value->IsTheHole()) {
1018 Handle<Object> error = isolate->factory()->NewReferenceError( 993 THROW_NEW_ERROR(isolate,
1019 MessageTemplate::kNotDefined, name); 994 NewReferenceError(MessageTemplate::kNotDefined, name),
1020 isolate->Throw(*error); 995 Object);
1021 return MakePair(isolate->heap()->exception(), NULL); 996 }
997 // FALLTHROUGH
998 case IMMUTABLE_CHECK_INITIALIZED:
999 if (value->IsTheHole()) {
1000 DCHECK(attributes & READ_ONLY);
1001 value = isolate->factory()->undefined_value();
1022 } 1002 }
1023 // FALLTHROUGH 1003 // FALLTHROUGH
1024 case MUTABLE_IS_INITIALIZED: 1004 case MUTABLE_IS_INITIALIZED:
1025 case IMMUTABLE_IS_INITIALIZED: 1005 case IMMUTABLE_IS_INITIALIZED:
1026 case IMMUTABLE_IS_INITIALIZED_HARMONY: 1006 case IMMUTABLE_IS_INITIALIZED_HARMONY:
1027 DCHECK(!value->IsTheHole()); 1007 DCHECK(!value->IsTheHole());
1028 return MakePair(value, *receiver); 1008 if (receiver_return) *receiver_return = receiver;
1029 case IMMUTABLE_CHECK_INITIALIZED: 1009 return value;
1030 if (value->IsTheHole()) {
1031 DCHECK((attributes & READ_ONLY) != 0);
1032 value = isolate->heap()->undefined_value();
1033 }
1034 return MakePair(value, *receiver);
1035 case MISSING_BINDING: 1010 case MISSING_BINDING:
1036 UNREACHABLE(); 1011 break;
1037 return MakePair(NULL, NULL);
1038 } 1012 }
1013 UNREACHABLE();
1039 } 1014 }
1040 1015
1041 // Otherwise, if the slot was found the holder is a context extension 1016 // Otherwise, if the slot was found the holder is a context extension
1042 // object, subject of a with, or a global object. We read the named 1017 // object, subject of a with, or a global object. We read the named
1043 // property from it. 1018 // property from it.
1044 if (!holder.is_null()) { 1019 if (!holder.is_null()) {
1045 Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
1046 // GetProperty below can cause GC.
1047 Handle<Object> receiver_handle(
1048 object->IsJSGlobalObject()
1049 ? Object::cast(isolate->heap()->undefined_value())
1050 : object->IsJSProxy() ? static_cast<Object*>(*object)
1051 : ComputeReceiverForNonGlobal(
1052 isolate, JSObject::cast(*object)),
1053 isolate);
1054
1055 // No need to unhole the value here. This is taken care of by the 1020 // No need to unhole the value here. This is taken care of by the
1056 // GetProperty function. 1021 // GetProperty function.
1057 Handle<Object> value; 1022 Handle<Object> value;
1058 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 1023 ASSIGN_RETURN_ON_EXCEPTION(
1059 isolate, value, Object::GetProperty(object, name), 1024 isolate, value, Object::GetProperty(holder, name),
1060 MakePair(isolate->heap()->exception(), NULL)); 1025 Object);
1061 return MakePair(*value, *receiver_handle); 1026 if (receiver_return) {
1027 *receiver_return =
1028 (holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject())
1029 ? Handle<Object>::cast(isolate->factory()->undefined_value())
1030 : holder;
1031 }
1032 return value;
1062 } 1033 }
1063 1034
1064 if (throw_error) { 1035 if (should_throw == Object::THROW_ON_ERROR) {
1065 // The property doesn't exist - throw exception. 1036 // The property doesn't exist - throw exception.
1066 Handle<Object> error = isolate->factory()->NewReferenceError( 1037 THROW_NEW_ERROR(
1067 MessageTemplate::kNotDefined, name); 1038 isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object);
1068 isolate->Throw(*error);
1069 return MakePair(isolate->heap()->exception(), NULL);
1070 } else {
1071 // The property doesn't exist - return undefined.
1072 return MakePair(isolate->heap()->undefined_value(),
1073 isolate->heap()->undefined_value());
1074 } 1039 }
1040
1041 // The property doesn't exist - return undefined.
1042 if (receiver_return) *receiver_return = isolate->factory()->undefined_value();
1043 return isolate->factory()->undefined_value();
1044 }
1045
1046 } // namespace
1047
1048
1049 RUNTIME_FUNCTION(Runtime_LoadLookupSlot) {
1050 HandleScope scope(isolate);
1051 DCHECK_EQ(1, args.length());
1052 CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
1053 Handle<Object> value;
1054 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1055 isolate, value, LoadLookupSlot(name, Object::THROW_ON_ERROR));
1056 return *value;
1075 } 1057 }
1076 1058
1077 1059
1078 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlot) { 1060 RUNTIME_FUNCTION(Runtime_LoadLookupSlotInsideTypeof) {
1079 return LoadLookupSlotHelper(args, isolate, true); 1061 HandleScope scope(isolate);
1062 DCHECK_EQ(1, args.length());
1063 CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
1064 Handle<Object> value;
1065 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1066 isolate, value, LoadLookupSlot(name, Object::DONT_THROW));
1067 return *value;
1080 } 1068 }
1081 1069
1082 1070
1083 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotNoReferenceError) { 1071 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotForCall) {
1084 return LoadLookupSlotHelper(args, isolate, false); 1072 HandleScope scope(isolate);
1073 DCHECK_EQ(1, args.length());
1074 DCHECK(args[0]->IsString());
1075 Handle<String> name = args.at<String>(0);
Michael Starzinger 2016/02/10 19:48:16 nit: Please use CONVERT_ARG_HANDLE_CHECKED(String,
Benedikt Meurer 2016/02/11 05:25:05 Not possible unfortunately until we change CONVERT
1076 Handle<Object> value;
1077 Handle<Object> receiver;
1078 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
1079 isolate, value, LoadLookupSlot(name, Object::THROW_ON_ERROR, &receiver),
1080 MakePair(isolate->heap()->exception(), nullptr));
1081 return MakePair(*value, *receiver);
1085 } 1082 }
1086 1083
1087 1084
1088 RUNTIME_FUNCTION(Runtime_StoreLookupSlot) { 1085 namespace {
1089 HandleScope scope(isolate);
1090 DCHECK(args.length() == 4);
1091 1086
1092 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); 1087 MaybeHandle<Object> StoreLookupSlot(Handle<String> name, Handle<Object> value,
1093 CONVERT_ARG_HANDLE_CHECKED(Context, context, 1); 1088 LanguageMode language_mode) {
1094 CONVERT_ARG_HANDLE_CHECKED(String, name, 2); 1089 Isolate* const isolate = name->GetIsolate();
1095 CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3); 1090 Handle<Context> context(isolate->context(), isolate);
1096 1091
1097 int index; 1092 int index;
1098 PropertyAttributes attributes; 1093 PropertyAttributes attributes;
1099 ContextLookupFlags flags = FOLLOW_CHAINS; 1094 BindingFlags flags;
1100 BindingFlags binding_flags;
1101 Handle<Object> holder = 1095 Handle<Object> holder =
1102 context->Lookup(name, flags, &index, &attributes, &binding_flags); 1096 context->Lookup(name, FOLLOW_CHAINS, &index, &attributes, &flags);
1103 if (holder.is_null()) { 1097 if (holder.is_null()) {
1104 // In case of JSProxy, an exception might have been thrown. 1098 // In case of JSProxy, an exception might have been thrown.
1105 if (isolate->has_pending_exception()) return isolate->heap()->exception(); 1099 if (isolate->has_pending_exception()) return MaybeHandle<Object>();
1106 } 1100 }
1107 1101
1108 // The property was found in a context slot. 1102 // The property was found in a context slot.
1109 if (index != Context::kNotFound) { 1103 if (index != Context::kNotFound) {
1110 if ((binding_flags == MUTABLE_CHECK_INITIALIZED || 1104 if ((flags == MUTABLE_CHECK_INITIALIZED ||
1111 binding_flags == IMMUTABLE_CHECK_INITIALIZED_HARMONY) && 1105 flags == IMMUTABLE_CHECK_INITIALIZED_HARMONY) &&
1112 Handle<Context>::cast(holder)->is_the_hole(index)) { 1106 Handle<Context>::cast(holder)->is_the_hole(index)) {
1113 THROW_NEW_ERROR_RETURN_FAILURE( 1107 THROW_NEW_ERROR(isolate,
1114 isolate, NewReferenceError(MessageTemplate::kNotDefined, name)); 1108 NewReferenceError(MessageTemplate::kNotDefined, name),
1109 Object);
1115 } 1110 }
1116 if ((attributes & READ_ONLY) == 0) { 1111 if ((attributes & READ_ONLY) == 0) {
1117 Handle<Context>::cast(holder)->set(index, *value); 1112 Handle<Context>::cast(holder)->set(index, *value);
1118 } else if (is_strict(language_mode)) { 1113 } else if (is_strict(language_mode)) {
1119 // Setting read only property in strict mode. 1114 // Setting read only property in strict mode.
1120 THROW_NEW_ERROR_RETURN_FAILURE( 1115 THROW_NEW_ERROR(isolate,
1121 isolate, NewTypeError(MessageTemplate::kStrictCannotAssign, name)); 1116 NewTypeError(MessageTemplate::kStrictCannotAssign, name),
1117 Object);
1122 } 1118 }
1123 return *value; 1119 return value;
1124 } 1120 }
1125 1121
1126 // Slow case: The property is not in a context slot. It is either in a 1122 // Slow case: The property is not in a context slot. It is either in a
1127 // context extension object, a property of the subject of a with, or a 1123 // context extension object, a property of the subject of a with, or a
1128 // property of the global object. 1124 // property of the global object.
1129 Handle<JSReceiver> object; 1125 Handle<JSReceiver> object;
1130 if (attributes != ABSENT) { 1126 if (attributes != ABSENT) {
1131 // The property exists on the holder. 1127 // The property exists on the holder.
1132 object = Handle<JSReceiver>::cast(holder); 1128 object = Handle<JSReceiver>::cast(holder);
1133 } else if (is_strict(language_mode)) { 1129 } else if (is_strict(language_mode)) {
1134 // If absent in strict mode: throw. 1130 // If absent in strict mode: throw.
1135 THROW_NEW_ERROR_RETURN_FAILURE( 1131 THROW_NEW_ERROR(
1136 isolate, NewReferenceError(MessageTemplate::kNotDefined, name)); 1132 isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object);
1137 } else { 1133 } else {
1138 // If absent in sloppy mode: add the property to the global object. 1134 // If absent in sloppy mode: add the property to the global object.
1139 object = Handle<JSReceiver>(context->global_object()); 1135 object = Handle<JSReceiver>(context->global_object());
1140 } 1136 }
1141 1137
1142 RETURN_FAILURE_ON_EXCEPTION( 1138 ASSIGN_RETURN_ON_EXCEPTION(
1143 isolate, Object::SetProperty(object, name, value, language_mode)); 1139 isolate, value, Object::SetProperty(object, name, value, language_mode),
1140 Object);
1141 return value;
1142 }
1144 1143
1144 } // namespace
1145
1146
1147 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Sloppy) {
1148 HandleScope scope(isolate);
1149 DCHECK_EQ(2, args.length());
1150 CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
1151 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
1152 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
1153 StoreLookupSlot(name, value, SLOPPY));
1145 return *value; 1154 return *value;
1146 } 1155 }
1147 1156
1157
1158 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) {
1159 HandleScope scope(isolate);
1160 DCHECK_EQ(2, args.length());
1161 CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
1162 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
1163 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
1164 StoreLookupSlot(name, value, STRICT));
1165 return *value;
1166 }
1167
1148 1168
1149 RUNTIME_FUNCTION(Runtime_ArgumentsLength) { 1169 RUNTIME_FUNCTION(Runtime_ArgumentsLength) {
1150 HandleScope scope(isolate); 1170 HandleScope scope(isolate);
1151 DCHECK(args.length() == 0); 1171 DCHECK(args.length() == 0);
1152 int argument_count = 0; 1172 int argument_count = 0;
1153 GetCallerArguments(isolate, &argument_count); 1173 GetCallerArguments(isolate, &argument_count);
1154 return Smi::FromInt(argument_count); 1174 return Smi::FromInt(argument_count);
1155 } 1175 }
1156 1176
1157 1177
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 1243
1224 // Lookup in the initial Object.prototype object. 1244 // Lookup in the initial Object.prototype object.
1225 Handle<Object> result; 1245 Handle<Object> result;
1226 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 1246 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1227 isolate, result, 1247 isolate, result,
1228 Object::GetProperty(isolate->initial_object_prototype(), key)); 1248 Object::GetProperty(isolate->initial_object_prototype(), key));
1229 return *result; 1249 return *result;
1230 } 1250 }
1231 } // namespace internal 1251 } // namespace internal
1232 } // namespace v8 1252 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698