From f47074c2955d97c581255886b6597bbc95a4ff10 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 26 Jul 2026 00:55:32 +0100 Subject: Implement shared values for rust-transient-0 --- .../rusttransient0/RustTransient0Generator.java | 179 +++++++++++++++++++-- .../compiler/output/lang/rust/RustTypes.java | 34 +++- 2 files changed, 198 insertions(+), 15 deletions(-) (limited to 'src/main/java/org/zwobble') diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java index af28e96..e37a974 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java @@ -29,6 +29,7 @@ public class RustTransient0Generator implements Generator { private static final RustIdentifier VALUE_NAME = RustIdentifier.of("value"); private static final RustIdentifier READER_NAME = RustIdentifier.of("reader"); private static final RustIdentifier WRITER_NAME = RustIdentifier.of("writer"); + private static final RustIdentifier SHARED_VALUES_NAME = RustIdentifier.of("shared_values"); public static OutputConfig parseGeneratorConfig( Path projectRoot, @@ -508,7 +509,13 @@ public class RustTransient0Generator implements Generator { encodeMethodName(type), List.of( new RustFunctionParam(VALUE_NAME, new RustSharedReferenceType(rustType)), - new RustFunctionParam(WRITER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Write")))) + new RustFunctionParam(WRITER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Write")))), + new RustFunctionParam( + SHARED_VALUES_NAME, + new RustMutableReferenceType( + RustTypes.hashMap(RustTypes.USIZE, RustPath.primitive("i64")) + ) + ) ), Optional.of( RustPath.global("std", "io", "Result") @@ -536,7 +543,10 @@ public class RustTransient0Generator implements Generator { Optional.of(RustVisibility.PUB), decodeMethodName(type), List.of( - new RustFunctionParam(READER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Read")))) + new RustFunctionParam(READER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Read")))), + new RustFunctionParam(SHARED_VALUES_NAME, new RustMutableReferenceType( + RustTypes.vec(RustTypes.arc(RustTypes.dyn(RustTypes.ANY, RustTypes.SYNC, RustTypes.SEND))) + )) ), Optional.of(RustPath.global("std", "io", "Result").withArgs(List.of(rustType))), Optional.of(new RustBlockExpression( @@ -637,7 +647,7 @@ public class RustTransient0Generator implements Generator { return new RustExpressionStatement(new RustTryPropagationExpression(new RustCallExpression( rustEncodeFunctionPath, - List.of(value, RustPath.of(WRITER_NAME)) + List.of(value, RustPath.of(WRITER_NAME), RustPath.of(SHARED_VALUES_NAME)) ))); } @@ -652,7 +662,7 @@ public class RustTransient0Generator implements Generator { return new RustTryPropagationExpression(new RustCallExpression( rustDecodeFunctionPath, - List.of(RustPath.of(READER_NAME)) + List.of(RustPath.of(READER_NAME), RustPath.of(SHARED_VALUES_NAME)) )); } @@ -784,20 +794,161 @@ public class RustTransient0Generator implements Generator { } private RustStatement generateEncodeShared(RustExpression value, Type type) { - return generateEncode( - new RustCallExpression( - new RustFieldExpression(value, RustIdentifier.of("as_ref")), - List.of() + var ptr = RustIdentifier.of("ptr"); + var id = RustIdentifier.of("id"); + + return new RustExpressionStatement(new RustBlockExpression( + List.of( + new RustLetStatement( + ptr, + false, + new RustTypeCastExpression( + new RustCallExpression( + RustTypes.ARC.addSegment(RustPathSegment.of("as_ptr")), + List.of(new RustPrefixExpression(RustPrefixOperator.BORROW, value)) + ), + RustTypes.USIZE + ) + ), + new RustExpressionStatement(new RustMatchExpression( + methodCall( + methodCall( + RustPath.of(SHARED_VALUES_NAME), + RustIdentifier.of("get"), + List.of(new RustPrefixExpression(RustPrefixOperator.BORROW, RustPath.of(ptr))) + ), + RustIdentifier.of("copied"), + List.of() + ), + List.of( + new RustMatchArm( + new RustTupleStructPattern(RustTypes.SOME, List.of(new RustIdentifierPattern(id))), + new RustBlockExpression( + List.of( + generateEncode( + new RustPrefixExpression(RustPrefixOperator.BORROW, RustPath.of(id)), + NativeTypes.INT_64 + ) + ), + Optional.empty() + ) + ), + new RustMatchArm( + new RustPathPattern(RustTypes.NONE), + new RustBlockExpression( + List.of( + new RustLetStatement( + id, + false, + tryIntoOrInvalidData( + methodCall(RustPath.of(SHARED_VALUES_NAME), RustIdentifier.of("len"), List.of()) + ) + ), + generateEncode( + new RustPrefixExpression(RustPrefixOperator.BORROW, RustPath.of(id)), + NativeTypes.INT_64 + ), + new RustExpressionStatement( + methodCall( + RustPath.of(SHARED_VALUES_NAME), + RustIdentifier.of("insert"), + List.of(RustPath.of(ptr), RustPath.of(id)) + ) + ), + generateEncode( + new RustCallExpression( + new RustFieldExpression(value, RustIdentifier.of("as_ref")), + List.of() + ), + type + ) + ), + Optional.empty() + ) + ) + ) + )) ), - type - ); + Optional.empty() + )); } private RustExpression generateDecodeShared(Type type) { - var value = generateDecode(type); - return new RustCallExpression( - RustPath.global("std", "sync", "Arc", "new"), - List.of(value) + var id = RustIdentifier.of("id"); + var decodedValue = RustIdentifier.of("decoded_value"); + + return new RustBlockExpression( + List.of( + new RustLetStatement( + id, + false, + generateDecode(NativeTypes.INT_64) + ) + ), + Optional.of(new RustIfExpression( + new RustBinaryExpression( + RustBinaryOperator.LESS_THAN, + RustPath.of(id), + tryIntoOrInvalidData(methodCall( + RustPath.of(SHARED_VALUES_NAME), + RustIdentifier.of("len"), + List.of() + )) + ), + new RustBlockExpression( + List.of(), + Optional.of( + methodCall( + methodCall( + new RustCallExpression( + RustTypes.ARC.addSegment(RustPathSegment.of("clone")), + List.of( + new RustPrefixExpression(RustPrefixOperator.BORROW, new RustIndexExpression( + RustPath.of(SHARED_VALUES_NAME), + // TODO: use try_into() + new RustTypeCastExpression(RustPath.of(id), RustTypes.USIZE) + )) + ) + ), + RustIdentifier.of("downcast"), + List.of() + ), + // TODO: remove unwrap + RustIdentifier.of("unwrap"), + List.of() + ) + ) + ), + new RustBlockExpression( + List.of( + new RustLetStatement( + decodedValue, + false, + new RustCallExpression( + RustTypes.ARC.addSegment(RustPathSegment.of("new")), + List.of(generateDecode(type)) + ) + ), + new RustExpressionStatement(methodCall( + RustPath.of(SHARED_VALUES_NAME), + RustIdentifier.of("push"), + List.of( + new RustTypeCastExpression( + new RustCallExpression( + RustTypes.ARC.addSegment(RustPathSegment.of("clone")), + List.of(new RustPrefixExpression( + RustPrefixOperator.BORROW, + RustPath.of(decodedValue) + )) + ), + RustTypes.arc(RustTypes.dyn(RustTypes.ANY, RustTypes.SYNC, RustTypes.SEND)) + ) + ) + )) + ), + Optional.of(RustPath.of(decodedValue)) + ) + )) ); } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java index c3d1cf0..1e43a24 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java @@ -1,20 +1,52 @@ package org.zwobble.hobgoblin.compiler.output.lang.rust; import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPath; +import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType; import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType; +import java.util.Arrays; import java.util.List; public class RustTypes { private RustTypes() {} + public static RustType dyn(RustPath... bounds) { + return new RustTraitObjectType(Arrays.asList(bounds)); + } + public static RustPath BOOL = RustPath.primitive("bool"); public static RustPath I32 = RustPath.primitive("i32"); public static RustPath I64 = RustPath.primitive("i64"); - public static RustPath STRING = RustPath.global("std", "string", "String"); + public static RustPath USIZE = RustPath.primitive("usize"); + + public static RustPath ANY = RustPath.global("std", "any", "Any"); public static RustPath box(RustType elementType) { return RustPath.global("std", "boxed", "Box") .withArgs(List.of(elementType)); } + + public static RustPath hashMap(RustType keyType, RustType valueType) { + return RustPath.global("std", "collections", "HashMap") + .withArgs(List.of(keyType, valueType)); + } + + public static RustPath SEND = RustPath.global("std", "marker", "Send"); + public static RustPath SYNC = RustPath.global("std", "marker", "Sync"); + + public static RustPath NONE = RustPath.global("std", "option", "Option", "None"); + public static RustPath SOME = RustPath.global("std", "option", "Option", "Some"); + + public static RustPath STRING = RustPath.global("std", "string", "String"); + + public static RustPath ARC = RustPath.global("std", "sync", "Arc"); + + public static RustPath arc(RustType innerType) { + return ARC.withArgs(List.of(innerType)); + } + + public static RustPath vec(RustType elementType) { + return RustPath.global("std", "vec", "Vec") + .withArgs(List.of(elementType)); + } } -- cgit v1.2.3