Skip to content

Commit e15649a

Browse files
committed
Support return in sub statements
1 parent 02dfba3 commit e15649a

File tree

3 files changed

+369
-43
lines changed

3 files changed

+369
-43
lines changed

instrumentation-wasm/src/js_transformer/helpers/insert_instrument_method_calls.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ pub fn insert_instrument_method_calls<'a>(
3939
}
4040

4141
if instruction.modify_return_value {
42-
transform_return_statements(allocator, builder, &instruction.identifier, body);
42+
transform_return_statements(
43+
allocator,
44+
builder,
45+
&instruction.identifier,
46+
&mut body.statements,
47+
);
4348
}
4449
}
Lines changed: 98 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,115 @@
1-
use oxc_allocator::{Allocator, Box, Vec as OxcVec};
1+
use oxc_allocator::{Allocator, Vec as OxcVec};
22
use oxc_ast::{
33
AstBuilder, NONE,
4-
ast::{Argument, FunctionBody, Statement},
4+
ast::{Argument, Statement},
55
};
66
use oxc_span::SPAN;
77

88
pub fn transform_return_statements<'a>(
99
allocator: &'a Allocator,
1010
builder: &AstBuilder<'a>,
1111
identifier: &str,
12-
body: &mut Box<'a, FunctionBody<'a>>,
12+
statements: &mut OxcVec<'a, Statement<'a>>,
13+
) {
14+
transform_statements(allocator, builder, identifier, statements);
15+
}
16+
fn transform_statements<'a>(
17+
allocator: &'a Allocator,
18+
builder: &AstBuilder<'a>,
19+
identifier: &str,
20+
statements: &mut OxcVec<'a, Statement<'a>>,
1321
) {
1422
// Iterate through the statements in the function body
23+
for statement in statements {
24+
transform_statement(allocator, builder, identifier, statement);
25+
}
26+
}
27+
28+
fn transform_statement<'a>(
29+
allocator: &'a Allocator,
30+
builder: &AstBuilder<'a>,
31+
identifier: &str,
32+
statement: &mut Statement<'a>,
33+
) {
34+
match statement {
35+
Statement::ReturnStatement(return_stmt) => {
36+
let mut instrument_args: OxcVec<'a, Argument<'a>> = builder.vec_with_capacity(3);
37+
38+
// Add the identifier to the arguments
39+
instrument_args.push(Argument::StringLiteral(builder.alloc_string_literal(
40+
SPAN,
41+
allocator.alloc_str(identifier),
42+
None,
43+
)));
44+
45+
// Also pass the function arguments
46+
instrument_args.push(builder.expression_identifier(SPAN, "arguments").into());
47+
48+
// Add original return value as the second argument
49+
let arg_expr = return_stmt
50+
.argument
51+
.take()
52+
.unwrap_or_else(|| builder.expression_identifier(SPAN, "undefined"));
53+
instrument_args.push(arg_expr.into());
1554

16-
// Todo fix subfunctions
17-
for statement in &mut body.statements {
18-
match statement {
19-
Statement::ReturnStatement(return_stmt) => {
20-
let mut instrument_args: OxcVec<'a, Argument<'a>> = builder.vec_with_capacity(3);
21-
22-
// Add the identifier to the arguments
23-
instrument_args.push(Argument::StringLiteral(builder.alloc_string_literal(
24-
SPAN,
25-
allocator.alloc_str(identifier),
26-
None,
27-
)));
28-
29-
// Also pass the function arguments
30-
instrument_args.push(builder.expression_identifier(SPAN, "arguments").into());
31-
32-
// Add original return value as the second argument
33-
let arg_expr = return_stmt
34-
.argument
35-
.take()
36-
.unwrap_or_else(|| builder.expression_identifier(SPAN, "undefined"));
37-
instrument_args.push(arg_expr.into());
38-
39-
// Add the `this` context as argument
40-
instrument_args.push(builder.expression_identifier(SPAN, "this").into());
41-
42-
let new_call_expr = builder.expression_call(
43-
SPAN,
44-
builder.expression_identifier(SPAN, "__instrumentModifyReturnValue"),
45-
NONE,
46-
instrument_args,
47-
false,
48-
);
49-
50-
// Replace the return statement with a call to the identifier
51-
return_stmt.argument = Some(new_call_expr);
55+
// Add the `this` context as argument
56+
instrument_args.push(builder.expression_identifier(SPAN, "this").into());
57+
58+
let new_call_expr = builder.expression_call(
59+
SPAN,
60+
builder.expression_identifier(SPAN, "__instrumentModifyReturnValue"),
61+
NONE,
62+
instrument_args,
63+
false,
64+
);
65+
66+
// Replace the return statement with a call to the identifier
67+
return_stmt.argument = Some(new_call_expr);
68+
}
69+
// Recursively transform nested statements
70+
Statement::BlockStatement(block_stmt) => {
71+
transform_statements(allocator, builder, identifier, &mut block_stmt.body);
72+
}
73+
Statement::IfStatement(if_stmt) => {
74+
transform_statement(allocator, builder, identifier, &mut if_stmt.consequent);
75+
if let Some(alt) = &mut if_stmt.alternate {
76+
transform_statement(allocator, builder, identifier, alt);
5277
}
53-
_ => {
54-
// Ignore
55-
continue;
78+
}
79+
Statement::DoWhileStatement(do_while_stmt) => {
80+
transform_statement(allocator, builder, identifier, &mut do_while_stmt.body);
81+
}
82+
Statement::ForStatement(for_stmt) => {
83+
transform_statement(allocator, builder, identifier, &mut for_stmt.body);
84+
}
85+
Statement::ForInStatement(for_in_stmt) => {
86+
transform_statement(allocator, builder, identifier, &mut for_in_stmt.body);
87+
}
88+
Statement::ForOfStatement(for_of_stmt) => {
89+
transform_statement(allocator, builder, identifier, &mut for_of_stmt.body);
90+
}
91+
Statement::WhileStatement(while_stmt) => {
92+
transform_statement(allocator, builder, identifier, &mut while_stmt.body);
93+
}
94+
Statement::SwitchStatement(switch_stmt) => {
95+
for case in &mut switch_stmt.cases {
96+
transform_statements(allocator, builder, identifier, &mut case.consequent);
97+
}
98+
}
99+
Statement::TryStatement(try_stmt) => {
100+
transform_statements(allocator, builder, identifier, &mut try_stmt.block.body);
101+
if let Some(handler) = &mut try_stmt.handler {
102+
transform_statements(allocator, builder, identifier, &mut handler.body.body);
56103
}
104+
if let Some(finally_block) = &mut try_stmt.finalizer {
105+
transform_statements(allocator, builder, identifier, &mut finally_block.body);
106+
}
107+
}
108+
Statement::LabeledStatement(labeled_stmt) => {
109+
transform_statement(allocator, builder, identifier, &mut labeled_stmt.body);
110+
}
111+
_ => {
112+
// Ignore
57113
}
58114
}
59115
}

0 commit comments

Comments
 (0)