xref: /openbsd-src/gnu/llvm/clang/www/demo/index.cgi (revision 12c855180aad702bbcca06e0398d774beeafb155)
1a9ac8606Spatrick#!/usr/dcs/software/supported/bin/perl
2e5dd7070Spatrick# LLVM Web Demo script
3e5dd7070Spatrick#
4e5dd7070Spatrick
5e5dd7070Spatrickuse strict;
6e5dd7070Spatrickuse CGI;
7e5dd7070Spatrickuse POSIX;
8e5dd7070Spatrickuse Mail::Send;
9a9ac8606Spatrickuse warnings;
10e5dd7070Spatrick
11e5dd7070Spatrick$| = 1;
12e5dd7070Spatrick
13e5dd7070Spatrickmy $ROOT = "/tmp/webcompile";
14e5dd7070Spatrick#my $ROOT = "/home/vadve/lattner/webcompile";
15e5dd7070Spatrick
16e5dd7070Spatrickopen( STDERR, ">&STDOUT" ) or die "can't redirect stderr to stdout";
17e5dd7070Spatrick
18e5dd7070Spatrickif ( !-d $ROOT ) { mkdir( $ROOT, 0777 ); }
19e5dd7070Spatrick
20e5dd7070Spatrickmy $LOGFILE         = "$ROOT/log.txt";
21e5dd7070Spatrickmy $FORM_URL        = 'index.cgi';
22e5dd7070Spatrickmy $MAILADDR        = 'sabre@nondot.org';
23*12c85518Srobertmy $CONTACT_ADDRESS = 'Questions or comments?  Discuss on the <a href="https://discourse.llvm.org">LLVM forum</a>.';
24e5dd7070Spatrickmy $LOGO_IMAGE_URL  = 'cathead.png';
25e5dd7070Spatrickmy $TIMEOUTAMOUNT   = 20;
26e5dd7070Spatrick$ENV{'LD_LIBRARY_PATH'} = '/home/vadve/shared/localtools/fc1/lib/';
27e5dd7070Spatrick
28e5dd7070Spatrickmy @PREPENDPATHDIRS =
29e5dd7070Spatrick  (
30e5dd7070Spatrick    '/home/vadve/shared/llvm-gcc4.0-2.1/bin/',
31e5dd7070Spatrick    '/home/vadve/shared/llvm-2.1/Release/bin');
32e5dd7070Spatrick
33e5dd7070Spatrickmy $defaultsrc = "#include <stdio.h>\n#include <stdlib.h>\n\n" .
34e5dd7070Spatrick                 "int power(int X) {\n  if (X == 0) return 1;\n" .
35e5dd7070Spatrick                 "  return X*power(X-1);\n}\n\n" .
36e5dd7070Spatrick                 "int main(int argc, char **argv) {\n" .
37e5dd7070Spatrick                 "  printf(\"%d\\n\", power(atoi(argv[0])));\n}\n";
38e5dd7070Spatrick
39e5dd7070Spatricksub getname {
40e5dd7070Spatrick    my ($extension) = @_;
41e5dd7070Spatrick    for ( my $count = 0 ; ; $count++ ) {
42e5dd7070Spatrick        my $name =
43e5dd7070Spatrick          sprintf( "$ROOT/_%d_%d%s", $$, $count, $extension );
44e5dd7070Spatrick        if ( !-f $name ) { return $name; }
45e5dd7070Spatrick    }
46e5dd7070Spatrick}
47e5dd7070Spatrick
48e5dd7070Spatrickmy $c;
49e5dd7070Spatrick
50e5dd7070Spatricksub barf {
51e5dd7070Spatrick    print "<b>", @_, "</b>\n";
52e5dd7070Spatrick    print $c->end_html;
53e5dd7070Spatrick    system("rm -f $ROOT/locked");
54e5dd7070Spatrick    exit 1;
55e5dd7070Spatrick}
56e5dd7070Spatrick
57e5dd7070Spatricksub writeIntoFile {
58e5dd7070Spatrick    my $extension = shift @_;
59e5dd7070Spatrick    my $contents  = join "", @_;
60e5dd7070Spatrick    my $name      = getname($extension);
61e5dd7070Spatrick    local (*FILE);
62e5dd7070Spatrick    open( FILE, ">$name" ) or barf("Can't write to $name: $!");
63e5dd7070Spatrick    print FILE $contents;
64e5dd7070Spatrick    close FILE;
65e5dd7070Spatrick    return $name;
66e5dd7070Spatrick}
67e5dd7070Spatrick
68e5dd7070Spatricksub addlog {
69e5dd7070Spatrick    my ( $source, $pid, $result ) = @_;
70e5dd7070Spatrick    open( LOG, ">>$LOGFILE" );
71e5dd7070Spatrick    my $time       = scalar localtime;
72e5dd7070Spatrick    my $remotehost = $ENV{'REMOTE_ADDR'};
73e5dd7070Spatrick    print LOG "[$time] [$remotehost]: $pid\n";
74e5dd7070Spatrick    print LOG "<<<\n$source\n>>>\nResult is: <<<\n$result\n>>>\n";
75e5dd7070Spatrick    close LOG;
76e5dd7070Spatrick}
77e5dd7070Spatrick
78e5dd7070Spatricksub dumpFile {
79e5dd7070Spatrick    my ( $header, $file ) = @_;
80e5dd7070Spatrick    my $result;
81e5dd7070Spatrick    open( FILE, "$file" ) or barf("Can't read $file: $!");
82e5dd7070Spatrick    while (<FILE>) {
83e5dd7070Spatrick        $result .= $_;
84e5dd7070Spatrick    }
85e5dd7070Spatrick    close FILE;
86e5dd7070Spatrick    my $UnhilightedResult = $result;
87e5dd7070Spatrick    my $HtmlResult        =
88e5dd7070Spatrick      "<h3>$header</h3>\n<pre>\n" . $c->escapeHTML($result) . "\n</pre>\n";
89e5dd7070Spatrick    if (wantarray) {
90e5dd7070Spatrick        return ( $UnhilightedResult, $HtmlResult );
91e5dd7070Spatrick    }
92e5dd7070Spatrick    else {
93e5dd7070Spatrick        return $HtmlResult;
94e5dd7070Spatrick    }
95e5dd7070Spatrick}
96e5dd7070Spatrick
97e5dd7070Spatricksub syntaxHighlightLLVM {
98e5dd7070Spatrick  my ($input) = @_;
99e5dd7070Spatrick  $input =~ s@\b(void|i8|i1|i16|i32|i64|float|double|type|label|opaque)\b@<span class="llvm_type">$1</span>@g;
100e5dd7070Spatrick  $input =~ s@\b(add|sub|mul|div|rem|and|or|xor|setne|seteq|setlt|setgt|setle|setge|phi|tail|call|cast|to|shl|shr|vaarg|vanext|ret|br|switch|invoke|unwind|malloc|alloca|free|load|store|getelementptr|begin|end|true|false|declare|global|constant|const|internal|uninitialized|external|implementation|linkonce|weak|appending|null|to|except|not|target|endian|pointersize|big|little|volatile)\b@<span class="llvm_keyword">$1</span>@g;
101e5dd7070Spatrick
102e5dd7070Spatrick  # Add links to the FAQ.
103e5dd7070Spatrick  $input =~ s@(_ZNSt8ios_base4Init[DC]1Ev)@<a href="../docs/FAQ.html#iosinit">$1</a>@g;
104e5dd7070Spatrick  $input =~ s@\bundef\b@<a href="../docs/FAQ.html#undef">undef</a>@g;
105e5dd7070Spatrick  return $input;
106e5dd7070Spatrick}
107e5dd7070Spatrick
108e5dd7070Spatricksub mailto {
109e5dd7070Spatrick    my ( $recipient, $body ) = @_;
110e5dd7070Spatrick    my $msg =
111e5dd7070Spatrick      new Mail::Send( Subject => "LLVM Demo Page Run", To => $recipient );
112e5dd7070Spatrick    my $fh = $msg->open();
113e5dd7070Spatrick    print $fh $body;
114e5dd7070Spatrick    $fh->close();
115e5dd7070Spatrick}
116e5dd7070Spatrick
117e5dd7070Spatrick$c = new CGI;
118e5dd7070Spatrickprint $c->header;
119e5dd7070Spatrick
120e5dd7070Spatrickprint <<EOF;
121e5dd7070Spatrick<html>
122e5dd7070Spatrick<head>
123e5dd7070Spatrick  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
124e5dd7070Spatrick  <title>Try out LLVM in your browser!</title>
125e5dd7070Spatrick  <style>
126e5dd7070Spatrick    \@import url("syntax.css");
127e5dd7070Spatrick    \@import url("http://llvm.org/llvm.css");
128e5dd7070Spatrick  </style>
129e5dd7070Spatrick</head>
130e5dd7070Spatrick<body leftmargin="10" marginwidth="10">
131e5dd7070Spatrick
132e5dd7070Spatrick<div class="www_sectiontitle">
133e5dd7070Spatrick  Try out LLVM in your browser!
134e5dd7070Spatrick</div>
135e5dd7070Spatrick
136e5dd7070Spatrick<table border=0><tr><td>
137e5dd7070Spatrick<img align=right width=100 height=111 src="$LOGO_IMAGE_URL">
138e5dd7070Spatrick</td><td>
139e5dd7070SpatrickEOF
140e5dd7070Spatrick
141e5dd7070Spatrickif ( -f "$ROOT/locked" ) {
142e5dd7070Spatrick  my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$locktime) =
143e5dd7070Spatrick    stat("$ROOT/locked");
144e5dd7070Spatrick  my $currtime = time();
145e5dd7070Spatrick  if ($locktime + 60 > $currtime) {
146e5dd7070Spatrick    print "This page is already in use by someone else at this ";
147e5dd7070Spatrick    print "time, try reloading in a second or two.  Meow!</td></tr></table>'\n";
148e5dd7070Spatrick    exit 0;
149e5dd7070Spatrick  }
150e5dd7070Spatrick}
151e5dd7070Spatrick
152e5dd7070Spatricksystem("touch $ROOT/locked");
153e5dd7070Spatrick
154e5dd7070Spatrickprint <<END;
155e5dd7070SpatrickBitter Melon the cat says, paste a C/C++ program in the text box or upload
156e5dd7070Spatrickone from your computer, and you can see LLVM compile it, meow!!
157e5dd7070Spatrick</td></tr></table><p>
158e5dd7070SpatrickEND
159e5dd7070Spatrick
160e5dd7070Spatrickprint $c->start_multipart_form( 'POST', $FORM_URL );
161e5dd7070Spatrick
162e5dd7070Spatrickmy $source = $c->param('source');
163e5dd7070Spatrick
164e5dd7070Spatrick
165e5dd7070Spatrick# Start the user out with something valid if no code.
166e5dd7070Spatrick$source = $defaultsrc if (!defined($source));
167e5dd7070Spatrick
168e5dd7070Spatrickprint '<table border="0"><tr><td>';
169e5dd7070Spatrick
170e5dd7070Spatrickprint "Type your source code in below: (<a href='DemoInfo.html#hints'>hints and
171e5dd7070Spatrickadvice</a>)<br>\n";
172e5dd7070Spatrick
173e5dd7070Spatrickprint $c->textarea(
174e5dd7070Spatrick    -name    => "source",
175e5dd7070Spatrick    -rows    => 16,
176e5dd7070Spatrick    -columns => 60,
177e5dd7070Spatrick    -default => $source
178e5dd7070Spatrick), "<br>";
179e5dd7070Spatrick
180e5dd7070Spatrickprint "Or upload a file: ";
181e5dd7070Spatrickprint $c->filefield( -name => 'uploaded_file', -default => '' );
182e5dd7070Spatrick
183e5dd7070Spatrickprint "<p />\n";
184e5dd7070Spatrick
185e5dd7070Spatrick
186e5dd7070Spatrickprint '<p></td><td valign=top>';
187e5dd7070Spatrick
188e5dd7070Spatrickprint "<center><h3>General Options</h3></center>";
189e5dd7070Spatrick
190e5dd7070Spatrickprint "Source language: ",
191e5dd7070Spatrick  $c->radio_group(
192e5dd7070Spatrick    -name    => 'language',
193e5dd7070Spatrick    -values  => [ 'C', 'C++' ],
194e5dd7070Spatrick    -default => 'C'
195e5dd7070Spatrick  ), "<p>";
196e5dd7070Spatrick
197e5dd7070Spatrickprint $c->checkbox(
198e5dd7070Spatrick    -name  => 'linkopt',
199e5dd7070Spatrick    -label => 'Run link-time optimizer',
200e5dd7070Spatrick    -checked => 'checked'
201e5dd7070Spatrick  ),' <a href="DemoInfo.html#lto">?</a><br>';
202e5dd7070Spatrick
203e5dd7070Spatrickprint $c->checkbox(
204e5dd7070Spatrick    -name  => 'showstats',
205e5dd7070Spatrick    -label => 'Show detailed pass statistics'
206e5dd7070Spatrick  ), ' <a href="DemoInfo.html#stats">?</a><br>';
207e5dd7070Spatrick
208e5dd7070Spatrickprint $c->checkbox(
209e5dd7070Spatrick    -name  => 'cxxdemangle',
210e5dd7070Spatrick    -label => 'Demangle C++ names'
211e5dd7070Spatrick  ),' <a href="DemoInfo.html#demangle">?</a><p>';
212e5dd7070Spatrick
213e5dd7070Spatrick
214e5dd7070Spatrickprint "<center><h3>Output Options</h3></center>";
215e5dd7070Spatrick
216e5dd7070Spatrickprint $c->checkbox(
217e5dd7070Spatrick    -name => 'showbcanalysis',
218e5dd7070Spatrick    -label => 'Show detailed bytecode analysis'
219e5dd7070Spatrick  ),' <a href="DemoInfo.html#bcanalyzer">?</a><br>';
220e5dd7070Spatrick
221e5dd7070Spatrickprint $c->checkbox(
222e5dd7070Spatrick    -name => 'showllvm2cpp',
223e5dd7070Spatrick    -label => 'Show LLVM C++ API code'
224e5dd7070Spatrick  ), ' <a href="DemoInfo.html#llvm2cpp">?</a>';
225e5dd7070Spatrick
226e5dd7070Spatrickprint "</td></tr></table>";
227e5dd7070Spatrick
228e5dd7070Spatrickprint "<center>", $c->submit(-value=> 'Compile Source Code'),
229e5dd7070Spatrick      "</center>\n", $c->endform;
230e5dd7070Spatrick
231e5dd7070Spatrickprint "\n<p>If you have questions about the LLVM code generated by the
232e5dd7070Spatrickfront-end, please check the <a href='/docs/FAQ.html#cfe_code'>FAQ</a> and
233e5dd7070Spatrickthe demo page <a href='DemoInfo.html#hints'>hints section</a>.
234e5dd7070Spatrick</p>\n";
235e5dd7070Spatrick
236e5dd7070Spatrick$ENV{'PATH'} = ( join ( ':', @PREPENDPATHDIRS ) ) . ":" . $ENV{'PATH'};
237e5dd7070Spatrick
238e5dd7070Spatricksub sanitychecktools {
239e5dd7070Spatrick    my $sanitycheckfail = '';
240e5dd7070Spatrick
241e5dd7070Spatrick    # insert tool-specific sanity checks here
242e5dd7070Spatrick    $sanitycheckfail .= ' llvm-dis'
243e5dd7070Spatrick      if `llvm-dis --help 2>&1` !~ /ll disassembler/;
244e5dd7070Spatrick
245e5dd7070Spatrick    $sanitycheckfail .= ' llvm-gcc'
246e5dd7070Spatrick      if ( `llvm-gcc --version 2>&1` !~ /Free Software Foundation/ );
247e5dd7070Spatrick
248e5dd7070Spatrick    $sanitycheckfail .= ' llvm-ld'
249e5dd7070Spatrick      if `llvm-ld --help 2>&1` !~ /llvm linker/;
250e5dd7070Spatrick
251e5dd7070Spatrick    $sanitycheckfail .= ' llvm-bcanalyzer'
252e5dd7070Spatrick      if `llvm-bcanalyzer --help 2>&1` !~ /bcanalyzer/;
253e5dd7070Spatrick
254e5dd7070Spatrick    barf(
255e5dd7070Spatrick"<br/>The demo page is currently unavailable. [tools: ($sanitycheckfail ) failed sanity check]"
256e5dd7070Spatrick      )
257e5dd7070Spatrick      if $sanitycheckfail;
258e5dd7070Spatrick}
259e5dd7070Spatrick
260e5dd7070Spatricksanitychecktools();
261e5dd7070Spatrick
262e5dd7070Spatricksub try_run {
263e5dd7070Spatrick    my ( $program, $commandline, $outputFile ) = @_;
264e5dd7070Spatrick    my $retcode = 0;
265e5dd7070Spatrick
266e5dd7070Spatrick    eval {
267e5dd7070Spatrick        local $SIG{ALRM} = sub { die "timeout"; };
268e5dd7070Spatrick        alarm $TIMEOUTAMOUNT;
269e5dd7070Spatrick        $retcode = system($commandline);
270e5dd7070Spatrick        alarm 0;
271e5dd7070Spatrick    };
272e5dd7070Spatrick    if ( $@ and $@ =~ /timeout/ ) {
273e5dd7070Spatrick      barf("Program $program took too long, compile time limited for the web script, sorry!\n");
274e5dd7070Spatrick    }
275e5dd7070Spatrick    if ( -s $outputFile ) {
276e5dd7070Spatrick        print scalar dumpFile( "Output from $program", $outputFile );
277e5dd7070Spatrick    }
278e5dd7070Spatrick    #print "<p>Finished dumping command output.</p>\n";
279e5dd7070Spatrick    if ( WIFEXITED($retcode) && WEXITSTATUS($retcode) != 0 ) {
280e5dd7070Spatrick        barf(
281e5dd7070Spatrick"$program exited with an error. Please correct source and resubmit.<p>\n" .
282e5dd7070Spatrick"Please note that this form only allows fully formed and correct source" .
283e5dd7070Spatrick" files.  It will not compile fragments of code.<p>"
284e5dd7070Spatrick        );
285e5dd7070Spatrick    }
286e5dd7070Spatrick    if ( WIFSIGNALED($retcode) != 0 ) {
287e5dd7070Spatrick        my $sig = WTERMSIG($retcode);
288e5dd7070Spatrick        barf(
289e5dd7070Spatrick            "Ouch, $program caught signal $sig. Sorry, better luck next time!\n"
290e5dd7070Spatrick        );
291e5dd7070Spatrick    }
292e5dd7070Spatrick}
293e5dd7070Spatrick
294e5dd7070Spatrickmy %suffixes = (
295e5dd7070Spatrick    'Java'             => '.java',
296e5dd7070Spatrick    'JO99'             => '.jo9',
297e5dd7070Spatrick    'C'                => '.c',
298e5dd7070Spatrick    'C++'              => '.cc',
299e5dd7070Spatrick    'Stacker'          => '.st',
300e5dd7070Spatrick    'preprocessed C'   => '.i',
301e5dd7070Spatrick    'preprocessed C++' => '.ii'
302e5dd7070Spatrick);
303e5dd7070Spatrickmy %languages = (
304e5dd7070Spatrick    '.jo9'  => 'JO99',
305e5dd7070Spatrick    '.java' => 'Java',
306e5dd7070Spatrick    '.c'    => 'C',
307e5dd7070Spatrick    '.i'    => 'preprocessed C',
308e5dd7070Spatrick    '.ii'   => 'preprocessed C++',
309e5dd7070Spatrick    '.cc'   => 'C++',
310e5dd7070Spatrick    '.cpp'  => 'C++',
311e5dd7070Spatrick    '.st'   => 'Stacker'
312e5dd7070Spatrick);
313e5dd7070Spatrick
314e5dd7070Spatrickmy $uploaded_file_name = $c->param('uploaded_file');
315e5dd7070Spatrickif ($uploaded_file_name) {
316e5dd7070Spatrick    if ($source) {
317e5dd7070Spatrick        barf(
318e5dd7070Spatrick"You must choose between uploading a file and typing code in. You can't do both at the same time."
319e5dd7070Spatrick        );
320e5dd7070Spatrick    }
321e5dd7070Spatrick    $uploaded_file_name =~ s/^.*(\.[A-Za-z]+)$/$1/;
322e5dd7070Spatrick    my $language = $languages{$uploaded_file_name};
323e5dd7070Spatrick    $c->param( 'language', $language );
324e5dd7070Spatrick
325e5dd7070Spatrick    print "<p>Processing uploaded file. It looks like $language.</p>\n";
326e5dd7070Spatrick    my $fh = $c->upload('uploaded_file');
327e5dd7070Spatrick    if ( !$fh ) {
328e5dd7070Spatrick        barf( "Error uploading file: " . $c->cgi_error );
329e5dd7070Spatrick    }
330e5dd7070Spatrick    while (<$fh>) {
331e5dd7070Spatrick        $source .= $_;
332e5dd7070Spatrick    }
333e5dd7070Spatrick    close $fh;
334e5dd7070Spatrick}
335e5dd7070Spatrick
336e5dd7070Spatrickif ($c->param('source')) {
337e5dd7070Spatrick    print $c->hr;
338e5dd7070Spatrick    my $extension = $suffixes{ $c->param('language') };
339e5dd7070Spatrick    barf "Unknown language; can't compile\n" unless $extension;
340e5dd7070Spatrick
341e5dd7070Spatrick    # Add a newline to the source here to avoid a warning from gcc.
342e5dd7070Spatrick    $source .= "\n";
343e5dd7070Spatrick
344e5dd7070Spatrick    # Avoid security hole due to #including bad stuff.
345e5dd7070Spatrick    $source =~
346e5dd7070Spatricks@(\n)?#include.*[<"](.*\.\..*)[">].*\n@$1#error "invalid #include file $2 detected"\n@g;
347e5dd7070Spatrick
348e5dd7070Spatrick    my $inputFile = writeIntoFile( $extension, $source );
349e5dd7070Spatrick    my $pid       = $$;
350e5dd7070Spatrick
351e5dd7070Spatrick    my $bytecodeFile = getname(".bc");
352e5dd7070Spatrick    my $outputFile   = getname(".llvm-gcc.out");
353e5dd7070Spatrick    my $timerFile    = getname(".llvm-gcc.time");
354e5dd7070Spatrick
355e5dd7070Spatrick    my $stats = '';
356e5dd7070Spatrick    if ( $extension eq ".st" ) {
357e5dd7070Spatrick      $stats = "-stats -time-passes "
358e5dd7070Spatrick	if ( $c->param('showstats') );
359e5dd7070Spatrick      try_run( "llvm Stacker front-end (stkrc)",
360e5dd7070Spatrick        "stkrc $stats -o $bytecodeFile $inputFile > $outputFile 2>&1",
361e5dd7070Spatrick        $outputFile );
362e5dd7070Spatrick    } else {
363e5dd7070Spatrick      #$stats = "-Wa,--stats,--time-passes,--info-output-file=$timerFile"
364e5dd7070Spatrick      $stats = "-ftime-report"
365e5dd7070Spatrick	if ( $c->param('showstats') );
366e5dd7070Spatrick      try_run( "llvm C/C++ front-end (llvm-gcc)",
367e5dd7070Spatrick	"llvm-gcc -emit-llvm -W -Wall -O2 $stats -o $bytecodeFile -c $inputFile > $outputFile 2>&1",
368e5dd7070Spatrick        $outputFile );
369e5dd7070Spatrick    }
370e5dd7070Spatrick
371e5dd7070Spatrick    if ( $c->param('showstats') && -s $timerFile ) {
372e5dd7070Spatrick        my ( $UnhilightedResult, $HtmlResult ) =
373e5dd7070Spatrick          dumpFile( "Statistics for front-end compilation", $timerFile );
374e5dd7070Spatrick        print "$HtmlResult\n";
375e5dd7070Spatrick    }
376e5dd7070Spatrick
377e5dd7070Spatrick    if ( $c->param('linkopt') ) {
378e5dd7070Spatrick        my $stats      = '';
379e5dd7070Spatrick        my $outputFile = getname(".gccld.out");
380e5dd7070Spatrick        my $timerFile  = getname(".gccld.time");
381e5dd7070Spatrick        $stats = "--stats --time-passes --info-output-file=$timerFile"
382e5dd7070Spatrick          if ( $c->param('showstats') );
383e5dd7070Spatrick        my $tmpFile = getname(".bc");
384e5dd7070Spatrick        try_run(
385e5dd7070Spatrick            "optimizing linker (llvm-ld)",
386e5dd7070Spatrick"llvm-ld $stats -o=$tmpFile $bytecodeFile > $outputFile 2>&1",
387e5dd7070Spatrick            $outputFile
388e5dd7070Spatrick        );
389e5dd7070Spatrick        system("mv $tmpFile.bc $bytecodeFile");
390e5dd7070Spatrick        system("rm $tmpFile");
391e5dd7070Spatrick
392e5dd7070Spatrick        if ( $c->param('showstats') && -s $timerFile ) {
393e5dd7070Spatrick            my ( $UnhilightedResult, $HtmlResult ) =
394e5dd7070Spatrick              dumpFile( "Statistics for optimizing linker", $timerFile );
395e5dd7070Spatrick            print "$HtmlResult\n";
396e5dd7070Spatrick        }
397e5dd7070Spatrick    }
398e5dd7070Spatrick
399e5dd7070Spatrick    print " Bytecode size is ", -s $bytecodeFile, " bytes.\n";
400e5dd7070Spatrick
401e5dd7070Spatrick    my $disassemblyFile = getname(".ll");
402e5dd7070Spatrick    try_run( "llvm-dis",
403e5dd7070Spatrick        "llvm-dis -o=$disassemblyFile $bytecodeFile > $outputFile 2>&1",
404e5dd7070Spatrick        $outputFile );
405e5dd7070Spatrick
406e5dd7070Spatrick    if ( $c->param('cxxdemangle') ) {
407e5dd7070Spatrick        print " Demangling disassembler output.\n";
408e5dd7070Spatrick        my $tmpFile = getname(".ll");
409e5dd7070Spatrick        system("c++filt < $disassemblyFile > $tmpFile 2>&1");
410e5dd7070Spatrick        system("mv $tmpFile $disassemblyFile");
411e5dd7070Spatrick    }
412e5dd7070Spatrick
413e5dd7070Spatrick    my ( $UnhilightedResult, $HtmlResult );
414e5dd7070Spatrick    if ( -s $disassemblyFile ) {
415e5dd7070Spatrick        ( $UnhilightedResult, $HtmlResult ) =
416e5dd7070Spatrick          dumpFile( "Output from LLVM disassembler", $disassemblyFile );
417e5dd7070Spatrick        print syntaxHighlightLLVM($HtmlResult);
418e5dd7070Spatrick    }
419e5dd7070Spatrick    else {
420e5dd7070Spatrick        print "<p>Hmm, that's weird, llvm-dis didn't produce any output.</p>\n";
421e5dd7070Spatrick    }
422e5dd7070Spatrick
423e5dd7070Spatrick    if ( $c->param('showbcanalysis') ) {
424e5dd7070Spatrick      my $analFile = getname(".bca");
425e5dd7070Spatrick      try_run( "llvm-bcanalyzer", "llvm-bcanalyzer $bytecodeFile > $analFile 2>&1",
426e5dd7070Spatrick        $analFile);
427e5dd7070Spatrick    }
428e5dd7070Spatrick    if ($c->param('showllvm2cpp') ) {
429e5dd7070Spatrick      my $l2cppFile = getname(".l2cpp");
430e5dd7070Spatrick      try_run("llvm2cpp","llvm2cpp $bytecodeFile -o $l2cppFile 2>&1",
431e5dd7070Spatrick        $l2cppFile);
432e5dd7070Spatrick    }
433e5dd7070Spatrick
434e5dd7070Spatrick    # Get the source presented by the user to CGI, convert newline sequences to simple \n.
435e5dd7070Spatrick    my $actualsrc = $c->param('source');
436e5dd7070Spatrick    $actualsrc =~ s/\015\012/\n/go;
437e5dd7070Spatrick    # Don't log this or mail it if it is the default code.
438e5dd7070Spatrick    if ($actualsrc ne $defaultsrc) {
439e5dd7070Spatrick    addlog( $source, $pid, $UnhilightedResult );
440e5dd7070Spatrick
441e5dd7070Spatrick    my ( $ip, $host, $lg, $lines );
442e5dd7070Spatrick    chomp( $lines = `wc -l < $inputFile` );
443e5dd7070Spatrick    $lg = $c->param('language');
444e5dd7070Spatrick    $ip = $c->remote_addr();
445e5dd7070Spatrick    chomp( $host = `host $ip` ) if $ip;
446e5dd7070Spatrick    mailto( $MAILADDR,
447e5dd7070Spatrick        "--- Query: ---\nFrom: ($ip) $host\nInput: $lines lines of $lg\n"
448e5dd7070Spatrick          . "C++ demangle = "
449e5dd7070Spatrick          . ( $c->param('cxxdemangle') ? 1 : 0 )
450e5dd7070Spatrick          . ", Link opt = "
451e5dd7070Spatrick          . ( $c->param('linkopt') ? 1 : 0 ) . "\n\n"
452e5dd7070Spatrick          . ", Show stats = "
453e5dd7070Spatrick          . ( $c->param('showstats') ? 1 : 0 ) . "\n\n"
454e5dd7070Spatrick          . "--- Source: ---\n$source\n"
455e5dd7070Spatrick          . "--- Result: ---\n$UnhilightedResult\n" );
456e5dd7070Spatrick    }
457e5dd7070Spatrick    unlink( $inputFile, $bytecodeFile, $outputFile, $disassemblyFile );
458e5dd7070Spatrick}
459e5dd7070Spatrick
460e5dd7070Spatrickprint $c->hr, "<address>$CONTACT_ADDRESS</address>", $c->end_html;
461e5dd7070Spatricksystem("rm $ROOT/locked");
462e5dd7070Spatrickexit 0;
463