FreeBASIC  0.91.0
rtl-mem.bas
Go to the documentation of this file.
1 '' intrinsic runtime lib memory functions (ALLOCATE, SWAP, ...)
2 ''
3 '' chng: oct/2004 written [v1ctor]
4 
5 #include once "fb.bi"
6 #include once "fbint.bi"
7 #include once "ast.bi"
8 #include once "rtl.bi"
9 
10  dim shared as FB_RTL_PROCDEF funcdata( 0 to ... ) = _
11  { _
12 /' function fb_NullPtrChk _
13  ( _
14  byval p as any ptr, _
15  byval linenum as long, _
16  byval fname as zstring ptr _
17  ) as any ptr '/ _
18  ( _
19  @FB_RTL_NULLPTRCHK, NULL, _
20  typeAddrOf( FB_DATATYPE_VOID ), FB_FUNCMODE_FBCALL, _
21  NULL, FB_RTL_OPT_NONE, _
22  3, _
23  { _
24  ( typeAddrOf( FB_DATATYPE_VOID ),FB_PARAMMODE_BYVAL, FALSE ), _
25  ( FB_DATATYPE_LONG, FB_PARAMMODE_BYVAL, FALSE ), _
26  ( typeAddrOf( FB_DATATYPE_CHAR ),FB_PARAMMODE_BYVAL, FALSE ) _
27  } _
28  ), _
29 /' function fb_MemCopy cdecl _
30  ( _
31  byref dst as any, _
32  byref src as any, _
33  byval bytes as uinteger _
34  ) as any ptr '/ _
35  ( _
36  @FB_RTL_MEMCOPY, @"memcpy", _
37  typeAddrOf( FB_DATATYPE_VOID ), FB_FUNCMODE_CDECL, _
38  NULL, FB_RTL_OPT_GCCBUILTIN, _
39  3, _
40  { _
41  ( FB_DATATYPE_VOID,FB_PARAMMODE_BYREF, FALSE ), _
42  ( FB_DATATYPE_VOID,FB_PARAMMODE_BYREF, FALSE ), _
43  ( FB_DATATYPE_UINT, FB_PARAMMODE_BYVAL, FALSE ) _
44  } _
45  ), _
46 /' sub fb_MemSwap( byref dst as any, byref src as any, byval bytes as integer ) '/ _
47  ( _
48  @FB_RTL_MEMSWAP, NULL, _
49  FB_DATATYPE_VOID, FB_FUNCMODE_FBCALL, _
50  NULL, FB_RTL_OPT_NONE, _
51  3, _
52  { _
53  ( FB_DATATYPE_VOID,FB_PARAMMODE_BYREF, FALSE ), _
54  ( FB_DATATYPE_VOID,FB_PARAMMODE_BYREF, FALSE ), _
55  ( FB_DATATYPE_INTEGER,FB_PARAMMODE_BYVAL, FALSE ) _
56  } _
57  ), _
58 /' sub fb_MemCopyClear _
59  ( _
60  byref dst as any, _
61  byval dstlen as integer, _
62  byref src as any, _
63  byval srclen as integer _
64  ) '/ _
65  ( _
66  @FB_RTL_MEMCOPYCLEAR, NULL, _
67  FB_DATATYPE_VOID, FB_FUNCMODE_FBCALL, _
68  NULL, FB_RTL_OPT_NONE, _
69  4, _
70  { _
71  ( FB_DATATYPE_VOID,FB_PARAMMODE_BYREF, FALSE ), _
72  ( FB_DATATYPE_INTEGER,FB_PARAMMODE_BYVAL, FALSE ), _
73  ( FB_DATATYPE_VOID,FB_PARAMMODE_BYREF, FALSE ), _
74  ( FB_DATATYPE_INTEGER,FB_PARAMMODE_BYVAL, FALSE ) _
75  } _
76  ), _
77 /' function fre( byval mode as long = 0 ) as uinteger '/ _
78  ( _
79  @"fre", @"fb_GetMemAvail", _
80  FB_DATATYPE_UINT, FB_FUNCMODE_FBCALL, _
81  NULL, FB_RTL_OPT_NONE, _
82  1, _
83  { _
84  ( FB_DATATYPE_LONG, FB_PARAMMODE_BYVAL, TRUE, 0 ) _
85  } _
86  ), _
87 /' function allocate cdecl( byval size as uinteger ) as any ptr '/ _
88  ( _
89  @"allocate", @"malloc", _
90  typeAddrOf( FB_DATATYPE_VOID ), FB_FUNCMODE_CDECL, _
91  NULL, FB_RTL_OPT_NOQB, _
92  1, _
93  { _
94  ( FB_DATATYPE_UINT,FB_PARAMMODE_BYVAL, FALSE ) _
95  } _
96  ), _
97 /' function callocate cdecl( byval items as uinteger, byval size as uinteger = 1 ) as any ptr '/ _
98  ( _
99  @"callocate", @"calloc", _
100  typeAddrOf( FB_DATATYPE_VOID ), FB_FUNCMODE_CDECL, _
101  NULL, FB_RTL_OPT_NOQB, _
102  2, _
103  { _
104  ( FB_DATATYPE_UINT,FB_PARAMMODE_BYVAL, FALSE ), _
105  ( FB_DATATYPE_UINT,FB_PARAMMODE_BYVAL, TRUE, 1 ) _
106  } _
107  ), _
108 /' function reallocate cdecl( byval p as any ptr, byval size as uinteger ) as any ptr '/ _
109  ( _
110  @"reallocate", @"realloc", _
111  typeAddrOf( FB_DATATYPE_VOID ), FB_FUNCMODE_CDECL, _
112  NULL, FB_RTL_OPT_NOQB, _
113  2, _
114  { _
115  ( typeAddrOf( FB_DATATYPE_VOID ),FB_PARAMMODE_BYVAL, FALSE ), _
116  ( FB_DATATYPE_UINT,FB_PARAMMODE_BYVAL, FALSE ) _
117  } _
118  ), _
119 /' sub deallocate cdecl( byval p as any ptr ) '/ _
120  ( _
121  @"deallocate", @"free", _
122  FB_DATATYPE_VOID, FB_FUNCMODE_CDECL, _
123  NULL, FB_RTL_OPT_NOQB, _
124  1, _
125  { _
126  ( typeAddrOf( FB_DATATYPE_VOID ),FB_PARAMMODE_BYVAL, FALSE ) _
127  } _
128  ), _
129 /' function clear cdecl _
130  ( _
131  byref dst as any, _
132  byval value as long = 0, _
133  byval bytes as uinteger _
134  ) as any ptr '/ _
135  ( _
136  @"clear", @"memset", _
137  typeAddrOf( FB_DATATYPE_VOID ), FB_FUNCMODE_CDECL, _
138  NULL, FB_RTL_OPT_GCCBUILTIN, _
139  3, _
140  { _
141  ( FB_DATATYPE_VOID,FB_PARAMMODE_BYREF, FALSE ), _
142  ( FB_DATATYPE_LONG, FB_PARAMMODE_BYVAL, TRUE, 0 ), _
143  ( FB_DATATYPE_UINT, FB_PARAMMODE_BYVAL, FALSE ) _
144  } _
145  ), _
146 /' operator new cdecl( byval bytes as uinteger ) as any ptr '/ _
147  ( _
148  cast( zstring ptr, AST_OP_NEW ), NULL, _
149  typeAddrOf( FB_DATATYPE_VOID ), FB_FUNCMODE_CDECL, _
150  NULL, FB_RTL_OPT_OVER or FB_RTL_OPT_OPERATOR, _
151  1, _
152  { _
153  ( FB_DATATYPE_UINT, FB_PARAMMODE_BYVAL, FALSE ) _
154  } _
155  ), _
156 /' operator new[] cdecl( byval bytes as uinteger ) as any ptr '/ _
157  ( _
158  cast( zstring ptr, AST_OP_NEW_VEC ), NULL, _
159  typeAddrOf( FB_DATATYPE_VOID ), FB_FUNCMODE_CDECL, _
160  NULL, FB_RTL_OPT_OVER or FB_RTL_OPT_OPERATOR, _
161  1, _
162  { _
163  ( FB_DATATYPE_UINT, FB_PARAMMODE_BYVAL, FALSE ) _
164  } _
165  ), _
166 /' operator delete cdecl( byval ptr as any ptr ) '/ _
167  ( _
168  cast( zstring ptr, AST_OP_DEL ), NULL, _
169  FB_DATATYPE_VOID, FB_FUNCMODE_CDECL, _
170  NULL, FB_RTL_OPT_OVER or FB_RTL_OPT_OPERATOR, _
171  1, _
172  { _
173  ( typeAddrOf( FB_DATATYPE_VOID ), FB_PARAMMODE_BYVAL, FALSE ) _
174  } _
175  ), _
176 /' operator delete[] cdecl( byval ptr as any ptr ) '/ _
177  ( _
178  cast( zstring ptr, AST_OP_DEL_VEC ), NULL, _
179  FB_DATATYPE_VOID, FB_FUNCMODE_CDECL, _
180  NULL, FB_RTL_OPT_OVER or FB_RTL_OPT_OPERATOR, _
181  1, _
182  { _
183  ( typeAddrOf( FB_DATATYPE_VOID ), FB_PARAMMODE_BYVAL, FALSE ) _
184  } _
185  ), _
186 /' EOL '/ _
187  ( _
188  NULL _
189  ) _
190  }
191 
192 sub hUpdateNewOpSizeParamType( byval op as AST_OP )
193  dim as FBSYMBOL ptr sym = any
194  sym = symbGetCompOpOvlHead( NULL, op )
195  if( sym ) then
196  sym = symbGetProcHeadParam( sym )
197  if( sym ) then
198  symbGetFullType( sym ) = iif( fbCpuTypeIs64bit( ), _
199  env.target.size_t64, _
200  env.target.size_t32 )
201  end if
202  end if
203 end sub
204 
205 '':::::
207 
209 
210  '' remap the new/new[] size param, size_t can be unsigned (int | long),
211  '' making the mangling incompatible..
212 
213  '' new
214  hUpdateNewOpSizeParamType( AST_OP_NEW )
215 
216  '' new[]
217  hUpdateNewOpSizeParamType( AST_OP_NEW_VEC )
218 
219 end sub
220 
221 '':::::
223 
224  '' procs will be deleted when symbEnd is called
225 
226 end sub
227 
228 
229 '':::::
230 function rtlNullPtrCheck _
231  ( _
232  byval p as ASTNODE ptr, _
233  byval linenum as integer, _
234  byval module as zstring ptr _
235  ) as ASTNODE ptr
236 
237  dim as ASTNODE ptr proc = any
238 
239  function = NULL
240 
241  proc = astNewCALL( PROCLOOKUP( NULLPTRCHK ) )
242 
243  '' ptr
244  if( astNewARG( proc, _
245  astNewCONV( typeAddrOf( FB_DATATYPE_VOID ), NULL, p ), _
246  typeAddrOf( FB_DATATYPE_VOID ) ) = NULL ) then
247  exit function
248  end if
249 
250  '' linenum
251  if( astNewARG( proc, astNewCONSTi( linenum ) ) = NULL ) then
252  exit function
253  end if
254 
255  '' module
256  if( astNewARG( proc, astNewCONSTstr( module ) ) = NULL ) then
257  exit function
258  end if
259 
260  function = proc
261 
262 end function
263 
264 '':::::
265 function rtlMemCopy _
266  ( _
267  byval dst as ASTNODE ptr, _
268  byval src as ASTNODE ptr, _
269  byval bytes as longint _
270  ) as ASTNODE ptr
271 
272  dim as ASTNODE ptr proc = any
273 
274  function = NULL
275 
276  ''
277  proc = astNewCALL( PROCLOOKUP( MEMCOPY ) )
278 
279  '' dst as any
280  if( astNewARG( proc, dst ) = NULL ) then
281  exit function
282  end if
283 
284  '' src as any
285  if( astNewARG( proc, src ) = NULL ) then
286  exit function
287  end if
288 
289  '' byval bytes as integer
290  if( astNewARG( proc, astNewCONSTi( bytes ) ) = NULL ) then
291  exit function
292  end if
293 
294  ''
295  function = proc
296 
297 end function
298 
299 '':::::
300 function rtlMemSwap _
301  ( _
302  byval dst as ASTNODE ptr, _
303  byval src as ASTNODE ptr _
304  ) as integer
305 
306  function = FALSE
307 
308  dim as ASTNODE ptr proc = astNewCALL( PROCLOOKUP( MEMSWAP ) )
309 
310  '' always calc len before pushing the param
311  dim as longint bytes = rtlCalcExprLen( dst )
312 
313  '' dst as any
314  if( astNewARG( proc, dst ) = NULL ) then
315  exit function
316  end if
317 
318  '' src as any
319  if( astNewARG( proc, src ) = NULL ) then
320  exit function
321  end if
322 
323  '' byval bytes as integer
324  if( astNewARG( proc, astNewCONSTi( bytes ) ) = NULL ) then
325  exit function
326  end if
327 
328  astAdd( proc )
329 
330  function = TRUE
331 end function
332 
333 '':::::
334 function rtlMemCopyClear _
335  ( _
336  byval dstexpr as ASTNODE ptr, _
337  byval dstlen as longint, _
338  byval srcexpr as ASTNODE ptr, _
339  byval srclen as longint _
340  ) as integer
341 
342  dim as ASTNODE ptr proc = any
343 
344  function = FALSE
345 
346  ''
347  proc = astNewCALL( PROCLOOKUP( MEMCOPYCLEAR ) )
348 
349  '' dst as any
350  if( astNewARG( proc, dstexpr ) = NULL ) then
351  exit function
352  end if
353 
354  '' byval dstlen as integer
355  if( astNewARG( proc, astNewCONSTi( dstlen ) ) = NULL ) then
356  exit function
357  end if
358 
359  '' src as any
360  if( astNewARG( proc, srcexpr ) = NULL ) then
361  exit function
362  end if
363 
364  '' byval srclen as integer
365  if( astNewARG( proc, astNewCONSTi( srclen ) ) = NULL ) then
366  exit function
367  end if
368 
369  ''
370  astAdd( proc )
371 
372  function = TRUE
373 
374 end function
375 
376 function rtlMemNewOp _
377  ( _
378  byval op as integer, _
379  byval len_expr as ASTNODE ptr, _
380  byval dtype as integer, _
381  byval subtype as FBSYMBOL ptr _
382  ) as ASTNODE ptr
383 
384  dim as ASTNODE ptr proc = any
385  dim as FBSYMBOL ptr sym = any
386 
387  '' try to find an overloaded new()
388  if( typeGet( dtype ) = FB_DATATYPE_STRUCT ) then
389  assert( (astGetOpSelfVer( op ) = AST_OP_NEW_SELF) or (astGetOpSelfVer( op ) = AST_OP_NEW_VEC_SELF) )
390  sym = symbGetCompOpOvlHead( subtype, astGetOpSelfVer( op ) )
391  if( sym ) then
392  if( symbCheckAccess( sym ) = FALSE ) then
393  errReport( FB_ERRMSG_ILLEGALMEMBERACCESS )
394  end if
395  end if
396  else
397  sym = NULL
398  end if
399 
400  '' if not defined, call the global one
401  if( sym = NULL ) then
402  assert( (op = AST_OP_NEW) or (op = AST_OP_NEW_VEC) )
403  sym = symbGetCompOpOvlHead( NULL, op )
404  end if
405 
406  proc = astNewCALL( sym )
407 
408  '' byval len as uinteger
409  if( astNewARG( proc, len_expr ) = NULL ) then
410  exit function
411  end if
412 
413  function = proc
414 end function
415 
416 function rtlMemDeleteOp _
417  ( _
418  byval op as integer, _
419  byval ptr_expr as ASTNODE ptr, _
420  byval dtype as integer, _
421  byval subtype as FBSYMBOL ptr _
422  ) as ASTNODE ptr
423 
424  dim as ASTNODE ptr proc = any
425  dim as FBSYMBOL ptr sym = any
426 
427  '' try to find an overloaded delete()
428  if( typeGet( dtype ) = FB_DATATYPE_STRUCT ) then
429  assert( (astGetOpSelfVer( op ) = AST_OP_DEL_SELF) or (astGetOpSelfVer( op ) = AST_OP_DEL_VEC_SELF) )
430  sym = symbGetCompOpOvlHead( subtype, astGetOpSelfVer( op ) )
431  if( sym ) then
432  if( symbCheckAccess( sym ) = FALSE ) then
433  errReport( FB_ERRMSG_ILLEGALMEMBERACCESS )
434  end if
435  end if
436  else
437  sym = NULL
438  end if
439 
440  '' if not defined, call the global one
441  if( sym = NULL ) then
442  assert( (op = AST_OP_DEL) or (op = AST_OP_DEL_VEC) )
443  sym = symbGetCompOpOvlHead( NULL, op )
444  end if
445 
446  proc = astNewCALL( sym )
447 
448  '' byval ptr as any ptr
449  if( astNewARG( proc, ptr_expr ) = NULL ) then
450  exit function
451  end if
452 
453  function = proc
454 end function
455