4 function h
$logEnv() { h
$log
.apply(h
$log
,arguments
); }
5 #define
TRACE_ENV(args
...) h
$logEnv(args
)
7 #define
TRACE_ENV(args
...)
10 // set up debug logging for the current JS environment/engine
11 // browser also logs to <div id="output"> if jquery is detected
12 // the various debug tracing options use h$log
15 function h
$getGlbl() { h
$glbl
= this; }
18 #ifdef GHCJS_LOG_BUFFER
19 var h
$logBufferSize
= 6000;
20 var h
$logBufferShrink
= 1000;
24 #ifdef GHCJS_LOG_BUFFER
25 if(!h
$logBuffer
) return;
27 for(var i
=0;i
<arguments
.length
;i
++) { s
= s
+ arguments
[i
]; }
29 if(h
$logBuffer
.length
> h
$logBufferSize
) h
$logBuffer
= h
$logBuffer
.slice(h
$logBufferShrink
);
34 if(h
$glbl
.console
&& h
$glbl
.console
.log
) {
35 h
$glbl
.console
.log
.apply(h
$glbl
.console
,arguments
);
37 h
$glbl
.print
.apply(this,arguments
);
40 if(typeof console
!== 'undefined') {
42 console
.log
.apply(console
, arguments
);
44 } else if(typeof print
!== 'undefined') {
45 print
.apply(null, arguments
);
50 // ignore console.log exceptions (for example for IE9 when console is closed)
53 #ifdef GHCJS_LOG_JQUERY
54 // if we have jquery, add to <div id='output'> element
55 if(typeof(jQuery
) !== 'undefined') {
57 for(var i
=0;i
<arguments
.length
;i
++) { x
= x
+ arguments
[i
]; }
58 var xd
= jQuery("<div></div>");
60 jQuery('#output').append(xd
);
65 function h
$collectProps(o
) {
67 for(var p
in o
) { props
.push(p
); }
68 return("{"+props
.join(",")+"}");
73 // load the command line arguments in h$programArgs
74 // the first element is the program name
78 function h
$programArgs() {
79 if (!h
$programArgs_
) {
82 return h
$programArgs_
;
85 function h
$rtsArgs() {
92 function h
$initArgs() {
94 h
$programArgs_
= [ "a.js" ];
97 h
$programArgs_
= process
.argv
.slice(1);
98 } else if(h
$isJvm()) {
99 h
$programArgs_
= h
$getGlobal(this).arguments
.slice(0);
100 h
$programArgs_
.unshift("a.js");
101 } else if(h
$isJsShell() && typeof h
$getGlobal(this).scriptArgs
!== 'undefined') {
102 h
$programArgs_
= h
$getGlobal(this).scriptArgs
.slice(0);
103 h
$programArgs_
.unshift("a.js");
104 } else if((h
$isJsShell() || h
$isJsCore()) && typeof h
$getGlobal(this).arguments
!== 'undefined') {
105 h
$programArgs_
= h
$getGlobal(this).arguments
.slice(0);
106 h
$programArgs_
.unshift("a.js");
108 h
$programArgs_
= [ "a.js" ];
112 //filter RTS arguments
118 for(i
=0;i
<h
$programArgs_
.length
;i
++) {
119 var a
= h
$programArgs_
[i
];
120 // The '--RTS' argument disables all future
121 // +RTS ... -RTS processing.
125 // The '--' argument is passed through to the program, but
126 // disables all further +RTS ... -RTS processing.
127 else if (a
=== "--") {
130 else if (a
=== "+RTS") {
133 else if (a
=== "-RTS") {
143 // process remaining program arguments
144 for (;i
<h
$programArgs_
.length
;i
++) {
145 prog_args
.push(h
$programArgs_
[i
]);
147 //set global variables
148 h
$programArgs_
= prog_args
;
149 h
$rtsArgs_
= rts_args
;
153 function h
$getProgArgv(argc_v
,argc_off
,argv_v
,argv_off
) {
154 TRACE_ENV("getProgArgV")
155 var c
= h
$programArgs().length
;
157 argc_v
.dv
.setInt32(argc_off
, 0, true);
159 argc_v
.dv
.setInt32(argc_off
, c
, true);
160 var argv
= h
$newByteArray(4*c
);
161 for(var i
=0;i
<h
$programArgs().length
;i
++) {
162 PUT_ADDR(argv
,4*i
,h
$encodeUtf8(h
$programArgs()[i
]),0);
164 PUT_ADDR(argv_v
,argv_off
,argv
,0);
168 function h
$setProgArgv(n
, ptr_d
, ptr_o
) {
170 for(var i
=0;i
<n
;i
++) {
172 GET_ADDR(ptr_d
,off
,p
,o
);
173 var arg
= h
$decodeUtf8z(p
, o
);
176 h
$programArgs_
= args
;
179 function h
$getpid() {
180 #ifndef GHCJS_BROWSER
181 if(h
$isNode()) return process
.id
;
186 function h
$cpuTimePrecision() {
190 var h
$fakeCpuTime
= 1.0;
192 function h
$getCPUTime() {
193 #ifndef GHCJS_BROWSER
195 var t
= process
.cpuUsage();
196 var cput
= t
.user
+ t
.system
;
197 TRACE_ENV("getCPUTime: " + cput
)
201 // XXX this allows more testsuites to run
202 // but I don't really like returning a fake value here
203 TRACE_ENV("getCPUTime: returning fake value")
204 return ++h
$fakeCpuTime
;
208 function h
$__hscore_environ() {
209 TRACE_ENV("hscore_environ")
210 #ifndef GHCJS_BROWSER
213 for(i
in process
.env
) {
214 var envv
= i
+ '=' + process
.env
[i
];
215 TRACE_ENV("hscore_environ: " + envv
)
218 if(env
.length
=== 0) return null;
219 var p
= h
$newByteArray(4*env
.length
+1);
220 for(i
=0;i
<env
.length
;i
++) {
221 PUT_ADDR(p
,4*i
,h
$encodeUtf8(env
[i
]),0);
223 PUT_ADDR(p
,4*env
.length
,null,0);
224 RETURN_UBX_TUP2(p
, 0);
227 RETURN_UBX_TUP2(null, 0);
230 function h
$__hsbase_unsetenv(name
, name_off
) {
231 return h
$unsetenv(name
, name_off
);
234 function h
$getenv(name
, name_off
) {
236 #ifndef GHCJS_BROWSER
238 var n
= h
$decodeUtf8z(name
, name_off
);
239 TRACE_ENV("getenv (node): " + n
)
240 if(typeof process
.env
[n
] !== 'undefined') {
241 TRACE_ENV("getenv (node): " + n
+ " -> " + process
.env
[n
])
242 RETURN_UBX_TUP2(h
$encodeUtf8(process
.env
[n
]), 0);
246 RETURN_UBX_TUP2(null, 0);
249 function h
$setenv(name
, name_off
, val
, val_off
, overwrite
) {
250 var n
= h
$decodeUtf8z(name
, name_off
);
251 var v
= h
$decodeUtf8z(val
, val_off
);
252 TRACE_ENV("setenv: " + n
+ " -> " + v
)
253 if(n
.indexOf('=') !== -1) {
254 h
$setErrno("EINVAL");
257 #ifndef GHCJS_BROWSER
259 if(overwrite
|| typeof process
.env
[n
] !== 'undefined') process
.env
[n
] = v
;
265 function h
$unsetenv(name
, name_off
) {
266 var n
= h
$decodeUtf8z(name
, name_off
);
267 TRACE_ENV("unsetenv: " + n
)
268 if(n
.indexOf('=') !== -1) {
269 h
$setErrno("EINVAL");
272 #ifndef GHCJS_BROWSER
273 if(h
$isNode()) delete process
.env
[n
];
280 SUSv2 specifies that the argument passed to putenv is made part
281 of the environment. Later changes to the value will be reflected
284 this implementation makes a copy instead.
286 function h
$putenv(str
, str_off
) {
287 #ifndef GHCJS_BROWSER
288 var x
= h
$decodeUtf8z(str
, str_off
);
289 var i
= x
.indexOf('=');
290 TRACE_ENV("putenv: " + x
)
291 if(i
=== -1) { // remove the value
292 TRACE_ENV("putenv unset: " + x
)
293 if(h
$isNode()) delete process
.env
[x
];
294 } else { // set the value
295 var name
= x
.substring(0, i
)
296 var val
= x
.substring(i
+1);
297 TRACE_ENV("putenv set: " + name
+ " -> " + val
)
298 if(h
$isNode()) process
.env
[name
] = val
;
304 function h
$errorBelch() {
305 h
$log("### errorBelch: do we need to handle a vararg function here?");
308 function h
$errorBelch2(buf1
, buf_offset1
, buf2
, buf_offset2
) {
309 var pat
= h
$decodeUtf8z(buf1
, buf_offset1
);
310 h
$errorMsg(h
$append_prog_name(pat
), h
$decodeUtf8z(buf2
, buf_offset2
));
313 // append program name to the given string if possible
314 function h
$append_prog_name(str
) {
315 // basename that only works with Unix paths for now...
316 function basename(path
) {
317 return path
.split('/').reverse()[0];
320 // only works for node for now
322 return basename(process
.argv
[1]) + ": " + str
;
328 function h
$debugBelch2(buf1
, buf_offset1
, buf2
, buf_offset2
) {
329 h
$errorMsg(h
$decodeUtf8z(buf1
, buf_offset1
), h
$decodeUtf8z(buf2
, buf_offset2
));
332 function h
$errorMsg(pat
) {
333 #ifndef GHCJS_BROWSER
334 function stripTrailingNewline(xs
) {
335 return xs
.replace(/\r?\n$/, "");
338 // poor man's vprintf
340 for(var i
=1;i
<arguments
.length
;i
++) {
341 str
= str
.replace(/%s/, arguments
[i
]);
343 #ifndef GHCJS_BROWSER
346 } else if(h
$isNode()) {
347 process
.stderr
.write(str
);
348 } else if (h
$isJsShell() && typeof printErr
!== 'undefined') {
349 if(str
.length
) printErr(stripTrailingNewline(str
));
350 } else if (h
$isJsShell() && typeof putstr
!== 'undefined') {
352 } else if (h
$isJsCore()) {
354 if(h
$base_stderrLeftover
.val
!== null) {
355 debug(h
$base_stderrLeftover
.val
+ stripTrailingNewline(str
));
356 h
$base_stderrLeftover
.val
= null;
358 debug(stripTrailingNewline(str
));
363 if(typeof console
!== 'undefined') {
366 #ifndef GHCJS_BROWSER
371 // this needs to be imported with foreign import ccall safe/interruptible
372 function h
$performMajorGC() {
373 // save current thread state so we can enter the GC
374 var t
= h
$currentThread
, err
= null;
376 h
$currentThread
= null;
384 // restore thread state
393 function h
$ghczminternalZCSystemziCPUTimeZCgetrusage() {
397 function h
$getrusage() {
402 // fixme need to fix these struct locations
404 function h
$gettimeofday(tv_v
,tv_o
,tz_v
,tz_o
) {
405 var now
= Date
.now();
406 tv_v
.dv
.setInt32(tv_o
, (now
/ 1000)|0, true);
407 tv_v
.dv
.setInt32(tv_o
+ 4, ((now
% 1000) * 1000)|0, true);
408 if(tv_v
.len
>= tv_o
+ 12) {
409 tv_v
.dv
.setInt32(tv_o
+ 8, ((now
% 1000) * 1000)|0, true);
414 var h
$__hscore_gettimeofday
= h
$gettimeofday
;
416 var h
$myTimeZone
= h
$encodeUtf8("UTC");
417 function h
$localtime_r(timep_v
, timep_o
, result_v
, result_o
) {
418 var t
= timep_v
.i3
[timep_o
];
419 var d
= new Date(t
* 1000);
420 result_v
.dv
.setInt32(result_o
, d
.getSeconds(), true);
421 result_v
.dv
.setInt32(result_o
+ 4 , d
.getMinutes(), true);
422 result_v
.dv
.setInt32(result_o
+ 8 , d
.getHours(), true);
423 result_v
.dv
.setInt32(result_o
+ 12, d
.getDate(), true);
424 result_v
.dv
.setInt32(result_o
+ 16, d
.getMonth(), true);
425 result_v
.dv
.setInt32(result_o
+ 20, d
.getFullYear()-1900, true);
426 result_v
.dv
.setInt32(result_o
+ 24, d
.getDay(), true);
427 result_v
.dv
.setInt32(result_o
+ 28, 0, true); // fixme yday 1-365 (366?)
428 result_v
.dv
.setInt32(result_o
+ 32, -1, true); // dst information unknown
429 result_v
.dv
.setInt32(result_o
+ 40, 0, true); // gmtoff?
430 PUT_ADDR(result_v
,result_o
+40, h
$myTimeZone
, 0);
431 PUT_ADDR(result_v
,result_o
+48, h
$myTimeZone
, 0);
432 RETURN_UBX_TUP2(result_v
, result_o
);
434 var h
$__hscore_localtime_r
= h
$localtime_r
;
436 function h
$checkForeignRefs(refs
) {
437 function argSize(t
) {
438 if(t
=== "ghc-internal:GHC.Internal.Prim.Word64#") return 2;
439 if(t
=== "ghc-internal:GHC.Internal.Prim.State#") return 0;
440 if(t
=== "ghc-internal:GHC.Internal.Prim.Void#") return 0;
441 if(t
=== "ghc-internal:GHC.Internal.Prim.Int#") return 1;
442 if(t
=== "ghc-internal:GHC.Internal.Prim.Int64#") return 2;
443 if(t
=== "ghc-internal:GHC.Internal.Prim.Weak#") return 1;
444 if(t
=== "ghc-internal:GHC.Internal.Prim.Addr#") return 2;
445 if(t
=== "ghc-internal:GHC.Internal.Prim.Word#") return 1;
446 if(t
=== "ghc-internal:GHC.Internal.Prim.Float#") return 1;
447 if(t
=== "ghc-internal:GHC.Internal.Prim.Double#") return 1;
448 if(t
=== "ghc-internal:GHC.Internal.Prim.ByteArray#") return 2;
449 if(t
=== "ghc-internal:GHC.Internal.Prim.ThreadId#") return 1;
450 console
.warn("unknown argument type: " + t
);
453 function callStr(r
) {
454 return r
.pattern
+ '(' + r
.arguments
.join(', ') + ') -> ' + r
.result
+ ' ' + r
.span
;
456 function checkRef(r
) {
457 if(r
.cconv
=== "ccall") {
463 console
.warn("referenced pattern does not exist: " + callStr(r
));
466 if(typeof f
!== 'function') {
467 console
.warn("referenced pattern is not a function: " + callStr(r
));
471 for(var i
= 0; i
< r
.arguments
.length
; i
++) {
472 var a
= r
.arguments
[i
];
474 ba
+= a
=== "ghc-internal:GHC.Internal.Prim.ByteArray#" ? 1 : 0;
477 console
.warn("number of arguments does not seem to match: " + callStr(r
));
479 if(ba
!== 0 && f
.length
=== (s
- ba
)) {
480 console
.warn("number of arguments matches old ByteArray calling convention: " + callStr(r
));
483 // todo: check other calling conventions
485 for(var i
=0;i
<refs
.length
;i
++) {
490 var h
$GHCConcSignalSignalHandlerStore_d
= null;
491 var h
$GHCConcSignalSignalHandlerStore_o
= 0;
493 function h
$getOrSetGHCConcSignalSignalHandlerStore(d
,o
) {
495 h
$GHCConcSignalSignalHandlerStore_d
= d
;
496 h
$GHCConcSignalSignalHandlerStore_o
= o
;
498 RETURN_UBX_TUP2(h
$GHCConcSignalSignalHandlerStore_d
, h
$GHCConcSignalSignalHandlerStore_o
);