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

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

Issue 1181733002: Revert of Replace SetObjectProperty / DefineObjectProperty with less powerful alternatives where relevant. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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
95 // Check if the given key is an array index. 108 // Check if the given key is an array index.
96 uint32_t index = 0; 109 uint32_t index = 0;
97 if (key->ToArrayIndex(&index)) { 110 if (key->ToArrayIndex(&index)) {
98 // TODO(verwaest): Support other objects as well. 111 // TODO(verwaest): Support non-JSObject receivers.
99 if (!object->IsJSReceiver()) return value; 112 if (!object->IsJSObject()) return value;
100 return JSReceiver::SetElement(Handle<JSReceiver>::cast(object), index, 113 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
101 value, language_mode); 114
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);
102 } 187 }
103 188
104 Handle<Name> name; 189 Handle<Name> name;
105 if (key->IsName()) { 190 if (key->IsName()) {
106 name = Handle<Name>::cast(key); 191 name = Handle<Name>::cast(key);
107 } else { 192 } else {
108 // Call-back into JavaScript to convert the key to a string. 193 // Call-back into JavaScript to convert the key to a string.
109 Handle<Object> converted; 194 Handle<Object> converted;
110 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted, 195 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
111 Execution::ToString(isolate, key), Object); 196 Execution::ToString(isolate, key), Object);
112 name = Handle<String>::cast(converted); 197 name = Handle<String>::cast(converted);
113 } 198 }
114 199
115 if (name->AsArrayIndex(&index)) { 200 if (name->AsArrayIndex(&index)) {
116 // TODO(verwaest): Support other objects as well. 201 return JSObject::SetOwnElementIgnoreAttributes(js_object, index, value,
117 if (!object->IsJSReceiver()) return value; 202 attrs);
118 return JSReceiver::SetElement(Handle<JSReceiver>::cast(object), index, 203 } else {
119 value, language_mode); 204 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
205 return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
206 attrs);
120 } 207 }
121 return Object::SetProperty(object, name, value, language_mode);
122 } 208 }
123 209
124 210
125 MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate, 211 MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate,
126 Handle<Object> obj) { 212 Handle<Object> obj) {
127 // We don't expect access checks to be needed on JSProxy objects. 213 // We don't expect access checks to be needed on JSProxy objects.
128 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); 214 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
129 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); 215 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
130 do { 216 do {
131 if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() && 217 if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 1348
1263 // Implements part of 8.12.9 DefineOwnProperty. 1349 // Implements part of 8.12.9 DefineOwnProperty.
1264 // There are 3 cases that lead here: 1350 // There are 3 cases that lead here:
1265 // Step 4a - define a new data property. 1351 // Step 4a - define a new data property.
1266 // Steps 9b & 12 - replace an existing accessor property with a data property. 1352 // Steps 9b & 12 - replace an existing accessor property with a data property.
1267 // Step 12 - update an existing data property with a data or generic 1353 // Step 12 - update an existing data property with a data or generic
1268 // descriptor. 1354 // descriptor.
1269 RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) { 1355 RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
1270 HandleScope scope(isolate); 1356 HandleScope scope(isolate);
1271 DCHECK(args.length() == 4); 1357 DCHECK(args.length() == 4);
1272 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 1358 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
1273 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); 1359 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1274 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); 1360 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
1275 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); 1361 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
1276 1362
1277 uint32_t index = 0; 1363 LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
1278 LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR; 1364 if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) {
1279 LookupIterator it = name->AsArrayIndex(&index) 1365 if (!isolate->MayAccess(js_object)) {
1280 ? LookupIterator(isolate, object, index, c) 1366 return isolate->heap()->undefined_value();
1281 : LookupIterator(object, name, c); 1367 }
1282 if (it.state() == LookupIterator::ACCESS_CHECK && !it.HasAccess()) { 1368 it.Next();
1283 return isolate->heap()->undefined_value();
1284 } 1369 }
1285 1370
1286 Handle<Object> result; 1371 Handle<Object> result;
1287 MaybeHandle<Object> maybe_result = 1372 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1288 it.IsElement() 1373 isolate, result,
1289 ? JSObject::SetOwnElementIgnoreAttributes(object, index, value, attrs) 1374 Runtime::DefineObjectProperty(js_object, name, obj_value, attrs));
1290 : JSObject::SetOwnPropertyIgnoreAttributes(object, name, value,
1291 attrs);
1292 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
1293 return *result; 1375 return *result;
1294 } 1376 }
1295 1377
1296 1378
1297 // Return property without being observable by accessors or interceptors. 1379 // Return property without being observable by accessors or interceptors.
1298 RUNTIME_FUNCTION(Runtime_GetDataProperty) { 1380 RUNTIME_FUNCTION(Runtime_GetDataProperty) {
1299 HandleScope scope(isolate); 1381 HandleScope scope(isolate);
1300 DCHECK(args.length() == 2); 1382 DCHECK(args.length() == 2);
1301 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); 1383 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
1302 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); 1384 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
1303 return *JSReceiver::GetDataProperty(object, name); 1385 return *JSReceiver::GetDataProperty(object, key);
1304 } 1386 }
1305 1387
1306 1388
1307 RUNTIME_FUNCTION(Runtime_HasFastPackedElements) { 1389 RUNTIME_FUNCTION(Runtime_HasFastPackedElements) {
1308 SealHandleScope shs(isolate); 1390 SealHandleScope shs(isolate);
1309 DCHECK(args.length() == 1); 1391 DCHECK(args.length() == 1);
1310 CONVERT_ARG_CHECKED(HeapObject, obj, 0); 1392 CONVERT_ARG_CHECKED(HeapObject, obj, 0);
1311 return isolate->heap()->ToBoolean( 1393 return isolate->heap()->ToBoolean(
1312 IsFastPackedElementsKind(obj->map()->elements_kind())); 1394 IsFastPackedElementsKind(obj->map()->elements_kind()));
1313 } 1395 }
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1440 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); 1522 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
1441 1523
1442 RETURN_FAILURE_ON_EXCEPTION( 1524 RETURN_FAILURE_ON_EXCEPTION(
1443 isolate, 1525 isolate,
1444 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(), 1526 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
1445 setter, attrs)); 1527 setter, attrs));
1446 return isolate->heap()->undefined_value(); 1528 return isolate->heap()->undefined_value();
1447 } 1529 }
1448 } // namespace internal 1530 } // namespace internal
1449 } // namespace v8 1531 } // 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