Bug 1147660, part 5 - Split the part of NativeDefineProperty that updates the object into a separate function again. r=efaust.

--HG--
extra : rebase_source : 38f9f48c7781328c5116d5e1a37ab39d68aecf89
This commit is contained in:
Jason Orendorff 2015-03-23 14:32:29 -05:00
Родитель fb07f68159
Коммит 24fcf2a236
1 изменённых файлов: 59 добавлений и 58 удалений

Просмотреть файл

@ -1221,6 +1221,64 @@ CheckAccessorRedefinition(ExclusiveContext* cx, HandleObject obj, HandleShape sh
return Throw(cx->asJSContext(), shape->propid(), JSMSG_CANT_REDEFINE_PROP);
}
static bool
AddOrChangeProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
Handle<PropertyDescriptor> desc)
{
desc.assertComplete();
if (!PurgeScopeChain(cx, obj, id))
return false;
// Use dense storage for new indexed properties where possible.
if (JSID_IS_INT(id) &&
!desc.getter() &&
!desc.setter() &&
desc.attributes() == JSPROP_ENUMERATE &&
(!obj->isIndexed() || !obj->containsPure(id)) &&
!IsAnyTypedArray(obj))
{
uint32_t index = JSID_TO_INT(id);
NativeObject::EnsureDenseResult edResult = obj->ensureDenseElements(cx, index, 1);
if (edResult == NativeObject::ED_FAILED)
return false;
if (edResult == NativeObject::ED_OK) {
obj->setDenseElementWithType(cx, index, desc.value());
if (!CallAddPropertyHookDense(cx, obj, index, desc.value()))
return false;
return true;
}
}
RootedShape shape(cx, NativeObject::putProperty(cx, obj, id, desc.getter(), desc.setter(),
SHAPE_INVALID_SLOT, desc.attributes(), 0));
if (!shape)
return false;
if (!UpdateShapeTypeAndValue(cx, obj, shape, desc.value()))
return false;
// Clear any existing dense index after adding a sparse indexed property,
// and investigate converting the object to dense indexes.
if (JSID_IS_INT(id)) {
if (!obj->maybeCopyElementsForWrite(cx))
return false;
uint32_t index = JSID_TO_INT(id);
NativeObject::removeDenseElementForSparseIndex(cx, obj, index);
NativeObject::EnsureDenseResult edResult =
NativeObject::maybeDensifySparseElements(cx, obj);
if (edResult == NativeObject::ED_FAILED)
return false;
if (edResult == NativeObject::ED_OK) {
MOZ_ASSERT(!desc.setter());
return CallAddPropertyHookDense(cx, obj, index, desc.value());
}
}
return CallAddPropertyHook(cx, obj, shape, desc.value());
}
bool
js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId id,
Handle<PropertyDescriptor> desc_,
@ -1387,65 +1445,8 @@ js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
// At this point, no mutation has happened yet, but all ES6 error cases
// have been dealt with.
desc.assertComplete();
MOZ_ASSERT(desc.getter() != JS_PropertyStub);
MOZ_ASSERT(desc.setter() != JS_StrictPropertyStub);
if (!PurgeScopeChain(cx, obj, id))
if (!AddOrChangeProperty(cx, obj, id, desc))
return false;
// Use dense storage for new indexed properties where possible.
if (JSID_IS_INT(id) &&
!desc.getter() &&
!desc.setter() &&
desc.attributes() == JSPROP_ENUMERATE &&
(!obj->isIndexed() || !obj->containsPure(id)) &&
!IsAnyTypedArray(obj))
{
uint32_t index = JSID_TO_INT(id);
NativeObject::EnsureDenseResult edResult = obj->ensureDenseElements(cx, index, 1);
if (edResult == NativeObject::ED_FAILED)
return false;
if (edResult == NativeObject::ED_OK) {
obj->setDenseElementWithType(cx, index, desc.value());
if (!CallAddPropertyHookDense(cx, obj, index, desc.value()))
return false;
return result.succeed();
}
}
shape = NativeObject::putProperty(cx, obj, id, desc.getter(), desc.setter(),
SHAPE_INVALID_SLOT, desc.attributes(), 0);
if (!shape)
return false;
if (!UpdateShapeTypeAndValue(cx, obj, shape, desc.value()))
return false;
// Clear any existing dense index after adding a sparse indexed property,
// and investigate converting the object to dense indexes.
if (JSID_IS_INT(id)) {
if (!obj->maybeCopyElementsForWrite(cx))
return false;
uint32_t index = JSID_TO_INT(id);
NativeObject::removeDenseElementForSparseIndex(cx, obj, index);
NativeObject::EnsureDenseResult edResult =
NativeObject::maybeDensifySparseElements(cx, obj);
if (edResult == NativeObject::ED_FAILED)
return false;
if (edResult == NativeObject::ED_OK) {
MOZ_ASSERT(!desc.setter());
if (!CallAddPropertyHookDense(cx, obj, index, desc.value()))
return false;
return result.succeed();
}
}
if (!CallAddPropertyHook(cx, obj, shape, desc.value()))
return false;
return result.succeed();
}