From 3d013843c7807155cfaf76979c4b02dabaa12cc6 Mon Sep 17 00:00:00 2001 From: Hugo Heuzard Date: Sat, 23 Nov 2019 15:03:11 +0800 Subject: [PATCH] Compiler: immutable strings --- compiler/lib/eval.ml | 2 +- compiler/lib/generate.ml | 20 +- compiler/lib/parse_bytecode.ml | 2 +- compiler/num-testsuite/test.ml | 2 +- compiler/tests/obj_dup.ml | 2 +- compiler/tests/static_eval.ml | 4 +- compiler/tests/variable_declaration_output.ml | 2 +- lib/js_of_ocaml/json.ml | 33 +-- runtime/bigstring.js | 12 +- runtime/dynlink.js | 4 +- runtime/fs.js | 4 +- runtime/fs_fake.js | 17 +- runtime/fs_node.js | 5 +- runtime/io.js | 24 +-- runtime/jslib_js_of_ocaml.js | 15 +- runtime/lexing.js | 12 +- runtime/marshal.js | 36 ++-- runtime/md5.js | 27 +-- runtime/mlString.js | 196 ++++++++---------- runtime/stdlib.js | 78 +++---- runtime/toplevel.js | 6 +- toplevel/examples/lwt_toplevel/dune | 1 + toplevel/lib/jsooTop.ml | 1 - 23 files changed, 236 insertions(+), 269 deletions(-) diff --git a/compiler/lib/eval.ml b/compiler/lib/eval.ml index 289e7926ad..d729d3eeaf 100644 --- a/compiler/lib/eval.ml +++ b/compiler/lib/eval.ml @@ -293,7 +293,7 @@ let eval_instr info i = ( prim , List.map2 prim_args prim_args' ~f:(fun arg c -> match c with - | Some ((Int _ | Float _) as c) -> Pc c + | Some ((Int _ | Float _ | String _ | IString _) as c) -> Pc c | Some _ (* do not be duplicated other constant as they're not represented with constant in javascript. *) diff --git a/compiler/lib/generate.ml b/compiler/lib/generate.ml index 4de8aa7d31..1abef6479a 100644 --- a/compiler/lib/generate.ml +++ b/compiler/lib/generate.ml @@ -105,9 +105,7 @@ module Share = struct let n = try IntMap.find i t.applies with Not_found -> 0 in { t with applies = IntMap.add i (n + 1) t.applies } - let add_code_string s share = - let share = add_string s share in - add_prim "caml_new_string" share + let add_code_string s share = add_string s share let add_code_istring s share = add_string s share @@ -308,8 +306,7 @@ let rec constant_rec ~ctx x level instrs = match x with | String s -> let e = Share.get_string str_js s ctx.Ctx.share in - let p = Share.get_prim (runtime_fun ctx) "caml_new_string" ctx.Ctx.share in - J.ECall (p, [ e ], J.N), instrs + e, instrs | IString s -> Share.get_string str_js s ctx.Ctx.share, instrs | Float f -> float_const f, instrs | Float_array a -> @@ -844,9 +841,8 @@ let register_bin_math_prim name prim = J.ECall (J.EDot (s_var "Math", prim), [ cx; cy ], loc)) let _ = - register_un_prim_ctx "%caml_format_int_special" `Pure (fun ctx cx loc -> - let p = Share.get_prim (runtime_fun ctx) "caml_new_string" ctx.Ctx.share in - J.ECall (p, [ J.EBin (J.Plus, str_js "", cx) ], loc)); + register_un_prim_ctx "%caml_format_int_special" `Pure (fun _ctx cx _loc -> + J.EBin (J.Plus, str_js "", cx)); register_bin_prim "caml_array_unsafe_get" `Mutable (fun cx cy _ -> Mlvalue.Array.field cx cy); register_bin_prim "%int_add" `Pure (fun cx cy _ -> to_int (plus_int cx cy)); @@ -911,8 +907,6 @@ let _ = register_un_prim "caml_js_from_bool" `Pure (fun cx _ -> J.EUn (J.Not, J.EUn (J.Not, cx))); register_un_prim "caml_js_to_bool" `Pure (fun cx _ -> to_int cx); - register_un_prim "caml_js_from_string" `Mutable (fun cx loc -> - J.ECall (J.EDot (cx, "toString"), [], loc)); register_tern_prim "caml_js_set" (fun cx cy cz _ -> J.EBin (J.Eq, J.EAccess (cx, cy), cz)); register_bin_prim "caml_js_get" `Mutable (fun cx cy _ -> J.EAccess (cx, cy)); @@ -922,7 +916,11 @@ let _ = bool (J.EBin (J.EqEq, cx, cy))); register_bin_prim "caml_js_instanceof" `Pure (fun cx cy _ -> bool (J.EBin (J.InstanceOf, cx, cy))); - register_un_prim "caml_js_typeof" `Pure (fun cx _ -> J.EUn (J.Typeof, cx)) + register_un_prim "caml_js_typeof" `Pure (fun cx _ -> J.EUn (J.Typeof, cx)); + register_bin_prim "caml_string_notequal" `Pure (fun cx cy _ -> + J.EBin (J.NotEqEq, cx, cy)); + register_bin_prim "caml_string_equal" `Pure (fun cx cy _ -> + bool (J.EBin (J.EqEq, cx, cy))) (****) (* when raising ocaml exception and [improved_stacktrace] is enabled, diff --git a/compiler/lib/parse_bytecode.ml b/compiler/lib/parse_bytecode.ml index 62eae8c018..6db15f171c 100644 --- a/compiler/lib/parse_bytecode.ml +++ b/compiler/lib/parse_bytecode.ml @@ -2492,7 +2492,7 @@ let predefined_exceptions () = let v_name_js = Var.fresh () in let v_index = Var.fresh () in [ Let (v_name, Constant (String name)) - ; Let (v_name_js, Prim (Extern "caml_js_from_string", [ Pc (IString name) ])) + ; Let (v_name_js, Constant (IString name)) ; Let (v_index, Constant (Int (Int32.of_int (-index)))) ; Let (exn, Block (248, [| v_name; v_index |], NotArray)) ; Let diff --git a/compiler/num-testsuite/test.ml b/compiler/num-testsuite/test.ml index 8b05039648..89bae70cf6 100644 --- a/compiler/num-testsuite/test.ml +++ b/compiler/num-testsuite/test.ml @@ -5,7 +5,7 @@ let flush_all () = flush stdout; flush stderr;; let message s = print_string s; print_newline ();; let error_occurred = ref false;; -let immediate_failure = ref true;; +let immediate_failure = ref false;; let error () = if !immediate_failure then exit 2 else begin diff --git a/compiler/tests/obj_dup.ml b/compiler/tests/obj_dup.ml index 6a7420fcd9..f2a63f1791 100644 --- a/compiler/tests/obj_dup.ml +++ b/compiler/tests/obj_dup.ml @@ -41,7 +41,7 @@ let%expect_test _ = |}; [%expect {| true - true + false true true true diff --git a/compiler/tests/static_eval.ml b/compiler/tests/static_eval.ml index b3f0085972..9c6d44c461 100644 --- a/compiler/tests/static_eval.ml +++ b/compiler/tests/static_eval.ml @@ -52,6 +52,6 @@ let%expect_test "static eval of string get" = print_var_decl program "bx"; [%expect {| - var ex = call_with_char(caml_string_get(constant,- 10)); + var ex = call_with_char(caml_string_get("abcdefghijklmnopqrstuvwxyz",- 10)); var ax = call_with_char(103); - var bx = call_with_char(caml_string_get(constant,30)); |}] + var bx = call_with_char(caml_string_get("abcdefghijklmnopqrstuvwxyz",30)); |}] diff --git a/compiler/tests/variable_declaration_output.ml b/compiler/tests/variable_declaration_output.ml index 4a84218511..e383228364 100644 --- a/compiler/tests/variable_declaration_output.ml +++ b/compiler/tests/variable_declaration_output.ml @@ -50,7 +50,7 @@ let%expect_test _ = print_var_decl program "symbol_op"; [%expect {| - var ex = [0,5,runtime.caml_new_string("hello")]; + var ex = [0,5,"hello"]; var ax = [0,1,2,3,4]; var bx = [254,1.,2.,3.,4.]; var cx = [254,NaN,NaN,Infinity,- Infinity,0.,- 0.]; diff --git a/lib/js_of_ocaml/json.ml b/lib/js_of_ocaml/json.ml index 9725920484..d53e686059 100644 --- a/lib/js_of_ocaml/json.ml +++ b/lib/js_of_ocaml/json.ml @@ -36,35 +36,6 @@ class type json = let json : json Js.t = Unsafe.global##._JSON -external unsafe_equals : 'a -> 'b -> bool = "caml_js_equals" +let unsafe_input s = json##parse s -external to_byte_MlBytes : js_string t -> 'a t = "caml_js_to_byte_string" - -external to_byte_jsstring : 'a t -> js_string t = "caml_jsbytes_of_string" - -let input_reviver = - let reviver _this _key value = - if unsafe_equals (typeof value) (typeof (string "foo")) - then to_byte_MlBytes (Unsafe.coerce value) - else value - in - wrap_meth_callback reviver - -let unsafe_input s = json##parse_ s input_reviver - -class type obj = - object - method constructor : 'a. 'a constr Js.readonly_prop - end - -let mlString_constr = - let dummy_string = "" in - let dummy_obj : obj t = Obj.magic dummy_string in - dummy_obj##.constructor - -let output_reviver _key value = - if instanceof value mlString_constr - then to_byte_jsstring (Unsafe.coerce value) - else value - -let output obj = json##stringify_ obj output_reviver +let output obj = json##stringify obj diff --git a/runtime/bigstring.js b/runtime/bigstring.js index 1edf4dc122..b82dd588b9 100644 --- a/runtime/bigstring.js +++ b/runtime/bigstring.js @@ -1,9 +1,9 @@ ///////// BIGSTRING //Provides: caml_hash_mix_bigstring -//Requires: caml_hash_mix_string_arr +//Requires: caml_hash_mix_bytes_arr function caml_hash_mix_bigstring(h, bs) { - return caml_hash_mix_string_arr(h,bs.data); + return caml_hash_mix_bytes_arr(h,bs.data); } //Provides: bigstring_to_array_buffer mutable @@ -83,20 +83,20 @@ function caml_bigstring_blit_string_to_ba(str1, pos1, ba2, pos2, len){ } //Provides: caml_bigstring_blit_bytes_to_ba -//Requires: caml_invalid_argument, caml_array_bound_error, caml_array_of_string -//Requires: caml_ml_string_length +//Requires: caml_invalid_argument, caml_array_bound_error, caml_array_of_bytes +//Requires: caml_ml_bytes_length function caml_bigstring_blit_bytes_to_ba(str1, pos1, ba2, pos2, len){ if(12 != ba2.kind) caml_invalid_argument("caml_bigstring_blit_string_to_ba: kind mismatch"); if(len == 0) return 0; var ofs2 = ba2.offset(pos2); - if(pos1 + len > caml_ml_string_length(str1)) { + if(pos1 + len > caml_ml_bytes_length(str1)) { caml_array_bound_error(); } if(ofs2 + len > ba2.data.length) { caml_array_bound_error(); } - var slice = caml_array_of_string(str1).slice(pos1,pos1 + len); + var slice = caml_array_of_bytes(str1).slice(pos1,pos1 + len); ba2.data.set(slice,ofs2); return 0 } diff --git a/runtime/dynlink.js b/runtime/dynlink.js index 2fda72ef42..b714a4495d 100644 --- a/runtime/dynlink.js +++ b/runtime/dynlink.js @@ -22,7 +22,7 @@ var current_libs = [0, joo_global_object] //Provides: caml_dynlink_open_lib //Requires: current_libs, caml_failwith function caml_dynlink_open_lib (_mode,file) { - var name = file.toString(); + var name = file; joo_global_object.console.log("Dynlink: try to open ", name); //caml_failwith("file not found: "+name) current_libs.push({}); @@ -39,7 +39,7 @@ function caml_dynlink_close_lib (idx) { //Provides: caml_dynlink_lookup_symbol //Requires: current_libs function caml_dynlink_lookup_symbol (idx, fun_name) { - var name = fun_name.toString(); + var name = fun_name; joo_global_object.console.log("Dynlink: look for symbol ", name); if(current_libs[idx] && current_libs[idx][name]) return current_libs[idx][name]; diff --git a/runtime/fs.js b/runtime/fs.js index 5a9cb546a1..b54f10d6e8 100644 --- a/runtime/fs.js +++ b/runtime/fs.js @@ -244,7 +244,7 @@ function caml_create_file(name,content) { } //Provides: caml_read_file_content -//Requires: resolve_fs_device, caml_raise_no_such_file, caml_create_bytes +//Requires: resolve_fs_device, caml_raise_no_such_file, caml_create_bytes, caml_string_of_bytes function caml_read_file_content (name) { var root = resolve_fs_device(name); if(root.device.exists(root.rest)) { @@ -252,7 +252,7 @@ function caml_read_file_content (name) { var len = file.length(); var buf = caml_create_bytes(len); file.read(0,buf,0,len); - return buf + return caml_string_of_bytes(buf) } caml_raise_no_such_file(name); } diff --git a/runtime/fs_fake.js b/runtime/fs_fake.js index ff361bcbf2..ee5997fbf7 100644 --- a/runtime/fs_fake.js +++ b/runtime/fs_fake.js @@ -19,7 +19,7 @@ //Provides: MlFakeDevice //Requires: MlFakeFile, caml_create_bytes -//Requires: caml_raise_sys_error, caml_raise_no_such_file, caml_new_string, caml_string_of_array +//Requires: caml_raise_sys_error, caml_raise_no_such_file, caml_new_string, caml_string_of_array, caml_bytes_of_string //Requires: MlBytes function MlFakeDevice (root, f) { this.content={}; @@ -32,7 +32,7 @@ MlFakeDevice.prototype.nm = function(name) { MlFakeDevice.prototype.lookup = function(name) { if(!this.content[name] && this.lookupFun) { var res = this.lookupFun(caml_new_string(this.root), caml_new_string(name)); - if(res !== 0) this.content[name]=new MlFakeFile(res[1]); + if(res !== 0) this.content[name]=new MlFakeFile(caml_bytes_of_string(res[1])); } } MlFakeDevice.prototype.exists = function(name) { @@ -100,17 +100,22 @@ MlFakeDevice.prototype.register= function (name,content){ this.content[name] = new MlFakeFile(content); else if(content instanceof Array) this.content[name] = new MlFakeFile(caml_string_of_array(content)); + else if(typeof content == "string") { + var bytes = caml_bytes_of_string(content); + this.content[name] = new MlFakeFile(bytes); + } else if(content.toString) { - var mlstring = caml_new_string(content.toString()); - this.content[name] = new MlFakeFile(mlstring); + var bytes = caml_bytes_of_string(content.toString()); + this.content[name] = new MlFakeFile(bytes); } + else caml_raise_sys_error(this.nm(name) + " : registering file with invalid content type"); } MlFakeDevice.prototype.constructor = MlFakeDevice //Provides: MlFakeFile //Requires: MlFile -//Requires: caml_create_bytes, caml_ml_bytes_length,caml_blit_bytes +//Requires: caml_create_bytes, caml_ml_bytes_length, caml_blit_bytes, caml_blit_string //Requires: caml_bytes_get function MlFakeFile(content){ this.data = content; @@ -132,7 +137,7 @@ MlFakeFile.prototype.write = function(offset,buf,pos,len){ this.data = new_str; caml_blit_bytes(old_data, 0, this.data, 0, clen); } - caml_blit_bytes(buf, pos, this.data, offset, len); + caml_blit_string(buf, pos, this.data, offset, len); return 0 } MlFakeFile.prototype.read = function(offset,buf,pos,len){ diff --git a/runtime/fs_node.js b/runtime/fs_node.js index 03dc1deb16..b7b06443c6 100644 --- a/runtime/fs_node.js +++ b/runtime/fs_node.js @@ -102,9 +102,8 @@ MlNodeDevice.prototype.rename = function(o,n) { MlNodeDevice.prototype.constructor = MlNodeDevice - //Provides: MlNodeFile -//Requires: MlFile, caml_array_of_string, caml_bytes_set, caml_raise_sys_error +//Requires: MlFile, caml_array_of_string, caml_array_of_bytes, caml_bytes_set, caml_raise_sys_error function MlNodeFile(fd){ this.fs = require('fs'); this.fd = fd; @@ -138,7 +137,7 @@ MlNodeFile.prototype.write = function(offset,buf,buf_offset,len){ return 0; } MlNodeFile.prototype.read = function(offset,buf,buf_offset,len){ - var a = caml_array_of_string(buf); + var a = caml_array_of_bytes(buf); if(! (a instanceof joo_global_object.Uint8Array)) a = new joo_global_object.Uint8Array(a); var buffer = joo_global_object.Buffer.from(a); diff --git a/runtime/io.js b/runtime/io.js index 75fa9740a4..2319d9eb3f 100644 --- a/runtime/io.js +++ b/runtime/io.js @@ -199,10 +199,10 @@ function caml_ml_set_channel_refill(chanid,f) { } //Provides: caml_ml_refill_input -//Requires: caml_ml_bytes_length +//Requires: caml_ml_string_length function caml_ml_refill_input (chan) { var str = chan.refill(); - var str_len = caml_ml_bytes_length(str); + var str_len = caml_ml_string_length(str); if (str_len == 0) chan.refill = null; chan.file.write(chan.file.length(), str, 0, str_len); return str_len; @@ -230,7 +230,7 @@ function caml_ml_input (chanid, s, i, l) { } //Provides: caml_input_value -//Requires: caml_marshal_data_size, caml_input_value_from_string, caml_create_bytes, caml_ml_channels +//Requires: caml_marshal_data_size, caml_input_value_from_bytes, caml_create_bytes, caml_ml_channels function caml_input_value (chanid) { var chan = caml_ml_channels[chanid]; @@ -244,7 +244,7 @@ function caml_input_value (chanid) { chan.file.read(chan.offset,buf,0,len); var offset = [0]; - var res = caml_input_value_from_string(buf, offset); + var res = caml_input_value_from_bytes(buf, offset); chan.offset = chan.offset + offset[0]; return res; } @@ -346,18 +346,18 @@ function caml_ml_flush (chanid) { //Provides: caml_ml_output_bytes //Requires: caml_ml_flush,caml_ml_bytes_length -//Requires: caml_create_bytes, caml_blit_bytes, caml_raise_sys_error, caml_ml_channels, caml_jsbytes_of_string +//Requires: caml_create_bytes, caml_blit_bytes, caml_raise_sys_error, caml_ml_channels, caml_string_of_bytes function caml_ml_output_bytes(chanid,buffer,offset,len) { var chan = caml_ml_channels[chanid]; if(! chan.opened) caml_raise_sys_error("Cannot output to a closed channel"); - var string; + var bytes; if(offset == 0 && caml_ml_bytes_length(buffer) == len) - string = buffer; + bytes = buffer; else { - string = caml_create_bytes(len); - caml_blit_bytes(buffer,offset,string,0,len); + bytes = caml_create_bytes(len); + caml_blit_bytes(buffer,offset,bytes,0,len); } - var jsstring = caml_jsbytes_of_string(string); + var jsstring = caml_string_of_bytes(bytes); var id = jsstring.lastIndexOf("\n"); if(id < 0) chan.buffer+=jsstring; @@ -370,9 +370,9 @@ function caml_ml_output_bytes(chanid,buffer,offset,len) { } //Provides: caml_ml_output -//Requires: caml_ml_output_bytes +//Requires: caml_ml_output_bytes, caml_bytes_of_string function caml_ml_output(chanid,buffer,offset,len){ - return caml_ml_output_bytes(chanid,buffer,offset,len); + return caml_ml_output_bytes(chanid,caml_bytes_of_string(buffer),offset,len); } //Provides: caml_ml_output_char diff --git a/runtime/jslib_js_of_ocaml.js b/runtime/jslib_js_of_ocaml.js index 54c5595cba..8e218da609 100644 --- a/runtime/jslib_js_of_ocaml.js +++ b/runtime/jslib_js_of_ocaml.js @@ -28,8 +28,10 @@ function caml_js_from_float(x) { return x; } //Provides: caml_js_to_float const (const) function caml_js_to_float(x) { return x; } //Provides: caml_js_from_string mutable (const) -//Requires: MlBytes -function caml_js_from_string(s) { return s.toString(); } +//Requires: caml_is_ascii, caml_utf16_of_utf8 +function caml_js_from_string(s) { + if(caml_is_ascii(s)) return s; + return caml_utf16_of_utf8(s); } //Provides: caml_js_from_array mutable (shallow) //Requires: raw_array_sub function caml_js_from_array(a) { return raw_array_sub(a,1,a.length-1); } @@ -37,6 +39,12 @@ function caml_js_from_array(a) { return raw_array_sub(a,1,a.length-1); } //Requires: raw_array_cons function caml_js_to_array(a) { return raw_array_cons(a,0); } +//Provides: caml_js_to_byte_string const +function caml_js_to_byte_string(x) { return x } + +//Provides: caml_jsbytes_of_string const +function caml_jsbytes_of_string(x) { return x } + //Provides: caml_js_var mutable (const) //Requires: js_print_stderr //Requires: MlBytes @@ -170,9 +178,6 @@ function caml_js_wrap_meth_callback_unsafe(f) { } //Provides: caml_js_equals mutable (const, const) function caml_js_equals (x, y) { return +(x == y); } -//Provides: caml_js_to_byte_string const -//Requires: caml_new_string -function caml_js_to_byte_string (s) {return caml_new_string (s);} //Provides: caml_js_eval_string (const) //Requires: MlBytes diff --git a/runtime/lexing.js b/runtime/lexing.js index c9fc266dff..943b3a7f7f 100644 --- a/runtime/lexing.js +++ b/runtime/lexing.js @@ -16,9 +16,7 @@ /* The table-driven automaton for lexers generated by camllex. */ //Provides: caml_lex_array -//Requires: caml_jsbytes_of_string function caml_lex_array(s) { - s = caml_jsbytes_of_string(s); var l = s.length / 2; var a = new Array(l); for (var i = 0; i < l; i++) @@ -27,7 +25,7 @@ function caml_lex_array(s) { } //Provides: caml_lex_engine -//Requires: caml_failwith, caml_lex_array, caml_array_of_string +//Requires: caml_failwith, caml_lex_array, caml_array_of_bytes function caml_lex_engine(tbl, start_state, lexbuf) { var lex_buffer = 2; var lex_buffer_len = 3; @@ -52,7 +50,7 @@ function caml_lex_engine(tbl, start_state, lexbuf) { var c, state = start_state; - var buffer = caml_array_of_string(lexbuf[lex_buffer]); + var buffer = caml_array_of_bytes(lexbuf[lex_buffer]); if (state >= 0) { /* First entry */ @@ -110,7 +108,7 @@ function caml_lex_engine(tbl, start_state, lexbuf) { //Provides: caml_new_lex_engine //Requires: caml_failwith, caml_lex_array -//Requires: caml_jsbytes_of_string, caml_array_of_string +//Requires: caml_array_of_bytes function caml_lex_run_mem(s, i, mem, curr_pos) { for (;;) { var dst = s.charCodeAt(i); i++; @@ -170,11 +168,11 @@ function caml_new_lex_engine(tbl, start_state, lexbuf) { tbl.lex_trans_code = caml_lex_array (tbl[lex_trans_code]); tbl.lex_default_code = caml_lex_array (tbl[lex_default_code]); } - if (tbl.lex_code == null) tbl.lex_code = caml_jsbytes_of_string(tbl[lex_code]); + if (tbl.lex_code == null) tbl.lex_code = tbl[lex_code]; var c, state = start_state; - var buffer = caml_array_of_string(lexbuf[lex_buffer]); + var buffer = caml_array_of_bytes(lexbuf[lex_buffer]); if (state >= 0) { /* First entry */ diff --git a/runtime/marshal.js b/runtime/marshal.js index 41eb76eee8..f86a1020d1 100644 --- a/runtime/marshal.js +++ b/runtime/marshal.js @@ -47,10 +47,9 @@ var caml_marshal_constants = { } -//Provides: MlBytesReader -//Requires: caml_new_string, caml_jsbytes_of_string -function MlBytesReader (s, i) { this.s = caml_jsbytes_of_string(s); this.i = i; } -MlBytesReader.prototype = { +//Provides: MlStringReader +function MlStringReader (s, i) { this.s = s; this.i = i; } +MlStringReader.prototype = { read8u:function () { return this.s.charCodeAt(this.i++); }, read8s:function () { return this.s.charCodeAt(this.i++) << 24 >> 24; }, read16u:function () { @@ -78,7 +77,7 @@ MlBytesReader.prototype = { readstr:function (len) { var i = this.i; this.i = i + len; - return caml_new_string(this.s.substring(i, i + len)); + return this.s.substring(i, i + len); } } @@ -130,16 +129,16 @@ function caml_float_of_bytes (a) { } //Provides: caml_input_value_from_string mutable -//Requires: MlBytesReader, caml_input_value_from_reader +//Requires: MlStringReader, caml_input_value_from_reader function caml_input_value_from_string(s,ofs) { - var reader = new MlBytesReader (s, typeof ofs=="number"?ofs:ofs[0]); + var reader = new MlStringReader (s, typeof ofs=="number"?ofs:ofs[0]); return caml_input_value_from_reader(reader, ofs) } //Provides: caml_input_value_from_bytes mutable -//Requires: MlBytesReader, caml_input_value_from_reader +//Requires: MlStringReader, caml_input_value_from_reader, caml_string_of_bytes function caml_input_value_from_bytes(s,ofs) { - var reader = new MlBytesReader (s, typeof ofs=="number"?ofs:ofs[0]); + var reader = new MlStringReader (caml_string_of_bytes(s), typeof ofs=="number"?ofs:ofs[0]); return caml_input_value_from_reader(reader, ofs) } @@ -452,7 +451,8 @@ var caml_legacy_custom_code = true //Provides: caml_output_val //Requires: caml_int64_to_bytes, caml_failwith //Requires: caml_int64_bits_of_float -//Requires: MlBytes, caml_ml_string_length, caml_string_unsafe_get +//Requires: MlBytes, caml_ml_bytes_length, caml_bytes_unsafe_get +//Requires: caml_ml_string_length, caml_string_unsafe_get //Requires: MlObjectTable, caml_list_to_js_array, caml_legacy_custom_code, caml_custom_ops //Requires: caml_invalid_argument var caml_output_val = function (){ @@ -565,6 +565,18 @@ var caml_output_val = function (){ if (v.length > 1) stack.push (v, 1); } else if (v instanceof MlBytes) { if (memo(v)) return; + var len = caml_ml_bytes_length(v); + if (len < 0x20) + writer.write (8, 0x20 /*cst.PREFIX_SMALL_STRING*/ + len); + else if (len < 0x100) + writer.write_code (8, 0x09/*cst.CODE_STRING8*/, len); + else + writer.write_code (32, 0x0A /*cst.CODE_STRING32*/, len); + for (var i = 0;i < len;i++) + writer.write (8, caml_bytes_unsafe_get(v,i)); + writer.size_32 += 1 + (((len + 4) / 4)|0); + writer.size_64 += 1 + (((len + 8) / 8)|0); + } else if (typeof v == "string") { var len = caml_ml_string_length(v); if (len < 0x20) writer.write (8, 0x20 /*cst.PREFIX_SMALL_STRING*/ + len); @@ -624,9 +636,9 @@ function caml_output_value_to_string (v, flags) { } //Provides: caml_output_value_to_bytes mutable -//Requires: caml_output_val, caml_string_of_array +//Requires: caml_output_val, caml_bytes_of_array function caml_output_value_to_bytes (v, flags) { - return caml_string_of_array (caml_output_val (v, flags)); + return caml_bytes_of_array (caml_output_val (v, flags)); } //Provides: caml_output_value_to_buffer diff --git a/runtime/md5.js b/runtime/md5.js index 01212a237a..f2f3449a7c 100644 --- a/runtime/md5.js +++ b/runtime/md5.js @@ -146,27 +146,14 @@ var caml_md5_string = function () { // FIX: maybe we should perform the computation by chunk of 64 bytes // as in http://www.myersdaily.org/joseph/javascript/md5.js var buf = []; - switch (s.t & 6) { - default: - caml_convert_string_to_bytes(s); - case 0: /* BYTES */ - var b = s.c; - for (var i = 0; i < len; i+=4) { - var j = i + ofs; - buf[i>>2] = - b.charCodeAt(j) | (b.charCodeAt(j+1) << 8) | - (b.charCodeAt(j+2) << 16) | (b.charCodeAt(j+3) << 24); - } - for (; i < len; i++) buf[i>>2] |= b.charCodeAt(i + ofs) << (8 * (i & 3)); - break; - case 4: /* ARRAY */ - var a = s.c; - for (var i = 0; i < len; i+=4) { - var j = i + ofs; - buf[i>>2] = a[j] | (a[j+1] << 8) | (a[j+2] << 16) | (a[j+3] << 24); - } - for (; i < len; i++) buf[i>>2] |= a[i + ofs] << (8 * (i & 3)); + var b = s; + for (var i = 0; i < len; i+=4) { + var j = i + ofs; + buf[i>>2] = + b.charCodeAt(j) | (b.charCodeAt(j+1) << 8) | + (b.charCodeAt(j+2) << 16) | (b.charCodeAt(j+3) << 24); } + for (; i < len; i++) buf[i>>2] |= b.charCodeAt(i + ofs) << (8 * (i & 3)); return caml_string_of_array(md5(buf, len)); } } (); diff --git a/runtime/mlString.js b/runtime/mlString.js index 7ad9a5d83b..5034450578 100644 --- a/runtime/mlString.js +++ b/runtime/mlString.js @@ -173,35 +173,9 @@ function caml_is_ascii (s) { return !/[^\x00-\x7f]/.test(s); } -//Provides: caml_to_js_string -//Requires: caml_convert_string_to_bytes, caml_is_ascii, caml_utf16_of_utf8 -function caml_to_js_string(s) { - switch (s.t) { - case 9: /*BYTES | ASCII*/ - return s.c; - default: - caml_convert_string_to_bytes(s); - case 0: /*BYTES | UNKOWN*/ - if (caml_is_ascii(s.c)) { - s.t = 9; /*BYTES | ASCII*/ - return s.c; - } - s.t = 8; /*BYTES | NOT_ASCII*/ - case 8: /*BYTES | NOT_ASCII*/ - return caml_utf16_of_utf8(s.c); - } -} - -//Provides: caml_string_unsafe_get mutable +//Provides: caml_string_unsafe_get const function caml_string_unsafe_get (s, i) { - switch (s.t & 6) { - default: /* PARTIAL */ - if (i >= s.c.length) return 0; - case 0: /* BYTES */ - return s.c.charCodeAt(i); - case 4: /* ARRAY */ - return s.c[i] - } + return s.charCodeAt(i); } //Provides: caml_bytes_unsafe_get mutable @@ -217,7 +191,7 @@ function caml_bytes_unsafe_get (s, i) { } //Provides: caml_bytes_unsafe_set -//Requires: caml_convert_string_to_array +//Requires: caml_convert_bytes_to_array function caml_bytes_unsafe_set (s, i, c) { // The OCaml compiler uses Char.unsafe_chr on integers larger than 255! c &= 0xff; @@ -227,16 +201,16 @@ function caml_bytes_unsafe_set (s, i, c) { if (i + 1 == s.l) s.t = 0; /*BYTES | UNKOWN*/ return 0; } - caml_convert_string_to_array (s); + caml_convert_bytes_to_array (s); } s.c[i] = c; return 0; } //Provides: caml_string_unsafe_set -//Requires: caml_bytes_unsafe_set +//Requires: caml_failwith function caml_string_unsafe_set (s, i, c) { - return caml_bytes_unsafe_set(s,i,c); + caml_failwith("caml_string_unsafe_set"); } //Provides: caml_string_bound_error @@ -248,14 +222,14 @@ function caml_string_bound_error () { //Provides: caml_string_get //Requires: caml_string_bound_error, caml_string_unsafe_get function caml_string_get (s, i) { - if (i >>> 0 >= s.l) caml_string_bound_error(); + if (i >>> 0 >= s.length) caml_string_bound_error(); return caml_string_unsafe_get (s, i); } //Provides: caml_string_get16 //Requires: caml_string_unsafe_get, caml_string_bound_error function caml_string_get16(s,i) { - if (i >>> 0 >= s.l - 1) caml_string_bound_error(); + if (i >>> 0 >= s.length - 1) caml_string_bound_error(); var b1 = caml_string_unsafe_get (s, i), b2 = caml_string_unsafe_get (s, i + 1); return (b2 << 8 | b1); @@ -273,7 +247,7 @@ function caml_bytes_get16(s,i) { //Provides: caml_string_get32 //Requires: caml_string_unsafe_get, caml_string_bound_error function caml_string_get32(s,i) { - if (i >>> 0 >= s.l - 3) caml_string_bound_error(); + if (i >>> 0 >= s.length - 3) caml_string_bound_error(); var b1 = caml_string_unsafe_get (s, i), b2 = caml_string_unsafe_get (s, i + 1), b3 = caml_string_unsafe_get (s, i + 2), @@ -296,7 +270,7 @@ function caml_bytes_get32(s,i) { //Requires: caml_string_unsafe_get, caml_string_bound_error //Requires: caml_int64_of_bytes function caml_string_get64(s,i) { - if (i >>> 0 >= s.l - 7) caml_string_bound_error(); + if (i >>> 0 >= s.length - 7) caml_string_bound_error(); var a = new Array(8); for(var j = 0; j < 8; j++){ a[7 - j] = caml_string_unsafe_get (s, i + j); @@ -324,10 +298,9 @@ function caml_bytes_get (s, i) { } //Provides: caml_string_set -//Requires: caml_string_unsafe_set, caml_string_bound_error +//Requires: caml_failwith function caml_string_set (s, i, c) { - if (i >>> 0 >= s.l) caml_string_bound_error(); - return caml_string_unsafe_set (s, i, c); + caml_failwith("caml_string_set"); } //Provides: caml_bytes_set16 @@ -342,9 +315,9 @@ function caml_bytes_set16(s,i,i16){ } //Provides: caml_string_set16 -//Requires: caml_bytes_set16 +//Requires: caml_failwith function caml_string_set16(s,i,i16){ - return caml_bytes_set16(s,i,i16); + caml_failwith("caml_string_set16"); } //Provides: caml_bytes_set32 @@ -363,9 +336,9 @@ function caml_bytes_set32(s,i,i32){ } //Provides: caml_string_set32 -//Requires: caml_bytes_set32 +//Requires: caml_failwith function caml_string_set32(s,i,i32){ - return caml_bytes_set32(s,i,i32); + caml_failwith("caml_string_set32"); } //Provides: caml_bytes_set64 @@ -381,9 +354,9 @@ function caml_bytes_set64(s,i,i64){ } //Provides: caml_string_set64 -//Requires: caml_bytes_set64 +//Requires: caml_failwith function caml_string_set64(s,i,i64){ - return caml_bytes_set64(s,i,i64); + caml_failwith("caml_string_set64"); } //Provides: caml_bytes_set @@ -394,11 +367,26 @@ function caml_bytes_set (s, i, c) { } //Provides: MlBytes -//Requires: caml_to_js_string +//Requires: caml_convert_string_to_bytes, caml_is_ascii, caml_utf16_of_utf8 function MlBytes (tag, contents, length) { this.t=tag; this.c=contents; this.l=length; } -MlBytes.prototype.toString = function(){return caml_to_js_string(this)}; +MlBytes.prototype.toString = function(){ + switch (this.t) { + case 9: /*BYTES | ASCII*/ + return this.c; + default: + caml_convert_string_to_bytes(this); + case 0: /*BYTES | UNKOWN*/ + if (caml_is_ascii(this.c)) { + this.t = 9; /*BYTES | ASCII*/ + return this.c; + } + this.t = 8; /*BYTES | NOT_ASCII*/ + case 8: /*BYTES | NOT_ASCII*/ + return caml_utf16_of_utf8(this.c); + } +}; MlBytes.prototype.slice = function (){ var content = this.t == 4 ? this.c.slice() : this.c; return new MlBytes(this.t,content,this.l); @@ -415,8 +403,8 @@ function caml_convert_string_to_bytes (s) { s.t = 0; /*BYTES | UNKOWN*/ } -//Provides: caml_convert_string_to_array -function caml_convert_string_to_array (s) { +//Provides: caml_convert_bytes_to_array +function caml_convert_bytes_to_array (s) { /* Assumes not ARRAY */ if(joo_global_object.Uint8Array) { var a = new joo_global_object.Uint8Array(s.l); @@ -431,34 +419,34 @@ function caml_convert_string_to_array (s) { return a; } -//Provides: caml_array_of_string mutable -//Requires: caml_convert_string_to_array -function caml_array_of_string (s) { - if (s.t != 4 /* ARRAY */) caml_convert_string_to_array(s); +//Provides: caml_array_of_bytes mutable +//Requires: caml_convert_bytes_to_array +function caml_array_of_bytes (s) { + if (s.t != 4 /* ARRAY */) caml_convert_bytes_to_array(s); return s.c; } -//Provides: caml_jsbytes_of_string mutable -//Requires: caml_convert_string_to_bytes -function caml_jsbytes_of_string (s) { - if ((s.t & 6) != 0 /* BYTES */) caml_convert_string_to_bytes(s); - return s.c; +//Provides: caml_array_of_string mutable +//Requires: caml_convert_bytes_to_array +function caml_array_of_string (s) { + var a = new Array(s.length); + var l = s.length, i = 0; + for (; i < l; i++) a[i] = s.charCodeAt(i); + return a; } //Provides: caml_js_to_string const -//Requires: caml_is_ascii, caml_utf8_of_utf16, MlBytes +//Requires: caml_is_ascii, caml_utf8_of_utf16 function caml_js_to_string (s) { - var tag = 9 /* BYTES | ASCII */; - if (!caml_is_ascii(s)) - tag = 8 /* BYTES | NOT_ASCII */, s = caml_utf8_of_utf16(s); - return new MlBytes(tag, s, s.length); + if (caml_is_ascii(s)) + return s + else return caml_utf8_of_utf16(s); } //Provides: caml_create_string const -//Requires: MlBytes,caml_invalid_argument +//Requires: caml_invalid_argument function caml_create_string(len) { - if (len < 0) caml_invalid_argument("String.create"); - return new MlBytes(len?2:9,"",len); + caml_invalid_argument("String.create"); } //Provides: caml_create_bytes const //Requires: MlBytes,caml_invalid_argument @@ -468,23 +456,20 @@ function caml_create_bytes(len) { } //Provides: caml_new_string const (const) -//Requires: MlBytes -function caml_new_string (s) { return new MlBytes(0,s,s.length); } +function caml_new_string (s) { return s; } //Provides: caml_string_of_array -//Requires: MlBytes -function caml_string_of_array (a) { return new MlBytes(4,a,a.length); } +//Requires: caml_subarray_to_string +function caml_string_of_array (a) { return caml_subarray_to_string(a,0,a.length); } //Provides: caml_bytes_of_array -//Requires: MlBytes -function caml_bytes_of_array (a) { return new MlBytes(4,a,a.length); } +//Requires: caml_subarray_to_string, caml_bytes_of_string +function caml_bytes_of_array (a) { + return caml_bytes_of_string(caml_subarray_to_string(a,0,a.length)); } -//Provides: caml_string_compare mutable -//Requires: caml_convert_string_to_bytes +//Provides: caml_string_compare const function caml_string_compare(s1, s2) { - (s1.t & 6) && caml_convert_string_to_bytes(s1); - (s2.t & 6) && caml_convert_string_to_bytes(s2); - return (s1.c < s2.c)?-1:(s1.c > s2.c)?1:0; + return (s1 < s2)?-1:(s1 > s2)?1:0; } @@ -496,13 +481,10 @@ function caml_bytes_compare(s1, s2) { return (s1.c < s2.c)?-1:(s1.c > s2.c)?1:0; } -//Provides: caml_string_equal mutable (const, const) -//Requires: caml_convert_string_to_bytes +//Provides: caml_string_equal const (const, const) function caml_string_equal(s1, s2) { if(s1 === s2) return 1; - (s1.t & 6) && caml_convert_string_to_bytes(s1); - (s2.t & 6) && caml_convert_string_to_bytes(s2); - return (s1.c == s2.c)?1:0; + return 0; } //Provides: caml_bytes_equal mutable (const, const) @@ -514,7 +496,7 @@ function caml_bytes_equal(s1, s2) { return (s1.c == s2.c)?1:0; } -//Provides: caml_string_notequal mutable (const, const) +//Provides: caml_string_notequal const (const, const) //Requires: caml_string_equal function caml_string_notequal(s1, s2) { return 1-caml_string_equal(s1, s2); } @@ -522,12 +504,9 @@ function caml_string_notequal(s1, s2) { return 1-caml_string_equal(s1, s2); } //Requires: caml_string_equal function caml_bytes_notequal(s1, s2) { return 1-caml_string_equal(s1, s2); } -//Provides: caml_string_lessequal mutable -//Requires: caml_convert_string_to_bytes +//Provides: caml_string_lessequal const function caml_string_lessequal(s1, s2) { - (s1.t & 6) && caml_convert_string_to_bytes(s1); - (s2.t & 6) && caml_convert_string_to_bytes(s2); - return (s1.c <= s2.c)?1:0; + return (s1 <= s2)?1:0; } //Provides: caml_bytes_lessequal mutable @@ -538,12 +517,9 @@ function caml_bytes_lessequal(s1, s2) { return (s1.c <= s2.c)?1:0; } -//Provides: caml_string_lessthan mutable -//Requires: caml_convert_string_to_bytes +//Provides: caml_string_lessthan const function caml_string_lessthan(s1, s2) { - (s1.t & 6) && caml_convert_string_to_bytes(s1); - (s2.t & 6) && caml_convert_string_to_bytes(s2); - return (s1.c < s2.c)?1:0; + return (s1 < s2)?1:0; } //Provides: caml_bytes_lessthan mutable @@ -578,7 +554,7 @@ function caml_bytes_greaterthan(s1, s2) { } //Provides: caml_fill_bytes -//Requires: caml_str_repeat, caml_convert_string_to_array +//Requires: caml_str_repeat, caml_convert_bytes_to_array function caml_fill_bytes(s, i, l, c) { if (l > 0) { if (i == 0 && (l >= s.l || (s.t == 2 /* PARTIAL */ && l >= s.c.length))) { @@ -590,7 +566,7 @@ function caml_fill_bytes(s, i, l, c) { s.t = (l == s.l)?0 /* BYTES | UNKOWN */ :2; /* PARTIAL */ } } else { - if (s.t != 4 /* ARRAY */) caml_convert_string_to_array(s); + if (s.t != 4 /* ARRAY */) caml_convert_bytes_to_array(s); for (l += i; i < l; i++) s.c[i] = c; } } @@ -602,7 +578,7 @@ function caml_fill_bytes(s, i, l, c) { var caml_fill_string = caml_fill_bytes //Provides: caml_blit_bytes -//Requires: caml_subarray_to_string, caml_convert_string_to_array +//Requires: caml_subarray_to_string, caml_convert_bytes_to_array function caml_blit_bytes(s1, i1, s2, i2, len) { if (len == 0) return 0; if ((i2 == 0) && @@ -617,7 +593,7 @@ function caml_blit_bytes(s1, i1, s2, i2, len) { (i1 == 0 && s1.c.length == len)?s1.c:s1.c.substr(i1, len); s2.t = (s2.c.length == s2.l)?0 /* BYTES | UNKOWN */ :2; /* PARTIAL */ } else { - if (s2.t != 4 /* ARRAY */) caml_convert_string_to_array(s2); + if (s2.t != 4 /* ARRAY */) caml_convert_bytes_to_array(s2); var c1 = s1.c, c2 = s2.c; if (s1.t == 4 /* ARRAY */) { if (i2 <= i1) { @@ -635,20 +611,26 @@ function caml_blit_bytes(s1, i1, s2, i2, len) { } //Provides: caml_blit_string -//Requires: caml_blit_bytes -function caml_blit_string(s1, i1, s2, i2, len) { - // TODO: s1 -> string to bytes - return caml_blit_bytes(s1, i1, s2, i2, len); +//Requires: caml_blit_bytes, caml_bytes_of_string +function caml_blit_string(a,b,c,d,e) { + caml_blit_bytes(caml_bytes_of_string(a),b,c,d,e); + return 0 } //Provides: caml_ml_string_length const -function caml_ml_string_length(s) { return s.l } +function caml_ml_string_length(s) { return s.length } //Provides: caml_ml_bytes_length const function caml_ml_bytes_length(s) { return s.l } -//Provides: caml_string_of_bytes const -function caml_string_of_bytes(s) { return s} - -//Provides: caml_bytes_of_string const -function caml_bytes_of_string(s) { return s} +//Provides: caml_string_of_bytes +//Requires: caml_convert_string_to_bytes +function caml_string_of_bytes(s) { + (s.t & 6) && caml_convert_string_to_bytes(s); + return s.c; +} +//Provides: caml_bytes_of_string +//Requires: MlBytes +function caml_bytes_of_string(s) { + return new MlBytes(0,s,s.length); +} diff --git a/runtime/stdlib.js b/runtime/stdlib.js index 78796e7c14..a7da7e8cf6 100644 --- a/runtime/stdlib.js +++ b/runtime/stdlib.js @@ -108,9 +108,9 @@ function caml_call_gen(f, args) { var caml_named_values = {}; //Provides: caml_register_named_value (const,const) -//Requires: caml_named_values, caml_jsbytes_of_string +//Requires: caml_named_values function caml_register_named_value(nm,v) { - caml_named_values[caml_jsbytes_of_string(nm)] = v; + caml_named_values[nm] = v; return 0; } @@ -149,9 +149,9 @@ function caml_return_exn_constant (tag) { return tag; } function caml_raise_with_arg (tag, arg) { throw [0, tag, arg]; } //Provides: caml_raise_with_string (const, const) -//Requires: caml_raise_with_arg,caml_new_string +//Requires: caml_raise_with_arg function caml_raise_with_string (tag, msg) { - caml_raise_with_arg (tag, caml_new_string (msg)); + caml_raise_with_arg (tag, msg); } //Provides: caml_raise_sys_error (const) @@ -176,7 +176,9 @@ function caml_wrap_exception(e) { && e instanceof joo_global_object.RangeError && e.message && e.message.match(/maximum call stack/i)) - return caml_return_exn_constant(caml_global_data.Stack_overflow); + { + return caml_return_exn_constant(caml_global_data.Stack_overflow); + } //Stack_overflow: firefox if(joo_global_object.InternalError && e instanceof joo_global_object.InternalError @@ -252,6 +254,8 @@ function caml_obj_tag (x) { return x[0] else if (x instanceof MlBytes) return 252 + else if (typeof x == "string") + return 252 else if ((x instanceof Function) || typeof x == "function") return 247 else if (x && x.caml_custom) @@ -429,7 +433,7 @@ function caml_compare_val_number_custom(num, custom, swap, total) { } //Provides: caml_compare_val (const, const, const) -//Requires: caml_int64_compare, caml_int_compare, caml_string_compare +//Requires: caml_int64_compare, caml_int_compare, caml_string_compare, caml_bytes_compare //Requires: caml_invalid_argument, caml_compare_val_get_custom, caml_compare_val_tag //Requires: caml_compare_val_number_custom function caml_compare_val (a, b, total) { @@ -483,7 +487,7 @@ function caml_compare_val (a, b, total) { break; case 252: // OCaml string if (a !== b) { - var x = caml_string_compare(a, b); + var x = caml_bytes_compare(a, b); if (x != 0) return (x | 0); }; break; @@ -681,10 +685,9 @@ function caml_int_of_string (s) { } //Provides: caml_float_of_string (const) -//Requires: caml_failwith, caml_jsbytes_of_string +//Requires: caml_failwith function caml_float_of_string(s) { var res; - s = caml_jsbytes_of_string (s); res = +s; if ((s.length > 0) && (res === res)) return res; s = s.replace(/_/g,""); @@ -709,9 +712,8 @@ function caml_is_printable(c) { return +(c > 31 && c < 127); } ///////////// Format //Provides: caml_parse_format -//Requires: caml_jsbytes_of_string, caml_invalid_argument +//Requires: caml_invalid_argument function caml_parse_format (fmt) { - fmt = caml_jsbytes_of_string(fmt); var len = fmt.length; if (len > 31) caml_invalid_argument("format_int: format too long"); var f = @@ -765,7 +767,6 @@ function caml_parse_format (fmt) { } //Provides: caml_finish_formatting -//Requires: caml_new_string function caml_finish_formatting(f, rawbuffer) { if (f.uppercase) rawbuffer = rawbuffer.toUpperCase(); var len = rawbuffer.length; @@ -790,14 +791,13 @@ function caml_finish_formatting(f, rawbuffer) { buffer += rawbuffer; if (f.justify == '-') for (var i = len; i < f.width; i++) buffer += ' '; - return caml_new_string (buffer); + return buffer; } //Provides: caml_format_int const (const, const) //Requires: caml_parse_format, caml_finish_formatting, caml_str_repeat -//Requires: caml_new_string, caml_jsbytes_of_string function caml_format_int(fmt, i) { - if (caml_jsbytes_of_string(fmt) == "%d") return caml_new_string(""+i); + if (fmt == "%d") return ""+i; var f = caml_parse_format(fmt); if (i < 0) { if (f.signedconv) { f.sign = -1; i = -i; } else i >>>= 0; } var s = i.toString(f.base); @@ -905,6 +905,9 @@ function caml_hash_univ_param (count, limit, obj) { hash_accu = (hash_accu * 19 + obj[0]) | 0; for (var i = obj.length - 1; i > 0; i--) hash_aux (obj[i]); } + } else if (typeof obj === "string") { + for (var b = obj, l = obj.length, i = 0; i < l; i++) + hash_accu = (hash_accu * 19 + b.charCodeAt(i)) | 0; } else if (obj instanceof MlBytes) { count --; switch (obj.t & 6) { @@ -975,9 +978,9 @@ function caml_hash_mix_int64 (h, v) { return h; } -//Provides: caml_hash_mix_string_str +//Provides: caml_hash_mix_bytes_str //Requires: caml_hash_mix_int -function caml_hash_mix_string_str(h, s) { +function caml_hash_mix_bytes_str(h, s) { var len = s.length, i, w; for (i = 0; i + 4 <= len; i += 4) { w = s.charCodeAt(i) @@ -999,9 +1002,9 @@ function caml_hash_mix_string_str(h, s) { return h; } -//Provides: caml_hash_mix_string_arr +//Provides: caml_hash_mix_bytes_arr //Requires: caml_hash_mix_int -function caml_hash_mix_string_arr(h, s) { +function caml_hash_mix_bytes_arr(h, s) { var len = s.length, i, w; for (i = 0; i + 4 <= len; i += 4) { w = s[i] @@ -1022,28 +1025,34 @@ function caml_hash_mix_string_arr(h, s) { return h; } -//Provides: caml_hash_mix_string +//Provides: caml_hash_mix_bytes //Requires: caml_convert_string_to_bytes -//Requires: caml_hash_mix_string_str -//Requires: caml_hash_mix_string_arr -function caml_hash_mix_string(h, v) { +//Requires: caml_hash_mix_bytes_str +//Requires: caml_hash_mix_bytes_arr +function caml_hash_mix_bytes(h, v) { switch (v.t & 6) { default: caml_convert_string_to_bytes (v); case 0: /* BYTES */ - h = caml_hash_mix_string_str(h, v.c); + h = caml_hash_mix_bytes_str(h, v.c); break; case 2: /* ARRAY */ - h = caml_hash_mix_string_arr(h, v.c); + h = caml_hash_mix_bytes_arr(h, v.c); } return h } +//Provides: caml_hash_mix_string +//Requires: caml_hash_mix_bytes_str +function caml_hash_mix_string(h, v) { + return caml_hash_mix_bytes_str(h, v); +} + //Provides: caml_hash mutable //Requires: MlBytes //Requires: caml_int64_bits_of_float, caml_hash_mix_int, caml_hash_mix_final -//Requires: caml_hash_mix_int64, caml_hash_mix_float, caml_hash_mix_string, caml_custom_ops +//Requires: caml_hash_mix_int64, caml_hash_mix_float, caml_hash_mix_string, caml_hash_mix_bytes, caml_custom_ops function caml_hash (count, limit, seed, obj) { var queue, rd, wr, sz, num, h, v, i, len; sz = limit; @@ -1085,9 +1094,12 @@ function caml_hash (count, limit, seed, obj) { } break; } - } else if (v instanceof MlBytes) { + } else if (typeof v === "string") { h = caml_hash_mix_string(h,v) num--; + } else if (v instanceof MlBytes) { + h = caml_hash_mix_bytes(h,v) + num--; } else if (v === (v|0)) { // Integer h = caml_hash_mix_int(h, v+v+1); @@ -1111,15 +1123,13 @@ function caml_sys_time () { } //Provides: caml_sys_get_config const -//Requires: caml_new_string function caml_sys_get_config () { - return [0, caml_new_string("Unix"), 32, 0]; + return [0, "Unix", 32, 0]; } //Provides: caml_sys_const_backend_type const -//Requires: caml_new_string function caml_sys_const_backend_type () { - return [0, caml_new_string("js_of_ocaml")]; + return [0, "js_of_ocaml"]; } //Provides: caml_sys_random_seed mutable @@ -1433,14 +1443,12 @@ function caml_ml_runtime_warnings_enabled (_unit) { } //Provides: caml_runtime_variant -//Requires: caml_new_string function caml_runtime_variant(_unit) { - return caml_new_string(""); + return ""; } //Provides: caml_runtime_parameters -//Requires: caml_new_string function caml_runtime_parameters(_unit) { - return caml_new_string(""); + return ""; } diff --git a/runtime/toplevel.js b/runtime/toplevel.js index 5811722ebf..06437014bf 100644 --- a/runtime/toplevel.js +++ b/runtime/toplevel.js @@ -61,8 +61,10 @@ function caml_reify_bytecode (code, _sz) { //Requires: caml_failwith //Version: >= 4.08 function caml_reify_bytecode (code, _sz,_) { - if(joo_global_object.toplevelCompile) - return [0, 0, joo_global_object.toplevelCompile(code)]; + if(joo_global_object.toplevelCompile) { + var x = joo_global_object.toplevelCompile(code); + return [0, 0, x]; + } else caml_failwith("Toplevel not initialized (toplevelCompile)") } diff --git a/toplevel/examples/lwt_toplevel/dune b/toplevel/examples/lwt_toplevel/dune index d154d8e3d3..12454de9b2 100644 --- a/toplevel/examples/lwt_toplevel/dune +++ b/toplevel/examples/lwt_toplevel/dune @@ -80,6 +80,7 @@ --toplevel --disable shortvar --noruntime + --pretty %{lib:js_of_ocaml-compiler:runtime.js} %{lib:js_of_ocaml-compiler:toplevel.js} %{lib:js_of_ocaml-compiler:dynlink.js} diff --git a/toplevel/lib/jsooTop.ml b/toplevel/lib/jsooTop.ml index 7e1fecfef8..c314897508 100644 --- a/toplevel/lib/jsooTop.ml +++ b/toplevel/lib/jsooTop.ml @@ -100,7 +100,6 @@ let setup = res); Js.Unsafe.global##.toplevelReloc := Js.Unsafe.callback (fun name -> - let name = Js.to_string name in Js_of_ocaml_compiler.Ocaml_compiler.Symtable.reloc_ident name); ())