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

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

Issue 1178503004: Replace SetObjectProperty / DefineObjectProperty with less powerful alternatives where relevant. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 5 years, 6 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
« no previous file with comments | « src/runtime/runtime-debug.cc ('k') | src/scopeinfo.cc » ('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 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/debug.h" 9 #include "src/debug.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 Handle<Object> key, 85 Handle<Object> key,
86 Handle<Object> value, 86 Handle<Object> value,
87 LanguageMode language_mode) { 87 LanguageMode language_mode) {
88 if (object->IsUndefined() || object->IsNull()) { 88 if (object->IsUndefined() || object->IsNull()) {
89 THROW_NEW_ERROR( 89 THROW_NEW_ERROR(
90 isolate, 90 isolate,
91 NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object), 91 NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object),
92 Object); 92 Object);
93 } 93 }
94 94
95 if (object->IsJSProxy()) {
96 Handle<Object> name_object;
97 if (key->IsSymbol()) {
98 name_object = key;
99 } else {
100 ASSIGN_RETURN_ON_EXCEPTION(isolate, name_object,
101 Execution::ToString(isolate, key), Object);
102 }
103 Handle<Name> name = Handle<Name>::cast(name_object);
104 return Object::SetProperty(Handle<JSProxy>::cast(object), name, value,
105 language_mode);
106 }
107
108 // Check if the given key is an array index. 95 // Check if the given key is an array index.
109 uint32_t index = 0; 96 uint32_t index = 0;
110 if (key->ToArrayIndex(&index)) { 97 if (key->ToArrayIndex(&index)) {
111 // TODO(verwaest): Support non-JSObject receivers. 98 // TODO(verwaest): Support other objects as well.
112 if (!object->IsJSObject()) return value; 99 if (!object->IsJSReceiver()) return value;
113 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 100 return JSReceiver::SetElement(Handle<JSReceiver>::cast(object), index,
114 101 value, language_mode);
115 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
116 // of a string using [] notation. We need to support this too in
117 // JavaScript.
118 // In the case of a String object we just need to redirect the assignment to
119 // the underlying string if the index is in range. Since the underlying
120 // string does nothing with the assignment then we can ignore such
121 // assignments.
122 if (js_object->IsStringObjectWithCharacterAt(index)) {
123 return value;
124 }
125
126 JSObject::ValidateElements(js_object);
127 if (js_object->HasExternalArrayElements() ||
128 js_object->HasFixedTypedArrayElements()) {
129 if (!value->IsNumber() && !value->IsUndefined()) {
130 ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
131 Execution::ToNumber(isolate, value), Object);
132 }
133 }
134
135 MaybeHandle<Object> result =
136 JSObject::SetElement(js_object, index, value, language_mode);
137 JSObject::ValidateElements(js_object);
138
139 return result.is_null() ? result : value;
140 }
141
142 if (key->IsName()) {
143 Handle<Name> name = Handle<Name>::cast(key);
144 if (name->AsArrayIndex(&index)) {
145 // TODO(verwaest): Support non-JSObject receivers.
146 if (!object->IsJSObject()) return value;
147 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
148 if (js_object->HasExternalArrayElements()) {
149 if (!value->IsNumber() && !value->IsUndefined()) {
150 ASSIGN_RETURN_ON_EXCEPTION(
151 isolate, value, Execution::ToNumber(isolate, value), Object);
152 }
153 }
154 return JSObject::SetElement(js_object, index, value, language_mode);
155 } else {
156 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
157 return Object::SetProperty(object, name, value, language_mode);
158 }
159 }
160
161 // Call-back into JavaScript to convert the key to a string.
162 Handle<Object> converted;
163 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
164 Execution::ToString(isolate, key), Object);
165 Handle<String> name = Handle<String>::cast(converted);
166
167 if (name->AsArrayIndex(&index)) {
168 // TODO(verwaest): Support non-JSObject receivers.
169 if (!object->IsJSObject()) return value;
170 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
171 return JSObject::SetElement(js_object, index, value, language_mode);
172 }
173 return Object::SetProperty(object, name, value, language_mode);
174 }
175
176
177 MaybeHandle<Object> Runtime::DefineObjectProperty(Handle<JSObject> js_object,
178 Handle<Object> key,
179 Handle<Object> value,
180 PropertyAttributes attrs) {
181 Isolate* isolate = js_object->GetIsolate();
182 // Check if the given key is an array index.
183 uint32_t index = 0;
184 if (key->ToArrayIndex(&index)) {
185 return JSObject::SetOwnElementIgnoreAttributes(js_object, index, value,
186 attrs);
187 } 102 }
188 103
189 Handle<Name> name; 104 Handle<Name> name;
190 if (key->IsName()) { 105 if (key->IsName()) {
191 name = Handle<Name>::cast(key); 106 name = Handle<Name>::cast(key);
192 } else { 107 } else {
193 // Call-back into JavaScript to convert the key to a string. 108 // Call-back into JavaScript to convert the key to a string.
194 Handle<Object> converted; 109 Handle<Object> converted;
195 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted, 110 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
196 Execution::ToString(isolate, key), Object); 111 Execution::ToString(isolate, key), Object);
197 name = Handle<String>::cast(converted); 112 name = Handle<String>::cast(converted);
198 } 113 }
199 114
200 if (name->AsArrayIndex(&index)) { 115 if (name->AsArrayIndex(&index)) {
201 return JSObject::SetOwnElementIgnoreAttributes(js_object, index, value, 116 // TODO(verwaest): Support other objects as well.
202 attrs); 117 if (!object->IsJSReceiver()) return value;
203 } else { 118 return JSReceiver::SetElement(Handle<JSReceiver>::cast(object), index,
204 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); 119 value, language_mode);
205 return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
206 attrs);
207 } 120 }
121 return Object::SetProperty(object, name, value, language_mode);
208 } 122 }
209 123
210 124
211 MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate, 125 MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate,
212 Handle<Object> obj) { 126 Handle<Object> obj) {
213 // We don't expect access checks to be needed on JSProxy objects. 127 // We don't expect access checks to be needed on JSProxy objects.
214 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); 128 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
215 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); 129 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
216 do { 130 do {
217 if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() && 131 if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 1262
1349 // Implements part of 8.12.9 DefineOwnProperty. 1263 // Implements part of 8.12.9 DefineOwnProperty.
1350 // There are 3 cases that lead here: 1264 // There are 3 cases that lead here:
1351 // Step 4a - define a new data property. 1265 // Step 4a - define a new data property.
1352 // Steps 9b & 12 - replace an existing accessor property with a data property. 1266 // Steps 9b & 12 - replace an existing accessor property with a data property.
1353 // Step 12 - update an existing data property with a data or generic 1267 // Step 12 - update an existing data property with a data or generic
1354 // descriptor. 1268 // descriptor.
1355 RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) { 1269 RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
1356 HandleScope scope(isolate); 1270 HandleScope scope(isolate);
1357 DCHECK(args.length() == 4); 1271 DCHECK(args.length() == 4);
1358 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); 1272 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
1359 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); 1273 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1360 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); 1274 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1361 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); 1275 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
1362 1276
1363 LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); 1277 uint32_t index = 0;
1364 if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) { 1278 LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
1365 if (!isolate->MayAccess(js_object)) { 1279 LookupIterator it = name->AsArrayIndex(&index)
1366 return isolate->heap()->undefined_value(); 1280 ? LookupIterator(isolate, object, index, c)
1367 } 1281 : LookupIterator(object, name, c);
1368 it.Next(); 1282 if (it.state() == LookupIterator::ACCESS_CHECK && !it.HasAccess()) {
1283 return isolate->heap()->undefined_value();
1369 } 1284 }
1370 1285
1371 Handle<Object> result; 1286 Handle<Object> result;
1372 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 1287 MaybeHandle<Object> maybe_result =
1373 isolate, result, 1288 it.IsElement()
1374 Runtime::DefineObjectProperty(js_object, name, obj_value, attrs)); 1289 ? JSObject::SetOwnElementIgnoreAttributes(object, index, value, attrs)
1290 : JSObject::SetOwnPropertyIgnoreAttributes(object, name, value,
1291 attrs);
1292 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
1375 return *result; 1293 return *result;
1376 } 1294 }
1377 1295
1378 1296
1379 // Return property without being observable by accessors or interceptors. 1297 // Return property without being observable by accessors or interceptors.
1380 RUNTIME_FUNCTION(Runtime_GetDataProperty) { 1298 RUNTIME_FUNCTION(Runtime_GetDataProperty) {
1381 HandleScope scope(isolate); 1299 HandleScope scope(isolate);
1382 DCHECK(args.length() == 2); 1300 DCHECK(args.length() == 2);
1383 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); 1301 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
1384 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); 1302 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1385 return *JSReceiver::GetDataProperty(object, key); 1303 return *JSReceiver::GetDataProperty(object, name);
1386 } 1304 }
1387 1305
1388 1306
1389 RUNTIME_FUNCTION(Runtime_HasFastPackedElements) { 1307 RUNTIME_FUNCTION(Runtime_HasFastPackedElements) {
1390 SealHandleScope shs(isolate); 1308 SealHandleScope shs(isolate);
1391 DCHECK(args.length() == 1); 1309 DCHECK(args.length() == 1);
1392 CONVERT_ARG_CHECKED(HeapObject, obj, 0); 1310 CONVERT_ARG_CHECKED(HeapObject, obj, 0);
1393 return isolate->heap()->ToBoolean( 1311 return isolate->heap()->ToBoolean(
1394 IsFastPackedElementsKind(obj->map()->elements_kind())); 1312 IsFastPackedElementsKind(obj->map()->elements_kind()));
1395 } 1313 }
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); 1440 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
1523 1441
1524 RETURN_FAILURE_ON_EXCEPTION( 1442 RETURN_FAILURE_ON_EXCEPTION(
1525 isolate, 1443 isolate,
1526 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(), 1444 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
1527 setter, attrs)); 1445 setter, attrs));
1528 return isolate->heap()->undefined_value(); 1446 return isolate->heap()->undefined_value();
1529 } 1447 }
1530 } // namespace internal 1448 } // namespace internal
1531 } // namespace v8 1449 } // namespace v8
OLDNEW
« no previous file with comments | « src/runtime/runtime-debug.cc ('k') | src/scopeinfo.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698