diff --git a/Makefile.mak b/Makefile.mak index ce7577582..bacd235da 100644 --- a/Makefile.mak +++ b/Makefile.mak @@ -184,7 +184,7 @@ ifeq ($(OPTION_WERROR),enable) endif ifeq ($(OPTION_MCU),disable) - DEFINES_JERRY += -D__HOST + DEFINES_JERRY += -D__HOST -DJERRY_SOURCE_BUFFER_SIZE=1048576 else CFLAGS_COMMON += -ffunction-sections -fdata-sections -nostdlib DEFINES_JERRY += -D__TARGET_MCU diff --git a/src/libjsparser/lexer.c b/src/libjsparser/lexer.c index ca912f8c5..672601f77 100644 --- a/src/libjsparser/lexer.c +++ b/src/libjsparser/lexer.c @@ -104,79 +104,15 @@ is_empty (token tok) return tok.type == TOK_EMPTY; } -#ifdef __HOST -FILE *lexer_debug_log; -#endif +/* Represents the contents of a script. */ +static const char *buffer_start = NULL; +static const char *buffer = NULL; +static const char *token_start; + +#define LA(I) (*(buffer + I)) #ifdef __HOST -static FILE *file; -static char *buffer_start; - -/* Represents the contents of a file. */ -static char *buffer = NULL; -static char *token_start; - -#define BUFFER_SIZE 1024 - -static char -get_char (size_t i) -{ - size_t error; - JERRY_ASSERT (buffer >= buffer_start); - const size_t tail_size = BUFFER_SIZE - (size_t) (buffer - buffer_start); - - JERRY_ASSERT (file); - - if (buffer == NULL) - { - buffer = (char *) mem_heap_alloc_block (BUFFER_SIZE, MEM_HEAP_ALLOC_SHORT_TERM); - error = __fread (buffer, 1, BUFFER_SIZE, file); - if (error == 0) - return '\0'; - if (error < BUFFER_SIZE) - __memset (buffer + error, '\0', BUFFER_SIZE - error); - buffer_start = buffer; - } - - if (tail_size <= i) - { - /* We are almost at the end of the buffer. */ - if (token_start) - { - JERRY_ASSERT (buffer >= token_start); - const size_t token_size = (size_t) (buffer - token_start); - /* Whole buffer contains single token. */ - if (token_start == buffer_start) - parser_fatal (ERR_BUFFER_SIZE); - /* Move parsed token and tail of buffer to head. */ - __memmove (buffer_start, token_start, tail_size + token_size); - /* Adjust pointers. */ - token_start = buffer_start; - buffer = buffer_start + token_size; - /* Read more characters form input file. */ - error = __fread (buffer + tail_size, 1, BUFFER_SIZE - tail_size - token_size, file); - if (error == 0) - return '\0'; - if (error < BUFFER_SIZE - tail_size - token_size) - __memset (buffer + tail_size + error, '\0', - BUFFER_SIZE - tail_size - token_size - error); - } - else - { - __memmove (buffer_start, buffer, tail_size); - buffer = buffer_start; - error = __fread (buffer + tail_size, 1, BUFFER_SIZE - tail_size, file); - if (error == 0) - return '\0'; - if (error < BUFFER_SIZE - tail_size) - __memset (buffer + tail_size + error, '\0', BUFFER_SIZE - tail_size - error); - } - } - - return *(buffer + i); -} - -#define LA(I) (get_char (I)) +_FILE *lexer_debug_log; static void dump_current_line (void) @@ -187,16 +123,7 @@ dump_current_line (void) __putchar (*i); __putchar ('\n'); } - -#else - -/* Represents the contents of a file. */ -static const char *buffer = NULL; -static const char *token_start; - -#define LA(I) (*(buffer + I)) - -#endif // __HOST +#endif /* If TOKEN represents a keyword, return decoded keyword, if TOKEN represents a Future Reserved Word, return KW_RESERVED, @@ -708,25 +635,20 @@ grobble_whitespaces (void) } } -#ifdef __HOST -void -lexer_set_file (FILE *ex_file) -{ - JERRY_ASSERT (ex_file); - file = ex_file; - lexer_debug_log = __fopen ("lexer.log", "w"); - saved_token = empty_token; - buffer = buffer_start = token_start = NULL; -} -#else -void +static void lexer_set_source (const char * source) { - buffer = source; - saved_token = empty_token; + buffer_start = source; + buffer = buffer_start; } -#endif +static void +lexer_rewind( void) +{ + JERRY_ASSERT( buffer_start != NULL ); + + buffer = buffer_start; +} static bool replace_comment_by_newline (void) @@ -765,13 +687,8 @@ replace_comment_by_newline (void) } } -#ifdef __HOST static token lexer_next_token_private (void) -#else -token -lexer_next_token (void) -#endif { char c = LA (0); @@ -805,12 +722,7 @@ lexer_next_token (void) if (__isspace (c)) { grobble_whitespaces (); - return -#ifdef __HOST - lexer_next_token_private (); -#else - lexer_next_token (); -#endif + return lexer_next_token_private (); } if (c == '/' && LA (1) == '*') @@ -818,23 +730,13 @@ lexer_next_token (void) if (replace_comment_by_newline ()) return (token) { .type = TOK_NEWLINE, .data.uid = 0 }; else - return -#ifdef __HOST - lexer_next_token_private (); -#else - lexer_next_token (); -#endif + return lexer_next_token_private (); } if (c == '/' && LA (1) == '/') { replace_comment_by_newline ();; - return -#ifdef __HOST - lexer_next_token_private (); -#else - lexer_next_token (); -#endif + return lexer_next_token_private (); } switch (c) @@ -904,16 +806,19 @@ lexer_next_token (void) #ifdef __HOST static int i = 0; +#endif /* __HOST */ token lexer_next_token (void) { - LA (0); // Init buffers - +#ifdef __HOST if (buffer == buffer_start) dump_current_line (); +#endif /* __HOST */ token tok = lexer_next_token_private (); + +#ifdef __HOST if (tok.type == TOK_NEWLINE) { dump_current_line (); @@ -925,9 +830,9 @@ lexer_next_token (void) __fprintf (lexer_debug_log, "lexer_next_token(%d): type=%d, data=%d\n", i, tok.type, tok.data.uid); i++; } +#endif /* __HOST */ return tok; } -#endif void lexer_save_token (token tok) @@ -935,7 +840,7 @@ lexer_save_token (token tok) #ifdef __HOST if (tok.type == TOK_CLOSE_BRACE) __fprintf (lexer_debug_log, "lexer_save_token(%d): type=%d, data=%d\n", i, tok.type, tok.data.uid); -#endif +#endif /* __HOST */ saved_token = tok; } @@ -944,3 +849,25 @@ lexer_dump_buffer_state (void) { __printf ("%s\n", buffer); } + +void +lexer_init( const char *source) +{ + saved_token = empty_token; + lexer_set_source( source); + +#ifdef __HOST + lexer_debug_log = __fopen ("lexer.log", "w"); +#endif /* __HOST */ +} + +void +lexer_run_first_pass( void) +{ + token tok = lexer_next_token (); + while (tok.type != TOK_EOF) + tok = lexer_next_token (); + + lexer_rewind(); +} + diff --git a/src/libjsparser/lexer.h b/src/libjsparser/lexer.h index bbc10b9c7..3d9988299 100644 --- a/src/libjsparser/lexer.h +++ b/src/libjsparser/lexer.h @@ -147,11 +147,8 @@ typedef struct } __packed token; -#ifdef __HOST -void lexer_set_file (FILE *); -#else -void lexer_set_source (const char *); -#endif +void lexer_init(const char *); +void lexer_run_first_pass( void); token lexer_next_token (void); void lexer_save_token (token); void lexer_dump_buffer_state (void); diff --git a/src/libjsparser/parser.c b/src/libjsparser/parser.c index 78f039ff3..9549b0fdc 100644 --- a/src/libjsparser/parser.c +++ b/src/libjsparser/parser.c @@ -27,7 +27,7 @@ static uint8_t current_opcode_in_buffer = 0; static uint8_t opcode_counter = 0; #ifdef __HOST -FILE *debug_file; +_FILE *debug_file; #endif static T_IDX parse_expression (void); diff --git a/src/libruntime/jerry-libc.h b/src/libruntime/jerry-libc.h index 9a3013781..ee812c0a8 100644 --- a/src/libruntime/jerry-libc.h +++ b/src/libruntime/jerry-libc.h @@ -21,7 +21,7 @@ #include "globals.h" -typedef void FILE; +typedef void _FILE; extern void* __memset (void *s, int c, size_t n); extern int __memcmp (const void *s1, const void *s2, size_t n); @@ -44,12 +44,26 @@ extern int __isalpha (int); extern int __isdigit (int); extern int __isxdigit (int); -extern FILE* __fopen(const char *, const char *); -extern int __fclose(FILE *); -extern void __rewind(FILE *); -extern size_t __fread(void *, size_t, size_t, FILE *); -extern size_t __fwrite(const void *, size_t, size_t, FILE *); -extern int __fprintf(FILE *, const char *, ...); +/** + * 'whence' argument of __fseek that identifies position + * the 'offset' argument is added to. + */ +typedef enum +{ + __SEEK_SET, /**< relative to begin of file */ + __SEEK_CUR, /**< relative to current position */ + __SEEK_END /**< relative to end of file */ +} _whence_t; + +extern _FILE* __fopen(const char *, const char *); +extern int __fclose(_FILE *); +extern int __fseek(_FILE *, long offset, _whence_t); +extern long __ftell(_FILE *); +extern void __rewind(_FILE *); +extern size_t __fread(void *, size_t, size_t, _FILE *); +extern size_t __fwrite(const void *, size_t, size_t, _FILE *); +extern int __ferror(_FILE *); +extern int __fprintf(_FILE *, const char *, ...); #define DBL_MANT_DIG ( 52) #define DBL_DIG ( 10) diff --git a/src/libruntime/serializer.h b/src/libruntime/serializer.h index 4802c139d..1bcb4fcfc 100644 --- a/src/libruntime/serializer.h +++ b/src/libruntime/serializer.h @@ -28,4 +28,4 @@ void serializer_dump_opcode (const void *); void serializer_rewrite_opcode (const int8_t, const void *); -#endif // SERIALIZER_H \ No newline at end of file +#endif // SERIALIZER_H diff --git a/src/libruntime/target/linux/jerry-libc.c b/src/libruntime/target/linux/jerry-libc.c index 699bcda72..abfb38682 100644 --- a/src/libruntime/target/linux/jerry-libc.c +++ b/src/libruntime/target/linux/jerry-libc.c @@ -21,16 +21,8 @@ #include "jerry-libc.h" #include - - -extern void __noreturn exit(int status); -extern FILE* fopen(const char *path, const char *mode); -extern int fclose(FILE *fp); -extern int rewind (FILE *); -extern size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); -extern size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); -extern int vprintf (__const char *__restrict __format, __builtin_va_list __arg); -extern int vfprintf (FILE *stream, __const char *__restrict __format, __builtin_va_list __arg); +#include +#include /** * printf @@ -69,10 +61,10 @@ __exit (int status) /** * fopen * - * @return FILE pointer - upon successful completion, + * @return _FILE pointer - upon successful completion, * NULL - otherwise */ -FILE* +_FILE* __fopen(const char *path, /**< file path */ const char *mode) /**< file open mode */ { @@ -82,7 +74,7 @@ __fopen(const char *path, /**< file path */ /** The rewind() function sets the file position indicator for the stream pointed to by STREAM to the beginning of the file. */ void -__rewind (FILE *stream) +__rewind (_FILE *stream) { rewind (stream); } @@ -94,11 +86,46 @@ __rewind (FILE *stream) * non-zero value - otherwise. */ int -__fclose(FILE *fp) /**< stream pointer */ +__fclose(_FILE *fp) /**< stream pointer */ { return fclose( fp); } /* __fclose */ +/** + * fseek + */ +int +__fseek(_FILE * fp, /**< stream pointer */ + long offset, /**< offset */ + _whence_t whence) /**< specifies position type + to add offset to */ +{ + int whence_real; + switch ( whence ) + { + case __SEEK_SET: + whence_real = SEEK_SET; + break; + case __SEEK_CUR: + whence_real = SEEK_CUR; + break; + case __SEEK_END: + whence_real = SEEK_END; + break; + } + + return fseek( fp, offset, whence_real); +} /* __fseek */ + +/** + * ftell + */ +long +__ftell(_FILE * fp) /**< stream pointer */ +{ + return ftell( fp); +} /* __ftell */ + /** * fread * @@ -108,7 +135,7 @@ size_t __fread(void *ptr, /**< address of buffer to read to */ size_t size, /**< size of elements to read */ size_t nmemb, /**< number of elements to read */ - FILE *stream) /**< stream pointer */ + _FILE *stream) /**< stream pointer */ { return fread(ptr, size, nmemb, stream); } /* __fread */ @@ -122,18 +149,27 @@ size_t __fwrite(const void *ptr, /**< data to write */ size_t size, /**< size of elements to write */ size_t nmemb, /**< number of elements */ - FILE *stream) /**< stream pointer */ + _FILE *stream) /**< stream pointer */ { return fwrite(ptr, size, nmemb, stream); } /* __fwrite */ +/** + * ferror + */ +int +__ferror(_FILE * fp) /**< stream pointer */ +{ + return ferror( fp); +} /* __ferror */ + /** * fprintf * * @return number of characters printed */ int -__fprintf(FILE *stream, /**< stream pointer */ +__fprintf(_FILE *stream, /**< stream pointer */ const char *format, /**< format string */ ...) /**< parameters' values */ { diff --git a/src/libruntime/target/linux/serializer.c b/src/libruntime/target/linux/serializer.c index 65ffbd23f..f3b440166 100644 --- a/src/libruntime/target/linux/serializer.c +++ b/src/libruntime/target/linux/serializer.c @@ -17,7 +17,7 @@ #include "jerry-libc.h" #include "opcodes.h" -FILE *dump; +_FILE *dump; #define OPCODE_STR(op) \ #op, diff --git a/src/libruntime/target/stm32f4/serializer.c b/src/libruntime/target/stm32f4/serializer.c index 3e7072876..816979ef6 100644 --- a/src/libruntime/target/stm32f4/serializer.c +++ b/src/libruntime/target/stm32f4/serializer.c @@ -19,27 +19,32 @@ void serializer_init (void) { + JERRY_UNIMPLEMENTED(); } uint8_t -serializer_dump_strings (const char *strings[] __unused, uint8_t size __unused) +serializer_dump_strings (const char *strings[], uint8_t size) { + JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( strings, size); } void -serializer_dump_nums (const int nums[] __unused, uint8_t size __unused, uint8_t offset __unused, uint8_t strings_num __unused) +serializer_dump_nums (const int nums[], uint8_t size, uint8_t offset, uint8_t strings_num) { + JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( nums, size, offset, strings_num); } void -serializer_dump_opcode (const void *opcode __unused) +serializer_dump_opcode (const void *opcode) { + JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( opcode); } void -serializer_rewrite_opcode (const int8_t offset __unused, const void *opcode __unused) +serializer_rewrite_opcode (const int8_t offset, const void *opcode) { + JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( offset, opcode); } -TODO (Dump memory) \ No newline at end of file +TODO (Dump memory) diff --git a/src/main.c b/src/main.c index c1f240fe7..b7c848a4d 100644 --- a/src/main.c +++ b/src/main.c @@ -40,12 +40,120 @@ #define MAX_STRINGS 100 #define MAX_NUMS 25 -void fake_exit (void); +static void +jerry_run( const char *script_source, + size_t script_source_size __unused) +{ + const char *strings[MAX_STRINGS]; + int nums[MAX_NUMS]; + uint8_t strings_num, nums_count; + uint8_t offset; + + mem_init(); + + TODO( Consider using script_source_size in lexer to check buffer boundaries ); + + lexer_init( script_source); + + lexer_run_first_pass(); + + strings_num = lexer_get_strings (strings); + nums_count = lexer_get_nums (nums); + lexer_adjust_num_ids (); + + offset = serializer_dump_strings (strings, strings_num); + serializer_dump_nums (nums, nums_count, offset, strings_num); + + parser_init (); + parser_parse_program (); + + //gen_bytecode (generated_source); + //gen_bytecode (); + //run_int (); +} /* jerry_run */ + +#ifdef __HOST +static uint8_t source_buffer[ JERRY_SOURCE_BUFFER_SIZE ]; + +static const char* +read_source( const char *script_file_name, + size_t *out_source_size_p) +{ + _FILE *file = __fopen (script_file_name, "r"); + + if (file == NULL) + { + jerry_exit (ERR_IO); + } + + int fseek_status = __fseek( file, 0, __SEEK_END); + + if ( fseek_status != 0 ) + { + jerry_exit (ERR_IO); + } + + long script_len = __ftell( file); + + if ( script_len < 0 ) + { + jerry_exit (ERR_IO); + } + + __rewind( file); + + const size_t source_size = (size_t)script_len; + size_t bytes_read = 0; + + while ( bytes_read < source_size ) + { + bytes_read += __fread( source_buffer, 1, source_size, file); + + if ( __ferror( file) != 0 ) + { + jerry_exit (ERR_IO); + } + } + + __fclose( file); + + *out_source_size_p = source_size; + return (const char*)source_buffer; +} + +int +main (int argc __unused, + char **argv __unused) +{ + const char *file_name = NULL; + + if (argc > 2) + { + jerry_exit (ERR_SEVERAL_FILES); + } + else if (argc == 2) + { + file_name = argv[1]; + } + else + { + jerry_exit (ERR_NO_FILES); + } + + size_t source_size; + const char *source_p = read_source( file_name, &source_size); + + jerry_run( source_p, + source_size); + + return 0; +} +#elif !defined(__HOST) && defined(__TARGET_MCU) +void fake_exit(void); void fake_exit (void) { -#ifdef __TARGET_MCU uint32_t pin = LED_RED; uint32_t mode = (uint32_t)GPIO_Mode_OUT << (pin * 2); uint32_t speed = (uint32_t)GPIO_Speed_100MHz << (pin * 2); @@ -90,76 +198,21 @@ fake_exit (void) for (index = 0; index < dash * 7; index++); } -#else - for (;;); -#endif } int -main (int argc __unused, - char **argv __unused) +main(void) { -#ifdef __HOST - const char *file_name = NULL; - FILE *file = NULL; -#endif - const char *strings[MAX_STRINGS]; - int nums[MAX_NUMS]; - uint8_t strings_num, nums_count, offset; + const char *source_p = generated_source; + const size_t source_size = sizeof(generated_source); - mem_init (); + jerry_run( source_p, + source_size); -#ifdef __HOST - if (argc > 0) - { - if (file_name == NULL) - file_name = argv[1]; - else - jerry_exit (ERR_SEVERAL_FILES); - } -#endif + fake_exit(); -#ifdef __HOST - if (file_name == NULL) - jerry_exit (ERR_NO_FILES); - - file = __fopen (file_name, "r"); - - if (file == NULL) - { - jerry_exit (ERR_IO); - } - - lexer_set_file (file); -#else - lexer_set_source (generated_source); -#endif - - // First run parser to fill list of strings - token tok = lexer_next_token (); - while (tok.type != TOK_EOF) - tok = lexer_next_token (); - - strings_num = lexer_get_strings (strings); - nums_count = lexer_get_nums (nums); - lexer_adjust_num_ids (); - - // Reset lexer -#ifdef __HOST - __rewind (file); - lexer_set_file (file); -#else - lexer_set_source (generated_source); -#endif - - parser_init (); - offset = serializer_dump_strings (strings, strings_num); - serializer_dump_nums (nums, nums_count, offset, strings_num); - parser_parse_program (); - -#ifdef __TARGET_MCU - fake_exit (); -#endif - - return 0; + JERRY_UNREACHABLE(); } +#else /* !__HOST && !__TARGET_MCU */ +# error "!__HOST && !__TARGET_MCU" +#endif /* !__HOST && !__TARGET_MCU */