@@ -120,7 +120,7 @@ impl<'a> Context<'a> {
120
120
self . symbols . enter ( self . module . root ) ;
121
121
self . links . enter ( self . module . root ) ;
122
122
123
- let hugr_children = self . hugr . children ( self . hugr . entrypoint ( ) ) ;
123
+ let hugr_children = self . hugr . children ( self . hugr . module_root ( ) ) ;
124
124
let mut children = Vec :: with_capacity ( hugr_children. size_hint ( ) . 0 ) ;
125
125
126
126
for child in hugr_children. clone ( ) {
@@ -291,9 +291,11 @@ impl<'a> Context<'a> {
291
291
}
292
292
293
293
OpType :: DFG ( _) => {
294
- regions = self
295
- . bump
296
- . alloc_slice_copy ( & [ self . export_dfg ( node, model:: ScopeClosure :: Open ) ] ) ;
294
+ regions = self . bump . alloc_slice_copy ( & [ self . export_dfg (
295
+ node,
296
+ model:: ScopeClosure :: Open ,
297
+ false ,
298
+ ) ] ) ;
297
299
table:: Operation :: Dfg
298
300
}
299
301
@@ -313,18 +315,22 @@ impl<'a> Context<'a> {
313
315
}
314
316
315
317
OpType :: DataflowBlock ( _) => {
316
- regions = self
317
- . bump
318
- . alloc_slice_copy ( & [ self . export_dfg ( node, model:: ScopeClosure :: Open ) ] ) ;
318
+ regions = self . bump . alloc_slice_copy ( & [ self . export_dfg (
319
+ node,
320
+ model:: ScopeClosure :: Open ,
321
+ false ,
322
+ ) ] ) ;
319
323
table:: Operation :: Block
320
324
}
321
325
322
326
OpType :: FuncDefn ( func) => self . with_local_scope ( node_id, |this| {
323
327
let name = this. get_func_name ( node) . unwrap ( ) ;
324
328
let symbol = this. export_poly_func_type ( name, & func. signature ) ;
325
- regions = this
326
- . bump
327
- . alloc_slice_copy ( & [ this. export_dfg ( node, model:: ScopeClosure :: Closed ) ] ) ;
329
+ regions = this. bump . alloc_slice_copy ( & [ this. export_dfg (
330
+ node,
331
+ model:: ScopeClosure :: Closed ,
332
+ false ,
333
+ ) ] ) ;
328
334
table:: Operation :: DefineFunc ( symbol)
329
335
} ) ,
330
336
@@ -426,9 +432,11 @@ impl<'a> Context<'a> {
426
432
}
427
433
428
434
OpType :: TailLoop ( _) => {
429
- regions = self
430
- . bump
431
- . alloc_slice_copy ( & [ self . export_dfg ( node, model:: ScopeClosure :: Open ) ] ) ;
435
+ regions = self . bump . alloc_slice_copy ( & [ self . export_dfg (
436
+ node,
437
+ model:: ScopeClosure :: Open ,
438
+ false ,
439
+ ) ] ) ;
432
440
table:: Operation :: TailLoop
433
441
}
434
442
@@ -479,7 +487,12 @@ impl<'a> Context<'a> {
479
487
let inputs = self . make_ports ( node, Direction :: Incoming , num_inputs) ;
480
488
let outputs = self . make_ports ( node, Direction :: Outgoing , num_outputs) ;
481
489
482
- let meta = self . export_node_metadata ( node) ;
490
+ let meta = {
491
+ let mut meta = Vec :: new ( ) ;
492
+ self . export_node_json_metadata ( node, & mut meta) ;
493
+ self . export_node_order_metadata ( node, & mut meta) ;
494
+ self . bump . alloc_slice_copy ( & meta)
495
+ } ;
483
496
484
497
self . module . nodes [ node_id. index ( ) ] = table:: Node {
485
498
operation,
@@ -532,7 +545,7 @@ impl<'a> Context<'a> {
532
545
}
533
546
534
547
for ( name, value) in opdef. iter_misc ( ) {
535
- meta. push ( self . export_json_meta ( name, value) ) ;
548
+ meta. push ( self . make_json_meta ( name, value) ) ;
536
549
}
537
550
538
551
self . bump . alloc_slice_copy ( & meta)
@@ -574,7 +587,12 @@ impl<'a> Context<'a> {
574
587
/// Creates a data flow region from the given node's children.
575
588
///
576
589
/// `Input` and `Output` nodes are used to determine the source and target ports of the region.
577
- pub fn export_dfg ( & mut self , node : Node , closure : model:: ScopeClosure ) -> table:: RegionId {
590
+ pub fn export_dfg (
591
+ & mut self ,
592
+ node : Node ,
593
+ closure : model:: ScopeClosure ,
594
+ export_json_meta : bool ,
595
+ ) -> table:: RegionId {
578
596
let region = self . module . insert_region ( table:: Region :: default ( ) ) ;
579
597
580
598
self . symbols . enter ( region) ;
@@ -586,8 +604,14 @@ impl<'a> Context<'a> {
586
604
let mut targets: & [ _ ] = & [ ] ;
587
605
let mut input_types = None ;
588
606
let mut output_types = None ;
607
+
589
608
let mut meta = Vec :: new ( ) ;
590
609
610
+ if export_json_meta {
611
+ self . export_node_json_metadata ( node, & mut meta) ;
612
+ }
613
+ self . export_node_entrypoint_metadata ( node, & mut meta) ;
614
+
591
615
let children = self . hugr . children ( node) ;
592
616
let mut region_children = BumpVec :: with_capacity_in ( children. size_hint ( ) . 0 - 2 , self . bump ) ;
593
617
@@ -672,6 +696,10 @@ impl<'a> Context<'a> {
672
696
let mut source = None ;
673
697
let mut targets: & [ _ ] = & [ ] ;
674
698
699
+ let mut meta = Vec :: new ( ) ;
700
+ self . export_node_json_metadata ( node, & mut meta) ;
701
+ self . export_node_entrypoint_metadata ( node, & mut meta) ;
702
+
675
703
let children = self . hugr . children ( node) ;
676
704
let mut region_children = BumpVec :: with_capacity_in ( children. size_hint ( ) . 0 - 1 , self . bump ) ;
677
705
@@ -728,7 +756,7 @@ impl<'a> Context<'a> {
728
756
sources : self . bump . alloc_slice_copy ( & [ source. unwrap ( ) ] ) ,
729
757
targets,
730
758
children : region_children. into_bump_slice ( ) ,
731
- meta : & [ ] , // TODO: Export metadata
759
+ meta : self . bump . alloc_slice_copy ( & meta ) ,
732
760
signature,
733
761
scope,
734
762
} ;
@@ -746,7 +774,7 @@ impl<'a> Context<'a> {
746
774
panic ! ( "expected a `Case` node as a child of a `Conditional` node" ) ;
747
775
} ;
748
776
749
- regions. push ( self . export_dfg ( child, model:: ScopeClosure :: Open ) ) ;
777
+ regions. push ( self . export_dfg ( child, model:: ScopeClosure :: Open , true ) ) ;
750
778
}
751
779
752
780
regions. into_bump_slice ( )
@@ -1000,7 +1028,7 @@ impl<'a> Context<'a> {
1000
1028
1001
1029
let region = match hugr. entrypoint_optype ( ) {
1002
1030
OpType :: DFG ( _) => {
1003
- self . export_dfg ( hugr. entrypoint ( ) , model:: ScopeClosure :: Closed )
1031
+ self . export_dfg ( hugr. entrypoint ( ) , model:: ScopeClosure :: Closed , true )
1004
1032
}
1005
1033
_ => panic ! ( "Value::Function root must be a DFG" ) ,
1006
1034
} ;
@@ -1031,41 +1059,43 @@ impl<'a> Context<'a> {
1031
1059
}
1032
1060
}
1033
1061
1034
- pub fn export_node_metadata ( & mut self , node : Node ) -> & ' a [ table:: TermId ] {
1062
+ fn export_node_json_metadata ( & mut self , node : Node , meta : & mut Vec < table:: TermId > ) {
1035
1063
let metadata_map = self . hugr . node_metadata_map ( node) ;
1064
+ meta. reserve ( metadata_map. len ( ) ) ;
1036
1065
1037
- let has_order_edges = {
1038
- fn is_relevant_node ( hugr : & Hugr , node : Node ) -> bool {
1039
- let optype = hugr. get_optype ( node) ;
1040
- !optype. is_input ( ) && !optype. is_output ( )
1041
- }
1042
-
1043
- let optype = self . hugr . get_optype ( node) ;
1066
+ for ( name, value) in metadata_map {
1067
+ meta. push ( self . make_json_meta ( name, value) ) ;
1068
+ }
1069
+ }
1044
1070
1045
- Direction :: BOTH
1046
- . iter ( )
1047
- . filter ( |dir| optype. other_port_kind ( * * dir) == Some ( EdgeKind :: StateOrder ) )
1048
- . filter_map ( |dir| optype. other_port ( * dir) )
1049
- . flat_map ( |port| self . hugr . linked_ports ( node, port) )
1050
- . any ( |( other, _) | is_relevant_node ( self . hugr , other) )
1051
- } ;
1071
+ fn export_node_order_metadata ( & mut self , node : Node , meta : & mut Vec < table:: TermId > ) {
1072
+ fn is_relevant_node ( hugr : & Hugr , node : Node ) -> bool {
1073
+ let optype = hugr. get_optype ( node) ;
1074
+ !optype. is_input ( ) && !optype. is_output ( )
1075
+ }
1052
1076
1053
- let meta_capacity = metadata_map. len ( ) + has_order_edges as usize ;
1054
- let mut meta = BumpVec :: with_capacity_in ( meta_capacity, self . bump ) ;
1077
+ let optype = self . hugr . get_optype ( node) ;
1055
1078
1056
- for ( name, value) in metadata_map {
1057
- meta. push ( self . export_json_meta ( name, value) ) ;
1058
- }
1079
+ let has_order_edges = Direction :: BOTH
1080
+ . iter ( )
1081
+ . filter ( |dir| optype. other_port_kind ( * * dir) == Some ( EdgeKind :: StateOrder ) )
1082
+ . filter_map ( |dir| optype. other_port ( * dir) )
1083
+ . flat_map ( |port| self . hugr . linked_ports ( node, port) )
1084
+ . any ( |( other, _) | is_relevant_node ( self . hugr , other) ) ;
1059
1085
1060
1086
if has_order_edges {
1061
1087
let key = self . make_term ( model:: Literal :: Nat ( node. index ( ) as u64 ) . into ( ) ) ;
1062
1088
meta. push ( self . make_term_apply ( model:: ORDER_HINT_KEY , & [ key] ) ) ;
1063
1089
}
1090
+ }
1064
1091
1065
- meta. into_bump_slice ( )
1092
+ fn export_node_entrypoint_metadata ( & mut self , node : Node , meta : & mut Vec < table:: TermId > ) {
1093
+ if self . hugr . entrypoint ( ) == node {
1094
+ meta. push ( self . make_term_apply ( model:: CORE_ENTRYPOINT , & [ ] ) ) ;
1095
+ }
1066
1096
}
1067
1097
1068
- pub fn export_json_meta ( & mut self , name : & str , value : & serde_json:: Value ) -> table:: TermId {
1098
+ pub fn make_json_meta ( & mut self , name : & str , value : & serde_json:: Value ) -> table:: TermId {
1069
1099
let value = serde_json:: to_string ( value) . expect ( "json values are always serializable" ) ;
1070
1100
let value = self . make_term ( model:: Literal :: Str ( value. into ( ) ) . into ( ) ) ;
1071
1101
let name = self . make_term ( model:: Literal :: Str ( name. into ( ) ) . into ( ) ) ;
0 commit comments