Handlify JSReceiver::SetProperty and friends.
R=verwaest@chromium.org Review URL: https://codereview.chromium.org/23601031 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16758 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
f89996a1ca
commit
16a22a96c3
20
src/ic.cc
20
src/ic.cc
@ -1670,8 +1670,10 @@ MaybeObject* StoreIC::Store(State state,
|
||||
JSReceiver::StoreFromKeyed store_mode) {
|
||||
// Handle proxies.
|
||||
if (object->IsJSProxy()) {
|
||||
return JSReceiver::SetPropertyOrFail(
|
||||
Handle<Object> result = JSReceiver::SetProperty(
|
||||
Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode);
|
||||
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
||||
return *result;
|
||||
}
|
||||
|
||||
// If the object is undefined or null it's illegal to try to set any
|
||||
@ -1709,8 +1711,10 @@ MaybeObject* StoreIC::Store(State state,
|
||||
|
||||
// Observed objects are always modified through the runtime.
|
||||
if (FLAG_harmony_observation && receiver->map()->is_observed()) {
|
||||
return JSReceiver::SetPropertyOrFail(
|
||||
Handle<Object> result = JSReceiver::SetProperty(
|
||||
receiver, name, value, NONE, strict_mode, store_mode);
|
||||
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
||||
return *result;
|
||||
}
|
||||
|
||||
// Use specialized code for setting the length of arrays with fast
|
||||
@ -1727,8 +1731,10 @@ MaybeObject* StoreIC::Store(State state,
|
||||
StoreArrayLengthStub(kind(), strict_mode).GetCode(isolate());
|
||||
set_target(*stub);
|
||||
TRACE_IC("StoreIC", name, state, *stub);
|
||||
return JSReceiver::SetPropertyOrFail(
|
||||
Handle<Object> result = JSReceiver::SetProperty(
|
||||
receiver, name, value, NONE, strict_mode, store_mode);
|
||||
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
||||
return *result;
|
||||
}
|
||||
|
||||
if (receiver->IsJSGlobalProxy()) {
|
||||
@ -1741,8 +1747,10 @@ MaybeObject* StoreIC::Store(State state,
|
||||
set_target(*stub);
|
||||
TRACE_IC("StoreIC", name, state, *stub);
|
||||
}
|
||||
return JSReceiver::SetPropertyOrFail(
|
||||
Handle<Object> result = JSReceiver::SetProperty(
|
||||
receiver, name, value, NONE, strict_mode, store_mode);
|
||||
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
||||
return *result;
|
||||
}
|
||||
|
||||
LookupResult lookup(isolate());
|
||||
@ -1773,8 +1781,10 @@ MaybeObject* StoreIC::Store(State state,
|
||||
}
|
||||
|
||||
// Set the property.
|
||||
return JSReceiver::SetPropertyOrFail(
|
||||
Handle<Object> result = JSReceiver::SetProperty(
|
||||
receiver, name, value, NONE, strict_mode, store_mode);
|
||||
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1566,21 +1566,6 @@ MaybeObject* JSObject::AllocateStorageForMap(Map* map) {
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* JSObject::MigrateInstance() {
|
||||
// Converting any field to the most specific type will cause the
|
||||
// GeneralizeFieldRepresentation algorithm to create the most general existing
|
||||
// transition that matches the object. This achieves what is needed.
|
||||
Map* original_map = map();
|
||||
MaybeObject* maybe_result = GeneralizeFieldRepresentation(
|
||||
0, Representation::None(), ALLOW_AS_CONSTANT);
|
||||
JSObject* result;
|
||||
if (FLAG_trace_migration && maybe_result->To(&result)) {
|
||||
PrintInstanceMigration(stdout, original_map, result->map());
|
||||
}
|
||||
return maybe_result;
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* JSObject::TryMigrateInstance() {
|
||||
Map* new_map = map()->CurrentMapForDeprecated();
|
||||
if (new_map == NULL) return Smi::FromInt(0);
|
||||
|
1010
src/objects.cc
1010
src/objects.cc
File diff suppressed because it is too large
Load Diff
242
src/objects.h
242
src/objects.h
@ -1950,42 +1950,24 @@ class JSReceiver: public HeapObject {
|
||||
// Casting.
|
||||
static inline JSReceiver* cast(Object* obj);
|
||||
|
||||
// Implementation of [[Put]], see ECMA-262 5th edition, section 8.12.5.
|
||||
static Handle<Object> SetProperty(Handle<JSReceiver> object,
|
||||
Handle<Name> key,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode);
|
||||
StrictModeFlag strict_mode,
|
||||
StoreFromKeyed store_mode =
|
||||
MAY_BE_STORE_FROM_KEYED);
|
||||
static Handle<Object> SetElement(Handle<JSReceiver> object,
|
||||
uint32_t index,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode);
|
||||
|
||||
MUST_USE_RESULT static MaybeObject* SetPropertyOrFail(
|
||||
Handle<JSReceiver> object,
|
||||
Handle<Name> key,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode,
|
||||
StoreFromKeyed store_from_keyed = MAY_BE_STORE_FROM_KEYED);
|
||||
|
||||
// Can cause GC.
|
||||
MUST_USE_RESULT MaybeObject* SetProperty(
|
||||
Name* key,
|
||||
Object* value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode,
|
||||
StoreFromKeyed store_from_keyed = MAY_BE_STORE_FROM_KEYED);
|
||||
MUST_USE_RESULT MaybeObject* SetProperty(
|
||||
LookupResult* result,
|
||||
Name* key,
|
||||
Object* value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode,
|
||||
StoreFromKeyed store_from_keyed = MAY_BE_STORE_FROM_KEYED);
|
||||
MUST_USE_RESULT MaybeObject* SetPropertyWithDefinedSetter(JSReceiver* setter,
|
||||
Object* value);
|
||||
|
||||
// Implementation of [[Delete]], see ECMA-262 5th edition, section 8.12.7.
|
||||
static Handle<Object> DeleteProperty(Handle<JSReceiver> object,
|
||||
Handle<Name> name,
|
||||
DeleteMode mode = NORMAL_DELETION);
|
||||
@ -2042,6 +2024,14 @@ class JSReceiver: public HeapObject {
|
||||
Name* name,
|
||||
bool continue_search);
|
||||
|
||||
static Handle<Object> SetProperty(Handle<JSReceiver> receiver,
|
||||
LookupResult* result,
|
||||
Handle<Name> key,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode,
|
||||
StoreFromKeyed store_from_keyed);
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
|
||||
};
|
||||
|
||||
@ -2135,13 +2125,6 @@ class JSObject: public JSReceiver {
|
||||
Object* structure,
|
||||
Name* name);
|
||||
|
||||
// Can cause GC.
|
||||
MUST_USE_RESULT MaybeObject* SetPropertyForResult(LookupResult* result,
|
||||
Name* key,
|
||||
Object* value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode,
|
||||
StoreFromKeyed store_mode);
|
||||
MUST_USE_RESULT MaybeObject* SetPropertyWithFailedAccessCheck(
|
||||
LookupResult* result,
|
||||
Name* name,
|
||||
@ -2154,17 +2137,21 @@ class JSObject: public JSReceiver {
|
||||
Object* value,
|
||||
JSObject* holder,
|
||||
StrictModeFlag strict_mode);
|
||||
MUST_USE_RESULT MaybeObject* SetPropertyWithInterceptor(
|
||||
Name* name,
|
||||
Object* value,
|
||||
static Handle<Object> SetPropertyWithInterceptor(
|
||||
Handle<JSObject> object,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode);
|
||||
MUST_USE_RESULT MaybeObject* SetPropertyPostInterceptor(
|
||||
Name* name,
|
||||
Object* value,
|
||||
|
||||
static Handle<Object> SetPropertyForResult(
|
||||
Handle<JSObject> object,
|
||||
LookupResult* result,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode,
|
||||
StoreMode mode = ALLOW_AS_CONSTANT);
|
||||
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
|
||||
|
||||
static Handle<Object> SetLocalPropertyIgnoreAttributes(
|
||||
Handle<JSObject> object,
|
||||
@ -2191,7 +2178,6 @@ class JSObject: public JSReceiver {
|
||||
inline MUST_USE_RESULT MaybeObject* AllocateStorageForMap(Map* map);
|
||||
|
||||
static void MigrateInstance(Handle<JSObject> instance);
|
||||
inline MUST_USE_RESULT MaybeObject* MigrateInstance();
|
||||
|
||||
static Handle<Object> TryMigrateInstance(Handle<JSObject> instance);
|
||||
inline MUST_USE_RESULT MaybeObject* TryMigrateInstance();
|
||||
@ -2483,32 +2469,6 @@ class JSObject: public JSReceiver {
|
||||
// Returns the number of enumerable elements.
|
||||
int GetEnumElementKeys(FixedArray* storage);
|
||||
|
||||
// Add a property to a fast-case object using a map transition to
|
||||
// new_map.
|
||||
MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(
|
||||
Map* new_map,
|
||||
Name* name,
|
||||
Object* value,
|
||||
int field_index,
|
||||
Representation representation);
|
||||
|
||||
// Add a constant function property to a fast-case object.
|
||||
// This leaves a CONSTANT_TRANSITION in the old map, and
|
||||
// if it is called on a second object with this map, a
|
||||
// normal property is added instead, with a map transition.
|
||||
// This avoids the creation of many maps with the same constant
|
||||
// function, all orphaned.
|
||||
MUST_USE_RESULT MaybeObject* AddConstantProperty(
|
||||
Name* name,
|
||||
Object* constant,
|
||||
PropertyAttributes attributes,
|
||||
TransitionFlag flag);
|
||||
|
||||
MUST_USE_RESULT MaybeObject* ReplaceSlowProperty(
|
||||
Name* name,
|
||||
Object* value,
|
||||
PropertyAttributes attributes);
|
||||
|
||||
// Returns a new map with all transitions dropped from the object's current
|
||||
// map and the ElementsKind set.
|
||||
static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
|
||||
@ -2525,37 +2485,12 @@ class JSObject: public JSReceiver {
|
||||
MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind);
|
||||
MUST_USE_RESULT MaybeObject* UpdateAllocationSite(ElementsKind to_kind);
|
||||
|
||||
static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map);
|
||||
MUST_USE_RESULT MaybeObject* MigrateToMap(Map* new_map);
|
||||
MUST_USE_RESULT MaybeObject* GeneralizeFieldRepresentation(
|
||||
int modify_index,
|
||||
Representation new_representation,
|
||||
StoreMode store_mode);
|
||||
|
||||
// Add a property to a fast-case object.
|
||||
MUST_USE_RESULT MaybeObject* AddFastProperty(
|
||||
Name* name,
|
||||
Object* value,
|
||||
PropertyAttributes attributes,
|
||||
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
|
||||
ValueType value_type = OPTIMAL_REPRESENTATION,
|
||||
TransitionFlag flag = INSERT_TRANSITION);
|
||||
|
||||
// Add a property to a slow-case object.
|
||||
MUST_USE_RESULT MaybeObject* AddSlowProperty(Name* name,
|
||||
Object* value,
|
||||
PropertyAttributes attributes);
|
||||
|
||||
// Add a property to an object. May cause GC.
|
||||
MUST_USE_RESULT MaybeObject* AddProperty(
|
||||
Name* name,
|
||||
Object* value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode,
|
||||
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
|
||||
ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
|
||||
ValueType value_type = OPTIMAL_REPRESENTATION,
|
||||
StoreMode mode = ALLOW_AS_CONSTANT,
|
||||
TransitionFlag flag = INSERT_TRANSITION);
|
||||
static void GeneralizeFieldRepresentation(Handle<JSObject> object,
|
||||
int modify_index,
|
||||
Representation new_representation,
|
||||
StoreMode store_mode);
|
||||
|
||||
// Convert the object to use the canonical dictionary
|
||||
// representation. If the object is expected to have additional properties
|
||||
@ -2735,15 +2670,6 @@ class JSObject: public JSReceiver {
|
||||
friend class DictionaryElementsAccessor;
|
||||
friend class JSReceiver;
|
||||
|
||||
// TODO(mstarzinger): Soon to be handlified.
|
||||
MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
|
||||
Name* key,
|
||||
Object* value,
|
||||
PropertyAttributes attributes,
|
||||
ValueType value_type = OPTIMAL_REPRESENTATION,
|
||||
StoreMode mode = ALLOW_AS_CONSTANT,
|
||||
ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK);
|
||||
|
||||
MUST_USE_RESULT MaybeObject* GetElementWithCallback(Object* receiver,
|
||||
Object* structure,
|
||||
uint32_t index,
|
||||
@ -2780,13 +2706,81 @@ class JSObject: public JSReceiver {
|
||||
// Searches the prototype chain for property 'name'. If it is found and
|
||||
// has a setter, invoke it and set '*done' to true. If it is found and is
|
||||
// read-only, reject and set '*done' to true. Otherwise, set '*done' to
|
||||
// false. Can cause GC and can return a failure result with '*done==true'.
|
||||
MUST_USE_RESULT MaybeObject* SetPropertyViaPrototypes(
|
||||
Name* name,
|
||||
Object* value,
|
||||
// false. Can throw and return an empty handle with '*done==true'.
|
||||
static Handle<Object> SetPropertyViaPrototypes(
|
||||
Handle<JSObject> object,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode,
|
||||
bool* done);
|
||||
static Handle<Object> SetPropertyPostInterceptor(
|
||||
Handle<JSObject> object,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode);
|
||||
static Handle<Object> SetPropertyUsingTransition(
|
||||
Handle<JSObject> object,
|
||||
LookupResult* lookup,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes);
|
||||
|
||||
// Add a property to an object.
|
||||
static Handle<Object> AddProperty(
|
||||
Handle<JSObject> object,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode,
|
||||
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
|
||||
ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
|
||||
ValueType value_type = OPTIMAL_REPRESENTATION,
|
||||
StoreMode mode = ALLOW_AS_CONSTANT,
|
||||
TransitionFlag flag = INSERT_TRANSITION);
|
||||
|
||||
// Add a constant function property to a fast-case object.
|
||||
// This leaves a CONSTANT_TRANSITION in the old map, and
|
||||
// if it is called on a second object with this map, a
|
||||
// normal property is added instead, with a map transition.
|
||||
// This avoids the creation of many maps with the same constant
|
||||
// function, all orphaned.
|
||||
static void AddConstantProperty(Handle<JSObject> object,
|
||||
Handle<Name> name,
|
||||
Handle<Object> constant,
|
||||
PropertyAttributes attributes,
|
||||
TransitionFlag flag);
|
||||
|
||||
// Add a property to a fast-case object.
|
||||
static void AddFastProperty(Handle<JSObject> object,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes,
|
||||
StoreFromKeyed store_mode,
|
||||
ValueType value_type,
|
||||
TransitionFlag flag);
|
||||
|
||||
// Add a property to a fast-case object using a map transition to
|
||||
// new_map.
|
||||
static Handle<Object> AddFastPropertyUsingMap(Handle<JSObject> object,
|
||||
Handle<Map> new_map,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
int field_index,
|
||||
Representation representation);
|
||||
MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(
|
||||
Map* new_map,
|
||||
Name* name,
|
||||
Object* value,
|
||||
int field_index,
|
||||
Representation representation);
|
||||
|
||||
// Add a property to a slow-case object.
|
||||
static void AddSlowProperty(Handle<JSObject> object,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes);
|
||||
|
||||
static Handle<Object> DeleteProperty(Handle<JSObject> object,
|
||||
Handle<Name> name,
|
||||
@ -3176,6 +3170,13 @@ class DescriptorArray: public FixedArray {
|
||||
DescriptorArray* src,
|
||||
int src_index,
|
||||
const WhitenessWitness&);
|
||||
static Handle<DescriptorArray> Merge(Handle<DescriptorArray> desc,
|
||||
int verbatim,
|
||||
int valid,
|
||||
int new_size,
|
||||
int modify_index,
|
||||
StoreMode store_mode,
|
||||
Handle<DescriptorArray> other);
|
||||
MUST_USE_RESULT MaybeObject* Merge(int verbatim,
|
||||
int valid,
|
||||
int new_size,
|
||||
@ -5618,11 +5619,8 @@ class Map: public HeapObject {
|
||||
int modify_index,
|
||||
Representation new_representation,
|
||||
StoreMode store_mode);
|
||||
MUST_USE_RESULT MaybeObject* GeneralizeRepresentation(
|
||||
int modify_index,
|
||||
Representation representation,
|
||||
StoreMode store_mode);
|
||||
MUST_USE_RESULT MaybeObject* CopyGeneralizeAllRepresentations(
|
||||
static Handle<Map> CopyGeneralizeAllRepresentations(
|
||||
Handle<Map> map,
|
||||
int modify_index,
|
||||
StoreMode store_mode,
|
||||
PropertyAttributes attributes,
|
||||
@ -5802,6 +5800,10 @@ class Map: public HeapObject {
|
||||
TransitionFlag flag,
|
||||
Name* name = NULL,
|
||||
SimpleTransitionFlag simple_flag = FULL_TRANSITION);
|
||||
static Handle<Map> CopyInstallDescriptors(
|
||||
Handle<Map> map,
|
||||
int new_descriptor,
|
||||
Handle<DescriptorArray> descriptors);
|
||||
MUST_USE_RESULT MaybeObject* CopyInstallDescriptors(
|
||||
int new_descriptor,
|
||||
DescriptorArray* descriptors);
|
||||
@ -9020,6 +9022,9 @@ class PropertyCell: public Cell {
|
||||
// of the cell's current type and the value's type. If the change causes
|
||||
// a change of the type of the cell's contents, code dependent on the cell
|
||||
// will be deoptimized.
|
||||
static void SetValueInferType(Handle<PropertyCell> cell,
|
||||
Handle<Object> value,
|
||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
MUST_USE_RESULT MaybeObject* SetValueInferType(
|
||||
Object* value,
|
||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
@ -9082,13 +9087,6 @@ class JSProxy: public JSReceiver {
|
||||
Object* receiver,
|
||||
uint32_t index);
|
||||
|
||||
MUST_USE_RESULT MaybeObject* SetPropertyWithHandler(
|
||||
JSReceiver* receiver,
|
||||
Name* name,
|
||||
Object* value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode);
|
||||
|
||||
// If the handler defines an accessor property with a setter, invoke it.
|
||||
// If it defines an accessor property without a setter, or a data property
|
||||
// that is read-only, throw. In all these cases set '*done' to true,
|
||||
@ -9144,6 +9142,12 @@ class JSProxy: public JSReceiver {
|
||||
private:
|
||||
friend class JSReceiver;
|
||||
|
||||
static Handle<Object> SetPropertyWithHandler(Handle<JSProxy> proxy,
|
||||
Handle<JSReceiver> receiver,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode);
|
||||
static Handle<Object> SetElementWithHandler(Handle<JSProxy> proxy,
|
||||
Handle<JSReceiver> receiver,
|
||||
uint32_t index,
|
||||
|
@ -2201,7 +2201,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
|
||||
SealHandleScope shs(isolate);
|
||||
HandleScope scope(isolate);
|
||||
// args[0] == name
|
||||
// args[1] == language_mode
|
||||
// args[2] == value (optional)
|
||||
@ -2212,7 +2212,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
|
||||
bool assign = args.length() == 3;
|
||||
|
||||
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
|
||||
GlobalObject* global = isolate->context()->global_object();
|
||||
RUNTIME_ASSERT(args[1]->IsSmi());
|
||||
CONVERT_LANGUAGE_MODE_ARG(language_mode, 1);
|
||||
StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE)
|
||||
@ -2229,28 +2228,33 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
|
||||
// to assign to the property.
|
||||
// Note that objects can have hidden prototypes, so we need to traverse
|
||||
// the whole chain of hidden prototypes to do a 'local' lookup.
|
||||
Object* object = global;
|
||||
LookupResult lookup(isolate);
|
||||
JSObject::cast(object)->LocalLookup(*name, &lookup, true);
|
||||
isolate->context()->global_object()->LocalLookup(*name, &lookup, true);
|
||||
if (lookup.IsInterceptor()) {
|
||||
HandleScope handle_scope(isolate);
|
||||
PropertyAttributes intercepted =
|
||||
lookup.holder()->GetPropertyAttribute(*name);
|
||||
if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
|
||||
// Found an interceptor that's not read only.
|
||||
if (assign) {
|
||||
return lookup.holder()->SetProperty(
|
||||
&lookup, *name, args[2], attributes, strict_mode_flag);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
|
||||
Handle<Object> result = JSObject::SetPropertyForResult(
|
||||
handle(lookup.holder()), &lookup, name, value, attributes,
|
||||
strict_mode_flag);
|
||||
RETURN_IF_EMPTY_HANDLE(isolate, result);
|
||||
return *result;
|
||||
} else {
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reload global in case the loop above performed a GC.
|
||||
global = isolate->context()->global_object();
|
||||
if (assign) {
|
||||
return global->SetProperty(*name, args[2], attributes, strict_mode_flag);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
|
||||
Handle<GlobalObject> global(isolate->context()->global_object());
|
||||
Handle<Object> result = JSReceiver::SetProperty(
|
||||
global, name, value, attributes, strict_mode_flag);
|
||||
RETURN_IF_EMPTY_HANDLE(isolate, result);
|
||||
return *result;
|
||||
}
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
@ -5133,11 +5137,14 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
|
||||
|
||||
if (object->IsJSProxy()) {
|
||||
bool has_pending_exception = false;
|
||||
Handle<Object> name = key->IsSymbol()
|
||||
Handle<Object> name_object = key->IsSymbol()
|
||||
? key : Execution::ToString(isolate, key, &has_pending_exception);
|
||||
if (has_pending_exception) return Failure::Exception();
|
||||
return JSProxy::cast(*object)->SetProperty(
|
||||
Name::cast(*name), *value, attr, strict_mode);
|
||||
Handle<Name> name = Handle<Name>::cast(name_object);
|
||||
Handle<Object> result = JSReceiver::SetProperty(
|
||||
Handle<JSProxy>::cast(object), name, value, attr, strict_mode);
|
||||
RETURN_IF_EMPTY_HANDLE(isolate, result);
|
||||
return *result;
|
||||
}
|
||||
|
||||
// If the object isn't a JavaScript object, we ignore the store.
|
||||
@ -5177,7 +5184,6 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
|
||||
}
|
||||
|
||||
if (key->IsName()) {
|
||||
MaybeObject* result;
|
||||
Handle<Name> name = Handle<Name>::cast(key);
|
||||
if (name->AsArrayIndex(&index)) {
|
||||
if (js_object->HasExternalArrayElements()) {
|
||||
@ -5189,13 +5195,15 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
|
||||
value = number;
|
||||
}
|
||||
}
|
||||
result = js_object->SetElement(
|
||||
MaybeObject* result = js_object->SetElement(
|
||||
index, *value, attr, strict_mode, true, set_mode);
|
||||
if (result->IsFailure()) return result;
|
||||
} else {
|
||||
if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
|
||||
result = js_object->SetProperty(*name, *value, attr, strict_mode);
|
||||
Handle<Object> result =
|
||||
JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
|
||||
RETURN_IF_EMPTY_HANDLE(isolate, result);
|
||||
}
|
||||
if (result->IsFailure()) return result;
|
||||
return *value;
|
||||
}
|
||||
|
||||
@ -5210,7 +5218,10 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
|
||||
return js_object->SetElement(
|
||||
index, *value, attr, strict_mode, true, set_mode);
|
||||
} else {
|
||||
return js_object->SetProperty(*name, *value, attr, strict_mode);
|
||||
Handle<Object> result =
|
||||
JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
|
||||
RETURN_IF_EMPTY_HANDLE(isolate, result);
|
||||
return *result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1395,17 +1395,19 @@ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) {
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) {
|
||||
HandleScope scope(isolate);
|
||||
ASSERT(args.length() == 4);
|
||||
JSObject* recv = JSObject::cast(args[0]);
|
||||
Name* name = Name::cast(args[1]);
|
||||
Object* value = args[2];
|
||||
Handle<JSObject> recv(JSObject::cast(args[0]));
|
||||
Handle<Name> name(Name::cast(args[1]));
|
||||
Handle<Object> value(args[2], isolate);
|
||||
ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode);
|
||||
StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3));
|
||||
ASSERT(recv->HasNamedInterceptor());
|
||||
PropertyAttributes attr = NONE;
|
||||
MaybeObject* result = recv->SetPropertyWithInterceptor(
|
||||
name, value, attr, strict_mode);
|
||||
return result;
|
||||
Handle<Object> result = JSObject::SetPropertyWithInterceptor(
|
||||
recv, name, value, attr, strict_mode);
|
||||
RETURN_IF_EMPTY_HANDLE(isolate, result);
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -14649,11 +14649,12 @@ class RegExpStringModificationTest {
|
||||
// Inject the input as a global variable.
|
||||
i::Handle<i::String> input_name =
|
||||
factory->NewStringFromAscii(i::Vector<const char>("input", 5));
|
||||
i::Isolate::Current()->native_context()->global_object()->SetProperty(
|
||||
*input_name,
|
||||
*input_,
|
||||
i::JSReceiver::SetProperty(
|
||||
i::handle(i::Isolate::Current()->native_context()->global_object()),
|
||||
input_name,
|
||||
input_,
|
||||
NONE,
|
||||
i::kNonStrictMode)->ToObjectChecked();
|
||||
i::kNonStrictMode);
|
||||
|
||||
MorphThread morph_thread(this);
|
||||
morph_thread.Start();
|
||||
|
@ -262,6 +262,8 @@ TEST(GarbageCollection) {
|
||||
Handle<String> prop_name = factory->InternalizeUtf8String("theSlot");
|
||||
Handle<String> prop_namex = factory->InternalizeUtf8String("theSlotx");
|
||||
Handle<String> obj_name = factory->InternalizeUtf8String("theObject");
|
||||
Handle<Smi> twenty_three(Smi::FromInt(23), isolate);
|
||||
Handle<Smi> twenty_four(Smi::FromInt(24), isolate);
|
||||
|
||||
{
|
||||
HandleScope inner_scope(isolate);
|
||||
@ -271,14 +273,12 @@ TEST(GarbageCollection) {
|
||||
Handle<Map> initial_map =
|
||||
factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
|
||||
function->set_initial_map(*initial_map);
|
||||
Isolate::Current()->context()->global_object()->SetProperty(
|
||||
*name, *function, NONE, kNonStrictMode)->ToObjectChecked();
|
||||
Handle<GlobalObject> global(Isolate::Current()->context()->global_object());
|
||||
JSReceiver::SetProperty(global, name, function, NONE, kNonStrictMode);
|
||||
// Allocate an object. Unrooted after leaving the scope.
|
||||
Handle<JSObject> obj = factory->NewJSObject(function);
|
||||
obj->SetProperty(
|
||||
*prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
obj->SetProperty(
|
||||
*prop_namex, Smi::FromInt(24), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode);
|
||||
JSReceiver::SetProperty(obj, prop_namex, twenty_four, NONE, kNonStrictMode);
|
||||
|
||||
CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name));
|
||||
CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex));
|
||||
@ -299,10 +299,9 @@ TEST(GarbageCollection) {
|
||||
HandleScope inner_scope(isolate);
|
||||
// Allocate another object, make it reachable from global.
|
||||
Handle<JSObject> obj = factory->NewJSObject(function);
|
||||
Isolate::Current()->context()->global_object()->SetProperty(
|
||||
*obj_name, *obj, NONE, kNonStrictMode)->ToObjectChecked();
|
||||
obj->SetProperty(
|
||||
*prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
Handle<GlobalObject> global(Isolate::Current()->context()->global_object());
|
||||
JSReceiver::SetProperty(global, obj_name, obj, NONE, kNonStrictMode);
|
||||
JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode);
|
||||
}
|
||||
|
||||
// After gc, it should survive.
|
||||
@ -628,14 +627,16 @@ TEST(FunctionAllocation) {
|
||||
factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
|
||||
function->set_initial_map(*initial_map);
|
||||
|
||||
Handle<Smi> twenty_three(Smi::FromInt(23), isolate);
|
||||
Handle<Smi> twenty_four(Smi::FromInt(24), isolate);
|
||||
|
||||
Handle<String> prop_name = factory->InternalizeUtf8String("theSlot");
|
||||
Handle<JSObject> obj = factory->NewJSObject(function);
|
||||
obj->SetProperty(
|
||||
*prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode);
|
||||
CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name));
|
||||
// Check that we can add properties to function objects.
|
||||
function->SetProperty(
|
||||
*prop_name, Smi::FromInt(24), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
JSReceiver::SetProperty(function, prop_name, twenty_four, NONE,
|
||||
kNonStrictMode);
|
||||
CHECK_EQ(Smi::FromInt(24), function->GetProperty(*prop_name));
|
||||
}
|
||||
|
||||
@ -655,12 +656,14 @@ TEST(ObjectProperties) {
|
||||
Handle<String> first = factory->InternalizeUtf8String("first");
|
||||
Handle<String> second = factory->InternalizeUtf8String("second");
|
||||
|
||||
Handle<Smi> one(Smi::FromInt(1), isolate);
|
||||
Handle<Smi> two(Smi::FromInt(2), isolate);
|
||||
|
||||
// check for empty
|
||||
CHECK(!obj->HasLocalProperty(*first));
|
||||
|
||||
// add first
|
||||
obj->SetProperty(
|
||||
*first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode);
|
||||
CHECK(obj->HasLocalProperty(*first));
|
||||
|
||||
// delete first
|
||||
@ -668,10 +671,8 @@ TEST(ObjectProperties) {
|
||||
CHECK(!obj->HasLocalProperty(*first));
|
||||
|
||||
// add first and then second
|
||||
obj->SetProperty(
|
||||
*first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
obj->SetProperty(
|
||||
*second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode);
|
||||
JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode);
|
||||
CHECK(obj->HasLocalProperty(*first));
|
||||
CHECK(obj->HasLocalProperty(*second));
|
||||
|
||||
@ -683,10 +684,8 @@ TEST(ObjectProperties) {
|
||||
CHECK(!obj->HasLocalProperty(*second));
|
||||
|
||||
// add first and then second
|
||||
obj->SetProperty(
|
||||
*first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
obj->SetProperty(
|
||||
*second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode);
|
||||
JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode);
|
||||
CHECK(obj->HasLocalProperty(*first));
|
||||
CHECK(obj->HasLocalProperty(*second));
|
||||
|
||||
@ -700,16 +699,14 @@ TEST(ObjectProperties) {
|
||||
// check string and internalized string match
|
||||
const char* string1 = "fisk";
|
||||
Handle<String> s1 = factory->NewStringFromAscii(CStrVector(string1));
|
||||
obj->SetProperty(
|
||||
*s1, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
JSReceiver::SetProperty(obj, s1, one, NONE, kNonStrictMode);
|
||||
Handle<String> s1_string = factory->InternalizeUtf8String(string1);
|
||||
CHECK(obj->HasLocalProperty(*s1_string));
|
||||
|
||||
// check internalized string and string match
|
||||
const char* string2 = "fugl";
|
||||
Handle<String> s2_string = factory->InternalizeUtf8String(string2);
|
||||
obj->SetProperty(
|
||||
*s2_string, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
JSReceiver::SetProperty(obj, s2_string, one, NONE, kNonStrictMode);
|
||||
Handle<String> s2 = factory->NewStringFromAscii(CStrVector(string2));
|
||||
CHECK(obj->HasLocalProperty(*s2));
|
||||
}
|
||||
@ -732,8 +729,8 @@ TEST(JSObjectMaps) {
|
||||
Handle<JSObject> obj = factory->NewJSObject(function);
|
||||
|
||||
// Set a propery
|
||||
obj->SetProperty(
|
||||
*prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
Handle<Smi> twenty_three(Smi::FromInt(23), isolate);
|
||||
JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode);
|
||||
CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name));
|
||||
|
||||
// Check the map has changed
|
||||
@ -805,10 +802,11 @@ TEST(JSObjectCopy) {
|
||||
Handle<String> first = factory->InternalizeUtf8String("first");
|
||||
Handle<String> second = factory->InternalizeUtf8String("second");
|
||||
|
||||
obj->SetProperty(
|
||||
*first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
obj->SetProperty(
|
||||
*second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
Handle<Smi> one(Smi::FromInt(1), isolate);
|
||||
Handle<Smi> two(Smi::FromInt(2), isolate);
|
||||
|
||||
JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode);
|
||||
JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode);
|
||||
|
||||
obj->SetElement(0, *first, NONE, kNonStrictMode)->ToObjectChecked();
|
||||
obj->SetElement(1, *second, NONE, kNonStrictMode)->ToObjectChecked();
|
||||
@ -824,10 +822,8 @@ TEST(JSObjectCopy) {
|
||||
CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*second));
|
||||
|
||||
// Flip the values.
|
||||
clone->SetProperty(
|
||||
*first, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
clone->SetProperty(
|
||||
*second, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
|
||||
JSReceiver::SetProperty(clone, first, two, NONE, kNonStrictMode);
|
||||
JSReceiver::SetProperty(clone, second, one, NONE, kNonStrictMode);
|
||||
|
||||
clone->SetElement(0, *second, NONE, kNonStrictMode)->ToObjectChecked();
|
||||
clone->SetElement(1, *first, NONE, kNonStrictMode)->ToObjectChecked();
|
||||
@ -3009,9 +3005,10 @@ TEST(Regression144230) {
|
||||
// visited later, causing the CallIC to be cleared.
|
||||
Handle<String> name = isolate->factory()->InternalizeUtf8String("call");
|
||||
Handle<GlobalObject> global(isolate->context()->global_object());
|
||||
Handle<Smi> zero(Smi::FromInt(0), isolate);
|
||||
MaybeObject* maybe_call = global->GetProperty(*name);
|
||||
JSFunction* call = JSFunction::cast(maybe_call->ToObjectChecked());
|
||||
USE(global->SetProperty(*name, Smi::FromInt(0), NONE, kNonStrictMode));
|
||||
JSReceiver::SetProperty(global, name, zero, NONE, kNonStrictMode);
|
||||
isolate->compilation_cache()->Clear();
|
||||
call->shared()->set_ic_age(heap->global_ic_age() + 1);
|
||||
Handle<Object> call_code(call->code(), isolate);
|
||||
@ -3022,7 +3019,7 @@ TEST(Regression144230) {
|
||||
|
||||
// Either heap verification caught the problem already or we go kaboom once
|
||||
// the CallIC is executed the next time.
|
||||
USE(global->SetProperty(*name, *call_function, NONE, kNonStrictMode));
|
||||
JSReceiver::SetProperty(global, name, call_function, NONE, kNonStrictMode);
|
||||
CompileRun("call();");
|
||||
}
|
||||
|
||||
|
@ -153,6 +153,7 @@ TEST(MarkCompactCollector) {
|
||||
Heap* heap = isolate->heap();
|
||||
|
||||
v8::HandleScope sc(CcTest::isolate());
|
||||
Handle<GlobalObject> global(isolate->context()->global_object());
|
||||
|
||||
// call mark-compact when heap is empty
|
||||
heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 1");
|
||||
@ -191,8 +192,8 @@ TEST(MarkCompactCollector) {
|
||||
Map::cast(heap->AllocateMap(JS_OBJECT_TYPE,
|
||||
JSObject::kHeaderSize)->ToObjectChecked());
|
||||
function->set_initial_map(initial_map);
|
||||
isolate->context()->global_object()->SetProperty(
|
||||
func_name, function, NONE, kNonStrictMode)->ToObjectChecked();
|
||||
JSReceiver::SetProperty(
|
||||
global, handle(func_name), handle(function), NONE, kNonStrictMode);
|
||||
|
||||
JSObject* obj = JSObject::cast(
|
||||
heap->AllocateJSObject(function)->ToObjectChecked());
|
||||
@ -209,14 +210,13 @@ TEST(MarkCompactCollector) {
|
||||
obj = JSObject::cast(heap->AllocateJSObject(function)->ToObjectChecked());
|
||||
String* obj_name =
|
||||
String::cast(heap->InternalizeUtf8String("theObject")->ToObjectChecked());
|
||||
isolate->context()->global_object()->SetProperty(
|
||||
obj_name, obj, NONE, kNonStrictMode)->ToObjectChecked();
|
||||
JSReceiver::SetProperty(
|
||||
global, handle(obj_name), handle(obj), NONE, kNonStrictMode);
|
||||
String* prop_name =
|
||||
String::cast(heap->InternalizeUtf8String("theSlot")->ToObjectChecked());
|
||||
obj->SetProperty(prop_name,
|
||||
Smi::FromInt(23),
|
||||
NONE,
|
||||
kNonStrictMode)->ToObjectChecked();
|
||||
Handle<Smi> twenty_three(Smi::FromInt(23), isolate);
|
||||
JSReceiver::SetProperty(
|
||||
handle(obj), handle(prop_name), twenty_three, NONE, kNonStrictMode);
|
||||
|
||||
heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 5");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user