Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2280 - Add string support in php.ini #2303

Merged
merged 6 commits into from
Oct 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ The format based on [Keep a Changelog](http://keepachangelog.com)
and this project adheres to [Semantic Versioning](http://semver.org).

## [Unreleased]
# Added
- Added support for `string` type in php.ini [#2280](https://github.com/zephir-lang/zephir/issues/2280)

### Fixed
- Fixed multiple return types in stubs [#2283](https://github.com/zephir-lang/zephir/issues/2283)
- Fixed `bool` return type in stubs [#2272](https://github.com/zephir-lang/zephir/issues/2272)
Expand Down
6 changes: 3 additions & 3 deletions Library/Backends/ZendEngine2/Backend.php
Original file line number Diff line number Diff line change
Expand Up @@ -1102,12 +1102,12 @@ protected function assignHelper(
return $output;
}

protected function returnHelper($macro, $value, CompilationContext $context, $useCodePrinter, $doCopy = null)
protected function returnHelper(string $macro, $value, CompilationContext $context, $useCodePrinter, $doCopy = null): string
{
if ($value instanceof Variable) {
$value = $value->getName();
} else {
$value = 'RETURN_MM_STRING' == $macro ? '"'.$value.'"' : $value;
} elseif ($macro === 'RETURN_MM_STRING' && !preg_match('/^ZEPHIR_GLOBAL/', $value)) {
$value = '"'.$value.'"';
}

$copyStr = '';
Expand Down
2 changes: 1 addition & 1 deletion Library/Backends/ZendEngine3/Backend.php
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ public function assignZval(Variable $variable, $code, CompilationContext $contex

public function returnString($value, CompilationContext $context, $useCodePrinter = true, $doCopy = true)
{
return $this->returnHelper('RETURN_MM_STRING', $value, $context, $useCodePrinter, null);
return $this->returnHelper('RETURN_MM_STRING', $value, $context, $useCodePrinter);
}

public function createClosure(Variable $variable, $classDefinition, CompilationContext $context)
Expand Down
29 changes: 14 additions & 15 deletions Library/Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -1325,7 +1325,7 @@ public function processExtensionGlobals(string $namespace): array
$structBuilder->addProperty($field, $global);

$isModuleGlobal = (int) !empty($global['module']);
$globalsDefault[$isModuleGlobal][] = $structBuilder->getCDefault($field, $global, $namespace).PHP_EOL;
$globalsDefault[$isModuleGlobal][] = $structBuilder->getCDefault($field, $global, $namespace);
$initEntries[] = $structBuilder->getInitEntry($field, $global, $namespace);
}

Expand All @@ -1334,8 +1334,7 @@ public function processExtensionGlobals(string $namespace): array

$globalCode = PHP_EOL;
foreach ($structures as $structureName => $internalStructure) {
$globalCode .= "\t".'zephir_struct_'.$structureName.' '.
$structureName.';'.PHP_EOL.PHP_EOL;
$globalCode .= "\t".'zephir_struct_'.$structureName.' '.$structureName.';'.PHP_EOL;
}

/**
Expand All @@ -1352,41 +1351,41 @@ public function processExtensionGlobals(string $namespace): array

$isModuleGlobal = (int) !empty($global['module']);
$type = $global['type'];
// TODO: Add support for 'string', 'hash'
// TODO: Add support for 'hash'
// TODO: Zephir\Optimizers\FunctionCall\GlobalsSetOptimizer
switch ($global['type']) {
case 'boolean':
case 'bool':
$type = 'zend_bool';
if (true === $global['default']) {
$globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = 1;'.PHP_EOL;
$globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = 1;';
} else {
$globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = 0;'.PHP_EOL;
$globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = 0;';
}
break;

case 'int':
case 'uint':
case 'long':
case 'double':
$globalsDefault[$isModuleGlobal][]
= "\t".$namespace.'_globals->'.$name.' = '.
$global['default'].';'.PHP_EOL;
$globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = '.$global['default'].';';
break;

case 'char':
case 'uchar':
$globalsDefault[$isModuleGlobal][]
= "\t".$namespace.'_globals->'.$name.' = \''.
$global['default'].'\';'.PHP_EOL;
$globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = \''.$global['default'].'\';';
break;
case 'string':
$type = 'char *';
$globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = ZSTR_VAL(zend_string_init(ZEND_STRL("'.$global['default'].'"), 0));';
break;
default:
throw new Exception(
"Unknown type '".$global['type']."' for extension global '".$name."'"
);
}

$globalCode .= "\t".$type.' '.$name.';'.PHP_EOL.PHP_EOL;
$globalCode .= "\t".$type.' '.$name.';'.PHP_EOL;
$iniEntry = [];
if (isset($global['ini-entry'])) {
$iniEntry = $global['ini-entry'];
Expand Down Expand Up @@ -1425,8 +1424,8 @@ public function processExtensionGlobals(string $namespace): array
}
}

$globalsDefault[0] = implode('', $globalsDefault[0]);
$globalsDefault[1] = implode('', $globalsDefault[1]);
$globalsDefault[0] = implode(PHP_EOL, $globalsDefault[0]);
$globalsDefault[1] = implode(PHP_EOL, $globalsDefault[1]);

return [$globalCode, $globalStruct, $globalsDefault, $initEntries];
}
Expand Down
24 changes: 14 additions & 10 deletions Library/Optimizers/FunctionCall/GlobalsGetOptimizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* the LICENSE file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Zephir\Optimizers\FunctionCall;

use Zephir\Call;
Expand All @@ -17,8 +19,10 @@
use Zephir\Exception\CompilerException;
use Zephir\Optimizers\OptimizerAbstract;

use function count;

/**
* GlobalsGetOptimizer.
* `globals_get()` internal function.
*
* Reads values from extensions globals
*/
Expand All @@ -29,21 +33,21 @@ class GlobalsGetOptimizer extends OptimizerAbstract
* @param Call $call
* @param CompilationContext $context
*
* @throws CompilerException
* @return CompiledExpression|null
*
* @return bool|CompiledExpression|mixed
* @throws CompilerException
*/
public function optimize(array $expression, Call $call, CompilationContext $context)
public function optimize(array $expression, Call $call, CompilationContext $context): ?CompiledExpression
{
if (!isset($expression['parameters'])) {
return false;
return null;
}

if (1 != \count($expression['parameters'])) {
if (1 !== count($expression['parameters'])) {
throw new CompilerException("'globals_get' only accepts one parameter", $expression);
}

if ('string' != $expression['parameters'][0]['parameter']['type']) {
if ('string' !== $expression['parameters'][0]['parameter']['type']) {
throw new CompilerException("A string parameter is required for 'globals_get'", $expression);
}

Expand All @@ -53,14 +57,14 @@ public function optimize(array $expression, Call $call, CompilationContext $cont
throw new CompilerException("Global '".$globalName."' cannot be read because it isn't defined", $expression);
}

$globalDefinition = $context->compiler->getExtensionGlobal($globalName);
$type = $context->compiler->getExtensionGlobal($globalName)['type'];

if (false !== strpos($globalName, '.')) {
$parts = explode('.', $globalName);

return new CompiledExpression($globalDefinition['type'], 'ZEPHIR_GLOBAL('.$parts[0].').'.$parts[1], $expression);
return new CompiledExpression($type, 'ZEPHIR_GLOBAL('.$parts[0].').'.$parts[1], $expression);
}

return new CompiledExpression($globalDefinition['type'], 'ZEPHIR_GLOBAL('.$globalName.')', $expression);
return new CompiledExpression($type, 'ZEPHIR_GLOBAL('.$globalName.')', $expression);
}
}
31 changes: 15 additions & 16 deletions Library/Optimizers/FunctionCall/GlobalsSetOptimizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* the LICENSE file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Zephir\Optimizers\FunctionCall;

use Zephir\Call;
Expand All @@ -18,10 +20,12 @@
use Zephir\Exception\CompilerException;
use Zephir\Optimizers\OptimizerAbstract;

use function count;

/**
* Zephir\Optimizers\FunctionCall\GlobalsSetOptimizer.
* `globals_set()` internal function.
*
* Writes values from extensions globals
* Writes values from extensions globals.
*/
class GlobalsSetOptimizer extends OptimizerAbstract
{
Expand All @@ -34,17 +38,17 @@ class GlobalsSetOptimizer extends OptimizerAbstract
*
* @return CompiledExpression
*/
public function optimize(array $expression, Call $call, CompilationContext $context)
public function optimize(array $expression, Call $call, CompilationContext $context): CompiledExpression
{
if (!isset($expression['parameters'])) {
throw new CompilerException("'globals_set' requires two parameters", $expression);
}

if (2 != \count($expression['parameters'])) {
if (2 !== count($expression['parameters'])) {
throw new CompilerException("'globals_set' only accepts two parameters", $expression);
}

if ('string' != $expression['parameters'][0]['parameter']['type']) {
if ('string' !== $expression['parameters'][0]['parameter']['type']) {
throw new CompilerException("A string parameter is required for 'globals_set'", $expression);
}

Expand Down Expand Up @@ -88,7 +92,7 @@ public function optimize(array $expression, Call $call, CompilationContext $cont
}
}

private function resolveInternalAccessor($globalName)
private function resolveInternalAccessor(string $globalName): string
{
$parts = explode('.', $globalName);

Expand All @@ -101,7 +105,6 @@ private function resolveInternalAccessor($globalName)

/**
* TODO: Add 'hash' support
* TODO: Use zval_get_string, zval_get_long, zval_get_double for ZE3
*
* @param array $definition
* @param array $expression
Expand All @@ -110,7 +113,7 @@ private function resolveInternalAccessor($globalName)
*
* @return string
*/
private function resolveInternalValue(array $definition, array $expression, $name, $value)
private function resolveInternalValue(array $definition, array $expression, string $name, string $value): string
{
$type = $definition['type'];

Expand All @@ -123,22 +126,18 @@ private function resolveInternalValue(array $definition, array $expression, $nam
case 'integer':
case 'long':
case 'ulong':
// TODO: Use zval_get_long when we'll drop Zend Engine 2
return strtr('Z_LVAL_P(:v)', [':v' => $value]);
return strtr('zval_get_long(:v)', [':v' => $value]);
case 'string':
// TODO: Use zval_get_string when we'll drop Zend Engine 2
return strtr('Z_STRVAL_P(:v)', [':v' => $value]);
return strtr('ZSTR_VAL(zval_get_string(:v))', [':v' => $value]);
case 'char':
case 'uchar':
// TODO: Use zval_get_string and zval_get_long when we'll drop Zend Engine 2
return strtr(
'(Z_TYPE_P(:v) == IS_STRING ? (Z_STRLEN_P(:v) ? Z_STRVAL_P(:v)[0] : NULL) : Z_LVAL_P(:v))',
'(Z_TYPE_P(:v) == IS_STRING ? (Z_STRLEN_P(:v) ? Z_STRVAL_P(:v)[0] : NULL) : zval_get_long(:v))',
[':v' => $value]
);
case 'double':
case 'float':
// TODO: Use zval_get_double when we'll drop Zend Engine 2
return strtr('Z_DVAL_P(:v)', [':v' => $value]);
return strtr('zval_get_double(:v)', [':v' => $value]);
default:
throw new CompilerException(
"Unknown type '{$type}' to setting global variable '{$name}'.",
Expand Down
22 changes: 10 additions & 12 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"author": "Phalcon Team and contributors",
"version": "1.0.0",
"verbose": true,

"requires": {
"extensions": [
"PDO",
Expand All @@ -15,27 +14,24 @@
"json"
]
},

"stubs": {
"path": "ide\/%version%\/%namespace%\/",
"stubs-run-after-generate": false,
"banner": "/**\n * This file is part of the Zephir.\n *\n * (c) Phalcon Team <team@zephir-lang.com>\n *\n * For the full copyright and license information, please view\n * the LICENSE file that was distributed with this source code.\n */"
},

"api": {
"path" : "doc/%version%",
"theme" : {
"name":"zephir",
"options" :{
"github":"https://github.com/user/repo",
"analytics":null,
"path": "doc/%version%",
"theme": {
"name": "zephir",
"options": {
"github": "https://github.com/user/repo",
"analytics": null,
"main_color": "#3E6496",
"link_color": "#3E6496",
"link_hover_color": "#5F9AE7"
}
}
},

"warnings": {
"unused-variable": true,
"unused-variable-external": false,
Expand All @@ -62,7 +58,6 @@
"invalid-typeof-comparison": true,
"conditional-initialization": true
},

"optimizations": {
"static-type-inference": true,
"static-type-inference-second-pass": true,
Expand All @@ -75,7 +70,6 @@
"public-internal-methods": false,
"public-internal-functions": true
},

"globals": {
"my_setting_1": {
"type": "bool",
Expand All @@ -101,6 +95,10 @@
"type": "char",
"default": "A"
},
"my_setting_5": {
"type": "string",
"default": "custom_value"
},
"db.my_setting_1": {
"type": "bool",
"default": false
Expand Down
9 changes: 1 addition & 8 deletions ext/php_stub.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,14 @@ ZEND_BEGIN_MODULE_GLOBALS(stub)


zephir_struct_db db;

zephir_struct_orm orm;

zephir_struct_extension extension;

zend_bool my_setting_1;

zend_bool test_setting_1;

int my_setting_2;

double my_setting_3;

char my_setting_4;

char * my_setting_5;

ZEND_END_MODULE_GLOBALS(stub)

Expand Down
2 changes: 1 addition & 1 deletion ext/stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ static void php_zephir_init_globals(zend_stub_globals *stub_globals)
stub_globals->my_setting_2 = 10;
stub_globals->my_setting_3 = 15.2;
stub_globals->my_setting_4 = 'A';

stub_globals->my_setting_5 = ZSTR_VAL(zend_string_init(ZEND_STRL("custom_value"), 0));

}

Expand Down
Loading