-
Notifications
You must be signed in to change notification settings - Fork 3
Implement std::intrinsics::raw_eq support in KMIR #665
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
base: master
Are you sure you want to change the base?
Changes from 7 commits
0ed9d98
e7f3a31
a545912
eb64d3e
28467a0
8f03fd7
9f66b04
95a6b5d
54de2b2
7eac083
d05eaa5
296e95f
3fb15d5
6d3d53f
1ada2ae
105d2aa
e4a9bc0
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 |
---|---|---|
|
@@ -515,7 +515,7 @@ An operand may be a `Reference` (the only way a function could access another fu | |
|
||
// Handle intrinsic functions - execute directly without setting up local stack frame | ||
rule <k> #setUpCalleeData(IntrinsicFunction(INTRINSIC_NAME), ARGS) | ||
=> #execIntrinsic(INTRINSIC_NAME, ARGS, DEST) ~> #execBlockIdx(RETURN_TARGET) | ||
=> #readOperands(ARGS) ~> #execIntrinsic(INTRINSIC_NAME, DEST) ~> #execBlockIdx(RETURN_TARGET) | ||
</k> | ||
<currentFrame> | ||
<dest> DEST </dest> | ||
|
@@ -525,7 +525,7 @@ An operand may be a `Reference` (the only way a function could access another fu | |
|
||
syntax KItem ::= #setArgsFromStack ( Int, Operands) | ||
| #setArgFromStack ( Int, Operand) | ||
| #execIntrinsic ( Symbol, Operands, Place ) | ||
| #execIntrinsic ( Symbol, Place ) | ||
|
||
// once all arguments have been retrieved, execute | ||
rule <k> #setArgsFromStack(_, .Operands) ~> CONT => CONT </k> | ||
|
@@ -629,7 +629,52 @@ its argument to the destination without modification. | |
|
||
```k | ||
// Black box intrinsic implementation - identity function | ||
rule <k> #execIntrinsic(symbol("black_box"), ARG .Operands, DEST) => #setLocalValue(DEST, ARG) ... </k> | ||
rule <k> ListItem(ARG:Value) ~> #execIntrinsic(symbol("black_box"), DEST) => #setLocalValue(DEST, ARG) ... </k> | ||
``` | ||
|
||
#### Raw Eq (`std::intrinsics::raw_eq`) | ||
|
||
The `raw_eq` intrinsic performs byte-by-byte equality comparison of the memory contents pointed to by two references. | ||
It returns a boolean value indicating whether the referenced values are equal. The implementation dereferences the | ||
provided References to access the underlying values, then compares them using K's built-in equality operator. | ||
This intrinsic is typically used for low-level memory comparison operations where type-specific equality methods | ||
are not suitable. | ||
|
||
**Current Limitations:** | ||
The current implementation only handles the simple case where References point to values of the same type. | ||
More complex scenarios require additional testing and implementation work: | ||
- References to different types with the same memory representation | ||
- References to composite types (structs, arrays, enums) | ||
- References with different alignments or padding | ||
|
||
Handling different types may require converting values to their byte representations before comparison, | ||
which will need to be addressed when such use cases are encountered. | ||
|
||
```k | ||
// Raw eq intrinsic - byte-by-byte equality comparison of referenced values | ||
|
||
// Handle Reference values by reading the referenced values directly | ||
rule <k> ListItem(Reference(_OFFSET1, place(LOCAL1, PROJ1), _MUT1, _META1):Value) | ||
ListItem(Reference(_OFFSET2, place(LOCAL2, PROJ2), _MUT2, _META2):Value) | ||
~> #execIntrinsic(symbol("raw_eq"), DEST) | ||
=> #readOperands( | ||
operandCopy(place(LOCAL1, PROJ1)) | ||
operandCopy(place(LOCAL2, PROJ2)) | ||
.Operands | ||
) ~> #execRawEq(DEST) | ||
... </k> | ||
[priority(1)] | ||
Stevengre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Dedicated raw_eq execution that compares dereferenced values | ||
syntax KItem ::= #execRawEq(Place) | ||
rule <k> ListItem(VAL1:Value) ListItem(VAL2:Value) ~> #execRawEq(DEST) | ||
=> #setLocalValue(DEST, BoolVal(VAL1 ==K VAL2)) | ||
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. There is a subtlety here that we have to address at some point: The enum MyEnum {
A(u64),
B(i64),
} and struct MyStruct(u64); then 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. We could compare the layouts (stable-mir-json is extracting them but they are not currently in the MIR-AST in K), but that will become complex. 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. Sorry, what 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. To distinguish this case, we need to store the original type of the As I mentioned this issue #666, should we tackle all the features in this PR? What kind of case can be moved to the furture work? 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. (PS. Apologies. I'm trying to type in English directly without AI rephrasing for faster response. But I may use some wrong grammar and words.) 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.
Maybe we should have a way to provide python hooks for K? 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. Is this feature will be used in p-token, @dkcumming? If not, maybe we should move this to future work. And for this case, I'm curious about the real ouput of this 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. As a first version, we could only implement 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. It seems like this issue touches the deep about what our architecture should look like, including:
BTW, it looks weird with 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. I think the code in |
||
... </k> | ||
|
||
// Generic rule for non-Reference values (commented out for now - unclear what behavior should be) | ||
// rule <k> ListItem(VAL1:Value) ListItem(VAL2:Value) ~> #execIntrinsic(symbol("raw_eq"), DEST) | ||
// => #setLocalValue(DEST, BoolVal(VAL1 ==K VAL2)) | ||
// ... </k> | ||
Stevengre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
### Stopping on Program Errors | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#![feature(core_intrinsics)] | ||
|
||
use std::intrinsics::raw_eq; | ||
|
||
// NOTE: This test demonstrates the raw_eq intrinsic implementation. | ||
// Known issue: Haskell backend produces more verbose symbolic execution output | ||
// compared to LLVM backend due to different handling of symbolic branches. | ||
// Both backends correctly implement the intrinsic but output format differs. | ||
Comment on lines
+5
to
+8
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. Is this true? Then the test should not pass because both HS backend and LLVM backend are tested. 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. Yes, I just changed the 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 means the LLVM backend is taking one branch and the HS backend explores more than one branch (non-deterministic branching). That should be investigated. 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. I found that is a 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. It could be a problem with one of the new rules. Maybe related to using |
||
|
||
fn main() { | ||
let a = 42; | ||
let b = 42; | ||
|
||
// Test raw_eq intrinsic with identical values | ||
let result = unsafe { raw_eq(&a, &b) }; | ||
|
||
// This assertion should pass as both values are identical | ||
assert!(result); | ||
} |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<kmir> | ||
<k> | ||
#execTerminator ( terminator (... kind: terminatorKindSwitchInt (... discr: operandCopy ( place (... local: local ( 3 ) , projection: .ProjectionElems ) ) , targets: switchTargets (... branches: branch ( 0 , basicBlockIdx ( 2 ) ) .Branches , otherwise: basicBlockIdx ( 3 ) ) ) , span: span ( 56 ) ) ) ~> .K | ||
</k> | ||
<retVal> | ||
noReturn | ||
</retVal> | ||
<currentFunc> | ||
ty ( 25 ) | ||
</currentFunc> | ||
<currentFrame> | ||
<currentBody> | ||
ListItem ( basicBlock (... statements: statement (... kind: statementKindAssign (... place: place (... local: local ( 1 ) , projection: .ProjectionElems ) , rvalue: rvalueUse ( operandConstant ( constOperand (... span: span ( 52 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindAllocated ( allocation (... bytes: b"*\x00\x00\x00" , provenance: provenanceMap (... ptrs: .ProvenanceMapEntries ) , align: align ( 4 ) , mutability: mutabilityMut ) ) , ty: ty ( 16 ) , id: mirConstId ( 10 ) ) ) ) ) ) , span: span ( 52 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 2 ) , projection: .ProjectionElems ) , rvalue: rvalueUse ( operandConstant ( constOperand (... span: span ( 53 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindAllocated ( allocation (... bytes: b"*\x00\x00\x00" , provenance: provenanceMap (... ptrs: .ProvenanceMapEntries ) , align: align ( 4 ) , mutability: mutabilityMut ) ) , ty: ty ( 16 ) , id: mirConstId ( 10 ) ) ) ) ) ) , span: span ( 53 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 4 ) , projection: .ProjectionElems ) , rvalue: rvalueRef ( region (... kind: regionKindReErased ) , borrowKindShared , place (... local: local ( 1 ) , projection: .ProjectionElems ) ) ) , span: span ( 54 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 5 ) , projection: .ProjectionElems ) , rvalue: rvalueRef ( region (... kind: regionKindReErased ) , borrowKindShared , place (... local: local ( 2 ) , projection: .ProjectionElems ) ) ) , span: span ( 55 ) ) .Statements , terminator: terminator (... kind: terminatorKindCall (... func: operandConstant ( constOperand (... span: span ( 50 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindZeroSized , ty: ty ( 25 ) , id: mirConstId ( 9 ) ) ) ) , args: operandCopy ( place (... local: local ( 4 ) , projection: .ProjectionElems ) ) operandCopy ( place (... local: local ( 5 ) , projection: .ProjectionElems ) ) .Operands , destination: place (... local: local ( 3 ) , projection: .ProjectionElems ) , target: someBasicBlockIdx ( basicBlockIdx ( 1 ) ) , unwind: unwindActionUnreachable ) , span: span ( 51 ) ) ) ) | ||
ListItem ( basicBlock (... statements: .Statements , terminator: terminator (... kind: terminatorKindSwitchInt (... discr: operandCopy ( place (... local: local ( 3 ) , projection: .ProjectionElems ) ) , targets: switchTargets (... branches: branch ( 0 , basicBlockIdx ( 2 ) ) .Branches , otherwise: basicBlockIdx ( 3 ) ) ) , span: span ( 56 ) ) ) ) | ||
ListItem ( basicBlock (... statements: .Statements , terminator: terminator (... kind: terminatorKindCall (... func: operandConstant ( constOperand (... span: span ( 57 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindZeroSized , ty: ty ( 26 ) , id: mirConstId ( 11 ) ) ) ) , args: operandConstant ( constOperand (... span: span ( 32 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindAllocated ( allocation (... bytes: b"\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00" , provenance: provenanceMap (... ptrs: provenanceMapEntry (... provSize: 0 , allocId: allocId ( 0 ) ) .ProvenanceMapEntries ) , align: align ( 8 ) , mutability: mutabilityMut ) ) , ty: ty ( 27 ) , id: mirConstId ( 12 ) ) ) ) .Operands , destination: place (... local: local ( 6 ) , projection: .ProjectionElems ) , target: noBasicBlockIdx , unwind: unwindActionContinue ) , span: span ( 57 ) ) ) ) | ||
ListItem ( basicBlock (... statements: .Statements , terminator: terminator (... kind: terminatorKindReturn , span: span ( 58 ) ) ) ) | ||
</currentBody> | ||
<caller> | ||
ty ( -1 ) | ||
</caller> | ||
<dest> | ||
place (... local: local ( 3 ) , projection: .ProjectionElems ) | ||
</dest> | ||
<target> | ||
someBasicBlockIdx ( basicBlockIdx ( 1 ) ) | ||
</target> | ||
<unwind> | ||
unwindActionUnreachable | ||
</unwind> | ||
<locals> | ||
ListItem ( newLocal ( ty ( 1 ) , mutabilityMut ) ) | ||
ListItem ( typedValue ( Integer ( 42 , 32 , true ) , ty ( 16 ) , mutabilityNot ) ) | ||
ListItem ( typedValue ( Integer ( 42 , 32 , true ) , ty ( 16 ) , mutabilityNot ) ) | ||
ListItem ( typedValue ( BoolVal ( true ) , ty ( 28 ) , mutabilityNot ) ) | ||
ListItem ( typedValue ( Reference ( 0 , place (... local: local ( 1 ) , projection: .ProjectionElems ) , mutabilityNot , noMetadata ) , ty ( 29 ) , mutabilityNot ) ) | ||
ListItem ( typedValue ( Reference ( 0 , place (... local: local ( 2 ) , projection: .ProjectionElems ) , mutabilityNot , noMetadata ) , ty ( 29 ) , mutabilityNot ) ) | ||
ListItem ( newLocal ( ty ( 30 ) , mutabilityMut ) ) | ||
</locals> | ||
</currentFrame> | ||
<stack> | ||
ListItem ( StackFrame ( ty ( -1 ) , place (... local: local ( 0 ) , projection: .ProjectionElems ) , noBasicBlockIdx , unwindActionContinue , ListItem ( newLocal ( ty ( 1 ) , mutabilityMut ) ) | ||
ListItem ( typedValue ( Integer ( 42 , 32 , true ) , ty ( 16 ) , mutabilityNot ) ) | ||
ListItem ( typedValue ( Integer ( 42 , 32 , true ) , ty ( 16 ) , mutabilityNot ) ) | ||
ListItem ( newLocal ( ty ( 28 ) , mutabilityNot ) ) | ||
ListItem ( typedValue ( Reference ( 0 , place (... local: local ( 1 ) , projection: .ProjectionElems ) , mutabilityNot , noMetadata ) , ty ( 29 ) , mutabilityNot ) ) | ||
ListItem ( typedValue ( Reference ( 0 , place (... local: local ( 2 ) , projection: .ProjectionElems ) , mutabilityNot , noMetadata ) , ty ( 29 ) , mutabilityNot ) ) | ||
ListItem ( newLocal ( ty ( 30 ) , mutabilityMut ) ) ) ) | ||
ListItem ( StackFrame ( ty ( -1 ) , place (... local: local ( -1 ) , projection: .ProjectionElems ) , noBasicBlockIdx , unwindActionUnreachable , .List ) ) | ||
</stack> | ||
<memory> | ||
.Map | ||
</memory> | ||
<functions> | ||
ty ( 20 ) |-> IntrinsicFunction ( symbol ( "black_box" ) ) | ||
ty ( 25 ) |-> IntrinsicFunction ( symbol ( "raw_eq" ) ) | ||
ty ( -1 ) |-> monoItemFn (... name: symbol ( "main" ) , id: defId ( 6 ) , body: someBody ( body (... blocks: basicBlock (... statements: statement (... kind: statementKindAssign (... place: place (... local: local ( 1 ) , projection: .ProjectionElems ) , rvalue: rvalueUse ( operandConstant ( constOperand (... span: span ( 52 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindAllocated ( allocation (... bytes: b"*\x00\x00\x00" , provenance: provenanceMap (... ptrs: .ProvenanceMapEntries ) , align: align ( 4 ) , mutability: mutabilityMut ) ) , ty: ty ( 16 ) , id: mirConstId ( 10 ) ) ) ) ) ) , span: span ( 52 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 2 ) , projection: .ProjectionElems ) , rvalue: rvalueUse ( operandConstant ( constOperand (... span: span ( 53 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindAllocated ( allocation (... bytes: b"*\x00\x00\x00" , provenance: provenanceMap (... ptrs: .ProvenanceMapEntries ) , align: align ( 4 ) , mutability: mutabilityMut ) ) , ty: ty ( 16 ) , id: mirConstId ( 10 ) ) ) ) ) ) , span: span ( 53 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 4 ) , projection: .ProjectionElems ) , rvalue: rvalueRef ( region (... kind: regionKindReErased ) , borrowKindShared , place (... local: local ( 1 ) , projection: .ProjectionElems ) ) ) , span: span ( 54 ) ) statement (... kind: statementKindAssign (... place: place (... local: local ( 5 ) , projection: .ProjectionElems ) , rvalue: rvalueRef ( region (... kind: regionKindReErased ) , borrowKindShared , place (... local: local ( 2 ) , projection: .ProjectionElems ) ) ) , span: span ( 55 ) ) .Statements , terminator: terminator (... kind: terminatorKindCall (... func: operandConstant ( constOperand (... span: span ( 50 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindZeroSized , ty: ty ( 25 ) , id: mirConstId ( 9 ) ) ) ) , args: operandCopy ( place (... local: local ( 4 ) , projection: .ProjectionElems ) ) operandCopy ( place (... local: local ( 5 ) , projection: .ProjectionElems ) ) .Operands , destination: place (... local: local ( 3 ) , projection: .ProjectionElems ) , target: someBasicBlockIdx ( basicBlockIdx ( 1 ) ) , unwind: unwindActionUnreachable ) , span: span ( 51 ) ) ) basicBlock (... statements: .Statements , terminator: terminator (... kind: terminatorKindSwitchInt (... discr: operandCopy ( place (... local: local ( 3 ) , projection: .ProjectionElems ) ) , targets: switchTargets (... branches: branch ( 0 , basicBlockIdx ( 2 ) ) .Branches , otherwise: basicBlockIdx ( 3 ) ) ) , span: span ( 56 ) ) ) basicBlock (... statements: .Statements , terminator: terminator (... kind: terminatorKindCall (... func: operandConstant ( constOperand (... span: span ( 57 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindZeroSized , ty: ty ( 26 ) , id: mirConstId ( 11 ) ) ) ) , args: operandConstant ( constOperand (... span: span ( 32 ) , userTy: noUserTypeAnnotationIndex , const: mirConst (... kind: constantKindAllocated ( allocation (... bytes: b"\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00" , provenance: provenanceMap (... ptrs: provenanceMapEntry (... provSize: 0 , allocId: allocId ( 0 ) ) .ProvenanceMapEntries ) , align: align ( 8 ) , mutability: mutabilityMut ) ) , ty: ty ( 27 ) , id: mirConstId ( 12 ) ) ) ) .Operands , destination: place (... local: local ( 6 ) , projection: .ProjectionElems ) , target: noBasicBlockIdx , unwind: unwindActionContinue ) , span: span ( 57 ) ) ) basicBlock (... statements: .Statements , terminator: terminator (... kind: terminatorKindReturn , span: span ( 58 ) ) ) .BasicBlocks , locals: localDecl (... ty: ty ( 1 ) , span: span ( 59 ) , mut: mutabilityMut ) localDecl (... ty: ty ( 16 ) , span: span ( 60 ) , mut: mutabilityNot ) localDecl (... ty: ty ( 16 ) , span: span ( 61 ) , mut: mutabilityNot ) localDecl (... ty: ty ( 28 ) , span: span ( 62 ) , mut: mutabilityNot ) localDecl (... ty: ty ( 29 ) , span: span ( 54 ) , mut: mutabilityNot ) localDecl (... ty: ty ( 29 ) , span: span ( 55 ) , mut: mutabilityNot ) localDecl (... ty: ty ( 30 ) , span: span ( 57 ) , mut: mutabilityMut ) .LocalDecls , argCount: 0 , varDebugInfo: varDebugInfo (... name: symbol ( "a" ) , sourceInfo: sourceInfo (... span: span ( 60 ) , scope: sourceScope ( 1 ) ) , composite: noVarDebugInfoFragment , value: varDebugInfoContentsPlace ( place (... local: local ( 1 ) , projection: .ProjectionElems ) ) , argumentIndex: noInt ) varDebugInfo (... name: symbol ( "b" ) , sourceInfo: sourceInfo (... span: span ( 61 ) , scope: sourceScope ( 2 ) ) , composite: noVarDebugInfoFragment , value: varDebugInfoContentsPlace ( place (... local: local ( 2 ) , projection: .ProjectionElems ) ) , argumentIndex: noInt ) varDebugInfo (... name: symbol ( "result" ) , sourceInfo: sourceInfo (... span: span ( 62 ) , scope: sourceScope ( 3 ) ) , composite: noVarDebugInfoFragment , value: varDebugInfoContentsPlace ( place (... local: local ( 3 ) , projection: .ProjectionElems ) ) , argumentIndex: noInt ) .VarDebugInfos , spreadArg: noLocal , span: span ( 63 ) ) ) ) | ||
</functions> | ||
<start-symbol> | ||
symbol ( "main" ) | ||
</start-symbol> | ||
<types> | ||
ty ( 1 ) |-> typeInfoTupleType ( .Tys ) | ||
ty ( 5 ) |-> typeInfoRefType ( ty ( 31 ) ) | ||
ty ( 6 ) |-> typeInfoPrimitiveType ( primTypeInt ( intTyIsize ) ) | ||
ty ( 8 ) |-> typeInfoPtrType ( ty ( 32 ) ) | ||
ty ( 9 ) |-> typeInfoPrimitiveType ( primTypeUint ( uintTyU8 ) ) | ||
ty ( 10 ) |-> typeInfoEnumType ( "std::result::Result<isize, !>" , adtDef ( 12 ) , Discriminant ( 0 ) Discriminant ( 1 ) .Discriminants ) | ||
ty ( 11 ) |-> typeInfoRefType ( ty ( 12 ) ) | ||
ty ( 15 ) |-> typeInfoStructType ( "std::sys::pal::unix::process::process_common::ExitCode" , adtDef ( 18 ) , ty ( 9 ) .Tys ) | ||
ty ( 16 ) |-> typeInfoPrimitiveType ( primTypeInt ( intTyI32 ) ) | ||
ty ( 17 ) |-> typeInfoStructType ( "std::process::ExitCode" , adtDef ( 16 ) , ty ( 15 ) .Tys ) | ||
ty ( 18 ) |-> typeInfoRefType ( ty ( 15 ) ) | ||
ty ( 22 ) |-> typeInfoPtrType ( ty ( 12 ) ) | ||
ty ( 24 ) |-> typeInfoRefType ( ty ( 12 ) ) | ||
ty ( 27 ) |-> typeInfoRefType ( ty ( 34 ) ) | ||
ty ( 28 ) |-> typeInfoPrimitiveType ( primTypeBool ) | ||
ty ( 29 ) |-> typeInfoRefType ( ty ( 16 ) ) | ||
ty ( 30 ) |-> typeInfoVoidType | ||
ty ( 32 ) |-> typeInfoPtrType ( ty ( 9 ) ) | ||
ty ( 33 ) |-> typeInfoRefType ( ty ( 35 ) ) | ||
ty ( 34 ) |-> typeInfoPrimitiveType ( primTypeStr ) | ||
ty ( 35 ) |-> typeInfoStructType ( "std::panic::Location<'_>" , adtDef ( 22 ) , ty ( 27 ) ty ( 36 ) ty ( 36 ) .Tys ) | ||
ty ( 36 ) |-> typeInfoPrimitiveType ( primTypeUint ( uintTyU32 ) ) | ||
</types> | ||
<adt-to-ty> | ||
adtDef ( 12 ) |-> ty ( 10 ) | ||
adtDef ( 16 ) |-> ty ( 17 ) | ||
adtDef ( 18 ) |-> ty ( 15 ) | ||
adtDef ( 22 ) |-> ty ( 35 ) | ||
</adt-to-ty> | ||
</kmir> |
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.
Maybe we should keep the operands within
#execIntrinsic
(might be better for indexing).We can do the argument evaluation (currently done in
readOperands
) within each intrinsic implementation (where necessary). For the intrinsics we have as of now,black_box
andraw_eq
, the rules would look likeThe
#execRawEq
needs two arguments of sortEvaluation
, declared[seqstrict(2,3)]
, and the helper#withDeref
would append theDeref
projection to any existing ones.(constant operands may still use a
Deref
when the constant is statically allocated, not implemented yet)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.
Thank you! That's better. One of my yesterday version is something like this. But I changed to this version because of gernalization.
But yes, it's more concise with this design. And thank you for the indexing thing. Let me refactor this.