blob: 32340e5acb78a504a20ffdb84aa60bb57a668aaf [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// 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
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005#include "src/runtime/runtime-utils.h"
6
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007#include "src/arguments.h"
8#include "src/conversions-inl.h"
9#include "src/factory.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010
11namespace v8 {
12namespace internal {
13
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000014
15RUNTIME_FUNCTION(Runtime_StringGetRawHashField) {
16 HandleScope scope(isolate);
17 DCHECK(args.length() == 1);
18 CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
19 return *isolate->factory()->NewNumberFromUint(string->hash_field());
20}
21
22
23RUNTIME_FUNCTION(Runtime_TheHole) {
24 SealHandleScope shs(isolate);
25 DCHECK(args.length() == 0);
26 return isolate->heap()->the_hole_value();
27}
28
29
30RUNTIME_FUNCTION(Runtime_JSCollectionGetTable) {
31 SealHandleScope shs(isolate);
32 DCHECK(args.length() == 1);
33 CONVERT_ARG_CHECKED(JSObject, object, 0);
34 RUNTIME_ASSERT(object->IsJSSet() || object->IsJSMap());
35 return static_cast<JSCollection*>(object)->table();
36}
37
38
39RUNTIME_FUNCTION(Runtime_GenericHash) {
40 HandleScope scope(isolate);
41 DCHECK(args.length() == 1);
42 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
43 Handle<Smi> hash = Object::GetOrCreateHash(isolate, object);
44 return *hash;
45}
46
47
Emily Bernierd0a1eb72015-03-24 16:35:39 -040048RUNTIME_FUNCTION(Runtime_SetInitialize) {
49 HandleScope scope(isolate);
50 DCHECK(args.length() == 1);
51 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000052 JSSet::Initialize(holder, isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040053 return *holder;
54}
55
56
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000057RUNTIME_FUNCTION(Runtime_SetGrow) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040058 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000059 DCHECK(args.length() == 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040060 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040061 Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000062 table = OrderedHashSet::EnsureGrowable(table);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040063 holder->set_table(*table);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064 return isolate->heap()->undefined_value();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040065}
66
67
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068RUNTIME_FUNCTION(Runtime_SetShrink) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040069 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000070 DCHECK(args.length() == 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040071 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040072 Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000073 table = OrderedHashSet::Shrink(table);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040074 holder->set_table(*table);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000075 return isolate->heap()->undefined_value();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040076}
77
78
79RUNTIME_FUNCTION(Runtime_SetClear) {
80 HandleScope scope(isolate);
81 DCHECK(args.length() == 1);
82 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000083 JSSet::Clear(holder);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040084 return isolate->heap()->undefined_value();
85}
86
87
Emily Bernierd0a1eb72015-03-24 16:35:39 -040088RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
89 HandleScope scope(isolate);
90 DCHECK(args.length() == 3);
91 CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
92 CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
93 CONVERT_SMI_ARG_CHECKED(kind, 2)
94 RUNTIME_ASSERT(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::FromInt(0));
99 holder->set_kind(Smi::FromInt(kind));
100 return isolate->heap()->undefined_value();
101}
102
103
104RUNTIME_FUNCTION(Runtime_SetIteratorClone) {
105 HandleScope scope(isolate);
106 DCHECK(args.length() == 1);
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
118RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
119 SealHandleScope shs(isolate);
120 DCHECK(args.length() == 2);
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
131RUNTIME_FUNCTION(Runtime_SetIteratorDetails) {
132 HandleScope scope(isolate);
133 DCHECK(args.length() == 1);
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
143RUNTIME_FUNCTION(Runtime_MapInitialize) {
144 HandleScope scope(isolate);
145 DCHECK(args.length() == 1);
146 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000147 JSMap::Initialize(holder, isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400148 return *holder;
149}
150
151
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000152RUNTIME_FUNCTION(Runtime_MapShrink) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400153 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000154 DCHECK(args.length() == 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400155 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400156 Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000157 table = OrderedHashMap::Shrink(table);
158 holder->set_table(*table);
159 return isolate->heap()->undefined_value();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400160}
161
162
163RUNTIME_FUNCTION(Runtime_MapClear) {
164 HandleScope scope(isolate);
165 DCHECK(args.length() == 1);
166 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000167 JSMap::Clear(holder);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400168 return isolate->heap()->undefined_value();
169}
170
171
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000172RUNTIME_FUNCTION(Runtime_MapGrow) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400173 HandleScope scope(isolate);
174 DCHECK(args.length() == 1);
175 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
176 Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000177 table = OrderedHashMap::EnsureGrowable(table);
178 holder->set_table(*table);
179 return isolate->heap()->undefined_value();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400180}
181
182
183RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
184 HandleScope scope(isolate);
185 DCHECK(args.length() == 3);
186 CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
187 CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
188 CONVERT_SMI_ARG_CHECKED(kind, 2)
189 RUNTIME_ASSERT(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::FromInt(0));
195 holder->set_kind(Smi::FromInt(kind));
196 return isolate->heap()->undefined_value();
197}
198
199
200RUNTIME_FUNCTION(Runtime_MapIteratorClone) {
201 HandleScope scope(isolate);
202 DCHECK(args.length() == 1);
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
218RUNTIME_FUNCTION(Runtime_MapIteratorDetails) {
219 HandleScope scope(isolate);
220 DCHECK(args.length() == 1);
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
230RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) {
231 HandleScope scope(isolate);
232 DCHECK(args.length() == 2);
233 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
234 CONVERT_NUMBER_CHECKED(int, max_entries, Int32, args[1]);
235 RUNTIME_ASSERT(max_entries >= 0);
236
237 Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
238 if (max_entries == 0 || max_entries > table->NumberOfElements()) {
239 max_entries = table->NumberOfElements();
240 }
241 Handle<FixedArray> entries =
242 isolate->factory()->NewFixedArray(max_entries * 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000243 // Allocation can cause GC can delete weak elements. Reload.
244 if (max_entries > table->NumberOfElements()) {
245 max_entries = table->NumberOfElements();
246 }
247
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400248 {
249 DisallowHeapAllocation no_gc;
250 int count = 0;
251 for (int i = 0; count / 2 < max_entries && i < table->Capacity(); i++) {
252 Handle<Object> key(table->KeyAt(i), isolate);
253 if (table->IsKey(*key)) {
254 entries->set(count++, *key);
255 Object* value = table->Lookup(key);
256 entries->set(count++, value);
257 }
258 }
259 DCHECK_EQ(max_entries * 2, count);
260 }
261 return *isolate->factory()->NewJSArrayWithElements(entries);
262}
263
264
265RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
266 SealHandleScope shs(isolate);
267 DCHECK(args.length() == 2);
268 CONVERT_ARG_CHECKED(JSMapIterator, holder, 0);
269 CONVERT_ARG_CHECKED(JSArray, value_array, 1);
270 return holder->Next(value_array);
271}
272
273
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400274RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
275 HandleScope scope(isolate);
276 DCHECK(args.length() == 1);
277 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000278 JSWeakCollection::Initialize(weak_collection, isolate);
279 return *weak_collection;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400280}
281
282
283RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
284 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000285 DCHECK(args.length() == 3);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400286 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
287 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000288 CONVERT_SMI_ARG_CHECKED(hash, 2)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400289 RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
290 Handle<ObjectHashTable> table(
291 ObjectHashTable::cast(weak_collection->table()));
292 RUNTIME_ASSERT(table->IsKey(*key));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000293 Handle<Object> lookup(table->Lookup(key, hash), isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400294 return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
295}
296
297
298RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
299 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000300 DCHECK(args.length() == 3);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400301 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
302 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000303 CONVERT_SMI_ARG_CHECKED(hash, 2)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400304 RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
305 Handle<ObjectHashTable> table(
306 ObjectHashTable::cast(weak_collection->table()));
307 RUNTIME_ASSERT(table->IsKey(*key));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000308 Handle<Object> lookup(table->Lookup(key, hash), isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400309 return isolate->heap()->ToBoolean(!lookup->IsTheHole());
310}
311
312
313RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
314 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000315 DCHECK(args.length() == 3);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400316 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
317 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000318 CONVERT_SMI_ARG_CHECKED(hash, 2)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400319 RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
320 Handle<ObjectHashTable> table(
321 ObjectHashTable::cast(weak_collection->table()));
322 RUNTIME_ASSERT(table->IsKey(*key));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000323 bool was_present = JSWeakCollection::Delete(weak_collection, key, hash);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400324 return isolate->heap()->ToBoolean(was_present);
325}
326
327
328RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
329 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000330 DCHECK(args.length() == 4);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400331 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
332 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
333 RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
334 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000335 CONVERT_SMI_ARG_CHECKED(hash, 3)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400336 Handle<ObjectHashTable> table(
337 ObjectHashTable::cast(weak_collection->table()));
338 RUNTIME_ASSERT(table->IsKey(*key));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000339 JSWeakCollection::Set(weak_collection, key, value, hash);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400340 return *weak_collection;
341}
342
343
344RUNTIME_FUNCTION(Runtime_GetWeakSetValues) {
345 HandleScope scope(isolate);
346 DCHECK(args.length() == 2);
347 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
348 CONVERT_NUMBER_CHECKED(int, max_values, Int32, args[1]);
349 RUNTIME_ASSERT(max_values >= 0);
350
351 Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
352 if (max_values == 0 || max_values > table->NumberOfElements()) {
353 max_values = table->NumberOfElements();
354 }
355 Handle<FixedArray> values = isolate->factory()->NewFixedArray(max_values);
356 // Recompute max_values because GC could have removed elements from the table.
357 if (max_values > table->NumberOfElements()) {
358 max_values = table->NumberOfElements();
359 }
360 {
361 DisallowHeapAllocation no_gc;
362 int count = 0;
363 for (int i = 0; count < max_values && i < table->Capacity(); i++) {
364 Handle<Object> key(table->KeyAt(i), isolate);
365 if (table->IsKey(*key)) values->set(count++, *key);
366 }
367 DCHECK_EQ(max_values, count);
368 }
369 return *isolate->factory()->NewJSArrayWithElements(values);
370}
371
372
373RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
374 HandleScope scope(isolate);
375 DCHECK(args.length() == 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000376 Handle<JSWeakMap> weakmap = isolate->factory()->NewJSWeakMap();
377 JSWeakCollection::Initialize(weakmap, isolate);
378 return *weakmap;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400379}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000380} // namespace internal
381} // namespace v8