-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Verify tmp registers #1010
base: main
Are you sure you want to change the base?
Verify tmp registers #1010
Changes from 14 commits
4d7932a
11f3509
9318029
753c457
abdbf53
3a4c0df
8eba31b
f2a1382
e2ec714
d6879e7
4d12ef0
54ce38f
87e1184
0b1638e
06d93f7
d16e0b2
a5b3a3f
9546bee
82cfbb3
59b6c9f
88838a1
2895ca3
f264fd5
029c548
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,18 +67,59 @@ class VerifyContext { | |
|
||
public function verifyFunctionCode(Module mod, FunctionDefn defn, FunctionCode code) returns Error? { | ||
VerifyContext cx = new(mod, defn); | ||
boolean[] tmpRegisterInit = []; | ||
if code.registers.length() > 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cleaner to do |
||
tmpRegisterInit[code.registers.length() - 1] = false; | ||
} | ||
foreach BasicBlock b in code.blocks { | ||
check verifyBasicBlock(cx, b); | ||
check verifyBasicBlock(cx, b, tmpRegisterInit); | ||
} | ||
} | ||
|
||
type IntBinaryInsn IntArithmeticBinaryInsn|IntBitwiseBinaryInsn; | ||
|
||
type Error err:Semantic|err:Internal; | ||
|
||
function verifyBasicBlock(VerifyContext vc, BasicBlock bb) returns Error? { | ||
function verifyBasicBlock(VerifyContext vc, BasicBlock bb, boolean[] tmpRegisterInit) returns Error? { | ||
foreach Insn insn in bb.insns { | ||
check verifyInsn(vc, insn); | ||
check verifyInsnRegisterKinds(vc, insn, tmpRegisterInit); | ||
} | ||
} | ||
|
||
function verifyInsnRegisterKinds(VerifyContext vc, Insn insn, boolean[] tmpRegisterInit) returns Error? { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
if insn is ResultInsnBase { | ||
if tmpRegisterInit[insn.result.number] { | ||
return vc.invalidErr("multiple assignments to a tmp register", insn.pos); | ||
} | ||
else { | ||
tmpRegisterInit[insn.result.number] = true; | ||
} | ||
} | ||
|
||
match insn { | ||
var { operand } => { | ||
check verifyRegisterKind(vc, operand, tmpRegisterInit, insn.pos); | ||
} | ||
var { operands } | var { args: operands } => { | ||
// JBUG #35557 can't iterate operands | ||
Operand[] ops = operands; | ||
foreach Operand op in ops { | ||
check verifyRegisterKind(vc, op, tmpRegisterInit, insn.pos); | ||
} | ||
} | ||
} | ||
} | ||
|
||
function verifyRegisterKind(VerifyContext vc, Operand r, boolean[] tmpRegisterInit, Position pos) returns Error? { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Current name doesn't explain what it does. How about |
||
if r is TmpRegister && !tmpRegisterInit[r.number] { | ||
return vc.invalidErr("tmp register not initialized", pos); | ||
} | ||
} | ||
|
||
function verifyNarrowRegister(VerifyContext vc, NarrowRegister r) returns Error? { | ||
if !t:isSubtype(vc.typeContext(), r.semType, r.underlying.semType) { | ||
return vc.invalidErr("narrow register is not a subtype of narrowed register", <Position>r.pos); | ||
} | ||
} | ||
|
||
|
@@ -151,6 +192,13 @@ function verifyInsn(VerifyContext vc, Insn insn) returns Error? { | |
else if insn is ErrorConstructInsn { | ||
check validOperandString(vc, name, insn.operand, insn.pos); | ||
} | ||
else if insn is TypeMergeInsn { | ||
check verifyNarrowRegister(vc, insn.result); | ||
} | ||
else if insn is TypeBranchInsn { | ||
check verifyNarrowRegister(vc, insn.ifTrueRegister); | ||
check verifyNarrowRegister(vc, insn.ifFalseRegister); | ||
} | ||
} | ||
|
||
function verifyCall(VerifyContext vc, CallInsn insn) returns err:Internal? { | ||
|
@@ -226,6 +274,9 @@ function verifyListSet(VerifyContext vc, ListSetInsn insn) returns Error? { | |
if !vc.isSubtype(insn.operands[0].semType, t:LIST) { | ||
return vc.semanticErr("list set applied to non-list", insn.pos); | ||
} | ||
if insn.operands[0] is FinalRegister { | ||
return vc.invalidErr("invalid register kind final for ListSetInsn", insn.pos); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is wrong. import ballerina/io;
public function main() {
final int[] i = [1, 2, 3];
i[0] = 4;
io:println(i);
} Above is a valid Ballerina program. |
||
t:SemType memberType = t:listMemberType(vc.typeContext(), insn.operands[0].semType, insn.operands[1].semType); | ||
return verifyOperandType(vc, insn.operands[2], memberType, "value assigned to member of list is not a subtype of array member type", insn.pos); | ||
} | ||
|
@@ -251,6 +302,9 @@ function verifyMappingSet(VerifyContext vc, MappingSetInsn insn) returns Error? | |
if !vc.isSubtype(insn.operands[0].semType, t:MAPPING) { | ||
return vc.semanticErr("mapping set applied to non-mapping", insn.pos); | ||
} | ||
if insn.operands[0] is FinalRegister { | ||
return vc.invalidErr("invalid register kind final for MappingSetInsn", insn.pos); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
t:SemType memberType = t:mappingMemberType(vc.typeContext(), insn.operands[0].semType, keyOperand.semType); | ||
return verifyOperandType(vc, insn.operands[2], memberType, "value assigned to member of mapping is not a subtype of map member type", insn.pos); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a second though, let's call this
tmpRegisterInitialized
to match with the func name.