Initialize lazy objects when caching classes in for-in.

Summary:
It was possible for the cached classes to be invalidated if there
existed a lazy object in the prototype chain, as calling
`getOwnPropertyNames` would initialize lazy objects.

Force an early initialization of all lazy objects to ensure that the
hidden classes don't change while the for-in caching mechanism is running.

Reviewed By: tmikov

Differential Revision: D23269675

fbshipit-source-id: 546492c2eb7e876c31b31731528a11ee23367f6c
This commit is contained in:
Aakash Patel 2020-08-24 15:32:33 -07:00 коммит произвёл Facebook GitHub Bot
Родитель b9c44ec5b2
Коммит 1848baf555
2 изменённых файлов: 27 добавлений и 0 удалений

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

@ -3072,6 +3072,12 @@ ExecutionStatus setProtoClasses(
arr->clear(runtime);
return ExecutionStatus::RETURNED;
}
if (JSObject::Helper::flags(*head).lazyObject) {
// Ensure all properties have been initialized before caching the hidden
// class. Not doing this will result in changes to the hidden class
// when getOwnPropertyKeys is called later.
JSObject::initializeLazyObject(runtime, head);
}
clazz = HermesValue::encodeObjectValue(head->getClass(runtime));
if (LLVM_UNLIKELY(
BigStorage::push_back(arr, runtime, clazz) ==

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

@ -0,0 +1,21 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// RUN: %hermes -O %s | %FileCheck --match-full-lines %s
// RUN: %hermes -O -emit-binary -out %t.hbc %s && %hermes %t.hbc | %FileCheck --match-full-lines %s
function f() {}
var obj = {
__proto__: f,
b: 12
};
for (var i in obj) {
print(i, obj[i]);
}
// CHECK: b 12