Skip to content

Commit ebdf6bb

Browse files
committed
1. fix of rescript-lang#132 static catch
2. add int64 mul support
1 parent c9830aa commit ebdf6bb

22 files changed

+1369
-408
lines changed

jscomp/bb_require.js

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
var globalEval = eval;
2+
3+
/**
4+
* assume user input is
5+
* @param {string} base './stdlib/array[.js]'
6+
* @rel '../runtime/caml_array'
7+
*/
8+
function relativePath(base, rel){
9+
return base + '/../' + rel
10+
}
11+
12+
/**
13+
* Used in cache
14+
* @param {string} path
15+
* for example './stdlib/array.js'
16+
*
17+
*/
18+
function normalizePath(path){
19+
if (!path.endsWith(".js")){
20+
path += ".js"
21+
}
22+
var files = path.split('/')
23+
var real = []
24+
for (var i = 0 ; i < files.length; ++i){
25+
if (files[i] === '..'){
26+
real.pop()
27+
}
28+
else if(files[i] === '.'){
29+
// nothing
30+
}
31+
else if (files[i] === ''){
32+
33+
}
34+
else {
35+
real.push(files[i])
36+
}
37+
}
38+
return real.join('/')
39+
}
40+
41+
42+
43+
function extractDeps(code){
44+
var deps = [];
45+
code.replace(/(?:^|[^\w\$_.])require\s*\(\s*["']([^"']*)["']\s*\)/g, function (_, id) {
46+
deps.push(id);
47+
});
48+
//return [deps, "(function (require,exports) {\n" + code + "\n})"];
49+
return deps;
50+
}
51+
52+
/**
53+
* @url example : './stdlib/array.js'
54+
*/
55+
function getContent(url, cb) {
56+
url = normalizePath(url);
57+
var x = new XMLHttpRequest();
58+
x.open('GET', url, true);
59+
x.addEventListener('load', function(event){ return cb(url, x.response)});
60+
x.send()
61+
}
62+
63+
var Modules = {}
64+
65+
function initModule(url, deps, response){
66+
if(!Modules[url]){
67+
Modules[url] = {
68+
deps : deps ,
69+
exports : undefined,
70+
response : response,
71+
url : url
72+
};
73+
}
74+
return Modules[url]
75+
}
76+
function decrDeps(mod){
77+
-- mod.deps ;
78+
if(mod.deps === 0){
79+
evalResponse(mod.url, mod.response)
80+
}
81+
}
82+
function evalResponse(url, response) {
83+
if (!Modules[url].exports) {
84+
(globalEval("(function(require, exports){\n" + response + "\n})//# sourceURL=" + document.getElementById('base_ref').href + url))(
85+
function (link) { return req(url, link); },
86+
Modules[url].exports = {});
87+
}
88+
}
89+
function req(currentloc, file) {
90+
var url = normalizePath(relativePath(currentloc, file));
91+
if (Modules[url].exports !== undefined) {
92+
return Modules[url].exports
93+
} else {
94+
throw new Error(currentloc + " " + file + "not loaded");
95+
}
96+
}
97+
function cb(url, response, evalResponse) {
98+
url = normalizePath(url);
99+
var deps = extractDeps(response);
100+
var mod = initModule(url, deps.length, response)
101+
if (deps.length > 0) {
102+
/* async.map(deps, function (value,yet_ignored){
103+
console.log(url, '..', value);
104+
getContent(relativePath(url,value),function(url,response){
105+
cb(url,response, yet_ignored);
106+
// yet_ignored(null,true);
107+
});
108+
109+
}, function(err, results){
110+
evalResponse(url,response)
111+
});
112+
*/
113+
for (var i = 0; i < deps.length; ++i) {
114+
// console.log(url,deps[i], relativePath(url,deps[i]));
115+
getContent(relativePath(url, deps[i]), function (url, response) {
116+
cb(url, response);
117+
decrDeps(mod)
118+
})
119+
}
120+
// evalResponse(url, response)
121+
} else {
122+
evalResponse(null, url, response)
123+
}
124+
}

jscomp/compiler.mllib

+1
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,4 @@ ppx_entry
107107

108108
literals
109109

110+
lam_exit_code

jscomp/index.html

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
<head>
2+
<base id="base_ref"></base>
23
</head>
34

45
<body>
56

67

7-
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.22/require.js"></script>
8-
<script src="./pre_load.js"></script>
9-
<!-- <script src="./require.js"></script> -->
8+
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.22/require.js"></script> -->
9+
<!-- <script src="./bb_require.js"></script> -->
10+
<!-- <script src="./async.js"></script> -->
11+
<script src="./require1k.js"></script>
12+
<script>
13+
R('./runtime/caml_int64', function(err,v){
14+
window.int64 = v
15+
})
16+
</script>
1017
</body>

jscomp/lam_compile.ml

+14-2
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,22 @@ let method_cache_id = ref 1 (*TODO: move to js runtime for re-entrant *)
3333
let rec flat_catches acc (x : Lambda.lambda)
3434
: (int * Lambda.lambda * Ident.t list ) list * Lambda.lambda =
3535
match x with
36+
| Lstaticcatch( Lstaticcatch(l, (code,bindings), handler), (code1, bindings1),handler1)
37+
when
38+
not @@ Lam_exit_code.has_exit_code
39+
(fun exit -> exit = code1 || List.exists (fun (c, _, _) -> c = exit ) acc ) handler
40+
->
41+
(* when handler does not have [exit code] which [code] belongs to collected,
42+
it is okay to merge
43+
*)
44+
flat_catches ( (code, handler,bindings) :: (code1,handler1,bindings1) :: acc) l
3645
| Lstaticcatch(l, (code, bindings), handler) ->
37-
flat_catches ((code,handler,bindings)::acc) l
46+
(code,handler,bindings)::acc, l
47+
(* flat_catches ((code,handler,bindings)::acc) l *)
3848
| _ -> acc, x
3949

50+
let flatten_caches x = flat_catches [] x
51+
4052
(* exception Not_an_expression *)
4153

4254
(* TODO:
@@ -956,7 +968,7 @@ and
956968
if not we should use ``javascript break`` or ``continue``
957969
*)
958970
| Lstaticcatch _ ->
959-
let code_table, body = flat_catches [] lam in
971+
let code_table, body = flatten_caches lam in
960972

961973
let exit_id = Ext_ident.gen_js ~name:"exit" () in
962974
let exit_expr = E.var exit_id in

jscomp/lam_exit_code.ml

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
(* BuckleScript compiler
2+
* Copyright (C) 2015-2016 Bloomberg Finance L.P.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License as published by
6+
* the Free Software Foundation, with linking exception;
7+
* either version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17+
*)
18+
19+
(* Author: Hongbo Zhang *)
20+
21+
let rec has_exit_code exits (lam : Lambda.lambda) : bool =
22+
match lam with
23+
| Lambda.Lvar _
24+
| Lambda.Lconst _
25+
| Lambda.Lfunction _ (* static exit can not across function boundary *)
26+
-> false
27+
| Lambda.Lapply (l,args,_apply_info)
28+
-> has_exit_code exits l || List.exists (fun x -> has_exit_code exits x ) args
29+
30+
| Lambda.Llet (_kind,_id,v,body)
31+
-> has_exit_code exits v || has_exit_code exits body
32+
| Lambda.Lletrec (binding,body) ->
33+
List.exists (fun (_, l) -> has_exit_code exits l ) binding ||
34+
has_exit_code exits body
35+
| Lambda.Lprim (_,ls)
36+
-> List.exists (fun x -> has_exit_code exits x) ls
37+
| Lambda.Lswitch (l,lam_switch)
38+
-> has_exit_code exits l || has_exit_code_lam_switch exits lam_switch
39+
40+
| Lambda.Lstringswitch (l,ls,opt) ->
41+
has_exit_code exits l ||
42+
List.exists (fun (_,l) -> has_exit_code exits l) ls ||
43+
(match opt with
44+
| None -> false
45+
| Some x -> has_exit_code exits l )
46+
| Lambda.Lstaticraise (v,ls) ->
47+
exits v ||
48+
List.exists (has_exit_code exits) ls
49+
| Lambda.Lstaticcatch (l,_,handler)
50+
->
51+
has_exit_code exits l || has_exit_code exits handler
52+
| Lambda.Ltrywith (l,_, handler)
53+
->
54+
has_exit_code exits l || has_exit_code exits handler
55+
| Lambda.Lifthenelse (a,b,c)
56+
->
57+
has_exit_code exits a || has_exit_code exits b || has_exit_code exits c
58+
| Lambda.Lsequence (a,b)
59+
->
60+
has_exit_code exits a || has_exit_code exits b
61+
| Lambda.Lwhile (a,b)
62+
->
63+
has_exit_code exits a || has_exit_code exits b
64+
| Lambda.Lfor (_,a,b,_dir,body) ->
65+
has_exit_code exits a
66+
|| has_exit_code exits b
67+
|| has_exit_code exits body
68+
69+
| Lambda.Lassign (_,a)
70+
->
71+
has_exit_code exits a
72+
| Lambda.Lsend (_,obj,l,ls,_loc)
73+
->
74+
has_exit_code exits obj ||
75+
has_exit_code exits l ||
76+
List.exists (has_exit_code exits) ls
77+
| Lambda.Levent (b,_)
78+
-> has_exit_code exits b
79+
| Lambda.Lifused (_,b)
80+
-> has_exit_code exits b
81+
82+
and has_exit_code_lam_switch exits (lam_switch : Lambda.lambda_switch) =
83+
match lam_switch with
84+
| { sw_numconsts = _; sw_consts; sw_numblocks = _ ; sw_blocks; sw_failaction } ->
85+
List.exists (fun (_,l) -> has_exit_code exits l) sw_consts ||
86+
List.exists (fun (_,l) -> has_exit_code exits l) sw_blocks ||
87+
(match sw_failaction with
88+
| None -> false
89+
| Some x -> has_exit_code exits x)

jscomp/lam_exit_code.mli

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
(* BuckleScript compiler
2+
* Copyright (C) 2015-2016 Bloomberg Finance L.P.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License as published by
6+
* the Free Software Foundation, with linking exception;
7+
* either version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17+
*)
18+
19+
(* Author: Hongbo Zhang *)
20+
21+
22+
val has_exit_code : (int -> bool ) -> Lambda.lambda -> bool

jscomp/lib/lib.mllib

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
js
22
bench
33
dom
4-
js_date
4+
js_date
5+
xmlHTTPRequest

jscomp/lib/xmlHTTPRequest.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

jscomp/lib/xmlHTTPRequest.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Generated CODE, PLEASE EDIT WITH CARE
2+
'use strict';
3+
4+
5+
6+
/* No side effect */

jscomp/lib/xmlHTTPRequest.ml

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
(* BuckleScript compiler
2+
* Copyright (C) 2015-2016 Bloomberg Finance L.P.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License as published by
6+
* the Free Software Foundation, with linking exception;
7+
* either version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17+
*)
18+
19+
(* Author: Hongbo Zhang *)
20+
open Js
21+
22+
type readyState =
23+
| UNSENT
24+
| OPENED
25+
| HEADERS_RECEIVED
26+
| LOADING
27+
| DONE
28+
29+
class type xmlHttpRequest = object
30+
method onreadystatechange__w : (unit -> unit) -> unit
31+
(* To make it type safe. we need mark
32+
it expclitly [(unit ->unit) Js.callback].
33+
But this is only type safe in theory, since
34+
pass functions to js side, there is no assumptions
35+
that you can make about those js code.
36+
*)
37+
method readyState__r : readyState
38+
method open__3 : string -> string -> boolean -> unit
39+
method open_full__3 :
40+
string -> string -> boolean -> unit
41+
method open_full__4 :
42+
string -> string -> boolean -> string -> unit
43+
method open_full__5 :
44+
string -> string -> boolean -> string -> string -> unit
45+
(* In the ppx
46+
we can write
47+
{[
48+
method open_full :
49+
string -> string -> boolean -> string [@opt] -> string [@opt] -> unit
50+
]}
51+
*)
52+
method setRequestHeader : string -> string -> unit
53+
method overrideMimeType : string -> unit
54+
method send : string opt -> unit
55+
method abort__0 : unit
56+
method status__r : int
57+
method statusText__r : string
58+
method getResponseHeader__1 : string -> string opt
59+
method getAllResponseHeaders__0 : string
60+
method responseText__r : string
61+
method responseType__r : string
62+
end

0 commit comments

Comments
 (0)