Skip to content
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
61 changes: 29 additions & 32 deletions crates/gen-c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ impl C {
TypeDefKind::Record(r) if r.is_flags() => false,
TypeDefKind::Record(_) | TypeDefKind::List(_) => true,
},
Type::String => true,
_ => false,
}
}
Expand Down Expand Up @@ -230,6 +231,11 @@ impl C {
self.src.h(&iface.resources[*id].name.to_snake_case());
self.src.h("_t");
}
Type::String => {
self.print_namespace(iface);
self.src.h("string_t");
self.needs_string = true;
}
Type::Id(id) => {
let ty = &iface.types[*id];
if let Some(name) = &ty.name {
Expand All @@ -250,11 +256,6 @@ impl C {
self.print_ty_name(iface, &Type::Id(*id));
self.src.h("_t");
}
TypeDefKind::List(Type::Char) => {
self.print_namespace(iface);
self.src.h("string_t");
self.needs_string = true;
}
TypeDefKind::Record(_) | TypeDefKind::List(_) => {
self.public_anonymous_types.insert(*id);
self.private_anonymous_types.remove(id);
Expand All @@ -281,6 +282,7 @@ impl C {
Type::Float32 => self.src.h("float32"),
Type::Float64 => self.src.h("float64"),
Type::Handle(id) => self.src.h(&iface.resources[*id].name.to_snake_case()),
Type::String => self.src.h("string"),
Type::Id(id) => {
let ty = &iface.types[*id];
if let Some(name) = &ty.name {
Expand Down Expand Up @@ -318,7 +320,6 @@ impl C {
unimplemented!();
}
}
TypeDefKind::List(Type::Char) => self.src.h("string"),
TypeDefKind::List(t) => {
self.src.h("list_");
self.print_ty_name(iface, t);
Expand Down Expand Up @@ -484,14 +485,10 @@ impl C {
self.free(iface, t, "&ptr->ptr[i]");
self.src.c("}\n");
}
let (size, align) = if *t == Type::Char {
(1, 1)
} else {
(self.sizes.size(t), self.sizes.align(t))
};
self.src.c(&format!(
"canonical_abi_free(ptr->ptr, ptr->len * {}, {});\n",
size, align,
self.sizes.size(t),
self.sizes.align(t),
));
}

Expand Down Expand Up @@ -524,6 +521,7 @@ impl C {
fn owns_anything(&self, iface: &Interface, ty: &Type) -> bool {
let id = match ty {
Type::Id(id) => *id,
Type::String => return true,
Type::Handle(_) => return true,
_ => return false,
};
Expand Down Expand Up @@ -568,6 +566,10 @@ impl Return {
fn return_single(&mut self, iface: &Interface, ty: &Type, orig_ty: &Type) {
let id = match ty {
Type::Id(id) => *id,
Type::String => {
self.retptrs.push(*orig_ty);
return;
}
_ => {
self.scalar = Some(Scalar::Type(*orig_ty));
return;
Expand Down Expand Up @@ -799,17 +801,11 @@ impl Generator for C {
fn type_list(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
let prev = mem::take(&mut self.src.header);
self.docs(docs);
if *ty == Type::Char {
self.src.h("typedef ");
self.print_namespace(iface);
self.src.h("string_t ");
} else {
self.src.h("typedef struct {\n");
self.print_ty(iface, ty);
self.src.h(" *ptr;\n");
self.src.h("size_t len;\n");
self.src.h("} ");
}
self.src.h("typedef struct {\n");
self.print_ty(iface, ty);
self.src.h(" *ptr;\n");
self.src.h("size_t len;\n");
self.src.h("} ");
self.print_namespace(iface);
self.src.h(&name.to_snake_case());
self.src.h("_t;\n");
Expand Down Expand Up @@ -1518,21 +1514,25 @@ impl Bindgen for FunctionBindgen<'_> {
results.push(result);
}

Instruction::ListCanonLower { .. } => {
Instruction::ListCanonLower { .. } | Instruction::StringLower { .. } => {
results.push(format!("(int32_t) ({}).ptr", operands[0]));
results.push(format!("(int32_t) ({}).len", operands[0]));
}
Instruction::ListCanonLift { element, ty, .. } => {
let list_name = self.gen.type_string(iface, &Type::Id(*ty));
let elem_name = match element {
Type::Char => "char".into(),
_ => self.gen.type_string(iface, element),
};
let elem_name = self.gen.type_string(iface, element);
results.push(format!(
"({}) {{ ({}*)({}), (size_t)({}) }}",
list_name, elem_name, operands[0], operands[1]
));
}
Instruction::StringLift { .. } => {
let list_name = self.gen.type_string(iface, &Type::String);
results.push(format!(
"({}) {{ (char*)({}), (size_t)({}) }}",
list_name, operands[0], operands[1]
));
}

Instruction::ListLower { .. } => {
let _body = self.blocks.pop().unwrap();
Expand All @@ -1543,10 +1543,7 @@ impl Bindgen for FunctionBindgen<'_> {
Instruction::ListLift { element, ty, .. } => {
let _body = self.blocks.pop().unwrap();
let list_name = self.gen.type_string(iface, &Type::Id(*ty));
let elem_name = match element {
Type::Char => "char".into(),
_ => self.gen.type_string(iface, element),
};
let elem_name = self.gen.type_string(iface, element);
results.push(format!(
"({}) {{ ({}*)({}), (size_t)({}) }}",
list_name, elem_name, operands[0], operands[1]
Expand Down
1 change: 1 addition & 0 deletions crates/gen-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ impl Types {
let mut info = TypeInfo::default();
match ty {
Type::Handle(_) => info.has_handle = true,
Type::String => info.has_list = true,
Type::Id(id) => return self.type_id_info(iface, *id),
_ => {}
}
Expand Down
129 changes: 70 additions & 59 deletions crates/gen-js/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ impl Js {
Type::Float64 => Some("Float64Array"),
Type::Char => None,
Type::Handle(_) => None,
Type::String => None,
Type::Id(id) => match &iface.types[*id].kind {
TypeDefKind::Type(t) => self.array_ty(iface, t),
_ => None,
Expand All @@ -155,6 +156,7 @@ impl Js {
Type::U64 | Type::S64 => self.src.ts("bigint"),
Type::Char => self.src.ts("string"),
Type::Handle(id) => self.src.ts(&iface.resources[*id].name.to_camel_case()),
Type::String => self.src.ts("string"),
Type::Id(id) => {
let ty = &iface.types[*id];
if let Some(name) = &ty.name {
Expand Down Expand Up @@ -201,12 +203,8 @@ impl Js {
match self.array_ty(iface, ty) {
Some(ty) => self.src.ts(ty),
None => {
if let Type::Char = ty {
self.src.ts("string");
} else {
self.print_ty(iface, ty);
self.src.ts("[]");
}
self.print_ty(iface, ty);
self.src.ts("[]");
}
}
}
Expand Down Expand Up @@ -1629,34 +1627,20 @@ impl Bindgen for FunctionBindgen<'_> {
self.needs_realloc = Some(realloc.to_string());
let tmp = self.tmp();

match element {
Type::Char => {
let encode = self.gen.intrinsic(Intrinsic::Utf8Encode);
self.src.js(&format!(
"const ptr{} = {}({}, realloc, memory);\n",
tmp, encode, operands[0],
));
let encoded_len = self.gen.intrinsic(Intrinsic::Utf8EncodedLen);
self.src
.js(&format!("const len{} = {};\n", tmp, encoded_len));
}
_ => {
let size = self.gen.sizes.size(element);
let align = self.gen.sizes.align(element);
self.src
.js(&format!("const val{} = {};\n", tmp, operands[0]));
self.src.js(&format!("const len{} = val{0}.length;\n", tmp));
self.src.js(&format!(
"const ptr{} = realloc(0, 0, {}, len{0} * {});\n",
tmp, align, size,
));
// TODO: this is the wrong endianness
self.src.js(&format!(
"(new Uint8Array(memory.buffer, ptr{0}, len{0} * {1})).set(new Uint8Array(val{0}.buffer, val{0}.byteOffset, len{0} * {1}));\n",
tmp, size,
));
}
};
let size = self.gen.sizes.size(element);
let align = self.gen.sizes.align(element);
self.src
.js(&format!("const val{} = {};\n", tmp, operands[0]));
self.src.js(&format!("const len{} = val{0}.length;\n", tmp));
self.src.js(&format!(
"const ptr{} = realloc(0, 0, {}, len{0} * {});\n",
tmp, align, size,
));
// TODO: this is the wrong endianness
self.src.js(&format!(
"(new Uint8Array(memory.buffer, ptr{0}, len{0} * {1})).set(new Uint8Array(val{0}.buffer, val{0}.byteOffset, len{0} * {1}));\n",
tmp, size,
));
results.push(format!("ptr{}", tmp));
results.push(format!("len{}", tmp));
}
Expand All @@ -1667,31 +1651,15 @@ impl Bindgen for FunctionBindgen<'_> {
.js(&format!("const ptr{} = {};\n", tmp, operands[0]));
self.src
.js(&format!("const len{} = {};\n", tmp, operands[1]));
let (result, align) = match element {
Type::Char => {
let decoder = self.gen.intrinsic(Intrinsic::Utf8Decoder);
(
format!(
"{}.decode(new Uint8Array(memory.buffer, ptr{}, len{1}))",
decoder, tmp,
),
1,
)
}
_ => {
// TODO: this is the wrong endianness
let array_ty = self.gen.array_ty(iface, element).unwrap();
(
format!(
"new {}(memory.buffer.slice(ptr{}, ptr{1} + len{1} * {}))",
array_ty,
tmp,
self.gen.sizes.size(element),
),
self.gen.sizes.align(element),
)
}
};
// TODO: this is the wrong endianness
let array_ty = self.gen.array_ty(iface, element).unwrap();
let result = format!(
"new {}(memory.buffer.slice(ptr{}, ptr{1} + len{1} * {}))",
array_ty,
tmp,
self.gen.sizes.size(element),
);
let align = self.gen.sizes.align(element);
match free {
Some(free) => {
self.needs_free = Some(free.to_string());
Expand All @@ -1703,6 +1671,49 @@ impl Bindgen for FunctionBindgen<'_> {
None => results.push(result),
}
}
Instruction::StringLower { realloc } => {
// Lowering only happens when we're passing strings into wasm,
// which forces us to always allocate, so this should always be
// `Some`.
let realloc = realloc.unwrap();
self.gen.needs_get_export = true;
self.needs_memory = true;
self.needs_realloc = Some(realloc.to_string());
let tmp = self.tmp();

let encode = self.gen.intrinsic(Intrinsic::Utf8Encode);
self.src.js(&format!(
"const ptr{} = {}({}, realloc, memory);\n",
tmp, encode, operands[0],
));
let encoded_len = self.gen.intrinsic(Intrinsic::Utf8EncodedLen);
self.src
.js(&format!("const len{} = {};\n", tmp, encoded_len));
results.push(format!("ptr{}", tmp));
results.push(format!("len{}", tmp));
}
Instruction::StringLift { free } => {
self.needs_memory = true;
let tmp = self.tmp();
self.src
.js(&format!("const ptr{} = {};\n", tmp, operands[0]));
self.src
.js(&format!("const len{} = {};\n", tmp, operands[1]));
let decoder = self.gen.intrinsic(Intrinsic::Utf8Decoder);
let result = format!(
"{}.decode(new Uint8Array(memory.buffer, ptr{}, len{1}))",
decoder, tmp,
);
match free {
Some(free) => {
self.needs_free = Some(free.to_string());
self.src.js(&format!("const list{} = {};\n", tmp, result));
self.src.js(&format!("free(ptr{}, len{0}, 1);\n", tmp));
results.push(format!("list{}", tmp));
}
None => results.push(result),
}
}

Instruction::ListLower { element, realloc } => {
let realloc = realloc.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion crates/gen-markdown/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ impl Markdown {
Type::Float32 => self.src.push_str("`float32`"),
Type::Float64 => self.src.push_str("`float64`"),
Type::Char => self.src.push_str("`char`"),
Type::String => self.src.push_str("`string`"),
Type::Handle(id) => {
self.src.push_str("handle<");
self.src.push_str(&iface.resources[*id].name);
Expand Down Expand Up @@ -99,7 +100,6 @@ impl Markdown {
unreachable!()
}
}
TypeDefKind::List(Type::Char) => self.src.push_str("`string`"),
TypeDefKind::List(t) => {
self.src.push_str("list<");
self.print_ty(iface, t, false);
Expand Down
Loading