}
Handle<Object> old_value;
- bool is_observed =
- FLAG_harmony_observation &&
- *function == *object &&
- function->map()->is_observed();
+ bool is_observed = *function == *object && function->map()->is_observed();
if (is_observed) {
if (function->has_prototype())
old_value = handle(function->prototype(), isolate);
INSTALL_NATIVE(JSObject, "functionCache", function_cache);
INSTALL_NATIVE(JSFunction, "ToCompletePropertyDescriptor",
to_complete_property_descriptor);
+ INSTALL_NATIVE(JSFunction, "NotifyChange", observers_notify_change);
+ INSTALL_NATIVE(JSFunction, "EnqueueSpliceRecord", observers_enqueue_splice);
+ INSTALL_NATIVE(JSFunction, "BeginPerformSplice",
+ observers_begin_perform_splice);
+ INSTALL_NATIVE(JSFunction, "EndPerformSplice",
+ observers_end_perform_splice);
}
INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
INSTALL_NATIVE(JSFunction, "ProxyEnumerate", proxy_enumerate);
}
- if (FLAG_harmony_observation) {
- INSTALL_NATIVE(JSFunction, "NotifyChange", observers_notify_change);
- INSTALL_NATIVE(JSFunction, "EnqueueSpliceRecord", observers_enqueue_splice);
- INSTALL_NATIVE(JSFunction, "BeginPerformSplice",
- observers_begin_perform_splice);
- INSTALL_NATIVE(JSFunction, "EndPerformSplice",
- observers_end_perform_splice);
- }
}
#undef INSTALL_NATIVE
INSTALL_EXPERIMENTAL_NATIVE(i, symbols, "symbol.js")
INSTALL_EXPERIMENTAL_NATIVE(i, proxies, "proxy.js")
INSTALL_EXPERIMENTAL_NATIVE(i, collections, "collection.js")
- INSTALL_EXPERIMENTAL_NATIVE(i, observation, "object-observe.js")
INSTALL_EXPERIMENTAL_NATIVE(i, promises, "promise.js")
INSTALL_EXPERIMENTAL_NATIVE(i, generators, "generator.js")
INSTALL_EXPERIMENTAL_NATIVE(i, iteration, "array-iterator.js")
DEFINE_bool(harmony_proxies, false, "enable harmony proxies")
DEFINE_bool(harmony_collections, false,
"enable harmony collections (sets, maps, and weak maps)")
-DEFINE_bool(harmony_observation, false,
- "enable harmony object observation (implies harmony collections")
DEFINE_bool(harmony_generators, false, "enable harmony generators")
DEFINE_bool(harmony_iteration, false, "enable harmony iteration (for-of)")
DEFINE_bool(harmony_numeric_literals, false,
DEFINE_implication(harmony, harmony_promises)
DEFINE_implication(harmony, harmony_proxies)
DEFINE_implication(harmony, harmony_collections)
-DEFINE_implication(harmony, harmony_observation)
DEFINE_implication(harmony, harmony_generators)
DEFINE_implication(harmony, harmony_iteration)
DEFINE_implication(harmony, harmony_numeric_literals)
DEFINE_implication(harmony, harmony_maths)
DEFINE_implication(harmony_promises, harmony_collections)
DEFINE_implication(harmony_modules, harmony_scoping)
-DEFINE_implication(harmony_observation, harmony_collections)
// Flags for experimental implementation features.
DEFINE_bool(packed_arrays, true, "optimizes arrays that have no holes")
}
// Observed objects are always modified through the runtime.
- if (FLAG_harmony_observation && receiver->map()->is_observed()) {
+ if (receiver->map()->is_observed()) {
Handle<Object> result = JSReceiver::SetProperty(
receiver, name, value, NONE, strict_mode(), store_mode);
RETURN_IF_EMPTY_HANDLE(isolate(), result);
if (maybe_object->IsFailure()) return maybe_object;
} else {
bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() &&
- !(FLAG_harmony_observation && object->IsJSObject() &&
+ !(object->IsJSObject() &&
JSObject::cast(*object)->map()->is_observed());
if (use_ic && !object->IsSmi()) {
// Don't use ICs for maps of the objects in Array's prototype chain. We
// implementation of (1) and (2) have "optimized" states which represent
// common cases which can be handled more efficiently.
-var observationState = %GetObservationState();
-if (IS_UNDEFINED(observationState.callbackInfoMap)) {
- observationState.callbackInfoMap = %ObservationWeakMapCreate();
- observationState.objectInfoMap = %ObservationWeakMapCreate();
- observationState.notifierObjectInfoMap = %ObservationWeakMapCreate();
- observationState.pendingObservers = null;
- observationState.nextCallbackPriority = 0;
-}
-
-function ObservationWeakMap(map) {
- this.map_ = map;
-}
-
-ObservationWeakMap.prototype = {
- get: function(key) {
- key = %UnwrapGlobalProxy(key);
- if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
- return %WeakCollectionGet(this.map_, key);
- },
- set: function(key, value) {
- key = %UnwrapGlobalProxy(key);
- if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
- %WeakCollectionSet(this.map_, key, value);
- },
- has: function(key) {
- return !IS_UNDEFINED(this.get(key));
+var observationState;
+
+function GetObservationState() {
+ if (IS_UNDEFINED(observationState))
+ observationState = %GetObservationState();
+
+ if (IS_UNDEFINED(observationState.callbackInfoMap)) {
+ observationState.callbackInfoMap = %ObservationWeakMapCreate();
+ observationState.objectInfoMap = %ObservationWeakMapCreate();
+ observationState.notifierObjectInfoMap = %ObservationWeakMapCreate();
+ observationState.pendingObservers = null;
+ observationState.nextCallbackPriority = 0;
+ }
+
+ return observationState;
+}
+
+function GetWeakMapWrapper() {
+ function MapWrapper(map) {
+ this.map_ = map;
+ };
+
+ MapWrapper.prototype = {
+ get: function(key) {
+ key = %UnwrapGlobalProxy(key);
+ if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
+ return %WeakCollectionGet(this.map_, key);
+ },
+ set: function(key, value) {
+ key = %UnwrapGlobalProxy(key);
+ if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
+ %WeakCollectionSet(this.map_, key, value);
+ },
+ has: function(key) {
+ return !IS_UNDEFINED(this.get(key));
+ }
+ };
+
+ return MapWrapper;
+}
+
+var contextMaps;
+
+function GetContextMaps() {
+ if (IS_UNDEFINED(contextMaps)) {
+ var map = GetWeakMapWrapper();
+ var observationState = GetObservationState();
+ contextMaps = {
+ callbackInfoMap: new map(observationState.callbackInfoMap),
+ objectInfoMap: new map(observationState.objectInfoMap),
+ notifierObjectInfoMap: new map(observationState.notifierObjectInfoMap)
+ };
}
-};
-var callbackInfoMap =
- new ObservationWeakMap(observationState.callbackInfoMap);
-var objectInfoMap = new ObservationWeakMap(observationState.objectInfoMap);
-var notifierObjectInfoMap =
- new ObservationWeakMap(observationState.notifierObjectInfoMap);
+ return contextMaps;
+}
+
+function GetCallbackInfoMap() {
+ return GetContextMaps().callbackInfoMap;
+}
+
+function GetObjectInfoMap() {
+ return GetContextMaps().objectInfoMap;
+}
+
+function GetNotifierObjectInfoMap() {
+ return GetContextMaps().notifierObjectInfoMap;
+}
+
+function GetPendingObservers() {
+ return GetObservationState().pendingObservers;
+}
+
+function SetPendingObservers(pendingObservers) {
+ GetObservationState().pendingObservers = pendingObservers;
+}
+
+function GetNextCallbackPriority() {
+ return GetObservationState().nextCallbackPriority++;
+}
function nullProtoObject() {
return { __proto__: null };
performing: null,
performingCount: 0,
};
- objectInfoMap.set(object, objectInfo);
+ GetObjectInfoMap().set(object, objectInfo);
}
return objectInfo;
}
function ObjectInfoGet(object) {
- return objectInfoMap.get(object);
+ return GetObjectInfoMap().get(object);
}
function ObjectInfoGetFromNotifier(notifier) {
- return notifierObjectInfoMap.get(notifier);
+ return GetNotifierObjectInfoMap().get(notifier);
}
function ObjectInfoGetNotifier(objectInfo) {
if (IS_NULL(objectInfo.notifier)) {
objectInfo.notifier = { __proto__: notifierPrototype };
- notifierObjectInfoMap.set(objectInfo.notifier, objectInfo);
+ GetNotifierObjectInfoMap().set(objectInfo.notifier, objectInfo);
}
return objectInfo.notifier;
// priority. When a change record must be enqueued for the callback, it
// normalizes. When delivery clears any pending change records, it re-optimizes.
function CallbackInfoGet(callback) {
- return callbackInfoMap.get(callback);
+ return GetCallbackInfoMap().get(callback);
}
function CallbackInfoGetOrCreate(callback) {
- var callbackInfo = callbackInfoMap.get(callback);
+ var callbackInfo = GetCallbackInfoMap().get(callback);
if (!IS_UNDEFINED(callbackInfo))
return callbackInfo;
- var priority = observationState.nextCallbackPriority++
- callbackInfoMap.set(callback, priority);
+ var priority = GetNextCallbackPriority();
+ GetCallbackInfoMap().set(callback, priority);
return priority;
}
}
function CallbackInfoNormalize(callback) {
- var callbackInfo = callbackInfoMap.get(callback);
+ var callbackInfo = GetCallbackInfoMap().get(callback);
if (IS_NUMBER(callbackInfo)) {
var priority = callbackInfo;
callbackInfo = new InternalArray;
callbackInfo.priority = priority;
- callbackInfoMap.set(callback, callbackInfo);
+ GetCallbackInfoMap().set(callback, callbackInfo);
}
return callbackInfo;
}
}
var callbackInfo = CallbackInfoNormalize(callback);
- if (IS_NULL(observationState.pendingObservers)) {
- observationState.pendingObservers = nullProtoObject();
+ if (IS_NULL(GetPendingObservers())) {
+ SetPendingObservers(nullProtoObject())
GetMicrotaskQueue().push(ObserveMicrotaskRunner);
%SetMicrotaskPending(true);
}
- observationState.pendingObservers[callbackInfo.priority] = callback;
+ GetPendingObservers()[callbackInfo.priority] = callback;
callbackInfo.push(changeRecord);
}
}
function CallbackDeliverPending(callback) {
- var callbackInfo = callbackInfoMap.get(callback);
+ var callbackInfo = GetCallbackInfoMap().get(callback);
if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo))
return false;
// Clear the pending change records from callback and return it to its
// "optimized" state.
var priority = callbackInfo.priority;
- callbackInfoMap.set(callback, priority);
+ GetCallbackInfoMap().set(callback, priority);
- if (observationState.pendingObservers)
- delete observationState.pendingObservers[priority];
+ if (GetPendingObservers())
+ delete GetPendingObservers()[priority];
var delivered = [];
%MoveArrayContents(callbackInfo, delivered);
}
function ObserveMicrotaskRunner() {
- var pendingObservers = observationState.pendingObservers;
+ var pendingObservers = GetPendingObservers();
if (pendingObservers) {
- observationState.pendingObservers = null;
+ SetPendingObservers(null);
for (var i in pendingObservers) {
CallbackDeliverPending(pendingObservers[i]);
}
AddSlowProperty(object, name, value, attributes);
}
- if (FLAG_harmony_observation &&
- object->map()->is_observed() &&
+ if (object->map()->is_observed() &&
*name != isolate->heap()->hidden_string()) {
Handle<Object> old_value = isolate->factory()->the_hole_value();
EnqueueChangeRecord(object, "add", name, old_value);
}
Handle<Object> old_value = isolate->factory()->the_hole_value();
- bool is_observed = FLAG_harmony_observation &&
- object->map()->is_observed() &&
+ bool is_observed = object->map()->is_observed() &&
*name != isolate->heap()->hidden_string();
if (is_observed && lookup->IsDataProperty()) {
old_value = Object::GetProperty(object, name);
Handle<Object> old_value = isolate->factory()->the_hole_value();
PropertyAttributes old_attributes = ABSENT;
- bool is_observed = FLAG_harmony_observation &&
- object->map()->is_observed() &&
+ bool is_observed = object->map()->is_observed() &&
*name != isolate->heap()->hidden_string();
if (is_observed && lookup.IsProperty()) {
if (lookup.IsDataProperty()) old_value =
Handle<Object> old_value;
bool should_enqueue_change_record = false;
- if (FLAG_harmony_observation && object->map()->is_observed()) {
+ if (object->map()->is_observed()) {
should_enqueue_change_record = HasLocalElement(object, index);
if (should_enqueue_change_record) {
old_value = object->GetLocalElementAccessorPair(index) != NULL
}
Handle<Object> old_value = isolate->factory()->the_hole_value();
- bool is_observed = FLAG_harmony_observation &&
- object->map()->is_observed() &&
+ bool is_observed = object->map()->is_observed() &&
*name != isolate->heap()->hidden_string();
if (is_observed && lookup.IsDataProperty()) {
old_value = Object::GetProperty(object, name);
JSObject::MigrateToMap(object, new_map);
ASSERT(!object->map()->is_extensible());
- if (FLAG_harmony_observation && object->map()->is_observed()) {
+ if (object->map()->is_observed()) {
EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
isolate->factory()->the_hole_value());
}
bool is_element = name->AsArrayIndex(&index);
Handle<Object> old_value = isolate->factory()->the_hole_value();
- bool is_observed = FLAG_harmony_observation &&
- object->map()->is_observed() &&
+ bool is_observed = object->map()->is_observed() &&
*name != isolate->heap()->hidden_string();
bool preexists = false;
if (is_observed) {
MaybeObject* JSArray::SetElementsLength(Object* len) {
// We should never end in here with a pixel or external array.
ASSERT(AllowsSetElementsLength());
- if (!(FLAG_harmony_observation && map()->is_observed()))
+ if (!map()->is_observed())
return GetElementsAccessor()->SetLength(this, len);
Isolate* isolate = GetIsolate();
dictionary->set_requires_slow_elements();
}
- if (!(FLAG_harmony_observation && object->map()->is_observed())) {
+ if (!object->map()->is_observed()) {
return object->HasIndexedInterceptor()
? SetElementWithInterceptor(object, index, value, attributes, strict_mode,
check_prototype,
if (IsAccessCheckNeeded()) return false;
// Observed objects may not go to fast mode because they rely on map checks,
// and for fast element accesses we sometimes check element kinds only.
- if (FLAG_harmony_observation && map()->is_observed()) return false;
+ if (map()->is_observed()) return false;
FixedArray* elements = FixedArray::cast(this->elements());
SeededNumberDictionary* dictionary = NULL;
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
- if (FLAG_harmony_observation && obj->map()->is_observed()) {
+ if (obj->map()->is_observed()) {
Handle<Object> old_value(
GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate);
Factory* factory = isolate->factory();
v8::HandleScope scope(CcTest::isolate());
+ CompileRun("var base = {};");
+ Handle<JSObject> baseObject =
+ v8::Utils::OpenHandle(
+ *v8::Handle<v8::Object>::Cast(
+ CcTest::global()->Get(v8_str("base"))));
+ int initialTransitions = baseObject->map()->NumberOfProtoTransitions();
+
CompileRun(
- "var base = {};"
"var live = [];"
"for (var i = 0; i < 10; i++) {"
" var object = {};"
" if (i >= 3) live.push(object, prototype);"
"}");
- Handle<JSObject> baseObject =
- v8::Utils::OpenHandle(
- *v8::Handle<v8::Object>::Cast(
- CcTest::global()->Get(v8_str("base"))));
-
// Verify that only dead prototype transitions are cleared.
- CHECK_EQ(10, baseObject->map()->NumberOfProtoTransitions());
+ CHECK_EQ(initialTransitions + 10,
+ baseObject->map()->NumberOfProtoTransitions());
CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
const int transitions = 10 - 3;
- CHECK_EQ(transitions, baseObject->map()->NumberOfProtoTransitions());
+ CHECK_EQ(initialTransitions + transitions,
+ baseObject->map()->NumberOfProtoTransitions());
// Verify that prototype transitions array was compacted.
FixedArray* trans = baseObject->map()->GetPrototypeTransitions();
- for (int i = 0; i < transitions; i++) {
+ for (int i = initialTransitions; i < initialTransitions + transitions; i++) {
int j = Map::kProtoTransitionHeaderSize +
i * Map::kProtoTransitionElementsPerEntry;
CHECK(trans->get(j + Map::kProtoTransitionMapOffset)->IsMap());
Object* proto = trans->get(j + Map::kProtoTransitionPrototypeOffset);
- CHECK(proto->IsTheHole() || proto->IsJSObject());
+ CHECK(proto->IsJSObject());
}
// Make sure next prototype is placed on an old-space evacuation candidate.
class HarmonyIsolate {
public:
HarmonyIsolate() {
- i::FLAG_harmony_observation = true;
i::FLAG_harmony_promises = true;
isolate_ = Isolate::New();
isolate_->Enter();
using namespace v8;
namespace i = v8::internal;
-namespace {
-// Need to create a new isolate when FLAG_harmony_observation is on.
-class HarmonyIsolate {
- public:
- HarmonyIsolate() {
- i::FLAG_harmony_observation = true;
- isolate_ = Isolate::New();
- isolate_->Enter();
- }
-
- ~HarmonyIsolate() {
- isolate_->Exit();
- isolate_->Dispose();
- }
-
- Isolate* GetIsolate() const { return isolate_; }
-
- private:
- Isolate* isolate_;
-};
-}
-
TEST(PerIsolateState) {
- HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
- LocalContext context1(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
+ LocalContext context1(CcTest::isolate());
CompileRun(
"var count = 0;"
"var calls = 0;"
"(function() { obj.foo = 'bar'; })");
Handle<Value> notify_fun2;
{
- LocalContext context2(isolate.GetIsolate());
- context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
+ LocalContext context2(CcTest::isolate());
+ context2->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "obj"),
obj);
notify_fun2 = CompileRun(
"(function() { obj.foo = 'baz'; })");
}
Handle<Value> notify_fun3;
{
- LocalContext context3(isolate.GetIsolate());
- context3->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
+ LocalContext context3(CcTest::isolate());
+ context3->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "obj"),
obj);
notify_fun3 = CompileRun(
"(function() { obj.foo = 'bat'; })");
}
{
- LocalContext context4(isolate.GetIsolate());
+ LocalContext context4(CcTest::isolate());
context4->Global()->Set(
- String::NewFromUtf8(isolate.GetIsolate(), "observer"), observer);
- context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "fun1"),
+ String::NewFromUtf8(CcTest::isolate(), "observer"), observer);
+ context4->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "fun1"),
notify_fun1);
- context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "fun2"),
+ context4->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "fun2"),
notify_fun2);
- context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "fun3"),
+ context4->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "fun3"),
notify_fun3);
CompileRun("fun1(); fun2(); fun3(); Object.deliverChangeRecords(observer)");
}
TEST(EndOfMicrotaskDelivery) {
- HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
- LocalContext context(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
+ LocalContext context(CcTest::isolate());
CompileRun(
"var obj = {};"
"var count = 0;"
TEST(DeliveryOrdering) {
- HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
- LocalContext context(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
+ LocalContext context(CcTest::isolate());
CompileRun(
"var obj1 = {};"
"var obj2 = {};"
TEST(DeliveryOrderingReentrant) {
- HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
- LocalContext context(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
+ LocalContext context(CcTest::isolate());
CompileRun(
"var obj = {};"
"var reentered = false;"
TEST(DeliveryOrderingDeliverChangeRecords) {
- HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
- LocalContext context(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
+ LocalContext context(CcTest::isolate());
CompileRun(
"var obj = {};"
"var ordering = [];"
TEST(ObjectHashTableGrowth) {
- HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
// Initializing this context sets up initial hash tables.
- LocalContext context(isolate.GetIsolate());
+ LocalContext context(CcTest::isolate());
Handle<Value> obj = CompileRun("obj = {};");
Handle<Value> observer = CompileRun(
"var ran = false;"
"(function() { ran = true })");
{
// As does initializing this context.
- LocalContext context2(isolate.GetIsolate());
- context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
+ LocalContext context2(CcTest::isolate());
+ context2->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "obj"),
obj);
context2->Global()->Set(
- String::NewFromUtf8(isolate.GetIsolate(), "observer"), observer);
+ String::NewFromUtf8(CcTest::isolate(), "observer"), observer);
CompileRun(
"var objArr = [];"
// 100 objects should be enough to make the hash table grow
TEST(GlobalObjectObservation) {
- HarmonyIsolate isolate;
- LocalContext context(isolate.GetIsolate());
- HandleScope scope(isolate.GetIsolate());
+ LocalContext context(CcTest::isolate());
+ HandleScope scope(CcTest::isolate());
Handle<Object> global_proxy = context->Global();
CompileRun(
"var records = [];"
// to the old context.
context->DetachGlobal();
{
- LocalContext context2(isolate.GetIsolate());
+ LocalContext context2(CcTest::isolate());
CompileRun(
"var records2 = [];"
"var global = this;"
{
// Delegates to Context::New
LocalContext context3(
- isolate.GetIsolate(), NULL, Handle<ObjectTemplate>(), global_proxy);
+ CcTest::isolate(), NULL, Handle<ObjectTemplate>(), global_proxy);
CompileRun(
"var records3 = [];"
"Object.observe(this, function(r) { [].push.apply(records3, r) });"
}
#define EXPECT_RECORDS(records, expectations) \
- ExpectRecords(isolate.GetIsolate(), records, expectations, \
+ ExpectRecords(CcTest::isolate(), records, expectations, \
ARRAY_SIZE(expectations))
TEST(APITestBasicMutation) {
- HarmonyIsolate isolate;
- v8::Isolate* v8_isolate = isolate.GetIsolate();
+ v8::Isolate* v8_isolate = CcTest::isolate();
HandleScope scope(v8_isolate);
LocalContext context(v8_isolate);
Handle<Object> obj = Handle<Object>::Cast(CompileRun(
TEST(HiddenPrototypeObservation) {
- HarmonyIsolate isolate;
- v8::Isolate* v8_isolate = isolate.GetIsolate();
+ v8::Isolate* v8_isolate = CcTest::isolate();
HandleScope scope(v8_isolate);
LocalContext context(v8_isolate);
Handle<FunctionTemplate> tmpl = FunctionTemplate::New(v8_isolate);
TEST(ObservationWeakMap) {
- HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
- LocalContext context(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
+ LocalContext context(CcTest::isolate());
CompileRun(
"var obj = {};"
"Object.observe(obj, function(){});"
"Object.getNotifier(obj);"
"obj = null;");
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate.GetIsolate());
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(CcTest::isolate());
i::Handle<i::JSObject> observation_state =
i_isolate->factory()->observation_state();
i::Handle<i::JSWeakMap> callbackInfoMap =
TEST(NamedAccessCheck) {
- HarmonyIsolate isolate;
const AccessType types[] = { ACCESS_GET, ACCESS_HAS };
for (size_t i = 0; i < ARRAY_SIZE(types); ++i) {
- HandleScope scope(isolate.GetIsolate());
- LocalContext context(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
+ LocalContext context(CcTest::isolate());
g_access_block_type = types[i];
Handle<Object> instance = CreateAccessCheckedObject(
- isolate.GetIsolate(),
+ CcTest::isolate(),
NamedAccessAllowUnlessBlocked,
IndexedAccessAlwaysAllowed,
- String::NewFromUtf8(isolate.GetIsolate(), "foo"));
+ String::NewFromUtf8(CcTest::isolate(), "foo"));
CompileRun("var records = null;"
"var objNoCheck = {};"
"var observer = function(r) { records = r };"
"Object.observe(objNoCheck, observer);");
Handle<Value> obj_no_check = CompileRun("objNoCheck");
{
- LocalContext context2(isolate.GetIsolate());
- context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
+ LocalContext context2(CcTest::isolate());
+ context2->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "obj"),
instance);
context2->Global()->Set(
- String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"),
+ String::NewFromUtf8(CcTest::isolate(), "objNoCheck"),
obj_no_check);
CompileRun("var records2 = null;"
"var observer2 = function(r) { records2 = r };"
const RecordExpectation expected_records2[] = {
{ instance, "add", "foo", Handle<Value>() },
{ instance, "update", "foo",
- String::NewFromUtf8(isolate.GetIsolate(), "bar") },
+ String::NewFromUtf8(CcTest::isolate(), "bar") },
{ instance, "reconfigure", "foo",
- Number::New(isolate.GetIsolate(), 5) },
+ Number::New(CcTest::isolate(), 5) },
{ instance, "add", "bar", Handle<Value>() },
{ obj_no_check, "add", "baz", Handle<Value>() },
};
TEST(IndexedAccessCheck) {
- HarmonyIsolate isolate;
const AccessType types[] = { ACCESS_GET, ACCESS_HAS };
for (size_t i = 0; i < ARRAY_SIZE(types); ++i) {
- HandleScope scope(isolate.GetIsolate());
- LocalContext context(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
+ LocalContext context(CcTest::isolate());
g_access_block_type = types[i];
Handle<Object> instance = CreateAccessCheckedObject(
- isolate.GetIsolate(), NamedAccessAlwaysAllowed,
- IndexedAccessAllowUnlessBlocked, Number::New(isolate.GetIsolate(), 7));
+ CcTest::isolate(), NamedAccessAlwaysAllowed,
+ IndexedAccessAllowUnlessBlocked, Number::New(CcTest::isolate(), 7));
CompileRun("var records = null;"
"var objNoCheck = {};"
"var observer = function(r) { records = r };"
"Object.observe(objNoCheck, observer);");
Handle<Value> obj_no_check = CompileRun("objNoCheck");
{
- LocalContext context2(isolate.GetIsolate());
- context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
+ LocalContext context2(CcTest::isolate());
+ context2->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "obj"),
instance);
context2->Global()->Set(
- String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"),
+ String::NewFromUtf8(CcTest::isolate(), "objNoCheck"),
obj_no_check);
CompileRun("var records2 = null;"
"var observer2 = function(r) { records2 = r };"
const RecordExpectation expected_records2[] = {
{ instance, "add", "7", Handle<Value>() },
{ instance, "update", "7",
- String::NewFromUtf8(isolate.GetIsolate(), "foo") },
- { instance, "reconfigure", "7", Number::New(isolate.GetIsolate(), 5) },
+ String::NewFromUtf8(CcTest::isolate(), "foo") },
+ { instance, "reconfigure", "7", Number::New(CcTest::isolate(), 5) },
{ instance, "add", "8", Handle<Value>() },
{ obj_no_check, "add", "42", Handle<Value>() }
};
TEST(SpliceAccessCheck) {
- HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
- LocalContext context(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
+ LocalContext context(CcTest::isolate());
g_access_block_type = ACCESS_GET;
Handle<Object> instance = CreateAccessCheckedObject(
- isolate.GetIsolate(), NamedAccessAlwaysAllowed,
- IndexedAccessAllowUnlessBlocked, Number::New(isolate.GetIsolate(), 1));
+ CcTest::isolate(), NamedAccessAlwaysAllowed,
+ IndexedAccessAllowUnlessBlocked, Number::New(CcTest::isolate(), 1));
CompileRun("var records = null;"
"obj[1] = 'foo';"
"obj.length = 2;"
"Array.observe(objNoCheck, observer);");
Handle<Value> obj_no_check = CompileRun("objNoCheck");
{
- LocalContext context2(isolate.GetIsolate());
- context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
+ LocalContext context2(CcTest::isolate());
+ context2->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "obj"),
instance);
context2->Global()->Set(
- String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"), obj_no_check);
+ String::NewFromUtf8(CcTest::isolate(), "objNoCheck"), obj_no_check);
CompileRun("var records2 = null;"
"var observer2 = function(r) { records2 = r };"
"Array.observe(obj, observer2);"
TEST(DisallowAllForAccessKeys) {
- HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
- LocalContext context(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
+ LocalContext context(CcTest::isolate());
Handle<Object> instance = CreateAccessCheckedObject(
- isolate.GetIsolate(), BlockAccessKeys, IndexedAccessAlwaysAllowed);
+ CcTest::isolate(), BlockAccessKeys, IndexedAccessAlwaysAllowed);
CompileRun("var records = null;"
"var objNoCheck = {};"
"var observer = function(r) { records = r };"
"Object.observe(objNoCheck, observer);");
Handle<Value> obj_no_check = CompileRun("objNoCheck");
{
- LocalContext context2(isolate.GetIsolate());
- context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
+ LocalContext context2(CcTest::isolate());
+ context2->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "obj"),
instance);
context2->Global()->Set(
- String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"), obj_no_check);
+ String::NewFromUtf8(CcTest::isolate(), "objNoCheck"), obj_no_check);
CompileRun("var records2 = null;"
"var observer2 = function(r) { records2 = r };"
"Object.observe(obj, observer2);"
TEST(AccessCheckDisallowApiModifications) {
- HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
- LocalContext context(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
+ LocalContext context(CcTest::isolate());
Handle<Object> instance = CreateAccessCheckedObject(
- isolate.GetIsolate(), BlockAccessKeys, IndexedAccessAlwaysAllowed);
+ CcTest::isolate(), BlockAccessKeys, IndexedAccessAlwaysAllowed);
CompileRun("var records = null;"
"var observer = function(r) { records = r };"
"Object.observe(obj, observer);");
{
- LocalContext context2(isolate.GetIsolate());
- context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
+ LocalContext context2(CcTest::isolate());
+ context2->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "obj"),
instance);
CompileRun("var records2 = null;"
"var observer2 = function(r) { records2 = r };"
"Object.observe(obj, observer2);");
- instance->Set(5, String::NewFromUtf8(isolate.GetIsolate(), "bar"));
- instance->Set(String::NewFromUtf8(isolate.GetIsolate(), "foo"),
- String::NewFromUtf8(isolate.GetIsolate(), "bar"));
+ instance->Set(5, String::NewFromUtf8(CcTest::isolate(), "bar"));
+ instance->Set(String::NewFromUtf8(CcTest::isolate(), "foo"),
+ String::NewFromUtf8(CcTest::isolate(), "bar"));
CompileRun(""); // trigger delivery
const RecordExpectation expected_records2[] = {
{ instance, "add", "5", Handle<Value>() },
TEST(HiddenPropertiesLeakage) {
- HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
- LocalContext context(isolate.GetIsolate());
+ HandleScope scope(CcTest::isolate());
+ LocalContext context(CcTest::isolate());
CompileRun("var obj = {};"
"var records = null;"
"var observer = function(r) { records = r };"
"Object.observe(obj, observer);");
Handle<Value> obj =
- context->Global()->Get(String::NewFromUtf8(isolate.GetIsolate(), "obj"));
+ context->Global()->Get(String::NewFromUtf8(CcTest::isolate(), "obj"));
Handle<Object>::Cast(obj)
- ->SetHiddenValue(String::NewFromUtf8(isolate.GetIsolate(), "foo"),
- Null(isolate.GetIsolate()));
+ ->SetHiddenValue(String::NewFromUtf8(CcTest::isolate(), "foo"),
+ Null(CcTest::isolate()));
CompileRun(""); // trigger delivery
CHECK(CompileRun("records")->IsNull());
}
}
// This has to be updated if the number of native scripts change.
-assertTrue(named_native_count == 16 || named_native_count == 17);
+assertTrue(named_native_count == 17 || named_native_count == 18);
// Only the 'gc' extension is loaded.
assertEquals(1, extension_count);
// This script and mjsunit.js has been loaded. If using d8, d8 loads
FAIL getSortedOwnPropertyNames(decodeURIComponent) should be length,name. Was arguments,caller,length,name.
FAIL getSortedOwnPropertyNames(encodeURI) should be length,name. Was arguments,caller,length,name.
FAIL getSortedOwnPropertyNames(encodeURIComponent) should be length,name. Was arguments,caller,length,name.
-FAIL getSortedOwnPropertyNames(Object) should be create,defineProperties,defineProperty,freeze,getOwnPropertyDescriptor,getOwnPropertyNames,getPrototypeOf,isExtensible,isFrozen,isSealed,keys,length,name,preventExtensions,prototype,seal,setPrototypeOf. Was arguments,caller,create,defineProperties,defineProperty,freeze,getOwnPropertyDescriptor,getOwnPropertyNames,getPrototypeOf,is,isExtensible,isFrozen,isSealed,keys,length,name,preventExtensions,prototype,seal,setPrototypeOf.
+FAIL getSortedOwnPropertyNames(Object) should be create,defineProperties,defineProperty,freeze,getOwnPropertyDescriptor,getOwnPropertyNames,getPrototypeOf,isExtensible,isFrozen,isSealed,keys,length,name,preventExtensions,prototype,seal,setPrototypeOf. Was arguments,caller,create,defineProperties,defineProperty,deliverChangeRecords,freeze,getNotifier,getOwnPropertyDescriptor,getOwnPropertyNames,getPrototypeOf,is,isExtensible,isFrozen,isSealed,keys,length,name,observe,preventExtensions,prototype,seal,setPrototypeOf,unobserve.
PASS getSortedOwnPropertyNames(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']
FAIL getSortedOwnPropertyNames(Function) should be length,name,prototype. Was arguments,caller,length,name,prototype.
FAIL getSortedOwnPropertyNames(Function.prototype) should be apply,bind,call,constructor,length,name,toString. Was apply,arguments,bind,call,caller,constructor,length,name,toString.
-FAIL getSortedOwnPropertyNames(Array) should be isArray,length,name,prototype. Was arguments,caller,isArray,length,name,prototype.
+FAIL getSortedOwnPropertyNames(Array) should be isArray,length,name,prototype. Was arguments,caller,isArray,length,name,observe,prototype,unobserve.
PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'every', 'filter', 'forEach', 'indexOf', 'join', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']
FAIL getSortedOwnPropertyNames(String) should be fromCharCode,length,name,prototype. Was arguments,caller,fromCharCode,length,name,prototype.
PASS getSortedOwnPropertyNames(String.prototype) is ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'replace', 'search', 'slice', 'small', 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']
'../../src/regexp.js',
'../../src/arraybuffer.js',
'../../src/typedarray.js',
+ '../../src/object-observe.js',
'../../src/macros.py',
],
'experimental_library_files': [
'../../src/symbol.js',
'../../src/proxy.js',
'../../src/collection.js',
- '../../src/object-observe.js',
'../../src/promise.js',
'../../src/generator.js',
'../../src/array-iterator.js',