OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [runtime/] [go-convert-interface.c] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
/* go-convert-interface.c -- convert interfaces for Go.
2
 
3
   Copyright 2009 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 "go-alloc.h"
8
#include "go-assert.h"
9
#include "go-panic.h"
10
#include "interface.h"
11
 
12
/* This is called when converting one interface type into another
13
   interface type.  LHS_DESCRIPTOR is the type descriptor of the
14
   resulting interface.  RHS_DESCRIPTOR is the type descriptor of the
15
   object being converted.  This builds and returns a new interface
16
   method table.  If any method in the LHS_DESCRIPTOR interface is not
17
   implemented by the object, the conversion fails.  If the conversion
18
   fails, then if MAY_FAIL is true this returns NULL; otherwise, it
19
   panics.  */
20
 
21
void *
22
__go_convert_interface_2 (const struct __go_type_descriptor *lhs_descriptor,
23
                          const struct __go_type_descriptor *rhs_descriptor,
24
                          _Bool may_fail)
25
{
26
  const struct __go_interface_type *lhs_interface;
27
  int lhs_method_count;
28
  const struct __go_interface_method* lhs_methods;
29
  const void **methods;
30
  const struct __go_uncommon_type *rhs_uncommon;
31
  int rhs_method_count;
32
  const struct __go_method *p_rhs_method;
33
  int i;
34
 
35
  if (rhs_descriptor == NULL)
36
    {
37
      /* A nil value always converts to nil.  */
38
      return NULL;
39
    }
40
 
41
  __go_assert (lhs_descriptor->__code == GO_INTERFACE);
42
  lhs_interface = (const struct __go_interface_type *) lhs_descriptor;
43
  lhs_method_count = lhs_interface->__methods.__count;
44
  lhs_methods = ((const struct __go_interface_method *)
45
                 lhs_interface->__methods.__values);
46
 
47
  /* This should not be called for an empty interface.  */
48
  __go_assert (lhs_method_count > 0);
49
 
50
  rhs_uncommon = rhs_descriptor->__uncommon;
51
  if (rhs_uncommon == NULL || rhs_uncommon->__methods.__count == 0)
52
    {
53
      struct __go_empty_interface panic_arg;
54
 
55
      if (may_fail)
56
        return NULL;
57
 
58
      newTypeAssertionError (NULL,
59
                             rhs_descriptor,
60
                             lhs_descriptor,
61
                             NULL,
62
                             rhs_descriptor->__reflection,
63
                             lhs_descriptor->__reflection,
64
                             lhs_methods[0].__name,
65
                             &panic_arg);
66
      __go_panic (panic_arg);
67
    }
68
 
69
  rhs_method_count = rhs_uncommon->__methods.__count;
70
  p_rhs_method = ((const struct __go_method *)
71
                  rhs_uncommon->__methods.__values);
72
 
73
  methods = NULL;
74
 
75
  for (i = 0; i < lhs_method_count; ++i)
76
    {
77
      const struct __go_interface_method *p_lhs_method;
78
 
79
      p_lhs_method = &lhs_methods[i];
80
 
81
      while (rhs_method_count > 0
82
             && (!__go_ptr_strings_equal (p_lhs_method->__name,
83
                                          p_rhs_method->__name)
84
                 || !__go_ptr_strings_equal (p_lhs_method->__pkg_path,
85
                                             p_rhs_method->__pkg_path)))
86
        {
87
          ++p_rhs_method;
88
          --rhs_method_count;
89
        }
90
 
91
      if (rhs_method_count == 0
92
          || !__go_type_descriptors_equal (p_lhs_method->__type,
93
                                           p_rhs_method->__mtype))
94
        {
95
          struct __go_empty_interface panic_arg;
96
 
97
          if (methods != NULL)
98
            __go_free (methods);
99
 
100
          if (may_fail)
101
            return NULL;
102
 
103
          newTypeAssertionError (NULL,
104
                                 rhs_descriptor,
105
                                 lhs_descriptor,
106
                                 NULL,
107
                                 rhs_descriptor->__reflection,
108
                                 lhs_descriptor->__reflection,
109
                                 p_lhs_method->__name,
110
                                 &panic_arg);
111
          __go_panic (panic_arg);
112
        }
113
 
114
      if (methods == NULL)
115
        {
116
          methods = (const void **) __go_alloc ((lhs_method_count + 1)
117
                                                * sizeof (void *));
118
 
119
          /* The first field in the method table is always the type of
120
             the object.  */
121
          methods[0] = rhs_descriptor;
122
        }
123
 
124
      methods[i + 1] = p_rhs_method->__function;
125
    }
126
 
127
  return methods;
128
}
129
 
130
/* This is called by the compiler to convert a value from one
131
   interface type to another.  */
132
 
133
void *
134
__go_convert_interface (const struct __go_type_descriptor *lhs_descriptor,
135
                        const struct __go_type_descriptor *rhs_descriptor)
136
{
137
  return __go_convert_interface_2 (lhs_descriptor, rhs_descriptor, 0);
138
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.