Skip to content
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

[move][ir-to-bytecode] Add source locations to Type in the Move IR #19875

Merged
merged 1 commit into from
Oct 16, 2024
Merged
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
30 changes: 15 additions & 15 deletions external-crates/move/crates/module-generation/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,12 @@ impl<'a> ModuleGenerator<'a> {
if !structs.is_empty() {
end += 1;
};

match self.index(end) {
0 => Type::Address,
1 => Type::U8,
2 => Type::U64,
3 => Type::U128,
4 => Type::Bool,
let type_ = match self.index(end) {
0 => Type_::Address,
1 => Type_::U8,
2 => Type_::U64,
3 => Type_::U128,
4 => Type_::Bool,
5 if !structs.is_empty() => {
let index = self.index(structs.len());
let struct_def = structs[index].value.clone();
Expand All @@ -133,17 +132,18 @@ impl<'a> ModuleGenerator<'a> {
let module_name = ModuleName::module_self();
QualifiedDatatypeIdent::new(module_name, struct_name)
};
Type::Datatype(struct_ident, ty_instants)
Type_::Datatype(struct_ident, ty_instants)
}
6 => Type::U16,
7 => Type::U32,
8 => Type::U256,
6 => Type_::U16,
7 => Type_::U32,
8 => Type_::U256,
_ => {
let index = self.index(ty_param_context.len());
let ty_var = ty_param_context[index].value.clone();
Type::TypeParameter(ty_var)
Type_::TypeParameter(ty_var)
}
}
};
Spanned::unsafe_no_loc(type_)
}

fn typ(&mut self, ty_param_context: &[(TypeVar, BTreeSet<Ability>)]) -> Type {
Expand All @@ -158,7 +158,7 @@ impl<'a> ModuleGenerator<'a> {
// if typ.is_nominal_resource { .... }
if self.options.references_allowed && self.gen.gen_bool(0.25) {
let is_mutable = self.gen.gen_bool(0.25);
Type::Reference(is_mutable, Box::new(typ))
Spanned::unsafe_no_loc(Type_::Reference(is_mutable, Box::new(typ)))
} else {
typ
}
Expand Down Expand Up @@ -209,7 +209,7 @@ impl<'a> ModuleGenerator<'a> {
.iter()
.map(|(ty_var_, _)| {
let param_name = Spanned::unsafe_no_loc(Var_(self.identifier().into()));
let ty = Type::TypeParameter(ty_var_.value.clone());
let ty = Spanned::unsafe_no_loc(Type_::TypeParameter(ty_var_.value.clone()));
(param_name, ty)
})
.collect();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -811,11 +811,11 @@ fn base_types(context: &mut Context, bs: Vec<H::BaseType>) -> Vec<IR::Type> {
bs.into_iter().map(|b| base_type(context, b)).collect()
}

fn base_type(context: &mut Context, sp!(_, bt_): H::BaseType) -> IR::Type {
fn base_type(context: &mut Context, sp!(bt_loc, bt_): H::BaseType) -> IR::Type {
use BuiltinTypeName_ as BT;
use H::{BaseType_ as B, TypeName_ as TN};
use IR::Type as IRT;
match bt_ {
use IR::Type_ as IRT;
let type_ = match bt_ {
B::Unreachable | B::UnresolvedError => {
panic!("ICE should not have reached compilation if there are errors")
}
Expand Down Expand Up @@ -845,15 +845,19 @@ fn base_type(context: &mut Context, sp!(_, bt_): H::BaseType) -> IR::Type {
user_specified_name,
..
}) => IRT::TypeParameter(type_var(user_specified_name).value),
}
};
sp(bt_loc, type_)
}

fn single_type(context: &mut Context, sp!(_, st_): H::SingleType) -> IR::Type {
fn single_type(context: &mut Context, sp!(st_loc, st_): H::SingleType) -> IR::Type {
use H::SingleType_ as S;
use IR::Type as IRT;
use IR::Type_ as IRT;
match st_ {
S::Base(bt) => base_type(context, bt),
S::Ref(mut_, bt) => IRT::Reference(mut_, Box::new(base_type(context, bt))),
S::Ref(mut_, bt) => sp(
st_loc,
IRT::Reference(mut_, Box::new(base_type(context, bt))),
),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1330,72 +1330,74 @@ fn parse_ability(tokens: &mut Lexer) -> Result<(Ability, Loc), ParseError<Loc, a
// }

fn parse_type(tokens: &mut Lexer) -> Result<Type, ParseError<Loc, anyhow::Error>> {
let start_loc = tokens.start_loc();
let t = match tokens.peek() {
Tok::NameValue if matches!(tokens.content(), "address") => {
tokens.advance()?;
Type::Address
Type_::Address
}
Tok::NameValue if matches!(tokens.content(), "u8") => {
tokens.advance()?;
Type::U8
Type_::U8
}
Tok::NameValue if matches!(tokens.content(), "u16") => {
tokens.advance()?;
Type::U16
Type_::U16
}
Tok::NameValue if matches!(tokens.content(), "u32") => {
tokens.advance()?;
Type::U32
Type_::U32
}
Tok::NameValue if matches!(tokens.content(), "u64") => {
tokens.advance()?;
Type::U64
Type_::U64
}
Tok::NameValue if matches!(tokens.content(), "u128") => {
tokens.advance()?;
Type::U128
Type_::U128
}
Tok::NameValue if matches!(tokens.content(), "u256") => {
tokens.advance()?;
Type::U256
Type_::U256
}
Tok::NameValue if matches!(tokens.content(), "bool") => {
tokens.advance()?;
Type::Bool
Type_::Bool
}
Tok::NameValue if matches!(tokens.content(), "signer") => {
tokens.advance()?;
Type::Signer
Type_::Signer
}
Tok::NameBeginTyValue if matches!(tokens.content(), "vector<") => {
tokens.advance()?;
let ty = parse_type(tokens)?;
adjust_token(tokens, &[Tok::Greater])?;
consume_token(tokens, Tok::Greater)?;
Type::Vector(Box::new(ty))
Type_::Vector(Box::new(ty))
}
Tok::DotNameValue => {
let s = parse_qualified_struct_ident(tokens)?;
let tys = parse_type_actuals(tokens)?;
Type::Datatype(s, tys)
Type_::Datatype(s, tys)
}
Tok::Amp => {
tokens.advance()?;
Type::Reference(false, Box::new(parse_type(tokens)?))
Type_::Reference(false, Box::new(parse_type(tokens)?))
}
Tok::AmpMut => {
tokens.advance()?;
Type::Reference(true, Box::new(parse_type(tokens)?))
Type_::Reference(true, Box::new(parse_type(tokens)?))
}
Tok::NameValue => Type::TypeParameter(TypeVar_(parse_name(tokens)?)),
Tok::NameValue => Type_::TypeParameter(TypeVar_(parse_name(tokens)?)),
t => {
return Err(ParseError::InvalidToken {
location: current_token_loc(tokens),
message: format!("invalid token kind for type {:?}", t),
})
}
};
Ok(t)
let end_loc = tokens.previous_end_loc();
Ok(spanned(tokens.file_hash(), start_loc, end_loc, t))
}

// TypeVar: TypeVar = {
Expand Down
98 changes: 55 additions & 43 deletions external-crates/move/crates/move-ir-to-bytecode/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ fn constant_name_as_constant_value_index(
) -> Result<ConstantPoolIndex> {
let name_constant = compile_constant(
context,
Type::Vector(Box::new(Type::U8)),
&MoveTypeLayout::Vector(Box::new(MoveTypeLayout::U8)),
MoveValue::vector_u8(const_name.to_string().into_bytes()),
)?;
context.constant_index(name_constant)
Expand Down Expand Up @@ -407,7 +407,11 @@ pub fn compile_module<'a>(
constant_name_as_constant_value_index(&mut context, &ir_constant.name)?;
}

let constant = compile_constant(&mut context, ir_constant.signature, ir_constant.value)?;
let constant = compile_constant(
&mut context,
&type_to_constant_type_layout(ir_constant.signature)?,
ir_constant.value,
)?;
context.declare_constant(ir_constant.name.clone(), constant.clone())?;
let const_idx = context.constant_index(constant)?;
record_src_loc!(const_decl: context, const_idx, ir_constant.name);
Expand Down Expand Up @@ -672,30 +676,30 @@ fn compile_type(
type_parameters: &HashMap<TypeVar_, TypeParameterIndex>,
ty: &Type,
) -> Result<SignatureToken> {
Ok(match ty {
Type::Address => SignatureToken::Address,
Type::Signer => SignatureToken::Signer,
Type::U8 => SignatureToken::U8,
Type::U16 => SignatureToken::U16,
Type::U32 => SignatureToken::U32,
Type::U64 => SignatureToken::U64,
Type::U128 => SignatureToken::U128,
Type::U256 => SignatureToken::U256,
Type::Bool => SignatureToken::Bool,
Type::Vector(inner_type) => SignatureToken::Vector(Box::new(compile_type(
Ok(match &ty.value {
Type_::Address => SignatureToken::Address,
Type_::Signer => SignatureToken::Signer,
Type_::U8 => SignatureToken::U8,
Type_::U16 => SignatureToken::U16,
Type_::U32 => SignatureToken::U32,
Type_::U64 => SignatureToken::U64,
Type_::U128 => SignatureToken::U128,
Type_::U256 => SignatureToken::U256,
Type_::Bool => SignatureToken::Bool,
Type_::Vector(inner_type) => SignatureToken::Vector(Box::new(compile_type(
context,
type_parameters,
inner_type,
)?)),
Type::Reference(is_mutable, inner_type) => {
Type_::Reference(is_mutable, inner_type) => {
let inner_token = Box::new(compile_type(context, type_parameters, inner_type)?);
if *is_mutable {
SignatureToken::MutableReference(inner_token)
} else {
SignatureToken::Reference(inner_token)
}
}
Type::Datatype(ident, tys) => {
Type_::Datatype(ident, tys) => {
let sh_idx = context.datatype_handle_index(ident.clone())?;

if tys.is_empty() {
Expand All @@ -705,7 +709,7 @@ fn compile_type(
SignatureToken::DatatypeInstantiation(Box::new((sh_idx, tokens)))
}
}
Type::TypeParameter(ty_var) => {
Type_::TypeParameter(ty_var) => {
let idx = match type_parameters.get(ty_var) {
None => bail!("Unbound type parameter {}", ty_var),
Some(idx) => *idx,
Expand Down Expand Up @@ -1267,7 +1271,7 @@ fn compile_expression(
Exp_::Value(cv) => match cv.value {
CopyableVal_::Address(address) => {
let address_value = MoveValue::Address(address);
let constant = compile_constant(context, Type::Address, address_value)?;
let constant = compile_constant(context, &MoveTypeLayout::Address, address_value)?;
let idx = context.constant_index(constant)?;
push_instr!(exp.loc, Bytecode::LdConst(idx));
function_frame.push()?;
Expand Down Expand Up @@ -1298,8 +1302,8 @@ fn compile_expression(
}
CopyableVal_::ByteArray(buf) => {
let vec_value = MoveValue::vector_u8(buf);
let ty = Type::Vector(Box::new(Type::U8));
let constant = compile_constant(context, ty, vec_value)?;
let ty = MoveTypeLayout::Vector(Box::new(MoveTypeLayout::U8));
let constant = compile_constant(context, &ty, vec_value)?;
let idx = context.constant_index(constant)?;
push_instr!(exp.loc, Bytecode::LdConst(idx));
function_frame.push()?;
Expand Down Expand Up @@ -1669,30 +1673,38 @@ fn compile_call(
Ok(())
}

fn compile_constant(_context: &mut Context, ty: Type, value: MoveValue) -> Result<Constant> {
fn type_layout(ty: Type) -> Result<MoveTypeLayout> {
Ok(match ty {
Type::Address => MoveTypeLayout::Address,
Type::Signer => MoveTypeLayout::Signer,
Type::U8 => MoveTypeLayout::U8,
Type::U16 => MoveTypeLayout::U16,
Type::U32 => MoveTypeLayout::U32,
Type::U64 => MoveTypeLayout::U64,
Type::U128 => MoveTypeLayout::U128,
Type::U256 => MoveTypeLayout::U256,
Type::Bool => MoveTypeLayout::Bool,
Type::Vector(inner_type) => MoveTypeLayout::Vector(Box::new(type_layout(*inner_type)?)),
Type::Reference(_, _) => bail!("References are not supported in constant type layouts"),
Type::TypeParameter(_) => {
bail!("Type parameters are not supported in constant type layouts")
}
Type::Datatype(_ident, _tys) => {
bail!("TODO Structs are not *yet* supported in constant type layouts")
}
})
}
fn type_to_constant_type_layout(ty: Type) -> Result<MoveTypeLayout> {
Ok(match ty.value {
Type_::Address => MoveTypeLayout::Address,
Type_::Signer => MoveTypeLayout::Signer,
Type_::U8 => MoveTypeLayout::U8,
Type_::U16 => MoveTypeLayout::U16,
Type_::U32 => MoveTypeLayout::U32,
Type_::U64 => MoveTypeLayout::U64,
Type_::U128 => MoveTypeLayout::U128,
Type_::U256 => MoveTypeLayout::U256,
Type_::Bool => MoveTypeLayout::Bool,
Type_::Vector(inner_type) => {
MoveTypeLayout::Vector(Box::new(type_to_constant_type_layout(*inner_type)?))
}
Type_::Reference(_, _) => {
bail!("References are not supported in constant type layouts")
}
Type_::TypeParameter(_) => {
bail!("Type parameters are not supported in constant type layouts")
}
Type_::Datatype(_ident, _tys) => {
bail!("TODO Structs are not *yet* supported in constant type layouts")
}
})
}

Constant::serialize_constant(&type_layout(ty)?, &value)
fn compile_constant(
_context: &mut Context,
layout: &MoveTypeLayout,
value: MoveValue,
) -> Result<Constant> {
Constant::serialize_constant(layout, &value)
.ok_or_else(|| format_err!("Could not serialize constant"))
}

Expand Down Expand Up @@ -1793,7 +1805,7 @@ fn compile_bytecode(
IRBytecode_::LdTrue => Bytecode::LdTrue,
IRBytecode_::LdFalse => Bytecode::LdFalse,
IRBytecode_::LdConst(ty, v) => {
let constant = compile_constant(context, ty, v)?;
let constant = compile_constant(context, &type_to_constant_type_layout(ty)?, v)?;
Bytecode::LdConst(context.constant_index(constant)?)
}
IRBytecode_::LdNamedConst(c) => Bytecode::LdConst(context.named_constant_index(&c)?),
Expand Down
Loading
Loading