| ... | ... | @@ -655,6 +655,28 @@ const DocData = struct { |
| 655 | 655 | sizeOf: usize, // index in `exprs` |
| 656 | 656 | compileError: []const u8, |
| 657 | 657 | string: []const u8, // direct value |
| 658 | // Index a `type` like struct with expressions |
| 659 | // it's necessary because when a caller ask by a binOp maybe there are |
| 660 | // more binary op inside them, so the caller get's the current `exprs` index |
| 661 | // and the binOp can walk the tree preserving the first index of the tree |
| 662 | // for examples see `.mul` and `analyzeFunctionExtended` in `has_align` section |
| 663 | binOp: BinOp, |
| 664 | binOpIndex: usize, |
| 665 | const BinOp = struct { |
| 666 | lhs: usize, // index in `exprs` |
| 667 | rhs: usize, // index in `exprs` |
| 668 | // opKind |
| 669 | // Identify the operator in js |
| 670 | // 0: add, 1: sub, 2: mul, 3: div, 4: mod, 5: rem, 6: shl, 7: shr, 8: bitwise_and, 9: bitwise_or |
| 671 | // Others binOp are not handled yet |
| 672 | opKind: usize = 0, |
| 673 | // flags to operations |
| 674 | wrap: bool = false, |
| 675 | sat: bool = false, |
| 676 | exact: bool = false, |
| 677 | floor: bool = false, |
| 678 | trunc: bool = false, |
| 679 | }; |
| 658 | 680 | const As = struct { |
| 659 | 681 | typeRefArg: ?usize, // index in `exprs` |
| 660 | 682 | exprArg: usize, // index in `exprs` |
| ... | ... | @@ -701,7 +723,11 @@ const DocData = struct { |
| 701 | 723 | \\{{ "bool":{} }} |
| 702 | 724 | , .{v}); |
| 703 | 725 | }, |
| 704 | | .sizeOf => |v| try std.json.stringify(v, options, w), |
| 726 | .sizeOf => |v| { |
| 727 | try w.print( |
| 728 | \\{{ "sizeOf":{} }} |
| 729 | , .{v}); |
| 730 | }, |
| 705 | 731 | .fieldRef => |v| try std.json.stringify( |
| 706 | 732 | struct { fieldRef: FieldRef }{ .fieldRef = v }, |
| 707 | 733 | options, |
| ... | ... | @@ -725,6 +751,16 @@ const DocData = struct { |
| 725 | 751 | try w.print("{s}", .{comma}); |
| 726 | 752 | } |
| 727 | 753 | }, |
| 754 | .binOp => |v| try std.json.stringify( |
| 755 | struct { binOp: BinOp }{ .binOp = v }, |
| 756 | options, |
| 757 | w, |
| 758 | ), |
| 759 | .binOpIndex => |v| try std.json.stringify( |
| 760 | struct { binOpIndex: usize }{ .binOpIndex = v }, |
| 761 | options, |
| 762 | w, |
| 763 | ), |
| 728 | 764 | .typeOf_peer => |v| try std.json.stringify( |
| 729 | 765 | struct { typeOf_peer: []usize }{ .typeOf_peer = v }, |
| 730 | 766 | options, |
| ... | ... | @@ -931,6 +967,381 @@ fn walkInstruction( |
| 931 | 967 | .expr = .{ .int = .{ .value = int } }, |
| 932 | 968 | }; |
| 933 | 969 | }, |
| 970 | .add => { |
| 971 | const pl_node = data[inst_index].pl_node; |
| 972 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| 973 | |
| 974 | const binop_index = self.exprs.items.len; |
| 975 | try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); |
| 976 | |
| 977 | var lhs: DocData.WalkResult = try self.walkRef( |
| 978 | file, |
| 979 | parent_scope, |
| 980 | extra.data.lhs, |
| 981 | false, |
| 982 | ); |
| 983 | var rhs: DocData.WalkResult = try self.walkRef( |
| 984 | file, |
| 985 | parent_scope, |
| 986 | extra.data.rhs, |
| 987 | false, |
| 988 | ); |
| 989 | |
| 990 | const lhs_index = self.exprs.items.len; |
| 991 | try self.exprs.append(self.arena, lhs.expr); |
| 992 | const rhs_index = self.exprs.items.len; |
| 993 | try self.exprs.append(self.arena, rhs.expr); |
| 994 | self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .opKind = 0 } }; |
| 995 | |
| 996 | return DocData.WalkResult{ |
| 997 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 998 | .expr = .{ .binOpIndex = binop_index }, |
| 999 | }; |
| 1000 | }, |
| 1001 | .addwrap => { |
| 1002 | const pl_node = data[inst_index].pl_node; |
| 1003 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| 1004 | |
| 1005 | const binop_index = self.exprs.items.len; |
| 1006 | try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); |
| 1007 | |
| 1008 | var lhs: DocData.WalkResult = try self.walkRef( |
| 1009 | file, |
| 1010 | parent_scope, |
| 1011 | extra.data.lhs, |
| 1012 | false, |
| 1013 | ); |
| 1014 | var rhs: DocData.WalkResult = try self.walkRef( |
| 1015 | file, |
| 1016 | parent_scope, |
| 1017 | extra.data.rhs, |
| 1018 | false, |
| 1019 | ); |
| 1020 | |
| 1021 | const lhs_index = self.exprs.items.len; |
| 1022 | try self.exprs.append(self.arena, lhs.expr); |
| 1023 | const rhs_index = self.exprs.items.len; |
| 1024 | try self.exprs.append(self.arena, rhs.expr); |
| 1025 | self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .wrap = true, .opKind = 0 } }; |
| 1026 | |
| 1027 | return DocData.WalkResult{ |
| 1028 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 1029 | .expr = .{ .binOpIndex = binop_index }, |
| 1030 | }; |
| 1031 | }, |
| 1032 | .add_sat => { |
| 1033 | const pl_node = data[inst_index].pl_node; |
| 1034 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| 1035 | |
| 1036 | const binop_index = self.exprs.items.len; |
| 1037 | try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); |
| 1038 | |
| 1039 | var lhs: DocData.WalkResult = try self.walkRef( |
| 1040 | file, |
| 1041 | parent_scope, |
| 1042 | extra.data.lhs, |
| 1043 | false, |
| 1044 | ); |
| 1045 | var rhs: DocData.WalkResult = try self.walkRef( |
| 1046 | file, |
| 1047 | parent_scope, |
| 1048 | extra.data.rhs, |
| 1049 | false, |
| 1050 | ); |
| 1051 | |
| 1052 | const lhs_index = self.exprs.items.len; |
| 1053 | try self.exprs.append(self.arena, lhs.expr); |
| 1054 | const rhs_index = self.exprs.items.len; |
| 1055 | try self.exprs.append(self.arena, rhs.expr); |
| 1056 | self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .sat = true, .opKind = 0 } }; |
| 1057 | |
| 1058 | return DocData.WalkResult{ |
| 1059 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 1060 | .expr = .{ .binOpIndex = binop_index }, |
| 1061 | }; |
| 1062 | }, |
| 1063 | |
| 1064 | .sub => { |
| 1065 | const pl_node = data[inst_index].pl_node; |
| 1066 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| 1067 | |
| 1068 | const binop_index = self.exprs.items.len; |
| 1069 | try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); |
| 1070 | |
| 1071 | var lhs: DocData.WalkResult = try self.walkRef( |
| 1072 | file, |
| 1073 | parent_scope, |
| 1074 | extra.data.lhs, |
| 1075 | false, |
| 1076 | ); |
| 1077 | var rhs: DocData.WalkResult = try self.walkRef( |
| 1078 | file, |
| 1079 | parent_scope, |
| 1080 | extra.data.rhs, |
| 1081 | false, |
| 1082 | ); |
| 1083 | |
| 1084 | const lhs_index = self.exprs.items.len; |
| 1085 | try self.exprs.append(self.arena, lhs.expr); |
| 1086 | const rhs_index = self.exprs.items.len; |
| 1087 | try self.exprs.append(self.arena, rhs.expr); |
| 1088 | self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .opKind = 1 } }; |
| 1089 | |
| 1090 | return DocData.WalkResult{ |
| 1091 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 1092 | .expr = .{ .binOpIndex = binop_index }, |
| 1093 | }; |
| 1094 | }, |
| 1095 | .subwrap => { |
| 1096 | const pl_node = data[inst_index].pl_node; |
| 1097 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| 1098 | |
| 1099 | const binop_index = self.exprs.items.len; |
| 1100 | try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); |
| 1101 | |
| 1102 | var lhs: DocData.WalkResult = try self.walkRef( |
| 1103 | file, |
| 1104 | parent_scope, |
| 1105 | extra.data.lhs, |
| 1106 | false, |
| 1107 | ); |
| 1108 | var rhs: DocData.WalkResult = try self.walkRef( |
| 1109 | file, |
| 1110 | parent_scope, |
| 1111 | extra.data.rhs, |
| 1112 | false, |
| 1113 | ); |
| 1114 | |
| 1115 | const lhs_index = self.exprs.items.len; |
| 1116 | try self.exprs.append(self.arena, lhs.expr); |
| 1117 | const rhs_index = self.exprs.items.len; |
| 1118 | try self.exprs.append(self.arena, rhs.expr); |
| 1119 | self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .wrap = true, .opKind = 1 } }; |
| 1120 | |
| 1121 | return DocData.WalkResult{ |
| 1122 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 1123 | .expr = .{ .binOpIndex = binop_index }, |
| 1124 | }; |
| 1125 | }, |
| 1126 | .sub_sat => { |
| 1127 | const pl_node = data[inst_index].pl_node; |
| 1128 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| 1129 | |
| 1130 | const binop_index = self.exprs.items.len; |
| 1131 | try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); |
| 1132 | |
| 1133 | var lhs: DocData.WalkResult = try self.walkRef( |
| 1134 | file, |
| 1135 | parent_scope, |
| 1136 | extra.data.lhs, |
| 1137 | false, |
| 1138 | ); |
| 1139 | var rhs: DocData.WalkResult = try self.walkRef( |
| 1140 | file, |
| 1141 | parent_scope, |
| 1142 | extra.data.rhs, |
| 1143 | false, |
| 1144 | ); |
| 1145 | |
| 1146 | const lhs_index = self.exprs.items.len; |
| 1147 | try self.exprs.append(self.arena, lhs.expr); |
| 1148 | const rhs_index = self.exprs.items.len; |
| 1149 | try self.exprs.append(self.arena, rhs.expr); |
| 1150 | self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .sat = true, .opKind = 1 } }; |
| 1151 | |
| 1152 | return DocData.WalkResult{ |
| 1153 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 1154 | .expr = .{ .binOpIndex = binop_index }, |
| 1155 | }; |
| 1156 | }, |
| 1157 | |
| 1158 | .mul => { |
| 1159 | const pl_node = data[inst_index].pl_node; |
| 1160 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| 1161 | |
| 1162 | const binop_index = self.exprs.items.len; |
| 1163 | try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); |
| 1164 | |
| 1165 | var lhs: DocData.WalkResult = try self.walkRef( |
| 1166 | file, |
| 1167 | parent_scope, |
| 1168 | extra.data.lhs, |
| 1169 | false, |
| 1170 | ); |
| 1171 | var rhs: DocData.WalkResult = try self.walkRef( |
| 1172 | file, |
| 1173 | parent_scope, |
| 1174 | extra.data.rhs, |
| 1175 | false, |
| 1176 | ); |
| 1177 | |
| 1178 | const lhs_index = self.exprs.items.len; |
| 1179 | try self.exprs.append(self.arena, lhs.expr); |
| 1180 | const rhs_index = self.exprs.items.len; |
| 1181 | try self.exprs.append(self.arena, rhs.expr); |
| 1182 | self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .opKind = 2 } }; |
| 1183 | |
| 1184 | return DocData.WalkResult{ |
| 1185 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 1186 | .expr = .{ .binOpIndex = binop_index }, |
| 1187 | }; |
| 1188 | }, |
| 1189 | .mulwrap => { |
| 1190 | const pl_node = data[inst_index].pl_node; |
| 1191 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| 1192 | |
| 1193 | const binop_index = self.exprs.items.len; |
| 1194 | try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); |
| 1195 | |
| 1196 | var lhs: DocData.WalkResult = try self.walkRef( |
| 1197 | file, |
| 1198 | parent_scope, |
| 1199 | extra.data.lhs, |
| 1200 | false, |
| 1201 | ); |
| 1202 | var rhs: DocData.WalkResult = try self.walkRef( |
| 1203 | file, |
| 1204 | parent_scope, |
| 1205 | extra.data.rhs, |
| 1206 | false, |
| 1207 | ); |
| 1208 | |
| 1209 | const lhs_index = self.exprs.items.len; |
| 1210 | try self.exprs.append(self.arena, lhs.expr); |
| 1211 | const rhs_index = self.exprs.items.len; |
| 1212 | try self.exprs.append(self.arena, rhs.expr); |
| 1213 | self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .wrap = true, .opKind = 2 } }; |
| 1214 | |
| 1215 | return DocData.WalkResult{ |
| 1216 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 1217 | .expr = .{ .binOpIndex = binop_index }, |
| 1218 | }; |
| 1219 | }, |
| 1220 | .mul_sat => { |
| 1221 | const pl_node = data[inst_index].pl_node; |
| 1222 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| 1223 | |
| 1224 | const binop_index = self.exprs.items.len; |
| 1225 | try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); |
| 1226 | |
| 1227 | var lhs: DocData.WalkResult = try self.walkRef( |
| 1228 | file, |
| 1229 | parent_scope, |
| 1230 | extra.data.lhs, |
| 1231 | false, |
| 1232 | ); |
| 1233 | var rhs: DocData.WalkResult = try self.walkRef( |
| 1234 | file, |
| 1235 | parent_scope, |
| 1236 | extra.data.rhs, |
| 1237 | false, |
| 1238 | ); |
| 1239 | |
| 1240 | const lhs_index = self.exprs.items.len; |
| 1241 | try self.exprs.append(self.arena, lhs.expr); |
| 1242 | const rhs_index = self.exprs.items.len; |
| 1243 | try self.exprs.append(self.arena, rhs.expr); |
| 1244 | self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .sat = true, .opKind = 2 } }; |
| 1245 | |
| 1246 | return DocData.WalkResult{ |
| 1247 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 1248 | .expr = .{ .binOpIndex = binop_index }, |
| 1249 | }; |
| 1250 | }, |
| 1251 | |
| 1252 | .div_exact => { |
| 1253 | const pl_node = data[inst_index].pl_node; |
| 1254 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| 1255 | |
| 1256 | const binop_index = self.exprs.items.len; |
| 1257 | try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); |
| 1258 | |
| 1259 | var lhs: DocData.WalkResult = try self.walkRef( |
| 1260 | file, |
| 1261 | parent_scope, |
| 1262 | extra.data.lhs, |
| 1263 | false, |
| 1264 | ); |
| 1265 | var rhs: DocData.WalkResult = try self.walkRef( |
| 1266 | file, |
| 1267 | parent_scope, |
| 1268 | extra.data.rhs, |
| 1269 | false, |
| 1270 | ); |
| 1271 | |
| 1272 | const lhs_index = self.exprs.items.len; |
| 1273 | try self.exprs.append(self.arena, lhs.expr); |
| 1274 | const rhs_index = self.exprs.items.len; |
| 1275 | try self.exprs.append(self.arena, rhs.expr); |
| 1276 | self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .exact = true, .opKind = 3 } }; |
| 1277 | |
| 1278 | return DocData.WalkResult{ |
| 1279 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 1280 | .expr = .{ .binOpIndex = binop_index }, |
| 1281 | }; |
| 1282 | }, |
| 1283 | .div_floor => { |
| 1284 | const pl_node = data[inst_index].pl_node; |
| 1285 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| 1286 | |
| 1287 | const binop_index = self.exprs.items.len; |
| 1288 | try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); |
| 1289 | |
| 1290 | var lhs: DocData.WalkResult = try self.walkRef( |
| 1291 | file, |
| 1292 | parent_scope, |
| 1293 | extra.data.lhs, |
| 1294 | false, |
| 1295 | ); |
| 1296 | var rhs: DocData.WalkResult = try self.walkRef( |
| 1297 | file, |
| 1298 | parent_scope, |
| 1299 | extra.data.rhs, |
| 1300 | false, |
| 1301 | ); |
| 1302 | |
| 1303 | const lhs_index = self.exprs.items.len; |
| 1304 | try self.exprs.append(self.arena, lhs.expr); |
| 1305 | const rhs_index = self.exprs.items.len; |
| 1306 | try self.exprs.append(self.arena, rhs.expr); |
| 1307 | self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .floor = true, .opKind = 3 } }; |
| 1308 | |
| 1309 | return DocData.WalkResult{ |
| 1310 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 1311 | .expr = .{ .binOpIndex = binop_index }, |
| 1312 | }; |
| 1313 | }, |
| 1314 | .div_trunc => { |
| 1315 | const pl_node = data[inst_index].pl_node; |
| 1316 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| 1317 | |
| 1318 | const binop_index = self.exprs.items.len; |
| 1319 | try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); |
| 1320 | |
| 1321 | var lhs: DocData.WalkResult = try self.walkRef( |
| 1322 | file, |
| 1323 | parent_scope, |
| 1324 | extra.data.lhs, |
| 1325 | false, |
| 1326 | ); |
| 1327 | var rhs: DocData.WalkResult = try self.walkRef( |
| 1328 | file, |
| 1329 | parent_scope, |
| 1330 | extra.data.rhs, |
| 1331 | false, |
| 1332 | ); |
| 1333 | |
| 1334 | const lhs_index = self.exprs.items.len; |
| 1335 | try self.exprs.append(self.arena, lhs.expr); |
| 1336 | const rhs_index = self.exprs.items.len; |
| 1337 | try self.exprs.append(self.arena, rhs.expr); |
| 1338 | self.exprs.items[binop_index] = .{ .binOp = .{ .lhs = lhs_index, .rhs = rhs_index, .trunc = true, .opKind = 3 } }; |
| 1339 | |
| 1340 | return DocData.WalkResult{ |
| 1341 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 1342 | .expr = .{ .binOpIndex = binop_index }, |
| 1343 | }; |
| 1344 | }, |
| 934 | 1345 | .error_union_type => { |
| 935 | 1346 | const pl_node = data[inst_index].pl_node; |
| 936 | 1347 | const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); |
| ... | ... | @@ -1435,6 +1846,14 @@ fn walkInstruction( |
| 1435 | 1846 | const dest_type_idx = self.exprs.items.len; |
| 1436 | 1847 | try self.exprs.append(self.arena, dest_type_walk.expr); |
| 1437 | 1848 | |
| 1849 | const sep = "=" ** 200; |
| 1850 | std.debug.print("{s}\n", .{sep}); |
| 1851 | std.debug.print("AS NODE\n", .{}); |
| 1852 | std.debug.print("extra = {any}\n", .{extra}); |
| 1853 | std.debug.print("desty_type_walk = {any}\n", .{dest_type_walk}); |
| 1854 | std.debug.print("operand = {any}\n", .{operand}); |
| 1855 | std.debug.print("{s}\n", .{sep}); |
| 1856 | |
| 1438 | 1857 | // TODO: there's something wrong with how both `as` and `WalkrResult` |
| 1439 | 1858 | // try to store type information. |
| 1440 | 1859 | return DocData.WalkResult{ |
| ... | ... | @@ -2886,7 +3305,14 @@ fn analyzeFunctionExtended( |
| 2886 | 3305 | if (extra.data.bits.has_align) { |
| 2887 | 3306 | const align_ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]); |
| 2888 | 3307 | align_index = self.exprs.items.len; |
| 2889 | | _ = try self.walkRef(file, scope, align_ref, false); |
| 3308 | const result = try self.walkRef(file, scope, align_ref, false); |
| 3309 | |
| 3310 | const sep = "=" ** 200; |
| 3311 | std.debug.print("{s}\n", .{sep}); |
| 3312 | std.debug.print("ALIGN\n", .{}); |
| 3313 | std.debug.print("align_ref = {any}\n", .{align_ref}); |
| 3314 | std.debug.print("result = {any}\n", .{result}); |
| 3315 | std.debug.print("{s}\n", .{sep}); |
| 2890 | 3316 | } |
| 2891 | 3317 | |
| 2892 | 3318 | self.types.items[type_slot_index] = .{ |