| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 Handle<Object> result; | 1188 Handle<Object> result; |
| 1189 ASSIGN_RETURN_ON_EXCEPTION( | 1189 ASSIGN_RETURN_ON_EXCEPTION( |
| 1190 isolate(), | 1190 isolate(), |
| 1191 result, | 1191 result, |
| 1192 Runtime::GetObjectProperty(isolate(), object, key), | 1192 Runtime::GetObjectProperty(isolate(), object, key), |
| 1193 Object); | 1193 Object); |
| 1194 return result; | 1194 return result; |
| 1195 } | 1195 } |
| 1196 | 1196 |
| 1197 | 1197 |
| 1198 static bool LookupForWrite(Handle<JSObject> receiver, | 1198 static bool LookupForWrite(Handle<Object> object, Handle<String> name, |
| 1199 Handle<String> name, | 1199 Handle<Object> value, LookupResult* lookup, IC* ic) { |
| 1200 Handle<Object> value, | 1200 // Disable ICs for non-JSObjects for now. |
| 1201 LookupResult* lookup, | 1201 if (!object->IsJSObject()) return false; |
| 1202 IC* ic) { | 1202 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 1203 |
| 1203 Handle<JSObject> holder = receiver; | 1204 Handle<JSObject> holder = receiver; |
| 1204 receiver->Lookup(name, lookup); | 1205 receiver->Lookup(name, lookup); |
| 1205 if (lookup->IsFound()) { | 1206 if (lookup->IsFound()) { |
| 1206 if (lookup->IsInterceptor() && !HasInterceptorSetter(lookup->holder())) { | 1207 if (lookup->IsInterceptor() && !HasInterceptorSetter(lookup->holder())) { |
| 1207 receiver->LookupOwnRealNamedProperty(name, lookup); | 1208 receiver->LookupOwnRealNamedProperty(name, lookup); |
| 1208 if (!lookup->IsFound()) return false; | 1209 if (!lookup->IsFound()) return false; |
| 1209 } | 1210 } |
| 1210 | 1211 |
| 1211 if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false; | 1212 if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false; |
| 1212 if (lookup->holder() == *receiver) return lookup->CanHoldValue(value); | 1213 if (lookup->holder() == *receiver) return lookup->CanHoldValue(value); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 } | 1262 } |
| 1262 | 1263 |
| 1263 | 1264 |
| 1264 MaybeHandle<Object> StoreIC::Store(Handle<Object> object, | 1265 MaybeHandle<Object> StoreIC::Store(Handle<Object> object, |
| 1265 Handle<String> name, | 1266 Handle<String> name, |
| 1266 Handle<Object> value, | 1267 Handle<Object> value, |
| 1267 JSReceiver::StoreFromKeyed store_mode) { | 1268 JSReceiver::StoreFromKeyed store_mode) { |
| 1268 // TODO(verwaest): Let SetProperty do the migration, since storing a property | 1269 // TODO(verwaest): Let SetProperty do the migration, since storing a property |
| 1269 // might deprecate the current map again, if value does not fit. | 1270 // might deprecate the current map again, if value does not fit. |
| 1270 if (MigrateDeprecated(object) || object->IsJSProxy()) { | 1271 if (MigrateDeprecated(object) || object->IsJSProxy()) { |
| 1271 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object); | |
| 1272 Handle<Object> result; | 1272 Handle<Object> result; |
| 1273 ASSIGN_RETURN_ON_EXCEPTION( | 1273 ASSIGN_RETURN_ON_EXCEPTION( |
| 1274 isolate(), result, | 1274 isolate(), result, |
| 1275 JSReceiver::SetProperty(receiver, name, value, strict_mode()), Object); | 1275 Object::SetProperty(object, name, value, strict_mode()), Object); |
| 1276 return result; | 1276 return result; |
| 1277 } | 1277 } |
| 1278 | 1278 |
| 1279 // If the object is undefined or null it's illegal to try to set any | 1279 // If the object is undefined or null it's illegal to try to set any |
| 1280 // properties on it; throw a TypeError in that case. | 1280 // properties on it; throw a TypeError in that case. |
| 1281 if (object->IsUndefined() || object->IsNull()) { | 1281 if (object->IsUndefined() || object->IsNull()) { |
| 1282 return TypeError("non_object_property_store", object, name); | 1282 return TypeError("non_object_property_store", object, name); |
| 1283 } | 1283 } |
| 1284 | 1284 |
| 1285 // The length property of string values is read-only. Throw in strict mode. | |
| 1286 if (strict_mode() == STRICT && object->IsString() && | |
| 1287 String::Equals(isolate()->factory()->length_string(), name)) { | |
| 1288 return TypeError("strict_read_only_property", object, name); | |
| 1289 } | |
| 1290 | |
| 1291 // Ignore other stores where the receiver is not a JSObject. | |
| 1292 // TODO(1475): Must check prototype chains of object wrappers. | |
| 1293 if (!object->IsJSObject()) return value; | |
| 1294 | |
| 1295 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | |
| 1296 | |
| 1297 // Check if the given name is an array index. | 1285 // Check if the given name is an array index. |
| 1298 uint32_t index; | 1286 uint32_t index; |
| 1299 if (name->AsArrayIndex(&index)) { | 1287 if (name->AsArrayIndex(&index)) { |
| 1288 // Ignore other stores where the receiver is not a JSObject. |
| 1289 // TODO(1475): Must check prototype chains of object wrappers. |
| 1290 if (!object->IsJSObject()) return value; |
| 1291 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 1292 |
| 1300 Handle<Object> result; | 1293 Handle<Object> result; |
| 1301 ASSIGN_RETURN_ON_EXCEPTION( | 1294 ASSIGN_RETURN_ON_EXCEPTION( |
| 1302 isolate(), | 1295 isolate(), |
| 1303 result, | 1296 result, |
| 1304 JSObject::SetElement(receiver, index, value, NONE, strict_mode()), | 1297 JSObject::SetElement(receiver, index, value, NONE, strict_mode()), |
| 1305 Object); | 1298 Object); |
| 1306 return value; | 1299 return value; |
| 1307 } | 1300 } |
| 1308 | 1301 |
| 1309 // Observed objects are always modified through the runtime. | 1302 // Observed objects are always modified through the runtime. |
| 1310 if (receiver->map()->is_observed()) { | 1303 if (object->IsHeapObject() && |
| 1304 Handle<HeapObject>::cast(object)->map()->is_observed()) { |
| 1311 Handle<Object> result; | 1305 Handle<Object> result; |
| 1312 ASSIGN_RETURN_ON_EXCEPTION( | 1306 ASSIGN_RETURN_ON_EXCEPTION( |
| 1313 isolate(), result, JSReceiver::SetProperty(receiver, name, value, | 1307 isolate(), result, |
| 1314 strict_mode(), store_mode), | 1308 Object::SetProperty(object, name, value, strict_mode(), store_mode), |
| 1315 Object); | 1309 Object); |
| 1316 return result; | 1310 return result; |
| 1317 } | 1311 } |
| 1318 | 1312 |
| 1319 LookupResult lookup(isolate()); | 1313 LookupResult lookup(isolate()); |
| 1320 bool can_store = LookupForWrite(receiver, name, value, &lookup, this); | 1314 bool can_store = LookupForWrite(object, name, value, &lookup, this); |
| 1321 if (!can_store && | 1315 if (!can_store && |
| 1322 strict_mode() == STRICT && | 1316 strict_mode() == STRICT && |
| 1323 !(lookup.IsProperty() && lookup.IsReadOnly()) && | 1317 !(lookup.IsProperty() && lookup.IsReadOnly()) && |
| 1324 object->IsGlobalObject()) { | 1318 object->IsGlobalObject()) { |
| 1325 // Strict mode doesn't allow setting non-existent global property. | 1319 // Strict mode doesn't allow setting non-existent global property. |
| 1326 return ReferenceError("not_defined", name); | 1320 return ReferenceError("not_defined", name); |
| 1327 } | 1321 } |
| 1328 if (FLAG_use_ic) { | 1322 if (FLAG_use_ic) { |
| 1329 if (state() == UNINITIALIZED) { | 1323 if (state() == UNINITIALIZED) { |
| 1330 Handle<Code> stub = pre_monomorphic_stub(); | 1324 Handle<Code> stub = pre_monomorphic_stub(); |
| 1331 set_target(*stub); | 1325 set_target(*stub); |
| 1332 TRACE_IC("StoreIC", name); | 1326 TRACE_IC("StoreIC", name); |
| 1333 } else if (can_store) { | 1327 } else if (can_store) { |
| 1334 UpdateCaches(&lookup, receiver, name, value); | 1328 UpdateCaches(&lookup, Handle<JSObject>::cast(object), name, value); |
| 1335 } else if (lookup.IsNormal() || | 1329 } else if (lookup.IsNormal() || |
| 1336 (lookup.IsField() && lookup.CanHoldValue(value))) { | 1330 (lookup.IsField() && lookup.CanHoldValue(value))) { |
| 1337 Handle<Code> stub = generic_stub(); | 1331 Handle<Code> stub = generic_stub(); |
| 1338 set_target(*stub); | 1332 set_target(*stub); |
| 1339 } | 1333 } |
| 1340 } | 1334 } |
| 1341 | 1335 |
| 1342 // Set the property. | 1336 // Set the property. |
| 1343 Handle<Object> result; | 1337 Handle<Object> result; |
| 1344 ASSIGN_RETURN_ON_EXCEPTION( | 1338 ASSIGN_RETURN_ON_EXCEPTION( |
| 1345 isolate(), result, | 1339 isolate(), result, |
| 1346 JSReceiver::SetProperty(receiver, name, value, strict_mode(), store_mode), | 1340 Object::SetProperty(object, name, value, strict_mode(), store_mode), |
| 1347 Object); | 1341 Object); |
| 1348 return result; | 1342 return result; |
| 1349 } | 1343 } |
| 1350 | 1344 |
| 1351 | 1345 |
| 1352 OStream& operator<<(OStream& os, const CallIC::State& s) { | 1346 OStream& operator<<(OStream& os, const CallIC::State& s) { |
| 1353 return os << "(args(" << s.arg_count() << "), " | 1347 return os << "(args(" << s.arg_count() << "), " |
| 1354 << (s.call_type() == CallIC::METHOD ? "METHOD" : "FUNCTION") | 1348 << (s.call_type() == CallIC::METHOD ? "METHOD" : "FUNCTION") |
| 1355 << ", "; | 1349 << ", "; |
| 1356 } | 1350 } |
| (...skipping 1705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3062 #undef ADDR | 3056 #undef ADDR |
| 3063 }; | 3057 }; |
| 3064 | 3058 |
| 3065 | 3059 |
| 3066 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3060 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 3067 return IC_utilities[id]; | 3061 return IC_utilities[id]; |
| 3068 } | 3062 } |
| 3069 | 3063 |
| 3070 | 3064 |
| 3071 } } // namespace v8::internal | 3065 } } // namespace v8::internal |
| OLD | NEW |