@@ -86,6 +86,8 @@ typedef struct _rule_stack_t {
8686} rule_stack_t ;
8787
8888typedef struct _parser_t {
89+ bool had_memory_error ;
90+
8991 uint rule_stack_alloc ;
9092 uint rule_stack_top ;
9193 rule_stack_t * rule_stack ;
@@ -97,9 +99,21 @@ typedef struct _parser_t {
9799 mp_lexer_t * lexer ;
98100} parser_t ;
99101
102+ STATIC inline void memory_error (parser_t * parser ) {
103+ parser -> had_memory_error = true;
104+ }
105+
100106STATIC void push_rule (parser_t * parser , int src_line , const rule_t * rule , int arg_i ) {
107+ if (parser -> had_memory_error ) {
108+ return ;
109+ }
101110 if (parser -> rule_stack_top >= parser -> rule_stack_alloc ) {
102- parser -> rule_stack = m_renew (rule_stack_t , parser -> rule_stack , parser -> rule_stack_alloc , parser -> rule_stack_alloc * 2 );
111+ rule_stack_t * rs = m_renew_maybe (rule_stack_t , parser -> rule_stack , parser -> rule_stack_alloc , parser -> rule_stack_alloc * 2 );
112+ if (rs == NULL ) {
113+ memory_error (parser );
114+ return ;
115+ }
116+ parser -> rule_stack = rs ;
103117 parser -> rule_stack_alloc *= 2 ;
104118 }
105119 rule_stack_t * rs = & parser -> rule_stack [parser -> rule_stack_top ++ ];
@@ -116,6 +130,7 @@ STATIC void push_rule_from_arg(parser_t *parser, uint arg) {
116130}
117131
118132STATIC void pop_rule (parser_t * parser , const rule_t * * rule , uint * arg_i , uint * src_line ) {
133+ assert (!parser -> had_memory_error );
119134 parser -> rule_stack_top -= 1 ;
120135 * rule = rules [parser -> rule_stack [parser -> rule_stack_top ].rule_id ];
121136 * arg_i = parser -> rule_stack [parser -> rule_stack_top ].arg_i ;
@@ -129,15 +144,6 @@ mp_parse_node_t mp_parse_node_new_leaf(machine_int_t kind, machine_int_t arg) {
129144 return (mp_parse_node_t )(kind | (arg << 5 ));
130145}
131146
132- //int num_parse_nodes_allocated = 0;
133- mp_parse_node_struct_t * parse_node_new_struct (int src_line , int rule_id , int num_args ) {
134- mp_parse_node_struct_t * pn = m_new_obj_var (mp_parse_node_struct_t , mp_parse_node_t , num_args );
135- pn -> source_line = src_line ;
136- pn -> kind_num_nodes = (rule_id & 0xff ) | (num_args << 8 );
137- //num_parse_nodes_allocated += 1;
138- return pn ;
139- }
140-
141147uint mp_parse_node_free (mp_parse_node_t pn ) {
142148 uint cnt = 0 ;
143149 if (MP_PARSE_NODE_IS_STRUCT (pn )) {
@@ -211,18 +217,32 @@ STATIC void result_stack_show(parser_t *parser) {
211217*/
212218
213219STATIC mp_parse_node_t pop_result (parser_t * parser ) {
220+ if (parser -> had_memory_error ) {
221+ return MP_PARSE_NODE_NULL ;
222+ }
214223 assert (parser -> result_stack_top > 0 );
215224 return parser -> result_stack [-- parser -> result_stack_top ];
216225}
217226
218227STATIC mp_parse_node_t peek_result (parser_t * parser , int pos ) {
228+ if (parser -> had_memory_error ) {
229+ return MP_PARSE_NODE_NULL ;
230+ }
219231 assert (parser -> result_stack_top > pos );
220232 return parser -> result_stack [parser -> result_stack_top - 1 - pos ];
221233}
222234
223235STATIC void push_result_node (parser_t * parser , mp_parse_node_t pn ) {
236+ if (parser -> had_memory_error ) {
237+ return ;
238+ }
224239 if (parser -> result_stack_top >= parser -> result_stack_alloc ) {
225- parser -> result_stack = m_renew (mp_parse_node_t , parser -> result_stack , parser -> result_stack_alloc , parser -> result_stack_alloc * 2 );
240+ mp_parse_node_t * pn = m_renew_maybe (mp_parse_node_t , parser -> result_stack , parser -> result_stack_alloc , parser -> result_stack_alloc * 2 );
241+ if (pn == NULL ) {
242+ memory_error (parser );
243+ return ;
244+ }
245+ parser -> result_stack = pn ;
226246 parser -> result_stack_alloc *= 2 ;
227247 }
228248 parser -> result_stack [parser -> result_stack_top ++ ] = pn ;
@@ -283,7 +303,13 @@ STATIC void push_result_token(parser_t *parser, const mp_lexer_t *lex) {
283303}
284304
285305STATIC void push_result_rule (parser_t * parser , int src_line , const rule_t * rule , int num_args ) {
286- mp_parse_node_struct_t * pn = parse_node_new_struct (src_line , rule -> rule_id , num_args );
306+ mp_parse_node_struct_t * pn = m_new_obj_var_maybe (mp_parse_node_struct_t , mp_parse_node_t , num_args );
307+ if (pn == NULL ) {
308+ memory_error (parser );
309+ return ;
310+ }
311+ pn -> source_line = src_line ;
312+ pn -> kind_num_nodes = (rule -> rule_id & 0xff ) | (num_args << 8 );
287313 for (int i = num_args ; i > 0 ; i -- ) {
288314 pn -> nodes [i - 1 ] = pop_result (parser );
289315 }
@@ -296,6 +322,8 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p
296322
297323 parser_t * parser = m_new_obj (parser_t );
298324
325+ parser -> had_memory_error = false;
326+
299327 parser -> rule_stack_alloc = 64 ;
300328 parser -> rule_stack_top = 0 ;
301329 parser -> rule_stack = m_new (rule_stack_t , parser -> rule_stack_alloc );
@@ -327,7 +355,7 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p
327355
328356 for (;;) {
329357 next_rule :
330- if (parser -> rule_stack_top == 0 ) {
358+ if (parser -> rule_stack_top == 0 || parser -> had_memory_error ) {
331359 break ;
332360 }
333361
@@ -596,6 +624,16 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p
596624 }
597625 }
598626
627+ mp_parse_node_t result ;
628+
629+ // check if we had a memory error
630+ if (parser -> had_memory_error ) {
631+ * parse_error_kind_out = MP_PARSE_ERROR_MEMORY ;
632+ result = MP_PARSE_NODE_NULL ;
633+ goto finished ;
634+
635+ }
636+
599637 // check we are at the end of the token stream
600638 if (!mp_lexer_is_kind (lex , MP_TOKEN_END )) {
601639 goto syntax_error ;
@@ -609,7 +647,7 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p
609647
610648 // get the root parse node that we created
611649 assert (parser -> result_stack_top == 1 );
612- mp_parse_node_t result = parser -> result_stack [0 ];
650+ result = parser -> result_stack [0 ];
613651
614652finished :
615653 // free the memory that we don't need anymore
0 commit comments