@@ -286,3 +286,89 @@ fn test_code_table_all_features() {
286286 . replace( " " , "" )
287287 ) ;
288288}
289+
290+ #[ test]
291+ fn test_reuse_code_table_multiple_times ( ) {
292+ let source: & str = r#"
293+ #define table CODE_TABLE {
294+ 0x1234
295+ }
296+
297+ #define macro MAIN() = takes(0) returns (0) {
298+ __tablesize(CODE_TABLE)
299+ __tablestart(CODE_TABLE)
300+
301+ __tablesize(CODE_TABLE)
302+ __tablestart(CODE_TABLE)
303+ }
304+ "# ;
305+
306+ // Parse tokens
307+ let flattened_source = FullFileSource { source, file : None , spans : vec ! [ ] } ;
308+ let lexer = Lexer :: new ( flattened_source) ;
309+ let tokens = lexer. into_iter ( ) . map ( |x| x. unwrap ( ) ) . collect :: < Vec < Token > > ( ) ;
310+ let mut parser = Parser :: new ( tokens, None ) ;
311+
312+ // Parse the AST
313+ let mut contract = parser. parse ( ) . unwrap ( ) ;
314+
315+ // Derive storage pointers
316+ contract. derive_storage_pointers ( ) ;
317+
318+ // Instantiate Codegen
319+ let cg = Codegen :: new ( ) ;
320+
321+ // The codegen instance should have no artifact
322+ assert ! ( cg. artifact. is_none( ) ) ;
323+
324+ // Have the Codegen create the constructor bytecode
325+ let mbytes = Codegen :: generate_main_bytecode ( & EVMVersion :: default ( ) , & contract, None ) . unwrap ( ) ;
326+
327+ // Two times: 60 = PUSH1, 02 = 2 bytes table size, 61 = PUSH2, 000a = 10 bytes table start
328+ // Plus the 0x1234
329+ assert_eq ! ( mbytes, "600261000a 600261000a 1234" . replace( " " , "" ) ) ;
330+ }
331+
332+ #[ test]
333+ fn test_reuse_code_table_multiple_times_macro ( ) {
334+ let source: & str = r#"
335+ #define table CODE_TABLE {
336+ 0x1234
337+ }
338+
339+ #define macro MAIN() = takes(0) returns (0) {
340+ TEST_TABLE()
341+ TEST_TABLE()
342+ }
343+
344+ #define macro TEST_TABLE() = takes(0) returns (0) {
345+ __tablesize(CODE_TABLE)
346+ __tablestart(CODE_TABLE)
347+ }
348+ "# ;
349+
350+ // Parse tokens
351+ let flattened_source = FullFileSource { source, file : None , spans : vec ! [ ] } ;
352+ let lexer = Lexer :: new ( flattened_source) ;
353+ let tokens = lexer. into_iter ( ) . map ( |x| x. unwrap ( ) ) . collect :: < Vec < Token > > ( ) ;
354+ let mut parser = Parser :: new ( tokens, None ) ;
355+
356+ // Parse the AST
357+ let mut contract = parser. parse ( ) . unwrap ( ) ;
358+
359+ // Derive storage pointers
360+ contract. derive_storage_pointers ( ) ;
361+
362+ // Instantiate Codegen
363+ let cg = Codegen :: new ( ) ;
364+
365+ // The codegen instance should have no artifact
366+ assert ! ( cg. artifact. is_none( ) ) ;
367+
368+ // Have the Codegen create the constructor bytecode
369+ let mbytes = Codegen :: generate_main_bytecode ( & EVMVersion :: default ( ) , & contract, None ) . unwrap ( ) ;
370+
371+ // Two times: 60 = PUSH1, 02 = 2 bytes table size, 61 = PUSH2, 000a = 10 bytes table start
372+ // Plus the 0x1234
373+ assert_eq ! ( mbytes, "600261000a 600261000a 1234" . replace( " " , "" ) ) ;
374+ }
0 commit comments