github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/runtime/go-map-range.c (about)

     1  /* go-map-range.c -- implement a range clause over a map.
     2  
     3     Copyright 2009, 2010 The Go Authors. All rights reserved.
     4     Use of this source code is governed by a BSD-style
     5     license that can be found in the LICENSE file.  */
     6  
     7  #include "runtime.h"
     8  #include "go-assert.h"
     9  #include "map.h"
    10  
    11  /* Initialize a range over a map.  */
    12  
    13  void
    14  __go_mapiterinit (const struct __go_map *h, struct __go_hash_iter *it)
    15  {
    16    it->entry = NULL;
    17    if (h != NULL)
    18      {
    19        it->map = h;
    20        it->next_entry = NULL;
    21        it->bucket = 0;
    22        --it->bucket;
    23        __go_mapiternext(it);
    24      }
    25  }
    26  
    27  /* Move to the next iteration, updating *HITER.  */
    28  
    29  void
    30  __go_mapiternext (struct __go_hash_iter *it)
    31  {
    32    const void *entry;
    33  
    34    entry = it->next_entry;
    35    if (entry == NULL)
    36      {
    37        const struct __go_map *map;
    38        uintptr_t bucket;
    39  
    40        map = it->map;
    41        bucket = it->bucket;
    42        while (1)
    43  	{
    44  	  ++bucket;
    45  	  if (bucket >= map->__bucket_count)
    46  	    {
    47  	      /* Map iteration is complete.  */
    48  	      it->entry = NULL;
    49  	      return;
    50  	    }
    51  	  entry = map->__buckets[bucket];
    52  	  if (entry != NULL)
    53  	    break;
    54  	}
    55        it->bucket = bucket;
    56      }
    57    it->entry = entry;
    58    it->next_entry = *(const void * const *) entry;
    59  }
    60  
    61  /* Get the key of the current iteration.  */
    62  
    63  void
    64  __go_mapiter1 (struct __go_hash_iter *it, unsigned char *key)
    65  {
    66    const struct __go_map *map;
    67    const struct __go_map_descriptor *descriptor;
    68    const struct __go_type_descriptor *key_descriptor;
    69    const char *p;
    70  
    71    map = it->map;
    72    descriptor = map->__descriptor;
    73    key_descriptor = descriptor->__map_descriptor->__key_type;
    74    p = it->entry;
    75    __go_assert (p != NULL);
    76    __builtin_memcpy (key, p + descriptor->__key_offset, key_descriptor->__size);
    77  }
    78  
    79  /* Get the key and value of the current iteration.  */
    80  
    81  void
    82  __go_mapiter2 (struct __go_hash_iter *it, unsigned char *key,
    83  	       unsigned char *val)
    84  {
    85    const struct __go_map *map;
    86    const struct __go_map_descriptor *descriptor;
    87    const struct __go_map_type *map_descriptor;
    88    const struct __go_type_descriptor *key_descriptor;
    89    const struct __go_type_descriptor *val_descriptor;
    90    const char *p;
    91  
    92    map = it->map;
    93    descriptor = map->__descriptor;
    94    map_descriptor = descriptor->__map_descriptor;
    95    key_descriptor = map_descriptor->__key_type;
    96    val_descriptor = map_descriptor->__val_type;
    97    p = it->entry;
    98    __go_assert (p != NULL);
    99    __builtin_memcpy (key, p + descriptor->__key_offset,
   100  		    key_descriptor->__size);
   101    __builtin_memcpy (val, p + descriptor->__val_offset,
   102  		    val_descriptor->__size);
   103  }