-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathNoAllocType.zu
280 lines (229 loc) · 7.94 KB
/
NoAllocType.zu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
#
# The Zimbu compiler written in Zimbu
#
# NoAllocType class.
#
# A Type used for items located on the stack. This wraps another type.
# Inheritance can't be used, because an object could be on the stack or not on
# the stack.
#
# Copyright 2014 Bram Moolenaar All Rights Reserved.
# Licensed under the Apache License, Version 2.0. See the LICENSE file or
# obtain a copy at: http://www.apache.org/licenses/LICENSE-2.0
#
IMPORT.PROTO "zui.proto"
IMPORT "ClassScope.zu"
IMPORT "ClassType.zu"
IMPORT "ClassRefType.zu"
IMPORT "Declaration.zu"
IMPORT "MethodType.zu"
IMPORT "ReferenceType.zu"
IMPORT "SContext.zu"
IMPORT "SymUse.zu"
IMPORT "Type.zu"
CLASS NoAllocType EXTENDS ReferenceType @items=public
Type $wrappedType
# When the wrapped type is an iobject, we don't know the size of the
# actually used object and would need to allocated it. But in most cases
# there is only one assignment and then we do know the object type. Then we
# can reserve room for that type and avoid the alloc.
# "iobjectType" is NIL until an assignment is found for this type, then it
# is set to that type. If another assignment is found for a different type,
# it is set to "THIS". In that case an alloc is needed.
Type $iobjectType
# Cached return value of getValueType()
Type $valueType
# Used to track scopes that depend on $iobjectType
ClassScope $scope
NEW(Type type, string name)
NEW(type.ttype, name)
$wrappedType = type
}
# Make a copy of this Type. Every subclass must redefine it.
FUNC $copyType() Type @replace @default
NoAllocType ret = NEW($wrappedType, $name)
$copyObjectValues(ret)
RETURN ret
}
# Copy the values of this object into |ret|.
PROC $copyObjectValues(NoAllocType ret) @default
$copyReferenceValues(ret)
ret.type = $wrappedType
}
FUNC $typeToString() string @replace
RETURN "%" .. $wrappedType.typeToString()
}
FUNC $getValueType(SContext ctx) Type @replace
IF $valueType == NIL
$valueType = $wrappedType.getValueType(ctx).getNoAllocType()
}
RETURN $valueType
}
FUNC $getNoAllocType() Type @replace
RETURN THIS
}
FUNC $isNoAlloc() bool @replace
RETURN TRUE
}
FUNC $getTtype() Enum @replace
RETURN $wrappedType.getTtype()
}
# Return the effective type. For a typedef it is the defined type.
FUNC $getEffType() Type @replace
RETURN $wrappedType.getEffType()
}
FUNC $getRefType() Type @replace
THROW "Internal: cannot pass a variable on stack by reference"
}
PROC $setCtypeName(string name) @replace
$wrappedType.setCtypeName(name)
}
FUNC $getCtypeName() string @replace
RETURN $wrappedType.getCtypeName()
}
FUNC $getAllocType(SContext ctx) Type @replace
THROW "Internal: getAllocType() does not work for a not allocated variable"
}
FUNC $isAllocType(SContext ctx) bool @replace
RETURN FALSE
}
FUNC $isManaged() bool @replace
RETURN FALSE # on the stack means not allocated
}
FUNC $getStarType(Zui.Position pos, SContext ctx) ClassRefType @replace
RETURN $wrappedType.getStarType(pos, ctx)
}
FUNC $isAbstract() bool @replace
RETURN $wrappedType.isAbstract()
}
FUNC $isIntType() bool @replace
RETURN FALSE
}
FUNC $isNatType() bool @replace
RETURN FALSE
}
FUNC $isFloatType() bool @replace
RETURN FALSE
}
FUNC $isMethodType() bool @replace
RETURN $wrappedType.isMethodType()
}
FUNC $isMethodOrRefType() bool @replace
RETURN $wrappedType.isMethodOrRefType()
}
FUNC $typeName(bool long) string @replace
RETURN "%" .. $wrappedType.typeName(long)
}
FUNC $getTypeName(SContext ctx) string @replace
RETURN $wrappedType.getTypeName(ctx)
}
FUNC $needCopyValue() bool @replace
RETURN $wrappedType.needCopyValue()
}
# |ctx| can be NIL if the scope doesn't need to be revisted when the type
# changes.
FUNC $getClassType(SContext ctx) ClassType @replace
IF ctx != NIL && ($iobjectType == NIL || $iobjectType ISNOT THIS)
# $iobjectType may change later, we need to come back here then.
IF $scope == NIL
$scope = ClassScope.NEW(NIL, NIL)
}
$scope.addScopeDependency(ctx.scope)
}
IF $iobjectType != NIL && $iobjectType ISNOT THIS
# We know what class is going to be used for the iobject, return that
# class.
RETURN $iobjectType
}
# Either we don't know what class is going to be used, or more than one
# class can be used ($iobjType IS THIS). Return the interface class.
RETURN $wrappedType.getClassType(ctx)
}
FUNC $getMethod() MethodType @replace
RETURN $wrappedType.getMethod()
}
FUNC $getDeclDict() multiDict<string, Declaration> @replace
RETURN $wrappedType.getDeclDict()
}
FUNC $getObjectDeclDict() multiDict<string, Declaration> @replace
RETURN $wrappedType.getDeclDict()
}
FUNC $getArgList() list<Declaration.C> @replace
RETURN $wrappedType.getArgList()
}
FUNC $getReturnType() Type @replace
RETURN $wrappedType.getReturnType()
}
FUNC $getTypespecType(int idx) Type @replace
RETURN $wrappedType.getTypespecType(idx)
}
FUNC $hasAnyMembers() bool @replace
RETURN $wrappedType.hasAnyMembers()
}
FUNC $findMember(string name, SymUse symUse) Declaration @replace
RETURN $wrappedType.findMember(name, symUse)
}
FUNC $findObjectMember(string name,
SymUse symUse,
MethodType.FindFuncOptions options,
bool inParent
) Declaration @replace
RETURN $wrappedType.findObjectMember(name, symUse, options, inParent)
}
PROC $findMatchingMethods(string name,
bool objectMethod,
list<Declaration.C> argList,
MethodType.Skip skip,
MethodType.FindFuncOptions options,
int &undef,
multiDict<int, Declaration> funcs,
SContext ctx
) @replace
$wrappedType.findMatchingMethods(name, objectMethod, argList, skip, options,
undef, funcs, ctx)
}
FUNC $findNewFromContainerMethod(Zui.Expression expr,
Type.Enum ttype, string tName,
SContext ctx) MethodType @replace
RETURN $wrappedType.findNewFromContainerMethod(expr, ttype, tName, ctx)
}
# This type isn't produced, the wrapped type is. Therefore depend on the
# wrapped type.
PROC $addDependsOn(Declaration decl) @replace
$wrappedType.addDependsOn(decl)
}
PROC $addDependsOnCond(Declaration decl, Declaration dependency) @replace
$wrappedType.addDependsOnCond(decl, dependency)
}
# Set the type of an iobject NEW() call, so that we know the size of the
# object.
PROC $setIobjectType(Type type, SContext ctx)
IF $wrappedType.getTtype() == Type.Enum.iobject
ClassType classType = type.getClassType(ctx)
IF classType != NIL && $iobjectType ISNOT THIS
&& $iobjectType ISNOT classType
IF $iobjectType == NIL
# Now we know what object type will be used.
$iobjectType = classType
ELSE
# Found two different NEW() calls, object type will change at runtime,
# need to allocate the object.
$iobjectType = THIS
}
# Scopes that used $iobjectType before must be re-visited.
IF $scope != NIL
$scope.setNeedPassInDependencies(ctx)
}
}
}
}
# Return TRUE if this is an iobject with more that one NEW() call types.
FUNC $needAlloc() bool
RETURN $iobjectType IS THIS
}
# Return the name of the class that this object or iobject should be
# initialzed with. Only to be used when $needAlloc() returns FALSE.
FUNC $getClassName(string default) string
RETURN $iobjectType == NIL ? default : $iobjectType.pName
}
}