TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.7 KiB
145 lines
4.7 KiB
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use native_types;
|
|
|
|
final class WasiDemo
|
|
{
|
|
public static function report(array $arguments, string $greeting, string $stdin): array
|
|
{
|
|
if ($greeting === '') {
|
|
$greeting = 'Hello from the WASI environment';
|
|
}
|
|
|
|
$argv = array_merge(['typephp.wasm'], $arguments);
|
|
|
|
return [
|
|
'runtime' => [
|
|
'php' => phpversion(),
|
|
'platform' => php_uname(),
|
|
'integerBits' => PHP_INT_SIZE * 8,
|
|
'extensions' => get_loaded_extensions(),
|
|
],
|
|
'clock' => [
|
|
'timestamp' => time(),
|
|
'iso8601' => date('Y-m-d H:i:s T'),
|
|
'microtime' => microtime(true),
|
|
],
|
|
'random' => [
|
|
'integer' => random_int(100000, 999999),
|
|
'token' => bin2hex(random_bytes(8)),
|
|
],
|
|
'input' => [
|
|
'argc' => count($argv),
|
|
'argv' => $argv,
|
|
'greeting' => $greeting,
|
|
'stdin' => trim($stdin),
|
|
],
|
|
'filesystem' => self::filesystemReport(),
|
|
'http' => self::httpReport(),
|
|
'precision' => self::precisionReport(),
|
|
'capabilities' => [
|
|
'supported' => ['arguments', 'environment', 'stdin/stdout/stderr', 'clock', 'random', 'filesystem', 'HTTP GET'],
|
|
'disabled' => ['raw sockets', 'process', 'signals', 'shell', 'Fiber', 'Generator'],
|
|
],
|
|
];
|
|
}
|
|
|
|
public static function extensionInfo(string $name): array
|
|
{
|
|
if (!extension_loaded($name)) {
|
|
throw new InvalidArgumentException("PHP extension '{$name}' is not loaded");
|
|
}
|
|
|
|
$extension = new ReflectionExtension($name);
|
|
$functions = get_extension_funcs($name);
|
|
if ($functions === false) {
|
|
$functions = [];
|
|
}
|
|
|
|
return [
|
|
'name' => $extension->getName(),
|
|
'version' => $extension->getVersion() ?: 'built-in',
|
|
'persistent' => $extension->isPersistent(),
|
|
'temporary' => $extension->isTemporary(),
|
|
'dependencies' => $extension->getDependencies(),
|
|
'iniEntries' => $extension->getINIEntries(),
|
|
'constants' => array_keys($extension->getConstants()),
|
|
'functions' => array_values($functions),
|
|
'classes' => $extension->getClassNames(),
|
|
];
|
|
}
|
|
|
|
private static function httpReport(): array
|
|
{
|
|
$url = getenv('TYPEPHP_FETCH_URL');
|
|
if ($url === false || $url === '') {
|
|
return ['ok' => false, 'url' => '', 'bytes' => 0, 'preview' => 'No URL configured'];
|
|
}
|
|
|
|
$body = file_get_contents($url);
|
|
if ($body === false) {
|
|
return ['ok' => false, 'url' => $url, 'bytes' => 0, 'preview' => 'Request failed'];
|
|
}
|
|
|
|
return [
|
|
'ok' => true,
|
|
'url' => $url,
|
|
'bytes' => strlen($body),
|
|
'preview' => trim(substr($body, 0, 80)),
|
|
];
|
|
}
|
|
|
|
private static function filesystemReport(): array
|
|
{
|
|
$directory = '/workspace';
|
|
if (!is_dir($directory)) {
|
|
mkdir($directory);
|
|
}
|
|
|
|
$counterFile = $directory . '/run-count.txt';
|
|
$counter = 0;
|
|
if (file_exists($counterFile)) {
|
|
$counter = (int) trim((string) file_get_contents($counterFile));
|
|
}
|
|
$counter++;
|
|
file_put_contents($counterFile, (string) $counter);
|
|
|
|
$messageFile = $directory . '/hello.txt';
|
|
$message = 'TypePHP wrote this file during browser run #' . $counter;
|
|
file_put_contents($messageFile, $message);
|
|
|
|
$files = scandir($directory);
|
|
if ($files === false) {
|
|
$files = [];
|
|
}
|
|
$visibleFiles = array_values(array_diff($files, ['.', '..']));
|
|
|
|
return [
|
|
'run' => $counter,
|
|
'readback' => (string) file_get_contents($messageFile),
|
|
'files' => $visibleFiles,
|
|
];
|
|
}
|
|
|
|
private static function precisionReport(): array
|
|
{
|
|
$big = std::bigInt('123456789012345678901234567890');
|
|
$bigResult = ($big * std::bigInt(1000000) + std::bigInt(42))->toString();
|
|
|
|
$price = std::decimal('199.95');
|
|
$taxRate = std::decimal('0.0825');
|
|
$decimalResult = ($price * (std::decimal(1) + $taxRate))->toString();
|
|
|
|
$pi = std::bigFloat('3.141592653589793238462643383279502884197');
|
|
$radius = std::bigFloat(12);
|
|
$bigFloatResult = ($pi * $radius * $radius)->toString();
|
|
|
|
return [
|
|
'bigint' => $bigResult,
|
|
'decimal' => $decimalResult,
|
|
'bigfloat' => $bigFloatResult,
|
|
];
|
|
}
|
|
}
|
|
|