1use super::gc::GcoVec;
2use super::instruction::{OpIndex, ValueType};
3use super::objects::{FunctionKey, MetadataKey, MetadataObjs, StructObj, VMObjects};
4use super::value::GosValue;
5use std::cell::RefCell;
6use std::collections::HashMap;
7use std::rc::Rc;
8
9#[macro_export]
10macro_rules! zero_val {
11 ($meta:ident, $objs:expr, $gcv:expr) => {
12 $meta.zero_val(&$objs.metas, $gcv)
13 };
14}
15
16#[derive(PartialEq, Eq, Clone, Debug)]
17pub enum ChannelType {
18 Send,
19 Recv,
20 SendRecv,
21}
22
23#[derive(Debug)]
24pub struct Metadata {
25 pub mbool: GosMetadata,
26 pub mint: GosMetadata,
27 pub mint8: GosMetadata,
28 pub mint16: GosMetadata,
29 pub mint32: GosMetadata,
30 pub mint64: GosMetadata,
31 pub muint: GosMetadata,
32 pub muint8: GosMetadata,
33 pub muint16: GosMetadata,
34 pub muint32: GosMetadata,
35 pub muint64: GosMetadata,
36 pub mfloat32: GosMetadata,
37 pub mfloat64: GosMetadata,
38 pub mcomplex64: GosMetadata,
39 pub mcomplex128: GosMetadata,
40 pub mstr: GosMetadata,
41 pub default_sig: GosMetadata,
42 pub empty_iface: GosMetadata,
43}
44
45impl Metadata {
46 pub fn new(objs: &mut MetadataObjs) -> Metadata {
47 Metadata {
48 mbool: GosMetadata::NonPtr(objs.insert(MetadataType::Bool), MetaCategory::Default),
49 mint: GosMetadata::NonPtr(objs.insert(MetadataType::Int), MetaCategory::Default),
50 mint8: GosMetadata::NonPtr(objs.insert(MetadataType::Int8), MetaCategory::Default),
51 mint16: GosMetadata::NonPtr(objs.insert(MetadataType::Int16), MetaCategory::Default),
52 mint32: GosMetadata::NonPtr(objs.insert(MetadataType::Int32), MetaCategory::Default),
53 mint64: GosMetadata::NonPtr(objs.insert(MetadataType::Int64), MetaCategory::Default),
54 muint: GosMetadata::NonPtr(objs.insert(MetadataType::Uint), MetaCategory::Default),
55 muint8: GosMetadata::NonPtr(objs.insert(MetadataType::Uint8), MetaCategory::Default),
56 muint16: GosMetadata::NonPtr(objs.insert(MetadataType::Uint16), MetaCategory::Default),
57 muint32: GosMetadata::NonPtr(objs.insert(MetadataType::Uint32), MetaCategory::Default),
58 muint64: GosMetadata::NonPtr(objs.insert(MetadataType::Uint64), MetaCategory::Default),
59 mfloat32: GosMetadata::NonPtr(
60 objs.insert(MetadataType::Float32),
61 MetaCategory::Default,
62 ),
63 mfloat64: GosMetadata::NonPtr(
64 objs.insert(MetadataType::Float64),
65 MetaCategory::Default,
66 ),
67 mcomplex64: GosMetadata::NonPtr(
68 objs.insert(MetadataType::Complex64),
69 MetaCategory::Default,
70 ),
71 mcomplex128: GosMetadata::NonPtr(
72 objs.insert(MetadataType::Complex128),
73 MetaCategory::Default,
74 ),
75 mstr: GosMetadata::NonPtr(
76 objs.insert(MetadataType::Str(GosValue::new_str("".to_string()))),
77 MetaCategory::Default,
78 ),
79 default_sig: GosMetadata::NonPtr(
80 objs.insert(MetadataType::Signature(SigMetadata::default())),
81 MetaCategory::Default,
82 ),
83 empty_iface: GosMetadata::NonPtr(
84 objs.insert(MetadataType::Interface(Fields::new(vec![], HashMap::new()))),
85 MetaCategory::Default,
86 ),
87 }
88 }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq)]
92pub enum MetaCategory {
93 Default,
94 Array,
95 Type,
96 ArrayType,
97}
98
99#[derive(Debug, Clone, Copy, PartialEq)]
100pub enum GosMetadata {
101 Untyped,
102 NonPtr(MetadataKey, MetaCategory),
103 Ptr1(MetadataKey, MetaCategory),
104 Ptr2(MetadataKey, MetaCategory),
105 Ptr3(MetadataKey, MetaCategory),
106 Ptr4(MetadataKey, MetaCategory),
107 Ptr5(MetadataKey, MetaCategory),
108 Ptr6(MetadataKey, MetaCategory),
109 Ptr7(MetadataKey, MetaCategory),
110}
111
112impl GosMetadata {
113 #[inline]
114 pub fn new(v: MetadataType, metas: &mut MetadataObjs) -> GosMetadata {
115 GosMetadata::NonPtr(metas.insert(v), MetaCategory::Default)
116 }
117
118 #[inline]
119 pub fn new_array(elem_meta: GosMetadata, size: usize, metas: &mut MetadataObjs) -> GosMetadata {
120 let t = MetadataType::SliceOrArray(elem_meta, size);
121 GosMetadata::NonPtr(metas.insert(t), MetaCategory::Array)
122 }
123
124 #[inline]
125 pub fn new_slice(val_meta: GosMetadata, metas: &mut MetadataObjs) -> GosMetadata {
126 GosMetadata::new(MetadataType::SliceOrArray(val_meta, 0), metas)
127 }
128
129 #[inline]
130 pub fn new_map(
131 kmeta: GosMetadata,
132 vmeta: GosMetadata,
133 metas: &mut MetadataObjs,
134 ) -> GosMetadata {
135 GosMetadata::new(MetadataType::Map(kmeta, vmeta), metas)
136 }
137
138 #[inline]
139 pub fn new_interface(fields: Fields, metas: &mut MetadataObjs) -> GosMetadata {
140 GosMetadata::new(MetadataType::Interface(fields), metas)
141 }
142
143 #[inline]
144 pub fn new_channel(
145 typ: ChannelType,
146 val_meta: GosMetadata,
147 metas: &mut MetadataObjs,
148 ) -> GosMetadata {
149 GosMetadata::new(MetadataType::Channel(typ, val_meta), metas)
150 }
151
152 #[inline]
153 pub fn new_struct(f: Fields, objs: &mut VMObjects, gcv: &mut GcoVec) -> GosMetadata {
154 let field_zeros: Vec<GosValue> = f.fields.iter().map(|x| zero_val!(x, objs, gcv)).collect();
155 let struct_val = StructObj {
156 meta: GosMetadata::Untyped, fields: field_zeros,
158 };
159 let gos_struct = GosValue::new_struct(struct_val, gcv);
160 let key = objs.metas.insert(MetadataType::Struct(f, gos_struct));
161 let gosm = GosMetadata::NonPtr(key, MetaCategory::Default);
162 match &mut objs.metas[key] {
163 MetadataType::Struct(_, v) => match v {
164 GosValue::Struct(s) => s.0.borrow_mut().meta = gosm,
165 _ => unreachable!(),
166 },
167 _ => unreachable!(),
168 }
169 gosm
170 }
171
172 pub fn new_sig(
173 recv: Option<GosMetadata>,
174 params: Vec<GosMetadata>,
175 results: Vec<GosMetadata>,
176 variadic: Option<(GosMetadata, GosMetadata)>,
177 metas: &mut MetadataObjs,
178 ) -> GosMetadata {
179 let ptypes = params.iter().map(|x| x.get_value_type(metas)).collect();
180 let t = MetadataType::Signature(SigMetadata {
181 recv: recv,
182 params: params,
183 results: results,
184 variadic: variadic,
185 params_type: ptypes,
186 });
187 GosMetadata::new(t, metas)
188 }
189
190 pub fn new_named(underlying: GosMetadata, metas: &mut MetadataObjs) -> GosMetadata {
191 debug_assert!(underlying.get_value_type(metas) != ValueType::Named);
192 GosMetadata::new(MetadataType::Named(Methods::new(), underlying), metas)
193 }
194
195 pub fn new_slice_from_array(array: GosMetadata) -> GosMetadata {
196 GosMetadata::NonPtr(array.as_non_ptr(), MetaCategory::Default)
197 }
198
199 #[inline]
200 pub fn ptr_to(&self) -> GosMetadata {
201 match self {
202 GosMetadata::Untyped => {
203 unreachable!() }
205 GosMetadata::NonPtr(k, t) => GosMetadata::Ptr1(*k, *t),
206 GosMetadata::Ptr1(k, t) => GosMetadata::Ptr2(*k, *t),
207 GosMetadata::Ptr2(k, t) => GosMetadata::Ptr3(*k, *t),
208 GosMetadata::Ptr3(k, t) => GosMetadata::Ptr4(*k, *t),
209 GosMetadata::Ptr4(k, t) => GosMetadata::Ptr5(*k, *t),
210 GosMetadata::Ptr5(k, t) => GosMetadata::Ptr6(*k, *t),
211 GosMetadata::Ptr6(k, t) => GosMetadata::Ptr7(*k, *t),
212 GosMetadata::Ptr7(_, _) => {
213 unreachable!() }
215 }
216 }
217
218 #[inline]
219 pub fn unptr_to(&self) -> GosMetadata {
220 match self {
221 GosMetadata::Untyped => {
222 unreachable!() }
224 GosMetadata::NonPtr(_, _) => {
225 unreachable!() }
227 GosMetadata::Ptr1(k, t) => GosMetadata::NonPtr(*k, *t),
228 GosMetadata::Ptr2(k, t) => GosMetadata::Ptr1(*k, *t),
229 GosMetadata::Ptr3(k, t) => GosMetadata::Ptr2(*k, *t),
230 GosMetadata::Ptr4(k, t) => GosMetadata::Ptr3(*k, *t),
231 GosMetadata::Ptr5(k, t) => GosMetadata::Ptr4(*k, *t),
232 GosMetadata::Ptr6(k, t) => GosMetadata::Ptr5(*k, *t),
233 GosMetadata::Ptr7(k, t) => GosMetadata::Ptr6(*k, *t),
234 }
235 }
236
237 #[inline]
239 pub fn as_non_ptr(&self) -> MetadataKey {
240 match self {
241 GosMetadata::NonPtr(k, _) => *k,
242 _ => unreachable!(),
243 }
244 }
245
246 #[inline]
248 pub fn unwrap_non_ptr(&self) -> (MetadataKey, MetaCategory) {
249 match self {
250 GosMetadata::NonPtr(k, mc) => (*k, *mc),
251 _ => unreachable!(),
252 }
253 }
254
255 #[inline]
256 pub fn into_type_category(self) -> GosMetadata {
257 let convert = |c| match c {
258 MetaCategory::Default => MetaCategory::Type,
259 MetaCategory::Array => MetaCategory::ArrayType,
260 _ => c,
261 };
262 match self {
263 GosMetadata::NonPtr(k, c) => GosMetadata::NonPtr(k, convert(c)),
264 GosMetadata::Ptr1(k, c) => GosMetadata::Ptr1(k, convert(c)),
265 GosMetadata::Ptr2(k, c) => GosMetadata::Ptr2(k, convert(c)),
266 GosMetadata::Ptr3(k, c) => GosMetadata::Ptr3(k, convert(c)),
267 GosMetadata::Ptr4(k, c) => GosMetadata::Ptr4(k, convert(c)),
268 GosMetadata::Ptr5(k, c) => GosMetadata::Ptr5(k, convert(c)),
269 GosMetadata::Ptr6(k, c) => GosMetadata::Ptr6(k, convert(c)),
270 GosMetadata::Ptr7(k, c) => GosMetadata::Ptr7(k, convert(c)),
271 GosMetadata::Untyped => {
272 unreachable!() }
274 }
275 }
276
277 #[inline]
278 pub fn get_value_type(&self, metas: &MetadataObjs) -> ValueType {
279 match self {
280 GosMetadata::NonPtr(k, mc) => match mc {
281 MetaCategory::Default => match &metas[*k] {
282 MetadataType::Bool => ValueType::Bool,
283 MetadataType::Int => ValueType::Int,
284 MetadataType::Int8 => ValueType::Int8,
285 MetadataType::Int16 => ValueType::Int16,
286 MetadataType::Int32 => ValueType::Int32,
287 MetadataType::Int64 => ValueType::Int64,
288 MetadataType::Uint => ValueType::Uint,
289 MetadataType::Uint8 => ValueType::Uint8,
290 MetadataType::Uint16 => ValueType::Uint16,
291 MetadataType::Uint32 => ValueType::Uint32,
292 MetadataType::Uint64 => ValueType::Uint64,
293 MetadataType::Float32 => ValueType::Float32,
294 MetadataType::Float64 => ValueType::Float64,
295 MetadataType::Complex64 => ValueType::Complex64,
296 MetadataType::Complex128 => ValueType::Complex128,
297 MetadataType::Str(_) => ValueType::Str,
298 MetadataType::Struct(_, _) => ValueType::Struct,
299 MetadataType::Signature(_) => ValueType::Closure,
300 MetadataType::SliceOrArray(_, _) => ValueType::Slice,
301 MetadataType::Map(_, _) => ValueType::Map,
302 MetadataType::Interface(_) => ValueType::Interface,
303 MetadataType::Channel(_, _) => ValueType::Channel,
304 MetadataType::Named(_, _) => ValueType::Named,
305 },
306 MetaCategory::Type | MetaCategory::ArrayType => ValueType::Metadata,
307 MetaCategory::Array => ValueType::Array,
308 },
309 GosMetadata::Untyped => {
310 unreachable!() }
312 _ => ValueType::Pointer,
313 }
314 }
315
316 #[inline]
317 pub fn zero_val(&self, mobjs: &MetadataObjs, gcos: &GcoVec) -> GosValue {
318 self.zero_val_impl(mobjs, gcos)
319 }
320
321 #[inline]
322 fn zero_val_impl(&self, mobjs: &MetadataObjs, gcos: &GcoVec) -> GosValue {
323 match &self {
324 GosMetadata::Untyped => GosValue::Nil(*self),
325 GosMetadata::NonPtr(k, mc) => match &mobjs[*k] {
326 MetadataType::Bool => GosValue::Bool(false),
327 MetadataType::Int => GosValue::Int(0),
328 MetadataType::Int8 => GosValue::Int8(0),
329 MetadataType::Int16 => GosValue::Int16(0),
330 MetadataType::Int32 => GosValue::Int32(0),
331 MetadataType::Int64 => GosValue::Int64(0),
332 MetadataType::Uint => GosValue::Uint(0),
333 MetadataType::Uint8 => GosValue::Uint8(0),
334 MetadataType::Uint16 => GosValue::Uint16(0),
335 MetadataType::Uint32 => GosValue::Uint32(0),
336 MetadataType::Uint64 => GosValue::Uint64(0),
337 MetadataType::Float32 => GosValue::Float32(0.0.into()),
338 MetadataType::Float64 => GosValue::Float64(0.0.into()),
339 MetadataType::Complex64 => GosValue::Complex64(0.0.into(), 0.0.into()),
340 MetadataType::Complex128 => {
341 GosValue::Complex128(Box::new((0.0.into(), 0.0.into())))
342 }
343 MetadataType::Str(s) => s.clone(),
344 MetadataType::SliceOrArray(m, size) => match mc {
345 MetaCategory::Array => {
346 let val = m.default_val(mobjs, gcos);
347 GosValue::array_with_size(*size, &val, *self, gcos)
348 }
349 MetaCategory::Default => GosValue::new_slice_nil(*self, gcos),
350 _ => unreachable!(),
351 },
352 MetadataType::Struct(_, s) => s.copy_semantic(gcos),
353 MetadataType::Signature(_) => GosValue::Nil(*self),
354 MetadataType::Map(_, v) => {
355 GosValue::new_map_nil(*self, v.default_val(mobjs, gcos), gcos)
356 }
357 MetadataType::Interface(_) => GosValue::Nil(*self),
358 MetadataType::Channel(_, _) => GosValue::Nil(*self),
359 MetadataType::Named(_, gm) => {
360 let val = gm.default_val(mobjs, gcos);
361 GosValue::Named(Box::new((val, *gm)))
362 }
363 },
364 _ => GosValue::Nil(*self),
365 }
366 }
367
368 #[inline]
369 pub fn default_val(&self, mobjs: &MetadataObjs, gcos: &GcoVec) -> GosValue {
370 match &self {
371 GosMetadata::NonPtr(k, mc) => match &mobjs[*k] {
372 MetadataType::Bool => GosValue::Bool(false),
373 MetadataType::Int => GosValue::Int(0),
374 MetadataType::Int8 => GosValue::Int8(0),
375 MetadataType::Int16 => GosValue::Int16(0),
376 MetadataType::Int32 => GosValue::Int32(0),
377 MetadataType::Int64 => GosValue::Int64(0),
378 MetadataType::Uint => GosValue::Uint(0),
379 MetadataType::Uint8 => GosValue::Uint8(0),
380 MetadataType::Uint16 => GosValue::Uint16(0),
381 MetadataType::Uint32 => GosValue::Uint32(0),
382 MetadataType::Uint64 => GosValue::Uint64(0),
383 MetadataType::Float32 => GosValue::Float32(0.0.into()),
384 MetadataType::Float64 => GosValue::Float64(0.0.into()),
385 MetadataType::Complex64 => GosValue::Complex64(0.0.into(), 0.0.into()),
386 MetadataType::Complex128 => {
387 GosValue::Complex128(Box::new((0.0.into(), 0.0.into())))
388 }
389 MetadataType::Str(s) => s.clone(),
390 MetadataType::SliceOrArray(m, size) => match mc {
391 MetaCategory::Array => {
392 let val = m.default_val(mobjs, gcos);
393 GosValue::array_with_size(*size, &val, *self, gcos)
394 }
395 MetaCategory::Default => GosValue::new_slice(0, 0, *self, None, gcos),
396 _ => unreachable!(),
397 },
398 MetadataType::Struct(_, s) => s.copy_semantic(gcos),
399 MetadataType::Signature(_) => GosValue::Nil(*self),
400 MetadataType::Map(_, v) => {
401 GosValue::new_map(*self, v.default_val(mobjs, gcos), gcos)
402 }
403 MetadataType::Interface(_) => GosValue::Nil(*self),
404 MetadataType::Channel(_, _) => GosValue::Nil(*self),
405 MetadataType::Named(_, gm) => {
406 let val = gm.default_val(mobjs, gcos);
407 GosValue::Named(Box::new((val, *gm)))
408 }
409 },
410 _ => unreachable!(),
411 }
412 }
413
414 #[inline]
415 pub fn field_index(&self, name: &str, metas: &MetadataObjs) -> OpIndex {
416 let key = self.recv_meta_key();
417 match &metas[GosMetadata::NonPtr(key, MetaCategory::Default)
418 .get_underlying(metas)
419 .as_non_ptr()]
420 {
421 MetadataType::Struct(m, _) => m.mapping[name] as OpIndex,
422 _ => unreachable!(),
423 }
424 }
425
426 #[inline]
427 pub fn get_underlying(&self, metas: &MetadataObjs) -> GosMetadata {
428 match self {
429 GosMetadata::NonPtr(k, _) => match &metas[*k] {
430 MetadataType::Named(_, u) => *u,
431 _ => *self,
432 },
433 _ => *self,
434 }
435 }
436
437 #[inline]
438 pub fn recv_meta_key(&self) -> MetadataKey {
439 match self {
440 GosMetadata::NonPtr(k, _) => *k,
441 GosMetadata::Ptr1(k, _) => *k,
442 _ => unreachable!(),
443 }
444 }
445
446 pub fn add_method(&self, name: String, pointer_recv: bool, metas: &mut MetadataObjs) {
447 let k = self.recv_meta_key();
448 match &mut metas[k] {
449 MetadataType::Named(m, _) => {
450 m.members.push(Rc::new(RefCell::new(MethodDesc {
451 pointer_recv: pointer_recv,
452 func: None,
453 })));
454 m.mapping.insert(name, m.members.len() as OpIndex - 1);
455 }
456 _ => unreachable!(),
457 }
458 }
459
460 pub fn set_method_code(&self, name: &String, func: FunctionKey, metas: &mut MetadataObjs) {
461 let k = self.recv_meta_key();
462 match &mut metas[k] {
463 MetadataType::Named(m, _) => {
464 let index = m.mapping[name] as usize;
465 m.members[index].borrow_mut().func = Some(func);
466 }
467 _ => unreachable!(),
468 }
469 }
470
471 #[inline]
472 pub fn get_named_metadate<'a>(
473 &self,
474 metas: &'a MetadataObjs,
475 ) -> (&'a Methods, &'a GosMetadata) {
476 let k = self.recv_meta_key();
477 match &metas[k] {
478 MetadataType::Named(methods, md) => (methods, md),
479 _ => unreachable!(),
480 }
481 }
482
483 #[inline]
484 pub fn get_method(&self, index: OpIndex, metas: &MetadataObjs) -> Rc<RefCell<MethodDesc>> {
485 let (m, _) = self.get_named_metadate(metas);
486 m.members[index as usize].clone()
487 }
488
489 #[inline]
491 pub fn method_index(&self, name: &str, metas: &MetadataObjs) -> OpIndex {
492 let (m, _) = self.get_named_metadate(metas);
493 m.mapping[name] as OpIndex
494 }
495
496 #[inline]
498 pub fn iface_method_index(&self, name: &str, metas: &MetadataObjs) -> OpIndex {
499 let (_, under) = self.get_named_metadate(metas);
500 if let MetadataType::Interface(m) = &metas[under.as_non_ptr()] {
501 m.mapping[name] as OpIndex
502 } else {
503 unreachable!()
504 }
505 }
506
507 pub fn semantic_eq(&self, other: &Self, metas: &MetadataObjs) -> bool {
508 match (self, other) {
509 (Self::NonPtr(ak, ac), Self::NonPtr(bk, bc)) => {
510 Self::semantic_eq_impl(ak, ac, bk, bc, metas)
511 }
512 (Self::Ptr1(ak, ac), Self::Ptr1(bk, bc)) => {
513 Self::semantic_eq_impl(ak, ac, bk, bc, metas)
514 }
515 (Self::Ptr2(ak, ac), Self::Ptr2(bk, bc)) => {
516 Self::semantic_eq_impl(ak, ac, bk, bc, metas)
517 }
518 (Self::Ptr3(ak, ac), Self::Ptr3(bk, bc)) => {
519 Self::semantic_eq_impl(ak, ac, bk, bc, metas)
520 }
521 (Self::Ptr4(ak, ac), Self::Ptr4(bk, bc)) => {
522 Self::semantic_eq_impl(ak, ac, bk, bc, metas)
523 }
524 (Self::Ptr5(ak, ac), Self::Ptr5(bk, bc)) => {
525 Self::semantic_eq_impl(ak, ac, bk, bc, metas)
526 }
527 (Self::Ptr6(ak, ac), Self::Ptr6(bk, bc)) => {
528 Self::semantic_eq_impl(ak, ac, bk, bc, metas)
529 }
530 (Self::Ptr7(ak, ac), Self::Ptr7(bk, bc)) => {
531 Self::semantic_eq_impl(ak, ac, bk, bc, metas)
532 }
533 (Self::Untyped, Self::Untyped) => true,
534 _ => false,
535 }
536 }
537
538 #[inline]
539 fn semantic_eq_impl(
540 ak: &MetadataKey,
541 ac: &MetaCategory,
542 bk: &MetadataKey,
543 bc: &MetaCategory,
544 metas: &MetadataObjs,
545 ) -> bool {
546 (ac == bc) && ((ak == bk) || metas[*ak].semantic_eq(&metas[*bk], *ac, metas))
547 }
548}
549
550#[derive(Debug, Clone)]
551pub struct Fields {
552 pub fields: Vec<GosMetadata>,
553 pub mapping: HashMap<String, OpIndex>,
554}
555
556impl Fields {
557 #[inline]
558 pub fn new(fields: Vec<GosMetadata>, mapping: HashMap<String, OpIndex>) -> Fields {
559 Fields {
560 fields: fields,
561 mapping: mapping,
562 }
563 }
564
565 #[inline]
566 pub fn iface_named_mapping(&self, named_obj: &Methods) -> Vec<Rc<RefCell<MethodDesc>>> {
567 let default = Rc::new(RefCell::new(MethodDesc {
568 pointer_recv: false,
569 func: None,
570 }));
571 let mut result = vec![default; self.fields.len()];
572 for (n, i) in self.mapping.iter() {
573 let f = &named_obj.members[named_obj.mapping[n] as usize];
574 result[*i as usize] = f.clone();
575 }
576 result
577 }
578
579 pub fn iface_ffi_info(&self) -> Vec<(String, GosMetadata)> {
580 let mut ret = vec![];
581 for f in self.fields.iter() {
582 ret.push((String::new(), *f));
583 }
584 for (name, index) in self.mapping.iter() {
585 ret[*index as usize].0 = name.clone();
586 }
587 ret
588 }
589
590 pub fn semantic_eq(&self, other: &Self, metas: &MetadataObjs) -> bool {
591 if self.fields.len() != other.fields.len() {
592 return false;
593 }
594 for (i, f) in self.fields.iter().enumerate() {
595 if !f.semantic_eq(&other.fields[i], metas) {
596 return false;
597 }
598 }
599 true
600 }
601}
602
603#[derive(Debug, Clone)]
604pub struct MethodDesc {
605 pub pointer_recv: bool,
606 pub func: Option<FunctionKey>,
607}
608
609#[derive(Debug, Clone)]
610pub struct Methods {
611 pub members: Vec<Rc<RefCell<MethodDesc>>>,
612 pub mapping: HashMap<String, OpIndex>,
613}
614
615impl Methods {
616 pub fn new() -> Methods {
617 Methods {
618 members: vec![],
619 mapping: HashMap::new(),
620 }
621 }
622}
623
624#[derive(Debug, Clone)]
625pub struct SigMetadata {
626 pub recv: Option<GosMetadata>,
627 pub params: Vec<GosMetadata>,
628 pub results: Vec<GosMetadata>,
629 pub variadic: Option<(GosMetadata, GosMetadata)>,
630 pub params_type: Vec<ValueType>, }
632
633impl Default for SigMetadata {
634 fn default() -> SigMetadata {
635 Self {
636 recv: None,
637 params: vec![],
638 results: vec![],
639 variadic: None,
640 params_type: vec![],
641 }
642 }
643}
644
645impl SigMetadata {
646 pub fn pointer_recv(&self) -> bool {
647 if let Some(r) = &self.recv {
648 match r {
649 GosMetadata::NonPtr(_, _) => false,
650 _ => true,
651 }
652 } else {
653 false
654 }
655 }
656
657 pub fn semantic_eq(&self, other: &Self, metas: &MetadataObjs) -> bool {
658 if !match (&self.recv, &other.recv) {
659 (None, None) => true,
660 (Some(a), Some(b)) => a.semantic_eq(b, metas),
661 _ => false,
662 } {
663 return false;
664 }
665
666 if self.params.len() != other.params.len() {
667 return false;
668 }
669 for (i, p) in self.params.iter().enumerate() {
670 if !p.semantic_eq(&other.params[i], metas) {
671 return false;
672 }
673 }
674
675 if self.results.len() != other.params.len() {
676 return false;
677 }
678 for (i, r) in self.results.iter().enumerate() {
679 if !r.semantic_eq(&other.results[i], metas) {
680 return false;
681 }
682 }
683 if !match (&self.variadic, &other.variadic) {
684 (None, None) => true,
685 (Some((a, _)), Some((b, _))) => a.semantic_eq(b, metas),
686 _ => false,
687 } {
688 return false;
689 }
690 true
691 }
692}
693
694#[derive(Debug, Clone)]
695pub enum MetadataType {
696 Bool,
697 Int,
698 Int8,
699 Int16,
700 Int32,
701 Int64,
702 Uint,
703 Uint8,
704 Uint16,
705 Uint32,
706 Uint64,
707 Float32,
708 Float64,
709 Complex64,
710 Complex128,
711 Str(GosValue),
712 SliceOrArray(GosMetadata, usize),
713 Struct(Fields, GosValue),
714 Signature(SigMetadata),
715 Map(GosMetadata, GosMetadata),
716 Interface(Fields),
717 Channel(ChannelType, GosMetadata),
718 Named(Methods, GosMetadata),
719}
720
721impl MetadataType {
722 #[inline]
723 pub fn as_signature(&self) -> &SigMetadata {
724 match self {
725 Self::Signature(s) => s,
726 _ => unreachable!(),
727 }
728 }
729
730 #[inline]
731 pub fn as_interface(&self) -> &Fields {
732 match self {
733 Self::Interface(fields) => fields,
734 _ => unreachable!(),
735 }
736 }
737
738 #[inline]
739 pub fn as_channel(&self) -> (&ChannelType, &GosMetadata) {
740 match self {
741 Self::Channel(t, m) => (t, m),
742 _ => unreachable!(),
743 }
744 }
745
746 pub fn semantic_eq(&self, other: &Self, mc: MetaCategory, metas: &MetadataObjs) -> bool {
747 match (self, other) {
748 (Self::Bool, Self::Bool) => true,
749 (Self::Int, Self::Int) => true,
750 (Self::Int8, Self::Int8) => true,
751 (Self::Int16, Self::Int16) => true,
752 (Self::Int32, Self::Int32) => true,
753 (Self::Int64, Self::Int64) => true,
754 (Self::Uint8, Self::Uint8) => true,
755 (Self::Uint16, Self::Uint16) => true,
756 (Self::Uint32, Self::Uint32) => true,
757 (Self::Uint64, Self::Uint64) => true,
758 (Self::Float32, Self::Float32) => true,
759 (Self::Float64, Self::Float64) => true,
760 (Self::Complex64, Self::Complex64) => true,
761 (Self::Complex128, Self::Complex128) => true,
762 (Self::Str(_), Self::Str(_)) => true,
763 (Self::Struct(a, _), Self::Struct(b, _)) => a.semantic_eq(b, metas),
764 (Self::Signature(a), Self::Signature(b)) => a.semantic_eq(b, metas),
765 (Self::SliceOrArray(a, size_a), Self::SliceOrArray(b, size_b)) => {
766 match mc {
767 MetaCategory::Array | MetaCategory::ArrayType => {
768 if size_a != size_b {
769 return false;
770 }
771 }
772 _ => {}
773 }
774 a.semantic_eq(b, metas)
775 }
776 (Self::Map(ak, av), Self::Map(bk, bv)) => {
777 ak.semantic_eq(bk, metas) && av.semantic_eq(bv, metas)
778 }
779 (Self::Interface(a), Self::Interface(b)) => a.semantic_eq(b, metas),
780 (Self::Channel(at, avt), Self::Channel(bt, bvt)) => {
781 at == bt && avt.semantic_eq(bvt, metas)
782 }
783 (Self::Named(_, a), Self::Named(_, b)) => a.semantic_eq(b, metas),
784 _ => false,
785 }
786 }
787}