1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/runtime/runtime-utils.h" 6 7 #include "src/arguments.h" 8 #include "src/conversions-inl.h" 9 #include "src/factory.h" 10 11 namespace v8 { 12 namespace internal { 13 14 15 RUNTIME_FUNCTION(Runtime_StringGetRawHashField) { 16 HandleScope scope(isolate); 17 DCHECK_EQ(1, args.length()); 18 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); 19 return *isolate->factory()->NewNumberFromUint(string->hash_field()); 20 } 21 22 23 RUNTIME_FUNCTION(Runtime_TheHole) { 24 SealHandleScope shs(isolate); 25 DCHECK_EQ(0, args.length()); 26 return isolate->heap()->the_hole_value(); 27 } 28 29 30 RUNTIME_FUNCTION(Runtime_JSCollectionGetTable) { 31 SealHandleScope shs(isolate); 32 DCHECK_EQ(1, args.length()); 33 CONVERT_ARG_CHECKED(JSObject, object, 0); 34 CHECK(object->IsJSSet() || object->IsJSMap()); 35 return static_cast<JSCollection*>(object)->table(); 36 } 37 38 39 RUNTIME_FUNCTION(Runtime_GenericHash) { 40 HandleScope scope(isolate); 41 DCHECK_EQ(1, args.length()); 42 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); 43 Smi* hash = Object::GetOrCreateHash(isolate, object); 44 return hash; 45 } 46 47 48 RUNTIME_FUNCTION(Runtime_SetInitialize) { 49 HandleScope scope(isolate); 50 DCHECK_EQ(1, args.length()); 51 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); 52 JSSet::Initialize(holder, isolate); 53 return *holder; 54 } 55 56 57 RUNTIME_FUNCTION(Runtime_SetGrow) { 58 HandleScope scope(isolate); 59 DCHECK_EQ(1, args.length()); 60 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); 61 Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table())); 62 table = OrderedHashSet::EnsureGrowable(table); 63 holder->set_table(*table); 64 return isolate->heap()->undefined_value(); 65 } 66 67 68 RUNTIME_FUNCTION(Runtime_SetShrink) { 69 HandleScope scope(isolate); 70 DCHECK_EQ(1, args.length()); 71 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); 72 Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table())); 73 table = OrderedHashSet::Shrink(table); 74 holder->set_table(*table); 75 return isolate->heap()->undefined_value(); 76 } 77 78 79 RUNTIME_FUNCTION(Runtime_SetClear) { 80 HandleScope scope(isolate); 81 DCHECK_EQ(1, args.length()); 82 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); 83 JSSet::Clear(holder); 84 return isolate->heap()->undefined_value(); 85 } 86 87 88 RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) { 89 HandleScope scope(isolate); 90 DCHECK_EQ(3, args.length()); 91 CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); 92 CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1); 93 CONVERT_SMI_ARG_CHECKED(kind, 2) 94 CHECK(kind == JSSetIterator::kKindValues || 95 kind == JSSetIterator::kKindEntries); 96 Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table())); 97 holder->set_table(*table); 98 holder->set_index(Smi::kZero); 99 holder->set_kind(Smi::FromInt(kind)); 100 return isolate->heap()->undefined_value(); 101 } 102 103 104 RUNTIME_FUNCTION(Runtime_SetIteratorClone) { 105 HandleScope scope(isolate); 106 DCHECK_EQ(1, args.length()); 107 CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); 108 109 Handle<JSSetIterator> result = isolate->factory()->NewJSSetIterator(); 110 result->set_table(holder->table()); 111 result->set_index(Smi::FromInt(Smi::cast(holder->index())->value())); 112 result->set_kind(Smi::FromInt(Smi::cast(holder->kind())->value())); 113 114 return *result; 115 } 116 117 118 RUNTIME_FUNCTION(Runtime_SetIteratorNext) { 119 SealHandleScope shs(isolate); 120 DCHECK_EQ(2, args.length()); 121 CONVERT_ARG_CHECKED(JSSetIterator, holder, 0); 122 CONVERT_ARG_CHECKED(JSArray, value_array, 1); 123 return holder->Next(value_array); 124 } 125 126 127 // The array returned contains the following information: 128 // 0: HasMore flag 129 // 1: Iteration index 130 // 2: Iteration kind 131 RUNTIME_FUNCTION(Runtime_SetIteratorDetails) { 132 HandleScope scope(isolate); 133 DCHECK_EQ(1, args.length()); 134 CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); 135 Handle<FixedArray> details = isolate->factory()->NewFixedArray(4); 136 details->set(0, isolate->heap()->ToBoolean(holder->HasMore())); 137 details->set(1, holder->index()); 138 details->set(2, holder->kind()); 139 return *isolate->factory()->NewJSArrayWithElements(details); 140 } 141 142 143 RUNTIME_FUNCTION(Runtime_MapInitialize) { 144 HandleScope scope(isolate); 145 DCHECK_EQ(1, args.length()); 146 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); 147 JSMap::Initialize(holder, isolate); 148 return *holder; 149 } 150 151 152 RUNTIME_FUNCTION(Runtime_MapShrink) { 153 HandleScope scope(isolate); 154 DCHECK_EQ(1, args.length()); 155 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); 156 Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table())); 157 table = OrderedHashMap::Shrink(table); 158 holder->set_table(*table); 159 return isolate->heap()->undefined_value(); 160 } 161 162 163 RUNTIME_FUNCTION(Runtime_MapClear) { 164 HandleScope scope(isolate); 165 DCHECK_EQ(1, args.length()); 166 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); 167 JSMap::Clear(holder); 168 return isolate->heap()->undefined_value(); 169 } 170 171 172 RUNTIME_FUNCTION(Runtime_MapGrow) { 173 HandleScope scope(isolate); 174 DCHECK_EQ(1, args.length()); 175 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); 176 Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table())); 177 table = OrderedHashMap::EnsureGrowable(table); 178 holder->set_table(*table); 179 return isolate->heap()->undefined_value(); 180 } 181 182 183 RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) { 184 HandleScope scope(isolate); 185 DCHECK_EQ(3, args.length()); 186 CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); 187 CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1); 188 CONVERT_SMI_ARG_CHECKED(kind, 2) 189 CHECK(kind == JSMapIterator::kKindKeys || 190 kind == JSMapIterator::kKindValues || 191 kind == JSMapIterator::kKindEntries); 192 Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table())); 193 holder->set_table(*table); 194 holder->set_index(Smi::kZero); 195 holder->set_kind(Smi::FromInt(kind)); 196 return isolate->heap()->undefined_value(); 197 } 198 199 200 RUNTIME_FUNCTION(Runtime_MapIteratorClone) { 201 HandleScope scope(isolate); 202 DCHECK_EQ(1, args.length()); 203 CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); 204 205 Handle<JSMapIterator> result = isolate->factory()->NewJSMapIterator(); 206 result->set_table(holder->table()); 207 result->set_index(Smi::FromInt(Smi::cast(holder->index())->value())); 208 result->set_kind(Smi::FromInt(Smi::cast(holder->kind())->value())); 209 210 return *result; 211 } 212 213 214 // The array returned contains the following information: 215 // 0: HasMore flag 216 // 1: Iteration index 217 // 2: Iteration kind 218 RUNTIME_FUNCTION(Runtime_MapIteratorDetails) { 219 HandleScope scope(isolate); 220 DCHECK_EQ(1, args.length()); 221 CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); 222 Handle<FixedArray> details = isolate->factory()->NewFixedArray(4); 223 details->set(0, isolate->heap()->ToBoolean(holder->HasMore())); 224 details->set(1, holder->index()); 225 details->set(2, holder->kind()); 226 return *isolate->factory()->NewJSArrayWithElements(details); 227 } 228 229 230 RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { 231 HandleScope scope(isolate); 232 DCHECK_EQ(2, args.length()); 233 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); 234 CONVERT_NUMBER_CHECKED(int, max_entries, Int32, args[1]); 235 CHECK(max_entries >= 0); 236 return *JSWeakCollection::GetEntries(holder, max_entries); 237 } 238 239 240 RUNTIME_FUNCTION(Runtime_MapIteratorNext) { 241 SealHandleScope shs(isolate); 242 DCHECK_EQ(2, args.length()); 243 CONVERT_ARG_CHECKED(JSMapIterator, holder, 0); 244 CONVERT_ARG_CHECKED(JSArray, value_array, 1); 245 return holder->Next(value_array); 246 } 247 248 249 RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) { 250 HandleScope scope(isolate); 251 DCHECK_EQ(1, args.length()); 252 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); 253 JSWeakCollection::Initialize(weak_collection, isolate); 254 return *weak_collection; 255 } 256 257 258 RUNTIME_FUNCTION(Runtime_WeakCollectionGet) { 259 HandleScope scope(isolate); 260 DCHECK_EQ(3, args.length()); 261 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); 262 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); 263 CONVERT_SMI_ARG_CHECKED(hash, 2) 264 CHECK(key->IsJSReceiver() || key->IsSymbol()); 265 Handle<ObjectHashTable> table( 266 ObjectHashTable::cast(weak_collection->table())); 267 CHECK(table->IsKey(isolate, *key)); 268 Handle<Object> lookup(table->Lookup(key, hash), isolate); 269 return lookup->IsTheHole(isolate) ? isolate->heap()->undefined_value() 270 : *lookup; 271 } 272 273 274 RUNTIME_FUNCTION(Runtime_WeakCollectionHas) { 275 HandleScope scope(isolate); 276 DCHECK_EQ(3, args.length()); 277 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); 278 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); 279 CONVERT_SMI_ARG_CHECKED(hash, 2) 280 CHECK(key->IsJSReceiver() || key->IsSymbol()); 281 Handle<ObjectHashTable> table( 282 ObjectHashTable::cast(weak_collection->table())); 283 CHECK(table->IsKey(isolate, *key)); 284 Handle<Object> lookup(table->Lookup(key, hash), isolate); 285 return isolate->heap()->ToBoolean(!lookup->IsTheHole(isolate)); 286 } 287 288 289 RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { 290 HandleScope scope(isolate); 291 DCHECK_EQ(3, args.length()); 292 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); 293 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); 294 CONVERT_SMI_ARG_CHECKED(hash, 2) 295 CHECK(key->IsJSReceiver() || key->IsSymbol()); 296 Handle<ObjectHashTable> table( 297 ObjectHashTable::cast(weak_collection->table())); 298 CHECK(table->IsKey(isolate, *key)); 299 bool was_present = JSWeakCollection::Delete(weak_collection, key, hash); 300 return isolate->heap()->ToBoolean(was_present); 301 } 302 303 304 RUNTIME_FUNCTION(Runtime_WeakCollectionSet) { 305 HandleScope scope(isolate); 306 DCHECK_EQ(4, args.length()); 307 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); 308 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); 309 CHECK(key->IsJSReceiver() || key->IsSymbol()); 310 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); 311 CONVERT_SMI_ARG_CHECKED(hash, 3) 312 Handle<ObjectHashTable> table( 313 ObjectHashTable::cast(weak_collection->table())); 314 CHECK(table->IsKey(isolate, *key)); 315 JSWeakCollection::Set(weak_collection, key, value, hash); 316 return *weak_collection; 317 } 318 319 320 RUNTIME_FUNCTION(Runtime_GetWeakSetValues) { 321 HandleScope scope(isolate); 322 DCHECK_EQ(2, args.length()); 323 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); 324 CONVERT_NUMBER_CHECKED(int, max_values, Int32, args[1]); 325 CHECK(max_values >= 0); 326 return *JSWeakCollection::GetEntries(holder, max_values); 327 } 328 } // namespace internal 329 } // namespace v8 330