class V8_EXPORT Map : public Object {
public:
size_t Size() const;
+ void Clear();
+ V8_WARN_UNUSED_RESULT MaybeLocal<Value> Get(Local<Context> context,
+ Local<Value> key);
+ V8_WARN_UNUSED_RESULT MaybeLocal<Map> Set(Local<Context> context,
+ Local<Value> key,
+ Local<Value> value);
+ V8_WARN_UNUSED_RESULT Maybe<bool> Has(Local<Context> context,
+ Local<Value> key);
+ V8_WARN_UNUSED_RESULT Maybe<bool> Delete(Local<Context> context,
+ Local<Value> key);
/**
* Returns an array of length Size() * 2, where index N is the Nth key and
class V8_EXPORT Set : public Object {
public:
size_t Size() const;
+ void Clear();
+ V8_WARN_UNUSED_RESULT MaybeLocal<Set> Add(Local<Context> context,
+ Local<Value> key);
+ V8_WARN_UNUSED_RESULT Maybe<bool> Has(Local<Context> context,
+ Local<Value> key);
+ V8_WARN_UNUSED_RESULT Maybe<bool> Delete(Local<Context> context,
+ Local<Value> key);
/**
* Returns an array of the keys in this Set.
}
+void Map::Clear() {
+ auto self = Utils::OpenHandle(this);
+ i::Isolate* isolate = self->GetIsolate();
+ LOG_API(isolate, "Map::Clear");
+ ENTER_V8(isolate);
+ i::Runtime::JSMapClear(isolate, self);
+}
+
+
+MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION(context, "Map::Get", Value);
+ auto self = Utils::OpenHandle(this);
+ Local<Value> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
+ has_pending_exception =
+ !ToLocal<Value>(i::Execution::Call(isolate, isolate->map_get(), self,
+ arraysize(argv), argv, false),
+ &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(result);
+}
+
+
+MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
+ Local<Value> value) {
+ PREPARE_FOR_EXECUTION(context, "Map::Set", Map);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
+ Utils::OpenHandle(*value)};
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->map_set(), self, arraysize(argv),
+ argv, false).ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Map);
+ RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
+}
+
+
+Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Map::Has", bool);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->map_has(), self, arraysize(argv),
+ argv, false).ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(result->IsTrue());
+}
+
+
+Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Map::Delete", bool);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->map_delete(), self, arraysize(argv),
+ argv, false).ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(result->IsTrue());
+}
+
+
Local<Array> Map::AsArray() const {
i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
i::Isolate* isolate = obj->GetIsolate();
}
+void Set::Clear() {
+ auto self = Utils::OpenHandle(this);
+ i::Isolate* isolate = self->GetIsolate();
+ LOG_API(isolate, "Set::Clear");
+ ENTER_V8(isolate);
+ i::Runtime::JSSetClear(isolate, self);
+}
+
+
+MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION(context, "Set::Add", Set);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->set_add(), self, arraysize(argv),
+ argv, false).ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Set);
+ RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
+}
+
+
+Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Set::Has", bool);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->set_has(), self, arraysize(argv),
+ argv, false).ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(result->IsTrue());
+}
+
+
+Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Set::Delete", bool);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->set_delete(), self, arraysize(argv),
+ argv, false).ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(result->IsTrue());
+}
+
+
Local<Array> Set::AsArray() const {
i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
i::Isolate* isolate = obj->GetIsolate();
INSTALL_NATIVE(JSFunction, "$observeNativeObjectNotifierPerformChange",
native_object_notifier_perform_change);
INSTALL_NATIVE(JSFunction, "$arrayValues", array_values_iterator);
+ INSTALL_NATIVE(JSFunction, "$mapGet", map_get);
+ INSTALL_NATIVE(JSFunction, "$mapSet", map_set);
+ INSTALL_NATIVE(JSFunction, "$mapHas", map_has);
+ INSTALL_NATIVE(JSFunction, "$mapDelete", map_delete);
+ INSTALL_NATIVE(JSFunction, "$setAdd", set_add);
+ INSTALL_NATIVE(JSFunction, "$setHas", set_has);
+ INSTALL_NATIVE(JSFunction, "$setDelete", set_delete);
INSTALL_NATIVE(JSFunction, "$mapFromArray", map_from_array);
INSTALL_NATIVE(JSFunction, "$setFromArray", set_from_array);
}
var $getHash;
var $getExistingHash;
+var $mapSet;
+var $mapHas;
+var $mapDelete;
+var $setAdd;
+var $setHas;
+var $setDelete;
var $mapFromArray;
var $setFromArray;
// Expose to the global scope.
$getHash = GetHash;
$getExistingHash = GetExistingHash;
+$mapGet = MapGet;
+$mapSet = MapSet;
+$mapHas = MapHas;
+$mapDelete = MapDelete;
+$setAdd = SetAdd;
+$setHas = SetHas;
+$setDelete = SetDelete;
$mapFromArray = function(array) {
var map = new GlobalMap;
V(JS_MAP_MAP_INDEX, Map, js_map_map) \
V(JS_SET_FUN_INDEX, JSFunction, js_set_fun) \
V(JS_SET_MAP_INDEX, Map, js_set_map) \
+ V(MAP_GET_METHOD_INDEX, JSFunction, map_get) \
+ V(MAP_SET_METHOD_INDEX, JSFunction, map_set) \
+ V(MAP_HAS_METHOD_INDEX, JSFunction, map_has) \
+ V(MAP_DELETE_METHOD_INDEX, JSFunction, map_delete) \
+ V(SET_ADD_METHOD_INDEX, JSFunction, set_add) \
+ V(SET_HAS_METHOD_INDEX, JSFunction, set_has) \
+ V(SET_DELETE_METHOD_INDEX, JSFunction, set_delete) \
V(MAP_FROM_ARRAY_INDEX, JSFunction, map_from_array) \
V(SET_FROM_ARRAY_INDEX, JSFunction, set_from_array) \
V(MAP_ITERATOR_MAP_INDEX, Map, map_iterator_map) \
JS_MAP_MAP_INDEX,
JS_SET_FUN_INDEX,
JS_SET_MAP_INDEX,
+ MAP_GET_METHOD_INDEX,
+ MAP_SET_METHOD_INDEX,
+ MAP_HAS_METHOD_INDEX,
+ MAP_DELETE_METHOD_INDEX,
+ SET_ADD_METHOD_INDEX,
+ SET_HAS_METHOD_INDEX,
+ SET_DELETE_METHOD_INDEX,
MAP_FROM_ARRAY_INDEX,
SET_FROM_ARRAY_INDEX,
MAP_ITERATOR_MAP_INDEX,
}
+void Runtime::JSSetClear(Isolate* isolate, Handle<JSSet> set) {
+ Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
+ table = OrderedHashSet::Clear(table);
+ set->set_table(*table);
+}
+
+
RUNTIME_FUNCTION(Runtime_SetClear) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
- Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
- table = OrderedHashSet::Clear(table);
- holder->set_table(*table);
+ Runtime::JSSetClear(isolate, holder);
return isolate->heap()->undefined_value();
}
}
+void Runtime::JSMapClear(Isolate* isolate, Handle<JSMap> map) {
+ Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
+ table = OrderedHashMap::Clear(table);
+ map->set_table(*table);
+}
+
+
RUNTIME_FUNCTION(Runtime_MapClear) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
- Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
- table = OrderedHashMap::Clear(table);
- holder->set_table(*table);
+ Runtime::JSMapClear(isolate, holder);
return isolate->heap()->undefined_value();
}
static void JSMapInitialize(Isolate* isolate, Handle<JSMap> map);
+ static void JSMapClear(Isolate* isolate, Handle<JSMap> map);
static void JSSetInitialize(Isolate* isolate, Handle<JSSet> set);
+ static void JSSetClear(Isolate* isolate, Handle<JSSet> set);
static void WeakCollectionInitialize(
Isolate* isolate, Handle<JSWeakCollection> weak_collection);
map = v8::Map::FromArray(env.local(), contents).ToLocalChecked();
CHECK_EQ(2U, map->Size());
+ CHECK(map->Has(env.local(), v8::Integer::New(isolate, 1)).FromJust());
+ CHECK(map->Has(env.local(), v8::Integer::New(isolate, 3)).FromJust());
+
+ CHECK(!map->Has(env.local(), v8::Integer::New(isolate, 2)).FromJust());
+ CHECK(!map->Has(env.local(), map).FromJust());
+
+ CHECK_EQ(2, map->Get(env.local(), v8::Integer::New(isolate, 1))
+ .ToLocalChecked()
+ ->Int32Value());
+ CHECK_EQ(4, map->Get(env.local(), v8::Integer::New(isolate, 3))
+ .ToLocalChecked()
+ ->Int32Value());
+
+ CHECK(map->Get(env.local(), v8::Integer::New(isolate, 42))
+ .ToLocalChecked()
+ ->IsUndefined());
+
+ CHECK(!map->Set(env.local(), map, map).IsEmpty());
+ CHECK_EQ(3U, map->Size());
+ CHECK(map->Has(env.local(), map).FromJust());
+
+ CHECK(map->Delete(env.local(), map).FromJust());
+ CHECK_EQ(2U, map->Size());
+ CHECK(!map->Has(env.local(), map).FromJust());
+ CHECK(!map->Delete(env.local(), map).FromJust());
+
+ map->Clear();
+ CHECK_EQ(0U, map->Size());
+}
+
+
+TEST(MapFromArrayOddLength) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
// Odd lengths result in a null MaybeLocal.
- contents = v8::Array::New(isolate, 41);
+ Local<v8::Array> contents = v8::Array::New(isolate, 41);
CHECK(v8::Map::FromArray(env.local(), contents).IsEmpty());
}
set = v8::Set::FromArray(env.local(), keys).ToLocalChecked();
CHECK_EQ(2U, set->Size());
+
+ CHECK(set->Has(env.local(), v8::Integer::New(isolate, 1)).FromJust());
+ CHECK(set->Has(env.local(), v8::Integer::New(isolate, 2)).FromJust());
+
+ CHECK(!set->Has(env.local(), v8::Integer::New(isolate, 3)).FromJust());
+ CHECK(!set->Has(env.local(), set).FromJust());
+
+ CHECK(!set->Add(env.local(), set).IsEmpty());
+ CHECK_EQ(3U, set->Size());
+ CHECK(set->Has(env.local(), set).FromJust());
+
+ CHECK(set->Delete(env.local(), set).FromJust());
+ CHECK_EQ(2U, set->Size());
+ CHECK(!set->Has(env.local(), set).FromJust());
+ CHECK(!set->Delete(env.local(), set).FromJust());
+
+ set->Clear();
+ CHECK_EQ(0U, set->Size());
}