authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-21 19:23:12-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-21 19:23:12-07:00
log5769c963e0748088ba2636e870cbc6f887d10454
tree1fee68ec22c0e7fcdc7666f4fd2e683eb241fb09
parent07c204393ff18b5503d9995fecabdbac154d385e

Sema: implement arithmetic


4 files changed, 121 insertions(+), 94 deletions(-)

src/Module.zig+26
...@@ -1667,6 +1667,9 @@ pub const SrcLoc = struct {...@@ -1667,6 +1667,9 @@ pub const SrcLoc = struct {
1667 .node_offset_asm_ret_ty,1667 .node_offset_asm_ret_ty,
1668 .node_offset_if_cond,1668 .node_offset_if_cond,
1669 .node_offset_anyframe_type,1669 .node_offset_anyframe_type,
1670 .node_offset_bin_op,
1671 .node_offset_bin_lhs,
1672 .node_offset_bin_rhs,
1670 => src_loc.container.decl.container.file_scope,1673 => src_loc.container.decl.container.file_scope,
1671 };1674 };
1672 }1675 }
...@@ -1722,6 +1725,9 @@ pub const SrcLoc = struct {...@@ -1722,6 +1725,9 @@ pub const SrcLoc = struct {
1722 .node_offset_asm_ret_ty => @panic("TODO"),1725 .node_offset_asm_ret_ty => @panic("TODO"),
1723 .node_offset_if_cond => @panic("TODO"),1726 .node_offset_if_cond => @panic("TODO"),
1724 .node_offset_anyframe_type => @panic("TODO"),1727 .node_offset_anyframe_type => @panic("TODO"),
1728 .node_offset_bin_op => @panic("TODO"),
1729 .node_offset_bin_lhs => @panic("TODO"),
1730 .node_offset_bin_rhs => @panic("TODO"),
1725 }1731 }
1726 }1732 }
1727};1733};
...@@ -1846,6 +1852,20 @@ pub const LazySrcLoc = union(enum) {...@@ -1846,6 +1852,20 @@ pub const LazySrcLoc = union(enum) {
1846 /// to the type expression.1852 /// to the type expression.
1847 /// The Decl is determined contextually.1853 /// The Decl is determined contextually.
1848 node_offset_anyframe_type: i32,1854 node_offset_anyframe_type: i32,
1855 /// The source location points to a binary expression, such as `a + b`, found
1856 /// by taking this AST node index offset from the containing Decl AST node.
1857 /// The Decl is determined contextually.
1858 node_offset_bin_op: i32,
1859 /// The source location points to the LHS of a binary expression, found
1860 /// by taking this AST node index offset from the containing Decl AST node,
1861 /// which points to a binary expression AST node. Next, nagivate to the LHS.
1862 /// The Decl is determined contextually.
1863 node_offset_bin_lhs: i32,
1864 /// The source location points to the RHS of a binary expression, found
1865 /// by taking this AST node index offset from the containing Decl AST node,
1866 /// which points to a binary expression AST node. Next, nagivate to the RHS.
1867 /// The Decl is determined contextually.
1868 node_offset_bin_rhs: i32,
18491869
1850 /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope.1870 /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope.
1851 pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc {1871 pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc {
...@@ -1877,6 +1897,9 @@ pub const LazySrcLoc = union(enum) {...@@ -1877,6 +1897,9 @@ pub const LazySrcLoc = union(enum) {
1877 .node_offset_asm_ret_ty,1897 .node_offset_asm_ret_ty,
1878 .node_offset_if_cond,1898 .node_offset_if_cond,
1879 .node_offset_anyframe_type,1899 .node_offset_anyframe_type,
1900 .node_offset_bin_op,
1901 .node_offset_bin_lhs,
1902 .node_offset_bin_rhs,
1880 => .{1903 => .{
1881 .container = .{ .decl = scope.srcDecl().? },1904 .container = .{ .decl = scope.srcDecl().? },
1882 .lazy = lazy,1905 .lazy = lazy,
...@@ -1914,6 +1937,9 @@ pub const LazySrcLoc = union(enum) {...@@ -1914,6 +1937,9 @@ pub const LazySrcLoc = union(enum) {
1914 .node_offset_asm_ret_ty,1937 .node_offset_asm_ret_ty,
1915 .node_offset_if_cond,1938 .node_offset_if_cond,
1916 .node_offset_anyframe_type,1939 .node_offset_anyframe_type,
1940 .node_offset_bin_op,
1941 .node_offset_bin_lhs,
1942 .node_offset_bin_rhs,
1917 => .{1943 => .{
1918 .container = .{ .decl = decl },1944 .container = .{ .decl = decl },
1919 .lazy = lazy,1945 .lazy = lazy,
src/Sema.zig+46-59
...@@ -2419,17 +2419,18 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr...@@ -2419,17 +2419,18 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
2419 const tracy = trace(@src());2419 const tracy = trace(@src());
2420 defer tracy.end();2420 defer tracy.end();
24212421
2422 if (true) @panic("TODO rework with zir-memory-layout in mind");2422 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
24232423 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
2424 const bin_inst = sema.code.instructions.items(.data)[inst].bin;2424 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
2425 const src: LazySrcLoc = .todo;2425 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
2426 const lhs = try sema.resolveInst(bin_inst.lhs);2426 const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;
2427 const rhs = try sema.resolveInst(bin_inst.rhs);2427 const lhs = try sema.resolveInst(extra.lhs);
2428 const rhs = try sema.resolveInst(extra.rhs);
24282429
2429 const instructions = &[_]*Inst{ lhs, rhs };2430 const instructions = &[_]*Inst{ lhs, rhs };
2430 const resolved_type = try sema.resolvePeerTypes(block, instructions);2431 const resolved_type = try sema.resolvePeerTypes(block, instructions);
2431 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs.src);2432 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
2432 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs.src);2433 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
24332434
2434 const scalar_type = if (resolved_type.zigTypeTag() == .Vector)2435 const scalar_type = if (resolved_type.zigTypeTag() == .Vector)
2435 resolved_type.elemType()2436 resolved_type.elemType()
...@@ -2455,8 +2456,9 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr...@@ -2455,8 +2456,9 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
24552456
2456 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;2457 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
2457 const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat;2458 const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat;
2459 const zir_tags = block.sema.code.instructions.items(.tag);
24582460
2459 if (!is_int and !(is_float and floatOpAllowed(inst.base.tag))) {2461 if (!is_int and !(is_float and floatOpAllowed(zir_tags[inst]))) {
2460 return sema.mod.fail(&block.base, src, "invalid operands to binary expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) });2462 return sema.mod.fail(&block.base, src, "invalid operands to binary expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) });
2461 }2463 }
24622464
...@@ -2468,71 +2470,56 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr...@@ -2468,71 +2470,56 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
2468 .val = Value.initTag(.undef),2470 .val = Value.initTag(.undef),
2469 });2471 });
2470 }2472 }
2471 return sema.analyzeInstComptimeOp(block, scalar_type, inst, lhs_val, rhs_val);2473 // incase rhs is 0, simply return lhs without doing any calculations
2474 // TODO Once division is implemented we should throw an error when dividing by 0.
2475 if (rhs_val.compareWithZero(.eq)) {
2476 return sema.mod.constInst(sema.arena, src, .{
2477 .ty = scalar_type,
2478 .val = lhs_val,
2479 });
2480 }
2481
2482 const value = switch (zir_tags[inst]) {
2483 .add => blk: {
2484 const val = if (is_int)
2485 try Module.intAdd(sema.arena, lhs_val, rhs_val)
2486 else
2487 try Module.floatAdd(sema.arena, scalar_type, src, lhs_val, rhs_val);
2488 break :blk val;
2489 },
2490 .sub => blk: {
2491 const val = if (is_int)
2492 try Module.intSub(sema.arena, lhs_val, rhs_val)
2493 else
2494 try Module.floatSub(sema.arena, scalar_type, src, lhs_val, rhs_val);
2495 break :blk val;
2496 },
2497 else => return sema.mod.fail(&block.base, src, "TODO Implement arithmetic operand '{s}'", .{@tagName(zir_tags[inst])}),
2498 };
2499
2500 log.debug("{s}({}, {}) result: {}", .{ @tagName(zir_tags[inst]), lhs_val, rhs_val, value });
2501
2502 return sema.mod.constInst(sema.arena, src, .{
2503 .ty = scalar_type,
2504 .val = value,
2505 });
2472 }2506 }
2473 }2507 }
24742508
2475 try sema.requireRuntimeBlock(block, src);2509 try sema.requireRuntimeBlock(block, src);
2476 const ir_tag: Inst.Tag = switch (inst.base.tag) {2510 const ir_tag: Inst.Tag = switch (zir_tags[inst]) {
2477 .add => .add,2511 .add => .add,
2478 .addwrap => .addwrap,2512 .addwrap => .addwrap,
2479 .sub => .sub,2513 .sub => .sub,
2480 .subwrap => .subwrap,2514 .subwrap => .subwrap,
2481 .mul => .mul,2515 .mul => .mul,
2482 .mulwrap => .mulwrap,2516 .mulwrap => .mulwrap,
2483 else => return sema.mod.fail(&block.base, src, "TODO implement arithmetic for operand '{s}''", .{@tagName(inst.base.tag)}),2517 else => return sema.mod.fail(&block.base, src, "TODO implement arithmetic for operand '{s}''", .{@tagName(zir_tags[inst])}),
2484 };2518 };
24852519
2486 return block.addBinOp(src, scalar_type, ir_tag, casted_lhs, casted_rhs);2520 return block.addBinOp(src, scalar_type, ir_tag, casted_lhs, casted_rhs);
2487}2521}
24882522
2489/// Analyzes operands that are known at comptime
2490fn analyzeInstComptimeOp(
2491 sema: *Sema,
2492 block: *Scope.Block,
2493 res_type: Type,
2494 inst: zir.Inst.Index,
2495 lhs_val: Value,
2496 rhs_val: Value,
2497) InnerError!*Inst {
2498 if (true) @panic("TODO rework analyzeInstComptimeOp for zir-memory-layout");
2499
2500 // incase rhs is 0, simply return lhs without doing any calculations
2501 // TODO Once division is implemented we should throw an error when dividing by 0.
2502 if (rhs_val.compareWithZero(.eq)) {
2503 return sema.mod.constInst(sema.arena, inst.base.src, .{
2504 .ty = res_type,
2505 .val = lhs_val,
2506 });
2507 }
2508 const is_int = res_type.isInt() or res_type.zigTypeTag() == .ComptimeInt;
2509
2510 const value = switch (inst.base.tag) {
2511 .add => blk: {
2512 const val = if (is_int)
2513 try Module.intAdd(sema.arena, lhs_val, rhs_val)
2514 else
2515 try Module.floatAdd(sema.arena, res_type, inst.base.src, lhs_val, rhs_val);
2516 break :blk val;
2517 },
2518 .sub => blk: {
2519 const val = if (is_int)
2520 try Module.intSub(sema.arena, lhs_val, rhs_val)
2521 else
2522 try Module.floatSub(sema.arena, res_type, inst.base.src, lhs_val, rhs_val);
2523 break :blk val;
2524 },
2525 else => return sema.mod.fail(&block.base, inst.base.src, "TODO Implement arithmetic operand '{s}'", .{@tagName(inst.base.tag)}),
2526 };
2527
2528 log.debug("{s}({}, {}) result: {}", .{ @tagName(inst.base.tag), lhs_val, rhs_val, value });
2529
2530 return sema.mod.constInst(sema.arena, inst.base.src, .{
2531 .ty = res_type,
2532 .val = value,
2533 });
2534}
2535
2536fn zirDerefNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2523fn zirDerefNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
2537 const tracy = trace(@src());2524 const tracy = trace(@src());
2538 defer tracy.end();2525 defer tracy.end();
src/astgen.zig+15-14
...@@ -3000,19 +3000,18 @@ fn as(...@@ -3000,19 +3000,18 @@ fn as(
3000 lhs: ast.Node.Index,3000 lhs: ast.Node.Index,
3001 rhs: ast.Node.Index,3001 rhs: ast.Node.Index,
3002) InnerError!zir.Inst.Ref {3002) InnerError!zir.Inst.Ref {
3003 if (true) @panic("TODO update for zir-memory-layout");
3004 const dest_type = try typeExpr(mod, scope, lhs);3003 const dest_type = try typeExpr(mod, scope, lhs);
3005 switch (rl) {3004 switch (rl) {
3006 .none, .discard, .ref, .ty => {3005 .none, .discard, .ref, .ty => {
3007 const result = try expr(mod, scope, .{ .ty = dest_type }, rhs);3006 const result = try expr(mod, scope, .{ .ty = dest_type }, rhs);
3008 return rvalue(mod, scope, rl, result);3007 return rvalue(mod, scope, rl, result, node);
3009 },3008 },
30103009
3011 .ptr => |result_ptr| {3010 .ptr => |result_ptr| {
3012 return asRlPtr(mod, scope, rl, src, result_ptr, rhs, dest_type);3011 return asRlPtr(mod, scope, rl, result_ptr, rhs, dest_type);
3013 },3012 },
3014 .block_ptr => |block_scope| {3013 .block_ptr => |block_scope| {
3015 return asRlPtr(mod, scope, rl, src, block_scope.rl_ptr.?, rhs, dest_type);3014 return asRlPtr(mod, scope, rl, block_scope.rl_ptr, rhs, dest_type);
3016 },3015 },
30173016
3018 .bitcasted_ptr => |bitcasted_ptr| {3017 .bitcasted_ptr => |bitcasted_ptr| {
...@@ -3030,7 +3029,6 @@ fn asRlPtr(...@@ -3030,7 +3029,6 @@ fn asRlPtr(
3030 mod: *Module,3029 mod: *Module,
3031 scope: *Scope,3030 scope: *Scope,
3032 rl: ResultLoc,3031 rl: ResultLoc,
3033 src: usize,
3034 result_ptr: zir.Inst.Ref,3032 result_ptr: zir.Inst.Ref,
3035 operand_node: ast.Node.Index,3033 operand_node: ast.Node.Index,
3036 dest_type: zir.Inst.Ref,3034 dest_type: zir.Inst.Ref,
...@@ -3038,32 +3036,35 @@ fn asRlPtr(...@@ -3038,32 +3036,35 @@ fn asRlPtr(
3038 // Detect whether this expr() call goes into rvalue() to store the result into the3036 // Detect whether this expr() call goes into rvalue() to store the result into the
3039 // result location. If it does, elide the coerce_result_ptr instruction3037 // result location. If it does, elide the coerce_result_ptr instruction
3040 // as well as the store instruction, instead passing the result as an rvalue.3038 // as well as the store instruction, instead passing the result as an rvalue.
3039 const parent_gz = scope.getGenZir();
3040
3041 var as_scope: Scope.GenZir = .{3041 var as_scope: Scope.GenZir = .{
3042 .parent = scope,3042 .parent = scope,
3043 .decl = scope.ownerDecl().?,3043 .zir_code = parent_gz.zir_code,
3044 .arena = scope.arena(),
3045 .force_comptime = scope.isComptime(),3044 .force_comptime = scope.isComptime(),
3046 .instructions = .{},3045 .instructions = .{},
3047 };3046 };
3048 defer as_scope.instructions.deinit(mod.gpa);3047 defer as_scope.instructions.deinit(mod.gpa);
30493048
3050 as_scope.rl_ptr = try addZIRBinOp(mod, &as_scope.base, src, .coerce_result_ptr, dest_type, result_ptr);3049 as_scope.rl_ptr = try as_scope.addBin(.coerce_result_ptr, dest_type, result_ptr);
3051 const result = try expr(mod, &as_scope.base, .{ .block_ptr = &as_scope }, operand_node);3050 const result = try expr(mod, &as_scope.base, .{ .block_ptr = &as_scope }, operand_node);
3052 const parent_zir = &scope.getGenZir().instructions;3051 const parent_zir = &parent_gz.instructions;
3053 if (as_scope.rvalue_rl_count == 1) {3052 if (as_scope.rvalue_rl_count == 1) {
3054 // Busted! This expression didn't actually need a pointer.3053 // Busted! This expression didn't actually need a pointer.
3054 const zir_tags = parent_gz.zir_code.instructions.items(.tag);
3055 const zir_datas = parent_gz.zir_code.instructions.items(.data);
3055 const expected_len = parent_zir.items.len + as_scope.instructions.items.len - 2;3056 const expected_len = parent_zir.items.len + as_scope.instructions.items.len - 2;
3056 try parent_zir.ensureCapacity(mod.gpa, expected_len);3057 try parent_zir.ensureCapacity(mod.gpa, expected_len);
3057 for (as_scope.instructions.items) |src_inst| {3058 for (as_scope.instructions.items) |src_inst| {
3058 if (src_inst == as_scope.rl_ptr.?) continue;3059 if (src_inst == as_scope.rl_ptr) continue;
3059 if (src_inst.castTag(.store_to_block_ptr)) |store| {3060 if (zir_tags[src_inst] == .store_to_block_ptr) {
3060 if (store.positionals.lhs == as_scope.rl_ptr.?) continue;3061 if (zir_datas[src_inst].bin.lhs == as_scope.rl_ptr) continue;
3061 }3062 }
3062 parent_zir.appendAssumeCapacity(src_inst);3063 parent_zir.appendAssumeCapacity(src_inst);
3063 }3064 }
3064 assert(parent_zir.items.len == expected_len);3065 assert(parent_zir.items.len == expected_len);
3065 const casted_result = try addZIRBinOp(mod, scope, dest_type.src, .as, dest_type, result);3066 const casted_result = try parent_gz.addBin(.as, dest_type, result);
3066 return rvalue(mod, scope, rl, casted_result);3067 return rvalue(mod, scope, rl, casted_result, operand_node);
3067 } else {3068 } else {
3068 try parent_zir.appendSlice(mod.gpa, as_scope.instructions.items);3069 try parent_zir.appendSlice(mod.gpa, as_scope.instructions.items);
3069 return result;3070 return result;
src/zir.zig+34-21
...@@ -524,6 +524,7 @@ pub const Inst = struct {...@@ -524,6 +524,7 @@ pub const Inst = struct {
524 cmp_neq,524 cmp_neq,
525 /// Coerces a result location pointer to a new element type. It is evaluated "backwards"-525 /// Coerces a result location pointer to a new element type. It is evaluated "backwards"-
526 /// as type coercion from the new element type to the old element type.526 /// as type coercion from the new element type to the old element type.
527 /// Uses the `bin` union field.
527 /// LHS is destination element type, RHS is result pointer.528 /// LHS is destination element type, RHS is result pointer.
528 coerce_result_ptr,529 coerce_result_ptr,
529 /// Emit an error message and fail compilation.530 /// Emit an error message and fail compilation.
...@@ -1327,33 +1328,12 @@ const Writer = struct {...@@ -1327,33 +1328,12 @@ const Writer = struct {
1327 const tag = tags[inst];1328 const tag = tags[inst];
1328 try stream.print("= {s}(", .{@tagName(tags[inst])});1329 try stream.print("= {s}(", .{@tagName(tags[inst])});
1329 switch (tag) {1330 switch (tag) {
1330 .add,
1331 .addwrap,
1332 .array_cat,
1333 .array_mul,
1334 .mul,
1335 .mulwrap,
1336 .sub,
1337 .subwrap,
1338 .array_type,1331 .array_type,
1339 .bit_and,1332 .bit_and,
1340 .bit_or,1333 .bit_or,
1341 .as,1334 .as,
1342 .bool_and,
1343 .bool_or,
1344 .@"break",1335 .@"break",
1345 .cmp_lt,
1346 .cmp_lte,
1347 .cmp_eq,
1348 .cmp_gte,
1349 .cmp_gt,
1350 .cmp_neq,
1351 .coerce_result_ptr,1336 .coerce_result_ptr,
1352 .div,
1353 .mod_rem,
1354 .shl,
1355 .shr,
1356 .xor,
1357 .elem_ptr,1337 .elem_ptr,
1358 .elem_val,1338 .elem_val,
1359 .intcast,1339 .intcast,
...@@ -1447,6 +1427,29 @@ const Writer = struct {...@@ -1447,6 +1427,29 @@ const Writer = struct {
1447 .suspend_block,1427 .suspend_block,
1448 => try self.writePlNode(stream, inst),1428 => try self.writePlNode(stream, inst),
14491429
1430 .add,
1431 .addwrap,
1432 .array_cat,
1433 .array_mul,
1434 .mul,
1435 .mulwrap,
1436 .sub,
1437 .subwrap,
1438 .bool_and,
1439 .bool_or,
1440 .cmp_lt,
1441 .cmp_lte,
1442 .cmp_eq,
1443 .cmp_gte,
1444 .cmp_gt,
1445 .cmp_neq,
1446 .div,
1447 .mod_rem,
1448 .shl,
1449 .shr,
1450 .xor,
1451 => try self.writePlNodeBin(stream, inst),
1452
1450 .as_node => try self.writeAs(stream, inst),1453 .as_node => try self.writeAs(stream, inst),
14511454
1452 .breakpoint,1455 .breakpoint,
...@@ -1589,6 +1592,16 @@ const Writer = struct {...@@ -1589,6 +1592,16 @@ const Writer = struct {
1589 try self.writeSrc(stream, inst_data.src());1592 try self.writeSrc(stream, inst_data.src());
1590 }1593 }
15911594
1595 fn writePlNodeBin(self: *Writer, stream: anytype, inst: Inst.Index) !void {
1596 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
1597 const extra = self.code.extraData(Inst.Bin, inst_data.payload_index).data;
1598 try self.writeInstRef(stream, extra.lhs);
1599 try stream.writeAll(", ");
1600 try self.writeInstRef(stream, extra.rhs);
1601 try stream.writeAll(") ");
1602 try self.writeSrc(stream, inst_data.src());
1603 }
1604
1592 fn writeAs(self: *Writer, stream: anytype, inst: Inst.Index) !void {1605 fn writeAs(self: *Writer, stream: anytype, inst: Inst.Index) !void {
1593 const inst_data = self.code.instructions.items(.data)[inst].pl_node;1606 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
1594 const extra = self.code.extraData(Inst.As, inst_data.payload_index).data;1607 const extra = self.code.extraData(Inst.As, inst_data.payload_index).data;