Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/javascript.ml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ and expression =
| ENew of expression * arguments option
| EVar of ident
| EFun of function_expression * node_pc
| EStr of string * [`Bytes (*| `Utf8*)]
| EStr of string * [`Bytes | `Utf8]
| EArr of array_litteral
| EBool of bool
| ENum of float
Expand Down
2 changes: 1 addition & 1 deletion compiler/javascript.mli
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ and expression =
| ENew of expression * arguments option
| EVar of ident
| EFun of function_expression * node_pc
| EStr of string * [`Bytes (*| `Utf8*)]
| EStr of string * [`Bytes | `Utf8]
| EArr of array_litteral
| EBool of bool
| ENum of float
Expand Down
34 changes: 26 additions & 8 deletions compiler/js_output.ml
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,19 @@ end) = struct
| EFun (_, _) | EObj _ ->
true

let string_escape s =
let best_string_quote s =
let simple = ref 0 and double = ref 0 in
for i = 0 to String.length s - 1 do
match s.[i] with
| '\'' -> incr simple
| '"' -> incr double
| _ -> ()
done;
if !simple < !double
then '\''
else '"'

let string_escape quote ?(utf=false) s =
let l = String.length s in
let b = Buffer.create (4 * l) in
let conv = "0123456789abcdef" in
Expand All @@ -209,16 +221,20 @@ end) = struct
Buffer.add_string b "\\f"
| '\r' ->
Buffer.add_string b "\\r"
| '"' ->
Buffer.add_string b "\\\""
| '\\' ->
Buffer.add_string b "\\\\"
| '\000' .. '\031' | '\127' .. '\255' ->
| '\000' .. '\031' | '\127'->
let c = Char.code c in
Buffer.add_string b "\\x";
Buffer.add_char b conv.[c lsr 4];
Buffer.add_char b conv.[c land 0xf]
| '\128' .. '\255' when not utf ->
let c = Char.code c in
Buffer.add_string b "\\x";
Buffer.add_char b conv.[c lsr 4];
Buffer.add_char b conv.[c land 0xf]
| _ ->
if c = quote then Buffer.add_char b '\\';
Buffer.add_char b c
done;
Buffer.contents b
Expand Down Expand Up @@ -274,10 +290,12 @@ end) = struct
PP.end_group f;
PP.end_group f;
if l > 15 then begin PP.string f ")"; PP.end_group f end
| EStr (s, `Bytes) ->
PP.string f "\"";
PP.string f (string_escape s);
PP.string f "\""
| EStr (s, kind) ->
let quote = best_string_quote s in
let quote_s = String.make 1 quote in
PP.string f quote_s;
PP.string f (string_escape ~utf:(kind = `Utf8) quote s);
PP.string f quote_s
| EBool b ->
PP.string f (if b then "true" else "false")
| ENum v ->
Expand Down
36 changes: 22 additions & 14 deletions compiler/js_var.ml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ let get_free t = S.diff t.use t.def

let get_free_name t = StringSet.diff t.use_name t.def_name

let add_constraints params g =
let add_constraints ?(offset=0) params g =
if Option.Optim.shortvar () then begin
let u = S.union g.def g.use in
let constr = g.global.constr in
Expand All @@ -167,15 +167,16 @@ let add_constraints params g =
(fun v -> let i = Code.Var.idx v in constr.(i) <- c :: constr.(i)) u;
let params = Array.of_list params in
let len = Array.length params in
if Array.length g.global.parameters < len then begin
let a = Array.make (2 * len) [] in
let len_max = len + offset in
if Array.length g.global.parameters < len_max then begin
let a = Array.make (2 * len_max) [] in
Array.blit g.global.parameters 0 a 0 (Array.length g.global.parameters);
g.global.parameters <- a
end;
for i = 0 to len - 1 do
match params.(i) with
Javascript.V x ->
g.global.parameters.(i) <- x :: g.global.parameters.(i)
g.global.parameters.(i + offset) <- x :: g.global.parameters.(i + offset)
| _ ->
()
done;
Expand Down Expand Up @@ -306,16 +307,23 @@ and statement t s = match s with
let t = match w with
| None -> t
| Some (id,block) ->
let t = statements t block in
let t = def_var t id in
t
(* let tbody = statements (empty t) block in *)
(* let tbody = def_var tbody id in *)
(* let tbody = mark tbody in *)
(* let t = merge_info ~from:tbody ~into:t in *)
(* { t with *)
(* use = S.union t.use (rm_var t.use id) ; *)
(* def = S.union t.def (rm_var t.def id) } *)
let t' = statements (empty t) block in
let t' = def_var t' id in
add_constraints ~offset:5 [id] t';

(* special merge here *)
(* we need to propagate both def and use .. *)
(* .. except 'id' because its scope is limitied to 'block' *)
let clean set sets = match id with
| S s -> set,StringSet.remove s sets
| V i -> S.remove i set, sets in
let def,def_name = clean t'.def t'.def_name in
let use,use_name = clean t'.use t'.use_name in
{t with
use = S.union t.use use;
use_name = StringSet.union t.use_name use_name;
def = S.union t.def def;
def_name = StringSet.union t.def_name def_name }
in
let t = match f with
| None -> t
Expand Down