forked from freebasic/fbc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
todo.txt
430 lines (381 loc) · 21.8 KB
/
todo.txt
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
o Dim Byref
- There might still be places in the compiler where symbIsRef() checks are
missing. E.g. calculating a variable size based on dtype alone would be
wrong now in case it's a reference. Previously this problem already existed
but only for parameters and function results.
- symbHasDtor() & co should either be adjusted to check for REF/IMPORT/PARAMBYREF/PARAMINSTANCE flags,
or be renamed to symbTypeHasDtor()
- arrays of refs
- parameter syntax?
byref as integer <= integer reference
(any) as integer <= bydesc array of integers
byref (any) as integer <= bydesc array of integer references?
(looks like array being passed byref - confusing)
- test that the rtlib functions like Redim don't call ctors/dtors
- allow/fix initialization from non-var:
- should allow everything that's allowed for byref parameters (CALLs,
CALLCTORs, TYPEINIs, constants, literals etc) by copying to a temp var
if needed
- Temp var life-time must be extended to the same scope as the reference;
WITH is already doing something much like this, except it uses an implicit scope block,
which we don't need. The temp vars from the reference var initializer are in the same
scope as the reference var, and it should be enough to just remove their TEMP flag.
- allow BYVAL initialization, like byref results/params
- allow BYREF fields; but they must be initialized in a constructor - what syntax to use for that?
@a = b works, but feels like a hack. Otherwise, a new syntax for field initialization is needed,
like initializer lists in C++
o boolean
- LLVM backend
- test overload resolution?
- add an -exx check to detect illegal boolean values on read?
- MacOSX/Darwin has 4-byte bool, that's the only case where gcc booleans aren't 1 byte.
fbc has to do it the same way to be compatible.
o 64bit
- FB includes must be adjusted for 64bit compatibility (if the corresponding
library even is available on 64bit)
- Windows port I/O driver? Can it be ported to 64bit? is it needed?
- 64bit bitfields aren't working properly - see tests/structs/bitfield-types.bas
o LLVM backend
- _setVregDataType() currently generates code (bitcasts), unlike other backends.
It works for noconv casts on rvalues, but breaks for noconv casts on lvalues.
Maybe it should use the *(newtype*)&x trick to support it.
- astTypeIniAddPad() must be ignored, but in exchange all fields must be
initialized explicitly by specifying the data type
(can use "zeroinitializer" as the value at least)
- Check whether F2I conversions work correctly for unsigned integers (compare
to issues in C/ASM backends), and overall can't trigger fptosi/fptoui's
conditions for undefined behaviour
- returning structs in registers? Disabled for -gen gcc in hGetReturnType(),
can the same be done for -gen llvm?
- structs should be emitted as byte arrays, to let the FB side handle
packing/alignment, unless the fields must be emitted individually as with
the C backend due to global varinis with procptrs that can't be emitted in
form of raw bytes since they're not literal numbers/constants.
- LLVM has "type <{ fields... }>" for packed structs, but that's just
FIELD = 1, there is no direct way to do FIELD = 2 or 4.
clang uses a packed struct and then inserts padding fields (i8) manually.
- LLVM doesn't have unions, it'd be easier to emit them as byte arrays
(instead of a struct containing the biggest member only)
- Debugging metadata
- Inline ASM
- va_*() macros can't be implemented, so must be disallowed just like with -gen gcc
o ABI
- review passing of short structs in registers or though hidden pointer
parameter on the stack. fbc appears to be consistent with it-self
for calling and returning but not when different backends are mixed
for example, gas/gcc32 or gas64/gcc64. Appears that windows only
passes structs through hidden parameter, regardless of the size.
- MinGW GCC 4.7 C++ defaults to __thiscall for methods like MSVC,
instead of __cdecl as on Linux, even though GCC doesn't use MSVC's name
mangling [yet].
[ ] refactor cProcCallingConv() usage and target specific checks
- FB can probably support __fastcall with C/LLVM backends pretty easily
[x] add the __fastcall keyword
[x] add '-z no-fastcall' to ignore "fastcall" calling convention
[x] allow defining and calling __fastcall procedures in gas 32
[x] only allow integral data types
[ ] testing on other arch / targets (arm, freebsd, dos, etc)
[ ] preserve EDX in nested calls - it could get trashed and currently
we don't have a defined way to preserve
- FB can probably support __thiscall with C/LLVM backends pretty easily
[x] use __thiscall calling by default for mingw gcc 32-bit,
currently, users must manage this explicitly, recommend using a
#define thiscall __thiscall depending on target platform
[x] only allow integral data types
[ ] more tests and documentation for mangling/calling conventions, not every
calling convention is tested or documented completely - also hard to test
[x] allow defining and calling __thiscall procedures in gas 32
[x] silently ignore on 64-bit, but warn if declare & procedure is different
[x] implement in -gen gas 32-bit. Hard to do, AST/IR/EMIT currently doesn't
have enough information or implementation for passing arguments in registers.
[x] add the __thiscall keyword
[x] add '-z no-thiscall' to ignore "thiscall" and revert to default calling
convention
o static member vars
- allow STATIC IMPORT, like EXTERN IMPORT (extract common code from cVariableDecl())
- the varexpr used to access (if any) is discarded since it's a static access
for which no specific instance is needed; currently this will even discard
function calls with side effects, this should be fixed, the same happens
with other static accesses, i.e. constants/enums.
type UDT
static i as integer
dummy as integer
end type
dim UDT.i as integer
function f( ) as UDT
dim x as UDT
print "called"
function = x
end function
print f( ).i
o If parsing namespace prefixes (cIdentifier()), it should be possible to save
it into the parser context, so it could be restored and re-used by the next
parsing function that tries to make sense of the input.
- needed to fix #404: cSymbolType (using cIdentifier) will eat namespace prefixes,
and should "restore" them if it fails (i.e. if it's not a type), so then the
expression parsing can retry, with the proper namespace prefix.
This only really matters for len/sizeof.
- needed to show FB_WARNINGMSG_AMBIGIOUSLENSIZEOF for namespaced symbols
- alternative: lexSkip backwards, but that seems harder to implement
o Allow typeless DIMs to implement EXTERNs:
extern a as integer
dim a
o ThreadCall
Cannot safely pass BYREF parameters, especially not temp strings or other
temp objects which will be destroyed at the end of the ThreadCall statement
so they cannot safely be referenced from the thread...
o -exx should catch...
- out-of-bounds dimension argument given to lbound()/ubound()
- add an -exx aka -eboolean check to detect illegal boolean values on read?
- expand on -elocation option to provide full location information or if not
given (or implied) optimize out calls to fb_ErrorSetFuncName() and
fb_ErrorSetModName(), because we still get location from fb_ErrorThrowAt()
and fb_ErrorThrowEx(). Must test interaction with ON ERROR
[ ] ctor/dtor
- add 'function foo (...) as SomeObj = any', so #1682972 could be fixed AND when
speed is important, the temporary result instance won't be cleared
- ArrayClear will be used instead of a loop calling the dtors to destroy
local non-dynamic arrays
- callVarDtor will have to use astAddAfter then with scope blocks..
[ ] output member functions and static member data to the STABS TYPE/UDT info
- operators must be handled as well
- properties may need a __get/__set suffix
[ ] STATIC
- allow all global operators to be declared as static methods so the private
members could be accessed
[ ] operator overloading:
- OPERATOR foo.() ( lb1, lb2, ..... ) AS TYPE -- array indexing, not functor
[ ] quirks:
[ ] OPEN ... FOR is not checking for mode
- does QB allow that? CONS won't work without INPUT or OUTPUT
[X] GET and PUT shouldn't allow strings when the number of items is passed
[ ] -exx is giving suspicious ptr assignment when module/name are been restored inside ns'
[ ] add the -lang (qb|fb) cmd-line option:
- "qb":
[ ] RESUME is not working with array bounds and null ptr checks because the labels are not passed
- that's the reason why QB needs a cmd-line option, every line executed needs a
prev and post labels to be emitted to allow that to work
[ ] SHARED at subs (non-shared vars at mod-level will have to be allocated
statically, as before)
[ ] STATIC shouldn't create/allocate arrays, just declare them as static
[ ] ()'s around function arguments passed to byref params should make a copy of the
argument
[ ] events:
- there should be a call to the event trapping function on EVERY line
emitted (we can't use threads because DOS)
- to the above work, a new cmd-line option must be added (as in QB)
[ ] on key()
[ ] on timer()
[ ] on uevent
- the other events are seldom, if ever, used..
[ ] add "qb" mangling
[x] symbols with same name but different sufixes than keywords
[ ] arrays with same name as scalars (most spaghetti-code won't compile w/o this)
[ ] labels with the same name as procs:
declare sub foo \n foo: \n goto foo \n call foo
[x] suffixes not optional in keywords (ie: it's always STR$, not STR)
[x] data type remapping
[x] INTEGER is 16-bit wide
[x] LONG is 32-bit wide
[x] CVI should take a short in -lang qb mode
[x] move all variables to function-level, implicit or explict (see no SCOPE)
[x] GOSUB and RETURN in subroutines (so RETURN can't be used as a shortcut to EXIT FUNCTION)
- implement it using setjmp/longjmp later in the rtlib
[x] periods in symbol names
[x] numeric labels
[x] params passed by reference by default
[x] DEF### (ie: explicit types required)
[x] implicit variables
[x] suffixes % & ! # $
[x] '$dynamic, '$static, '$include
[x] LET
[x] ON .. GOTO|GOSUB
[x] ON ERROR, RESUME
[x] OPTION's
[x] DEFSNG by default
[x] OPEN should be compatible with QB (ie: OPEN "DEVICE:"), the bloat doesn't
matter in -lang qb mode, just implement a fb_OpenDev or so in the rtlib doing
the parsing that will call any supported fb_hFileOpen###'s (COM, LPT, CONS, etc)
[x] CALL: support undefined functions as in QB, all params BYREF as ANY
[ ] DEF - neither a macro nor function will work. The statements inside the DEF FN...
need module level scope except for the parameters which shadow module level
vars. Would be like a module level GOSUB but callable from any scope, taking
parameters and returning a value. Very messy. Also, it will make any symbol
called Fn... invalid because it allows forward refs.
[x] no SCOPE
[x] no NAMESPACE
[x] no CLASS (and exception handling)
[x] no op and function overloading
[x] no EXTERN (periods and suffixes screw mangling)
[x] no multi-threading - not thread*, mutex*, cond*
[x] no keyword not present in QB (prefixed with '__')
- "fb" - the inverse of "qb", but show deprecated messages by now for:
[ ] without ON ERROR, all stmts returning rt errors should be allowed to
be used as functions too
[ ] ParamArray, but with this syntax: foo(...) as bar
- array must be built at compile-time and destroyed after the call
- take care with objects..
[ ] PP:
[ ] add #pragma cmdline="-foo bar -baz"
[x] added as '#cmdline "args..."'
[x] don't allow #cmdline if any line was parsed already that emits backend code
[ ] clean-up the lang compatibility options in fbc source,
the restart logic and option tracking is difficult to
follow (even with the comments and well named symbols).
[ ] #if( sizeof() ) and other expressions will give wrong results
unless user specifically adds #cmdline "-end" since the auto
detection of first executable line can't be determined
For example real command line is "fbc -target win32 file.bas"
#cmdline "-target win64 -gen gcc"
#if( sizeof(integer) = 4 ) )
#print "this shouldn't happen, but will"
#endif
[x] default to -lang FB
[x] allow '-lang' to override '-lang' on real command line
[x] allow '-forcelang' to override '-lang' on real command line
[x] don't allow '-lang' to override '-forcelang' on the command line
[x] #lang directive applies to current module only
[x] '-forcelang' on real command line overrides #lang directives.
[x] '#cmdline "-lang"' should apply to all modules and can overide real command line
[x] '#cmdline "-forcelang ..."' should apply to all modules and can overide real command line '-lang' but not '-forcelang'
[X] add '-z nocmdline' to ignore #cmdline directives
[X] reset parser for command line options that require it
[X] reset fbc for command line options that require it (-target, -arch, -lib, etc)
- macro expansion: won't work for inner macros
- support default arguments?
[ ] SCOPE..END SCOPE:
- can't optimize multiple MEM_CLEAR's if there's any branch to
one of them
- error handlers should be restored too (or not allowed at all)
[ ] disallow (in -lang qb mode):
dim foo as foo
.. and later ..
const|dim|function|etc foo.bar
[ ] fbmain - explicit main function
- must check if anything but the init/end labels were defined already inside
the implicit main() or the mod-level constructor
- must delete proto and all ast nodes
- must create as CDECL but it doesn't have to be obligatory
- must support RETURN or FUNCTION = to set the result
- must check the params if passed byval and if they have the right types
[ ] forward type defs used in byval parms of function ptr type defs shouldn't be an error
- the prototype mangling must be updated when that occurs, but how to do that fast
enough? the args would have to be linked to parent (the prototype), but updating
the mangled alias on every argument can be slow..
[ ] add the wstring type:
- fb_ConsoleInput() won't call fb_DevScrnInit_ReadWstr( ), so an input to a
wstring won't work.. to not add more bloat, the compiler should have to
call fb_ConsoleInput(there_is_any_wstr_argument), not so simple..
- auto-convert literal strings to w- or z- on assignments, depending on the l-hand
side type
- fix the !!!FIXME!!!'s and write the !!!WRITEME!!!'s in the rtlib
[ ] passing a temporary string to a zstring ptr should not make yet-another temporary
assignment in hStrParamToPtrArg(), just a pointer copy that later should be
strDelete()'d
[ ] proc call:
- add named parameters (foo := expr)
- can be hard to be added because they don't have to come in order, params in
prototypes don't require a name and because overloading
- := must be a new token because the "foo bar : baz" ambiguity
[ ] method pointers / delegates
[x] extend PROCPTR( id [, signature] ) to allow pointers to methods
[x] fbc handles method pointers fairly well even though the syntax is not symmetrical
with invoking a method on a TYPE (class). We should probably be ok with this since
at a low level methods are just procedures and allowing this syntax at the very
least avoids extra procedure calls (i.e. non-static member calls static member
to call non-static member hack) and we would prefer to just call the non-static
member directly.
[x] var x = procptr( T.method ) returns a method pointer and can be invoked with
x( instance, [params]... ) - see above
[ ] safe-ish delegates would need to aggregate the instance and method pointer which will
likely requre a new built-in type to handle by the compiler. It's possible that we
could build a delegate in user code, but would have to sacrifice some type safety
since type information about the virtual table is not exposed to the user in any way.
The net result is that lookups in virtual tables must be cast to the proper type and
we don't have a way to check in user code the function signature of the virtual table
in user code.
*** *** *** *** ***
[ ] All functions returning STRING should actually return the FBSTRING object
- it must be coded in plain C to avoid C++ dependencies
- compiler has to allocate the descriptor as it does now following the gcc ABI
- any function in the run-time library returning strings will have to be
modified (chicken-egg problem)
- allocated on stack instead of using temp descriptors,
- better with threads, as no more locking needed in the rtlib
- allows STRING results to be passed between multiple rtlibs without
memory leaks (e.g. returned from DLL)
- no more STR_LOCK's
- no more checks for temp descriptors in all rtlib procs taking STRINGs
[x] fixed-len strings compatible with QB:
- no null-term, temporaries always created when passing to functions
- probably will need their own assign and concat functions
[ ] proc def:
- when checking the prototype, the access modifiers must be checked too: PUBLIC, PRIVATE
- to support params > 64k, "ret" can't be used
[ ] .stabn can't have args > 65535 (ie: line numbers)
- only switching to DWARF2 (ie: too complex) would fix that, let GCC do it..
[ ] arrays will fail in quirk gfx funcs if multi-dimensional and have <> 0 lBounds
[ ] add "fix-len|w|z|string * expr" support to array args passed by descriptor
[ ] named field initializers: ( foo => bar, udt => ( 1, { 2, 3 }, 4 ) )
- all fields initialized must be named as a special parser routine will have to be used,
that will keep track of what wasn't initialized to fill 'em with 0's - static only,
locals are already cleared
[ ] full debug support
- add dynamic arrays - couldn't get GDB to use Fortran-like arrays
- each overloaded function will show the locals of *ALL* functions
[ ] inline functions
- better than macros as they can be "turned off" when debugged
- too hard to be added now due the register spills, IR must handle inter blocks and
keep track of live vregs
o rtlib
- The decimal separator used/recognized by the CRT float <-> string conversion
functions (strtod, wcstod, sprintf, swprintf) depends on the CRT's locale
setting (setlocale()), i.e. STR()/VAL() and other internal users of these
functions will break if anyone calls setlocale() for LC_NUMERIC or LC_ALL
and changes away from the '.' decimal separator (e.g. gtk_init() sets LC_ALL).
However FB should always use '.' for portability.
We'd need our own float <-> string routines (PRINT USING/FORMAT may have one
part of that already) to really fix this.
o gfxlib2 thread-safety
- ScreenList() works like Dir(); it should use TLS instead of simple global var
o classes
- vtable lookup should handle THIS expression with side-effects
- obvious calls to unimplemented ABSTRACTs should be disallowed,
i.e. if the THIS expression is a stack/global object that cannot have
overridden the ABSTRACT, in contrast to a object pointer or byref object
- INTERFACE ... END INTERFACE
- structs extending OBJECT, not allowing any fields, only methods
- all methods automatically are ABSTRACT
interface A
declare [abstract] sub bar( )
end interface
- IMPLEMENTS:
type Child [extends Parent] [implements A, B, C]
or allow just one interface?
type Child extends A
- multiple interfaces comes down to multiple inheritance (too hard?)
- g++/clang++ emit vtables and implicit ctor/copyctor/dtor/let into one
section each allowing the linker to merge/discard duplicates:
.linkonce (COFF: http://sourceware.org/binutils/docs/as/Linkonce.html)
.section ...,comdat (ELF COMDAT groups: http://sourceware.org/binutils/docs-2.23/as/Section.html#Section)
fbc makes them PRIVATE currently; should it be changed to reduce .exe size?
- what should CLASS keyword do? struct vs. class as in C++?
- Down casting
- static (base to derived)
- dynamic (polymorphic)
- dynamic_cast<toType>(ptr) is converted to: ptr = (ptr != NULL? __dynamic_cast(void *ptr, RTTI *fromType, RTTI *toType, void *nullPtr): NULL);
- exceptions - with stack unwind support?
- FBSYMCHAINs are currently allocated from a fixed-size pool. If used up, it
wraps around and starts re-using nodes. This is dangerous because it could
overwrite nodes that are still in use.
- A huge CHAINPOOL_SIZE value should prevent any issues in practice
- But still the compiler should have a way to detect the overflow and report
an error, instead of running into "random" bugs
- Refcounting seems impossible though, because for that we'd have to unref
FBSYMCHAINs at proper places in lexer/parser/..., but symbLookup() can
return FBSYMCHAINs from imported namespaces that weren't allocated from
the chainpool, and even worse FBSYMCHAINs have references to each-other
through next/prev links...
- To really fix this, FBSYMCHAINs should be unique nodes allocated from a
dynamic list, and have clear ownership/lifetime, perhaps wrapped in some
kind of parent object