diff options
author | Yonggang Luo <luoyonggang@gmail.com> | 2021-02-04 20:13:57 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-04 13:13:57 +0100 |
commit | 982cd080832e2b2ca965ea96867d98fd7c4ff3a0 (patch) | |
tree | c1713707b6d1c86008dcf512518825f708295f62 /jerry-main/main-jerry-test.c | |
parent | e7d11eaf9efccb941a4d6ee7daf1e9a938dbbb09 (diff) |
Rename unix to jerry for entrance files. (#4536)
JerryScript-DCO-1.0-Signed-off-by: Yonggang Luo luoyonggang@gmail.com
Diffstat (limited to 'jerry-main/main-jerry-test.c')
-rw-r--r-- | jerry-main/main-jerry-test.c | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/jerry-main/main-jerry-test.c b/jerry-main/main-jerry-test.c new file mode 100644 index 00000000..aea640c8 --- /dev/null +++ b/jerry-main/main-jerry-test.c @@ -0,0 +1,244 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * 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 <stdlib.h> +#include <string.h> + +#include "jerryscript.h" +#include "jerryscript-port.h" + +/** + * Maximum size of source code / snapshots buffer + */ +#define JERRY_BUFFER_SIZE (1048576) + +/** + * Standalone Jerry exit codes + */ +#define JERRY_STANDALONE_EXIT_CODE_OK (0) +#define JERRY_STANDALONE_EXIT_CODE_FAIL (1) + +static uint8_t buffer[ JERRY_BUFFER_SIZE ]; + +static const uint8_t * +read_file (const char *file_name, + size_t *out_size_p) +{ + FILE *file = fopen (file_name, "rb"); + if (file == NULL) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to open file: %s\n", file_name); + return NULL; + } + + size_t bytes_read = fread (buffer, 1u, sizeof (buffer), file); + if (!bytes_read) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to read file: %s\n", file_name); + fclose (file); + return NULL; + } + + fclose (file); + + *out_size_p = bytes_read; + return (const uint8_t *) buffer; +} /* read_file */ + +static void +print_help (char *name) +{ + printf ("Usage: %s [OPTION]... [FILE]...\n" + "\n" + "Options:\n" + " -h, --help\n" + "\n", + name); +} /* print_help */ + +/* Global "argc" and "argv" used to avoid argument passing via stack. */ +static int argc; +static char **argv; + +static JERRY_ATTR_NOINLINE int +run (void) +{ + jerry_init (JERRY_INIT_EMPTY); + jerry_value_t ret_value = jerry_create_undefined (); + + for (int i = 1; i < argc; i++) + { + const char *file_name = argv[i]; + size_t source_size; + + const jerry_char_t *source_p = read_file (file_name, &source_size); + + if (source_p == NULL) + { + ret_value = jerry_create_error (JERRY_ERROR_COMMON, (jerry_char_t *) ""); + break; + } + else + { + ret_value = jerry_parse (NULL, 0, source_p, source_size, JERRY_PARSE_NO_OPTS); + + if (!jerry_value_is_error (ret_value)) + { + jerry_value_t func_val = ret_value; + ret_value = jerry_run (func_val); + jerry_release_value (func_val); + } + } + + if (jerry_value_is_error (ret_value)) + { + break; + } + + jerry_release_value (ret_value); + ret_value = jerry_create_undefined (); + } + + int ret_code = !jerry_value_is_error (ret_value) ? JERRY_STANDALONE_EXIT_CODE_OK : JERRY_STANDALONE_EXIT_CODE_FAIL; + + jerry_release_value (ret_value); + jerry_cleanup (); + + return ret_code; +} /* run */ + +#if defined (JERRY_TEST_STACK_MEASURE) && (JERRY_TEST_STACK_MEASURE) + +/** + * How this stack measuring works: + * + * 1) Get the current stack pointer before doing the test execution. + * This will be the "Stack bottom". + * 2) Fill the stack towards lower addresses with a placeholder 32 bit value. + * A "STACK_MEASURE_RANGE" big area will be filled with the value starting + * from "Stack bottom". + * The "Stack bottom" + "STACK_MEASURE_RANGE" will be the "Stack top". + * 3) Run the tests. + * 4) Check the stack backwards from "Stack top" to see where the 32 bit placeholder + * value is not present. The point where the 32 bit value is not found is + * considered to be the "Stack max". The "Stack bottom" - "Stack max" substraction + * will give the stack usage in bytes. + * + * + * Based on this the expected stack layout is: + * The stack is expected to "grow" towards lower address. + * + * |-------| + * | | <- low address - "Stack top" + * |-------| + * | | + * |-------| + * .... + * |-------| + * | | <- "Stack max" + * |-------| + * .... + * |-------| + * | | <- high address - "Stack bottom" + * |-------| + * + */ + +#if !(defined (__linux__) && __linux__) +#error "Unsupported stack measurement platform!" +#endif /* !(defined ( __linux__) && __linux__) */ + +#if defined (__x86_64__) +#define STACK_SAVE(TARGET) { __asm volatile ("mov %%rsp, %0" : "=m" (TARGET)); } +#elif defined (__i386__) +#define STACK_SAVE(TARGET) { __asm volatile ("mov %%esp, %0" : "=m" (TARGET)); } +#elif defined (__arm__) +#define STACK_SAVE(TARGET) { __asm volatile ("mov %0, sp" : "=r" (TARGET)); } +#else /* !defined (__x86_64__) && !defined (__i386__) && !defined (__arm__) */ +#error "Unsupported stack measurement target!" +#endif /* !defined (__x86_64__) && !defined (__i386__) && !defined (__arm__) */ + +static void *g_stack_bottom = 0x0; + +#define STACK_MEASURE_RANGE ((2 * 1024 * 1024)) +#define STACK_PATTERN (0xDEADBEEF) +#define STACK_INIT(TARGET, SIZE) do \ + { \ + for (size_t idx = 0; idx < (SIZE / sizeof (uint32_t)); idx++) \ + { \ + ((uint32_t*)(TARGET))[idx] = STACK_PATTERN; \ + } \ + } while (0) + +#define STACK_USAGE(TARGET, SIZE) stack_usage (TARGET, SIZE) +#define STACK_TOP_PTR(TARGET, SIZE) (uint32_t *) (((uint8_t *) TARGET) - SIZE) + +static void +stack_usage (uint32_t *stack_top_p, size_t length_in_bytes) +{ + uint32_t *stack_bottom_p = stack_top_p + (length_in_bytes / sizeof (uint32_t)); + uint32_t *stack_p = stack_top_p; + + while (stack_p < stack_bottom_p) + { + if (*stack_p != STACK_PATTERN) + { + break; + } + stack_p++; + } + + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Used stack: %d\n", (int) ((uint8_t *) stack_bottom_p - (uint8_t *) stack_p)); +} /* stack_usage */ + +#else /* (JERRY_TEST_STACK_MEASURE) && (JERRY_TEST_STACK_MEASURE) */ +#define STACK_SAVE(TARGET) +#define STACK_INIT(TARGET, SIZE) +#define STACK_USAGE(TARGET, SIZE) +#endif /* #if defined (JERRY_TEST_STACK_MEASURE) && (JERRY_TEST_STACK_MEASURE) */ + +int main (int main_argc, + char **main_argv) +{ + union + { + double d; + unsigned u; + } now = { .d = jerry_port_get_current_time () }; + srand (now.u); + + argc = main_argc; + argv = main_argv; + + if (argc <= 1 || (argc == 2 && (!strcmp ("-h", argv[1]) || !strcmp ("--help", argv[1])))) + { + print_help (argv[0]); + return JERRY_STANDALONE_EXIT_CODE_OK; + } + + STACK_SAVE (g_stack_bottom); + STACK_INIT (STACK_TOP_PTR (g_stack_bottom, STACK_MEASURE_RANGE), STACK_MEASURE_RANGE); + + int result = run (); + + STACK_USAGE (STACK_TOP_PTR (g_stack_bottom, STACK_MEASURE_RANGE), STACK_MEASURE_RANGE); + + if (result == JERRY_STANDALONE_EXIT_CODE_FAIL) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unhandled exception: Script Error!\n"); + } + + return result; +} /* main */ |