}
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);
object->set_map(*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
'../../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',