Skip to content

Commit aaad87e

Browse files
fix(bindgen): async stream list lower impl
1 parent 2aa4087 commit aaad87e

3 files changed

Lines changed: 115 additions & 38 deletions

File tree

crates/js-component-bindgen/src/intrinsics/lift.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ impl LiftIntrinsic {
308308
Self::LiftFlatU8 => {
309309
let debug_log_fn = Intrinsic::DebugLog.name();
310310
let lift_flat_u8_fn = self.name();
311-
output.push_str(&format!("
311+
output.push_str(&format!(r#"
312312
function {lift_flat_u8_fn}(ctx) {{
313313
{debug_log_fn}('[{lift_flat_u8_fn}()] args', {{ ctx }});
314314
let val;
@@ -331,7 +331,7 @@ impl LiftIntrinsic {
331331
332332
return [val, ctx];
333333
}}
334-
"));
334+
"#));
335335
}
336336

337337
Self::LiftFlatS16 => {
@@ -633,15 +633,17 @@ impl LiftIntrinsic {
633633
return [val, ctx];
634634
}}
635635
636+
const rem = ctx.storagePtr % 4;
637+
if (rem !== 0) {{ ctx.storagePtr += (4 - rem); }}
638+
636639
const dv = new DataView(ctx.memory.buffer);
637640
const start = dv.getUint32(ctx.storagePtr, true);
638641
const codeUnits = dv.getUint32(ctx.storagePtr + 4, true);
642+
639643
val = {decoder}.decode(new Uint8Array(ctx.memory.buffer, start, codeUnits));
640644
641645
ctx.storagePtr += 8;
642-
643-
const rem = ctx.storagePtr % 4;
644-
if (rem !== 0) {{ ctx.storagePtr += (4 - rem); }}
646+
if (ctx.storageLen !== undefined) {{ ctx.storagelen -= 8; }}
645647
646648
return [val, ctx];
647649
}}
@@ -778,7 +780,7 @@ impl LiftIntrinsic {
778780

779781
output.push_str(&format!(r#"
780782
function {lift_flat_list_fn}(meta) {{
781-
const {{ elemLiftFn, size32, align32, knownLen }} = meta;
783+
const {{ elemLiftFn, elemSize32, elemAlign32, knownLen }} = meta;
782784
783785
const readValuesAndReset = (ctx, originalPtr, dataPtr, len) => {{
784786
ctx.storagePtr = dataPtr;
@@ -788,13 +790,15 @@ impl LiftIntrinsic {
788790
val.push(res);
789791
ctx = nextCtx;
790792
791-
const rem = ctx.storagePtr % align32;
792-
if (rem !== 0) {{ ctx.storagePtr += align32 - rem; }}
793+
const rem = ctx.storagePtr % elemAlign32;
794+
if (rem !== 0) {{ ctx.storagePtr += elemAlign32 - rem; }}
793795
}}
794796
if (originalPtr !== null) {{ ctx.storagePtr = originalPtr; }}
795797
return [val, ctx];
796798
}};
797799
800+
// TODO(fix): special case for u8/u16/etc into appropriate type
801+
798802
return function {lift_flat_list_fn}Inner(ctx) {{
799803
{debug_log_fn}('[{lift_flat_list_fn}()] args', {{ ctx }});
800804
@@ -810,7 +814,7 @@ impl LiftIntrinsic {
810814
811815
ctx.useDirectParams = false;
812816
const originalPtr = ctx.storagePtr;
813-
ctx.storageLen = knownLen * size32;
817+
ctx.storageLen = knownLen * elemSize32;
814818
815819
liftResults = readValuesAndReset(ctx, originalPtr, dataPtr, knownLen);
816820
@@ -819,6 +823,7 @@ impl LiftIntrinsic {
819823
ctx.storageLen = null;
820824
821825
}} else {{
826+
ctx.storageLen = knownLen * elemSize32;
822827
liftResults = readValuesAndReset(ctx, null, ctx.storagePtr, knownLen);
823828
}}
824829
@@ -832,7 +837,7 @@ impl LiftIntrinsic {
832837
833838
ctx.useDirectParams = false;
834839
const originalPtr = ctx.storagePtr;
835-
ctx.storageLen = len * size32;
840+
ctx.storageLen = len * elemSize32;
836841
837842
liftResults = readValuesAndReset(ctx, originalPtr, dataPtr, len);
838843
@@ -842,6 +847,8 @@ impl LiftIntrinsic {
842847
843848
}} else {{
844849
// unknown length list ptr w/ in-memory params
850+
ctx.storageLen = 8;
851+
845852
const dataPtrLiftRes = {lift_u32}(ctx);
846853
const dataPtr = dataPtrLiftRes[0];
847854
ctx = dataPtrLiftRes[1];
@@ -853,6 +860,7 @@ impl LiftIntrinsic {
853860
const originalPtr = ctx.storagePtr;
854861
ctx.storagePtr = dataPtr;
855862
863+
ctx.storageLen = len * elemSize32;
856864
liftResults = readValuesAndReset(ctx, originalPtr, dataPtr, len);
857865
}}
858866
}}

crates/js-component-bindgen/src/intrinsics/lower.rs

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -589,13 +589,13 @@ impl LowerIntrinsic {
589589
if (!ctx.realloc) {{ throw new Error('missing realloc during flat string lower'); }}
590590
591591
const s = ctx.vals[0];
592-
const {{ ptr, len, codepoints }} = {utf8_encode_fn}(ctx.vals[0], ctx.realloc, ctx.memory);
592+
const {{ ptr, codepoints }} = {utf8_encode_fn}(ctx.vals[0], ctx.realloc, ctx.memory);
593593
594594
const view = new DataView(ctx.memory.buffer);
595595
view.setUint32(ctx.storagePtr, ptr, true);
596596
view.setUint32(ctx.storagePtr + 4, codepoints, true);
597597
598-
ctx.storagePtr += len;
598+
ctx.storagePtr += 8;
599599
}}
600600
"#));
601601
}
@@ -681,17 +681,24 @@ impl LowerIntrinsic {
681681
Self::LowerFlatList => {
682682
let debug_log_fn = Intrinsic::DebugLog.name();
683683
let lower_flat_list_fn = self.name();
684+
let lower_u32_fn = Self::LowerFlatU32.name();
684685

685686
output.push_str(&format!(r#"
686-
function {lower_flat_list_fn}(args) {{
687-
const {{ elemLowerFn, knownLen, size32, align32 }} = args;
687+
function {lower_flat_list_fn}(meta) {{
688+
const {{
689+
elemLowerFn,
690+
knownLen,
691+
size32,
692+
align32,
693+
elemSize32,
694+
elemAlign32,
695+
}} = meta;
696+
688697
if (!elemLowerFn) {{ throw new TypeError("missing/invalid element lower fn for list"); }}
689698
690699
return function {lower_flat_list_fn}Inner(ctx) {{
691700
{debug_log_fn}('[{lower_flat_list_fn}()] args', {{ ctx }});
692701
693-
// TODO: fix known-length processing
694-
695702
if (ctx.useDirectParams) {{
696703
if (ctx.params.length < 2) {{ throw new Error('insufficient params left to lower list'); }}
697704
const storagePtr = ctx.params[0];
@@ -714,23 +721,57 @@ impl LowerIntrinsic {
714721
const bytesLowered = lowerCtx.storagePtr - ctx.storagePtr;
715722
ctx.storagePtr = lowerCtx.storagePtr;
716723
724+
// TODO: implement parma-only known-length processing
725+
717726
ctx.storagePtr += bytesLowered;
718727
return;
719728
}}
720729
721-
if (ctx.vals.length !== 2) {{
722-
throw new Error('indirect parameter loading must have a pointer and length as vals');
730+
// TODO(fix): is it possible to get a vals that are a addr and length here from
731+
// a component lower?
732+
733+
const elems = ctx.vals[0];
734+
if (knownLen === undefined) {{
735+
// unknown length
736+
if (!ctx.realloc) {{ throw new Error('missing realloc during flat string lower'); }}
737+
const dataPtr = ctx.realloc(0, 0, elemAlign32, elemSize32 * elems.length);
738+
739+
ctx.vals[0] = dataPtr;
740+
{lower_u32_fn}(ctx);
741+
742+
ctx.vals[0] = elems.length;
743+
{lower_u32_fn}(ctx);
744+
745+
const origPtr = ctx.storagePtr;
746+
ctx.storagePtr = dataPtr;
747+
748+
ctx.storagePtr = dataPtr;
749+
for (const elem of elems) {{
750+
ctx.vals = [elem];
751+
elemLowerFn(ctx);
752+
}}
753+
754+
ctx.storagePtr = origPtr;
755+
756+
}} else {{
757+
// known length
758+
759+
if (elems.length !== knownLen) {{
760+
throw new TypeError(`invalid list input of length [${{elems.length}}], must be length [${{knownLen}}]`);
761+
}}
762+
763+
for (const elem of elems) {{
764+
ctx.vals = [elem];
765+
elemLowerFn(ctx);
766+
}}
723767
}}
724-
let [valStartPtr, valLen] = ctx.vals;
725-
const totalSizeBytes = valLen * size;
768+
769+
// TODO(fix): special case for u8/u16/etc, we can do a direct copy
770+
771+
const totalSizeBytes = elems.length * size32;
726772
if (ctx.storageLen !== undefined && totalSizeBytes > ctx.storageLen) {{
727773
throw new Error('not enough storage remaining for list flat lower');
728774
}}
729-
730-
const data = new Uint8Array(ctx.memory.buffer, valStartPtr, totalSizeBytes);
731-
new Uint8Array(ctx.memory.buffer, ctx.storagePtr, totalSizeBytes).set(data);
732-
733-
ctx.storagePtr += totalSizeBytes;
734775
}}
735776
}}
736777
"#));

crates/js-component-bindgen/src/transpile_bindgen.rs

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4647,22 +4647,37 @@ pub fn gen_flat_lift_fn_js_expr(intrinsic_mgr: &mut Instantiator, ty: &Interface
46474647
let list_ty = &component_types[*ty_idx];
46484648
let lift_fn_expr = gen_flat_lift_fn_js_expr(intrinsic_mgr, &list_ty.element);
46494649
let elem_cabi = component_types.canonical_abi(&list_ty.element);
4650-
let align_32 = elem_cabi.align32;
4651-
let size_32 = elem_cabi.size32;
4652-
format!("{f}({{ elemLiftFn: {lift_fn_expr}, align32: {align_32}, size32: {size_32} }})")
4650+
let elem_align32 = elem_cabi.align32;
4651+
let elem_size32 = elem_cabi.size32;
4652+
format!(
4653+
"{f}({{
4654+
elemLiftFn: {lift_fn_expr},
4655+
elemAlign32: {elem_align32},
4656+
elemSize32: {elem_size32},
4657+
}})"
4658+
)
46534659
}
46544660

46554661
InterfaceType::FixedLengthList(ty_idx) => {
46564662
intrinsic_mgr.add_intrinsic(Intrinsic::Lift(LiftIntrinsic::LiftFlatList));
46574663
let f = Intrinsic::Lift(LiftIntrinsic::LiftFlatList).name();
46584664
let list_ty = &component_types[*ty_idx];
4665+
let list_size32 = list_ty.abi.size32;
4666+
let list_align32 = list_ty.abi.align32;
46594667
let lift_fn_expr = gen_flat_lift_fn_js_expr(intrinsic_mgr, &list_ty.element);
46604668
let list_len = list_ty.size;
46614669
let elem_cabi = component_types.canonical_abi(&list_ty.element);
4662-
let align_32 = elem_cabi.align32;
4663-
let size_32 = elem_cabi.size32;
4670+
let elem_align32 = elem_cabi.align32;
4671+
let elem_size32 = elem_cabi.size32;
46644672
format!(
4665-
"{f}({{ elemLiftFn: {lift_fn_expr}, align32: {align_32}, size32: {size_32}, knownLen: {list_len} }})"
4673+
"{f}({{
4674+
elemLiftFn: {lift_fn_expr},
4675+
elemAlign32: {elem_align32},
4676+
elemSize32: {elem_size32},
4677+
listSize32: {list_size32},
4678+
listAlign32: {list_align32},
4679+
knownLen: {list_len},
4680+
}})"
46664681
)
46674682
}
46684683

@@ -5097,11 +5112,20 @@ pub fn gen_flat_lower_fn_js_expr(intrinsic_mgr: &mut Instantiator, ty: &Interfac
50975112

50985113
InterfaceType::List(ty_idx) => {
50995114
intrinsic_mgr.add_intrinsic(Intrinsic::Lower(LowerIntrinsic::LowerFlatList));
5115+
let f = Intrinsic::Lower(LowerIntrinsic::LowerFlatList).name();
51005116
let list_ty = &component_types[*ty_idx];
51015117
let elem_ty_lower_expr = gen_flat_lower_fn_js_expr(intrinsic_mgr, &list_ty.element);
5102-
let f = Intrinsic::Lower(LowerIntrinsic::LowerFlatList).name();
5103-
let ty_idx = ty_idx.as_u32();
5104-
format!("{f}({{ elemLowerFn: {elem_ty_lower_expr}, typeIdx: {ty_idx} }})")
5118+
let elem_cabi = component_types.canonical_abi(&list_ty.element);
5119+
let elem_align32 = elem_cabi.align32;
5120+
let elem_size32 = elem_cabi.size32;
5121+
5122+
format!(
5123+
"{f}({{
5124+
elemLowerFn: {elem_ty_lower_expr},
5125+
elemSize32: {elem_size32},
5126+
elemAlign32: {elem_align32},
5127+
}})"
5128+
)
51055129
}
51065130

51075131
InterfaceType::FixedLengthList(ty_idx) => {
@@ -5110,15 +5134,19 @@ pub fn gen_flat_lower_fn_js_expr(intrinsic_mgr: &mut Instantiator, ty: &Interfac
51105134
let list_ty = &component_types[*ty_idx];
51115135
let elem_ty_lower_expr = gen_flat_lower_fn_js_expr(intrinsic_mgr, &list_ty.element);
51125136
let list_len = list_ty.size;
5137+
let list_align32 = list_ty.abi.size32;
5138+
let list_size32 = list_ty.abi.size32;
51135139
let elem_cabi = component_types.canonical_abi(&list_ty.element);
5114-
let align_32 = elem_cabi.align32;
5115-
let size_32 = elem_cabi.size32;
5140+
let elem_align32 = elem_cabi.align32;
5141+
let elem_size32 = elem_cabi.size32;
51165142

51175143
format!(
51185144
r#"{f}({{
51195145
elemLowerFn: {elem_ty_lower_expr},
5120-
align32: {align_32},
5121-
size32: {size_32},
5146+
elemAlign32: {elem_align32},
5147+
elemSize32: {elem_size32},
5148+
align32: {list_align32},
5149+
size32: {list_size32},
51225150
knownLen: {list_len},
51235151
}})"#
51245152
)

0 commit comments

Comments
 (0)