Compact Byte Code parser and executor for Jerry.

JerryScript-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com
JerryScript-DCO-1.0-Signed-off-by: Tamas Gergely tgergely.u-szeged@partner.samsung.com
JerryScript-DCO-1.0-Signed-off-by: Zsolt Borbély zsborbely.u-szeged@partner.samsung.com
JerryScript-DCO-1.0-Signed-off-by: Roland Takacs rtakacs.u-szeged@partner.samsung.com
JerryScript-DCO-1.0-Signed-off-by: István Kádár ikadar@inf.u-szeged.hu
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2016-02-05 00:10:10 -08:00
parent db6caf3c48
commit 4d2dd22ced
92 changed files with 17184 additions and 20276 deletions
+67 -34
View File
@@ -1,5 +1,5 @@
/* Copyright 2015 Samsung Electronics Co., Ltd.
* Copyright 2015 University of Szeged.
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,16 @@
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN
/** \addtogroup parser Parser
* @{
*
* \addtogroup regexparser Regular expression
* @{
*
* \addtogroup regexparser_bytecode Bytecode
* @{
*/
/**
* Size of block of RegExp bytecode. Used for allocation
*/
@@ -34,7 +44,7 @@
* Get length of bytecode
*/
static uint32_t
re_get_bytecode_length (re_bytecode_ctx_t *bc_ctx_p)
re_get_bytecode_length (re_bytecode_ctx_t *bc_ctx_p) /**< RegExp bytecode context */
{
return ((uint32_t) (bc_ctx_p->current_p - bc_ctx_p->block_start_p));
} /* re_get_bytecode_length */
@@ -47,7 +57,7 @@ re_dump_bytecode (re_bytecode_ctx_t *bc_ctx);
*
* @return current position in RegExp bytecode
*/
static re_bytecode_t*
static uint8_t *
re_realloc_regexp_bytecode_block (re_bytecode_ctx_t *bc_ctx_p) /**< RegExp bytecode context */
{
JERRY_ASSERT (bc_ctx_p->block_end_p - bc_ctx_p->block_start_p >= 0);
@@ -62,8 +72,8 @@ re_realloc_regexp_bytecode_block (re_bytecode_ctx_t *bc_ctx_p) /**< RegExp bytec
JERRY_ASSERT (bc_ctx_p->current_p - bc_ctx_p->block_start_p >= 0);
size_t current_ptr_offset = static_cast<size_t> (bc_ctx_p->current_p - bc_ctx_p->block_start_p);
re_bytecode_t *new_block_start_p = (re_bytecode_t *) mem_heap_alloc_block (new_block_size,
MEM_HEAP_ALLOC_SHORT_TERM);
uint8_t *new_block_start_p = (uint8_t *) mem_heap_alloc_block (new_block_size,
MEM_HEAP_ALLOC_SHORT_TERM);
if (bc_ctx_p->current_p)
{
memcpy (new_block_start_p, bc_ctx_p->block_start_p, static_cast<size_t> (current_ptr_offset));
@@ -81,12 +91,12 @@ re_realloc_regexp_bytecode_block (re_bytecode_ctx_t *bc_ctx_p) /**< RegExp bytec
*/
static void
re_bytecode_list_append (re_bytecode_ctx_t *bc_ctx_p, /**< RegExp bytecode context */
re_bytecode_t *bytecode_p, /**< input bytecode */
uint8_t *bytecode_p, /**< input bytecode */
size_t length) /**< length of input */
{
JERRY_ASSERT (length <= REGEXP_BYTECODE_BLOCK_SIZE);
re_bytecode_t *current_p = bc_ctx_p->current_p;
uint8_t *current_p = bc_ctx_p->current_p;
if (current_p + length > bc_ctx_p->block_end_p)
{
current_p = re_realloc_regexp_bytecode_block (bc_ctx_p);
@@ -102,24 +112,24 @@ re_bytecode_list_append (re_bytecode_ctx_t *bc_ctx_p, /**< RegExp bytecode conte
static void
re_bytecode_list_insert (re_bytecode_ctx_t *bc_ctx_p, /**< RegExp bytecode context */
size_t offset, /**< distance from the start of the container */
re_bytecode_t *bytecode_p, /**< input bytecode */
uint8_t *bytecode_p, /**< input bytecode */
size_t length) /**< length of input */
{
JERRY_ASSERT (length <= REGEXP_BYTECODE_BLOCK_SIZE);
re_bytecode_t *current_p = bc_ctx_p->current_p;
uint8_t *current_p = bc_ctx_p->current_p;
if (current_p + length > bc_ctx_p->block_end_p)
{
re_realloc_regexp_bytecode_block (bc_ctx_p);
}
re_bytecode_t *src_p = bc_ctx_p->block_start_p + offset;
uint8_t *src_p = bc_ctx_p->block_start_p + offset;
if ((re_get_bytecode_length (bc_ctx_p) - offset) > 0)
{
re_bytecode_t *dest_p = src_p + length;
re_bytecode_t *tmp_block_start_p;
tmp_block_start_p = (re_bytecode_t *) mem_heap_alloc_block ((re_get_bytecode_length (bc_ctx_p) - offset),
MEM_HEAP_ALLOC_SHORT_TERM);
uint8_t *dest_p = src_p + length;
uint8_t *tmp_block_start_p;
tmp_block_start_p = (uint8_t *) mem_heap_alloc_block ((re_get_bytecode_length (bc_ctx_p) - offset),
MEM_HEAP_ALLOC_SHORT_TERM);
memcpy (tmp_block_start_p, src_p, (size_t) (re_get_bytecode_length (bc_ctx_p) - offset));
memcpy (dest_p, tmp_block_start_p, (size_t) (re_get_bytecode_length (bc_ctx_p) - offset));
mem_heap_free_block (tmp_block_start_p);
@@ -136,7 +146,7 @@ static void
re_append_opcode (re_bytecode_ctx_t *bc_ctx_p, /**< RegExp bytecode context */
re_opcode_t opcode) /**< input opcode */
{
re_bytecode_list_append (bc_ctx_p, (re_bytecode_t*) &opcode, sizeof (re_bytecode_t));
re_bytecode_list_append (bc_ctx_p, (uint8_t*) &opcode, sizeof (uint8_t));
} /* re_append_opcode */
/**
@@ -146,7 +156,7 @@ static void
re_append_u32 (re_bytecode_ctx_t *bc_ctx_p, /**< RegExp bytecode context */
uint32_t value) /**< input value */
{
re_bytecode_list_append (bc_ctx_p, (re_bytecode_t*) &value, sizeof (uint32_t));
re_bytecode_list_append (bc_ctx_p, (uint8_t*) &value, sizeof (uint32_t));
} /* re_append_u32 */
/**
@@ -168,7 +178,7 @@ re_insert_opcode (re_bytecode_ctx_t *bc_ctx_p, /**< RegExp bytecode context */
uint32_t offset, /**< distance from the start of the container */
re_opcode_t opcode) /**< input opcode */
{
re_bytecode_list_insert (bc_ctx_p, offset, (re_bytecode_t*) &opcode, sizeof (re_bytecode_t));
re_bytecode_list_insert (bc_ctx_p, offset, (uint8_t*) &opcode, sizeof (uint8_t));
} /* re_insert_opcode */
/**
@@ -179,17 +189,17 @@ re_insert_u32 (re_bytecode_ctx_t *bc_ctx_p, /**< RegExp bytecode context */
uint32_t offset, /**< distance from the start of the container */
uint32_t value) /**< input value */
{
re_bytecode_list_insert (bc_ctx_p, offset, (re_bytecode_t*) &value, sizeof (uint32_t));
re_bytecode_list_insert (bc_ctx_p, offset, (uint8_t*) &value, sizeof (uint32_t));
} /* re_insert_u32 */
/**
* Get a RegExp opcode
*/
re_opcode_t
re_get_opcode (re_bytecode_t **bc_p) /**< pointer to bytecode start */
re_get_opcode (uint8_t **bc_p) /**< pointer to bytecode start */
{
re_bytecode_t bytecode = **bc_p;
(*bc_p) += sizeof (re_bytecode_t);
uint8_t bytecode = **bc_p;
(*bc_p) += sizeof (uint8_t);
return (re_opcode_t) bytecode;
} /* get_opcode */
@@ -197,7 +207,7 @@ re_get_opcode (re_bytecode_t **bc_p) /**< pointer to bytecode start */
* Get a parameter of a RegExp opcode
*/
uint32_t
re_get_value (re_bytecode_t **bc_p) /**< pointer to bytecode start */
re_get_value (uint8_t **bc_p) /**< pointer to bytecode start */
{
uint32_t value = *((uint32_t*) *bc_p);
(*bc_p) += sizeof (uint32_t);
@@ -368,6 +378,13 @@ re_insert_into_group_with_jump (re_compiler_ctx_t *re_ctx_p, /**< RegExp compile
re_insert_into_group (re_ctx_p, group_start_offset, idx, is_capturable);
} /* re_insert_into_group_with_jump */
/**
* @}
*
* \addtogroup regexparser_compiler Compiler
* @{
*/
/**
* Parse alternatives
*
@@ -614,9 +631,9 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
re_compile_bytecode (re_bytecode_t **out_bytecode_p, /**< out:pointer to bytecode */
re_compile_bytecode (re_compiled_code_t **out_bytecode_p, /**< out:pointer to bytecode */
ecma_string_t *pattern_str_p, /**< pattern */
uint8_t flags) /**< flags */
uint16_t flags) /**< flags */
{
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
re_compiler_ctx_t re_ctx;
@@ -661,9 +678,18 @@ re_compile_bytecode (re_bytecode_t **out_bytecode_p, /**< out:pointer to bytecod
re_append_opcode (&bc_ctx, RE_OP_EOF);
/* 3. Insert extra informations for bytecode header */
re_insert_u32 (&bc_ctx, 0, (uint32_t) re_ctx.num_of_non_captures);
re_insert_u32 (&bc_ctx, 0, (uint32_t) re_ctx.num_of_captures * 2);
re_insert_u32 (&bc_ctx, 0, (uint32_t) re_ctx.flags);
re_compiled_code_t re_compiled_code;
re_compiled_code.flags = re_ctx.flags | (1 << ECMA_BYTECODE_REF_SHIFT);
ECMA_SET_NON_NULL_POINTER (re_compiled_code.pattern_cp,
ecma_copy_or_ref_ecma_string (pattern_str_p));
re_compiled_code.num_of_captures = re_ctx.num_of_captures * 2;
re_compiled_code.num_of_non_captures = re_ctx.num_of_non_captures;
re_bytecode_list_insert (&bc_ctx,
0,
(uint8_t *) &re_compiled_code,
sizeof (re_compiled_code_t));
}
ECMA_FINALIZE (empty);
@@ -679,7 +705,7 @@ re_compile_bytecode (re_bytecode_t **out_bytecode_p, /**< out:pointer to bytecod
{
/* The RegExp bytecode contains at least a RE_OP_SAVE_AT_START opdoce, so it cannot be NULL. */
JERRY_ASSERT (bc_ctx.block_start_p != NULL);
*out_bytecode_p = bc_ctx.block_start_p;
*out_bytecode_p = (re_compiled_code_t *) bc_ctx.block_start_p;
}
#ifdef JERRY_ENABLE_LOG
@@ -694,12 +720,14 @@ re_compile_bytecode (re_bytecode_t **out_bytecode_p, /**< out:pointer to bytecod
* RegExp bytecode dumper
*/
void
re_dump_bytecode (re_bytecode_ctx_t *bc_ctx_p)
re_dump_bytecode (re_bytecode_ctx_t *bc_ctx_p) /**< RegExp bytecode context */
{
re_bytecode_t *bytecode_p = bc_ctx_p->block_start_p;
JERRY_DLOG ("%d ", re_get_value (&bytecode_p));
JERRY_DLOG ("%d ", re_get_value (&bytecode_p));
JERRY_DLOG ("%d | ", re_get_value (&bytecode_p));
re_compiled_code_t *compiled_code_p = bc_ctx_p->block_start_p;
JERRY_DLOG ("%d ", compiled_code_p->flags);
JERRY_DLOG ("%d ", compiled_code_p->num_of_captures);
JERRY_DLOG ("%d | ", compiled_code_p->num_of_non_captures);
uint8_t *bytecode_p = (uint8_t *) (compiled_code_p + 1);
re_opcode_t op;
while ((op = re_get_opcode (&bytecode_p)))
@@ -891,4 +919,9 @@ re_dump_bytecode (re_bytecode_ctx_t *bc_ctx_p)
} /* re_dump_bytecode */
#endif /* JERRY_ENABLE_LOG */
/**
* @}
* @}
*/
#endif /* CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN */