Move jerry-core/parser/collections to jerry-core/parser/js/collections.
JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "array-list.h"
|
||||
#include "mem-heap.h"
|
||||
#include "jrt-libc-includes.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t element_size;
|
||||
size_t len;
|
||||
size_t size;
|
||||
} array_list_header;
|
||||
|
||||
static array_list_header *
|
||||
extract_header (array_list al)
|
||||
{
|
||||
JERRY_ASSERT (al != null_list);
|
||||
array_list_header *header = (array_list_header *) al;
|
||||
return header;
|
||||
}
|
||||
|
||||
static uint8_t *
|
||||
data (array_list al)
|
||||
{
|
||||
return (uint8_t *) al + sizeof (array_list_header);
|
||||
}
|
||||
|
||||
array_list
|
||||
array_list_append (array_list al, void *element)
|
||||
{
|
||||
array_list_header *h = extract_header (al);
|
||||
if ((h->len + 1) * h->element_size + sizeof (array_list_header) > h->size)
|
||||
{
|
||||
size_t size = mem_heap_recommend_allocation_size (h->size + h->element_size);
|
||||
JERRY_ASSERT (size > h->size);
|
||||
|
||||
uint8_t* new_block_p = (uint8_t*) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
memcpy (new_block_p, h, h->size);
|
||||
memset (new_block_p + h->size, 0, size - h->size);
|
||||
|
||||
mem_heap_free_block ((uint8_t *) h);
|
||||
|
||||
h = (array_list_header *) new_block_p;
|
||||
h->size = size;
|
||||
al = (array_list) h;
|
||||
}
|
||||
memcpy (data (al) + (h->len * h->element_size), element, h->element_size);
|
||||
h->len++;
|
||||
return al;
|
||||
}
|
||||
|
||||
void
|
||||
array_list_drop_last (array_list al)
|
||||
{
|
||||
array_list_header *h = extract_header (al);
|
||||
JERRY_ASSERT (h->len > 0);
|
||||
h->len--;
|
||||
}
|
||||
|
||||
void *
|
||||
array_list_element (array_list al, size_t index)
|
||||
{
|
||||
array_list_header *h = extract_header (al);
|
||||
if (h->len <= index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return data (al) + (index * h->element_size);
|
||||
}
|
||||
|
||||
void
|
||||
array_list_set_element (array_list al, size_t index, void *elem)
|
||||
{
|
||||
array_list_header *h = extract_header (al);
|
||||
JERRY_ASSERT (index < h->len);
|
||||
memcpy (data (al) + (index * h->element_size), elem, h->element_size);
|
||||
}
|
||||
|
||||
void *
|
||||
array_list_last_element (array_list al, size_t index)
|
||||
{
|
||||
array_list_header *h = extract_header (al);
|
||||
if (index == 0 || index > h->len)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return array_list_element (al, (size_t) (h->len - index));
|
||||
}
|
||||
|
||||
void
|
||||
array_list_set_last_element (array_list al, size_t index, void *elem)
|
||||
{
|
||||
array_list_header *h = extract_header (al);
|
||||
JERRY_ASSERT (index != 0 && index <= h->len);
|
||||
array_list_set_element (al, (size_t) (h->len - index), elem);
|
||||
}
|
||||
|
||||
array_list
|
||||
array_list_init (uint8_t element_size)
|
||||
{
|
||||
size_t size = mem_heap_recommend_allocation_size (sizeof (array_list_header));
|
||||
array_list_header *header = (array_list_header *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
memset (header, 0, size);
|
||||
header->element_size = element_size;
|
||||
header->len = 0;
|
||||
header->size = size;
|
||||
return (array_list) header;
|
||||
}
|
||||
|
||||
size_t
|
||||
array_list_len (array_list al)
|
||||
{
|
||||
array_list_header *h = extract_header (al);
|
||||
return h->len;
|
||||
}
|
||||
|
||||
void
|
||||
array_list_free (array_list al)
|
||||
{
|
||||
array_list_header *h = extract_header (al);
|
||||
mem_heap_free_block ((uint8_t *) h);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ARRAY_LIST_H
|
||||
#define ARRAY_LIST_H
|
||||
|
||||
#include "jrt.h"
|
||||
|
||||
typedef uint8_t* array_list;
|
||||
#define null_list NULL
|
||||
|
||||
array_list array_list_init (uint8_t);
|
||||
void array_list_free (array_list);
|
||||
array_list array_list_append (array_list, void *);
|
||||
void array_list_drop_last (array_list);
|
||||
void *array_list_element (array_list, size_t);
|
||||
void array_list_set_element (array_list, size_t, void *);
|
||||
void *array_list_last_element (array_list, size_t);
|
||||
void array_list_set_last_element (array_list, size_t, void *);
|
||||
size_t array_list_len (array_list);
|
||||
|
||||
#endif /* ARRAY_LIST_H */
|
||||
@@ -0,0 +1,130 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hash-table.h"
|
||||
#include "array-list.h"
|
||||
#include "mem-heap.h"
|
||||
#include "jrt-libc-includes.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t (*hash) (void *);
|
||||
array_list *data;
|
||||
uint16_t size;
|
||||
uint8_t key_size;
|
||||
uint8_t value_size;
|
||||
mem_heap_alloc_term_t alloc_term;
|
||||
} hash_table_int;
|
||||
|
||||
static hash_table_int *
|
||||
extract_header (hash_table ht)
|
||||
{
|
||||
JERRY_ASSERT (ht != null_hash);
|
||||
hash_table_int *hti = (hash_table_int *) ht;
|
||||
return hti;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
bucket_size (hash_table_int *hti)
|
||||
{
|
||||
return (uint8_t) (hti->key_size + hti->value_size);
|
||||
}
|
||||
|
||||
static array_list
|
||||
get_list (hash_table_int *h, uint16_t i)
|
||||
{
|
||||
return h->data[i];
|
||||
}
|
||||
|
||||
static void
|
||||
set_list (hash_table_int *h, uint16_t i, array_list al)
|
||||
{
|
||||
h->data[i] = al;
|
||||
}
|
||||
|
||||
void
|
||||
hash_table_insert (hash_table ht, void *key, void *value)
|
||||
{
|
||||
hash_table_int *hti = extract_header (ht);
|
||||
uint16_t index = hti->hash (key);
|
||||
JERRY_ASSERT (index < hti->size);
|
||||
array_list list = get_list (hti, index);
|
||||
if (list == null_list)
|
||||
{
|
||||
list = array_list_init (bucket_size (hti));
|
||||
}
|
||||
uint8_t *bucket = (uint8_t*) mem_heap_alloc_block (bucket_size (hti), hti->alloc_term);
|
||||
memcpy (bucket, key, hti->key_size);
|
||||
memcpy (bucket + hti->key_size, value, hti->value_size);
|
||||
list = array_list_append (list, bucket);
|
||||
hti->data[index] = list;
|
||||
mem_heap_free_block (bucket);
|
||||
}
|
||||
|
||||
void *
|
||||
hash_table_lookup (hash_table ht, void *key)
|
||||
{
|
||||
JERRY_ASSERT (key != NULL);
|
||||
hash_table_int *h = extract_header (ht);
|
||||
uint16_t index = h->hash (key);
|
||||
array_list al = get_list (h, index);
|
||||
if (al == null_list)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
for (uint16_t i = 0; i < array_list_len (al); i++)
|
||||
{
|
||||
uint8_t *bucket = (uint8_t*) array_list_element (al, i);
|
||||
JERRY_ASSERT (bucket != NULL);
|
||||
if (!memcmp (bucket, key, h->key_size))
|
||||
{
|
||||
return bucket + h->key_size;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash_table
|
||||
hash_table_init (uint8_t key_size, uint8_t value_size, uint16_t size,
|
||||
uint16_t (*hash) (void *), mem_heap_alloc_term_t alloc_term)
|
||||
{
|
||||
hash_table_int *res = (hash_table_int *) mem_heap_alloc_block (sizeof (hash_table_int), alloc_term);
|
||||
memset (res, 0, sizeof (hash_table_int));
|
||||
res->key_size = key_size;
|
||||
res->value_size = value_size;
|
||||
res->size = size;
|
||||
res->alloc_term = alloc_term;
|
||||
res->data = (array_list *) mem_heap_alloc_block (size * sizeof (array_list), alloc_term);
|
||||
memset (res->data, 0, size * sizeof (array_list));
|
||||
res->hash = hash;
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
hash_table_free (hash_table ht)
|
||||
{
|
||||
hash_table_int *h = extract_header (ht);
|
||||
for (uint16_t i = 0; i < h->size; i++)
|
||||
{
|
||||
array_list al = get_list (h, i);
|
||||
if (al != null_list)
|
||||
{
|
||||
array_list_free (al);
|
||||
set_list (h, i, null_list);
|
||||
}
|
||||
}
|
||||
mem_heap_free_block ((uint8_t *) h->data);
|
||||
mem_heap_free_block ((uint8_t *) h);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/* Copyright 2014 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
This file contains functions to create and manipulate hash-tables.
|
||||
Before using the hash initialize it by calling hash_table_init function.
|
||||
The function takes pointer to hash function as the last parameter.
|
||||
URGENT: the result of the hash function must not be greater than size of the hash table.
|
||||
To insert a key-value pair, use hash_table_insert function.
|
||||
To lookup a value by the key, use hash_table_lookup function.
|
||||
After using the hash, delete it by calling hash_table_free function.
|
||||
*/
|
||||
#ifndef HASH_TABLE_H
|
||||
#define HASH_TABLE_H
|
||||
|
||||
#include "mem-heap.h"
|
||||
|
||||
typedef void* hash_table;
|
||||
#define null_hash NULL
|
||||
|
||||
hash_table hash_table_init (uint8_t, uint8_t, uint16_t, uint16_t (*hash) (void *), mem_heap_alloc_term_t);
|
||||
void hash_table_free (hash_table);
|
||||
void hash_table_insert (hash_table, void *, void *);
|
||||
void *hash_table_lookup (hash_table, void *);
|
||||
|
||||
#endif /* HASH_TABLE_H */
|
||||
@@ -0,0 +1,112 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "linked-list.h"
|
||||
#include "jrt-libc-includes.h"
|
||||
#include "mem-heap.h"
|
||||
|
||||
typedef struct linked_list_header
|
||||
{
|
||||
struct linked_list_header *next;
|
||||
uint16_t element_size;
|
||||
} linked_list_header;
|
||||
|
||||
#define ASSERT_LIST(list) \
|
||||
do { \
|
||||
linked_list_header *header = (linked_list_header *) list; \
|
||||
JERRY_ASSERT (header); \
|
||||
} while (0);
|
||||
|
||||
static size_t linked_list_block_size (uint16_t element_size)
|
||||
{
|
||||
return mem_heap_recommend_allocation_size (sizeof (linked_list_header) + element_size) - sizeof (linked_list_header);
|
||||
}
|
||||
|
||||
linked_list
|
||||
linked_list_init (uint16_t element_size)
|
||||
{
|
||||
size_t size = sizeof (linked_list_header) + linked_list_block_size (element_size);
|
||||
linked_list list = (linked_list) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
if (list == null_list)
|
||||
{
|
||||
printf ("Out of memory");
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
memset (list, 0, size);
|
||||
linked_list_header* header = (linked_list_header *) list;
|
||||
header->next = null_list;
|
||||
header->element_size = element_size;
|
||||
return list;
|
||||
}
|
||||
|
||||
void
|
||||
linked_list_free (linked_list list)
|
||||
{
|
||||
ASSERT_LIST (list);
|
||||
linked_list_header *header = (linked_list_header *) list;
|
||||
if (header->next)
|
||||
{
|
||||
linked_list_free ((linked_list) header->next);
|
||||
}
|
||||
mem_heap_free_block (list);
|
||||
}
|
||||
|
||||
void *
|
||||
linked_list_element (linked_list list, size_t element_num)
|
||||
{
|
||||
ASSERT_LIST (list);
|
||||
linked_list_header *header = (linked_list_header *) list;
|
||||
size_t block_size = linked_list_block_size (header->element_size);
|
||||
linked_list raw = list + sizeof (linked_list_header);
|
||||
if (block_size < header->element_size * (element_num + 1))
|
||||
{
|
||||
if (header->next)
|
||||
{
|
||||
return linked_list_element ((linked_list) header->next,
|
||||
element_num - (block_size / header->element_size));
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
raw += header->element_size * element_num;
|
||||
return raw;
|
||||
}
|
||||
|
||||
void
|
||||
linked_list_set_element (linked_list list, size_t element_num, void *element)
|
||||
{
|
||||
ASSERT_LIST (list);
|
||||
linked_list_header *header = (linked_list_header *) list;
|
||||
size_t block_size = linked_list_block_size (header->element_size);
|
||||
uint8_t *raw = (uint8_t *) (header + 1);
|
||||
if (block_size < header->element_size * (element_num + 1))
|
||||
{
|
||||
if (header->next == null_list)
|
||||
{
|
||||
header->next = (linked_list_header *) linked_list_init (header->element_size);
|
||||
}
|
||||
linked_list_set_element ((linked_list) header->next,
|
||||
element_num - (block_size / header->element_size),
|
||||
element);
|
||||
return;
|
||||
}
|
||||
if (element == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
memcpy (raw + element_num * header->element_size, element, header->element_size);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef LINKED_LIST_H
|
||||
#define LINKED_LIST_H
|
||||
|
||||
#include "jrt.h"
|
||||
|
||||
typedef uint8_t* linked_list;
|
||||
#define null_list NULL
|
||||
|
||||
linked_list linked_list_init (uint16_t);
|
||||
void linked_list_free (linked_list);
|
||||
void *linked_list_element (linked_list, size_t);
|
||||
void linked_list_set_element (linked_list, size_t, void *);
|
||||
|
||||
#endif /* LINKED_LIST_H */
|
||||
@@ -0,0 +1,64 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "lit-id-hash-table.h"
|
||||
#include "bytecode-data.h"
|
||||
|
||||
lit_id_hash_table *
|
||||
lit_id_hash_table_init (size_t buckets_count, size_t blocks_count)
|
||||
{
|
||||
size_t size = mem_heap_recommend_allocation_size (sizeof (lit_id_hash_table));
|
||||
lit_id_hash_table *table = (lit_id_hash_table *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM);
|
||||
memset (table, 0, size);
|
||||
size = mem_heap_recommend_allocation_size (sizeof (lit_cpointer_t) * buckets_count);
|
||||
table->raw_buckets = (lit_cpointer_t *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM);
|
||||
memset (table->raw_buckets, 0, size);
|
||||
size = mem_heap_recommend_allocation_size (sizeof (lit_cpointer_t *) * blocks_count);
|
||||
table->buckets = (lit_cpointer_t **) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM);
|
||||
memset (table->buckets, 0, size);
|
||||
table->current_bucket_pos = 0;
|
||||
return table;
|
||||
}
|
||||
|
||||
void
|
||||
lit_id_hash_table_free (lit_id_hash_table *table)
|
||||
{
|
||||
JERRY_ASSERT (table);
|
||||
mem_heap_free_block ((uint8_t *) table->raw_buckets);
|
||||
mem_heap_free_block ((uint8_t *) table->buckets);
|
||||
mem_heap_free_block ((uint8_t *) table);
|
||||
}
|
||||
|
||||
void
|
||||
lit_id_hash_table_insert (lit_id_hash_table *table, idx_t uid, opcode_counter_t oc, lit_cpointer_t lit_cp)
|
||||
{
|
||||
JERRY_ASSERT (table);
|
||||
size_t block_id = oc / BLOCK_SIZE;
|
||||
if (table->buckets[block_id] == NULL)
|
||||
{
|
||||
table->buckets[block_id] = table->raw_buckets + table->current_bucket_pos;
|
||||
}
|
||||
table->buckets[block_id][uid] = lit_cp;
|
||||
table->current_bucket_pos++;
|
||||
}
|
||||
|
||||
lit_cpointer_t
|
||||
lit_id_hash_table_lookup (lit_id_hash_table *table, idx_t uid, opcode_counter_t oc)
|
||||
{
|
||||
JERRY_ASSERT (table);
|
||||
size_t block_id = oc / BLOCK_SIZE;
|
||||
JERRY_ASSERT (table->buckets[block_id]);
|
||||
return table->buckets[block_id][uid];
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef LIT_ID_HASH_TABLE
|
||||
#define LIT_ID_HASH_TABLE
|
||||
|
||||
#include "jrt.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "opcodes.h"
|
||||
#include "lit-literal.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t current_bucket_pos;
|
||||
lit_cpointer_t *raw_buckets;
|
||||
lit_cpointer_t **buckets;
|
||||
} lit_id_hash_table;
|
||||
|
||||
lit_id_hash_table *lit_id_hash_table_init (size_t, size_t);
|
||||
void lit_id_hash_table_free (lit_id_hash_table *);
|
||||
void lit_id_hash_table_insert (lit_id_hash_table *, idx_t, opcode_counter_t, lit_cpointer_t);
|
||||
lit_cpointer_t lit_id_hash_table_lookup (lit_id_hash_table *, idx_t, opcode_counter_t);
|
||||
|
||||
#endif /* LIT_ID_HASH_TABLE */
|
||||
@@ -0,0 +1,236 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
This file contains macros to define and use stacks.
|
||||
Use macro STACK or STATIC_STACK to create stack variable and define all necessaty routines.
|
||||
Also, define variable with name NAME##_global_size. If the variable more than 0,
|
||||
first NAME##_global_size element will remain untouched during STACK_PUSH and STACK_POP operations.
|
||||
Before using the stack, init it by calling STACK_INIT macro.
|
||||
Use macros STACK_PUSH, STACK_POP, STACK_DROP, STACK_CLEAN and STACK_HEAD to manipulate the stack.
|
||||
DO NOT FORGET to free stack memory by calling STACK_FREE macro.
|
||||
For check usage of stack during a function, use STACK_DECLARE_USAGE and STACK_CHECK_USAGE macros.
|
||||
|
||||
For the purpose of memory fragmentation reduction, the memory is allocated by chunks and them are
|
||||
used to store data. The chunks are connected to each other in manner of double-linked list.
|
||||
|
||||
Macro STACK_CONVERT_TO_RAW_DATA allocates memory, so use it after finishing working with the stack.
|
||||
|
||||
Example (parser.c):
|
||||
|
||||
enum
|
||||
{
|
||||
temp_name,
|
||||
min_temp_name,
|
||||
max_temp_name,
|
||||
temp_names_global_size
|
||||
};
|
||||
STACK (temp_names, uint8_t, uint8_t)
|
||||
|
||||
#define GLOBAL(NAME, VAR) \
|
||||
STACK_ELEMENT (NAME, VAR)
|
||||
|
||||
#define MAX_TEMP_NAME() \
|
||||
GLOBAL (temp_names, max_temp_name)
|
||||
|
||||
#define MIN_TEMP_NAME() \
|
||||
GLOBAL (temp_names, min_temp_name)
|
||||
|
||||
#define TEMP_NAME() \
|
||||
GLOBAL (temp_names, temp_name)
|
||||
|
||||
void
|
||||
parser_init (void)
|
||||
{
|
||||
STACK_INIT (temp_names)
|
||||
}
|
||||
|
||||
void
|
||||
parser_free (void)
|
||||
{
|
||||
STACK_FREE (temp_names)
|
||||
}
|
||||
*/
|
||||
#ifndef STACK_H
|
||||
#define STACK_H
|
||||
|
||||
#include "array-list.h"
|
||||
|
||||
#define DEFINE_STACK_TYPE(NAME, TYPE) \
|
||||
typedef TYPE NAME##_stack_value_type; \
|
||||
typedef struct \
|
||||
{ \
|
||||
array_list data; \
|
||||
} \
|
||||
NAME##_stack;
|
||||
|
||||
#define STACK_INIT(NAME) \
|
||||
do { \
|
||||
NAME.data = array_list_init (sizeof (NAME##_stack_value_type)); \
|
||||
} while (0)
|
||||
|
||||
#define STACK_FREE(NAME) \
|
||||
do { \
|
||||
array_list_free (NAME.data); \
|
||||
NAME.data = null_list; \
|
||||
} while (0)
|
||||
|
||||
#define DEFINE_STACK_ELEMENT(NAME, TYPE) \
|
||||
static TYPE NAME##_stack_element (size_t) __attr_unused___; \
|
||||
static TYPE NAME##_stack_element (size_t elem) { \
|
||||
return *((TYPE *) array_list_element (NAME.data, elem)); \
|
||||
}
|
||||
|
||||
#define DEFINE_SET_STACK_ELEMENT(NAME, TYPE) \
|
||||
static void set_##NAME##_stack_element (size_t, TYPE) __attr_unused___; \
|
||||
static void set_##NAME##_stack_element (size_t elem, TYPE value) { \
|
||||
array_list_set_element (NAME.data, elem, &value); \
|
||||
}
|
||||
|
||||
#define DEFINE_STACK_HEAD(NAME, TYPE) \
|
||||
static TYPE NAME##_stack_head (size_t) __attr_unused___; \
|
||||
static TYPE NAME##_stack_head (size_t elem) { \
|
||||
return *((TYPE *) array_list_last_element (NAME.data, elem)); \
|
||||
}
|
||||
|
||||
#define DEFINE_SET_STACK_HEAD(NAME, TYPE) \
|
||||
static void set_##NAME##_stack_head (size_t, TYPE) __attr_unused___; \
|
||||
static void set_##NAME##_stack_head (size_t elem, TYPE value) { \
|
||||
array_list_set_last_element (NAME.data, elem, &value); \
|
||||
}
|
||||
|
||||
#define DEFINE_STACK_PUSH(NAME, TYPE) \
|
||||
static void NAME##_stack_push (TYPE) __attr_unused___; \
|
||||
static void NAME##_stack_push (TYPE value) { \
|
||||
NAME.data = array_list_append (NAME.data, &value); \
|
||||
}
|
||||
|
||||
#define DEFINE_CONVERT_TO_RAW_DATA(NAME, TYPE) \
|
||||
static TYPE *convert_##NAME##_to_raw_data (void) __attr_unused___; \
|
||||
static TYPE *convert_##NAME##_to_raw_data (void) { \
|
||||
if (array_list_len (NAME.data) == 0) \
|
||||
{ \
|
||||
return NULL; \
|
||||
} \
|
||||
size_t size = mem_heap_recommend_allocation_size (array_list_len (NAME.data) * sizeof (NAME##_stack_value_type)); \
|
||||
TYPE *DATA = (TYPE *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM); \
|
||||
if (DATA == NULL) \
|
||||
{ \
|
||||
printf ("Out of memory\n"); \
|
||||
JERRY_UNREACHABLE (); \
|
||||
} \
|
||||
memcpy (DATA, array_list_element (NAME.data, 0), array_list_len (NAME.data) * sizeof (NAME##_stack_value_type)); \
|
||||
return DATA; \
|
||||
}
|
||||
|
||||
#define STACK_PUSH(NAME, VALUE) \
|
||||
do { NAME##_stack_push (VALUE); } while (0)
|
||||
|
||||
#define STACK_DROP(NAME, I) \
|
||||
do { \
|
||||
for (size_t i = 0, till = (size_t) (I); i < till; i++) { \
|
||||
array_list_drop_last (NAME.data); } } while (0)
|
||||
|
||||
#define STACK_CLEAN(NAME) \
|
||||
STACK_DROP (NAME, NAME.current - NAME##_global_size);
|
||||
|
||||
#define STACK_HEAD(NAME, I) \
|
||||
NAME##_stack_head ((size_t) (I))
|
||||
|
||||
#define STACK_SET_HEAD(NAME, I, VALUE) \
|
||||
do { set_##NAME##_stack_head ((size_t) (I), VALUE); } while (0)
|
||||
|
||||
#define STACK_INCR_HEAD(NAME, I) \
|
||||
do { STACK_SET_HEAD (NAME, I, (NAME##_stack_value_type) (STACK_HEAD (NAME, I) + 1)); } while (0)
|
||||
|
||||
#define STACK_DECR_HEAD(NAME, I) \
|
||||
do { STACK_SET_HEAD (NAME, I, (NAME##_stack_value_type) (STACK_HEAD (NAME, I) - 1)); } while (0)
|
||||
|
||||
#define STACK_TOP(NAME) \
|
||||
STACK_HEAD (NAME, 1)
|
||||
|
||||
#define STACK_SWAP(NAME) \
|
||||
do { \
|
||||
NAME##_stack_value_type temp = STACK_TOP (NAME); \
|
||||
STACK_SET_HEAD (NAME, 1, STACK_HEAD (NAME, 2)); \
|
||||
STACK_SET_HEAD (NAME, 2, temp); \
|
||||
} while (0)
|
||||
|
||||
#define STACK_SIZE(NAME) \
|
||||
array_list_len (NAME.data)
|
||||
|
||||
#define STACK_ELEMENT(NAME, I) \
|
||||
NAME##_stack_element ((size_t) (I))
|
||||
|
||||
#define STACK_SET_ELEMENT(NAME, I, VALUE) \
|
||||
do { set_##NAME##_stack_element ((size_t) I, VALUE); } while (0)
|
||||
|
||||
#define STACK_CONVERT_TO_RAW_DATA(NAME, DATA) \
|
||||
do { DATA = convert_##NAME##_to_raw_data (); } while (0)
|
||||
|
||||
#define STACK_INCR_ELEMENT(NAME, I) \
|
||||
do { STACK_SET_ELEMENT (NAME, I, (NAME##_stack_value_type) (STACK_ELEMENT (NAME, I) + 1)); } while (0)
|
||||
|
||||
#define STACK_DECR_ELEMENT(NAME, I) \
|
||||
do { STACK_SET_ELEMENT (NAME, I, (NAME##_stack_value_type) (STACK_ELEMENT (NAME, I) - 1)); } while (0)
|
||||
|
||||
#define STACK_ITERATE(NAME, VAL, FROM) \
|
||||
for (size_t NAME##_i = FROM; \
|
||||
NAME##_i < array_list_len (NAME.data); \
|
||||
NAME##_i++) \
|
||||
{ \
|
||||
NAME##_stack_value_type VAL = STACK_ELEMENT (NAME, NAME##_i);
|
||||
|
||||
#define STACK_ITERATE_END() \
|
||||
}
|
||||
|
||||
#define STACK_ITERATE_VARG_SET(NAME, FUNC, FROM, ...) \
|
||||
do { for (size_t i = FROM; i < array_list_len (NAME.data); i++) { \
|
||||
STACK_SET_ELEMENT (NAME, i, FUNC (STACK_ELEMENT (NAME, i), __VA_ARGS__)); \
|
||||
} } while (0)
|
||||
|
||||
#define STACK(NAME, TYPE) \
|
||||
DEFINE_STACK_TYPE (NAME, TYPE) \
|
||||
NAME##_stack NAME; \
|
||||
DEFINE_STACK_ELEMENT (NAME, TYPE) \
|
||||
DEFINE_SET_STACK_ELEMENT (NAME, TYPE) \
|
||||
DEFINE_STACK_HEAD (NAME, TYPE) \
|
||||
DEFINE_CONVERT_TO_RAW_DATA (NAME, TYPE) \
|
||||
DEFINE_SET_STACK_HEAD (NAME, TYPE) \
|
||||
DEFINE_STACK_PUSH (NAME, TYPE)
|
||||
|
||||
#define STATIC_STACK(NAME, TYPE) \
|
||||
DEFINE_STACK_TYPE (NAME, TYPE) \
|
||||
static NAME##_stack NAME; \
|
||||
DEFINE_STACK_ELEMENT (NAME, TYPE) \
|
||||
DEFINE_SET_STACK_ELEMENT (NAME, TYPE) \
|
||||
DEFINE_STACK_HEAD (NAME, TYPE) \
|
||||
DEFINE_CONVERT_TO_RAW_DATA (NAME, TYPE) \
|
||||
DEFINE_SET_STACK_HEAD (NAME, TYPE) \
|
||||
DEFINE_STACK_PUSH (NAME, TYPE)
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
#define STACK_DECLARE_USAGE(NAME) \
|
||||
size_t NAME##_current = array_list_len (NAME.data);
|
||||
#define STACK_CHECK_USAGE(NAME) \
|
||||
do { \
|
||||
JERRY_ASSERT (array_list_len (NAME.data) == NAME##_current); \
|
||||
} while (0)
|
||||
#else
|
||||
#define STACK_DECLARE_USAGE(NAME) ;
|
||||
#define STACK_CHECK_USAGE(NAME) ;
|
||||
#endif /* JERRY_NDEBUG */
|
||||
|
||||
#endif /* STACK_H */
|
||||
Reference in New Issue
Block a user