parent
1d6681ade3
commit
33d8693776
1 changed files with 0 additions and 441 deletions
@ -1,441 +0,0 @@ |
|||||||
<?php |
|
||||||
/** |
|
||||||
* This file is part of Swoole-Compiler(AOT). |
|
||||||
* |
|
||||||
* @link https://www.swoole.com/ |
|
||||||
* @contact service@swoole.com |
|
||||||
*/ |
|
||||||
|
|
||||||
namespace PhpAot\Php; |
|
||||||
|
|
||||||
use PhpParser\PrettyPrinter\Standard; |
|
||||||
|
|
||||||
class Encryptor extends \PhpAot\Core\Translator |
|
||||||
{ |
|
||||||
protected array $stmts; |
|
||||||
protected string $phpxDir = '~/workspace/phpx'; |
|
||||||
protected string $lang = 'PHP'; |
|
||||||
protected array $typeMap = []; |
|
||||||
protected array $headers = [ |
|
||||||
'phpx.h', |
|
||||||
]; |
|
||||||
protected array $encodeMap; |
|
||||||
protected array $decodeMap; |
|
||||||
protected array $constants; |
|
||||||
|
|
||||||
public function __construct(array $stmts) |
|
||||||
{ |
|
||||||
$confDir = __DIR__ . '/../../config'; |
|
||||||
$this->stmts = $stmts; |
|
||||||
$this->encodeMap = require $confDir . '/functions.php'; |
|
||||||
$this->decodeMap = array_flip($this->encodeMap); |
|
||||||
$this->constants = require $confDir . '/constants.php'; |
|
||||||
} |
|
||||||
|
|
||||||
public function parseHeaders(): string |
|
||||||
{ |
|
||||||
$lines = []; |
|
||||||
foreach ($this->headers as $header) { |
|
||||||
$lines[] = '#include <' . $header . '>'; |
|
||||||
} |
|
||||||
|
|
||||||
return implode(PHP_EOL, $lines) . PHP_EOL . PHP_EOL; |
|
||||||
} |
|
||||||
|
|
||||||
public function setPhpxDir($dir): void |
|
||||||
{ |
|
||||||
$this->phpxDir = $dir; |
|
||||||
} |
|
||||||
|
|
||||||
public function convert() |
|
||||||
{ |
|
||||||
$this->parseStmts($this->stmts); |
|
||||||
$prettyPrinter = new Standard(); |
|
||||||
|
|
||||||
return $prettyPrinter->prettyPrintFile($this->stmts); |
|
||||||
} |
|
||||||
|
|
||||||
public function save($code, $file) |
|
||||||
{ |
|
||||||
file_put_contents($file, $code); |
|
||||||
} |
|
||||||
|
|
||||||
public function getLine($node): int |
|
||||||
{ |
|
||||||
return $node->getLine(); |
|
||||||
} |
|
||||||
|
|
||||||
public function getType($node): string |
|
||||||
{ |
|
||||||
return $node->getType(); |
|
||||||
} |
|
||||||
|
|
||||||
public function compileFile($file) |
|
||||||
{ |
|
||||||
$cmd = 'g++ -c ' . $file . ' -o ' . $file . '.o ' . $this->parseIncludes() . $this->parseLdflags() . $this->parseLibs(); |
|
||||||
echo $cmd . PHP_EOL; |
|
||||||
shell_exec($cmd); |
|
||||||
} |
|
||||||
|
|
||||||
protected function parseIdentifier($node) |
|
||||||
{ |
|
||||||
$type = $node->getType(); |
|
||||||
switch ($type) { |
|
||||||
case 'Identifier': |
|
||||||
case 'Expr_Variable': |
|
||||||
return $node->name; |
|
||||||
case 'Scalar_Int': |
|
||||||
case 'Scalar_Float': |
|
||||||
return $node->value; |
|
||||||
case 'Scalar_String': |
|
||||||
return '"' . $node->value . '"'; |
|
||||||
case 'Expr_Array': |
|
||||||
return $this->parseArray($node); |
|
||||||
case 'Expr_FuncCall': |
|
||||||
$this->parseFuncCall($node->name); |
|
||||||
break; |
|
||||||
case 'Expr_Ternary': |
|
||||||
case 'Expr_ArrayDimFetch': |
|
||||||
case 'Expr_New': |
|
||||||
case 'Expr_ClassConstFetch': |
|
||||||
case 'Expr_BinaryOp_Identical': |
|
||||||
case 'Expr_BinaryOp_Mul': |
|
||||||
case 'Expr_BinaryOp_Concat': |
|
||||||
case 'Expr_BinaryOp_Plus': |
|
||||||
case 'Expr_Isset': |
|
||||||
case 'Stmt_Switch': |
|
||||||
break; |
|
||||||
default: |
|
||||||
abort($node); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private function parseFunctionDef($v) |
|
||||||
{ |
|
||||||
if ($v->name) { |
|
||||||
$name = $this->parseIdentifier($v->name); |
|
||||||
} else { |
|
||||||
$name = ''; |
|
||||||
} |
|
||||||
|
|
||||||
if ($v->returnType) { |
|
||||||
$return = $this->parseIdentifier($v->returnType); |
|
||||||
} else { |
|
||||||
$return = ''; |
|
||||||
} |
|
||||||
|
|
||||||
if ($v->params) { |
|
||||||
$params = $this->parseParams($v->params); |
|
||||||
} else { |
|
||||||
$params = ''; |
|
||||||
} |
|
||||||
|
|
||||||
$code = $return . ' ' . $name . '(' . $params . ') {' . PHP_EOL; |
|
||||||
$this->indentLevel++; |
|
||||||
$stmts = $this->parseStmts($v->stmts); |
|
||||||
$this->indentLevel--; |
|
||||||
$code .= $stmts; |
|
||||||
$code .= '}'; |
|
||||||
|
|
||||||
return $code; |
|
||||||
} |
|
||||||
|
|
||||||
private function parseParams($params) |
|
||||||
{ |
|
||||||
$list = []; |
|
||||||
foreach ($params as $param) { |
|
||||||
$type = $param->type ? $this->parseType($param->type) : ''; |
|
||||||
$name = $param->var ? $this->parseIdentifier($param->var) : ''; |
|
||||||
$list[] = $type . ' ' . $name; |
|
||||||
$this->typeMap[$name] = $type; |
|
||||||
} |
|
||||||
|
|
||||||
return implode(', ', $list); |
|
||||||
} |
|
||||||
|
|
||||||
private function parseStmts(array $stmts) |
|
||||||
{ |
|
||||||
$lines = []; |
|
||||||
foreach ($stmts as $v) { |
|
||||||
$class = $v->getType(); |
|
||||||
switch ($class) { |
|
||||||
case 'Stmt_Function': |
|
||||||
$lines[] = $this->parseFunctionDef($v); |
|
||||||
break; |
|
||||||
case 'Stmt_Expression': |
|
||||||
$lines[] = $this->parseExpr($v->expr) . ';'; |
|
||||||
break; |
|
||||||
case 'Stmt_Echo': |
|
||||||
$lines[] = $this->parseEcho($v) . ';'; |
|
||||||
break; |
|
||||||
case 'Stmt_Return': |
|
||||||
$this->parseReturn($v); |
|
||||||
break; |
|
||||||
case 'Expr_Include': |
|
||||||
$this->parseInclude($v); |
|
||||||
break; |
|
||||||
case 'Stmt_If': |
|
||||||
$this->parseIf($v); |
|
||||||
break; |
|
||||||
case 'Stmt_Global': |
|
||||||
case 'Stmt_InlineHTML': |
|
||||||
case 'Stmt_Nop': |
|
||||||
case 'Stmt_Switch': |
|
||||||
break; |
|
||||||
default: |
|
||||||
abort($v); |
|
||||||
} |
|
||||||
} |
|
||||||
$code = ''; |
|
||||||
foreach ($lines as $line) { |
|
||||||
$code .= $this->getIndent() . $line . PHP_EOL; |
|
||||||
} |
|
||||||
|
|
||||||
return $code; |
|
||||||
} |
|
||||||
|
|
||||||
private function parseExpr(mixed $expr) |
|
||||||
{ |
|
||||||
$type = $expr->getType(); |
|
||||||
switch ($type) { |
|
||||||
case 'Expr_Assign': |
|
||||||
return $this->parseAssign($expr); |
|
||||||
case 'Expr_BinaryOp_Plus': |
|
||||||
return $this->parseBinaryOpPlus($expr); |
|
||||||
case 'Expr_BinaryOp_Mul': |
|
||||||
return $this->parseBinaryOpMul($expr); |
|
||||||
case 'Expr_BinaryOp_Concat': |
|
||||||
return $this->parseBinaryOpConcat($expr); |
|
||||||
case 'Expr_FuncCall': |
|
||||||
return $this->parseFuncCall($expr->name); |
|
||||||
case 'Expr_Include': |
|
||||||
return $this->parseInclude($expr->expr); |
|
||||||
case 'Expr_BinaryOp_BooleanAnd': |
|
||||||
return $this->parseBinaryOpBooleanAnd($expr); |
|
||||||
case 'Expr_MethodCall': |
|
||||||
case 'Expr_Isset': |
|
||||||
case 'Expr_Variable': |
|
||||||
case 'Expr_BooleanNot': |
|
||||||
case 'Scalar_String': |
|
||||||
case 'Scalar_MagicConst_File': |
|
||||||
case 'Scalar_MagicConst_Dir': |
|
||||||
break; |
|
||||||
case 'Expr_BinaryOp_NotIdentical': |
|
||||||
$this->parseBinaryOpNotIdentical($expr); |
|
||||||
break; |
|
||||||
case 'Expr_BinaryOp_Identical': |
|
||||||
$this->parseBinaryOpIdentical($expr); |
|
||||||
break; |
|
||||||
case 'Expr_ConstFetch': |
|
||||||
$this->parseConstFetch($expr); |
|
||||||
break; |
|
||||||
default: |
|
||||||
abort($expr); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private function parseAssign(mixed $v) |
|
||||||
{ |
|
||||||
$this->parseExpr($v->var); |
|
||||||
$this->parseExpr($v->expr); |
|
||||||
} |
|
||||||
|
|
||||||
private function parseEcho(mixed $v) |
|
||||||
{ |
|
||||||
return 'php::echo(' . $this->parseExprs($v->exprs) . ')'; |
|
||||||
} |
|
||||||
|
|
||||||
private function parseExprs($exprs) |
|
||||||
{ |
|
||||||
$code = ''; |
|
||||||
foreach ($exprs as $expr) { |
|
||||||
$code .= $this->parseExpr($expr); |
|
||||||
} |
|
||||||
|
|
||||||
return $code; |
|
||||||
} |
|
||||||
|
|
||||||
private function parseBinaryOpPlus(mixed $expr) |
|
||||||
{ |
|
||||||
$left = $this->parseIdentifier($expr->left); |
|
||||||
$right = $this->parseIdentifier($expr->right); |
|
||||||
|
|
||||||
return $left . ' + ' . $right; |
|
||||||
} |
|
||||||
|
|
||||||
private function parseReturn(mixed $v) |
|
||||||
{ |
|
||||||
return 'return ' . $this->parseExpr($v->expr); |
|
||||||
} |
|
||||||
|
|
||||||
private function parseBinaryOpMul(mixed $expr) |
|
||||||
{ |
|
||||||
$left = $this->parseIdentifier($expr->left); |
|
||||||
$right = $this->parseIdentifier($expr->right); |
|
||||||
|
|
||||||
return $left . ' * ' . $right; |
|
||||||
} |
|
||||||
|
|
||||||
private function detectType($var, $expr) |
|
||||||
{ |
|
||||||
$exprType = $expr->getType(); |
|
||||||
switch ($exprType) { |
|
||||||
case 'Scalar_Int': |
|
||||||
return 'zend_long'; |
|
||||||
case 'Scalar_Float': |
|
||||||
return 'double'; |
|
||||||
case 'Scalar_String': |
|
||||||
return 'php::Variant'; |
|
||||||
case 'Expr_Array': |
|
||||||
return 'php::Array'; |
|
||||||
default: |
|
||||||
abort($expr); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private function parseArray($node) |
|
||||||
{ |
|
||||||
$items = $node->items; |
|
||||||
$list = []; |
|
||||||
$this->indentLevel++; |
|
||||||
foreach ($items as $item) { |
|
||||||
if ($item->key) { |
|
||||||
$list[] = $this->getIndent() . '{ php::Variant(' . $this->parseIdentifier($item->key) . '), php::Variant(' . $this->parseIdentifier($item->value) . ') }'; |
|
||||||
} else { |
|
||||||
$list[] = $this->getIndent() . 'php::Variant(' . $this->parseIdentifier($item->value) . ')'; |
|
||||||
} |
|
||||||
} |
|
||||||
$this->indentLevel--; |
|
||||||
|
|
||||||
return '{' . PHP_EOL . |
|
||||||
implode(', ' . PHP_EOL, $list) . PHP_EOL . |
|
||||||
$this->getIndent() . |
|
||||||
'}'; |
|
||||||
} |
|
||||||
|
|
||||||
private function parseType($type) |
|
||||||
{ |
|
||||||
$name = $type->name; |
|
||||||
switch ($name) { |
|
||||||
case 'int': |
|
||||||
return 'zend_long'; |
|
||||||
case 'array': |
|
||||||
return 'php::Array'; |
|
||||||
case 'float': |
|
||||||
return 'double'; |
|
||||||
default: |
|
||||||
abort($type); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private function parseIncludes() |
|
||||||
{ |
|
||||||
$list = [ |
|
||||||
$this->phpxDir . '/include', |
|
||||||
]; |
|
||||||
$out = '$(php-config --includes) '; |
|
||||||
foreach ($list as $li) { |
|
||||||
$out .= '-I ' . $li . ' '; |
|
||||||
} |
|
||||||
|
|
||||||
return $out; |
|
||||||
} |
|
||||||
|
|
||||||
private function parseLdflags() |
|
||||||
{ |
|
||||||
$list = [ |
|
||||||
'$(php-config --prefix)/lib', |
|
||||||
$this->phpxDir . '/lib', |
|
||||||
]; |
|
||||||
$out = ''; |
|
||||||
foreach ($list as $li) { |
|
||||||
$out .= '-L ' . $li . ' '; |
|
||||||
} |
|
||||||
|
|
||||||
return $out; |
|
||||||
} |
|
||||||
|
|
||||||
private function parseLibs() |
|
||||||
{ |
|
||||||
$list = [ |
|
||||||
'phpx', |
|
||||||
'php', |
|
||||||
]; |
|
||||||
$out = ''; |
|
||||||
foreach ($list as $li) { |
|
||||||
$out .= '-l' . $li . ' '; |
|
||||||
} |
|
||||||
|
|
||||||
return $out; |
|
||||||
} |
|
||||||
|
|
||||||
private function parseBinaryOpConcat(mixed $expr) |
|
||||||
{ |
|
||||||
$left = $this->parseIdentifier($expr->left); |
|
||||||
$right = $this->parseIdentifier($expr->right); |
|
||||||
|
|
||||||
return $left . ' + ' . $right; |
|
||||||
} |
|
||||||
|
|
||||||
private function parseFuncCall($expr) |
|
||||||
{ |
|
||||||
if (isset($this->decodeMap[$expr->name])) { |
|
||||||
$expr->name = $this->decodeMap[$expr->name]; |
|
||||||
} |
|
||||||
|
|
||||||
return $expr; |
|
||||||
} |
|
||||||
|
|
||||||
private function parseInclude(mixed $v) |
|
||||||
{ |
|
||||||
return ''; |
|
||||||
} |
|
||||||
|
|
||||||
private function parseIf(mixed $v) |
|
||||||
{ |
|
||||||
$cond = $v->cond; |
|
||||||
$this->parseCond($cond); |
|
||||||
} |
|
||||||
|
|
||||||
private function parseCond(mixed $cond) |
|
||||||
{ |
|
||||||
return $this->parseExpr($cond); |
|
||||||
} |
|
||||||
|
|
||||||
private function parseBinaryOpBooleanAnd(mixed $expr) |
|
||||||
{ |
|
||||||
if (!empty($expr->left)) { |
|
||||||
$this->parseExpr($expr->left); |
|
||||||
} |
|
||||||
if (!empty($expr->right)) { |
|
||||||
$this->parseExpr($expr->right); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private function parseBinaryOpNotIdentical(mixed $expr) |
|
||||||
{ |
|
||||||
if (!empty($expr->left)) { |
|
||||||
$this->parseExpr($expr->left); |
|
||||||
} |
|
||||||
if (!empty($expr->right)) { |
|
||||||
$this->parseExpr($expr->right); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private function parseBinaryOpIdentical(mixed $expr) |
|
||||||
{ |
|
||||||
if (!empty($expr->left)) { |
|
||||||
$this->parseExpr($expr->left); |
|
||||||
} |
|
||||||
if (!empty($expr->right)) { |
|
||||||
$this->parseExpr($expr->right); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private function parseConstFetch(mixed $expr) |
|
||||||
{ |
|
||||||
$name = $expr->name->name; |
|
||||||
if (isset($this->constants[$name])) { |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
Loading…
Reference in new issue