Home | History | Annotate | Download | only in runtime
      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