Skip to content

Commit 0234aa2

Browse files
authored
update the Java guest generator for world-based generation (#405)
We now generate a top-level class for the world, which contains any tuple, result, and cleanup types, as well as the return area (if needed) and the custom section directive for the component type. Each imported or exported interface also gets its own top level file in the same package as the world class. Signed-off-by: Joel Dice <joel.dice@fermyon.com> Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent 407d892 commit 0234aa2

17 files changed

Lines changed: 891 additions & 1062 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,16 @@ These generators are for creating guest modules that import/export WIT types.
8787
for Rust as well. With C the `wit-bindgen` CLI tool will emit a `*.h` and a
8888
`*.c` file to be compiled into the wasm module.
8989

90+
* `teavm-java` - this is for Java bytecode compiled to WebAssembly using
91+
[TeaVM-WASI](https://github.com/fermyon/teavm-wasi). With this generator,
92+
`wit-bindgen` will emit a `*.java` file which may be used with any JVM
93+
language, e.g. Java, Kotlin, Clojure, Scala, etc.
94+
9095
### Hosts
9196

9297
These generators are for hosts interacting with modules that import/export WIT types.
9398

94-
* `wasmtime-rust` - this is for Rust users using the `wasmtime` crate. This generator
99+
* `wasmtime-rust` - this is for Rust users using the `wasmtime` crate. This generator
95100
can also be is used through the `wit-bindgen-host-wasmtime-rust` crate (located at
96101
`crates/host-wasmtime-rust`) and, like the guest Rust support, has an
97102
`import!` and an `export!` macro for generating code.

crates/bindgen-core/src/lib.rs

Lines changed: 1 addition & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -14,156 +14,6 @@ pub use ns::Ns;
1414
#[cfg(feature = "component-generator")]
1515
pub mod component;
1616

17-
/// This is the direction from the user's perspective. Are we importing
18-
/// functions to call, or defining functions and exporting them to be called?
19-
///
20-
/// This is only used outside of `Generator` implementations. Inside of
21-
/// `Generator` implementations, the `Direction` is translated to an
22-
/// `AbiVariant` instead. The ABI variant is usually the same as the
23-
/// `Direction`, but it's different in the case of the Wasmtime host bindings:
24-
///
25-
/// In a wasm-calling-wasm use case, one wasm module would use the `Import`
26-
/// ABI, the other would use the `Export` ABI, and there would be an adapter
27-
/// layer between the two that translates from one ABI to the other.
28-
///
29-
/// But with wasm-calling-host, we don't go through a separate adapter layer;
30-
/// the binding code we generate on the host side just does everything itself.
31-
/// So when the host is conceptually "exporting" a function to wasm, it uses
32-
/// the `Import` ABI so that wasm can also use the `Import` ABI and import it
33-
/// directly from the host.
34-
///
35-
/// These are all implementation details; from the user perspective, and
36-
/// from the perspective of everything outside of `Generator` implementations,
37-
/// `export` means I'm exporting functions to be called, and `import` means I'm
38-
/// importing functions that I'm going to call, in both wasm modules and host
39-
/// code. The enum here represents this user perspective.
40-
#[derive(Copy, Clone, Eq, PartialEq, Default)]
41-
pub enum Direction {
42-
#[default]
43-
Import,
44-
Export,
45-
}
46-
47-
pub trait Generator {
48-
fn preprocess_all(&mut self, imports: &[Interface], exports: &[Interface]) {
49-
drop((imports, exports));
50-
}
51-
52-
fn preprocess_one(&mut self, iface: &Interface, dir: Direction) {
53-
drop((iface, dir));
54-
}
55-
56-
fn type_record(
57-
&mut self,
58-
iface: &Interface,
59-
id: TypeId,
60-
name: &str,
61-
record: &Record,
62-
docs: &Docs,
63-
);
64-
fn type_flags(&mut self, iface: &Interface, id: TypeId, name: &str, flags: &Flags, docs: &Docs);
65-
fn type_tuple(&mut self, iface: &Interface, id: TypeId, name: &str, flags: &Tuple, docs: &Docs);
66-
fn type_variant(
67-
&mut self,
68-
iface: &Interface,
69-
id: TypeId,
70-
name: &str,
71-
variant: &Variant,
72-
docs: &Docs,
73-
);
74-
fn type_option(
75-
&mut self,
76-
iface: &Interface,
77-
id: TypeId,
78-
name: &str,
79-
payload: &Type,
80-
docs: &Docs,
81-
);
82-
fn type_result(
83-
&mut self,
84-
iface: &Interface,
85-
id: TypeId,
86-
name: &str,
87-
result: &Result_,
88-
docs: &Docs,
89-
);
90-
fn type_union(&mut self, iface: &Interface, id: TypeId, name: &str, union: &Union, docs: &Docs);
91-
fn type_enum(&mut self, iface: &Interface, id: TypeId, name: &str, enum_: &Enum, docs: &Docs);
92-
fn type_alias(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs);
93-
fn type_list(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs);
94-
fn type_builtin(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs);
95-
96-
fn preprocess_functions(&mut self, iface: &Interface, dir: Direction) {
97-
drop((iface, dir));
98-
}
99-
fn import(&mut self, iface: &Interface, func: &Function);
100-
fn export(&mut self, iface: &Interface, func: &Function);
101-
fn finish_functions(&mut self, iface: &Interface, dir: Direction) {
102-
drop((iface, dir));
103-
}
104-
105-
fn finish_one(&mut self, iface: &Interface, files: &mut Files);
106-
107-
fn finish_all(&mut self, files: &mut Files) {
108-
drop(files);
109-
}
110-
111-
fn generate_one(&mut self, iface: &Interface, dir: Direction, files: &mut Files) {
112-
self.preprocess_one(iface, dir);
113-
114-
for (id, ty) in iface.types.iter() {
115-
// assert!(ty.foreign_module.is_none()); // TODO
116-
let name = match &ty.name {
117-
Some(name) => name,
118-
None => continue,
119-
};
120-
match &ty.kind {
121-
TypeDefKind::Record(record) => self.type_record(iface, id, name, record, &ty.docs),
122-
TypeDefKind::Flags(flags) => self.type_flags(iface, id, name, flags, &ty.docs),
123-
TypeDefKind::Tuple(tuple) => self.type_tuple(iface, id, name, tuple, &ty.docs),
124-
TypeDefKind::Enum(enum_) => self.type_enum(iface, id, name, enum_, &ty.docs),
125-
TypeDefKind::Variant(variant) => {
126-
self.type_variant(iface, id, name, variant, &ty.docs)
127-
}
128-
TypeDefKind::Option(t) => self.type_option(iface, id, name, t, &ty.docs),
129-
TypeDefKind::Result(r) => self.type_result(iface, id, name, r, &ty.docs),
130-
TypeDefKind::Union(u) => self.type_union(iface, id, name, u, &ty.docs),
131-
TypeDefKind::List(t) => self.type_list(iface, id, name, t, &ty.docs),
132-
TypeDefKind::Type(t) => self.type_alias(iface, id, name, t, &ty.docs),
133-
TypeDefKind::Future(_) => todo!("generate for future"),
134-
TypeDefKind::Stream(_) => todo!("generate for stream"),
135-
}
136-
}
137-
138-
self.preprocess_functions(iface, dir);
139-
140-
for f in iface.functions.iter() {
141-
match dir {
142-
Direction::Import => self.import(iface, f),
143-
Direction::Export => self.export(iface, f),
144-
}
145-
}
146-
147-
self.finish_functions(iface, dir);
148-
149-
self.finish_one(iface, files)
150-
}
151-
152-
fn generate_all(&mut self, imports: &[Interface], exports: &[Interface], files: &mut Files) {
153-
self.preprocess_all(imports, exports);
154-
155-
for imp in imports {
156-
self.generate_one(imp, Direction::Import, files);
157-
}
158-
159-
for exp in exports {
160-
self.generate_one(exp, Direction::Export, files);
161-
}
162-
163-
self.finish_all(files);
164-
}
165-
}
166-
16717
#[derive(Default)]
16818
pub struct Types {
16919
type_info: HashMap<TypeId, TypeInfo>,
@@ -508,7 +358,7 @@ macro_rules! uwriteln {
508358

509359
#[cfg(test)]
510360
mod tests {
511-
use super::{Generator, Source};
361+
use super::Source;
512362

513363
#[test]
514364
fn simple_append() {
@@ -555,11 +405,6 @@ mod tests {
555405
);
556406
assert_eq!(s.s, "function() {\n x\n}");
557407
}
558-
559-
#[test]
560-
fn generator_is_object_safe() {
561-
fn _assert(_: &dyn Generator) {}
562-
}
563408
}
564409

565410
pub trait WorldGenerator {

crates/gen-guest-teavm-java/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ edition.workspace = true
55

66
[dependencies]
77
wit-bindgen-core = { workspace = true }
8+
wit-component = { workspace = true }
89
heck = { workspace = true }
910
clap = { workspace = true, optional = true }
1011

1112
[dev-dependencies]
12-
test-helpers = { path = '../test-helpers', default-features = false }
13+
test-helpers = { path = '../test-helpers', default-features = false, features = ['macros'] }

0 commit comments

Comments
 (0)