From 9c710b2a3447d93501dd6183bd9ad268e4c801b7 Mon Sep 17 00:00:00 2001 From: playX Date: Wed, 14 Jul 2021 11:43:48 +0300 Subject: [PATCH] v.gen.js: improve reference support (#10793) --- vlib/v/gen/js/js.v | 131 ++++++++++++--------------------------------- 1 file changed, 33 insertions(+), 98 deletions(-) diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index 4dfa5b9fd4..c1c9cdf33b 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -655,13 +655,18 @@ fn (mut g JsGen) expr(node ast.Expr) { if node.op in [.amp, .mul] { // C pointers/references: ignore them if node.op == .amp { - g.write('{ value: ') - g.expr(node.right) - g.write(' } ') + type_sym := g.table.get_type_symbol(node.right_type) + if !type_sym.is_primitive() && !node.right_type.is_pointer() { + g.write('{ val: ') + g.expr(node.right) + g.write(' } ') + } else { + g.expr(node.right) + } } else { g.write('(') g.expr(node.right) - g.write(').value') + g.write(').val') } } else { g.write(node.op.str()) @@ -808,13 +813,18 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) { } } g.expr(left) + mut is_ptr := false if stmt.op == .assign && stmt.left_types[i].is_ptr() { - g.write('.value') + is_ptr = true + g.write('.val') } if g.inside_map_set && op == .assign { g.inside_map_set = false g.write(', ') g.expr(val) + if is_ptr { + g.write('.val') + } g.write(')') } else { g.write(' $op ') @@ -831,6 +841,9 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) { g.write('${g.typ(stmt.left_types.first())}(') } g.expr(val) + if is_ptr { + g.write('.val') + } if should_cast { g.write(')') g.cast_stack.delete_last() @@ -1302,14 +1315,20 @@ fn (mut g JsGen) gen_array_init_values(exprs []ast.Expr) { fn (mut g JsGen) gen_call_expr(it ast.CallExpr) { g.call_stack << it - expected_types := it.expected_arg_types mut name := g.js_name(it.name) call_return_is_optional := it.return_type.has_flag(.optional) - if it.is_method { + if call_return_is_optional { + g.writeln('(function(){') + g.inc_indent() + g.writeln('try {') + g.inc_indent() + g.write('return builtin.unwrap(') + } + g.expr(it.left) + if it.is_method { // foo.bar.baz() sym := g.table.get_type_symbol(it.receiver_type) + g.write('.') if sym.kind == .array && it.name in ['map', 'filter'] { - g.expr(it.left) - g.write('.') // Prevent 'it' from getting shadowed inside the match node := it g.write(it.name) @@ -1342,52 +1361,6 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) { g.write(')') return } - } - - g.writeln('(function() { ') - g.inc_indent() - mut mut_args := map[int]MutArg{} - // store all the mutable arguments in temporary variable + allocate an object which boxes these arguments - for i, arg in it.args { - if arg.is_mut { - tmp_var := g.new_tmp_var() - g.writeln('const $tmp_var = ') - expr := arg.expr - match expr { - ast.Ident { - if expr.var_info().typ.is_ptr() { - g.write(expr.name) - g.writeln(';') - } else { - g.write('{ value: ') - g.expr(expr) - g.writeln(' }; ') - } - } - else { - g.write('{ value: ') - g.expr(expr) - g.writeln(' }; ') - } - } - - mut_args[i] = MutArg{tmp_var, arg.expr} - } - } - g.write('let result;') - if call_return_is_optional { - g.writeln('(function(){') - g.inc_indent() - g.writeln('try {') - g.inc_indent() - // g.write('return builtin.unwrap(') - } - - g.writeln('result = ') - g.expr(it.left) - - if it.is_method { // foo.bar.baz() - g.write('.') } else { if name in g.builtin_fns { g.write('builtin.') @@ -1395,51 +1368,16 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) { } g.write('${name}(') for i, arg in it.args { - if arg.is_mut { - mut_arg := mut_args[i] - g.write(mut_arg.tmp_var) - } else { - g.expr(arg.expr) - } - // TODO: Is this correct way of passing argument? - if i < expected_types.len && arg.typ.is_ptr() && !arg.is_mut && !expected_types[i].is_ptr() { - g.write('.value') - } + g.expr(arg.expr) if i != it.args.len - 1 { g.write(', ') } } // end method call - g.writeln(');') - // now unbox all the mutable arguments - for i, arg in it.args { - if arg.is_mut { - mut_arg := mut_args[i] - expr := mut_arg.expr - match expr { - ast.Ident { - if !expr.var_info().typ.is_ptr() { - g.writeln('$expr.name = ($mut_arg.tmp_var).value;') - } - } - ast.IndexExpr { - g.expr(mut_arg.expr) - g.writeln(' = ($mut_arg.tmp_var).value;') - } - ast.SelectorExpr { - g.expr(mut_arg.expr) - g.writeln(' = ($mut_arg.tmp_var).value;') - } - else { - // TODO - } - } - } - } - + g.write(')') if call_return_is_optional { // end unwrap - g.writeln('result = builtin.unwrap(result)') + g.writeln(')') g.dec_indent() // begin catch block g.writeln('} catch(err) {') @@ -1450,7 +1388,7 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) { if it.or_block.stmts.len > 1 { g.stmts(it.or_block.stmts[..it.or_block.stmts.len - 1]) } - // g.write('result = ') + g.write('return ') g.stmt(it.or_block.stmts.last()) } .propagate { @@ -1468,11 +1406,8 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) { g.writeln('}') // end anon fn g.dec_indent() - g.writeln('})()') + g.write('})()') } - g.dec_indent() - g.writeln('return result;') - g.writeln('})()') g.call_stack.delete_last() }