@@ -372,3 +372,172 @@ fn test_reuse_code_table_multiple_times_macro() {
372372 // Plus the 0x1234
373373 assert_eq ! ( mbytes, "600261000a 600261000a 1234" . replace( " " , "" ) ) ;
374374}
375+
376+ #[ test]
377+ fn test_code_table_builtin_constant_rightpad ( ) {
378+ let source: & str = r#"
379+ #define constant C = __RIGHTPAD(0x)
380+
381+ #define table T {
382+ [C]
383+ }
384+
385+ #define macro MAIN() = takes(0) returns (0) {
386+ __tablesize(T)
387+ __tablestart(T)
388+ }
389+ "# ;
390+
391+ // Parse tokens
392+ let flattened_source = FullFileSource { source, file : None , spans : vec ! [ ] } ;
393+ let lexer = Lexer :: new ( flattened_source) ;
394+ let tokens = lexer. into_iter ( ) . map ( |x| x. unwrap ( ) ) . collect :: < Vec < Token > > ( ) ;
395+ let mut parser = Parser :: new ( tokens, None ) ;
396+
397+ // Parse the AST
398+ let mut contract = parser. parse ( ) . unwrap ( ) ;
399+
400+ // Derive storage pointers
401+ contract. derive_storage_pointers ( ) ;
402+
403+ // Instantiate Codegen
404+ let cg = Codegen :: new ( ) ;
405+
406+ // The codegen instance should have no artifact
407+ assert ! ( cg. artifact. is_none( ) ) ;
408+
409+ // Have the Codegen create the constructor bytecode
410+ let mbytes = Codegen :: generate_main_bytecode ( & EVMVersion :: default ( ) , & contract, None , false ) . unwrap ( ) ;
411+
412+ // 60 = PUSH1, 20 = 32 bytes table size, 61 = PUSH2, 0005 = 5 bytes table start
413+ // RIGHTPAD(0x) produces 32 bytes of zeros
414+ assert_eq ! ( mbytes, "60 20 61 0005 0000000000000000000000000000000000000000000000000000000000000000" . replace( " " , "" ) ) ;
415+ }
416+
417+ #[ test]
418+ fn test_code_table_builtin_constant_leftpad ( ) {
419+ let source: & str = r#"
420+ #define constant PADDED = __LEFTPAD(0x1234)
421+
422+ #define table T {
423+ [PADDED]
424+ }
425+
426+ #define macro MAIN() = takes(0) returns (0) {
427+ __tablesize(T)
428+ __tablestart(T)
429+ }
430+ "# ;
431+
432+ // Parse tokens
433+ let flattened_source = FullFileSource { source, file : None , spans : vec ! [ ] } ;
434+ let lexer = Lexer :: new ( flattened_source) ;
435+ let tokens = lexer. into_iter ( ) . map ( |x| x. unwrap ( ) ) . collect :: < Vec < Token > > ( ) ;
436+ let mut parser = Parser :: new ( tokens, None ) ;
437+
438+ // Parse the AST
439+ let mut contract = parser. parse ( ) . unwrap ( ) ;
440+
441+ // Derive storage pointers
442+ contract. derive_storage_pointers ( ) ;
443+
444+ // Instantiate Codegen
445+ let cg = Codegen :: new ( ) ;
446+
447+ // The codegen instance should have no artifact
448+ assert ! ( cg. artifact. is_none( ) ) ;
449+
450+ // Have the Codegen create the constructor bytecode
451+ let mbytes = Codegen :: generate_main_bytecode ( & EVMVersion :: default ( ) , & contract, None , false ) . unwrap ( ) ;
452+
453+ // 60 = PUSH1, 20 = 32 bytes table size, 61 = PUSH2, 0005 = 5 bytes table start
454+ assert_eq ! ( mbytes, "60 20 61 0005 0000000000000000000000000000000000000000000000000000000000001234" . replace( " " , "" ) ) ;
455+ }
456+
457+ #[ test]
458+ fn test_code_table_builtin_constant_func_sig ( ) {
459+ let source: & str = r#"
460+ #define constant TRANSFER_SIG = __FUNC_SIG("transfer(address,uint256)")
461+
462+ #define table T {
463+ [TRANSFER_SIG]
464+ }
465+
466+ #define macro MAIN() = takes(0) returns (0) {
467+ __tablesize(T)
468+ __tablestart(T)
469+ }
470+ "# ;
471+
472+ // Parse tokens
473+ let flattened_source = FullFileSource { source, file : None , spans : vec ! [ ] } ;
474+ let lexer = Lexer :: new ( flattened_source) ;
475+ let tokens = lexer. into_iter ( ) . map ( |x| x. unwrap ( ) ) . collect :: < Vec < Token > > ( ) ;
476+ let mut parser = Parser :: new ( tokens, None ) ;
477+
478+ // Parse the AST
479+ let mut contract = parser. parse ( ) . unwrap ( ) ;
480+
481+ // Derive storage pointers
482+ contract. derive_storage_pointers ( ) ;
483+
484+ // Instantiate Codegen
485+ let cg = Codegen :: new ( ) ;
486+
487+ // The codegen instance should have no artifact
488+ assert ! ( cg. artifact. is_none( ) ) ;
489+
490+ // Have the Codegen create the constructor bytecode
491+ let mbytes = Codegen :: generate_main_bytecode ( & EVMVersion :: default ( ) , & contract, None , false ) . unwrap ( ) ;
492+
493+ // 60 = PUSH1, 04 = 4 bytes table size, 61 = PUSH2, 0005 = 5 bytes table start
494+ // a9059cbb = transfer(address,uint256) function signature
495+ assert_eq ! ( mbytes, "60 04 61 0005 a9059cbb" . replace( " " , "" ) ) ;
496+ }
497+
498+ #[ test]
499+ fn test_code_table_builtin_constant_mixed ( ) {
500+ let source: & str = r#"
501+ #define constant PADDED = __RIGHTPAD(0xABCD)
502+ #define constant SIG = __FUNC_SIG("balanceOf(address)")
503+ #define constant LITERAL = 0xDEADBEEF
504+
505+ #define table T {
506+ [PADDED]
507+ [SIG]
508+ [LITERAL]
509+ }
510+
511+ #define macro MAIN() = takes(0) returns (0) {
512+ __tablesize(T)
513+ __tablestart(T)
514+ }
515+ "# ;
516+
517+ // Parse tokens
518+ let flattened_source = FullFileSource { source, file : None , spans : vec ! [ ] } ;
519+ let lexer = Lexer :: new ( flattened_source) ;
520+ let tokens = lexer. into_iter ( ) . map ( |x| x. unwrap ( ) ) . collect :: < Vec < Token > > ( ) ;
521+ let mut parser = Parser :: new ( tokens, None ) ;
522+
523+ // Parse the AST
524+ let mut contract = parser. parse ( ) . unwrap ( ) ;
525+
526+ // Derive storage pointers
527+ contract. derive_storage_pointers ( ) ;
528+
529+ // Instantiate Codegen
530+ let cg = Codegen :: new ( ) ;
531+
532+ // The codegen instance should have no artifact
533+ assert ! ( cg. artifact. is_none( ) ) ;
534+
535+ // Have the Codegen create the constructor bytecode
536+ let mbytes = Codegen :: generate_main_bytecode ( & EVMVersion :: default ( ) , & contract, None , false ) . unwrap ( ) ;
537+
538+ // 60 = PUSH1, 28 = 40 bytes table size (32 + 4 + 4), 61 = PUSH2, 0005 = 5 bytes table start
539+ // RIGHTPAD(0xABCD) = 32 bytes with abcd at the start, padded right with zeros
540+ // balanceOf(address) = 70a08231
541+ // 0xDEADBEEF = deadbeef
542+ assert_eq ! ( mbytes, "60 28 61 0005 abcd00000000000000000000000000000000000000000000000000000000000070a08231 deadbeef" . replace( " " , "" ) ) ;
543+ }
0 commit comments