├── .gitignore
├── README.md
├── composer.json
├── config.json
├── example
├── ajax-example
│ ├── _reset.php
│ ├── _set.php
│ ├── control.php
│ └── index.html
├── blink.php
├── board.php
├── pin.php
├── pulse.php
├── reset.php
├── rgbled.php
└── softpwm.php
├── ext
└── kernel
│ ├── README.md
│ ├── array.c
│ ├── array.h
│ ├── assert.c
│ ├── assert.h
│ ├── backtrace.c
│ ├── backtrace.h
│ ├── concat.c
│ ├── concat.h
│ ├── debug.c
│ ├── debug.h
│ ├── exception.c
│ ├── exception.h
│ ├── exit.c
│ ├── exit.h
│ ├── extended
│ ├── array.c
│ ├── array.h
│ ├── fcall.c
│ └── fcall.h
│ ├── fcall.c
│ ├── fcall.h
│ ├── file.c
│ ├── file.h
│ ├── filter.c
│ ├── filter.h
│ ├── globals.h
│ ├── hash.c
│ ├── hash.h
│ ├── iterator.c
│ ├── iterator.h
│ ├── main.c
│ ├── main.h
│ ├── math.c
│ ├── math.h
│ ├── memory.c
│ ├── memory.h
│ ├── object.c
│ ├── object.h
│ ├── operators.c
│ ├── operators.h
│ ├── output.c
│ ├── output.h
│ ├── persistent.c
│ ├── persistent.h
│ ├── require.c
│ ├── require.h
│ ├── session.c
│ ├── session.h
│ ├── string.c
│ ├── string.h
│ ├── time.c
│ ├── time.h
│ ├── variables.c
│ └── variables.h
├── phpiwire
├── Board.zep
└── Pin.zep
└── phpstorm-stub.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PHPiWire
2 |
3 | A wrapper for [wiringPi](http://wiringpi.com/) written in [Zephir](http://www.zephir-lang.com/) so that is can be compiled as an extension for PHP.
4 |
5 | [](https://flattr.com/submit/auto?user_id=acollington&url=https://github.com/amnuts/phpiwire&title=phpiwire&language=&tags=github&category=software)
6 |
7 | ## Requirements
8 |
9 | This extension and the wiringPi library are intended to run on a RaspberryPi, so having a RaspberryPi is kind of a big requirement here! You also need to have Git installed, the wiringPi library, various build tools and the php development headers.
10 |
11 | ### Installing Git
12 |
13 | ```
14 | sudo apt-get update
15 | sudo apt-get install git
16 | ```
17 |
18 | ### Installing wiringPi
19 |
20 | ```
21 | git clone git://git.drogon.net/wiringPi
22 | cd wiringPi
23 | ./build
24 | ```
25 |
26 | If all goes well you should be able to run the gpio utility:
27 |
28 | ```
29 | gpio -v
30 | ```
31 |
32 | Full instructions for [installing wiringPi](http://wiringpi.com/download-and-install/).
33 |
34 | ### Installing zephir
35 |
36 | ```
37 | sudo apt-get install gcc make re2c php5 php5-json php5-dev libpcre3-dev
38 | git clone https://github.com/phalcon/zephir
39 | cd zephir
40 | ./install-json
41 | ./install -c
42 | ```
43 |
44 | If all goes well you should be able to get the help info for zephir:
45 |
46 | ```
47 | zephir help
48 | ```
49 |
50 | Full instructions for [installing zephir](http://zephir-lang.com/install.html#installing-zephir).
51 |
52 | ## Building the extension
53 |
54 | ```
55 | git clone https://github.com/amnuts/phpiwire
56 | cd phpiwire
57 | zephir build
58 | ```
59 |
60 | That will build and install the extension. You'll then have to add the extension to your php.ini file. You may find that you have two php.ini files, one for cli and one for web, so remember to add the extension to both. You'll want to add the line:
61 |
62 | ```
63 | extension=phpiwire.so
64 | ```
65 |
66 | Once this is done (and the web server restarted if you're adding the extension for web use and not just cli) you should be able to see the extension info when using the ```phpinfo()``` method or via the command line ```php -i```.
67 |
68 | ## Example
69 |
70 | Here's a very simple example of how to make an LED attached to pin 0 (using the wiringPi pin numbering scheme, BCM_GPIO pin 17) blink on and off.
71 |
72 | Assuming the LED is attached as shown:
73 |
74 | 
75 |
76 | ```php
77 | getPin(0)->mode(Pin::OUTPUT);
87 |
88 | while (true) {
89 | $p->write(Pin::HIGH);
90 | sleep(1);
91 | $p->write(Pin::LOW);
92 | sleep(1);
93 | }
94 | ```
95 |
96 | And to run it you'll need to be running as root:
97 |
98 | ```
99 | sudo php blink.php
100 | ```
101 |
102 | ## Releases
103 |
104 | Releases of the extension are available at:
105 |
106 | https://github.com/amnuts/phpiwire/releases/
107 |
108 | ## License
109 |
110 | MIT: http://acollington.mit-license.org/
111 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "amnuts/phpiwire",
3 | "description": "A PHP extension (written using Zephir) that interfaces with wiringPi, allowing you to easily control your Raspberry Pi's GPIO using PHP.",
4 | "keywords": ["gpio", "rpi", "raspberrypi", "zephir", "iot", "hardware", "wiringpi", "extension"],
5 | "minimum-stability": "stable",
6 | "license": "MIT",
7 | "homepage": "https://github.com/amnuts/phpiwire",
8 | "authors": [
9 | {
10 | "name": "Andrew Collington",
11 | "email": "andy@amnuts.com",
12 | "homepage": "http://www.amnuts.com/",
13 | "role": "Developer"
14 | },
15 | {
16 | "name": "Contributors",
17 | "homepage": "https://github.com/amnuts/phpiwire/graphs/contributors"
18 | }
19 | ],
20 | "support": {
21 | "email": "andy@amnuts.com",
22 | "issues": "https://github.com/amnuts/phpiwire/issues"
23 | }
24 | }
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "stubs": {
3 | "path": "ide\/%version%\/%namespace%\/",
4 | "stubs-run-after-generate": false
5 | },
6 | "api": {
7 | "path": "doc\/%version%",
8 | "theme": {
9 | "name": "zephir",
10 | "options": {
11 | "github": null,
12 | "analytics": null,
13 | "main_color": "#3E6496",
14 | "link_color": "#3E6496",
15 | "link_hover_color": "#5F9AE7"
16 | }
17 | }
18 | },
19 | "warnings": {
20 | "unused-variable": true,
21 | "unused-variable-external": false,
22 | "possible-wrong-parameter": true,
23 | "possible-wrong-parameter-undefined": false,
24 | "nonexistent-function": true,
25 | "nonexistent-class": true,
26 | "non-valid-isset": true,
27 | "non-array-update": true,
28 | "non-valid-objectupdate": true,
29 | "non-valid-fetch": true,
30 | "invalid-array-index": true,
31 | "non-array-append": true,
32 | "invalid-return-type": true,
33 | "unreachable-code": true,
34 | "nonexistent-constant": true,
35 | "not-supported-magic-constant": true,
36 | "non-valid-decrement": true,
37 | "non-valid-increment": true,
38 | "non-valid-clone": true,
39 | "non-valid-new": true,
40 | "non-array-access": true,
41 | "invalid-reference": true,
42 | "invalid-typeof-comparison": true,
43 | "conditional-initialization": true
44 | },
45 | "optimizations": {
46 | "static-type-inference": true,
47 | "static-type-inference-second-pass": true,
48 | "local-context-pass": true,
49 | "constant-folding": true,
50 | "static-constant-class-folding": true,
51 | "call-gatherer-pass": true,
52 | "check-invalid-reads": false
53 | },
54 | "namespace": "phpiwire",
55 | "name": "PHPiWire",
56 | "description": "Control the RaspberryPi GPIO via PHP (with wiringPi)",
57 | "author": "Andrew Collington (andy@amnuts.com)",
58 | "version": "0.2.0",
59 | "verbose": false,
60 | "requires": {
61 | "extensions": []
62 | },
63 | "extra-libs": "-lwiringPi -pthreads"
64 | }
--------------------------------------------------------------------------------
/example/ajax-example/_reset.php:
--------------------------------------------------------------------------------
1 | $val) {
20 | $p = $pi->getPin($pin)->mode(Pin::OUTPUT);
21 | $p->write(Pin::LOW);
22 | $pins[$pin] = $p->read();
23 | }
24 |
25 | echo json_encode($pins);
26 |
27 |
--------------------------------------------------------------------------------
/example/ajax-example/_set.php:
--------------------------------------------------------------------------------
1 | 'Incorrect number of parameters']);
22 | } else if ($argv[1] < 0 || $argv[1] > 3) {
23 | echo json_encode(['error' => 'Incorrect pin numbers selected - only 0-3 valid']);
24 | } else {
25 | foreach ($pins as $pin => $val) {
26 | $p = $pi->getPin($pin)->mode(Pin::OUTPUT);
27 | if ($pin == $argv[1]) {
28 | $p->write((bool)$argv[2] ? Pin::HIGH : Pin::LOW);
29 | }
30 | $pins[$pin] = $p->read();
31 | }
32 | echo json_encode($pins);
33 | }
34 |
--------------------------------------------------------------------------------
/example/ajax-example/control.php:
--------------------------------------------------------------------------------
1 | &1');
22 | break;
23 | case 'set':
24 | echo shell_exec('sudo php ' . __DIR__ . '/_set.php ' . (int)$_GET['pin'] . ' ' . (int)$_GET['onoff'] . ' 2>&1');
25 | break;
26 | default:
27 | echo json_encode(['error' => 'Bad function call']);
28 | break;
29 | }
30 |
--------------------------------------------------------------------------------
/example/ajax-example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 |
16 | Ajax example
17 |
18 |
86 |
87 |
88 |
89 | Test of activating pins via ajax
90 |
91 | This example needs to run from your web server and shows that the GPIO pins can be toggled via a web interface using an ajax request.
92 | When the page loads the pins will be set to 0 and you can toggle from there.
93 |
94 | Important
95 |
96 | To get this working on the Raspberry Pi, the PHP binary needs to be added to the sudoers file. The easiest way to do this is to use the command:
97 | sudo visudo
98 | and then append this at the bottom of the file and save:
99 | www-data ALL=(ALL) NOPASSWD: /usr/bin/php
100 |
101 | Toggle pin values
102 |
103 |
104 |
105 |
106 |
110 |
111 |
Pin reports as 0
112 |
113 |
114 |
115 |
116 |
117 |
121 |
122 |
Pin reports as 0
123 |
124 |
125 |
126 |
127 |
128 |
132 |
133 |
Pin reports as 0
134 |
135 |
136 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/example/blink.php:
--------------------------------------------------------------------------------
1 | getPin(0)->mode(Pin::OUTPUT);
27 |
28 | while (true) {
29 | echo "\033[1K\rON";
30 | $p->write(Pin::HIGH);
31 | sleep(1);
32 | echo "\033[1K\rOFF";
33 | $p->write(Pin::LOW);
34 | sleep(1);
35 | }
36 |
--------------------------------------------------------------------------------
/example/board.php:
--------------------------------------------------------------------------------
1 | version());
--------------------------------------------------------------------------------
/example/pin.php:
--------------------------------------------------------------------------------
1 | getPin(0)->mode(Pin::OUTPUT);
18 |
19 | echo $p, "\n";
20 |
21 | if ($p->read() == Pin::LOW) {
22 | echo "Setting {$p->getId()} to HIGH\n\n";
23 | $p->write(Pin::HIGH);
24 | } else {
25 | echo "Setting {$p->getId()} to LOW\n\n";
26 | $p->write(Pin::LOW);
27 | }
28 |
29 | echo $p, "\n";
30 |
--------------------------------------------------------------------------------
/example/pulse.php:
--------------------------------------------------------------------------------
1 | getPin(1)->mode(Pin::PWM_OUT);
27 | $p->pwmWrite(0);
28 |
29 | $sleep = 500;
30 | $pwmValue = 1024; // 0 min, 1024 max
31 |
32 | while (true) {
33 | for ($i = 0; $i <= $pwmValue; ++$i) {
34 | $p->pwmWrite($i);
35 | usleep($sleep);
36 | }
37 | sleep(1);
38 | for ($i = $pwmValue; $i > 0; --$i) {
39 | $p->pwmWrite($i);
40 | usleep($sleep);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/example/reset.php:
--------------------------------------------------------------------------------
1 | getPin($pin)->mode(Pin::OUTPUT);
26 | $p->write(Pin::LOW);
27 | }
28 |
--------------------------------------------------------------------------------
/example/rgbled.php:
--------------------------------------------------------------------------------
1 | getPin(0)->mode(Pin::SOFT_PWM_OUT)->softPwmWrite(100);
46 | $g = $pi->getPin(1)->mode(Pin::SOFT_PWM_OUT);
47 | $b = $pi->getPin(2)->mode(Pin::SOFT_PWM_OUT);
48 | }
49 | $r->softPwmWrite($rgb[0]);
50 | $g->softPwmWrite($rgb[1]);
51 | $b->softPwmWrite($rgb[2]);
52 | }
53 |
--------------------------------------------------------------------------------
/example/softpwm.php:
--------------------------------------------------------------------------------
1 | getPin(0)->mode(Pin::SOFT_PWM_OUT);
27 |
28 | $sleep = 20000;
29 | $pwmValue = 100; // 0 min, 100 max
30 |
31 | while (true) {
32 | for ($i = 0; $i <= $pwmValue; ++$i) {
33 | $p->softPwmWrite($i);
34 | usleep($sleep);
35 | }
36 | for ($i = $pwmValue; $i > 0; --$i) {
37 | $p->softPwmWrite($i);
38 | usleep($sleep);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/ext/kernel/README.md:
--------------------------------------------------------------------------------
1 | Zephir Kernel
2 | ==============
3 |
4 | Zephir Kernel is a meta-framework on top of the Zend API helping to create PHP extensions in an easier way
5 | for a PHP developer.
6 |
7 | In order to build a fast and stable framework, we have created the Zephir Kernel. The use of
8 | this API helps us to write C code in a PHP style. We have developed a number of functions to help the
9 | programmer to write code more interoperable with PHP in a easier way.
10 |
11 | Zephir Kernel API is based on the Zend API, but we have added more features to facilitate us the work.
12 | Zephir is a very large project, frameworks need to be developed and improved every day, Zephir Kernel API
13 | helps us to write C code that is more stable and familiar to PHP developers.
14 |
15 | If you’re a PHP developer maybe you don’t know C or you don’t want to learn C, but after read this guide
16 | you will find the Zephir API very familiar to your knowledge.
17 |
18 | Zephir Kernel provides you:
19 |
20 | * Manipulate arrays/objects
21 | * Call functions/methods in the PHP userland
22 | * Automatic memory management
23 | * Require and execute PHP plain files
24 | * Simplification of common operations like concatenation
25 | * Read superglobals and update the active symbol table
26 | * Register classes in namespaces
27 | * Throw exceptions
28 | * And more
29 |
30 | License
31 | -------
32 | Zephir is open-sourced software licensed under the New BSD License. See the LICENSE file for more information.
33 |
34 | Related Documentation
35 | ---------------------
36 | * http://internals.phalconphp.com/en/latest/index.html
--------------------------------------------------------------------------------
/ext/kernel/array.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_ARRAY_H
22 | #define ZEPHIR_KERNEL_ARRAY_H
23 | #define ZEPHIR_MAX_ARRAY_LEVELS 16
24 |
25 | #include
26 | #include
27 | #include "kernel/globals.h"
28 | #include "kernel/main.h"
29 |
30 | /** Combined isset/fetch */
31 | int zephir_array_isset_fetch(zval **fetched, const zval *arr, zval *index, int readonly TSRMLS_DC);
32 | int zephir_array_isset_quick_string_fetch(zval **fetched, zval *arr, char *index, uint index_length, unsigned long key, int readonly TSRMLS_DC);
33 | int zephir_array_isset_string_fetch(zval **fetched, zval *arr, char *index, uint index_length, int readonly TSRMLS_DC);
34 | int zephir_array_isset_long_fetch(zval **fetched, zval *arr, unsigned long index, int readonly TSRMLS_DC);
35 |
36 | /** Check for index existence */
37 | int ZEPHIR_FASTCALL zephir_array_isset(const zval *arr, zval *index);
38 | int ZEPHIR_FASTCALL zephir_array_isset_long(const zval *arr, unsigned long index);
39 | int ZEPHIR_FASTCALL zephir_array_isset_string(const zval *arr, const char *index, uint index_length);
40 |
41 | /** Fast index existence checking */
42 | int ZEPHIR_FASTCALL zephir_array_isset_quick_string(const zval *arr, const char *index, uint index_length, unsigned long key);
43 |
44 | /** Unset existing indexes */
45 | int ZEPHIR_FASTCALL zephir_array_unset(zval **arr, zval *index, int flags);
46 | int ZEPHIR_FASTCALL zephir_array_unset_long(zval **arr, unsigned long index, int flags);
47 | int ZEPHIR_FASTCALL zephir_array_unset_string(zval **arr, const char *index, uint index_length, int flags);
48 |
49 | /** Append elements to arrays */
50 | int zephir_array_append(zval **arr, zval *value, int separate ZEPHIR_DEBUG_PARAMS);
51 | int zephir_array_append_long(zval **arr, long value, int separate);
52 | int zephir_array_append_string(zval **arr, char *value, uint value_length, int separate);
53 |
54 | /** Modify arrays */
55 | int zephir_array_update_zval(zval **arr, zval *index, zval **value, int flags);
56 | int zephir_array_update_string(zval **arr, const char *index, uint index_length, zval **value, int flags);
57 | int zephir_array_update_long(zval **arr, unsigned long index, zval **value, int flags ZEPHIR_DEBUG_PARAMS);
58 |
59 | /** Fetch items from arrays */
60 | int zephir_array_fetch(zval **return_value, zval *arr, zval *index, int flags ZEPHIR_DEBUG_PARAMS TSRMLS_DC);
61 | int zephir_array_fetch_string(zval **return_value, zval *arr, const char *index, uint index_length, int flags ZEPHIR_DEBUG_PARAMS TSRMLS_DC);
62 | int zephir_array_fetch_long(zval **return_value, zval *arr, unsigned long index, int flags ZEPHIR_DEBUG_PARAMS TSRMLS_DC);
63 |
64 | /** Merge+Append */
65 | void zephir_merge_append(zval *left, zval *values);
66 |
67 | /* Traversing Arays */
68 | void zephir_array_get_current(zval *return_value, zval *array);
69 | void zephir_array_next(zval *array);
70 |
71 | /* In Array */
72 | int zephir_fast_in_array(zval *needle, zval *haystack TSRMLS_DC);
73 |
74 | /** Fast Array Merge */
75 | void zephir_fast_array_merge(zval *return_value, zval **array1, zval **array2 TSRMLS_DC);
76 |
77 | /** Recursive merge */
78 | void zephir_array_merge_recursive_n(zval **a1, zval *a2 TSRMLS_DC);
79 |
80 | void zephir_array_unshift(zval *arr, zval *arg TSRMLS_DC);
81 | void zephir_array_keys(zval *return_value, zval *arr TSRMLS_DC);
82 | void zephir_array_values(zval *return_value, zval *arr);
83 | int zephir_array_key_exists(zval *arr, zval *key TSRMLS_DC);
84 | int zephir_array_is_associative(zval *arr);
85 |
86 | void zephir_array_update_multi_ex(zval **arr, zval **value, const char *types, int types_length, int types_count, va_list ap TSRMLS_DC);
87 | int zephir_array_update_multi(zval **arr, zval **value TSRMLS_DC, const char *types, int types_length, int types_count, ...);
88 |
89 | void ZEPHIR_FASTCALL zephir_create_array(zval *return_value, uint size, int initialize TSRMLS_DC);
90 |
91 | #define zephir_array_fast_append(arr, value) \
92 | Z_ADDREF_P(value); \
93 | zend_hash_next_index_insert(Z_ARRVAL_P(arr), &value, sizeof(zval *), NULL);
94 |
95 | #endif /* ZEPHIR_KERNEL_ARRAY_H */
96 |
--------------------------------------------------------------------------------
/ext/kernel/assert.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
20 | #ifdef HAVE_CONFIG_H
21 | #include "config.h"
22 | #endif
23 |
24 | #include
25 | #include "php_ext.h"
26 | #include "kernel/debug.h"
27 |
28 | #ifndef ZEPHIR_RELEASE
29 |
30 | int zephir_assert_class(zval *object, char *class_name TSRMLS_DC) {
31 | if (object) {
32 | if (Z_TYPE_P(object) != IS_OBJECT) {
33 | zephir_error_space();
34 | fprintf(zephir_log, "AssertClass: [Failed] Value is not an object\n");
35 | return FAILURE;
36 | } else {
37 | if (strcmp(Z_OBJCE_P(object)->name, class_name)) {
38 | zephir_error_space();
39 | fprintf(zephir_log, "AssertClass: [Failed] Object is not class %s, is %s\n", class_name, Z_OBJCE_P(object)->name);
40 | return FAILURE;
41 | }
42 | }
43 | }
44 | return SUCCESS;
45 | }
46 |
47 | #endif
48 |
--------------------------------------------------------------------------------
/ext/kernel/assert.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
20 | #ifndef ZEPHIR_KERNEL_ASSERT_H
21 | #define ZEPHIR_KERNEL_ASSERT_H
22 |
23 | #ifndef ZEPHIR_RELEASE
24 |
25 | #include
26 | #include
27 |
28 | extern int zephir_assert_class(zval *object, char *class_name TSRMLS_DC);
29 |
30 | #endif
31 | #endif /* ZEPHIR_KERNEL_ASSERT_H */
32 |
--------------------------------------------------------------------------------
/ext/kernel/backtrace.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_RELEASE
22 | #if defined(linux) || defined(DARWIN) || defined(__APPLE__)
23 |
24 | #include
25 | #include
26 | #include
27 |
28 | /**
29 | * A buffer for backtrace. It is better to have it allocated statically
30 | * in order not to face out of memory conditions later
31 | */
32 | void *backtrace_buf[4096];
33 |
34 | void zephir_print_backtrace(void)
35 | {
36 | int i;
37 | int stack_size = backtrace(backtrace_buf, sizeof(backtrace_buf) / sizeof(void*));
38 | char **stack_symbols = backtrace_symbols(backtrace_buf, stack_size);
39 | char buf[50];
40 | smart_str s;
41 |
42 | s.c = NULL;
43 |
44 | for (i = 0; i < stack_size; ++i) {
45 | snprintf(buf, sizeof(buf), "#%d %p [", i, backtrace_buf[i]);
46 | smart_str_appends(&s, buf);
47 | smart_str_appends(&s, stack_symbols[i]);
48 | smart_str_appends(&s, "]\n");
49 | }
50 |
51 | smart_str_0(&s);
52 |
53 | fprintf(stderr, "%s\n", s.c);
54 | smart_str_free(&s);
55 | }
56 |
57 | #else
58 |
59 | void zephir_print_backtrace(void)
60 | {
61 | /**
62 | * Not implemented yet for anything other than Linux
63 | */
64 | }
65 |
66 | #endif
67 | #endif /* ZEPHIR_RELEASE */
68 |
--------------------------------------------------------------------------------
/ext/kernel/backtrace.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_BACKTRACE_H
22 | #define ZEPHIR_KERNEL_BACKTRACE_H
23 |
24 | #ifndef ZEPHIR_RELEASE
25 |
26 | extern void zephir_print_backtrace(void);
27 |
28 | #else
29 |
30 | #ifndef zephir_print_backtrace
31 | #define zephir_print_backtrace()
32 | #endif
33 |
34 | #endif
35 | #endif /* ZEPHIR_KERNEL_BACKTRACE_H */
36 |
--------------------------------------------------------------------------------
/ext/kernel/concat.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef ZEPHIR_KERNEL_CONCAT_H
3 | #define ZEPHIR_KERNEL_CONCAT_H
4 |
5 | #include
6 | #include
7 |
8 | #include "kernel/main.h"
9 |
10 | #define ZEPHIR_CONCAT_SS(result, op1, op2) \
11 | zephir_concat_ss(&result, op1, sizeof(op1)-1, op2, sizeof(op2)-1, 0 TSRMLS_CC);
12 | #define ZEPHIR_SCONCAT_SS(result, op1, op2) \
13 | zephir_concat_ss(&result, op1, sizeof(op1)-1, op2, sizeof(op2)-1, 1 TSRMLS_CC);
14 |
15 | #define ZEPHIR_CONCAT_SSSSSSS(result, op1, op2, op3, op4, op5, op6, op7) \
16 | zephir_concat_sssssss(&result, op1, sizeof(op1)-1, op2, sizeof(op2)-1, op3, sizeof(op3)-1, op4, sizeof(op4)-1, op5, sizeof(op5)-1, op6, sizeof(op6)-1, op7, sizeof(op7)-1, 0 TSRMLS_CC);
17 | #define ZEPHIR_SCONCAT_SSSSSSS(result, op1, op2, op3, op4, op5, op6, op7) \
18 | zephir_concat_sssssss(&result, op1, sizeof(op1)-1, op2, sizeof(op2)-1, op3, sizeof(op3)-1, op4, sizeof(op4)-1, op5, sizeof(op5)-1, op6, sizeof(op6)-1, op7, sizeof(op7)-1, 1 TSRMLS_CC);
19 |
20 | #define ZEPHIR_CONCAT_SSV(result, op1, op2, op3) \
21 | zephir_concat_ssv(&result, op1, sizeof(op1)-1, op2, sizeof(op2)-1, op3, 0 TSRMLS_CC);
22 | #define ZEPHIR_SCONCAT_SSV(result, op1, op2, op3) \
23 | zephir_concat_ssv(&result, op1, sizeof(op1)-1, op2, sizeof(op2)-1, op3, 1 TSRMLS_CC);
24 |
25 | #define ZEPHIR_CONCAT_SV(result, op1, op2) \
26 | zephir_concat_sv(&result, op1, sizeof(op1)-1, op2, 0 TSRMLS_CC);
27 | #define ZEPHIR_SCONCAT_SV(result, op1, op2) \
28 | zephir_concat_sv(&result, op1, sizeof(op1)-1, op2, 1 TSRMLS_CC);
29 |
30 | #define ZEPHIR_CONCAT_SVS(result, op1, op2, op3) \
31 | zephir_concat_svs(&result, op1, sizeof(op1)-1, op2, op3, sizeof(op3)-1, 0 TSRMLS_CC);
32 | #define ZEPHIR_SCONCAT_SVS(result, op1, op2, op3) \
33 | zephir_concat_svs(&result, op1, sizeof(op1)-1, op2, op3, sizeof(op3)-1, 1 TSRMLS_CC);
34 |
35 | #define ZEPHIR_CONCAT_SVSV(result, op1, op2, op3, op4) \
36 | zephir_concat_svsv(&result, op1, sizeof(op1)-1, op2, op3, sizeof(op3)-1, op4, 0 TSRMLS_CC);
37 | #define ZEPHIR_SCONCAT_SVSV(result, op1, op2, op3, op4) \
38 | zephir_concat_svsv(&result, op1, sizeof(op1)-1, op2, op3, sizeof(op3)-1, op4, 1 TSRMLS_CC);
39 |
40 | #define ZEPHIR_CONCAT_VS(result, op1, op2) \
41 | zephir_concat_vs(&result, op1, op2, sizeof(op2)-1, 0 TSRMLS_CC);
42 | #define ZEPHIR_SCONCAT_VS(result, op1, op2) \
43 | zephir_concat_vs(&result, op1, op2, sizeof(op2)-1, 1 TSRMLS_CC);
44 |
45 | #define ZEPHIR_CONCAT_VV(result, op1, op2) \
46 | zephir_concat_vv(&result, op1, op2, 0 TSRMLS_CC);
47 | #define ZEPHIR_SCONCAT_VV(result, op1, op2) \
48 | zephir_concat_vv(&result, op1, op2, 1 TSRMLS_CC);
49 |
50 | #define ZEPHIR_CONCAT_VVV(result, op1, op2, op3) \
51 | zephir_concat_vvv(&result, op1, op2, op3, 0 TSRMLS_CC);
52 | #define ZEPHIR_SCONCAT_VVV(result, op1, op2, op3) \
53 | zephir_concat_vvv(&result, op1, op2, op3, 1 TSRMLS_CC);
54 |
55 |
56 | void zephir_concat_ss(zval **result, const char *op1, zend_uint op1_len, const char *op2, zend_uint op2_len, int self_var TSRMLS_DC);
57 | void zephir_concat_sssssss(zval **result, const char *op1, zend_uint op1_len, const char *op2, zend_uint op2_len, const char *op3, zend_uint op3_len, const char *op4, zend_uint op4_len, const char *op5, zend_uint op5_len, const char *op6, zend_uint op6_len, const char *op7, zend_uint op7_len, int self_var TSRMLS_DC);
58 | void zephir_concat_ssv(zval **result, const char *op1, zend_uint op1_len, const char *op2, zend_uint op2_len, zval *op3, int self_var TSRMLS_DC);
59 | void zephir_concat_sv(zval **result, const char *op1, zend_uint op1_len, zval *op2, int self_var TSRMLS_DC);
60 | void zephir_concat_svs(zval **result, const char *op1, zend_uint op1_len, zval *op2, const char *op3, zend_uint op3_len, int self_var TSRMLS_DC);
61 | void zephir_concat_svsv(zval **result, const char *op1, zend_uint op1_len, zval *op2, const char *op3, zend_uint op3_len, zval *op4, int self_var TSRMLS_DC);
62 | void zephir_concat_vs(zval **result, zval *op1, const char *op2, zend_uint op2_len, int self_var TSRMLS_DC);
63 | void zephir_concat_vv(zval **result, zval *op1, zval *op2, int self_var TSRMLS_DC);
64 | void zephir_concat_vvv(zval **result, zval *op1, zval *op2, zval *op3, int self_var TSRMLS_DC);
65 | void zephir_concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
66 |
67 | #endif /* ZEPHIR_KERNEL_CONCAT_H */
68 |
69 |
--------------------------------------------------------------------------------
/ext/kernel/debug.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
20 | #ifdef HAVE_CONFIG_H
21 | #include "config.h"
22 | #endif
23 |
24 | #include
25 | #include "php_ext.h"
26 | #include "kernel/debug.h"
27 | #include "kernel/main.h"
28 | #include "kernel/string.h"
29 |
30 | #ifndef ZEPHIR_RELEASE
31 |
32 | FILE *zephir_log = NULL;
33 | int zephir_debug_trace = 0;
34 | static zephir_debug_entry *start = NULL;
35 | static zephir_debug_entry *active = NULL;
36 |
37 | /**
38 | * Stars debug on file pipe
39 | */
40 | int zephir_start_debug(){
41 | if(!zephir_log){
42 | /*//zephir_log = fopen("/home/gutierrezandresfelipe/phalcon-debug.a", "w");
43 | zephir_log = fopen("/tmp/phalcon-debug.a", "w");
44 | if(!zephir_log){
45 | fprintf(stderr, "Can't open debug log\n");
46 | }*/
47 | zephir_log = stderr;
48 | }
49 | return SUCCESS;
50 | }
51 |
52 | /**
53 | * Stops debug process
54 | */
55 | int zephir_stop_debug(){
56 | zephir_debug_entry *ptr = active;
57 | zephir_debug_entry *this_entry = NULL;
58 | while(ptr){
59 | this_entry = ptr;
60 | ptr = ptr->prev;
61 | efree(this_entry);
62 | }
63 | //fclose(zephir_log);
64 | zephir_log = NULL;
65 | return SUCCESS;
66 | }
67 |
68 | /**
69 | * Executes a print_r on an interal zval
70 | */
71 | int zephir_print_r(zval *userval TSRMLS_DC){
72 | zend_print_zval_r(userval, 0 TSRMLS_CC);
73 | return SUCCESS;
74 | }
75 |
76 | /**
77 | * Internal fast zval dump
78 | */
79 | int zephir_vdump(zval *uservar TSRMLS_DC){
80 | zephir_start_debug();
81 | if(!uservar){
82 | fprintf(zephir_log, "Null pointer\n");
83 | return SUCCESS;
84 | }
85 | switch(Z_TYPE_P(uservar)){
86 | case IS_NULL:
87 | fprintf(zephir_log, "NULL \n");
88 | break;
89 | case IS_BOOL:
90 | fprintf(zephir_log, "Boolean: %s\n", Z_LVAL_P(uservar) ? "TRUE" : "FALSE");
91 | break;
92 | case IS_LONG:
93 | fprintf(zephir_log, "Long: %ld at %p, refcount=%d\n", Z_LVAL_P(uservar), uservar, Z_REFCOUNT_P(uservar));
94 | break;
95 | case IS_DOUBLE:
96 | fprintf(zephir_log, "Double: %f\n", Z_DVAL_P(uservar));
97 | break;
98 | case IS_STRING:
99 | fprintf(zephir_log, "String: %s(%d) at %p, refcount=%d\n", Z_STRVAL_P(uservar), Z_STRLEN_P(uservar), uservar, Z_REFCOUNT_P(uservar));
100 | break;
101 | case IS_RESOURCE:
102 | fprintf(zephir_log, "Resource\n");
103 | break;
104 | case IS_ARRAY:
105 | fprintf(zephir_log, "Array at %p, refcount=%d\n", uservar, Z_REFCOUNT_P(uservar));
106 | break;
107 | case IS_OBJECT:
108 | fprintf(zephir_log, "Object <%s> at %p\n", Z_OBJCE_P(uservar)->name, uservar);
109 | break;
110 | default:
111 | fprintf(zephir_log, "Unknown\n");
112 | }
113 | return SUCCESS;
114 | }
115 |
116 | int zephir_dump_ce(zend_class_entry *ce TSRMLS_DC){
117 | char *message = emalloc(sizeof(char *)*120);
118 | if(ce){
119 | sprintf(message, "- ClassType => %d", ce->type);
120 | zephir_step_over(message);
121 | if(ce->name){
122 | sprintf(message, "- ClassName => %s", ce->name);
123 | zephir_step_over(message);
124 | } else {
125 | zephir_step_over("- ClassName => NULL");
126 | }
127 | } else {
128 | zephir_step_over("- NULL class entry :(");
129 | }
130 | return SUCCESS;
131 | }
132 |
133 | int zephir_class_debug(zval *val TSRMLS_DC){
134 | char *message = emalloc(sizeof(char *)*120);
135 | zend_class_entry *ce;
136 | if(val){
137 | ce = Z_OBJCE_P(val);
138 | if(ce){
139 | sprintf(message, "- MemoryAddress => %p", val);
140 | zephir_step_over(message);
141 | zephir_dump_ce(ce TSRMLS_CC);
142 | } else {
143 | zephir_step_over("- No class entry :(");
144 | }
145 | } else {
146 | zephir_step_over("- this_ptr is null :(");
147 | }
148 | return SUCCESS;
149 | }
150 |
151 | /**
152 | * Append debug information to file
153 | */
154 | int zephir_debug_str(char *what, char *message){
155 | fprintf(zephir_log, "%s", what);
156 | fprintf(zephir_log, "%s", message);
157 | fprintf(zephir_log, "\n");
158 | return SUCCESS;
159 | }
160 |
161 | int zephir_debug_long(char *what, uint vlong){
162 | fprintf(zephir_log, "%s", what);
163 | fprintf(zephir_log, "%u", vlong);
164 | fprintf(zephir_log, "\n");
165 | return SUCCESS;
166 | }
167 |
168 | int zephir_debug_screen(char *message){
169 | zephir_debug_space();
170 | fprintf(zephir_log, "%s\n", message);
171 | return SUCCESS;
172 | }
173 |
174 | int zephir_debug_method_call(zval *obj, char *method_name TSRMLS_DC){
175 | if(Z_TYPE_P(obj)==IS_OBJECT){
176 | zephir_debug_space();
177 | } else {
178 | zephir_error_space();
179 | }
180 | if(Z_TYPE_P(obj)==IS_OBJECT){
181 | fprintf(zephir_log, "Calling method %s::%s on Object at %p\n", Z_OBJCE_P(obj)->name, method_name, obj);
182 | } else {
183 | fprintf(zephir_log, "Calling method %s on non object :(\n", method_name);
184 | }
185 | return SUCCESS;
186 | }
187 |
188 | int zephir_error_space(){
189 | int i;
190 | fprintf(zephir_log, "[ERROR] ");
191 | for(i=0;i ");
209 | zephir_vdump(param TSRMLS_CC);
210 | return SUCCESS;
211 | }
212 |
213 | int zephir_debug_vdump(char *preffix, zval *value TSRMLS_DC){
214 | zephir_debug_space();
215 | fprintf(zephir_log, "%s", preffix);
216 | zephir_vdump(value TSRMLS_CC);
217 | return SUCCESS;
218 | }
219 |
220 | int zephir_debug_assign(char *name, zval *value TSRMLS_DC){
221 | zephir_debug_space();
222 | fprintf(zephir_log, "Assign on %s with ", name);
223 | zephir_vdump(value TSRMLS_CC);
224 | return SUCCESS;
225 | }
226 |
227 | int zephir_step_over(char *message){
228 | zephir_debug_screen(message);
229 | return SUCCESS;
230 | }
231 |
232 | int zephir_step_into(char *message){
233 | zephir_debug_trace++;
234 | zephir_debug_screen(message);
235 | return SUCCESS;
236 | }
237 |
238 | int zephir_step_out(char *message){
239 | zephir_debug_screen(message);
240 | zephir_debug_trace--;
241 | return SUCCESS;
242 | }
243 |
244 | /**
245 | * Prints internal debug backtrace
246 | */
247 | int zephir_debug_backtrace_internal(){
248 | int step = 0;
249 | char *message;
250 | zephir_debug_entry *ptr = active;
251 | while(ptr){
252 | zephir_spprintf(&message, 0, "#%d %s::%s", step, ptr->class_name, ptr->method_name);
253 | zephir_debug_screen(message);
254 | efree(message);
255 | ptr = ptr->prev;
256 | step++;
257 | }
258 | return SUCCESS;
259 | }
260 |
261 | /**
262 | * Appends a debug entry to internal execution scope
263 | */
264 | int zephir_step_into_entry(char *class_name, char *method_name, int lineno){
265 |
266 | char *message;
267 | zephir_debug_entry *entry;
268 |
269 | if (!start) {
270 | start = (zephir_debug_entry *) emalloc(sizeof(zephir_debug_entry));
271 | start->class_name = "__main__";
272 | start->method_name = "__init__";
273 | start->lineno = 0;
274 | start->prev = NULL;
275 | start->next = NULL;
276 | active = start;
277 | }
278 |
279 | zephir_spprintf(&message, 0, "Step Into %s::%s", class_name, method_name);
280 | zephir_debug_screen(message);
281 | efree(message);
282 |
283 | entry = emalloc(sizeof(zephir_debug_entry));
284 | entry->class_name = class_name;
285 | entry->method_name = method_name;
286 | entry->lineno = lineno;
287 | entry->prev = active;
288 | active->next = entry;
289 | active = entry;
290 | zephir_debug_trace++;
291 |
292 | return SUCCESS;
293 | }
294 |
295 | /**
296 | * Steps out current stack
297 | */
298 | int zephir_step_out_entry(){
299 |
300 | char *message;
301 | zephir_debug_entry *prev;
302 | if(active){
303 |
304 | zephir_debug_trace--;
305 |
306 | zephir_spprintf(&message, 0, "Step out %s::%s", active->class_name, active->method_name);
307 | zephir_debug_screen(message);
308 | efree(message);
309 |
310 | prev = active->prev;
311 | efree(active);
312 | active = prev;
313 |
314 | } else {
315 | fprintf(zephir_log, "Problem, stack?");
316 | return FAILURE;
317 | }
318 | return SUCCESS;
319 | }
320 |
321 | #endif
322 |
--------------------------------------------------------------------------------
/ext/kernel/debug.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
20 | #ifndef ZEPHIR_KERNEL_DEBUG_H
21 | #define ZEPHIR_KERNEL_DEBUG_H
22 |
23 | #ifndef ZEPHIR_RELEASE
24 |
25 | #include
26 |
27 | #define PHV(v) zephir_vdump(v)
28 | #define PHPR(v) zephir_print_r(v)
29 |
30 | typedef struct _zephir_debug_entry {
31 | struct _zephir_debug_entry *prev;
32 | struct _zephir_debug_entry *next;
33 | char *class_name;
34 | char *method_name;
35 | int lineno;
36 | } zephir_debug_entry;
37 |
38 | int zephir_start_debug();
39 | int zephir_stop_debug();
40 |
41 | int zephir_print_r(zval *userval TSRMLS_DC);
42 | int zephir_vdump(zval *uservar TSRMLS_DC);
43 | int zephir_debug_assign(char *name, zval *value TSRMLS_DC);
44 | int zephir_vpdump(const zval **uservar TSRMLS_DC);
45 | int zephir_dump_ce(zend_class_entry *ce TSRMLS_DC);
46 | int zephir_class_debug(zval *val TSRMLS_DC);
47 |
48 | int zephir_debug_backtrace_internal();
49 | int zephir_debug_str(char *what, char *message);
50 | int zephir_debug_long(char *what, uint vlong);
51 | int zephir_debug_screen(char *message);
52 |
53 | int zephir_step_over(char *message);
54 | int zephir_step_into(char *message);
55 | int zephir_step_out(char *message);
56 |
57 | int zephir_step_into_entry(char *class_name, char *method_name, int lineno);
58 | int zephir_step_out_entry();
59 |
60 | int zephir_debug_method_call(zval *obj, char *method_name TSRMLS_DC);
61 | int zephir_debug_vdump(char *preffix, zval *value TSRMLS_DC);
62 | int zephir_debug_param(zval *param TSRMLS_DC);
63 |
64 | int zephir_error_space();
65 | int zephir_debug_space();
66 |
67 | #endif
68 | #endif
--------------------------------------------------------------------------------
/ext/kernel/exception.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifdef HAVE_CONFIG_H
22 | #include "config.h"
23 | #endif
24 |
25 | #include "php.h"
26 | #include "php_ext.h"
27 | #include "php_main.h"
28 | #include "ext/standard/php_string.h"
29 |
30 | #include "kernel/main.h"
31 | #include "kernel/memory.h"
32 | #include "kernel/fcall.h"
33 | #include "kernel/operators.h"
34 |
35 | #include "Zend/zend_exceptions.h"
36 |
37 | /**
38 | * Throws a zval object as exception
39 | */
40 | void zephir_throw_exception(zval *object TSRMLS_DC){
41 | Z_ADDREF_P(object);
42 | zend_throw_exception_object(object TSRMLS_CC);
43 | }
44 |
45 | /**
46 | * Throws a zval object as exception
47 | */
48 | void zephir_throw_exception_debug(zval *object, const char *file, zend_uint line TSRMLS_DC) {
49 |
50 | zend_class_entry *default_exception_ce;
51 | int ZEPHIR_LAST_CALL_STATUS = 0;
52 | zval *curline = NULL, *object_copy = NULL;
53 |
54 | ZEPHIR_MM_GROW();
55 |
56 | if (Z_TYPE_P(object) != IS_OBJECT) {
57 | object_copy = object;
58 | ALLOC_INIT_ZVAL(object);
59 | object_init_ex(object, zend_exception_get_default(TSRMLS_C));
60 | ZEPHIR_CALL_METHOD(NULL, object, "__construct", NULL, 0, object_copy);
61 | }
62 |
63 | Z_ADDREF_P(object);
64 |
65 | if (line > 0) {
66 | curline = 0;
67 | ZEPHIR_CALL_METHOD(&curline, object, "getline", NULL, 0);
68 | zephir_check_call_status();
69 | if (ZEPHIR_IS_LONG(curline, 0)) {
70 | default_exception_ce = zend_exception_get_default(TSRMLS_C);
71 | zend_update_property_string(default_exception_ce, object, "file", sizeof("file") - 1, file TSRMLS_CC);
72 | zend_update_property_long(default_exception_ce, object, "line", sizeof("line") - 1, line TSRMLS_CC);
73 | }
74 | }
75 |
76 | zend_throw_exception_object(object TSRMLS_CC);
77 | ZEPHIR_MM_RESTORE();
78 | }
79 |
80 | /**
81 | * Throws an exception with a single string parameter + debug info
82 | */
83 | void zephir_throw_exception_string_debug(zend_class_entry *ce, const char *message, zend_uint message_len, const char *file, zend_uint line TSRMLS_DC) {
84 |
85 | zval *object, *msg;
86 | int ZEPHIR_LAST_CALL_STATUS = 0;
87 | zend_class_entry *default_exception_ce;
88 |
89 | ALLOC_INIT_ZVAL(object);
90 | object_init_ex(object, ce);
91 |
92 | ALLOC_INIT_ZVAL(msg);
93 | ZVAL_STRINGL(msg, message, message_len, 1);
94 |
95 | ZEPHIR_CALL_METHOD(NULL, object, "__construct", NULL, 0, msg);
96 | zephir_check_call_status();
97 |
98 | if (line > 0) {
99 | default_exception_ce = zend_exception_get_default(TSRMLS_C);
100 | zend_update_property_string(default_exception_ce, object, "file", sizeof("file")-1, file TSRMLS_CC);
101 | zend_update_property_long(default_exception_ce, object, "line", sizeof("line")-1, line TSRMLS_CC);
102 | }
103 |
104 | zend_throw_exception_object(object TSRMLS_CC);
105 |
106 | zval_ptr_dtor(&msg);
107 | }
108 |
109 | /**
110 | * Throws an exception with a single string parameter
111 | */
112 | void zephir_throw_exception_string(zend_class_entry *ce, const char *message, zend_uint message_len TSRMLS_DC){
113 |
114 | zval *object, *msg;
115 | int ZEPHIR_LAST_CALL_STATUS = 0;
116 |
117 | ALLOC_INIT_ZVAL(object);
118 | object_init_ex(object, ce);
119 |
120 | ALLOC_INIT_ZVAL(msg);
121 | ZVAL_STRINGL(msg, message, message_len, 1);
122 |
123 | ZEPHIR_CALL_METHOD(NULL, object, "__construct", NULL, 0, msg);
124 | zephir_check_call_status();
125 |
126 | zend_throw_exception_object(object TSRMLS_CC);
127 |
128 | zval_ptr_dtor(&msg);
129 | }
130 |
131 | /**
132 | * Throws an exception with a string format as parameter
133 | */
134 | void zephir_throw_exception_format(zend_class_entry *ce TSRMLS_DC, const char *format, ...) {
135 |
136 | zval *object, *msg;
137 | int ZEPHIR_LAST_CALL_STATUS = 0, len;
138 | char *buffer;
139 | va_list args;
140 |
141 | ALLOC_INIT_ZVAL(object);
142 | object_init_ex(object, ce);
143 |
144 | va_start(args, format);
145 | len = vspprintf(&buffer, 0, format, args);
146 | va_end(args);
147 |
148 | ALLOC_INIT_ZVAL(msg);
149 | ZVAL_STRINGL(msg, buffer, len, 0);
150 |
151 | ZEPHIR_CALL_METHOD(NULL, object, "__construct", NULL, 0, msg);
152 | zephir_check_call_status();
153 |
154 | zend_throw_exception_object(object TSRMLS_CC);
155 |
156 | zval_ptr_dtor(&msg);
157 | }
158 |
159 | /**
160 | * Throws an exception with a single zval parameter
161 | */
162 | void zephir_throw_exception_zval_debug(zend_class_entry *ce, zval *message, const char *file, zend_uint line TSRMLS_DC){
163 |
164 | zval *object;
165 | int ZEPHIR_LAST_CALL_STATUS = 0;
166 | zend_class_entry *default_exception_ce;
167 |
168 | ALLOC_INIT_ZVAL(object);
169 | object_init_ex(object, ce);
170 |
171 | ZEPHIR_CALL_METHOD(NULL, object, "__construct", NULL, 0, message);
172 | zephir_check_call_status();
173 |
174 | if (line > 0) {
175 | default_exception_ce = zend_exception_get_default(TSRMLS_C);
176 | zend_update_property_string(default_exception_ce, object, "file", sizeof("file")-1, file TSRMLS_CC);
177 | zend_update_property_long(default_exception_ce, object, "line", sizeof("line")-1, line TSRMLS_CC);
178 | }
179 |
180 | zend_throw_exception_object(object TSRMLS_CC);
181 | }
182 |
183 | /**
184 | * Throws an exception with a single zval parameter
185 | */
186 | void zephir_throw_exception_zval(zend_class_entry *ce, zval *message TSRMLS_DC){
187 |
188 | zval *object;
189 | int ZEPHIR_LAST_CALL_STATUS = 0;
190 |
191 | ALLOC_INIT_ZVAL(object);
192 | object_init_ex(object, ce);
193 |
194 | ZEPHIR_CALL_METHOD(NULL, object, "__construct", NULL, 0, message);
195 | zephir_check_call_status();
196 |
197 | zend_throw_exception_object(object TSRMLS_CC);
198 | }
199 |
--------------------------------------------------------------------------------
/ext/kernel/exception.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_EXCEPTIONS_H
22 | #define ZEPHIR_KERNEL_EXCEPTIONS_H
23 |
24 | #include
25 | #include "kernel/main.h"
26 |
27 | /** Exceptions */
28 | #define ZEPHIR_THROW_EXCEPTION_STR(class_entry, message) \
29 | do { \
30 | zephir_throw_exception_string(class_entry, message, strlen(message) TSRMLS_CC); \
31 | ZEPHIR_MM_RESTORE(); \
32 | } while (0)
33 |
34 | #define ZEPHIR_THROW_EXCEPTION_DEBUG_STR(class_entry, message, file, line) \
35 | do { \
36 | zephir_throw_exception_string_debug(class_entry, message, strlen(message), file, line TSRMLS_CC); \
37 | ZEPHIR_MM_RESTORE(); \
38 | } while (0)
39 |
40 | #define ZEPHIR_THROW_EXCEPTION_ZVAL(class_entry, message) \
41 | do { \
42 | zephir_throw_exception_zval(class_entry, message TSRMLS_CC); \
43 | ZEPHIR_MM_RESTORE(); \
44 | } while (0)
45 |
46 | #define ZEPHIR_THROW_EXCEPTION_DEBUG_ZVAL(class_entry, message, file, line) \
47 | do { \
48 | zephir_throw_exception_zval(class_entry, message, file, line TSRMLS_CC); \
49 | ZEPHIR_MM_RESTORE(); \
50 | } while (0)
51 |
52 |
53 | #define ZEPHIR_THROW_EXCEPTION_DEBUG_STRW(class_entry, message, file, line) zephir_throw_exception_string_debug(class_entry, message, strlen(message), file, line TSRMLS_CC)
54 | #define ZEPHIR_THROW_EXCEPTION_STRW(class_entry, message) zephir_throw_exception_string(class_entry, message, strlen(message) TSRMLS_CC)
55 | #define ZEPHIR_THROW_EXCEPTION_ZVALW(class_entry, message) zephir_throw_exception_zval(class_entry, message TSRMLS_CC)
56 | #define ZEPHIR_THROW_EXCEPTION_DEBUG_ZVALW(class_entry, message, file, line) zephir_throw_exception_zval_debug(class_entry, message, file, line TSRMLS_CC)
57 |
58 | /** Throw Exceptions */
59 | void zephir_throw_exception(zval *object TSRMLS_DC);
60 | void zephir_throw_exception_debug(zval *object, const char *file, zend_uint line TSRMLS_DC);
61 | void zephir_throw_exception_string_debug(zend_class_entry *ce, const char *message, zend_uint message_len, const char *file, zend_uint line TSRMLS_DC);
62 | void zephir_throw_exception_string(zend_class_entry *ce, const char *message, zend_uint message_len TSRMLS_DC);
63 | void zephir_throw_exception_zval(zend_class_entry *ce, zval *message TSRMLS_DC);
64 | void zephir_throw_exception_zval_debug(zend_class_entry *ce, zval *message, const char *file, zend_uint line TSRMLS_DC);
65 | void zephir_throw_exception_format(zend_class_entry *ce TSRMLS_DC, const char *format, ...);
66 |
67 | #endif /* ZEPHIR_KERNEL_EXCEPTIONS_H */
68 |
--------------------------------------------------------------------------------
/ext/kernel/exit.c:
--------------------------------------------------------------------------------
1 | /*
2 | +------------------------------------------------------------------------+
3 | | Zephir Language |
4 | +------------------------------------------------------------------------+
5 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
6 | +------------------------------------------------------------------------+
7 | | This source file is subject to the New BSD License that is bundled |
8 | | with this package in the file docs/LICENSE.txt. |
9 | | |
10 | | If you did not receive a copy of the license and are unable to |
11 | | obtain it through the world-wide-web, please send an email |
12 | | to license@zephir-lang.com so we can send you a copy immediately. |
13 | +------------------------------------------------------------------------+
14 | | Authors: Song Yeung |
15 | +------------------------------------------------------------------------+
16 | */
17 |
18 | #ifdef HAVE_CONFIG_H
19 | #include "config.h"
20 | #endif
21 |
22 | #include "php.h"
23 | #include "php_ext.h"
24 | #include "php_main.h"
25 |
26 | #include "kernel/main.h"
27 | #include "kernel/exit.h"
28 |
29 | void zephir_exit_empty() {
30 | TSRMLS_FETCH();
31 | zend_bailout();
32 | }
33 |
34 | void zephir_exit(zval *ptr) {
35 | TSRMLS_FETCH();
36 | if (Z_TYPE_P(ptr) == IS_LONG) {
37 | EG(exit_status) = Z_LVAL_P(ptr);
38 | } else {
39 | zend_print_variable(ptr);
40 | }
41 | zephir_exit_empty();
42 | }
43 |
--------------------------------------------------------------------------------
/ext/kernel/exit.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Song Yeung |
16 | +------------------------------------------------------------------------+
17 | */
18 |
19 | #ifndef ZEPHIR_KERNEL_EXIT_H
20 | #define ZEPHIR_KERNEL_EXIT_H
21 |
22 | #include
23 |
24 | void zephir_exit_empty();
25 | void zephir_exit(zval *ptr);
26 |
27 | #endif
28 |
--------------------------------------------------------------------------------
/ext/kernel/extended/array.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
--------------------------------------------------------------------------------
/ext/kernel/extended/array.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
--------------------------------------------------------------------------------
/ext/kernel/extended/fcall.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | +------------------------------------------------------------------------+
17 | */
18 |
19 | #ifndef ZEPHIR_KERNEL_FCALL_EXT_H
20 | #define ZEPHIR_KERNEL_FCALL_EXT_H
21 |
22 | #define ZEPHIR_FCALL_TYPE_UNKNOWN 0
23 | #define ZEPHIR_FCALL_TYPE_FUNC 1
24 | #define ZEPHIR_FCALL_TYPE_ZVAL_METHOD 2
25 | #define ZEPHIR_FCALL_TYPE_CLASS_PARENT_METHOD 3
26 | #define ZEPHIR_FCALL_TYPE_CLASS_SELF_METHOD 4
27 | #define ZEPHIR_FCALL_TYPE_CLASS_STATIC_METHOD 5
28 | #define ZEPHIR_FCALL_TYPE_CE_METHOD 6
29 |
30 | typedef struct _zephir_fcall_info {
31 | int type;
32 | zend_class_entry *ce;
33 | zval *object_ptr;
34 | const char *class_name;
35 | int class_length;
36 | const char *func_name;
37 | int func_length;
38 | } zephir_fcall_info;
39 |
40 | int zephir_call_function_opt(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache, zephir_fcall_info *info TSRMLS_DC);
41 | int zephir_call_func_aparams_fast(zval **return_value_ptr, zephir_fcall_cache_entry **cache_entry, uint param_count, zval **params TSRMLS_DC);
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/ext/kernel/file.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
20 | #ifndef ZEPHIR_KERNEL_FILE_H
21 | #define ZEPHIR_KERNEL_FILE_H
22 |
23 | #include
24 |
25 | int zephir_file_exists(zval *filename TSRMLS_DC);
26 | int zephir_compare_mtime(zval *filename1, zval *filename2 TSRMLS_DC);
27 | void zephir_fix_path(zval **return_value, zval *path, zval *directory_separator TSRMLS_DC);
28 | void zephir_prepare_virtual_path(zval *return_value, zval *path, zval *virtual_separator TSRMLS_DC);
29 | void zephir_unique_path_key(zval *return_value, zval *path TSRMLS_DC);
30 | void zephir_realpath(zval *return_value, zval *filename TSRMLS_DC);
31 | void zephir_file_get_contents(zval *return_value, zval *filename TSRMLS_DC);
32 | void zephir_file_put_contents(zval *return_value, zval *filename, zval *data TSRMLS_DC);
33 | void zephir_possible_autoload_filepath(zval *return_value, zval *prefix, zval *class_name, zval *virtual_separator, zval *separator TSRMLS_DC);
34 |
35 | void zephir_is_dir(zval *return_value, zval *path TSRMLS_DC);
36 | void zephir_unlink(zval *return_value, zval *path TSRMLS_DC);
37 | void zephir_filemtime(zval *return_value, zval *path TSRMLS_DC);
38 | void zephir_basename(zval *return_value, zval *path TSRMLS_DC);
39 |
40 | void zephir_fwrite(zval *return_value, zval *stream_zval, zval *data TSRMLS_DC);
41 | int zephir_feof(zval *stream_zval TSRMLS_DC);
42 | int zephir_fclose(zval *stream_zval TSRMLS_DC);
43 |
44 | #ifdef TSRM_WIN32
45 | #define ZEPHIR_DIRECTORY_SEPARATOR "\\"
46 | #else
47 | #define ZEPHIR_DIRECTORY_SEPARATOR "/"
48 | #endif
49 |
50 | #endif /* ZEPHIR_KERNEL_FILE_H */
51 |
--------------------------------------------------------------------------------
/ext/kernel/filter.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
20 | #ifdef HAVE_CONFIG_H
21 | #include "config.h"
22 | #endif
23 |
24 | #include
25 |
26 | #include "php.h"
27 | #include "php_ext.h"
28 | #include "php_main.h"
29 | #include "ext/standard/php_smart_str.h"
30 | #include "ext/standard/php_math.h"
31 | #include "ext/standard/html.h"
32 |
33 | #include "kernel/main.h"
34 | #include "kernel/memory.h"
35 |
36 | #include "Zend/zend_exceptions.h"
37 | #include "Zend/zend_interfaces.h"
38 |
39 | /**
40 | * Filter alphanum string
41 | */
42 | void zephir_filter_alphanum(zval *return_value, zval *param) {
43 |
44 | unsigned int i;
45 | unsigned char ch;
46 | smart_str filtered_str = {0};
47 | zval copy;
48 | int use_copy = 0;
49 |
50 | if (Z_TYPE_P(param) != IS_STRING) {
51 | zend_make_printable_zval(param, ©, &use_copy);
52 | if (use_copy) {
53 | param = ©
54 | }
55 | }
56 |
57 | for (i = 0; i < Z_STRLEN_P(param); i++) {
58 | ch = Z_STRVAL_P(param)[i];
59 | if (ch == '\0') {
60 | break;
61 | }
62 | if (isalnum(ch)) {
63 | smart_str_appendc(&filtered_str, ch);
64 | }
65 | }
66 |
67 | if (use_copy) {
68 | zval_dtor(param);
69 | }
70 |
71 | smart_str_0(&filtered_str);
72 |
73 | if (filtered_str.c) {
74 | RETURN_STRINGL(filtered_str.c, filtered_str.len, 0);
75 | } else {
76 | RETURN_EMPTY_STRING();
77 | }
78 | }
79 |
80 | /**
81 | * Filter identifiers string like variables or database columns/tables
82 | */
83 | void zephir_filter_identifier(zval *return_value, zval *param){
84 |
85 | unsigned int i;
86 | unsigned char ch;
87 | zval copy;
88 | smart_str filtered_str = {0};
89 | int use_copy = 0;
90 |
91 | if (Z_TYPE_P(param) != IS_STRING) {
92 | zend_make_printable_zval(param, ©, &use_copy);
93 | if (use_copy) {
94 | param = ©
95 | }
96 | }
97 |
98 | for (i = 0; i < Z_STRLEN_P(param); i++) {
99 | ch = Z_STRVAL_P(param)[i];
100 | if (ch == '\0') {
101 | break;
102 | }
103 | if (isalnum(ch) || ch == '_') {
104 | smart_str_appendc(&filtered_str, ch);
105 | }
106 | }
107 |
108 | if (use_copy) {
109 | zval_dtor(param);
110 | }
111 |
112 | smart_str_0(&filtered_str);
113 |
114 | if (filtered_str.c) {
115 | RETURN_STRINGL(filtered_str.c, filtered_str.len, 0);
116 | } else {
117 | RETURN_EMPTY_STRING();
118 | }
119 |
120 | }
121 |
122 | /**
123 | * Check if a string is encoded with ASCII or ISO-8859-1
124 | */
125 | void zephir_is_basic_charset(zval *return_value, const zval *param){
126 |
127 | unsigned int i;
128 | unsigned int ch;
129 | int iso88591 = 0;
130 |
131 | for (i = 0; i < Z_STRLEN_P(param); i++) {
132 | ch = Z_STRVAL_P(param)[i];
133 | if (ch != '\0') {
134 | if (ch == 172 || (ch >= 128 && ch <= 159)) {
135 | continue;
136 | }
137 | if (ch >= 160 && ch <= 255) {
138 | iso88591 = 1;
139 | continue;
140 | }
141 | }
142 | RETURN_FALSE;
143 | }
144 |
145 | if (!iso88591) {
146 | RETURN_STRING("ASCII", 1);
147 | }
148 |
149 | RETURN_STRING("ISO-8859-1", 1);
150 | }
151 |
152 | static long zephir_unpack(char *data, int size, int issigned, int *map)
153 | {
154 | long result;
155 | char *cresult = (char *) &result;
156 | int i;
157 |
158 | result = issigned ? -1 : 0;
159 |
160 | for (i = 0; i < size; i++) {
161 | cresult[map[i]] = *data++;
162 | }
163 |
164 | return result;
165 | }
166 |
167 | /**
168 | * Converts an unsigned long to a char*
169 | */
170 | static inline char *zephir_longtohex(unsigned long value) {
171 |
172 | static char digits[] = "0123456789abcdef";
173 | char buf[(sizeof(unsigned long) << 3) + 1];
174 | char *ptr, *end;
175 |
176 | end = ptr = buf + sizeof(buf) - 1;
177 | *ptr = '\0';
178 | do {
179 | *--ptr = digits[value & 0x0F];
180 | value >>= 4;
181 | } while (ptr > buf && value);
182 |
183 | return estrndup(ptr, end - ptr);
184 | }
185 |
186 | /**
187 | * Perform escaping of non-alphanumeric characters to different formats
188 | */
189 | void zephir_escape_multi(zval *return_value, zval *param, const char *escape_char, unsigned int escape_length, char escape_extra, int use_whitelist) {
190 |
191 | unsigned int i;
192 | zval copy;
193 | smart_str escaped_str = {0};
194 | char machine_little_endian, *hex;
195 | int big_endian_long_map[4];
196 | int use_copy = 0, machine_endian_check = 1;
197 | int issigned = 0;
198 | long value;
199 |
200 | if (Z_TYPE_P(param) != IS_STRING) {
201 | zend_make_printable_zval(param, ©, &use_copy);
202 | if (use_copy) {
203 | param = ©
204 | }
205 | }
206 |
207 | if (Z_STRLEN_P(param) <= 0) {
208 | RETURN_FALSE;
209 | }
210 |
211 | /**
212 | * This is how the big_ending_long_map is calculated as in 'pack'
213 | */
214 | machine_little_endian = ((char *) &machine_endian_check)[0];
215 | if (machine_little_endian) {
216 | big_endian_long_map[0] = 3;
217 | big_endian_long_map[1] = 2;
218 | big_endian_long_map[2] = 1;
219 | big_endian_long_map[3] = 0;
220 | } else {
221 | int size = sizeof(Z_LVAL_P(param));
222 | big_endian_long_map[0] = size - 4;
223 | big_endian_long_map[1] = size - 3;
224 | big_endian_long_map[2] = size - 2;
225 | big_endian_long_map[3] = size - 1;
226 | }
227 |
228 | /**
229 | * The input must be a valid UTF-32 string
230 | */
231 | if ((Z_STRLEN_P(param) % 4) != 0) {
232 | RETURN_FALSE;
233 | }
234 |
235 | for (i = 0; i < Z_STRLEN_P(param); i += 4) {
236 |
237 | issigned = Z_STRVAL_P(param)[i] & 0x80;
238 |
239 | value = 0;
240 | if (sizeof(long) > 4 && issigned) {
241 | value = ~INT_MAX;
242 | }
243 |
244 | value |= zephir_unpack(&Z_STRVAL_P(param)[i], 4, issigned, big_endian_long_map);
245 | if (sizeof(long) > 4) {
246 | value = (unsigned int) value;
247 | }
248 |
249 | /**
250 | * CSS 2.1 section 4.1.3: "It is undefined in CSS 2.1 what happens if a
251 | * style sheet does contain a character with Unicode codepoint zero."
252 | */
253 | if (value == '\0') {
254 | RETURN_FALSE;
255 | }
256 |
257 | /**
258 | * Alphanumeric characters are not escaped
259 | */
260 | if (value < 256 && isalnum(value)) {
261 | smart_str_appendc(&escaped_str, (unsigned char) value);
262 | continue;
263 | }
264 |
265 | /**
266 | * Chararters in the whitelist are left as they are
267 | */
268 | if (use_whitelist) {
269 | switch (value) {
270 | case ' ':
271 | case '/':
272 | case '*':
273 | case '+':
274 | case '-':
275 | case '\t':
276 | case '\n':
277 | case '^':
278 | case '$':
279 | case '!':
280 | case '?':
281 | case '\\':
282 | case '#':
283 | case '}':
284 | case '{':
285 | case ')':
286 | case '(':
287 | case ']':
288 | case '[':
289 | case '.':
290 | case ',':
291 | case ':':
292 | case ';':
293 | case '_':
294 | case '|':
295 | smart_str_appendc(&escaped_str, (unsigned char) value);
296 | continue;
297 | }
298 | }
299 |
300 | /**
301 | * Convert character to hexadecimal
302 | */
303 | hex = zephir_longtohex(value);
304 |
305 | /**
306 | * Append the escaped character
307 | */
308 | smart_str_appendl(&escaped_str, escape_char, escape_length);
309 | smart_str_appendl(&escaped_str, hex, strlen(hex));
310 | if (escape_extra != '\0') {
311 | smart_str_appendc(&escaped_str, escape_extra);
312 | }
313 |
314 | efree(hex);
315 | }
316 |
317 | if (use_copy) {
318 | zval_dtor(param);
319 | }
320 |
321 | smart_str_0(&escaped_str);
322 |
323 | if (escaped_str.c) {
324 | RETURN_STRINGL(escaped_str.c, escaped_str.len, 0);
325 | } else {
326 | RETURN_EMPTY_STRING();
327 | }
328 |
329 | }
330 |
331 | /**
332 | * Escapes non-alphanumeric characters to \HH+space
333 | */
334 | void zephir_escape_css(zval *return_value, zval *param) {
335 | zephir_escape_multi(return_value, param, "\\", sizeof("\\")-1, ' ', 0);
336 | }
337 |
338 | /**
339 | * Escapes non-alphanumeric characters to \xHH+
340 | */
341 | void zephir_escape_js(zval *return_value, zval *param) {
342 | zephir_escape_multi(return_value, param, "\\x", sizeof("\\x")-1, '\0', 1);
343 | }
344 |
345 | /**
346 | * Escapes non-alphanumeric characters to &xHH;
347 | */
348 | void zephir_escape_htmlattr(zval *return_value, zval *param) {
349 | zephir_escape_multi(return_value, param, "", sizeof("")-1, ';', 1);
350 | }
351 |
352 | /**
353 | * Escapes HTML replacing special chars by entities
354 | */
355 | void zephir_escape_html(zval *return_value, zval *str, zval *quote_style, zval *charset TSRMLS_DC) {
356 |
357 | #if PHP_VERSION_ID < 50400
358 | int length;
359 | #else
360 | size_t length;
361 | #endif
362 |
363 | char *escaped;
364 |
365 | if (Z_TYPE_P(str) != IS_STRING) {
366 | /* Nothing to escape */
367 | RETURN_ZVAL(str, 1, 0);
368 | }
369 |
370 | if (Z_TYPE_P(quote_style) != IS_LONG) {
371 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid quote_style supplied for zephir_escape_html()");
372 | RETURN_ZVAL(str, 1, 0);
373 | }
374 |
375 | if (Z_TYPE_P(charset) != IS_STRING) {
376 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid charset supplied for zephir_escape_html()");
377 | RETURN_ZVAL(str, 1, 0);
378 | }
379 |
380 | escaped = php_escape_html_entities((unsigned char*) Z_STRVAL_P(str), Z_STRLEN_P(str), &length, 0, Z_LVAL_P(quote_style), Z_STRVAL_P(charset) TSRMLS_CC);
381 |
382 | RETURN_STRINGL(escaped, length, 0);
383 | }
384 |
--------------------------------------------------------------------------------
/ext/kernel/filter.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
20 | #ifndef ZEPHIR_KERNEL_FILTER_H
21 | #define ZEPHIR_KERNEL_FILTER_H
22 |
23 | #include
24 |
25 | /** Low level filters */
26 | void zephir_filter_alphanum(zval *return_value, zval *param);
27 | void zephir_filter_identifier(zval *return_value, zval *param);
28 |
29 | /** Encoding */
30 | void zephir_is_basic_charset(zval *return_value, const zval *param);
31 |
32 | /** Escaping */
33 | void zephir_escape_css(zval *return_value, zval *param);
34 | void zephir_escape_js(zval *return_value, zval *param);
35 | void zephir_escape_htmlattr(zval *return_value, zval *param);
36 | void zephir_escape_html(zval *return_value, zval *str, zval *quote_style, zval *charset TSRMLS_DC);
37 |
38 | #endif
--------------------------------------------------------------------------------
/ext/kernel/globals.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_GLOBALS_H
22 | #define ZEPHIR_KERNEL_GLOBALS_H
23 |
24 | #include
25 |
26 | #define ZEPHIR_MAX_MEMORY_STACK 48
27 | #define ZEPHIR_MAX_CACHE_SLOTS 512
28 |
29 | /** Memory frame */
30 | typedef struct _zephir_memory_entry {
31 | size_t pointer;
32 | size_t capacity;
33 | zval ***addresses;
34 | size_t hash_pointer;
35 | size_t hash_capacity;
36 | zval ***hash_addresses;
37 | struct _zephir_memory_entry *prev;
38 | struct _zephir_memory_entry *next;
39 | #ifndef ZEPHIR_RELEASE
40 | int permanent;
41 | const char *func;
42 | #endif
43 | } zephir_memory_entry;
44 |
45 | /** Virtual Symbol Table */
46 | typedef struct _zephir_symbol_table {
47 | struct _zephir_memory_entry *scope;
48 | HashTable *symbol_table;
49 | struct _zephir_symbol_table *prev;
50 | } zephir_symbol_table;
51 |
52 | typedef struct _zephir_function_cache {
53 | zend_class_entry *ce;
54 | zend_function *func;
55 | } zephir_function_cache;
56 |
57 | #ifndef ZEPHIR_RELEASE
58 |
59 | typedef struct _zephir_fcall_cache_entry {
60 | zend_function *f;
61 | zend_uint times;
62 | } zephir_fcall_cache_entry;
63 |
64 | #else
65 |
66 | typedef zend_function zephir_fcall_cache_entry;
67 |
68 | #endif
69 |
70 | #if PHP_VERSION_ID >= 50400
71 | #define ZEPHIR_INIT_FUNCS(class_functions) static const zend_function_entry class_functions[] =
72 | #else
73 | #define ZEPHIR_INIT_FUNCS(class_functions) static const function_entry class_functions[] =
74 | #endif
75 |
76 | #ifndef PHP_FE_END
77 | #define PHP_FE_END { NULL, NULL, NULL, 0, 0 }
78 | #endif
79 |
80 | /** Define FASTCALL */
81 | #if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__)
82 | # define ZEPHIR_FASTCALL __attribute__((fastcall))
83 | #elif defined(_MSC_VER) && defined(_M_IX86)
84 | # define ZEPHIR_FASTCALL __fastcall
85 | #else
86 | # define ZEPHIR_FASTCALL
87 | #endif
88 |
89 | #define ZEPHIR_INIT_CLASS(name) \
90 | int zephir_ ##name## _init(INIT_FUNC_ARGS)
91 |
92 | #define ZEPHIR_INIT(name) \
93 | if (zephir_ ##name## _init(INIT_FUNC_ARGS_PASSTHRU) == FAILURE) { \
94 | return FAILURE; \
95 | }
96 |
97 | /* Compatibility macros for PHP 5.3 */
98 | #ifndef PHP_FE_END
99 | #define PHP_FE_END { NULL, NULL, NULL, 0, 0 }
100 | #endif
101 |
102 | #ifndef INIT_PZVAL_COPY
103 | #define INIT_PZVAL_COPY(z, v) \
104 | ZVAL_COPY_VALUE(z, v); \
105 | Z_SET_REFCOUNT_P(z, 1); \
106 | Z_UNSET_ISREF_P(z);
107 | #endif
108 |
109 | #ifndef ZVAL_COPY_VALUE
110 | #define ZVAL_COPY_VALUE(z, v) \
111 | (z)->value = (v)->value; \
112 | Z_TYPE_P(z) = Z_TYPE_P(v);
113 | #endif
114 |
115 | #ifndef HASH_KEY_NON_EXISTENT
116 | # define HASH_KEY_NON_EXISTENT HASH_KEY_NON_EXISTANT
117 | #endif
118 |
119 | /** Macros for branch prediction */
120 | #define likely(x) EXPECTED(x)
121 | #define unlikely(x) UNEXPECTED(x)
122 |
123 | #if defined(__GNUC__) && (defined(__clang__) || ((__GNUC__ * 100 + __GNUC_MINOR__) >= 405))
124 | # define UNREACHABLE() __builtin_unreachable()
125 | # define ASSUME(x) if (x) {} else __builtin_unreachable()
126 | #else
127 | # define UNREACHABLE() assert(0)
128 | # define ASSUME(x) assert(!!(x));
129 | #endif
130 |
131 | #if defined(__GNUC__) || defined(__clang__)
132 | # define ZEPHIR_ATTR_NONNULL __attribute__((nonnull))
133 | # define ZEPHIR_ATTR_NONNULL1(x) __attribute__((nonnull (x)))
134 | # define ZEPHIR_ATTR_NONNULL2(x, y) __attribute__((nonnull (x, y)))
135 | # define ZEPHIR_ATTR_NONNULL3(x, y, z) __attribute__((nonnull (x, y, z)))
136 | # define ZEPHIR_ATTR_PURE __attribute__((pure))
137 | # define ZEPHIR_ATTR_CONST __attribute__((const))
138 | # define ZEPHIR_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
139 | #else
140 | # define ZEPHIR_ATTR_NONNULL
141 | # define ZEPHIR_ATTR_NONNULL1(x)
142 | # define ZEPHIR_ATTR_NONNULL2(x, y)
143 | # define ZEPHIR_ATTR_NONNULL3(x, y, z)
144 | # define ZEPHIR_ATTR_PURE
145 | # define ZEPHIR_ATTR_CONST
146 | # define ZEPHIR_ATTR_WARN_UNUSED_RESULT
147 | #endif
148 |
149 | #if !defined(__GNUC__) && !(defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
150 | # define __builtin_constant_p(s) (0)
151 | #endif
152 |
153 | #ifndef ZEND_MOD_END
154 | # define ZEND_MOD_END { NULL, NULL, NULL, 0 }
155 | #endif
156 |
157 | #ifndef __func__
158 | # define __func__ __FUNCTION__
159 | #endif
160 |
161 | #if defined(__GNUC__)
162 | # define ZEPHIR_NO_OPT __attribute__((optimize("O0")))
163 | #else
164 | # define ZEPHIR_NO_OPT
165 | #endif
166 |
167 | /*#if PHP_VERSION_ID > 50399
168 | # define ZLK_DC , const struct _zend_literal* key
169 | # define ZLK_CC , key
170 | # define ZLK_NULL_CC , NULL
171 | #else
172 | # define ZLK_DC
173 | # define ZLK_CC
174 | # define ZLK_NULL_CC
175 | #endif*/
176 |
177 | #ifdef ZTS
178 | #define zephir_nts_static
179 | #else
180 | #define zephir_nts_static
181 | #endif
182 |
183 | #define ZEPHIR_STATIC
184 |
185 | #endif
186 |
--------------------------------------------------------------------------------
/ext/kernel/hash.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifdef HAVE_CONFIG_H
22 | #include "config.h"
23 | #endif
24 |
25 | #include "php.h"
26 | #include "php_ext.h"
27 | #include
28 |
29 | #include "kernel/memory.h"
30 |
31 | #if PHP_VERSION_ID < 70000
32 |
33 | int zephir_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent)
34 | {
35 | #if PHP_VERSION_ID < 50400
36 | Bucket **tmp;
37 | #endif
38 |
39 | if (nSize >= 0x80000000) {
40 | ht->nTableSize = 0x80000000;
41 | } else {
42 | if (nSize > 3) {
43 | ht->nTableSize = nSize + (nSize >> 2);
44 | } else {
45 | ht->nTableSize = 3;
46 | }
47 | }
48 |
49 | #if ZEND_DEBUG
50 | ht->inconsistent = 0;
51 | #endif
52 |
53 | #if PHP_VERSION_ID < 50400
54 | ht->nTableMask = ht->nTableSize - 1;
55 | #else
56 | ht->nTableMask = 0; /* 0 means that ht->arBuckets is uninitialized */
57 | #endif
58 | ht->pDestructor = pDestructor;
59 | ht->arBuckets = NULL;
60 | ht->pListHead = NULL;
61 | ht->pListTail = NULL;
62 | ht->nNumOfElements = 0;
63 | ht->nNextFreeElement = 0;
64 | ht->pInternalPointer = NULL;
65 | ht->persistent = persistent;
66 | ht->nApplyCount = 0;
67 | ht->bApplyProtection = 1;
68 |
69 | #if PHP_VERSION_ID < 50400
70 | /* Uses ecalloc() so that Bucket* == NULL */
71 | if (persistent) {
72 | tmp = (Bucket **) calloc(ht->nTableSize, sizeof(Bucket *));
73 | if (!tmp) {
74 | return FAILURE;
75 | }
76 | ht->arBuckets = tmp;
77 | } else {
78 | tmp = (Bucket **) ecalloc_rel(ht->nTableSize, sizeof(Bucket *));
79 | if (tmp) {
80 | ht->arBuckets = tmp;
81 | }
82 | }
83 | #endif
84 |
85 | return SUCCESS;
86 | }
87 |
88 | #else
89 |
90 | void zephir_hash_init(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent)
91 | {
92 | #if ZEND_DEBUG
93 | ht->inconsistent = 0;
94 | #endif
95 |
96 | if (nSize >= 0x80000000) {
97 | ht->nTableSize = 0x80000000;
98 | } else {
99 | if (nSize > 3) {
100 | ht->nTableSize = nSize + (nSize >> 2);
101 | } else {
102 | ht->nTableSize = 3;
103 | }
104 | }
105 |
106 | ht->nTableMask = 0; /* 0 means that ht->arBuckets is uninitialized */
107 | ht->nNumUsed = 0;
108 | ht->nNumOfElements = 0;
109 | ht->nNextFreeElement = 0;
110 | ht->arData = NULL;
111 | ht->arHash = (zend_uint*)&uninitialized_bucket;
112 | ht->pDestructor = pDestructor;
113 | ht->nInternalPointer = INVALID_IDX;
114 | if (persistent) {
115 | ht->u.flags = HASH_FLAG_PERSISTENT | HASH_FLAG_APPLY_PROTECTION;
116 | } else {
117 | ht->u.flags = HASH_FLAG_APPLY_PROTECTION;
118 | }
119 | }
120 |
121 | #endif
122 |
123 |
124 | int zephir_hash_exists(const HashTable *ht, const char *arKey, uint nKeyLength)
125 | {
126 | ulong h;
127 | uint nIndex;
128 | Bucket *p;
129 |
130 | h = zend_inline_hash_func(arKey, nKeyLength);
131 | nIndex = h & ht->nTableMask;
132 |
133 | p = ht->arBuckets[nIndex];
134 | while (p != NULL) {
135 | if (p->arKey == arKey || ((p->h == h) && (p->nKeyLength == nKeyLength))) {
136 | if (!memcmp(p->arKey, arKey, nKeyLength)) {
137 | return 1;
138 | }
139 | }
140 | p = p->pNext;
141 | }
142 | return 0;
143 | }
144 |
145 | int zephir_hash_quick_exists(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h)
146 | {
147 | uint nIndex;
148 | Bucket *p;
149 |
150 | if (nKeyLength == 0) {
151 | return zend_hash_index_exists(ht, h);
152 | }
153 |
154 | nIndex = h & ht->nTableMask;
155 |
156 | p = ht->arBuckets[nIndex];
157 | while (p != NULL) {
158 | if (p->arKey == arKey || ((p->h == h) && (p->nKeyLength == nKeyLength))) {
159 | if (!memcmp(p->arKey, arKey, nKeyLength)) {
160 | return 1;
161 | }
162 | }
163 | p = p->pNext;
164 | }
165 | return 0;
166 | }
167 |
168 | int zephir_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData)
169 | {
170 | ulong h;
171 | uint nIndex;
172 | Bucket *p;
173 |
174 | h = zend_inline_hash_func(arKey, nKeyLength);
175 | nIndex = h & ht->nTableMask;
176 |
177 | p = ht->arBuckets[nIndex];
178 | while (p != NULL) {
179 | if (p->arKey == arKey || ((p->h == h) && (p->nKeyLength == nKeyLength))) {
180 | if (!memcmp(p->arKey, arKey, nKeyLength)) {
181 | *pData = p->pData;
182 | return SUCCESS;
183 | }
184 | }
185 | p = p->pNext;
186 | }
187 | return FAILURE;
188 | }
189 |
190 | int zephir_hash_quick_find(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h, void **pData)
191 | {
192 | uint nIndex;
193 | Bucket *p;
194 |
195 | if (nKeyLength == 0) {
196 | return zend_hash_index_find(ht, h, pData);
197 | }
198 |
199 | nIndex = h & ht->nTableMask;
200 |
201 | p = ht->arBuckets[nIndex];
202 | while (p != NULL) {
203 | if (p->arKey == arKey || ((p->h == h) && (p->nKeyLength == nKeyLength))) {
204 | if (!memcmp(p->arKey, arKey, nKeyLength)) {
205 | *pData = p->pData;
206 | return SUCCESS;
207 | }
208 | }
209 | p = p->pNext;
210 | }
211 | return FAILURE;
212 | }
213 |
214 | /**
215 | * Assigns the current value in a hash traversing to a zval
216 | */
217 | void zephir_get_current_key(zval **key, const HashTable *hash_table, HashPosition *hash_position TSRMLS_DC)
218 | {
219 | Bucket *p;
220 |
221 | ZEPHIR_INIT_NVAR_PNULL(*key);
222 |
223 | p = hash_position ? (*hash_position) : hash_table->pInternalPointer;
224 |
225 | if (p) {
226 | if (p->nKeyLength) {
227 | ZVAL_STRINGL(*key, (char *) p->arKey, p->nKeyLength - 1, 0);
228 | } else {
229 | ZVAL_LONG(*key, p->h);
230 | }
231 | }
232 |
233 | }
234 |
235 | zval zephir_get_current_key_w(const HashTable *hash_table, HashPosition *hash_position)
236 | {
237 | Bucket *p;
238 | zval result;
239 |
240 | INIT_ZVAL(result);
241 | p = hash_position ? (*hash_position) : hash_table->pInternalPointer;
242 |
243 | if (p) {
244 | if (p->nKeyLength) {
245 | ZVAL_STRINGL(&result, (char *) p->arKey, p->nKeyLength - 1, 0);
246 | } else {
247 | ZVAL_LONG(&result, p->h);
248 | }
249 | }
250 |
251 | return result;
252 | }
253 |
254 | /**
255 | * Traverses the hash checking if at least one of the keys is numeric
256 | */
257 | int zephir_has_numeric_keys(const zval *data)
258 | {
259 | HashTable *ht;
260 |
261 | if (Z_TYPE_P(data) == IS_ARRAY) {
262 |
263 | ht = Z_ARRVAL_P(data);
264 |
265 | ht->pInternalPointer = ht->pListHead;
266 | while (ht->pInternalPointer) {
267 | if (!ht->pInternalPointer->nKeyLength) {
268 | return 1;
269 | }
270 | ht->pInternalPointer = ht->pInternalPointer->pListNext;
271 | }
272 |
273 | }
274 |
275 | return 0;
276 | }
277 |
278 | /**
279 | * @brief Adds or updates item @a key in the hash table @a ht
280 | * @param ht Hash table
281 | * @param[in] key Key
282 | * @param[in] value Value
283 | * @note @a value's reference count in not updated
284 | * @note If @a key is @c NULL or is @c IS_NULL, @a value is appended to @a ht
285 | * @throw E_WARNING if @a key type is not supported
286 | */
287 | void zephir_hash_update_or_insert(HashTable *ht, zval *key, zval *value)
288 | {
289 | if (!key || Z_TYPE_P(key) == IS_NULL) {
290 | zend_hash_next_index_insert(ht, (void**)&value, sizeof(zval*), NULL);
291 | return;
292 | }
293 |
294 | switch (Z_TYPE_P(key)) {
295 | case IS_STRING:
296 | zend_symtable_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key)+1, (void**)&value, sizeof(zval*), NULL);
297 | return;
298 |
299 | case IS_RESOURCE:
300 | case IS_DOUBLE:
301 | case IS_BOOL:
302 | case IS_LONG:
303 | zend_hash_index_update(ht, ((Z_TYPE_P(key) == IS_DOUBLE) ? (ulong)Z_DVAL_P(key) : Z_LVAL_P(key)), (void*)&value, sizeof(zval*), NULL);
304 | return;
305 |
306 | default:
307 | zend_error(E_WARNING, "Illegal offset type");
308 | return;
309 | }
310 | }
311 |
312 | /**
313 | * @brief Returns the entry @a ht identified by @a key
314 | * @param[in] ht Hash table
315 | * @param[in] key
316 | * @param[in] type One of @c BP_VAR_XXX values
317 | * @return Pointer to the stored value or a pointer to the special variable / @c NULL if @a key was not found
318 | * @retval &EG(error_zval_ptr) when @a key was not found and @a type is one of @c BP_VAR_W, @c BP_VAR_RW
319 | * @retval &EG(uninitialized_zval_ptr) when @a key was not found and @a type is one of @c BP_VAR_R, @c BP_VAR_UNSET, @c BP_VAR_IS
320 | * @retval @c NULL when @a key was not found and @a type is not any of the above
321 | * @throw @c E_WARNING when @a key is of not supported typel in this case the function never returns @c NULL
322 | * @throw @c E_STRICT when @a key is a resource
323 | * @throw @c E_NOTICE if @a key was not found and @a type is @c BP_VAR_R or @c BP_VAR_RW
324 | * @note Reference count of the returned item is not modified
325 | * @note The implementation is suitable for @c read_property, @c get_property_ptr_ptr and @c read_dimension object handlers
326 | * @warning If @a type is @c BP_VAR_W or @c BP_VAR_RW and @a key was not found, it is added to @a ht and its value is set to @c IS_NULL
327 | */
328 | zval** zephir_hash_get(HashTable *ht, zval *key, int type)
329 | {
330 | zval **ret = NULL;
331 |
332 | switch (Z_TYPE_P(key)) {
333 | case IS_RESOURCE:
334 | zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(key), Z_LVAL_P(key));
335 | /* no break */
336 | case IS_LONG:
337 | case IS_DOUBLE:
338 | case IS_BOOL: {
339 | ulong index = (Z_TYPE_P(key) == IS_DOUBLE) ? ((long int)Z_DVAL_P(key)) : Z_LVAL_P(key);
340 | if (FAILURE == zend_hash_index_find(ht, index, (void**)&ret)) {
341 | switch (type) {
342 | case BP_VAR_R:
343 | zend_error(E_NOTICE, "Undefined offset: %ld", index);
344 | /* no break */
345 | case BP_VAR_UNSET:
346 | case BP_VAR_IS: {
347 | TSRMLS_FETCH();
348 | ret = &EG(uninitialized_zval_ptr);
349 | break;
350 | }
351 |
352 | case BP_VAR_RW:
353 | zend_error(E_NOTICE, "Undefined offset: %ld", index);
354 | /* no break */
355 | case BP_VAR_W: {
356 | zval *value;
357 | ALLOC_INIT_ZVAL(value);
358 | zend_hash_index_update(ht, index, (void**)&value, sizeof(void*), (void**)&ret);
359 | break;
360 | }
361 | }
362 | }
363 |
364 | return ret;
365 | }
366 |
367 | case IS_STRING:
368 | if (FAILURE == zend_symtable_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key)+1, (void**)&ret)) {
369 | switch (type) {
370 | case BP_VAR_R:
371 | zend_error(E_NOTICE, "Undefined offset: %s", Z_STRVAL_P(key));
372 | /* no break */
373 | case BP_VAR_UNSET:
374 | case BP_VAR_IS: {
375 | TSRMLS_FETCH();
376 | ret = &EG(uninitialized_zval_ptr);
377 | break;
378 | }
379 |
380 | case BP_VAR_RW:
381 | zend_error(E_NOTICE, "Undefined offset: %s", Z_STRVAL_P(key));
382 | /* no break */
383 | case BP_VAR_W: {
384 | zval *value;
385 | ALLOC_INIT_ZVAL(value);
386 | zend_symtable_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key)+1, (void**)&value, sizeof(void*), (void**)&ret);
387 | break;
388 | }
389 | }
390 | }
391 |
392 | return ret;
393 |
394 | default: {
395 | TSRMLS_FETCH();
396 | zend_error(E_WARNING, "Illegal offset type");
397 | return (type == BP_VAR_W || type == BP_VAR_RW) ? &EG(error_zval_ptr) : &EG(uninitialized_zval_ptr);
398 | }
399 | }
400 | }
401 |
402 | /**
403 | * @brief Unset @a key from @a ht
404 | * @param ht
405 | * @param key
406 | * @return
407 | */
408 | int zephir_hash_unset(HashTable *ht, zval *key)
409 | {
410 | switch (Z_TYPE_P(key)) {
411 | case IS_LONG:
412 | case IS_DOUBLE:
413 | case IS_BOOL:
414 | case IS_RESOURCE:
415 | return (zend_hash_index_del(ht, (Z_TYPE_P(key) == IS_DOUBLE) ? ((long int)Z_DVAL_P(key)) : Z_LVAL_P(key)) == SUCCESS);
416 |
417 | case IS_STRING:
418 | return (zend_symtable_del(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1) == SUCCESS);
419 |
420 | default:
421 | zend_error(E_WARNING, "Illegal offset type");
422 | return 0;
423 | }
424 | }
425 |
--------------------------------------------------------------------------------
/ext/kernel/hash.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_HASH_H
22 | #define ZEPHIR_KERNEL_HASH_H
23 |
24 | #include
25 | #include
26 | #include
27 |
28 | #if PHP_VERSION_ID < 70000
29 | int zephir_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent);
30 | #else
31 | void zephir_hash_init(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent);
32 | #endif
33 |
34 | int zephir_hash_exists(const HashTable *ht, const char *arKey, uint nKeyLength);
35 | int zephir_hash_quick_exists(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h);
36 | int zephir_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
37 | int zephir_hash_quick_find(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h, void **pData);
38 | void zephir_get_current_key(zval **key, const HashTable *hash_table, HashPosition *hash_position TSRMLS_DC);
39 | zval zephir_get_current_key_w(const HashTable *hash_table, HashPosition *hash_position);
40 | int zephir_has_numeric_keys(const zval *data);
41 | void zephir_hash_update_or_insert(HashTable *ht, zval *offset, zval *value);
42 | zval** zephir_hash_get(HashTable *ht, zval *key, int type);
43 | int zephir_hash_unset(HashTable *ht, zval *offset);
44 |
45 | #define zephir_hash_move_forward_ex(ht, pos) *pos = (*pos ? (*pos)->pListNext : NULL)
46 |
47 | #if PHP_VERSION_ID < 70000
48 |
49 | static zend_always_inline int zephir_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos)
50 | {
51 | Bucket *p;
52 | p = pos ? (*pos) : ht->pInternalPointer;
53 | if (p) {
54 | *pData = p->pData;
55 | return SUCCESS;
56 | } else {
57 | return FAILURE;
58 | }
59 | }
60 |
61 | #else
62 |
63 | static zend_always_inline zval *zephir_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
64 | {
65 | uint idx = *pos;
66 | Bucket *p;
67 |
68 | IS_CONSISTENT(ht);
69 | if (idx != INVALID_IDX) {
70 | p = ht->arData + idx;
71 | return &p->val;
72 | } else {
73 | return NULL;
74 | }
75 | }
76 |
77 | #endif
78 |
79 | static zend_always_inline int zephir_hash_move_backwards_ex(HashTable *ht, HashPosition *pos)
80 | {
81 | #if PHP_VERSION_ID < 70000
82 | HashPosition *current = pos ? pos : &ht->pInternalPointer;
83 | if (*current) {
84 | *current = (*current)->pListLast;
85 | return SUCCESS;
86 | } else {
87 | return FAILURE;
88 | }
89 | #else
90 | uint idx = *pos;
91 |
92 | IS_CONSISTENT(ht);
93 |
94 | if (idx != INVALID_IDX) {
95 | while (idx > 0) {
96 | idx--;
97 | if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
98 | *pos = idx;
99 | return SUCCESS;
100 | }
101 | }
102 | *pos = INVALID_IDX;
103 | return SUCCESS;
104 | } else {
105 | return FAILURE;
106 | }
107 | #endif
108 | }
109 |
110 | #endif
111 |
--------------------------------------------------------------------------------
/ext/kernel/iterator.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifdef HAVE_CONFIG_H
22 | #include "config.h"
23 | #endif
24 |
25 | #include "php.h"
26 | #include "php_ext.h"
27 |
28 | #include "kernel/main.h"
29 | #include "kernel/memory.h"
30 |
31 | /**
32 | * Returns an iterator from the object
33 | */
34 | zend_object_iterator *zephir_get_iterator(zval *iterator TSRMLS_DC) {
35 |
36 | zend_class_entry *ce;
37 | zend_object_iterator *it;
38 |
39 | if (Z_TYPE_P(iterator) != IS_OBJECT) {
40 | return NULL;
41 | }
42 |
43 | ce = Z_OBJCE_P(iterator);
44 | it = ce->get_iterator(ce, iterator, 0 TSRMLS_CC);
45 | if (!it || EG(exception)) {
46 | return NULL;
47 | }
48 |
49 | if (it->funcs->get_current_key == NULL) {
50 | return NULL;
51 | }
52 |
53 | if (it->funcs->rewind == NULL) {
54 | return NULL;
55 | }
56 |
57 | return it;
58 | }
59 |
--------------------------------------------------------------------------------
/ext/kernel/iterator.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_ITERATOR_H
22 | #define ZEPHIR_KERNEL_ITERATOR_H
23 |
24 | #include
25 | #include
26 |
27 | zend_object_iterator *zephir_get_iterator(zval *iterator TSRMLS_DC);
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/ext/kernel/main.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
20 | #ifdef HAVE_CONFIG_H
21 | #include "config.h"
22 | #endif
23 |
24 | #include "php.h"
25 | #include "php_ext.h"
26 | #include "php_main.h"
27 | #include "ext/spl/spl_exceptions.h"
28 |
29 | #include "kernel/main.h"
30 | #include "kernel/memory.h"
31 | #include "kernel/fcall.h"
32 | #include "kernel/exception.h"
33 |
34 | #include "Zend/zend_exceptions.h"
35 | #include "Zend/zend_interfaces.h"
36 |
37 | /**
38 | * Initializes internal interface with extends
39 | */
40 | zend_class_entry *zephir_register_internal_interface_ex(zend_class_entry *orig_ce, zend_class_entry *parent_ce TSRMLS_DC) {
41 |
42 | zend_class_entry *ce;
43 |
44 | ce = zend_register_internal_interface(orig_ce TSRMLS_CC);
45 | if (parent_ce) {
46 | zend_do_inheritance(ce, parent_ce TSRMLS_CC);
47 | }
48 |
49 | return ce;
50 | }
51 |
52 | /**
53 | * Initilializes super global variables if doesn't
54 | */
55 | int zephir_init_global(char *global, unsigned int global_length TSRMLS_DC) {
56 |
57 | #if PHP_VERSION_ID < 50400
58 | zend_bool jit_initialization = (PG(auto_globals_jit) && !PG(register_globals) && !PG(register_long_arrays));
59 | if (jit_initialization) {
60 | return zend_is_auto_global(global, global_length - 1 TSRMLS_CC);
61 | }
62 | #else
63 | if (PG(auto_globals_jit)) {
64 | return zend_is_auto_global(global, global_length - 1 TSRMLS_CC);
65 | }
66 | #endif
67 |
68 | return SUCCESS;
69 | }
70 |
71 | /**
72 | * Gets the global zval into PG macro
73 | */
74 | int zephir_get_global(zval **arr, const char *global, unsigned int global_length TSRMLS_DC) {
75 |
76 | zval **gv;
77 |
78 | zend_bool jit_initialization = PG(auto_globals_jit);
79 | if (jit_initialization) {
80 | zend_is_auto_global(global, global_length - 1 TSRMLS_CC);
81 | }
82 |
83 | if (&EG(symbol_table)) {
84 | if (zend_hash_find(&EG(symbol_table), global, global_length, (void **) &gv) == SUCCESS) {
85 | if (Z_TYPE_PP(gv) == IS_ARRAY) {
86 | *arr = *gv;
87 | if (!*arr) {
88 | ZEPHIR_INIT_VAR(*arr);
89 | array_init(*arr);
90 | }
91 | } else {
92 | ZEPHIR_INIT_VAR(*arr);
93 | array_init(*arr);
94 | }
95 | return SUCCESS;
96 | }
97 | }
98 |
99 | ZEPHIR_INIT_VAR(*arr);
100 | array_init(*arr);
101 |
102 | return SUCCESS;
103 | }
104 |
105 | /**
106 | * Makes fast count on implicit array types
107 | */
108 | void zephir_fast_count(zval *result, zval *value TSRMLS_DC) {
109 |
110 | if (Z_TYPE_P(value) == IS_ARRAY) {
111 | ZVAL_LONG(result, zend_hash_num_elements(Z_ARRVAL_P(value)));
112 | return;
113 | }
114 |
115 | if (Z_TYPE_P(value) == IS_OBJECT) {
116 |
117 | #ifdef HAVE_SPL
118 | zval *retval = NULL;
119 | #endif
120 |
121 | if (Z_OBJ_HT_P(value)->count_elements) {
122 | ZVAL_LONG(result, 1);
123 | if (SUCCESS == Z_OBJ_HT(*value)->count_elements(value, &Z_LVAL_P(result) TSRMLS_CC)) {
124 | return;
125 | }
126 | }
127 |
128 | #ifdef HAVE_SPL
129 | if (Z_OBJ_HT_P(value)->get_class_entry && instanceof_function(Z_OBJCE_P(value), spl_ce_Countable TSRMLS_CC)) {
130 | zend_call_method_with_0_params(&value, NULL, NULL, "count", &retval);
131 | if (retval) {
132 | convert_to_long_ex(&retval);
133 | ZVAL_LONG(result, Z_LVAL_P(retval));
134 | zval_ptr_dtor(&retval);
135 | }
136 | return;
137 | }
138 | #endif
139 |
140 | ZVAL_LONG(result, 0);
141 | return;
142 | }
143 |
144 | if (Z_TYPE_P(value) == IS_NULL) {
145 | ZVAL_LONG(result, 0);
146 | return;
147 | }
148 |
149 | ZVAL_LONG(result, 1);
150 | }
151 |
152 | /**
153 | * Makes fast count on implicit array types without creating a return zval value
154 | */
155 | int zephir_fast_count_ev(zval *value TSRMLS_DC) {
156 |
157 | long count = 0;
158 |
159 | if (Z_TYPE_P(value) == IS_ARRAY) {
160 | return zend_hash_num_elements(Z_ARRVAL_P(value)) > 0;
161 | }
162 |
163 | if (Z_TYPE_P(value) == IS_OBJECT) {
164 |
165 | #ifdef HAVE_SPL
166 | zval *retval = NULL;
167 | #endif
168 |
169 | if (Z_OBJ_HT_P(value)->count_elements) {
170 | Z_OBJ_HT(*value)->count_elements(value, &count TSRMLS_CC);
171 | return (int) count > 0;
172 | }
173 |
174 | #ifdef HAVE_SPL
175 | if (Z_OBJ_HT_P(value)->get_class_entry && instanceof_function(Z_OBJCE_P(value), spl_ce_Countable TSRMLS_CC)) {
176 | zend_call_method_with_0_params(&value, NULL, NULL, "count", &retval);
177 | if (retval) {
178 | convert_to_long_ex(&retval);
179 | count = Z_LVAL_P(retval);
180 | zval_ptr_dtor(&retval);
181 | return (int) count > 0;
182 | }
183 | return 0;
184 | }
185 | #endif
186 |
187 | return 0;
188 | }
189 |
190 | if (Z_TYPE_P(value) == IS_NULL) {
191 | return 0;
192 | }
193 |
194 | return 1;
195 | }
196 |
197 | /**
198 | * Makes fast count on implicit array types without creating a return zval value
199 | */
200 | int zephir_fast_count_int(zval *value TSRMLS_DC) {
201 |
202 | long count = 0;
203 |
204 | if (Z_TYPE_P(value) == IS_ARRAY) {
205 | return zend_hash_num_elements(Z_ARRVAL_P(value));
206 | }
207 |
208 | if (Z_TYPE_P(value) == IS_OBJECT) {
209 |
210 | #ifdef HAVE_SPL
211 | zval *retval = NULL;
212 | #endif
213 |
214 | if (Z_OBJ_HT_P(value)->count_elements) {
215 | Z_OBJ_HT(*value)->count_elements(value, &count TSRMLS_CC);
216 | return (int) count;
217 | }
218 |
219 | #ifdef HAVE_SPL
220 | if (Z_OBJ_HT_P(value)->get_class_entry && instanceof_function(Z_OBJCE_P(value), spl_ce_Countable TSRMLS_CC)) {
221 | zend_call_method_with_0_params(&value, NULL, NULL, "count", &retval);
222 | if (retval) {
223 | convert_to_long_ex(&retval);
224 | count = Z_LVAL_P(retval);
225 | zval_ptr_dtor(&retval);
226 | return (int) count;
227 | }
228 | return 0;
229 | }
230 | #endif
231 |
232 | return 0;
233 | }
234 |
235 | if (Z_TYPE_P(value) == IS_NULL) {
236 | return 0;
237 | }
238 |
239 | return 1;
240 | }
241 |
242 | /**
243 | * Check if a function exists
244 | */
245 | int zephir_function_exists(const zval *function_name TSRMLS_DC) {
246 |
247 | return zephir_function_quick_exists_ex(
248 | Z_STRVAL_P(function_name),
249 | Z_STRLEN_P(function_name) + 1,
250 | zend_inline_hash_func(Z_STRVAL_P(function_name), Z_STRLEN_P(function_name) + 1) TSRMLS_CC
251 | );
252 | }
253 |
254 | /**
255 | * Check if a function exists using explicit char param
256 | *
257 | * @param function_name
258 | * @param function_len strlen(function_name)+1
259 | */
260 | int zephir_function_exists_ex(const char *function_name, unsigned int function_len TSRMLS_DC) {
261 |
262 | return zephir_function_quick_exists_ex(function_name, function_len, zend_inline_hash_func(function_name, function_len) TSRMLS_CC);
263 | }
264 |
265 | /**
266 | * Check if a function exists using explicit char param (using precomputed hash key)
267 | */
268 | int zephir_function_quick_exists_ex(const char *method_name, unsigned int method_len, unsigned long key TSRMLS_DC) {
269 |
270 | if (zend_hash_quick_exists(CG(function_table), method_name, method_len, key)) {
271 | return SUCCESS;
272 | }
273 |
274 | return FAILURE;
275 | }
276 |
277 | /**
278 | * Checks if a zval is callable
279 | */
280 | int zephir_is_callable(zval *var TSRMLS_DC) {
281 |
282 | char *error = NULL;
283 | zend_bool retval;
284 |
285 | retval = zend_is_callable_ex(var, NULL, 0, NULL, NULL, NULL, &error TSRMLS_CC);
286 | if (error) {
287 | efree(error);
288 | }
289 |
290 | return (int) retval;
291 | }
292 |
293 | /**
294 | * Initialize an array to start an iteration over it
295 | */
296 | int zephir_is_iterable_ex(zval *arr, HashTable **arr_hash, HashPosition *hash_position, int duplicate, int reverse) {
297 |
298 | if (unlikely(Z_TYPE_P(arr) != IS_ARRAY)) {
299 | return 0;
300 | }
301 |
302 | if (duplicate) {
303 | ALLOC_HASHTABLE(*arr_hash);
304 | zend_hash_init(*arr_hash, 0, NULL, NULL, 0);
305 | zend_hash_copy(*arr_hash, Z_ARRVAL_P(arr), NULL, NULL, sizeof(zval*));
306 | } else {
307 | *arr_hash = Z_ARRVAL_P(arr);
308 | }
309 |
310 | if (reverse) {
311 | if (hash_position) {
312 | *hash_position = (*arr_hash)->pListTail;
313 | } else {
314 | (*arr_hash)->pInternalPointer = (*arr_hash)->pListTail;
315 | }
316 | } else {
317 | if (hash_position) {
318 | *hash_position = (*arr_hash)->pListHead;
319 | } else {
320 | (*arr_hash)->pInternalPointer = (*arr_hash)->pListHead;
321 | }
322 | }
323 |
324 | return 1;
325 | }
326 |
327 | void zephir_safe_zval_ptr_dtor(zval *pzval)
328 | {
329 | if (pzval) {
330 | zval_ptr_dtor(&pzval);
331 | }
332 | }
333 |
334 | /**
335 | * Parses method parameters with minimum overhead
336 | */
337 | int zephir_fetch_parameters(int num_args TSRMLS_DC, int required_args, int optional_args, ...)
338 | {
339 | va_list va;
340 | int arg_count = (int) (zend_uintptr_t) *(zend_vm_stack_top(TSRMLS_C) - 1);
341 | zval **arg, **p;
342 | int i;
343 |
344 | if (num_args < required_args || (num_args > (required_args + optional_args))) {
345 | zephir_throw_exception_string(spl_ce_BadMethodCallException, SL("Wrong number of parameters") TSRMLS_CC);
346 | return FAILURE;
347 | }
348 |
349 | if (num_args > arg_count) {
350 | zephir_throw_exception_string(spl_ce_BadMethodCallException, SL("Could not obtain parameters for parsing") TSRMLS_CC);
351 | return FAILURE;
352 | }
353 |
354 | if (!num_args) {
355 | return SUCCESS;
356 | }
357 |
358 | va_start(va, optional_args);
359 |
360 | i = 0;
361 | while (num_args-- > 0) {
362 |
363 | arg = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count - i));
364 |
365 | p = va_arg(va, zval **);
366 | *p = *arg;
367 |
368 | i++;
369 | }
370 |
371 | va_end(va);
372 |
373 | return SUCCESS;
374 | }
375 |
376 | /**
377 | * Returns the type of a variable as a string
378 | */
379 | void zephir_gettype(zval *return_value, zval *arg TSRMLS_DC) {
380 |
381 | switch (Z_TYPE_P(arg)) {
382 |
383 | case IS_NULL:
384 | RETVAL_STRING("NULL", 1);
385 | break;
386 |
387 | case IS_BOOL:
388 | RETVAL_STRING("boolean", 1);
389 | break;
390 |
391 | case IS_LONG:
392 | RETVAL_STRING("integer", 1);
393 | break;
394 |
395 | case IS_DOUBLE:
396 | RETVAL_STRING("double", 1);
397 | break;
398 |
399 | case IS_STRING:
400 | RETVAL_STRING("string", 1);
401 | break;
402 |
403 | case IS_ARRAY:
404 | RETVAL_STRING("array", 1);
405 | break;
406 |
407 | case IS_OBJECT:
408 | RETVAL_STRING("object", 1);
409 | break;
410 |
411 | case IS_RESOURCE:
412 | {
413 | const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_P(arg) TSRMLS_CC);
414 |
415 | if (type_name) {
416 | RETVAL_STRING("resource", 1);
417 | break;
418 | }
419 | }
420 |
421 | default:
422 | RETVAL_STRING("unknown type", 1);
423 | }
424 | }
425 |
426 | zend_class_entry* zephir_get_internal_ce(const char *class_name, unsigned int class_name_len TSRMLS_DC) {
427 | zend_class_entry** temp_ce;
428 |
429 | if (zend_hash_find(CG(class_table), class_name, class_name_len, (void **)&temp_ce) == FAILURE) {
430 | zend_error(E_ERROR, "Class '%s' not found", class_name);
431 | return NULL;
432 | }
433 |
434 | return *temp_ce;
435 | }
436 |
--------------------------------------------------------------------------------
/ext/kernel/math.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
20 | #ifdef HAVE_CONFIG_H
21 | #include "config.h"
22 | #endif
23 |
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include "php_ext.h"
30 | #include "kernel/main.h"
31 | #include "kernel/memory.h"
32 | #include "kernel/string.h"
33 | #include "kernel/operators.h"
34 |
35 | #include "Zend/zend_operators.h"
36 |
37 | double zephir_floor(zval *op1 TSRMLS_DC)
38 | {
39 | switch (Z_TYPE_P(op1)) {
40 | case IS_LONG:
41 | return (double) Z_LVAL_P(op1);
42 | case IS_ARRAY:
43 | case IS_OBJECT:
44 | case IS_RESOURCE:
45 | zend_error(E_WARNING, "Unsupported operand types");
46 | break;
47 | }
48 | return floor(zephir_get_numberval(op1));
49 | }
50 |
51 |
52 | double zephir_ceil(zval *op1 TSRMLS_DC)
53 | {
54 | switch (Z_TYPE_P(op1)) {
55 | case IS_LONG:
56 | return (double) Z_LVAL_P(op1);
57 | case IS_ARRAY:
58 | case IS_OBJECT:
59 | case IS_RESOURCE:
60 | zend_error(E_WARNING, "Unsupported operand types");
61 | break;
62 | }
63 | return ceil(zephir_get_numberval(op1));
64 | }
65 |
66 | extern double _php_math_round(double value, int places, int mode);
67 |
68 | void zephir_round(zval *return_value, zval *op1, zval *op2, zval *op3 TSRMLS_DC)
69 | {
70 | int places = 0;
71 | long mode = PHP_ROUND_HALF_UP;
72 | double return_val;
73 |
74 | convert_scalar_to_number_ex(&op1);
75 |
76 | if (op2) {
77 | places = zephir_get_intval_ex(op2);
78 | }
79 | if (op3) {
80 | mode = zephir_get_intval_ex(op3);
81 | }
82 |
83 | switch (Z_TYPE_PP(&op1)) {
84 | case IS_LONG:
85 | /* Simple case - long that doesn't need to be rounded. */
86 | if (places >= 0) {
87 | RETURN_DOUBLE((double) Z_LVAL_PP(&op1));
88 | }
89 | /* break omitted intentionally */
90 |
91 | case IS_DOUBLE:
92 | return_val = (Z_TYPE_PP(&op1) == IS_LONG) ? (double)Z_LVAL_PP(&op1) : Z_DVAL_PP(&op1);
93 | return_val = _php_math_round(return_val, places, mode);
94 | RETURN_DOUBLE(return_val);
95 | break;
96 |
97 | default:
98 | RETURN_FALSE;
99 | break;
100 | }
101 | }
102 |
103 | #if PHP_VERSION_ID < 50600
104 | #include "Zend/zend_multiply.h"
105 | void zephir_pow_function_ex(zval *return_value, zval *zbase, zval *zexp TSRMLS_DC)
106 | {
107 | /* make sure we're dealing with numbers */
108 | convert_scalar_to_number(zbase TSRMLS_CC);
109 | convert_scalar_to_number(zexp TSRMLS_CC);
110 |
111 | /* if both base and exponent were longs, we'll try to get a long out */
112 | if (Z_TYPE_P(zbase) == IS_LONG && Z_TYPE_P(zexp) == IS_LONG && Z_LVAL_P(zexp) >= 0) {
113 | long l1 = 1, l2 = Z_LVAL_P(zbase), i = Z_LVAL_P(zexp);
114 |
115 | if (i == 0) {
116 | RETURN_LONG(1L);
117 | } else if (l2 == 0) {
118 | RETURN_LONG(0);
119 | }
120 |
121 | /* calculate pow(long,long) in O(log exp) operations, bail if overflow */
122 | while (i >= 1) {
123 | int overflow;
124 | double dval = 0.0;
125 |
126 | if (i % 2) {
127 | --i;
128 | ZEND_SIGNED_MULTIPLY_LONG(l1, l2, l1, dval, overflow);
129 | if (overflow) RETURN_DOUBLE(dval * pow(l2, i));
130 | } else {
131 | i /= 2;
132 | ZEND_SIGNED_MULTIPLY_LONG(l2, l2, l2, dval,overflow);
133 | if (overflow) RETURN_DOUBLE((double)l1 * pow(dval, i));
134 | }
135 | if (i == 0) {
136 | RETURN_LONG(l1);
137 | }
138 | }
139 | }
140 | convert_to_double(zbase);
141 | convert_to_double(zexp);
142 |
143 | RETURN_DOUBLE(pow(Z_DVAL_P(zbase), Z_DVAL_P(zexp)));
144 | }
145 | #endif
146 |
147 | long zephir_mt_rand(long min, long max TSRMLS_DC) {
148 |
149 | long number;
150 |
151 | if (max < min) {
152 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "max(%ld) is smaller than min(%ld)", max, min);
153 | return 0;
154 | }
155 |
156 | if (!BG(mt_rand_is_seeded)) {
157 | php_mt_srand(GENERATE_SEED() TSRMLS_CC);
158 | }
159 |
160 | number = (long) (php_mt_rand(TSRMLS_C) >> 1);
161 | RAND_RANGE(number, min, max, PHP_MT_RAND_MAX);
162 |
163 | return number;
164 | }
165 |
--------------------------------------------------------------------------------
/ext/kernel/math.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
20 | #ifndef ZEPHIR_KERNEL_MATH_H
21 | #define ZEPHIR_KERNEL_MATH_H
22 |
23 | #include
24 | #include
25 |
26 | double zephir_floor(zval *op1 TSRMLS_DC);
27 | double zephir_ceil(zval *op1 TSRMLS_DC);
28 | void zephir_round(zval *return_value, zval *op1, zval *op2, zval *op3 TSRMLS_DC);
29 | void zephir_pow(zval *return_value, zval *op1, zval *op2 TSRMLS_DC);
30 | long zephir_mt_rand(long min, long max TSRMLS_DC);
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/ext/kernel/memory.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_MEMORY_H
22 | #define ZEPHIR_KERNEL_MEMORY_H
23 |
24 | #include
25 | #include
26 | #include "php_ext.h"
27 | #include "kernel/globals.h"
28 |
29 | #define ZEPHIR_NUM_PREALLOCATED_FRAMES 25
30 |
31 | /* Variable Tracking */
32 | void zephir_init_nvar(zval **var TSRMLS_DC);
33 | void zephir_cpy_wrt(zval **dest, zval *var TSRMLS_DC);
34 | void zephir_cpy_wrt_ctor(zval **dest, zval *var TSRMLS_DC);
35 |
36 | void zephir_value_dtor(zval *zvalue ZEND_FILE_LINE_DC);
37 | void ZEND_FASTCALL zephir_ptr_dtor(zval **var);
38 | void ZEND_FASTCALL zephir_dtor(zval *var);
39 |
40 | /* Memory Frames */
41 | #ifndef ZEPHIR_RELEASE
42 | void ZEPHIR_FASTCALL zephir_memory_grow_stack(const char *func TSRMLS_DC);
43 | int ZEPHIR_FASTCALL zephir_memory_restore_stack(const char *func TSRMLS_DC);
44 |
45 | #define ZEPHIR_MM_GROW() zephir_memory_grow_stack(NULL TSRMLS_CC)
46 | #define ZEPHIR_MM_RESTORE() zephir_memory_restore_stack(NULL TSRMLS_CC)
47 |
48 | #else
49 | void ZEPHIR_FASTCALL zephir_memory_grow_stack(TSRMLS_D);
50 | int ZEPHIR_FASTCALL zephir_memory_restore_stack(TSRMLS_D);
51 |
52 | #define ZEPHIR_MM_GROW() zephir_memory_grow_stack(TSRMLS_C)
53 | #define ZEPHIR_MM_RESTORE() zephir_memory_restore_stack(TSRMLS_C)
54 |
55 | #endif
56 |
57 | void ZEPHIR_FASTCALL zephir_memory_observe(zval **var TSRMLS_DC);
58 | void ZEPHIR_FASTCALL zephir_memory_remove(zval **var TSRMLS_DC);
59 | void ZEPHIR_FASTCALL zephir_memory_alloc(zval **var TSRMLS_DC);
60 | void ZEPHIR_FASTCALL zephir_memory_alloc_pnull(zval **var TSRMLS_DC);
61 |
62 | int ZEPHIR_FASTCALL zephir_clean_restore_stack(TSRMLS_D);
63 |
64 | /* Virtual symbol tables */
65 | void zephir_create_symbol_table(TSRMLS_D);
66 | /*void zephir_restore_symbol_table(TSRMLS_D);*/
67 | void zephir_clean_symbol_tables(TSRMLS_D);
68 |
69 | /** Export symbols to active symbol table */
70 | int zephir_set_symbol(zval *key_name, zval *value TSRMLS_DC);
71 | int zephir_set_symbol_str(char *key_name, unsigned int key_length, zval *value TSRMLS_DC);
72 |
73 | void ZEPHIR_FASTCALL zephir_copy_ctor(zval *destiny, zval *origin);
74 |
75 | void zephir_initialize_memory(zend_zephir_globals_def *zephir_globals_ptr TSRMLS_DC);
76 | int zephir_cleanup_fcache(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
77 | void zephir_deinitialize_memory(TSRMLS_D);
78 |
79 | /* Memory macros */
80 | #define ZEPHIR_ALLOC_ZVAL(z) \
81 | ALLOC_INIT_ZVAL(z)
82 |
83 | #define ZEPHIR_SINIT_VAR(z) \
84 | INIT_PZVAL(&z); \
85 | ZVAL_NULL(&z);
86 |
87 | #define ZEPHIR_SINIT_NVAR(z) Z_SET_REFCOUNT_P(&z, 1)
88 |
89 | #define ZEPHIR_INIT_ZVAL_NREF(z) \
90 | ALLOC_ZVAL(z); \
91 | Z_SET_REFCOUNT_P(z, 0); \
92 | Z_UNSET_ISREF_P(z);
93 |
94 | #define ZEPHIR_INIT_VAR(z) \
95 | zephir_memory_alloc(&z TSRMLS_CC)
96 |
97 | #define ZEPHIR_INIT_NVAR(z)\
98 | if (z) { \
99 | if (!Z_ISREF_P(z)) { \
100 | if (Z_REFCOUNT_P(z) > 1) { \
101 | Z_DELREF_P(z); \
102 | ALLOC_ZVAL(z); \
103 | Z_SET_REFCOUNT_P(z, 1); \
104 | Z_UNSET_ISREF_P(z); \
105 | } else { \
106 | zephir_dtor(z); \
107 | Z_SET_REFCOUNT_P(z, 1); \
108 | Z_UNSET_ISREF_P(z); \
109 | } \
110 | ZVAL_NULL(z); \
111 | } \
112 | } else { \
113 | zephir_memory_alloc(&z TSRMLS_CC); \
114 | }
115 |
116 | /**
117 | * Second allocation, assumes the variable was allocated for the first time in the branch zero
118 | */
119 | #define ZEPHIR_INIT_BNVAR(z) \
120 | if (Z_REFCOUNT_P(z) > 1) { \
121 | zephir_ptr_dtor(&z); \
122 | ALLOC_ZVAL(z); \
123 | Z_SET_REFCOUNT_P(z, 1); \
124 | Z_UNSET_ISREF_P(z); \
125 | ZVAL_NULL(z); \
126 | } else {\
127 | zephir_ptr_dtor(&z); \
128 | ZEPHIR_ALLOC_ZVAL(z); \
129 | }
130 |
131 | #define ZEPHIR_INIT_NVAR_PNULL(z)\
132 | if (z) { \
133 | if (Z_REFCOUNT_P(z) > 1) { \
134 | Z_DELREF_P(z); \
135 | if (Z_REFCOUNT_P(z) >= 1) { \
136 | zval_copy_ctor(z); \
137 | } \
138 | ALLOC_ZVAL(z); \
139 | Z_SET_REFCOUNT_P(z, 1); \
140 | Z_UNSET_ISREF_P(z); \
141 | } \
142 | ZVAL_NULL(z); \
143 | } else { \
144 | zephir_memory_alloc_pnull(&z TSRMLS_CC); \
145 | }
146 |
147 | /* only removes the value body of the zval */
148 | #define ZEPHIR_INIT_LNVAR(z)\
149 | if (z) { \
150 | if (Z_REFCOUNT_P(z) > 1) { \
151 | Z_DELREF_P(z); \
152 | ALLOC_ZVAL(z); \
153 | Z_SET_REFCOUNT_P(z, 1); \
154 | Z_UNSET_ISREF_P(z); \
155 | } else { \
156 | if (!Z_ISREF_P(z)) { \
157 | zephir_value_dtor(z ZEND_FILE_LINE_CC); \
158 | } \
159 | Z_SET_REFCOUNT_P(z, 1); \
160 | Z_UNSET_ISREF_P(z); \
161 | } \
162 | ZVAL_NULL(z); \
163 | } else { \
164 | zephir_memory_alloc(&z TSRMLS_CC); \
165 | }
166 |
167 | #define ZEPHIR_CPY_WRT(d, v) \
168 | Z_ADDREF_P(v); \
169 | if (d) { \
170 | if (Z_REFCOUNT_P(d) > 0) { \
171 | zephir_ptr_dtor(&d); \
172 | } \
173 | } else { \
174 | zephir_memory_observe(&d TSRMLS_CC); \
175 | } \
176 | d = v;
177 |
178 | #define ZEPHIR_CPY_WRT_CTOR(d, v) \
179 | if (d) { \
180 | if (Z_REFCOUNT_P(d) > 0) { \
181 | zephir_ptr_dtor(&d); \
182 | } \
183 | } else { \
184 | zephir_memory_observe(&d TSRMLS_CC); \
185 | } \
186 | ALLOC_ZVAL(d); \
187 | *d = *v; \
188 | zval_copy_ctor(d); \
189 | Z_SET_REFCOUNT_P(d, 1); \
190 | Z_UNSET_ISREF_P(d);
191 |
192 | #define ZEPHIR_MAKE_REFERENCE(d, v) \
193 | if (d) { \
194 | if (Z_REFCOUNT_P(d) > 0) { \
195 | zephir_ptr_dtor(&d); \
196 | } \
197 | } else { \
198 | zephir_memory_observe(&d TSRMLS_CC); \
199 | } \
200 | ALLOC_ZVAL(d); \
201 | Z_TYPE_P(d) = Z_TYPE_P(v); \
202 | d->value = v->value; \
203 | Z_SET_REFCOUNT_P(d, 1); \
204 | Z_SET_ISREF_P(d);
205 |
206 | /* */
207 | #define ZEPHIR_OBS_VAR(z) \
208 | zephir_memory_observe(&z TSRMLS_CC)
209 |
210 | #define ZEPHIR_OBS_NVAR(z)\
211 | if (z) { \
212 | if (Z_REFCOUNT_P(z) > 1) { \
213 | Z_DELREF_P(z); \
214 | } else {\
215 | zephir_ptr_dtor(&z); \
216 | z = NULL; \
217 | } \
218 | } else { \
219 | zephir_memory_observe(&z TSRMLS_CC); \
220 | }
221 |
222 | #define ZEPHIR_OBSERVE_OR_NULLIFY_PPZV(ppzv) \
223 | do { \
224 | zval ** restrict tmp_ = (ppzv); \
225 | if (tmp_ != NULL) { \
226 | if (*tmp_) { \
227 | zephir_ptr_dtor(tmp_); \
228 | *tmp_ = NULL; \
229 | } \
230 | else { \
231 | zephir_memory_observe((ppzv) TSRMLS_CC); \
232 | } \
233 | } \
234 | } while (0)
235 |
236 | #define ZEPHIR_OBSERVE_OR_NULLIFY_VAR(z) \
237 | do { \
238 | if (z) { \
239 | zephir_ptr_dtor(&z); \
240 | z = NULL; \
241 | } \
242 | else { \
243 | zephir_memory_observe(&z TSRMLS_CC); \
244 | } \
245 | } while (0)
246 |
247 | #define ZEPHIR_SEPARATE_ARRAY(a) \
248 | { \
249 | if (Z_REFCOUNT_P(a) > 1) { \
250 | zval *new_zv; \
251 | Z_DELREF_P(a); \
252 | ALLOC_ZVAL(new_zv); \
253 | INIT_PZVAL_COPY(new_zv, a); \
254 | a = new_zv; \
255 | zval_copy_ctor(new_zv); \
256 | } \
257 | }
258 |
259 | #define ZEPHIR_SEPARATE(z) SEPARATE_ZVAL(&z)
260 |
261 | #define ZEPHIR_SEPARATE_PARAM(z) \
262 | do { \
263 | zval *orig_ptr = z;\
264 | zephir_memory_observe(&z TSRMLS_CC);\
265 | ALLOC_ZVAL(z);\
266 | *z = *orig_ptr;\
267 | zval_copy_ctor(z);\
268 | Z_SET_REFCOUNT_P(z, 1);\
269 | Z_UNSET_ISREF_P(z);\
270 | } while (0)
271 |
272 | #define ZEPHIR_SEPARATE_PARAM_NMO(z) { \
273 | zval *orig_ptr = z; \
274 | if (Z_REFCOUNT_P(orig_ptr) > 1) { \
275 | ALLOC_ZVAL(z); \
276 | *z = *orig_ptr; \
277 | zval_copy_ctor(z); \
278 | Z_SET_REFCOUNT_P(z, 1); \
279 | Z_UNSET_ISREF_P(z); \
280 | } \
281 | }
282 |
283 | #endif
284 |
--------------------------------------------------------------------------------
/ext/kernel/object.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_OBJECT_H
22 | #define ZEPHIR_KERNEL_OBJECT_H
23 |
24 | #include
25 | #include
26 |
27 | #include "kernel/globals.h"
28 | #include "kernel/main.h"
29 |
30 | /** Class Retrieving/Checking */
31 | int zephir_class_exists(const zval *class_name, int autoload TSRMLS_DC);
32 | int zephir_interface_exists(const zval *interface_name, int autoload TSRMLS_DC);
33 | void zephir_get_class(zval *result, zval *object, int lower TSRMLS_DC);
34 | void zephir_get_class_ns(zval *result, zval *object, int lower TSRMLS_DC);
35 | void zephir_get_ns_class(zval *result, zval *object, int lower TSRMLS_DC);
36 | void zephir_get_called_class(zval *return_value TSRMLS_DC);
37 | zend_class_entry *zephir_fetch_class(const zval *class_name TSRMLS_DC);
38 | zend_class_entry* zephir_fetch_self_class(TSRMLS_D);
39 | zend_class_entry* zephir_fetch_parent_class(TSRMLS_D);
40 | zend_class_entry* zephir_fetch_static_class(TSRMLS_D);
41 |
42 | #define ZEPHIR_GET_CLASS_CONSTANT(return_value, ce, const_name) \
43 | do { \
44 | if (FAILURE == zephir_get_class_constant(return_value, ce, const_name, strlen(const_name)+1 TSRMLS_CC)) { \
45 | ZEPHIR_MM_RESTORE(); \
46 | return; \
47 | } \
48 | } while (0)
49 |
50 | /** Class constants */
51 | int zephir_get_class_constant(zval *return_value, zend_class_entry *ce, char *constant_name, unsigned int constant_length TSRMLS_DC);
52 |
53 | /** Cloning/Instance of*/
54 | int zephir_clone(zval *destiny, zval *obj TSRMLS_DC);
55 | int zephir_instance_of(zval *result, const zval *object, const zend_class_entry *ce TSRMLS_DC);
56 | int zephir_is_instance_of(zval *object, const char *class_name, unsigned int class_length TSRMLS_DC);
57 | int zephir_instance_of_ev(const zval *object, const zend_class_entry *ce TSRMLS_DC);
58 | int zephir_zval_is_traversable(zval *object TSRMLS_DC);
59 |
60 | /** Method exists */
61 | int zephir_method_exists(const zval *object, const zval *method_name TSRMLS_DC);
62 | int zephir_method_exists_ex(const zval *object, const char *method_name, unsigned int method_len TSRMLS_DC);
63 | int zephir_method_quick_exists_ex(const zval *object, const char *method_name, unsigned int method_len, unsigned long hash TSRMLS_DC);
64 |
65 | /** Isset properties */
66 | int zephir_isset_property(zval *object, const char *property_name, unsigned int property_length TSRMLS_DC);
67 | int zephir_isset_property_quick(zval *object, const char *property_name, unsigned int property_length, unsigned long hash TSRMLS_DC);
68 | int zephir_isset_property_zval(zval *object, const zval *property TSRMLS_DC);
69 |
70 | /** Reading properties */
71 | zval* zephir_fetch_property_this_quick(zval *object, const char *property_name, zend_uint property_length, ulong key, int silent TSRMLS_DC);
72 | int zephir_read_property(zval **result, zval *object, const char *property_name, zend_uint property_length, int silent TSRMLS_DC);
73 | int zephir_read_property_zval(zval **result, zval *object, zval *property, int silent TSRMLS_DC);
74 | int zephir_return_property(zval *return_value, zval **return_value_ptr, zval *object, char *property_name, unsigned int property_length TSRMLS_DC);
75 | int zephir_return_property_quick(zval *return_value, zval **return_value_ptr, zval *object, char *property_name, unsigned int property_length, unsigned long key TSRMLS_DC);
76 | int zephir_fetch_property(zval **result, zval *object, const char *property_name, zend_uint property_length, int silent TSRMLS_DC);
77 | int zephir_fetch_property_zval(zval **result, zval *object, zval *property, int silent TSRMLS_DC);
78 |
79 | /** Updating properties */
80 | int zephir_update_property_this(zval *object, char *property_name, unsigned int property_length, zval *value TSRMLS_DC);
81 | int zephir_update_property_long(zval *obj, char *property_name, unsigned int property_length, long value TSRMLS_DC);
82 | int zephir_update_property_string(zval *object, char *property_name, unsigned int property_length, char *str, unsigned int str_length TSRMLS_DC);
83 | int zephir_update_property_bool(zval *obj, char *property_name, unsigned int property_length, int value TSRMLS_DC);
84 | int zephir_update_property_null(zval *obj, char *property_name, unsigned int property_length TSRMLS_DC);
85 | int zephir_update_property_zval(zval *obj, const char *property_name, unsigned int property_length, zval *value TSRMLS_DC);
86 | int zephir_update_property_zval_zval(zval *obj, zval *property, zval *value TSRMLS_DC);
87 | int zephir_update_property_empty_array(zend_class_entry *ce, zval *object, char *property, unsigned int property_length TSRMLS_DC);
88 |
89 | /** Updating array properties */
90 | int zephir_update_property_array(zval *object, const char *property, zend_uint property_length, const zval *index, zval *value TSRMLS_DC);
91 | int zephir_update_property_array_string(zval *object, char *property, unsigned int property_length, char *index, unsigned int index_length, zval *value TSRMLS_DC);
92 | int zephir_update_property_array_append(zval *object, char *property, unsigned int property_length, zval *value TSRMLS_DC);
93 | int zephir_update_property_array_multi(zval *object, const char *property, zend_uint property_length, zval **value TSRMLS_DC, const char *types, int types_length, int types_count, ...);
94 |
95 | /** Increment/Decrement properties */
96 | int zephir_property_incr(zval *object, char *property_name, unsigned int property_length TSRMLS_DC);
97 | int zephir_property_decr(zval *object, char *property_name, unsigned int property_length TSRMLS_DC);
98 |
99 | /** Unset properties */
100 | int zephir_unset_property(zval* object, const char* name TSRMLS_DC);
101 | int zephir_unset_property_array(zval *object, char *property, unsigned int property_length, zval *index TSRMLS_DC);
102 |
103 | /** Static properties */
104 | int zephir_read_static_property(zval **result, const char *class_name, unsigned int class_length, char *property_name, unsigned int property_length TSRMLS_DC);
105 | int zephir_update_static_property_ce(zend_class_entry *ce, const char *name, int len, zval **value TSRMLS_DC);
106 | int zephir_update_static_property_ce_cache(zend_class_entry *ce, const char *name, int len, zval **value, zend_property_info **property_info TSRMLS_DC);
107 | int zephir_update_static_property(const char *class_name, unsigned int class_length, char *name, unsigned int name_length, zval **value TSRMLS_DC);
108 | int zephir_read_static_property_ce(zval **result, zend_class_entry *ce, const char *property, int len TSRMLS_DC);
109 | int zephir_read_class_property(zval **result, int type, const char *property, int len TSRMLS_DC);
110 | zval* zephir_fetch_static_property_ce(zend_class_entry *ce, const char *property, int len TSRMLS_DC);
111 | int zephir_update_static_property_array_multi_ce(zend_class_entry *ce, const char *property, zend_uint property_length, zval **value TSRMLS_DC, const char *types, int types_length, int types_count, ...);
112 |
113 | /** Create instances */
114 | int zephir_create_instance(zval *return_value, const zval *class_name TSRMLS_DC);
115 | int zephir_create_instance_params(zval *return_value, const zval *class_name, zval *params TSRMLS_DC);
116 |
117 | /** Create closures */
118 | int zephir_create_closure_ex(zval *return_value, zval *this_ptr, zend_class_entry *ce, const char *method_name, zend_uint method_length TSRMLS_DC);
119 |
120 | /**
121 | * Reads a property from this_ptr (with pre-calculated key)
122 | * Variables must be defined in the class definition. This function ignores magic methods or dynamic properties
123 | */
124 | ZEPHIR_ATTR_NONNULL static inline int zephir_read_property_this_quick(zval **result, zval *object, const char *property_name, zend_uint property_length, ulong key, int silent TSRMLS_DC)
125 | {
126 | zval *tmp = zephir_fetch_property_this_quick(object, property_name, property_length, key, silent TSRMLS_CC);
127 | if (EXPECTED(tmp != NULL)) {
128 | *result = tmp;
129 | Z_ADDREF_PP(result);
130 | return SUCCESS;
131 | }
132 |
133 | ALLOC_INIT_ZVAL(*result);
134 | return FAILURE;
135 | }
136 |
137 | /**
138 | * Reads a property from this_ptr
139 | * Variables must be defined in the class definition. This function ignores magic methods or dynamic properties
140 | */
141 | ZEPHIR_ATTR_NONNULL static inline int zephir_read_property_this(zval **result, zval *object, const char *property_name, zend_uint property_length, int silent TSRMLS_DC)
142 | {
143 | #ifdef __GNUC__
144 | if (__builtin_constant_p(property_name) && __builtin_constant_p(property_length)) {
145 | return zephir_read_property_this_quick(result, object, property_name, property_length, zend_inline_hash_func(property_name, property_length + 1), silent TSRMLS_CC);
146 | }
147 | #endif
148 |
149 | return zephir_read_property_this_quick(result, object, property_name, property_length, zend_hash_func(property_name, property_length + 1), silent TSRMLS_CC);
150 | }
151 |
152 | ZEPHIR_ATTR_NONNULL static inline zval* zephir_fetch_nproperty_this_quick(zval *object, const char *property_name, zend_uint property_length, ulong key, int silent TSRMLS_DC)
153 | {
154 | #ifdef __GNUC__
155 | if (__builtin_constant_p(property_name) && __builtin_constant_p(property_length)) {
156 | zval *result = zephir_fetch_property_this_quick(object, property_name, property_length, key, silent TSRMLS_CC);
157 | return result ? result : EG(uninitialized_zval_ptr);
158 | }
159 | #endif
160 |
161 | zval *result = zephir_fetch_property_this_quick(object, property_name, property_length, key, silent TSRMLS_CC);
162 | return result ? result : EG(uninitialized_zval_ptr);
163 | }
164 |
165 | ZEPHIR_ATTR_NONNULL static inline zval* zephir_fetch_nproperty_this(zval *object, const char *property_name, zend_uint property_length, int silent TSRMLS_DC)
166 | {
167 | #ifdef __GNUC__
168 | if (__builtin_constant_p(property_name) && __builtin_constant_p(property_length)) {
169 | return zephir_fetch_nproperty_this_quick(object, property_name, property_length, zend_inline_hash_func(property_name, property_length + 1), silent TSRMLS_CC);
170 | }
171 | #endif
172 |
173 | return zephir_fetch_nproperty_this_quick(object, property_name, property_length, zend_hash_func(property_name, property_length + 1), silent TSRMLS_CC);
174 | }
175 |
176 | ZEPHIR_ATTR_NONNULL static inline zval* zephir_fetch_property_this(zval *object, const char *property_name, zend_uint property_length, int silent TSRMLS_DC)
177 | {
178 | #ifdef __GNUC__
179 | if (__builtin_constant_p(property_name) && __builtin_constant_p(property_length)) {
180 | return zephir_fetch_property_this_quick(object, property_name, property_length, zend_inline_hash_func(property_name, property_length + 1), silent TSRMLS_CC);
181 | }
182 | #endif
183 |
184 | return zephir_fetch_property_this_quick(object, property_name, property_length, zend_hash_func(property_name, property_length + 1), silent TSRMLS_CC);
185 | }
186 |
187 | #endif
188 |
189 | #define zephir_fetch_safe_class(destination, var) \
190 | { \
191 | if (Z_TYPE_P(var) == IS_STRING) { \
192 | ZEPHIR_CPY_WRT(destination, var); \
193 | } else { \
194 | ZEPHIR_INIT_NVAR(destination); \
195 | ZVAL_STRING(destination, "", 1); \
196 | } \
197 | }
198 |
--------------------------------------------------------------------------------
/ext/kernel/operators.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_OPERATORS_H
22 | #define ZEPHIR_KERNEL_OPERATORS_H
23 |
24 | #include
25 | #include
26 |
27 | /** Strict comparing */
28 | #define ZEPHIR_IS_LONG(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) == op2) || zephir_compare_strict_long(op1, op2 TSRMLS_CC))
29 | #define ZEPHIR_IS_DOUBLE(op1, op2) ((Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) == op2) || zephir_compare_strict_double(op1, op2 TSRMLS_CC))
30 | #define ZEPHIR_IS_STRING(op1, op2) zephir_compare_strict_string(op1, op2, strlen(op2))
31 |
32 | #define ZEPHIR_IS_LONG_IDENTICAL(op1, op2) (Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) == op2)
33 | #define ZEPHIR_IS_DOUBLE_IDENTICAL(op1, op2) (Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) == op2)
34 | #define ZEPHIR_IS_STRING_IDENTICAL(op1, op2) (Z_TYPE_P(op1) == IS_STRING && zephir_compare_strict_string(op1, op2, strlen(op2)))
35 |
36 | /** strict boolean comparison */
37 | #define ZEPHIR_IS_FALSE(var) ((Z_TYPE_P(var) == IS_BOOL && !Z_BVAL_P(var)) || zephir_compare_strict_bool(var, 0 TSRMLS_CC))
38 | #define ZEPHIR_IS_TRUE(var) ((Z_TYPE_P(var) == IS_BOOL && Z_BVAL_P(var)) || zephir_compare_strict_bool(var, 1 TSRMLS_CC))
39 |
40 | #define ZEPHIR_IS_FALSE_IDENTICAL(var) (Z_TYPE_P(var) == IS_BOOL && !Z_BVAL_P(var))
41 | #define ZEPHIR_IS_TRUE_IDENTICAL(var) (Z_TYPE_P(var) == IS_BOOL && Z_BVAL_P(var))
42 |
43 | #define ZEPHIR_IS_NOT_FALSE(var) (Z_TYPE_P(var) != IS_BOOL || (Z_TYPE_P(var) == IS_BOOL && Z_BVAL_P(var)))
44 | #define ZEPHIR_IS_NOT_TRUE(var) (Z_TYPE_P(var) != IS_BOOL || (Z_TYPE_P(var) == IS_BOOL && !Z_BVAL_P(var)))
45 | #define ZEPHIR_IS_BOOL(op1, op2) ((Z_TYPE_P(op1) == IS_BOOL && Z_BVAL_P(op1) == op2) || zephir_compare_strict_bool(op1, op2 TSRMLS_CC))
46 |
47 | /** SQL null empty **/
48 | #define ZEPHIR_IS_EMPTY(var) (Z_TYPE_P(var) == IS_NULL || ZEPHIR_IS_FALSE(var) || (Z_TYPE_P(var) == IS_STRING && !Z_STRLEN_P(var)) || !zend_is_true(var))
49 | #define ZEPHIR_IS_NOT_EMPTY(var) (!ZEPHIR_IS_EMPTY(var))
50 |
51 | /** Is scalar */
52 | #define ZEPHIR_IS_SCALAR(var) (!ZEPHIR_IS_NOT_SCALAR(var))
53 | #define ZEPHIR_IS_NOT_SCALAR(var) (Z_TYPE_P(var) == IS_NULL || Z_TYPE_P(var) == IS_ARRAY || Z_TYPE_P(var) == IS_OBJECT || Z_TYPE_P(var) == IS_RESOURCE)
54 |
55 | /** Equals/Identical */
56 | #define ZEPHIR_IS_EQUAL(op1, op2) zephir_is_equal(op1, op2 TSRMLS_CC)
57 | #define ZEPHIR_IS_IDENTICAL(op1, op2) zephir_is_identical(op1, op2 TSRMLS_CC)
58 |
59 | /** Greater/Smaller equals */
60 | #define ZEPHIR_LE(op1, op2) zephir_less_equal(op1, op2 TSRMLS_CC)
61 | #define ZEPHIR_LE_LONG(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) <= op2) || zephir_less_equal_long(op1, op2 TSRMLS_CC))
62 | #define ZEPHIR_LE_DOUBLE(op1, op2) ((Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) <= op2) || zephir_less_equal_double(op1, op2 TSRMLS_CC))
63 | #define ZEPHIR_GE(op1, op2) zephir_greater_equal(op1, op2 TSRMLS_CC)
64 | #define ZEPHIR_GE_LONG(op1, op2) zephir_greater_equal_long(op1, op2 TSRMLS_CC)
65 | #define ZEPHIR_LT(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_TYPE_P(op2) == IS_LONG) ? Z_LVAL_P(op1) < Z_LVAL_P(op2) : zephir_less(op1, op2 TSRMLS_CC))
66 | #define ZEPHIR_LT_LONG(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) < op2) || zephir_less_long(op1, op2 TSRMLS_CC))
67 | #define ZEPHIR_LT_DOUBLE(op1, op2) ((Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) < op2) || zephir_less_double(op1, op2 TSRMLS_CC))
68 | #define ZEPHIR_GT(op1, op2) zephir_greater(op1, op2 TSRMLS_CC)
69 | #define ZEPHIR_GT_LONG(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) > op2) || zephir_greater_long(op1, op2 TSRMLS_CC))
70 | #define ZEPHIR_GT_DOUBLE(op1, op2) ((Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) > op2) || zephir_greater_double(op1, op2 TSRMLS_CC))
71 |
72 | #define ZEPHIR_STRING_OFFSET(op1, index) ((index >= 0 && index < Z_STRLEN_P(op1)) ? Z_STRVAL_P(op1)[index] : '\0')
73 |
74 | #if PHP_VERSION_ID < 50400
75 | #define zephir_increment(var) increment_function(var)
76 | #else
77 | #define zephir_increment(var) fast_increment_function(var)
78 | #endif
79 |
80 | #if PHP_VERSION_ID < 50400
81 | #define zephir_decrement(var) decrement_function(var)
82 | #else
83 | #define zephir_decrement(var) fast_decrement_function(var)
84 | #endif
85 |
86 | void zephir_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy);
87 |
88 | #if PHP_VERSION_ID < 50400
89 | #define zephir_sub_function(result, left, right, t) sub_function(result, left, right TSRMLS_CC)
90 | #define zephir_add_function(result, left, right, t) zephir_add_function_ex(result, left, right TSRMLS_CC)
91 | #else
92 | #define zephir_add_function(result, left, right, t) fast_add_function(result, left, right TSRMLS_CC)
93 | #define zephir_sub_function(result, left, right, t) fast_sub_function(result, left, right TSRMLS_CC)
94 | #endif
95 |
96 | #if PHP_VERSION_ID < 50600
97 | void zephir_pow_function_ex(zval *return_value, zval *zbase, zval *zexp TSRMLS_DC);
98 | #define zephir_pow_function(result, op1, op2) zephir_pow_function_ex(result, op1, op2 TSRMLS_CC)
99 | #else
100 | #define zephir_pow_function(result, op1, op2) pow_function(result, op1, op2 TSRMLS_CC)
101 | #endif
102 |
103 | /** Operator functions */
104 | int zephir_add_function_ex(zval *result, zval *op1, zval *op2 TSRMLS_DC);
105 | int zephir_and_function(zval *result, zval *left, zval *right);
106 | void zephir_negate(zval *z TSRMLS_DC);
107 |
108 | /** Bitwise functions */
109 | int zephir_bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
110 | int zephir_bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
111 | int zephir_bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
112 | int zephir_shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
113 | int zephir_shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
114 |
115 | void zephir_concat_self(zval **left, zval *right TSRMLS_DC);
116 | void zephir_concat_self_str(zval **left, const char *right, int right_length TSRMLS_DC);
117 | void zephir_concat_self_long(zval **left, const long right TSRMLS_DC);
118 | void zephir_concat_self_char(zval **left, unsigned char right TSRMLS_DC);
119 |
120 | /** Strict comparing */
121 | int zephir_compare_strict_string(zval *op1, const char *op2, int op2_length);
122 | int zephir_compare_strict_long(zval *op1, long op2 TSRMLS_DC);
123 | int zephir_compare_strict_double(zval *op1, double op2 TSRMLS_DC);
124 | int zephir_compare_strict_bool(zval *op1, zend_bool op2 TSRMLS_DC);
125 |
126 | void zephir_cast(zval *result, zval *var, zend_uint type);
127 | void zephir_convert_to_object(zval *op);
128 | long zephir_get_intval_ex(const zval *op);
129 | double zephir_get_doubleval_ex(const zval *op);
130 | zend_bool zephir_get_boolval_ex(const zval *op);
131 |
132 | int zephir_is_numeric_ex(const zval *op);
133 |
134 | int zephir_is_equal(zval *op1, zval *op2 TSRMLS_DC);
135 | int zephir_is_identical(zval *op1, zval *op2 TSRMLS_DC);
136 |
137 | int zephir_less(zval *op1, zval *op2 TSRMLS_DC);
138 | int zephir_less_long(zval *op1, long op2 TSRMLS_DC);
139 | int zephir_less_double(zval *op1, double op2 TSRMLS_DC);
140 |
141 | int zephir_greater(zval *op1, zval *op2 TSRMLS_DC);
142 | int zephir_greater_long(zval *op1, long op2 TSRMLS_DC);
143 | int zephir_greater_double(zval *op1, double op2 TSRMLS_DC);
144 |
145 | int zephir_less_equal(zval *op1, zval *op2 TSRMLS_DC);
146 | int zephir_less_equal_long(zval *op1, long op2 TSRMLS_DC);
147 |
148 | int zephir_greater_equal(zval *op1, zval *op2 TSRMLS_DC);
149 | int zephir_greater_equal_long(zval *op1, long op2 TSRMLS_DC);
150 |
151 | double zephir_safe_div_long_long(long op1, long op2 TSRMLS_DC);
152 | double zephir_safe_div_long_double(long op1, double op2 TSRMLS_DC);
153 | double zephir_safe_div_double_long(double op1, long op2 TSRMLS_DC);
154 | double zephir_safe_div_double_double(double op1, double op2 TSRMLS_DC);
155 | double zephir_safe_div_zval_long(zval *op1, long op2 TSRMLS_DC);
156 | double zephir_safe_div_zval_double(zval *op1, double op2 TSRMLS_DC);
157 | double zephir_safe_div_long_zval(long op1, zval *op2 TSRMLS_DC);
158 | double zephir_safe_div_double_zval(double op1, zval *op2 TSRMLS_DC);
159 |
160 | long zephir_safe_mod_long_long(long op1, long op2 TSRMLS_DC);
161 | long zephir_safe_mod_long_double(long op1, double op2 TSRMLS_DC);
162 | long zephir_safe_mod_double_long(double op1, long op2 TSRMLS_DC);
163 | long zephir_safe_mod_double_double(double op1, double op2 TSRMLS_DC);
164 | long zephir_safe_mod_zval_long(zval *op1, long op2 TSRMLS_DC);
165 | long zephir_safe_mod_zval_double(zval *op1, double op2 TSRMLS_DC);
166 | long zephir_safe_mod_long_zval(long op1, zval *op2 TSRMLS_DC);
167 | long zephir_safe_mod_double_zval(double op1, zval *op2 TSRMLS_DC);
168 |
169 | #define zephir_get_numberval(z) (Z_TYPE_P(z) == IS_LONG ? Z_LVAL_P(z) : zephir_get_doubleval(z))
170 | #define zephir_get_intval(z) (Z_TYPE_P(z) == IS_LONG ? Z_LVAL_P(z) : zephir_get_intval_ex(z))
171 | #define zephir_get_doubleval(z) (Z_TYPE_P(z) == IS_DOUBLE ? Z_DVAL_P(z) : zephir_get_doubleval_ex(z))
172 | #define zephir_get_boolval(z) (Z_TYPE_P(z) == IS_BOOL ? Z_BVAL_P(z) : zephir_get_boolval_ex(z))
173 |
174 | #ifndef PHP_WIN32
175 |
176 | #define ZEPHIR_ADD_ASSIGN(z, v) \
177 | { \
178 | zval tmp; \
179 | ZEPHIR_SEPARATE(z); \
180 | if (Z_TYPE_P(z) == IS_LONG && Z_TYPE_P(v) == IS_LONG) { \
181 | Z_LVAL_P(z) += Z_LVAL_P(v); \
182 | } else { \
183 | if (Z_TYPE_P(z) == IS_LONG && Z_TYPE_P(v) == IS_DOUBLE) { \
184 | Z_LVAL_P(z) += Z_DVAL_P(v); \
185 | } else { \
186 | add_function(&tmp, z, v TSRMLS_CC); \
187 | if (Z_TYPE(tmp) == IS_LONG) { \
188 | Z_LVAL_P(z) = Z_LVAL(tmp); \
189 | } else { \
190 | if (Z_TYPE(tmp) == IS_DOUBLE) { \
191 | Z_DVAL_P(z) = Z_DVAL(tmp); \
192 | } \
193 | } \
194 | } \
195 | } \
196 | }
197 |
198 | #define ZEPHIR_SUB_ASSIGN(z, v) \
199 | { \
200 | zval tmp; \
201 | ZEPHIR_SEPARATE(z); \
202 | if (Z_TYPE_P(z) == IS_LONG && Z_TYPE_P(v) == IS_LONG) { \
203 | Z_LVAL_P(z) -= Z_LVAL_P(v); \
204 | } else { \
205 | if (Z_TYPE_P(z) == IS_LONG && Z_TYPE_P(v) == IS_DOUBLE) { \
206 | Z_LVAL_P(z) -= Z_DVAL_P(v); \
207 | } else { \
208 | sub_function(&tmp, z, v TSRMLS_CC); \
209 | if (Z_TYPE(tmp) == IS_LONG) { \
210 | Z_LVAL_P(z) = Z_LVAL(tmp); \
211 | } else { \
212 | if (Z_TYPE(tmp) == IS_DOUBLE) { \
213 | Z_DVAL_P(z) = Z_DVAL(tmp); \
214 | } \
215 | } \
216 | } \
217 | } \
218 | }
219 |
220 | #define ZEPHIR_MUL_ASSIGN(z, v) \
221 | { \
222 | zval tmp; \
223 | ZEPHIR_SEPARATE(z); \
224 | if (Z_TYPE_P(z) == IS_LONG && Z_TYPE_P(v) == IS_LONG) { \
225 | Z_LVAL_P(z) *= Z_LVAL_P(v); \
226 | } else { \
227 | if (Z_TYPE_P(z) == IS_LONG && Z_TYPE_P(v) == IS_DOUBLE) { \
228 | Z_LVAL_P(z) *= Z_DVAL_P(v); \
229 | } else { \
230 | mul_function(&tmp, z, v TSRMLS_CC); \
231 | if (Z_TYPE(tmp) == IS_LONG) { \
232 | Z_LVAL_P(z) = Z_LVAL(tmp); \
233 | } else { \
234 | if (Z_TYPE(tmp) == IS_DOUBLE) { \
235 | Z_DVAL_P(z) = Z_DVAL(tmp); \
236 | } \
237 | } \
238 | } \
239 | } \
240 | }
241 |
242 | #else
243 |
244 | #define ZEPHIR_ADD_ASSIGN(z, v) \
245 | { \
246 | zval tmp; \
247 | ZEPHIR_SEPARATE(z); \
248 | add_function(&tmp, z, v TSRMLS_CC); \
249 | if (Z_TYPE(tmp) == IS_LONG) { \
250 | Z_LVAL_P(z) = Z_LVAL(tmp); \
251 | } else { \
252 | if (Z_TYPE(tmp) == IS_DOUBLE) { \
253 | Z_DVAL_P(z) = Z_DVAL(tmp); \
254 | } \
255 | } \
256 | }
257 |
258 | #define ZEPHIR_SUB_ASSIGN(z, v) \
259 | { \
260 | zval tmp; \
261 | ZEPHIR_SEPARATE(z); \
262 | sub_function(&tmp, z, v TSRMLS_CC); \
263 | if (Z_TYPE(tmp) == IS_LONG) { \
264 | Z_LVAL_P(z) = Z_LVAL(tmp); \
265 | } else { \
266 | if (Z_TYPE(tmp) == IS_DOUBLE) { \
267 | Z_DVAL_P(z) = Z_DVAL(tmp); \
268 | } \
269 | } \
270 | }
271 |
272 | #define ZEPHIR_MUL_ASSIGN(z, v) \
273 | { \
274 | zval tmp; \
275 | ZEPHIR_SEPARATE(z); \
276 | mul_function(&tmp, z, v TSRMLS_CC); \
277 | if (Z_TYPE(tmp) == IS_LONG) { \
278 | Z_LVAL_P(z) = Z_LVAL(tmp); \
279 | } else { \
280 | if (Z_TYPE(tmp) == IS_DOUBLE) { \
281 | Z_DVAL_P(z) = Z_DVAL(tmp); \
282 | } \
283 | } \
284 | }
285 |
286 | #endif
287 |
288 | #define zephir_get_strval(left, right) \
289 | { \
290 | int use_copy_right; \
291 | zval right_tmp; \
292 | if (Z_TYPE_P(right) == IS_STRING) { \
293 | ZEPHIR_CPY_WRT(left, right); \
294 | } else { \
295 | INIT_ZVAL(right_tmp); \
296 | zephir_make_printable_zval(right, &right_tmp, &use_copy_right); \
297 | if (use_copy_right) { \
298 | ZEPHIR_INIT_NVAR(left); \
299 | ZVAL_STRINGL(left, Z_STRVAL_P(&right_tmp), Z_STRLEN_P(&right_tmp), 0); \
300 | } \
301 | } \
302 | }
303 |
304 | #define zephir_get_arrval(returnValue, passValue) \
305 | { \
306 | if (Z_TYPE_P(passValue) == IS_ARRAY) { \
307 | ZEPHIR_CPY_WRT(returnValue, passValue); \
308 | } else { \
309 | ZEPHIR_INIT_NVAR(returnValue); \
310 | array_init_size(returnValue, 0); \
311 | } \
312 | }
313 |
314 | #define zephir_is_numeric(value) (Z_TYPE_P(value) == IS_LONG || Z_TYPE_P(value) == IS_DOUBLE || zephir_is_numeric_ex(value))
315 |
316 | #define zephir_is_true(value) \
317 | (Z_TYPE_P(value) == IS_NULL ? 0 : \
318 | (Z_TYPE_P(value) == IS_BOOL ? Z_BVAL_P(value) : \
319 | (Z_TYPE_P(value) == IS_LONG ? (Z_LVAL_P(value) ? 1 : 0) : \
320 | zend_is_true(value) \
321 | ) \
322 | ) \
323 | )
324 |
325 | #endif
326 |
--------------------------------------------------------------------------------
/ext/kernel/output.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifdef HAVE_CONFIG_H
22 | #include "config.h"
23 | #endif
24 |
25 | #include "php.h"
26 | #include "php_ext.h"
27 | #include "kernel/memory.h"
28 | #include "kernel/output.h"
29 |
30 | #include
31 | #include
32 |
33 | void zephir_ob_start(TSRMLS_D)
34 | {
35 | #if PHP_VERSION_ID < 50400
36 | php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
37 | #else
38 | php_output_start_default(TSRMLS_C);
39 | #endif
40 | }
41 |
42 | void zephir_ob_get_contents(zval *result TSRMLS_DC)
43 | {
44 | #if PHP_VERSION_ID < 50400
45 | php_ob_get_buffer(result TSRMLS_CC);
46 | #else
47 | php_output_get_contents(result TSRMLS_CC);
48 | #endif
49 | }
50 |
51 | int zephir_ob_end_flush(TSRMLS_D)
52 | {
53 | if (zephir_ob_get_level(TSRMLS_C) < 1) {
54 | php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete and flush buffer. No buffer to flush");
55 | return FAILURE;
56 | }
57 |
58 | #if PHP_VERSION_ID < 50400
59 | php_end_ob_buffer(1, 0 TSRMLS_CC);
60 | return SUCCESS;
61 | #else
62 | return php_output_end(TSRMLS_C);
63 | #endif
64 | }
65 |
66 | int zephir_ob_end_clean(TSRMLS_D)
67 | {
68 | if (zephir_ob_get_level(TSRMLS_C) < 1) {
69 | php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete");
70 | return FAILURE;
71 | }
72 |
73 | #if PHP_VERSION_ID < 50400
74 | php_end_ob_buffer(0, 0 TSRMLS_CC);
75 | return SUCCESS;
76 | #else
77 | return php_output_discard(TSRMLS_C);
78 | #endif
79 | }
80 |
81 | int zephir_ob_flush(TSRMLS_D)
82 | {
83 | if (zephir_ob_get_level(TSRMLS_C) < 1) {
84 | php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to flush buffer. No buffer to flush");
85 | return FAILURE;
86 | }
87 |
88 | #if PHP_VERSION_ID < 50400
89 | php_end_ob_buffer(1, 1 TSRMLS_CC);
90 | return SUCCESS;
91 | #else
92 | return php_output_flush(TSRMLS_C);
93 | #endif
94 | }
95 |
96 | int zephir_ob_clean(TSRMLS_D)
97 | {
98 | if (zephir_ob_get_level(TSRMLS_C) < 1) {
99 | php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete");
100 | return FAILURE;
101 | }
102 |
103 | #if PHP_VERSION_ID < 50400
104 | php_end_ob_buffer(0, 1 TSRMLS_CC);
105 | return SUCCESS;
106 | #else
107 | return php_output_clean(TSRMLS_C);
108 | #endif
109 | }
110 |
111 | int zephir_ob_get_level(TSRMLS_D)
112 | {
113 | #if PHP_VERSION_ID < 50400
114 | return OG(ob_nesting_level);
115 | #else
116 | return php_output_get_level(TSRMLS_C);
117 | #endif
118 | }
119 |
--------------------------------------------------------------------------------
/ext/kernel/output.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_OUTPUT_H
22 | #define ZEPHIR_KERNEL_OUTPUT_H
23 |
24 | #include
25 |
26 | void zephir_ob_start(TSRMLS_D);
27 | void zephir_ob_get_contents(zval *result TSRMLS_DC);
28 | int zephir_ob_end_flush(TSRMLS_D);
29 | int zephir_ob_end_clean(TSRMLS_D);
30 | int zephir_ob_flush(TSRMLS_D);
31 | int zephir_ob_clean(TSRMLS_D);
32 | int zephir_ob_get_level(TSRMLS_D);
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/ext/kernel/persistent.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
20 | #ifdef HAVE_CONFIG_H
21 | #include "config.h"
22 | #endif
23 |
24 | #include "php.h"
25 | #include "php_ext.h"
26 |
27 | /* represents a connection to a database */
28 | struct _zephir_persist_obj {
29 | char *data;
30 | } zephir_persist_obj;
31 |
32 | int zephir_persistent_fetch(zval *return_value, zval *service TSRMLS_DC){
33 | zend_rsrc_list_entry *le;
34 |
35 | /* try to find if we already have this link in our persistent list */
36 | if (zend_hash_find(&EG(persistent_list), Z_STRVAL_P(service), Z_STRLEN_P(service)+1, (void **) &le)==FAILURE) {
37 |
38 | }
39 | }
40 |
41 | int zephir_persistent_store(zval *service, zval *object TSRMLS_DC){
42 |
43 | //pdo_dbh_t *dbh = NULL;
44 |
45 | //zend_object_store_set_object(object, dbh TSRMLS_CC);
46 |
47 |
48 | zend_rsrc_list_entry new_le;
49 |
50 | Z_TYPE(new_le) = 1;
51 | new_le.ptr = pestrdup("hello", 1);
52 | if (zend_hash_update(&EG(persistent_list), Z_STRVAL_P(service), Z_STRLEN_P(service)+1, (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
53 | //goto err;
54 | }
55 |
56 | //zephir_persistent_store
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/ext/kernel/persistent.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | +------------------------------------------------------------------------+
18 | */
19 |
20 | #ifndef ZEPHIR_KERNEL_PERSISTENT_H
21 | #define ZEPHIR_KERNEL_PERSISTENT_H
22 |
23 | #include
24 |
25 | int zephir_persistent_store(zval *service, zval *object TSRMLS_DC);
26 | int zephir_persistent_fetch(zval *return_value, zval *service TSRMLS_DC);
27 |
28 | #endif
--------------------------------------------------------------------------------
/ext/kernel/require.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifdef HAVE_CONFIG_H
22 | #include "config.h"
23 | #endif
24 |
25 | #include "php.h"
26 | #include "php_ext.h"
27 | #include "kernel/require.h"
28 | #include "kernel/backtrace.h"
29 |
30 | #include
31 | #include
32 |
33 | #ifndef ENFORCE_SAFE_MODE
34 | #define ENFORCE_SAFE_MODE 0
35 | #endif
36 |
37 | /**
38 | * Do an internal require to a plain php file taking care of the value returned by the file
39 | */
40 | int zephir_require_ret(zval **return_value_ptr, const char *require_path TSRMLS_DC)
41 | {
42 | zend_file_handle file_handle;
43 | int ret, use_ret, mode;
44 |
45 | #ifndef ZEPHIR_RELEASE
46 | if (return_value_ptr && *return_value_ptr) {
47 | fprintf(stderr, "%s: *return_value_ptr is expected to be NULL", __func__);
48 | zephir_print_backtrace();
49 | abort();
50 | }
51 | #endif
52 |
53 | if (!require_path) {
54 | /* @TODO, throw an exception here */
55 | return FAILURE;
56 | }
57 |
58 | use_ret = !!return_value_ptr;
59 |
60 | ret = php_stream_open_for_zend_ex(require_path, &file_handle, ENFORCE_SAFE_MODE | USE_PATH | STREAM_OPEN_FOR_INCLUDE | IGNORE_URL TSRMLS_CC);
61 | if (ret == SUCCESS) {
62 | int dummy = 1;
63 | zend_op_array *new_op_array;
64 |
65 | if (!file_handle.opened_path) {
66 | file_handle.opened_path = estrdup(require_path);
67 | }
68 |
69 | zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path) + 1, (void *)&dummy, sizeof(int), NULL);
70 | new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC);
71 | zend_destroy_file_handle(&file_handle TSRMLS_CC);
72 |
73 | if (new_op_array) {
74 | zval **original_return_value = EG(return_value_ptr_ptr);
75 | zend_op_array *original_active_op_array = EG(active_op_array);
76 | zend_op **original_opline_ptr = EG(opline_ptr);
77 |
78 | EG(return_value_ptr_ptr) = return_value_ptr;
79 | EG(active_op_array) = new_op_array;
80 |
81 | zend_execute(new_op_array TSRMLS_CC);
82 | zend_exception_restore(TSRMLS_C);
83 | destroy_op_array(new_op_array TSRMLS_CC);
84 | efree(new_op_array);
85 |
86 | if (EG(exception)) {
87 | assert(!return_value_ptr || !*return_value_ptr);
88 | ret = FAILURE;
89 | }
90 | else {
91 | ret = SUCCESS;
92 | }
93 |
94 | EG(return_value_ptr_ptr) = original_return_value;
95 | EG(active_op_array) = original_active_op_array;
96 | EG(opline_ptr) = original_opline_ptr;
97 | return ret;
98 | }
99 | }
100 | else {
101 | zend_destroy_file_handle(&file_handle TSRMLS_CC);
102 | }
103 |
104 | return FAILURE;
105 | }
106 |
--------------------------------------------------------------------------------
/ext/kernel/require.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_REQUIRE_H
22 | #define ZEPHIR_KERNEL_REQUIRE_H
23 |
24 | #include "php_ext.h"
25 |
26 | int zephir_require_ret(zval **return_value_ptr, const char *require_path TSRMLS_DC) ZEPHIR_ATTR_NONNULL1(2);
27 |
28 | ZEPHIR_ATTR_NONNULL static inline int zephir_require(const char *require_path TSRMLS_DC)
29 | {
30 | return zephir_require_ret(NULL, require_path TSRMLS_CC);
31 | }
32 |
33 | ZEPHIR_ATTR_NONNULL static inline int zephir_require_zval(const zval *require_path TSRMLS_DC)
34 | {
35 | return zephir_require_ret(NULL, Z_TYPE_P(require_path) == IS_STRING ? Z_STRVAL_P(require_path) : "" TSRMLS_CC);
36 | }
37 |
38 | ZEPHIR_ATTR_NONNULL static inline int zephir_require_zval_ret(zval **return_value_ptr, const zval *require_path TSRMLS_DC)
39 | {
40 | return zephir_require_ret(return_value_ptr, Z_TYPE_P(require_path) == IS_STRING ? Z_STRVAL_P(require_path) : "" TSRMLS_CC);
41 | }
42 |
43 | #endif /* ZEPHIR_KERNEL_REQUIRE_H */
44 |
--------------------------------------------------------------------------------
/ext/kernel/session.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifdef HAVE_CONFIG_H
22 | #include "config.h"
23 | #endif
24 |
25 | #include "php.h"
26 | #include "php_ext.h"
27 |
28 | #include "kernel/main.h"
29 | #include "kernel/fcall.h"
30 | #include "kernel/session.h"
31 |
32 | #ifdef ZEPHIR_USE_PHP_SESSION
33 | #include
34 | #endif
35 |
36 | void zephir_session_start(TSRMLS_D)
37 | {
38 | #ifdef ZEPHIR_USE_PHP_SESSION
39 | php_session_start(TSRMLS_C);
40 | #else
41 | //zephir_call_func_params(NULL, NULL, SL("session_start") TSRMLS_CC, 0);
42 | #endif
43 | }
44 |
45 | void zephir_session_destroy(TSRMLS_D)
46 | {
47 | //zephir_call_func_params(NULL, NULL, SL("session_destroy") TSRMLS_CC, 0);
48 | }
49 |
50 | void zephir_get_session_id(zval *return_value, zval **return_value_ptr TSRMLS_DC)
51 | {
52 | #ifdef ZEPHIR_USE_PHP_SESSION
53 | if (PS(id)) {
54 | RETURN_STRING(PS(id), 1);
55 | }
56 |
57 | RETURN_EMPTY_STRING();
58 | #else
59 | //zephir_call_func_params(return_value, return_value_ptr, SL("session_id") TSRMLS_CC, 0);
60 | #endif
61 | }
62 |
63 | void zephir_set_session_id(zval *sid TSRMLS_DC)
64 | {
65 | #ifdef ZEPHIR_USE_PHP_SESSION
66 | zval copy;
67 | int use_copy = 0;
68 |
69 | if (unlikely(Z_TYPE_P(sid) != IS_STRING)) {
70 | zend_make_printable_zval(sid, ©, &use_copy);
71 | if (use_copy) {
72 | sid = ©
73 | }
74 | }
75 |
76 | if (PS(id)) {
77 | efree(PS(id));
78 | }
79 |
80 | PS(id) = estrndup(Z_STRVAL_P(sid), Z_STRLEN_P(sid));
81 |
82 | if (unlikely(use_copy)) {
83 | zval_dtor(©);
84 | }
85 | #else
86 | //zephir_call_func_params(NULL, NULL, SL("session_id") TSRMLS_CC, 1, sid);
87 | #endif
88 | }
89 |
--------------------------------------------------------------------------------
/ext/kernel/session.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_SESSION_H
22 | #define ZEPHIR_KERNEL_SESSION_H
23 |
24 | #include
25 | #include
26 |
27 | void zephir_session_start(TSRMLS_D);
28 | void zephir_session_destroy(TSRMLS_D);
29 | void zephir_get_session_id(zval *return_value, zval **return_value_ptr TSRMLS_DC);
30 | void zephir_set_session_id(zval *sid TSRMLS_DC);
31 |
32 | #endif /* ZEPHIR_KERNEL_SESSION_H */
33 |
--------------------------------------------------------------------------------
/ext/kernel/string.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Vladimir Kolesnikov |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_STRING_H
22 | #define ZEPHIR_KERNEL_STRING_H
23 |
24 | #include
25 | #include
26 | #include "kernel/main.h"
27 |
28 | #define ZEPHIR_TRIM_LEFT 1
29 | #define ZEPHIR_TRIM_RIGHT 2
30 | #define ZEPHIR_TRIM_BOTH 3
31 | #define ZEPHIR_SUBSTR_NO_LENGTH 1
32 |
33 | /** Fast char position */
34 | int zephir_memnstr(const zval *haystack, const zval *needle ZEPHIR_DEBUG_PARAMS);
35 | int zephir_memnstr_str(const zval *haystack, char *needle, unsigned int needle_length ZEPHIR_DEBUG_PARAMS);
36 |
37 | /** Function replacement */
38 | void zephir_fast_strlen(zval *return_value, zval *str);
39 | int zephir_fast_strlen_ev(zval *str);
40 | void zephir_fast_strtolower(zval *return_value, zval *str);
41 | void zephir_strtolower_inplace(zval *s);
42 | void zephir_fast_join(zval *result, zval *glue, zval *pieces TSRMLS_DC);
43 | void zephir_fast_join_str(zval *result, char *glue, unsigned int glue_length, zval *pieces TSRMLS_DC);
44 | void zephir_fast_explode(zval *result, zval *delimiter, zval *str, long limit TSRMLS_DC);
45 | void zephir_fast_explode_str(zval *result, const char *delimiter, int delimiter_length, zval *str, long limit TSRMLS_DC);
46 | void zephir_fast_strpos(zval *return_value, const zval *haystack, const zval *needle, unsigned int offset);
47 | void zephir_fast_strpos_str(zval *return_value, const zval *haystack, char *needle, unsigned int needle_length);
48 | void zephir_fast_stripos_str(zval *return_value, zval *haystack, char *needle, unsigned int needle_length);
49 | void zephir_fast_str_replace(zval **return_value, zval *search, zval *replace, zval *subject TSRMLS_DC);
50 | void zephir_fast_trim(zval *return_value, zval *str, zval *charlist, int where TSRMLS_DC);
51 | void zephir_fast_strip_tags(zval *return_value, zval *str);
52 | void zephir_fast_strtoupper(zval *return_value, zval *str);
53 |
54 | /** Camelize/Uncamelize */
55 | void zephir_camelize(zval *return_value, const zval *str);
56 | void zephir_uncamelize(zval *return_value, const zval *str);
57 |
58 | /** Starts/Ends with */
59 | int zephir_start_with(const zval *str, const zval *compared, zval *case_sensitive);
60 | int zephir_start_with_str(const zval *str, char *compared, unsigned int compared_length);
61 | int zephir_start_with_str_str(char *str, unsigned int str_length, char *compared, unsigned int compared_length);
62 | int zephir_end_with(const zval *str, const zval *compared, zval *case_sensitive);
63 | int zephir_end_with_str(const zval *str, char *compared, unsigned int compared_length);
64 |
65 | /** Random string */
66 | void zephir_random_string(zval *return_value, const zval *type, const zval *length TSRMLS_DC);
67 |
68 | /* Strips extra slashes */
69 | void zephir_remove_extra_slashes(zval *return_value, const zval *str);
70 |
71 | /** Generates a unique key for an array/object */
72 | void zephir_unique_key(zval *return_value, zval *prefix, zval *value TSRMLS_DC);
73 |
74 | /** spprintf */
75 | int zephir_spprintf(char **message, int max_len, char *format, ...);
76 |
77 | /* Substr */
78 | void zephir_substr(zval *return_value, zval *str, long from, long length, int flags);
79 |
80 | /** EOL */
81 | zval *zephir_eol(int eol TSRMLS_DC);
82 |
83 | /** Preg-Match */
84 | void zephir_preg_match(zval *return_value, zval *regex, zval *subject, zval *matches, int global, long flags, long offset TSRMLS_DC);
85 |
86 | /** Base64 */
87 | void zephir_base64_encode(zval *return_value, zval *data);
88 | void zephir_base64_decode(zval *return_value, zval *data);
89 |
90 | /** Hash */
91 | void zephir_md5(zval *return_value, zval *str);
92 | void zephir_crc32(zval *return_value, zval *str TSRMLS_DC);
93 |
94 | /** JSON */
95 | int zephir_json_encode(zval *return_value, zval **return_value_ptr, zval *v, int opts TSRMLS_DC);
96 | int zephir_json_decode(zval *return_value, zval **return_value_ptr, zval *v, zend_bool assoc TSRMLS_DC);
97 |
98 | /***/
99 | void zephir_lcfirst(zval *return_value, zval *s);
100 | void zephir_ucfirst(zval *return_value, zval *s);
101 | int zephir_http_build_query(zval *return_value, zval *params, char *sep TSRMLS_DC);
102 | void zephir_htmlspecialchars(zval *return_value, zval *string, zval *quoting, zval *charset TSRMLS_DC);
103 | void zephir_htmlentities(zval *return_value, zval *string, zval *quoting, zval *charset TSRMLS_DC);
104 | void zephir_strval(zval *return_value, zval *v);
105 | void zephir_date(zval *return_value, zval *format, zval *timestamp TSRMLS_DC);
106 | void zephir_addslashes(zval *return_value, zval *str TSRMLS_DC);
107 | void zephir_stripslashes(zval *return_value, zval *str TSRMLS_DC);
108 | void zephir_stripcslashes(zval *return_value, zval *str TSRMLS_DC);
109 |
110 | #if PHP_VERSION_ID < 50400
111 |
112 | const char* zend_new_interned_string(const char *arKey, int nKeyLength, int free_src TSRMLS_DC);
113 | #define ZEPHIR_ZVAL_MAYBE_INTERNED_STRING(pz, string) ZVAL_STRING(pz, string, 1);
114 |
115 | #else
116 |
117 | #define ZEPHIR_ZVAL_MAYBE_INTERNED_STRING(pz, string) \
118 | do { \
119 | if (IS_INTERNED(string)) { \
120 | ZVAL_STRINGL(pz, string, INTERNED_LEN(string)-1, 0); \
121 | } \
122 | else { \
123 | ZVAL_STRING(pz, string, 1); \
124 | } \
125 | } while (0)
126 |
127 | #endif /* PHP_VERSION_ID < 50400 */
128 |
129 | #endif /* ZEPHIR_KERNEL_STRING_H */
130 |
--------------------------------------------------------------------------------
/ext/kernel/time.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | */
16 |
17 | #ifdef HAVE_CONFIG_H
18 | #include "config.h"
19 | #endif
20 |
21 | #ifdef PHP_WIN32
22 | #include "win32/time.h"
23 | #elif defined(NETWARE)
24 | #include
25 | #include
26 | #else
27 | #include
28 | #endif
29 |
30 | #include
31 |
32 | #include "php.h"
33 | #include "php_ext.h"
34 |
35 | #include "kernel/main.h"
36 | #include "kernel/time.h"
37 | #include "kernel/operators.h"
38 |
39 | void zephir_time(zval *return_value)
40 | {
41 | RETURN_LONG(time(NULL));
42 | }
43 |
44 | void zephir_microtime(zval *return_value, zval *get_as_float TSRMLS_DC)
45 | {
46 | struct timeval tp = {0};
47 | char ret[100];
48 |
49 | if (gettimeofday(&tp, NULL)) {
50 | RETURN_FALSE;
51 | }
52 |
53 | if (get_as_float && ZEPHIR_IS_TRUE(get_as_float)) {
54 | RETURN_DOUBLE((double)(tp.tv_sec + tp.tv_usec / MICRO_IN_SEC));
55 | }
56 |
57 | snprintf(ret, 100, "%.8F %ld", tp.tv_usec / MICRO_IN_SEC, tp.tv_sec);
58 | RETURN_STRING(ret, 1);
59 | }
60 |
--------------------------------------------------------------------------------
/ext/kernel/time.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | */
16 |
17 | #ifndef ZEPHIR_KERNEL_TIME_H
18 | #define ZEPHIR_KERNEL_TIME_H
19 |
20 | #include
21 | #include
22 |
23 | #define MICRO_IN_SEC 1000000.00
24 |
25 | void zephir_time(zval *return_value);
26 | #ifdef HAVE_GETTIMEOFDAY
27 | void zephir_microtime(zval *return_value, zval *get_as_float TSRMLS_DC);
28 | #endif
29 |
30 | #endif /* ZEPHIR_KERNEL_TIME_H */
31 |
--------------------------------------------------------------------------------
/ext/kernel/variables.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Rack Lin |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifdef HAVE_CONFIG_H
22 | #include "config.h"
23 | #endif
24 |
25 | #include "php.h"
26 | #include "php_ext.h"
27 |
28 | #include "ext/standard/php_smart_str.h"
29 | #include "ext/standard/php_var.h"
30 |
31 | /**
32 | * Serializes php variables without using the PHP userland
33 | */
34 | void zephir_serialize(zval *return_value, zval **var TSRMLS_DC) {
35 |
36 | php_serialize_data_t var_hash;
37 | smart_str buf = {0};
38 |
39 | PHP_VAR_SERIALIZE_INIT(var_hash);
40 | php_var_serialize(&buf, var, &var_hash TSRMLS_CC);
41 | PHP_VAR_SERIALIZE_DESTROY(var_hash);
42 |
43 | if (EG(exception)) {
44 | smart_str_free(&buf);
45 | RETURN_FALSE;
46 | }
47 |
48 | if (buf.c) {
49 | RETURN_STRINGL(buf.c, buf.len, 0);
50 | } else {
51 | RETURN_NULL();
52 | }
53 | }
54 |
55 | /**
56 | * Unserializes php variables without using the PHP userland
57 | */
58 | void zephir_unserialize(zval *return_value, zval *var TSRMLS_DC) {
59 |
60 | const unsigned char *p;
61 | php_unserialize_data_t var_hash;
62 |
63 | if (Z_TYPE_P(var) != IS_STRING) {
64 | RETURN_FALSE;
65 | }
66 |
67 | if (Z_STRLEN_P(var) == 0) {
68 | RETURN_FALSE;
69 | }
70 |
71 | p = (const unsigned char*) Z_STRVAL_P(var);
72 | PHP_VAR_UNSERIALIZE_INIT(var_hash);
73 | if (!php_var_unserialize(&return_value, &p, p + Z_STRLEN_P(var), &var_hash TSRMLS_CC)) {
74 | PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
75 | zval_dtor(return_value);
76 | ZVAL_NULL(return_value);
77 | if (!EG(exception)) {
78 | php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - Z_STRVAL_P(var)), Z_STRLEN_P(var));
79 | }
80 | RETURN_FALSE;
81 | }
82 | PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
83 |
84 | }
85 |
86 | /**
87 | * var_export outputs php variables without using the PHP userland
88 | */
89 | void zephir_var_export(zval **var TSRMLS_DC) {
90 | php_var_export(var, 1 TSRMLS_CC);
91 | }
92 |
93 | /**
94 | * var_export returns php variables without using the PHP userland
95 | */
96 | void zephir_var_export_ex(zval *return_value, zval **var TSRMLS_DC) {
97 |
98 | smart_str buf = { NULL, 0, 0 };
99 |
100 | php_var_export_ex(var, 1, &buf TSRMLS_CC);
101 | smart_str_0(&buf);
102 | ZVAL_STRINGL(return_value, buf.c, buf.len, 0);
103 | }
104 |
105 | /**
106 | * var_dump outputs php variables without using the PHP userland
107 | */
108 | void zephir_var_dump(zval **var TSRMLS_DC) {
109 | php_var_dump(var, 1 TSRMLS_CC);
110 | }
111 |
--------------------------------------------------------------------------------
/ext/kernel/variables.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | +------------------------------------------------------------------------+
4 | | Zephir Language |
5 | +------------------------------------------------------------------------+
6 | | Copyright (c) 2011-2015 Zephir Team (http://www.zephir-lang.com) |
7 | +------------------------------------------------------------------------+
8 | | This source file is subject to the New BSD License that is bundled |
9 | | with this package in the file docs/LICENSE.txt. |
10 | | |
11 | | If you did not receive a copy of the license and are unable to |
12 | | obtain it through the world-wide-web, please send an email |
13 | | to license@zephir-lang.com so we can send you a copy immediately. |
14 | +------------------------------------------------------------------------+
15 | | Authors: Andres Gutierrez |
16 | | Eduar Carvajal |
17 | | Rack Lin |
18 | +------------------------------------------------------------------------+
19 | */
20 |
21 | #ifndef ZEPHIR_KERNEL_VARIABLES_H
22 | #define ZEPHIR_KERNEL_VARIABLES_H
23 |
24 | #include
25 | #include
26 |
27 | void zephir_serialize(zval *return_value, zval **var TSRMLS_DC);
28 | void zephir_unserialize(zval *return_value, zval *var TSRMLS_DC);
29 |
30 | void zephir_var_export(zval **var TSRMLS_DC);
31 | void zephir_var_export_ex(zval *return_value, zval **var TSRMLS_DC);
32 |
33 | void zephir_var_dump(zval **var TSRMLS_DC);
34 |
35 | #endif
--------------------------------------------------------------------------------
/phpiwire/Board.zep:
--------------------------------------------------------------------------------
1 | /*
2 | * Phpiwire: A PHP wrapper for wiringPi
3 | *
4 | * @author Andrew Collington, andy@amnuts.com
5 | * @version 0.2.0
6 | * @link https://github.com/amnuts/phpiwire
7 | * @license MIT, http://acollington.mit-license.org/
8 | *
9 | * Board control
10 | *
11 | * Further information about the intricacies of the pin modes, where they can
12 | * and cannot be used, etc., can be found on the wiringpi website.
13 | *
14 | * @see
15 | * @see
16 | */
17 |
18 | namespace Phpiwire;
19 |
20 | %{
21 | #include
22 | }%
23 |
24 | class Board
25 | {
26 | // pin numbering scheme
27 | const WIRINGPI = 0;
28 | const GPIO = 1;
29 | const SYSTEM = 2;
30 | const PHYSICAL = 3;
31 | // pwm mode
32 | const MARKSPACE = 0;
33 | const BALANCED = 1;
34 |
35 | protected scheme;
36 | protected schemeName = [];
37 | protected board = [];
38 |
39 | /**
40 | *
41 | */
42 | public function __construct(int! scheme = self::WIRINGPI)
43 | {
44 | this->mode(scheme);
45 | let this->schemeName = [
46 | self::WIRINGPI : "WiringPi pin numbers (virtual pin numbers 0 through 16)",
47 | self::GPIO : "GPIO pin numbers (direct pin numbers with no re-mapping - different across board revisions)",
48 | self::SYSTEM : "System numbers (uses /sys/class/gpio interface but pins first need exporting via gpio)",
49 | self::PHYSICAL : "Physical pin numbers (the P1 connector only)"
50 | ];
51 |
52 | var ver_model = "", ver_rev = "", ver_maker = "",
53 | ver_mem = "", ver_overvolted = "";
54 | var int_model = 0, int_rev = 0, int_maker = 0,
55 | int_mem = 0, int_overvolted = 0;
56 |
57 | %{
58 | char mb[7];
59 | int model, rev, maker, mem, overVolted;
60 | piBoardId(&model, &rev, &mem, &maker, &overVolted);
61 | ZVAL_STRING(ver_model, (char *)piModelNames[model], 1);
62 | ZVAL_STRING(ver_rev, (char *)piRevisionNames[rev], 1);
63 | ZVAL_STRING(ver_maker, (char *)piMakerNames[maker], 1);
64 | sprintf(mb, "%dMB", piMemorySize[mem]);
65 | ZVAL_STRING(ver_mem, mb, 1);
66 | ZVAL_BOOL(ver_overvolted, overVolted);
67 | ZVAL_LONG(&int_model, model);
68 | ZVAL_LONG(&int_rev, rev);
69 | ZVAL_LONG(&int_maker, maker);
70 | ZVAL_LONG(&int_mem, mem);
71 | ZVAL_LONG(&int_overvolted, overVolted);
72 | }%
73 |
74 | let this->board = [
75 | "model" : ["val" : int_model, "desc" : ver_model ],
76 | "revision" : ["val" : int_rev, "desc" : ver_rev ],
77 | "memory" : ["val" : int_mem, "desc" : ver_mem ],
78 | "maker" : ["val" : int_maker, "desc" : ver_maker ],
79 | "overvolted" : ["val" : int_overvolted, "desc" : ver_overvolted ]
80 | ];
81 | }
82 |
83 | /**
84 | * String representation of the board
85 | *
86 | * @return string
87 | */
88 | public function __toString()
89 | {
90 | var v;
91 | let v = this->version();
92 |
93 | return "Model: " . v["model"] . " (rev " . v["revision"]
94 | . ") built by " . v["maker"] . ", " . v["memory"]
95 | . (v["overvolted"] ? " [OV]" : "") . "\nUsing pin scheme: "
96 | . this->schemeName[this->scheme];
97 | }
98 |
99 | /**
100 | * Set up the board pin configuration
101 | *
102 | * @param int
103 | */
104 | public function mode(int! scheme)
105 | {
106 | int ret = -1;
107 |
108 | let this->scheme = scheme;
109 | switch scheme {
110 | case self::WIRINGPI:
111 | %{ ret = wiringPiSetup(); }%
112 | break;
113 | case self::GPIO:
114 | %{ ret = wiringPiSetupGpio(); }%
115 | break;
116 | case self::SYSTEM:
117 | %{ ret = wiringPiSetupSys(); }%
118 | break;
119 | case self::PHYSICAL:
120 | %{ ret = wiringPiSetupPhys(); }%
121 | break;
122 | default:
123 | throw new \Exception("Pin numbering scheme not supported");
124 | }
125 |
126 | if ret == -1 {
127 | throw new \Exception("Could not set board scheme");
128 | }
129 |
130 | return this;
131 | }
132 |
133 | /**
134 | * Get version information about the board
135 | *
136 | * @return array
137 | */
138 | public function version() -> array
139 | {
140 | return [
141 | "model" : this->board["model"]["desc"],
142 | "revision" : this->board["revision"]["desc"],
143 | "memory" : this->board["memory"]["desc"],
144 | "maker" : this->board["maker"]["desc"],
145 | "overvolted" : this->board["overvolted"]["desc"]
146 | ];
147 | }
148 |
149 | /**
150 | * Get the pin numbering scheme
151 | *
152 | * @return array
153 | */
154 | public function getPinScheme() -> array
155 | {
156 | return [
157 | "scheme" : this->scheme,
158 | "description" : this->schemeName[this->scheme]
159 | ];
160 | }
161 |
162 | /**
163 | * Instantiate a Pin class
164 | *
165 | * @param int pin The pin number to use
166 | * @return Pin
167 | */
168 | public function getPin(int! pin) ->
169 | {
170 | return new Pin(pin, this);
171 | }
172 |
173 | /**
174 | * Set the mode for the PWM generator.
175 | *
176 | * @param int
177 | */
178 | public function pwmMode(int! mode)
179 | {
180 | if !in_array(mode, [self::BALANCED, self::MARKSPACE]) {
181 | throw new \Exception("PWM mode not supported");
182 | }
183 |
184 | %{ pwmSetMode(mode); }%
185 |
186 | return this;
187 | }
188 |
189 | /**
190 | * Set the range for the PWM generator.
191 | *
192 | * @param int
193 | */
194 | public function pwmRange(uint! range = 1024)
195 | {
196 | %{ pwmSetRange(range); }%
197 |
198 | return this;
199 | }
200 |
201 | /**
202 | * Set the divisor for the PWM clock.
203 | *
204 | * @param int
205 | */
206 | public function pwmClock(int! divisor)
207 | {
208 | %{ pwmSetClock(divisor); }%
209 |
210 | return this;
211 | }
212 |
213 | }
214 |
215 |
--------------------------------------------------------------------------------
/phpiwire/Pin.zep:
--------------------------------------------------------------------------------
1 | /*
2 | * Phpiwire: A PHP wrapper for wiringPi
3 | *
4 | * @author Andrew Collington, andy@amnuts.com
5 | * @version 0.2.0
6 | * @link https://github.com/amnuts/phpiwire
7 | * @license MIT, http://acollington.mit-license.org/
8 | *
9 | * Pin control
10 | *
11 | * Further information about the intricacies of the pin modes, where they can
12 | * and cannot be used, etc., can be found on the wiringpi website.
13 | *
14 | * @see
15 | * @see
16 | */
17 |
18 | namespace Phpiwire;
19 |
20 | %{
21 | #include
22 | }%
23 |
24 | class Pin
25 | {
26 | // read/write types
27 | const DIGITAL = 0;
28 | const ANALOG = 1;
29 | const PWM = 2;
30 | const SOFT_PWM = 3;
31 | // pin modes
32 | const INPUT = 0;
33 | const OUTPUT = 1;
34 | const PWM_OUT = 2;
35 | const CLOCK = 3;
36 | const SOFT_PWM_OUT = 4;
37 | // pud modes
38 | const OFF = 0;
39 | const DOWN = 1;
40 | const UP = 2;
41 | // values
42 | const LOW = 0;
43 | const HIGH = 1;
44 |
45 | protected id { get };
46 | protected board { get };
47 | protected mode = null;
48 | protected modeName = [];
49 |
50 | /**
51 | * Initialize the Pin class
52 | */
53 | public function __construct(int! pin, board)
54 | {
55 | let this->id = pin;
56 | let this->board = board;
57 | let this->modeName = [
58 | self::INPUT : "Input",
59 | self::OUTPUT : "Output",
60 | self::PWM_OUT : "Hardware PWM output",
61 | self::SOFT_PWM_OUT : "Software PWM output",
62 | self::CLOCK : "GPIO clock"
63 | ];
64 | }
65 |
66 | /**
67 | * String representation of the pin
68 | *
69 | * @return string
70 | */
71 | public function __toString()
72 | {
73 | return "Pin " . this->id . ", mode: " . this->is(true) . "\n"
74 | . "Digital value: " . this->digitalRead()
75 | . ", Analog value: " . this->analogRead() . "\n";
76 | }
77 |
78 | /**
79 | * Set pin mode
80 | *
81 | * @param int
82 | */
83 | public function mode(int! mode)
84 | {
85 | if !in_array(mode, [self::INPUT, self::OUTPUT, self::PWM_OUT, self::SOFT_PWM_OUT, self::CLOCK]) {
86 | throw new \Exception("Pin mode not supported");
87 | }
88 |
89 | %{
90 | zval *pinnum;
91 | zephir_read_property_this(&pinnum, this_ptr, SL("id"), PH_NOISY_CC);
92 | }%
93 | if mode == self::SOFT_PWM_OUT {
94 | var scheme;
95 | let scheme = this->board->getPinScheme();
96 | if scheme["scheme"] == Board::SYSTEM {
97 | throw new \Exception("Cannot use soft PWM with system number pin layout");
98 | }
99 | %{
100 | softPwmCreate (Z_LVAL_P(pinnum), 0, 100);
101 | }%
102 | } else {
103 | %{
104 | pinMode(Z_LVAL_P(pinnum), mode);
105 | }%
106 | }
107 |
108 | let this->mode = mode;
109 | return this;
110 | }
111 |
112 | /**
113 | * Get the pin mode
114 | *
115 | * @param bool Return the value as a string
116 | */
117 | public function is(bool! asString = false)
118 | {
119 | return (asString ? this->modeName[this->mode] : this->mode);
120 | }
121 |
122 | /**
123 | * Sets the pull-up or pull-down resistor mode on the pin.
124 | *
125 | * The mode can either be OFF, (no pull up/down), DOWN (pull to ground)
126 | * or UP (pull to 3.3v). The internal pull up/down resistors have a value
127 | * of approximately 50KΩ on the Raspberry Pi.
128 | *
129 | * @param int
130 | */
131 | public function pudMode(int! mode)
132 | {
133 | if !in_array(mode, [self::OFF, self::DOWN, self::UP]) {
134 | throw new \Exception("Pull-up/down resistor mode not supported");
135 | }
136 |
137 | %{
138 | zval *pinnum;
139 | zephir_read_property_this(&pinnum, this_ptr, SL("id"), PH_NOISY_CC);
140 | pullUpDnControl(Z_LVAL_P(pinnum), mode);
141 | }%
142 |
143 | return this;
144 | }
145 |
146 | /**
147 | * Read the value from the pin
148 | *
149 | * @param int type Read as digital or analog
150 | * @return var
151 | */
152 | public function read(int! type = self::DIGITAL) -> long
153 | {
154 | var value = null;
155 |
156 | %{
157 | zval *pinnum;
158 | zephir_read_property_this(&pinnum, this_ptr, SL("id"), PH_NOISY_CC);
159 | int pin = Z_LVAL_P(pinnum);
160 | }%
161 |
162 | switch type {
163 | case self::DIGITAL:
164 | %{ ZVAL_LONG(value, digitalRead(pin)); }%
165 | break;
166 | case self::ANALOG:
167 | %{ ZVAL_LONG(value, analogRead(pin)); }%
168 | break;
169 | }
170 |
171 | return value;
172 | }
173 |
174 | /**
175 | * Get digital pin value
176 | *
177 | * @return var
178 | */
179 | public function digitalRead()
180 | {
181 | return this->read(self::DIGITAL);
182 | }
183 |
184 | /**
185 | * Get analog pin value
186 | *
187 | * @return var
188 | */
189 | public function analogRead()
190 | {
191 | return this->read(self::ANALOG);
192 | }
193 |
194 | /**
195 | * Write a value to the pin.
196 | *
197 | * With DIGITAL, value is either high (1) or low (0). Any non-zero value
198 | * is considered high, but only 0 is considered low.
199 | *
200 | * With PWM, the Raspberry Pi has one on-board PWM pin - pin 1, 18 or 12
201 | * depending on whether you're using the wiringpi numbering scheme, or
202 | * GPIO, or physical (respectively). Not available in system mode.
203 | *
204 | * @param int value
205 | * @param int type Write digital or analog pin
206 | * @return void
207 | */
208 | public function write(int! value, int! type = self::DIGITAL)
209 | {
210 | %{
211 | zval *pinnum;
212 | zephir_read_property_this(&pinnum, this_ptr, SL("id"), PH_NOISY_CC);
213 | int pin = Z_LVAL_P(pinnum);
214 | }%
215 |
216 | switch type {
217 | case self::DIGITAL:
218 | %{ digitalWrite(pin, value); }%
219 | break;
220 | case self::ANALOG:
221 | %{ analogWrite(pin, value); }%
222 | break;
223 | case self::PWM:
224 | %{ pwmWrite(pin, value); }%
225 | break;
226 | case self::SOFT_PWM:
227 | %{ softPwmWrite(pin, value); }%
228 | break;
229 | }
230 |
231 | return this;
232 | }
233 |
234 | /**
235 | * Set digital pin value
236 | *
237 | * @return var
238 | */
239 | public function digitalWrite(int! value)
240 | {
241 | return this->write(value, self::DIGITAL);
242 | }
243 |
244 | /**
245 | * Set analog pin value
246 | *
247 | * @return var
248 | */
249 | public function analogWrite(int! value)
250 | {
251 | return this->write(value, self::ANALOG);
252 | }
253 |
254 | /**
255 | * Set PWM pin value
256 | *
257 | * @return var
258 | */
259 | public function pwmWrite(int! value)
260 | {
261 | return this->write(value, self::PWM);
262 | }
263 |
264 | /**
265 | * Set PWM pin value
266 | *
267 | * @return var
268 | */
269 | public function softPwmWrite(int! value)
270 | {
271 | return this->write(value, self::SOFT_PWM);
272 | }
273 | }
274 |
--------------------------------------------------------------------------------
/phpstorm-stub.php:
--------------------------------------------------------------------------------
1 |