20
20
21
21
#include < libsolidity/experimental/codegen/IRGenerationContext.h>
22
22
#include < libsolidity/experimental/codegen/IRVariable.h>
23
+ #include < libsolidity/experimental/ast/TypeSystemHelper.h>
24
+ #include < libsolidity/experimental/analysis/TypeInference.h>
23
25
24
26
#include < libsolidity/ast/ASTVisitor.h>
25
27
@@ -37,10 +39,58 @@ class IRGeneratorForStatements: public ASTConstVisitor
37
39
38
40
std::string generate (ASTNode const & _node);
39
41
40
- static std::size_t stackSize (IRGenerationContext, Type)
42
+ static std::size_t stackSize (IRGenerationContext const & _context , Type _type )
41
43
{
42
- // TODO
43
- return 1 ;
44
+ TypeSystemHelpers helper{_context.analysis .typeSystem ()};
45
+ _type = _context.env ->resolve (_type);
46
+ solAssert (std::holds_alternative<TypeConstant>(_type), " No monomorphized type." );
47
+
48
+ // type -> # stack slots
49
+ // unit, itself -> 0
50
+ // void, literals(integer), typeFunction -> error (maybe generate a revert)
51
+ // word, bool, function -> 1
52
+ // pair -> sum(stackSize(args))
53
+ // user-defined -> stackSize(underlying type)
54
+ TypeConstant typeConstant = std::get<TypeConstant>(_type);
55
+ if (helper.isPrimitiveType (_type, PrimitiveType::Unit) ||
56
+ helper.isPrimitiveType (_type, PrimitiveType::Itself))
57
+ return 0 ;
58
+ else if (helper.isPrimitiveType (_type, PrimitiveType::Bool) || helper.isPrimitiveType (_type, PrimitiveType::Word))
59
+ {
60
+ solAssert (typeConstant.arguments .empty (), " Primitive type Bool or Word should have no arguments." );
61
+ return 1 ;
62
+ }
63
+ else if (helper.isFunctionType (_type))
64
+ return 1 ;
65
+ else if (
66
+ helper.isPrimitiveType (_type, PrimitiveType::Integer) ||
67
+ helper.isPrimitiveType (_type, PrimitiveType::Void) ||
68
+ helper.isPrimitiveType (_type, PrimitiveType::TypeFunction))
69
+ solThrow (langutil::CompilerError, " Primitive type Void, Unit or TypeFunction do not have stack slot" ); // FIXME: proper error
70
+ else if (helper.isPrimitiveType (_type, PrimitiveType::Pair))
71
+ {
72
+ solAssert (typeConstant.arguments .size () == 2 );
73
+ return stackSize (_context, typeConstant.arguments .front ()) + stackSize (_context, typeConstant.arguments .back ());
74
+ }
75
+ else
76
+ {
77
+ Type underlyingType = _context.analysis .annotation <TypeInference>().underlyingTypes .at (typeConstant.constructor );
78
+ if (helper.isTypeConstant (underlyingType))
79
+ return stackSize (_context, underlyingType);
80
+
81
+ TypeEnvironment env = _context.env ->clone ();
82
+ Type genericFunctionType = helper.typeFunctionType (
83
+ helper.tupleType (typeConstant.arguments ),
84
+ env.typeSystem ().freshTypeVariable ({}));
85
+ solAssert (env.unify (genericFunctionType, underlyingType).empty ());
86
+
87
+ Type resolvedType = env.resolveRecursive (genericFunctionType);
88
+ auto [argumentType, resultType] = helper.destTypeFunctionType (resolvedType);
89
+ return stackSize (_context, resultType);
90
+ }
91
+
92
+ // TODO: sum types
93
+ return 0 ;
44
94
}
45
95
46
96
private:
0 commit comments