mirror of
https://github.com/php/php-src.git
synced 2024-11-27 11:53:33 +08:00
49c1e6eb33
* Zend/zend_operators: pass const pointers to zend_is_identical() * Zend/zend_operators: pass const pointers to zend_get_{long,double}() * Zend/Optimizer/sccp: make pointers const * Zend/Optimizer/scdf: make pointers const * Zend/Optimizer/zend_worklist: make pointers const * Zend/Optimizer/zend_optimizer: make pointers const * Zend/zend_compile: make pointers const
120 lines
3.8 KiB
C
120 lines
3.8 KiB
C
/*
|
|
+----------------------------------------------------------------------+
|
|
| Zend Engine |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) The PHP Group |
|
|
+----------------------------------------------------------------------+
|
|
| This source file is subject to version 3.01 of the PHP license, |
|
|
| that is bundled with this package in the file LICENSE, and is |
|
|
| available through the world-wide-web at the following url: |
|
|
| https://www.php.net/license/3_01.txt |
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
+----------------------------------------------------------------------+
|
|
| Authors: Andy Wingo <wingo@igalia.com> |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
#ifndef _ZEND_WORKLIST_H_
|
|
#define _ZEND_WORKLIST_H_
|
|
|
|
#include "zend_arena.h"
|
|
#include "zend_bitset.h"
|
|
|
|
typedef struct _zend_worklist_stack {
|
|
int *buf;
|
|
int len;
|
|
int capacity;
|
|
} zend_worklist_stack;
|
|
|
|
#define ZEND_WORKLIST_STACK_ALLOCA(s, _len, use_heap) do { \
|
|
(s)->buf = (int*)do_alloca(sizeof(int) * _len, use_heap); \
|
|
(s)->len = 0; \
|
|
(s)->capacity = _len; \
|
|
} while (0)
|
|
|
|
#define ZEND_WORKLIST_STACK_FREE_ALLOCA(s, use_heap) \
|
|
free_alloca((s)->buf, use_heap)
|
|
|
|
static inline void zend_worklist_stack_prepare(zend_arena **arena, zend_worklist_stack *stack, int len)
|
|
{
|
|
ZEND_ASSERT(len >= 0);
|
|
|
|
stack->buf = (int*)zend_arena_calloc(arena, sizeof(*stack->buf), len);
|
|
stack->len = 0;
|
|
stack->capacity = len;
|
|
}
|
|
|
|
static inline void zend_worklist_stack_push(zend_worklist_stack *stack, int i)
|
|
{
|
|
ZEND_ASSERT(stack->len < stack->capacity);
|
|
stack->buf[stack->len++] = i;
|
|
}
|
|
|
|
static inline int zend_worklist_stack_peek(const zend_worklist_stack *stack)
|
|
{
|
|
ZEND_ASSERT(stack->len);
|
|
return stack->buf[stack->len - 1];
|
|
}
|
|
|
|
static inline int zend_worklist_stack_pop(zend_worklist_stack *stack)
|
|
{
|
|
ZEND_ASSERT(stack->len);
|
|
return stack->buf[--stack->len];
|
|
}
|
|
|
|
typedef struct _zend_worklist {
|
|
zend_bitset visited;
|
|
zend_worklist_stack stack;
|
|
} zend_worklist;
|
|
|
|
#define ZEND_WORKLIST_ALLOCA(w, _len, use_heap) do { \
|
|
(w)->stack.buf = (int*)do_alloca(ZEND_MM_ALIGNED_SIZE(sizeof(int) * _len) + sizeof(zend_ulong) * zend_bitset_len(_len), use_heap); \
|
|
(w)->stack.len = 0; \
|
|
(w)->stack.capacity = _len; \
|
|
(w)->visited = (zend_bitset)((char*)(w)->stack.buf + ZEND_MM_ALIGNED_SIZE(sizeof(int) * _len)); \
|
|
memset((w)->visited, 0, sizeof(zend_ulong) * zend_bitset_len(_len)); \
|
|
} while (0)
|
|
|
|
#define ZEND_WORKLIST_FREE_ALLOCA(w, use_heap) \
|
|
free_alloca((w)->stack.buf, use_heap)
|
|
|
|
static inline void zend_worklist_prepare(zend_arena **arena, zend_worklist *worklist, int len)
|
|
{
|
|
ZEND_ASSERT(len >= 0);
|
|
worklist->visited = (zend_bitset)zend_arena_calloc(arena, sizeof(zend_ulong), zend_bitset_len(len));
|
|
zend_worklist_stack_prepare(arena, &worklist->stack, len);
|
|
}
|
|
|
|
static inline int zend_worklist_len(const zend_worklist *worklist)
|
|
{
|
|
return worklist->stack.len;
|
|
}
|
|
|
|
static inline bool zend_worklist_push(zend_worklist *worklist, int i)
|
|
{
|
|
ZEND_ASSERT(i >= 0 && i < worklist->stack.capacity);
|
|
|
|
if (zend_bitset_in(worklist->visited, i)) {
|
|
return 0;
|
|
}
|
|
|
|
zend_bitset_incl(worklist->visited, i);
|
|
zend_worklist_stack_push(&worklist->stack, i);
|
|
return 1;
|
|
}
|
|
|
|
static inline int zend_worklist_peek(const zend_worklist *worklist)
|
|
{
|
|
return zend_worklist_stack_peek(&worklist->stack);
|
|
}
|
|
|
|
static inline int zend_worklist_pop(zend_worklist *worklist)
|
|
{
|
|
/* Does not clear visited flag */
|
|
return zend_worklist_stack_pop(&worklist->stack);
|
|
}
|
|
|
|
#endif /* _ZEND_WORKLIST_H_ */
|