|
@@ -336,31 +336,15 @@ let rec concat ctx s f = function
|
|
It's the only way to avoid disabling javascript VM optimizations of functions
|
|
It's the only way to avoid disabling javascript VM optimizations of functions
|
|
with rest arguments.
|
|
with rest arguments.
|
|
*)
|
|
*)
|
|
-let declare_rest_args_legacy com args rest_arg =
|
|
|
|
- let arguments = mk (TIdent "arguments") t_dynamic null_pos
|
|
|
|
- and index i = mk (TConst (TInt (Int32.of_int i))) com.basic.tint null_pos in
|
|
|
|
- let rec loop args i =
|
|
|
|
- match args with
|
|
|
|
- | [] -> []
|
|
|
|
- | (v,e_opt) :: rest ->
|
|
|
|
- (* var v = arguments[i]; *)
|
|
|
|
- let value = mk (TArray (arguments,index i)) v.v_type null_pos in
|
|
|
|
- let decl = mk (TVar (v,Some value)) com.basic.tvoid v.v_pos in
|
|
|
|
-
|
|
|
|
- match e_opt with
|
|
|
|
- | None -> decl :: loop rest (i + 1)
|
|
|
|
- | Some e -> decl :: Texpr.set_default com.basic v e v.v_pos :: loop rest (i + 1)
|
|
|
|
- in
|
|
|
|
- let i = string_of_int (List.length args) in
|
|
|
|
- let new_array = mk (TIdent ("new Array($l-"^ i ^")")) t_dynamic rest_arg.v_pos
|
|
|
|
- and populate = mk (TIdent ("for(var $i=" ^ i ^ ";$i<$l;++$i){" ^ (ident rest_arg.v_name) ^ "[$i-" ^ i ^ "]=arguments[$i];}")) com.basic.tvoid rest_arg.v_pos
|
|
|
|
|
|
+let declare_rest_args_legacy com offset rest_arg =
|
|
|
|
+ let arguments = mk (TIdent "arguments") t_dynamic null_pos in
|
|
|
|
+ let array_slice = mk (TIdent ("Array.prototype.slice.call")) t_dynamic null_pos in
|
|
|
|
+ let array_slice_call = mk (TCall (
|
|
|
|
+ array_slice,
|
|
|
|
+ if offset = 0 then [arguments] else [arguments; Texpr.Builder.make_int com.basic offset null_pos]
|
|
|
|
+ )) rest_arg.v_type null_pos
|
|
in
|
|
in
|
|
- loop args 0
|
|
|
|
- @ [
|
|
|
|
- mk (TIdent ("var $l=arguments.length")) com.basic.tvoid rest_arg.v_pos;
|
|
|
|
- mk (TVar (rest_arg,Some new_array)) com.basic.tvoid rest_arg.v_pos;
|
|
|
|
- populate
|
|
|
|
- ]
|
|
|
|
|
|
+ mk (TVar (rest_arg,Some array_slice_call)) com.basic.tvoid rest_arg.v_pos
|
|
|
|
|
|
let fun_block ctx f p =
|
|
let fun_block ctx f p =
|
|
let e = List.fold_left (fun e (a,c) ->
|
|
let e = List.fold_left (fun e (a,c) ->
|
|
@@ -902,6 +886,12 @@ and gen_function ?(keyword="function") ctx f pos =
|
|
let old = ctx.in_value, ctx.in_loop in
|
|
let old = ctx.in_value, ctx.in_loop in
|
|
ctx.in_value <- None;
|
|
ctx.in_value <- None;
|
|
ctx.in_loop <- false;
|
|
ctx.in_loop <- false;
|
|
|
|
+ let mk_non_rest_arg_names arg_list =
|
|
|
|
+ List.map (fun (v,_) ->
|
|
|
|
+ check_var_declaration v;
|
|
|
|
+ ident v.v_name
|
|
|
|
+ ) arg_list
|
|
|
|
+ in
|
|
let f,args =
|
|
let f,args =
|
|
match List.rev f.tf_args with
|
|
match List.rev f.tf_args with
|
|
| (v,None) :: args_rev when ExtType.is_rest (follow v.v_type) ->
|
|
| (v,None) :: args_rev when ExtType.is_rest (follow v.v_type) ->
|
|
@@ -914,21 +904,19 @@ and gen_function ?(keyword="function") ctx f pos =
|
|
) f.tf_args
|
|
) f.tf_args
|
|
(* Resort to `arguments` special object for ES < 6 *)
|
|
(* Resort to `arguments` special object for ES < 6 *)
|
|
else
|
|
else
|
|
- let args_decl = declare_rest_args_legacy ctx.com (List.rev args_rev) v in
|
|
|
|
|
|
+ let non_rest_args = List.rev args_rev in
|
|
|
|
+ let rest_args_decl = declare_rest_args_legacy ctx.com (List.length non_rest_args) v in
|
|
let body =
|
|
let body =
|
|
let el =
|
|
let el =
|
|
match f.tf_expr.eexpr with
|
|
match f.tf_expr.eexpr with
|
|
- | TBlock el -> args_decl @ el
|
|
|
|
- | _ -> args_decl @ [f.tf_expr]
|
|
|
|
|
|
+ | TBlock el -> rest_args_decl :: el
|
|
|
|
+ | _ -> [rest_args_decl; f.tf_expr]
|
|
in
|
|
in
|
|
mk (TBlock el) f.tf_expr.etype f.tf_expr.epos
|
|
mk (TBlock el) f.tf_expr.etype f.tf_expr.epos
|
|
in
|
|
in
|
|
- { f with tf_args = []; tf_expr = body }, []
|
|
|
|
|
|
+ { f with tf_args = non_rest_args; tf_expr = body }, mk_non_rest_arg_names non_rest_args
|
|
| _ ->
|
|
| _ ->
|
|
- f, List.map (fun (v,_) ->
|
|
|
|
- check_var_declaration v;
|
|
|
|
- ident v.v_name
|
|
|
|
- ) f.tf_args
|
|
|
|
|
|
+ f, mk_non_rest_arg_names f.tf_args
|
|
in
|
|
in
|
|
print ctx "%s(%s) " keyword (String.concat "," args);
|
|
print ctx "%s(%s) " keyword (String.concat "," args);
|
|
gen_expr ctx (fun_block ctx f pos);
|
|
gen_expr ctx (fun_block ctx f pos);
|