Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions docs/book/src/reference/compiler_intrinsics.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,3 +408,30 @@ on real nodes and it only increases gas usage.
**Constraints:**

- `T` must implement Debug

---

```sway
__transmute<A, B>(src: A) -> B
```

**Description:** Reinterprets the bits of a value of one type as another type.

**Constraints:** A and B must have the exactly same size.

---

```sway
__runtime_mem_id<T>() -> u64
__encoding_mem_id<T> -> u64
```

**Description:** Returns an opaque number that identifies the memory representation of a type. No information is conveyed by this number and should only be compared for equality.

This number is not guaranteed to be stable on different compiler versions.

`__runtime_mem_id` represents how the type is represented inside the VM.

`__encoding_mem_id` represents how the type is encoded. It returns 0 when a type does not have encoding representation.

**Constraints:** None
8 changes: 4 additions & 4 deletions forc-plugins/forc-client/tests/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ async fn test_simple_deploy() {
node.kill().unwrap();
let expected = vec![DeployedPackage::Contract(DeployedContract {
id: ContractId::from_str(
"307a59fbb6888da41942653ca21d9c71e06d72edb58b8d775eea87c7e755ebdb",
"e3e0f5c8c9585a7dc6673775a73104acc847905b5e7ea085db822241444fee7e",
)
.unwrap(),
proxy: None,
Expand Down Expand Up @@ -421,7 +421,7 @@ async fn test_deploy_submit_only() {
node.kill().unwrap();
let expected = vec![DeployedPackage::Contract(DeployedContract {
id: ContractId::from_str(
"307a59fbb6888da41942653ca21d9c71e06d72edb58b8d775eea87c7e755ebdb",
"e3e0f5c8c9585a7dc6673775a73104acc847905b5e7ea085db822241444fee7e",
)
.unwrap(),
proxy: None,
Expand Down Expand Up @@ -468,12 +468,12 @@ async fn test_deploy_fresh_proxy() {
node.kill().unwrap();
let impl_contract = DeployedPackage::Contract(DeployedContract {
id: ContractId::from_str(
"307a59fbb6888da41942653ca21d9c71e06d72edb58b8d775eea87c7e755ebdb",
"e3e0f5c8c9585a7dc6673775a73104acc847905b5e7ea085db822241444fee7e",
)
.unwrap(),
proxy: Some(
ContractId::from_str(
"70a447780b00c9725859bbef1cd327a9455cc62fbe607a0524b2c82a5846f5a9",
"92343c25e373958aee4cecfe58ab6533261b5f54de471291c22ee05182d39122",
)
.unwrap(),
),
Expand Down
8 changes: 4 additions & 4 deletions forc/tests/cli_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ fn test_forc_test_raw_logs() -> Result<(), rexpect::error::Error> {
// Assert that the output is correct
process.exp_string(" test test_log_4")?;
process.exp_string("raw logs:")?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12044,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12312,"ptr":67108856,"ra":0,"rb":1515152261580153489}}]"#)?;
process.exp_string(" test test_log_2")?;
process.exp_string("raw logs:")?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12044,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12312,"ptr":67108856,"ra":0,"rb":1515152261580153489}}]"#)?;

process.process.exit()?;
Ok(())
Expand All @@ -77,12 +77,12 @@ fn test_forc_test_both_logs() -> Result<(), rexpect::error::Error> {
process.exp_string("decoded log values:")?;
process.exp_string("4, log rb: 1515152261580153489")?;
process.exp_string("raw logs:")?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12044,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12312,"ptr":67108856,"ra":0,"rb":1515152261580153489}}]"#)?;
process.exp_string(" test test_log_2")?;
process.exp_string("decoded log values:")?;
process.exp_string("2, log rb: 1515152261580153489")?;
process.exp_string("raw logs:")?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12044,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12312,"ptr":67108856,"ra":0,"rb":1515152261580153489}}]"#)?;
process.process.exit()?;
Ok(())
}
6 changes: 6 additions & 0 deletions sway-ast/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ pub enum Intrinsic {
ElemAt, // let elem: &T = __elem_at::<T: array or ref_to_slice>(item: T, index)
Transmute, // let dst: B = __transmute::<A, B>(src)
Dbg, // __dbg(value)
RuntimeMemoryId, // __runtime_mem_id::<T>() -> u64
EncodingMemoryId, // __encoding_mem_id::<T>() -> u64
}

impl fmt::Display for Intrinsic {
Expand Down Expand Up @@ -94,6 +96,8 @@ impl fmt::Display for Intrinsic {
Intrinsic::ElemAt => "elem_at",
Intrinsic::Transmute => "transmute",
Intrinsic::Dbg => "dbg",
Intrinsic::RuntimeMemoryId => "runtime_mem_id",
Intrinsic::EncodingMemoryId => "encoding_mem_id",
};
write!(f, "{s}")
}
Expand Down Expand Up @@ -146,6 +150,8 @@ impl Intrinsic {
"__elem_at" => ElemAt,
"__transmute" => Transmute,
"__dbg" => Dbg,
"__runtime_mem_id" => RuntimeMemoryId,
"__encoding_mem_id" => EncodingMemoryId,
_ => return None,
})
}
Expand Down
46 changes: 46 additions & 0 deletions sway-core/src/ir_generation/const_eval.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use std::{
hash::{DefaultHasher, Hash},
io::Read,
ops::{BitAnd, BitOr, BitXor, Not, Rem},
};

use crate::{
engine_threading::*,
ir_generation::function::{get_encoding_representation, get_memory_id},
language::{
ty::{self, TyConstantDecl, TyIntrinsicFunctionKind},
CallPath, Literal,
Expand Down Expand Up @@ -1693,6 +1695,50 @@ fn const_eval_intrinsic(
Intrinsic::Dbg => {
unreachable!("__dbg should not exist in the typed tree")
}
Intrinsic::RuntimeMemoryId => {
assert!(intrinsic.type_arguments.len() == 1);
assert!(intrinsic.arguments.is_empty());

let t = &intrinsic.type_arguments[0];
let t = convert_resolved_type_id(
lookup.engines,
lookup.context,
lookup.md_mgr,
lookup.module,
lookup.function_compiler,
t.type_id(),
&t.span(),
)
.unwrap();

let id = get_memory_id(lookup.context, t);
let c = ConstantContent {
ty: Type::get_uint64(lookup.context),
value: ConstantValue::Uint(id),
};

Ok(Some(Constant::unique(lookup.context, c)))
}
Intrinsic::EncodingMemoryId => {
assert!(intrinsic.type_arguments.len() == 1);
assert!(intrinsic.arguments.is_empty());

let t = intrinsic.type_arguments[0].as_type_argument().unwrap();

let r = get_encoding_representation(lookup.engines, t.type_id);

use std::hash::Hasher;
let mut state = DefaultHasher::default();
r.hash(&mut state);
let id = state.finish();

let c = ConstantContent {
ty: Type::get_uint64(lookup.context),
value: ConstantValue::Uint(id),
};

Ok(Some(Constant::unique(lookup.context, c)))
}
}
}

Expand Down
Loading
Loading