Skip to content

Commit d5df284

Browse files
committed
avoid method name encoding by generating the expected format directly
1 parent f7761d6 commit d5df284

File tree

12 files changed

+156
-111
lines changed

12 files changed

+156
-111
lines changed

sway-core/src/ir_generation/convert.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,6 @@ use sway_types::{integer_bits::IntegerBits, span::Span};
1414

1515
pub(super) fn convert_literal_to_value(context: &mut Context, ast_literal: &Literal) -> Value {
1616
match ast_literal {
17-
// In Sway for now we don't have `as` casting and for integers which may be implicitly cast
18-
// between widths we just emit a warning, and essentially ignore it. We also assume a
19-
// 'Numeric' integer of undetermined width is 'u64`. The IR would like to be type
20-
// consistent and doesn't tolerate missing integers of different width, so for now, until we
21-
// do introduce explicit `as` casting, all integers are `u64` as far as the IR is
22-
// concerned.
23-
//
24-
// XXX The above isn't true for other targets. We need to improved this.
25-
// FIXME
2617
Literal::U8(n) => ConstantContent::get_uint(context, 8, *n as u64),
2718
Literal::U16(n) => ConstantContent::get_uint(context, 64, *n as u64),
2819
Literal::U32(n) => ConstantContent::get_uint(context, 64, *n as u64),
@@ -32,6 +23,7 @@ pub(super) fn convert_literal_to_value(context: &mut Context, ast_literal: &Lite
3223
Literal::String(s) => ConstantContent::get_string(context, s.as_str().as_bytes().to_vec()),
3324
Literal::Boolean(b) => ConstantContent::get_bool(context, *b),
3425
Literal::B256(bs) => ConstantContent::get_b256(context, *bs),
26+
Literal::Binary(bytes) => ConstantContent::get_untyped_slice(context, bytes.clone()),
3527
}
3628
}
3729

@@ -40,7 +32,6 @@ pub(super) fn convert_literal_to_constant(
4032
ast_literal: &Literal,
4133
) -> Constant {
4234
let c = match ast_literal {
43-
// All integers are `u64`. See comment above.
4435
Literal::U8(n) => ConstantContent::new_uint(context, 8, *n as u64),
4536
Literal::U16(n) => ConstantContent::new_uint(context, 64, *n as u64),
4637
Literal::U32(n) => ConstantContent::new_uint(context, 64, *n as u64),
@@ -50,6 +41,7 @@ pub(super) fn convert_literal_to_constant(
5041
Literal::String(s) => ConstantContent::new_string(context, s.as_str().as_bytes().to_vec()),
5142
Literal::Boolean(b) => ConstantContent::new_bool(context, *b),
5243
Literal::B256(bs) => ConstantContent::new_b256(context, *bs),
44+
Literal::Binary(_) => todo!(),
5345
};
5446
Constant::unique(context, c)
5547
}

sway-core/src/ir_generation/function.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -457,12 +457,13 @@ impl<'a> FnCompiler<'a> {
457457
))
458458
}
459459

460-
fn compile_string_slice(
460+
// Can be used to raw untyped slice and string slice
461+
fn compile_slice(
461462
&mut self,
462463
context: &mut Context,
463464
span_md_idx: Option<MetadataIndex>,
464-
string_data: Value,
465-
string_len: u64,
465+
slice_ptr: Value,
466+
slice_len: u64,
466467
) -> Result<TerminatorValue, CompileError> {
467468
let int_ty = Type::get_uint64(context);
468469
let ptr_ty = Type::get_ptr(context);
@@ -471,9 +472,9 @@ impl<'a> FnCompiler<'a> {
471472
let ptr_val = self
472473
.current_block
473474
.append(context)
474-
.cast_ptr(string_data, ptr_ty)
475+
.cast_ptr(slice_ptr, ptr_ty)
475476
.add_metadatum(context, span_md_idx);
476-
let len_val = ConstantContent::get_uint(context, 64, string_len);
477+
let len_val = ConstantContent::get_uint(context, 64, slice_len);
477478

478479
// a slice is a pointer and a length
479480
let field_types = vec![ptr_ty, int_ty];
@@ -569,7 +570,24 @@ impl<'a> FnCompiler<'a> {
569570
.append(context)
570571
.get_global(string_data_ptr);
571572
let string_len = s.as_str().len() as u64;
572-
self.compile_string_slice(context, span_md_idx, string_ptr, string_len)
573+
self.compile_slice(context, span_md_idx, string_ptr, string_len)
574+
}
575+
ty::TyExpressionVariant::Literal(Literal::Binary(bytes)) => {
576+
let data = ConstantContent::get_untyped_slice(context, bytes.clone())
577+
.get_constant(context)
578+
.unwrap();
579+
let data_ptr = self.module.new_unique_global_var(
580+
context,
581+
"__const_global".into(),
582+
data.get_content(context).ty,
583+
Some(*data),
584+
false,
585+
);
586+
587+
let slice_ptr = self.current_block.append(context).get_global(data_ptr);
588+
let slice_len = bytes.len() as u64;
589+
590+
self.compile_slice(context, span_md_idx, slice_ptr, slice_len)
573591
}
574592
ty::TyExpressionVariant::Literal(Literal::Numeric(n)) => {
575593
let implied_lit = match &*self.engines.te().get(ast_expr.return_type) {

sway-core/src/language/literal.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub enum Literal {
1919
Numeric(u64),
2020
Boolean(bool),
2121
B256([u8; 32]),
22+
Binary(Vec<u8>),
2223
}
2324

2425
impl Literal {
@@ -74,6 +75,10 @@ impl Hash for Literal {
7475
state.write_u8(8);
7576
x.hash(state);
7677
}
78+
Binary(x) => {
79+
state.write_u8(9);
80+
x.hash(state);
81+
}
7782
}
7883
}
7984
}
@@ -111,6 +116,7 @@ impl fmt::Display for Literal {
111116
.map(|x| x.to_string())
112117
.collect::<Vec<_>>()
113118
.join(", "),
119+
Literal::Binary(_) => todo!(),
114120
};
115121
write!(f, "{s}")
116122
}
@@ -154,6 +160,7 @@ impl Literal {
154160
Literal::U256(_) => TypeInfo::UnsignedInteger(IntegerBits::V256),
155161
Literal::Boolean(_) => TypeInfo::Boolean,
156162
Literal::B256(_) => TypeInfo::B256,
163+
Literal::Binary(_) => todo!(),
157164
}
158165
}
159166
}

sway-core/src/semantic_analysis/ast_node/expression/match_expression/analysis/pattern.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ impl Pattern {
180180
Literal::Boolean(b) => Pattern::Boolean(b),
181181
Literal::Numeric(x) => Pattern::Numeric(Range::from_single(x)),
182182
Literal::String(s) => Pattern::String(s.as_str().to_string()),
183+
Literal::Binary(_) => todo!(),
183184
}
184185
}
185186

sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,7 @@ impl ty::TyExpression {
635635
Literal::U256(_) => type_engine.id_of_u256(),
636636
Literal::Boolean(_) => type_engine.id_of_bool(),
637637
Literal::B256(_) => type_engine.id_of_b256(),
638+
Literal::Binary(_) => type_engine.id_of_raw_slice(),
638639
};
639640
ty::TyExpression {
640641
expression: ty::TyExpressionVariant::Literal(lit),

sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -533,10 +533,17 @@ pub(crate) fn type_check_method_application(
533533
}
534534
}
535535

536-
fn string_slice_literal(ident: &BaseIdent) -> Expression {
536+
fn method_name_literal(method_name: &BaseIdent) -> Expression {
537+
let method_name_str = method_name.as_str().to_string();
538+
let len_bytes = (method_name_str.len() as u64).to_be_bytes();
539+
540+
let mut blob = vec![];
541+
blob.extend(len_bytes);
542+
blob.extend(method_name_str.as_bytes());
543+
537544
Expression {
538-
kind: ExpressionKind::Literal(Literal::String(ident.span())),
539-
span: ident.span(),
545+
kind: ExpressionKind::Literal(Literal::Binary(blob)),
546+
span: method_name.span(),
540547
}
541548
}
542549

@@ -581,7 +588,7 @@ pub(crate) fn type_check_method_application(
581588
&mut ctx,
582589
span,
583590
method.return_type.type_id(),
584-
string_slice_literal(&method.name),
591+
method_name_literal(&method.name),
585592
old_arguments.first().cloned().unwrap(),
586593
args,
587594
arguments.iter().map(|x| x.1.return_type).collect(),

sway-ir/src/constant.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ impl ConstantContent {
120120
}
121121
}
122122

123+
pub fn new_untyped_slice(context: &mut Context, bytes: Vec<u8>) -> Self {
124+
ConstantContent {
125+
ty: Type::new_untyped_slice(context),
126+
value: ConstantValue::RawUntypedSlice(bytes),
127+
}
128+
}
129+
123130
pub fn new_array(context: &mut Context, elm_ty: Type, elems: Vec<ConstantContent>) -> Self {
124131
ConstantContent {
125132
ty: Type::new_array(context, elm_ty, elems.len() as u64),
@@ -181,6 +188,12 @@ impl ConstantContent {
181188
Value::new_constant(context, new_const)
182189
}
183190

191+
pub fn get_untyped_slice(context: &mut Context, value: Vec<u8>) -> Value {
192+
let new_const_contents = ConstantContent::new_untyped_slice(context, value);
193+
let new_const = Constant::unique(context, new_const_contents);
194+
Value::new_constant(context, new_const)
195+
}
196+
184197
/// `value` must be created as an array constant first, using [`Constant::new_array()`].
185198
pub fn get_array(context: &mut Context, value: ConstantContent) -> Value {
186199
assert!(value.ty.is_array(context));

sway-ir/src/irtype.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ impl Type {
140140
Self::get_type(context, &TypeContent::Pointer).expect("create_basic_types not called")
141141
}
142142

143+
pub fn new_untyped_slice(context: &mut Context) -> Type {
144+
Self::get_or_create_unique_type(context, TypeContent::Slice)
145+
}
146+
143147
/// Get string type
144148
pub fn new_string_array(context: &mut Context, len: u64) -> Type {
145149
Self::get_or_create_unique_type(context, TypeContent::StringArray(len))

sway-lib-std/src/codec.sw

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5347,9 +5347,10 @@ where
53475347
// END TUPLES_DECODE
53485348
use ::ops::*;
53495349

5350+
#[inline(never)]
53505351
pub fn contract_call<T, TArgs>(
53515352
contract_id: b256,
5352-
method_name: str,
5353+
method_name: raw_slice,
53535354
args: TArgs,
53545355
coins: u64,
53555356
asset_id: b256,
@@ -5359,11 +5360,10 @@ where
53595360
T: AbiDecode,
53605361
TArgs: AbiEncode,
53615362
{
5362-
let first_parameter = encode(method_name);
53635363
let second_parameter = encode(args);
53645364
let params = encode((
53655365
contract_id,
5366-
asm(a: first_parameter.ptr()) {
5366+
asm(a: method_name.ptr()) {
53675367
a: u64
53685368
},
53695369
asm(a: second_parameter.ptr()) {

sway-lsp/src/traverse/parsed_tree.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,5 +1241,6 @@ fn literal_to_symbol_kind(value: &Literal) -> SymbolKind {
12411241
Literal::String(..) => SymbolKind::StringLiteral,
12421242
Literal::B256(..) => SymbolKind::ByteLiteral,
12431243
Literal::Boolean(..) => SymbolKind::BoolLiteral,
1244+
Literal::Binary(_) => todo!(),
12441245
}
12451246
}

0 commit comments

Comments
 (0)