Created
January 3, 2016 15:59
-
-
Save Garciat/0a6c70a6ccf2d5df4e57 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function compileCPP(string $sourcePath, string $binaryPath): bool { | |
$descriptorspec = [ | |
0 => ['pipe', 'r'], | |
1 => ['pipe', 'w'], | |
2 => ['pipe', 'w'] | |
]; | |
$cwd = '/tmp'; | |
$process = proc_open("em++ $sourcePath -o $binaryPath", $descriptorspec, $pipes, $cwd); | |
if (is_resource($process)) { | |
fclose($pipes[0]); | |
echo stream_get_contents($pipes[1]); | |
fclose($pipes[1]); | |
echo stream_get_contents($pipes[2]); | |
fclose($pipes[2]); | |
$return_value = proc_close($process); | |
return $return_value === 0; | |
} | |
return false; | |
} | |
function runJS(string $sourcePath, string $input = null) { | |
$descriptorspec = [ | |
0 => ['pipe', 'r'], | |
1 => ['pipe', 'w'], | |
2 => ['pipe', 'w'] | |
]; | |
$cwd = '/tmp'; | |
$process = proc_open("node $sourcePath", $descriptorspec, $pipes, $cwd); | |
if (is_resource($process)) { | |
if ($input) { | |
fwrite($pipes[0], $input); | |
} | |
fclose($pipes[0]); | |
$proc_out = stream_get_contents($pipes[1]); | |
fclose($pipes[1]); | |
$proc_err = stream_get_contents($pipes[2]); | |
fclose($pipes[2]); | |
$exit_status = proc_close($process); | |
return ['exit' => $exit_status, 'out' => $proc_out, 'err' => $proc_err]; | |
} | |
return null; | |
} | |
class CompilationException extends Exception { } | |
class ExecutionException extends Exception { } | |
class CPlusPlusSource { | |
private $sourcePath; | |
function __construct($sourcePath) { | |
$this->sourcePath = $sourcePath; | |
} | |
function compile(): CPlusPlusBinary { | |
$binaryPath = tempnam(sys_get_temp_dir(), 'emcc_') . '.js'; | |
$r = compileCPP($this->sourcePath, $binaryPath); | |
if (!$r) { | |
throw new CompilationException(); | |
} | |
$binary = new CPlusPlusBinary($binaryPath); | |
return $binary; | |
} | |
} | |
class CPlusPlusBinary { | |
private $binaryPath; | |
function __construct($binaryPath) { | |
$this->binaryPath = $binaryPath; | |
} | |
function execute(string $input = null): ExecutionResult { | |
$r = runJS($this->binaryPath, $input); | |
if ($r === null) { | |
throw new ExecutionException(); | |
} | |
$result = new ExecutionResult($r['exit'], $r['out'], $r['err']); | |
return $result; | |
} | |
} | |
class ExecutionResult { | |
private $exitStatus; | |
private $processOut; | |
private $processErr; | |
function __construct($exitStatus, $processOut, $processErr) { | |
$this->exitStatus = $exitStatus; | |
$this->processOut = $processOut; | |
$this->processErr = $processErr; | |
} | |
function getExitStatus(): int { | |
return $this->exitStatus; | |
} | |
function getOutput(): string { | |
return $this->processOut; | |
} | |
function getError(): string { | |
return $this->processErr; | |
} | |
} | |
$src = new CPlusPlusSource('/home/garciat/Desktop/hello.cpp'); | |
echo $src->compile()->execute('123')->getOutput(), PHP_EOL; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment