Name | Executed | Routines | % | Executed | Lines | % | Unexecuted |
/home/matt/eu/rds/include/std/memory.e | 6 | 11 | 54.55% | 23 | 37 | 62.16% | 14 |
Routine | Executed | Lines | Unexecuted | |
register_block() | 0 | 4 | 0.00% | 4 |
dep_works() | 0 | 3 | 0.00% | 3 |
unregister_block() | 0 | 3 | 0.00% | 3 |
bordered_address() | 0 | 2 | 0.00% | 2 |
check_all_blocks() | 0 | 2 | 0.00% | 2 |
deallocate() | 4 | 4 | 100.00% | 0 |
free_code() | 4 | 4 | 100.00% | 0 |
machine_addr() | 2 | 2 | 100.00% | 0 |
positive_int() | 2 | 2 | 100.00% | 0 |
prepare_block() | 2 | 2 | 100.00% | 0 |
safe_address() | 2 | 2 | 100.00% | 0 |
# | Executed | |
1 | namespace memory | |
2 | ||
3 | --**** | |
4 | -- == Memory Management - Low-Level | |
5 | -- | |
6 | -- < | |
7 | -- | |
8 | -- === Usage Notes | |
9 | --@[safe.e] | |
10 | -- This file is not normally included directly. The normal approach is to | |
11 | -- ##include std/machine.e##, which will automatically include either this file | |
12 | -- or ##std/safe.e## if the SAFE symbol has been defined. | |
13 | -- | |
14 | -- Warning: Some of these routines require a knowledge of | |
15 | -- machine-level programming. You could crash your system! | |
16 | -- | |
17 | -- These routines, along with [[:peek]](), [[:poke]]() and [[:call]](), let you access all | |
18 | -- of the features of your computer. You can read and write to any memory | |
19 | -- location, and you can create and execute machine code subroutines. | |
20 | -- | |
21 | -- If you are manipulating 32-bit addresses or values, remember to use | |
22 | -- variables declared as atom. The integer type only goes up to 31 bits. | |
23 | -- | |
24 | -- Writing characters to screen memory with poke() is much faster than | |
25 | -- using puts(). Address of start of text screen memory: | |
26 | -- | |
27 | -- * mono: #B0000 | |
28 | -- * color: #B8000 | |
29 | -- | |
30 | -- If you choose to call machine_proc() or machine_func() directly (to save | |
31 | -- a bit of overhead) you *must* pass valid arguments or Euphoria could crash. | |
32 | -- | |
33 | -- Some example programs to look at: | |
34 | -- * ##demo/callmach.ex## ~-- calling a machine language routine | |
35 | -- | |
36 | -- See also ##include/safe.e##. It's a safe, debugging version of this | |
37 | -- file. | |
38 | -- | |
39 | ||
40 | public include std/memconst.e | |
41 | include std/error.e | |
42 | ||
43 | 93 | ifdef DATA_EXECUTE then |
44 | include std/machine.e | |
45 | end ifdef | |
46 | ||
47 | without warning &= (not_used) | |
48 | ||
49 | public integer edges_only | |
50 | ||
51 | -- biggest address on a 32-bit machine | |
52 | 93 | constant MAX_ADDR = power(2, 32)-1 |
53 | ||
54 | --** | |
55 | -- Positive integer type | |
56 | ||
57 | 484 | |
58 | 484 | return x >= 1 |
59 | end type | |
60 | ||
61 | --** | |
62 | -- Machine address type | |
63 | ||
64 | 960 | |
65 | -- a 32-bit non-null machine address | |
66 | 960 | return a > 0 and a <= MAX_ADDR and floor(a) = a |
67 | end type | |
68 | ||
69 | -- Internal use of the library only. free() calls this. It works with | |
70 | -- only atoms and in the SAFE implementation is different. | |
71 | 193 | |
72 | 193 | ifdef DATA_EXECUTE and WINDOWS then |
73 | if dep_works() then | |
74 | c_func( VirtualFree_rid, { addr, 1, MEM_RELEASE } ) | |
75 | return | |
76 | end if | |
77 | end ifdef | |
78 | 193 | machine_proc(M_FREE, addr) |
79 | 193 | end procedure |
80 | 93 | FREE_RID = routine_id("deallocate") |
81 | ||
82 | ||
83 | --**** | |
84 | -- === Reading from, Writing to, and Calling into Memory | |
85 | ||
86 | --**** | |
87 | -- Signature: | |
88 | -- | |
89 | -- | |
90 | -- Description: | |
91 | -- Fetches a byte, or some bytes, from an address in memory. | |
92 | -- | |
93 | -- Parameters: | |
94 | -- # ##addr_n_length## : an object, either of | |
95 | -- ** an atom ##addr## ~-- to fetch one byte at ##addr##, or | |
96 | -- ** a pair {##addr,len}## ~-- to fetch ##len## bytes at ##addr## | |
97 | -- | |
98 | -- Returns: | |
99 | -- An **object**, either an integer if the input was a single address, | |
100 | -- or a sequence of integers if a sequence was passed. In both cases, | |
101 | -- integers returned are bytes, in the range 0..255. | |
102 | -- | |
103 | -- Errors: | |
104 | -- | |
105 | -- [[:peek | Peeking]] in memory you don't own may be blocked by the OS, and cause a | |
106 | -- machine exception. If you use the define safe these routines will catch these problems with a EUPHORIA error. | |
107 | -- | |
108 | -- When supplying a {address, count} sequence, the count must not be negative. | |
109 | -- | |
110 | -- Comments: | |
111 | -- | |
112 | -- Since addresses are 32-bit numbers, they can be larger than the largest | |
113 | -- value of type integer (31-bits). Variables that hold an address should | |
114 | -- therefore be declared as atoms. | |
115 | -- | |
116 | -- It is faster to read several bytes at once using the second form of peek() | |
117 | -- than it is to read one byte at a time in a loop. The returned sequence has | |
118 | -- the length you asked for on input. | |
119 | -- | |
120 | -- Remember that ##peek##() takes just one argument, which in the second form | |
121 | -- is actually a 2-element sequence. | |
122 | -- | |
123 | -- Example 1: | |
124 | -- | |
125 | -- -- The following are equivalent: | |
126 | -- -- method 1 | |
127 | -- s = {peek(100), peek(101), peek(102), peek(103)} | |
128 | -- | |
129 | -- -- method 2 | |
130 | -- s = peek({100, 4}) | |
131 | -- | |
132 | -- | |
133 | -- See Also: | |
134 | -- [[:poke]], [[:peeks]], [[:peek4u]], [[:allocate]], [[:free]], | |
135 | -- [[:peek2u]] | |
136 | -- | |
137 | ||
138 | --**** | |
139 | -- Signature: | |
140 | -- | |
141 | -- | |
142 | -- Description: | |
143 | -- Fetches a byte, or some bytes, from an address in memory. | |
144 | -- | |
145 | -- Parameters: | |
146 | -- # ##addr_n_length## : an object, either of | |
147 | -- ** an atom ##addr## : to fetch one byte at ##addr##, or | |
148 | -- ** a pair {##addr,len}## : to fetch ##len## bytes at ##addr## | |
149 | -- | |
150 | -- Returns: | |
151 | -- | |
152 | -- An **object**, either an integer if the input was a single address, | |
153 | -- or a sequence of integers if a sequence was passed. In both cases, | |
154 | -- integers returned are bytes, in the range -128..127. | |
155 | -- | |
156 | -- Errors: | |
157 | -- | |
158 | -- [[:peek | Peeking]] in memory you don't own may be blocked by the OS, and cause | |
159 | -- a machine exception. If you use the define safe these routines will catch these problems with a EUPHORIA error. | |
160 | -- | |
161 | -- When supplying a {address, count} sequence, the count must not be negative. | |
162 | -- | |
163 | -- Comments: | |
164 | -- | |
165 | -- Since addresses are 32-bit numbers, they can be larger than the largest | |
166 | -- value of type integer (31-bits). Variables that hold an address should | |
167 | -- therefore be declared as atoms. | |
168 | -- | |
169 | -- It is faster to read several bytes at once using the second form of ##peek##() | |
170 | -- than it is to read one byte at a time in a loop. The returned sequence has | |
171 | -- the length you asked for on input. | |
172 | -- | |
173 | -- Remember that ##peeks##() takes just one argument, which in the second | |
174 | -- form is actually a 2-element sequence. | |
175 | -- | |
176 | -- Example 1: | |
177 | -- | |
178 | -- | |
179 | -- -- The following are equivalent: | |
180 | -- -- method 1 | |
181 | -- s = {peeks(100), peek(101), peek(102), peek(103)} | |
182 | -- | |
183 | -- -- method 2 | |
184 | -- s = peeks({100, 4}) | |
185 | -- | |
186 | -- | |
187 | -- See Also: | |
188 | -- | |
189 | -- [[:poke]], [[:peek4s]], [[:allocate]], [[:free]], | |
190 | -- [[:peek2s]], [[:peek]] | |
191 | -- | |
192 | ||
193 | --**** | |
194 | -- Signature: | |
195 | -- | |
196 | -- | |
197 | -- Description: | |
198 | -- Fetches a //signed// word, or some //signed// words , from an address | |
199 | -- in memory. | |
200 | -- | |
201 | -- Parameters: | |
202 | -- # ##addr_n_length## : an object, either of | |
203 | -- ** an atom ##addr## ~-- to fetch one word at ##addr##, or | |
204 | -- ** a pair ##{ addr, len}##, to fetch ##len## words at ##addr## | |
205 | -- | |
206 | -- Returns: | |
207 | -- An **object**, either an integer if the input was a single address, | |
208 | -- or a sequence of integers if a sequence was passed. In both cases, | |
209 | -- integers returned are double words, in the range -32768..32767. | |
210 | -- | |
211 | -- Errors: | |
212 | -- Peeking in memory you don't own may be blocked by the OS, and cause | |
213 | -- a machine exception. If you use the define safe these routines will catch these problems with a EUPHORIA error. | |
214 | -- | |
215 | -- When supplying a {address, count} sequence, the count must not be negative. | |
216 | -- | |
217 | -- Comments: | |
218 | -- Since addresses are 32-bit numbers, they can be larger than the largest | |
219 | -- value of type integer (31-bits). Variables that hold an address should | |
220 | -- therefore be declared as atoms. | |
221 | -- | |
222 | -- It is faster to read several words at once using the second form of peek() | |
223 | -- than it is to read one word at a time in a loop. The returned sequence has | |
224 | -- the length you asked for on input. | |
225 | -- | |
226 | -- Remember that ##peek2s##() takes just one argument, which in the second | |
227 | -- form is actually a 2-element sequence. | |
228 | -- | |
229 | -- The only difference between ##peek2s##() and ##peek2u##() is how words | |
230 | -- with the highest bit set are returned. ##peek2s##() assumes them to be | |
231 | -- negative, while ##peek2u##() just assumes them to be large and positive. | |
232 | -- | |
233 | -- Example 1: | |
234 | -- | |
235 | -- | |
236 | -- -- The following are equivalent: | |
237 | -- -- method 1 | |
238 | -- s = {peek2s(100), peek2s(102), peek2s(104), peek2s(106)} | |
239 | -- | |
240 | -- -- method 2 | |
241 | -- s = peek2s({100, 4}) | |
242 | -- | |
243 | -- | |
244 | -- See Also: | |
245 | -- | |
246 | -- [[:poke2]], [[:peeks]], [[:peek4s]], [[:allocate]], [[:free]] | |
247 | -- [[:peek2u]] | |
248 | -- | |
249 | ||
250 | --**** | |
251 | -- Signature: | |
252 | -- | |
253 | -- | |
254 | -- Description: | |
255 | -- Fetches an //unsigned// word, or some //unsigned// words, from an address | |
256 | -- in memory. | |
257 | -- | |
258 | -- Parameters: | |
259 | -- # ##addr_n_length## : an object, either of | |
260 | -- ** an atom ##addr## ~-- to fetch one double word at ##addr##, or | |
261 | -- ** a pair {##addr,len}## ~-- to fetch ##len## double words at ##addr## | |
262 | -- | |
263 | -- Returns: | |
264 | -- An **object**, either an integer if the input was a single address, | |
265 | -- or a sequence of integers if a sequence was passed. In both cases, | |
266 | -- integers returned are words, in the range 0..65535. | |
267 | -- | |
268 | -- Errors: | |
269 | -- Peek() in memory you don't own may be blocked by the OS, and cause a | |
270 | -- machine exception. If you use the define safe these routines will catch these problems with a EUPHORIA error. | |
271 | -- | |
272 | -- When supplying a {address, count} sequence, the count must not be negative. | |
273 | -- | |
274 | -- Comments: | |
275 | -- | |
276 | -- Since addresses are 32-bit numbers, they can be larger than the largest | |
277 | -- value of type integer (31-bits). Variables that hold an address should | |
278 | -- therefore be declared as atoms. | |
279 | -- | |
280 | -- It is faster to read several words at once using the second form of peek() | |
281 | -- than it is to read one word at a time in a loop. The returned sequence has | |
282 | -- the length you asked for on input. | |
283 | -- | |
284 | -- Remember that ##peek2u##() takes just one argument, which in the second | |
285 | -- form is actually a 2-element sequence. | |
286 | -- | |
287 | -- The only difference between ##peek2s##() and ##peek2u##() is how words | |
288 | -- with the highest bit set are returned. ##peek2s##() assumes them to be | |
289 | -- negative, while ##peek2u##() just assumes them to be large and positive. | |
290 | -- | |
291 | -- Example 1: | |
292 | -- | |
293 | -- -- The following are equivalent: | |
294 | -- -- method 1 | |
295 | -- Get 4 2-byte numbers starting address 100. | |
296 | -- s = {peek2u(100), peek2u(102), peek2u(104), peek2u(106)} | |
297 | -- | |
298 | -- -- method 2 | |
299 | -- Get 4 2-byte numbers starting address 100. | |
300 | -- s = peek2u({100, 4}) | |
301 | -- | |
302 | -- | |
303 | -- See Also: | |
304 | -- [[:poke2]], [[:peek]], [[:peek2s]], [[:allocate]], [[:free]] | |
305 | -- [[:peek4u]] | |
306 | -- | |
307 | ||
308 | --**** | |
309 | -- Signature: | |
310 | -- | |
311 | -- | |
312 | -- Description: | |
313 | -- Fetches a //signed// double words, or some //signed// double words, | |
314 | -- from an address in memory. | |
315 | -- | |
316 | -- Parameters: | |
317 | -- # ##addr_n_length## : an object, either of | |
318 | -- ** an atom ##addr## ~-- to fetch one double word at ##addr##, or | |
319 | -- ** a pair ##{ addr, len }## ~-- to fetch ##len## double words at ##addr## | |
320 | -- | |
321 | -- Returns: | |
322 | -- An **object**, either an atom if the input was a single address, or a | |
323 | -- sequence of atoms if a sequence was passed. In both cases, atoms returned | |
324 | -- are double words, in the range -power(2,31)..power(2,31)-1. | |
325 | -- | |
326 | -- Errors: | |
327 | -- Peeking in memory you don't own may be blocked by the OS, and cause a | |
328 | -- machine exception. If you use the define safe these routines will catch these problems with a EUPHORIA error. | |
329 | -- | |
330 | -- When supplying a {address, count} sequence, the count must not be negative. | |
331 | -- | |
332 | -- Comments: | |
333 | -- | |
334 | -- Since addresses are 32-bit numbers, they can be larger than the largest | |
335 | -- value of type integer (31-bits). Variables that hold an address should | |
336 | -- therefore be declared as atoms. | |
337 | -- | |
338 | -- It is faster to read several double words at once using the second form | |
339 | -- of ##peek##() than it is to read one double word at a time in a loop. The | |
340 | -- returned sequence has the length you asked for on input. | |
341 | -- | |
342 | -- Remember that ##peek4s##() takes just one argument, which in the second | |
343 | -- form is actually a 2-element sequence. | |
344 | -- | |
345 | -- The only difference between ##peek4s##() and [[:peek4u]]() is how double | |
346 | -- words with the highest bit set are returned. ##peek4s##() assumes them to | |
347 | -- be negative, while [[:peek4u]]() just assumes them to be large and positive. | |
348 | -- | |
349 | -- Example 1: | |
350 | -- | |
351 | -- -- The following are equivalent: | |
352 | -- -- method 1 | |
353 | -- s = {peek4s(100), peek4s(104), peek4s(108), peek4s(112)} | |
354 | -- | |
355 | -- -- method 2 | |
356 | -- s = peek4s({100, 4}) | |
357 | -- | |
358 | -- | |
359 | -- See Also: | |
360 | -- [[:poke4]], [[:peeks]], [[:peek4u]], [[:allocate]], [[:free]], | |
361 | -- [[:peek2s]] | |
362 | -- | |
363 | ||
364 | --**** | |
365 | -- Signature: | |
366 | -- | |
367 | -- | |
368 | -- Description: | |
369 | -- Fetches an //unsigned// double word, or some //unsigned// double words, | |
370 | -- from an address in memory. | |
371 | -- | |
372 | -- Parameters: | |
373 | -- # ##addr_n_length## : an object, either of | |
374 | -- ** an atom ##addr## ~-- to fetch one double word at ##addr##, or | |
375 | -- ** a pair {##addr,len}## ~-- to fetch ##len## double words at ##addr## | |
376 | -- | |
377 | -- Returns: | |
378 | -- An **object**, either an atom if the input was a single address, or | |
379 | -- a sequence of atoms if a sequence was passed. In both cases, atoms | |
380 | -- returned are double words, in the range 0..power(2,32)-1. | |
381 | -- | |
382 | -- Errors: | |
383 | -- Peek() in memory you don't own may be blocked by the OS, and cause | |
384 | -- a machine exception. If you use the define safe these routines will catch these problems with a EUPHORIA error. | |
385 | -- | |
386 | -- When supplying a {address, count} sequence, the count must not be negative. | |
387 | -- | |
388 | -- Comments: | |
389 | -- | |
390 | -- Since addresses are 32-bit numbers, they can be larger than the largest | |
391 | -- value of type integer (31-bits). Variables that hold an address should | |
392 | -- therefore be declared as atoms. | |
393 | -- | |
394 | -- It is faster to read several double words at once using the second form | |
395 | -- of ##peek##() than it is to read one double word at a time in a loop. The | |
396 | -- returned sequence has the length you asked for on input. | |
397 | -- | |
398 | -- Remember that ##peek4u##() takes just one argument, which in the second | |
399 | -- form is actually a 2-element sequence. | |
400 | -- | |
401 | -- The only difference between ##peek4s##() and ##peek4u##() is how double | |
402 | -- words with the highest bit set are returned. ##peek4s##() assumes them | |
403 | -- to be negative, while ##peek4u##() just assumes them to be large and | |
404 | -- positive. | |
405 | -- | |
406 | -- Example 1: | |
407 | -- | |
408 | -- -- The following are equivalent: | |
409 | -- -- method 1 | |
410 | -- s = {peek4u(100), peek4u(104), peek4u(108), peek4u(112)} | |
411 | -- | |
412 | -- -- method 2 | |
413 | -- s = peek4u({100, 4}) | |
414 | -- | |
415 | -- | |
416 | -- See Also: | |
417 | -- [[:poke4]], [[:peek]], [[:peek4s]], [[:allocate]], [[:free]], [[:peek2u]] | |
418 | -- | |
419 | ||
420 | --**** | |
421 | -- Signature: | |
422 | -- | |
423 | -- | |
424 | -- Description: | |
425 | -- Read an ASCII string in RAM, starting from a supplied address. | |
426 | -- | |
427 | -- Parameters: | |
428 | -- # ##addr## : an atom, the address at which to start reading. | |
429 | -- | |
430 | -- Returns: | |
431 | -- A **sequence**, of bytes, the string that could be read. | |
432 | -- | |
433 | -- Errors: | |
434 | -- Further, ##peek##() memory that doesn't belong to your process is something the operating | |
435 | -- system could prevent, and you'd crash with a machine level exception. | |
436 | -- | |
437 | -- Comments: | |
438 | -- | |
439 | -- An ASCII string is any sequence of bytes and ends with a 0 byte. | |
440 | -- If you ##peek_string##() at some place where there is no string, you will get a sequence of garbage. | |
441 | -- | |
442 | -- See Also: | |
443 | -- [[:peek]], [[:peek_wstring]], [[:allocate_string]] | |
444 | ||
445 | ||
446 | --**** | |
447 | -- Signature: | |
448 | -- | |
449 | -- | |
450 | -- Description: | |
451 | -- Stores one or more bytes, starting at a memory location. | |
452 | -- | |
453 | -- Parameters: | |
454 | -- # ##addr## : an atom, the address at which to store | |
455 | -- # ##x## : an object, either a byte or a non empty sequence of bytes. | |
456 | -- | |
457 | -- Errors: | |
458 | -- Poke() in memory you don't own may be blocked by the OS, and cause a | |
459 | -- machine exception. The -D SAFE option will make ##poke()## catch this sort of issues. | |
460 | -- | |
461 | -- Comments: | |
462 | -- | |
463 | -- The lower 8-bits of each byte value, i.e. remainder(x, 256), is actually | |
464 | -- stored in memory. | |
465 | -- | |
466 | -- It is faster to write several bytes at once by poking a sequence of values, | |
467 | -- than it is to write one byte at a time in a loop. | |
468 | -- | |
469 | -- Writing to the screen memory with ##poke##() can be much faster than using | |
470 | -- ##puts##() or ##printf##(), but the programming is more difficult. In most cases | |
471 | -- the speed is not needed. For example, the Euphoria editor, ##ed##, never uses | |
472 | -- ##poke##(). | |
473 | -- | |
474 | -- Example 1: | |
475 | -- | |
476 | -- a = allocate(100) -- allocate 100 bytes in memory | |
477 | -- | |
478 | -- -- poke one byte at a time: | |
479 | -- poke(a, 97) | |
480 | -- poke(a+1, 98) | |
481 | -- poke(a+2, 99) | |
482 | -- | |
483 | -- -- poke 3 bytes at once: | |
484 | -- poke(a, {97, 98, 99}) | |
485 | -- | |
486 | -- | |
487 | -- Example 2: | |
488 | -- ##demo/callmach.ex## | |
489 | -- | |
490 | -- See Also: | |
491 | -- [[:peek]], [[:peeks]], [[:poke4]], [[:allocate]], [[:free]], [[:poke2]], [[:call]], | |
492 | -- [[:mem_copy]], [[:mem_set]] | |
493 | -- | |
494 | ||
495 | --**** | |
496 | -- Signature: | |
497 | -- | |
498 | -- | |
499 | -- Description: | |
500 | -- Stores one or more words, starting at a memory location. | |
501 | -- | |
502 | -- Parameters: | |
503 | -- # ##addr## : an atom, the address at which to store | |
504 | -- # ##x## : an object, either a word or a non empty sequence of words. | |
505 | -- | |
506 | -- Errors: | |
507 | -- Poke() in memory you don't own may be blocked by the OS, and cause a | |
508 | -- machine exception. If you use the define safe these routines will catch these problems with a EUPHORIA error. | |
509 | -- | |
510 | -- Comments: | |
511 | -- | |
512 | -- There is no point in having ##poke2s##() or ##poke2u##(). For example, both 32768 | |
513 | -- and -32768 are stored as #F000 when stored as words. It's up to whoever | |
514 | -- reads the value to figure it out. | |
515 | -- | |
516 | -- It is faster to write several words at once by poking a sequence of | |
517 | -- values, than it is to write one words at a time in a loop. | |
518 | -- | |
519 | -- Writing to the screen memory with ##poke2##() can be much faster than using | |
520 | -- ##puts##() or ##printf##(), but the programming is more difficult. In most cases | |
521 | -- the speed is not needed. For example, the Euphoria editor, ed, never uses | |
522 | -- poke2(). | |
523 | -- | |
524 | -- The 2-byte values to be stored can be negative or positive. You can read | |
525 | -- them back with either ##peek2s##() or ##peek2u##(). Actually, only | |
526 | -- remainder(##x##,65536) is being stored. | |
527 | -- | |
528 | -- Example 1: | |
529 | -- | |
530 | -- a = allocate(100) -- allocate 100 bytes in memory | |
531 | -- | |
532 | -- -- poke one 2-byte value at a time: | |
533 | -- poke2(a, 12345) | |
534 | -- poke2(a+2, #FF00) | |
535 | -- poke2(a+4, -12345) | |
536 | -- | |
537 | -- -- poke 3 2-byte values at once: | |
538 | -- poke4(a, {12345, #FF00, -12345}) | |
539 | -- | |
540 | -- | |
541 | -- See Also: | |
542 | -- [[:peek2s]], [[:peek2u]], [[:poke]], [[:poke4]], [[:allocate]], [[:free]], [[:call]] | |
543 | -- | |
544 | ||
545 | --**** | |
546 | -- Signature: | |
547 | -- | |
548 | -- | |
549 | -- Description: | |
550 | -- Stores one or more double words, starting at a memory location. | |
551 | -- | |
552 | -- Parameters: | |
553 | -- # ##addr## : an atom, the address at which to store | |
554 | -- # ##x## : an object, either a double word or a non empty sequence of | |
555 | -- double words. | |
556 | -- | |
557 | -- Errors: | |
558 | -- Poke() in memory you don't own may be blocked by the OS, and cause a | |
559 | -- machine exception. If you use the define safe these routines will catch these problems with a EUPHORIA error. | |
560 | -- | |
561 | -- Comments: | |
562 | -- | |
563 | -- There is no point in having poke4s() or poke4u(). For example, both | |
564 | -- +power(2,31) and -power(2,31) are stored as #F0000000. It's up to whoever | |
565 | -- reads the value to figure it out. | |
566 | -- | |
567 | -- It is faster to write several double words at once by poking a sequence | |
568 | -- of values, than it is to write one double words at a time in a loop. | |
569 | -- | |
570 | -- Writing to the screen memory with poke4() can be much faster than using | |
571 | -- puts() or printf(), but the programming is more difficult. In most cases | |
572 | -- the speed is not needed. For example, the Euphoria editor, ed, never uses | |
573 | -- poke4(). | |
574 | -- | |
575 | -- The 4-byte values to be stored can be negative or positive. You can read | |
576 | -- them back with either ##peek4s##() or ##peek4u##(). However, the results | |
577 | -- are unpredictable if you want to store values with a fractional part or a | |
578 | -- magnitude greater than power(2,32), even though Euphoria represents them | |
579 | -- all as atoms. | |
580 | -- | |
581 | -- Example 1: | |
582 | -- | |
583 | -- a = allocate(100) -- allocate 100 bytes in memory | |
584 | -- | |
585 | -- -- poke one 4-byte value at a time: | |
586 | -- poke4(a, 9712345) | |
587 | -- poke4(a+4, #FF00FF00) | |
588 | -- poke4(a+8, -12345) | |
589 | -- | |
590 | -- -- poke 3 4-byte values at once: | |
591 | -- poke4(a, {9712345, #FF00FF00, -12345}) | |
592 | -- | |
593 | -- | |
594 | -- See Also: | |
595 | -- [[:peek4s]], [[:peek4u]], [[:poke]], [[:poke2]], [[:allocate]], [[:free]], [[:call]] | |
596 | -- | |
597 | ||
598 | --**** | |
599 | -- Signature: | |
600 | -- | |
601 | -- | |
602 | -- Description: | |
603 | -- Copy a block of memory from an address to another. | |
604 | -- | |
605 | -- Parameters: | |
606 | -- # ##destination## : an atom, the address at which data is to be copied | |
607 | -- # ##origin## : an atom, the address from which data is to be copied | |
608 | -- # ##len## : an integer, how many bytes are to be copied. | |
609 | -- | |
610 | -- Comments: | |
611 | -- | |
612 | -- The bytes of memory will be copied correctly even if the block of memory | |
613 | -- at ##destination## overlaps with the block of memory at ##origin##. | |
614 | -- | |
615 | -- mem_copy(destination, origin, len) is equivalent to: poke(destination, | |
616 | -- peek({origin, len})) but is much faster. | |
617 | -- | |
618 | -- Example 1: | |
619 | -- | |
620 | -- dest = allocate(50) | |
621 | -- src = allocate(100) | |
622 | -- poke(src, {1,2,3,4,5,6,7,8,9}) | |
623 | -- mem_copy(dest, src, 9) | |
624 | -- | |
625 | -- | |
626 | -- See Also: | |
627 | -- [[:mem_set]], [[:peek]], [[:poke]], [[:allocate]], [[:free]] | |
628 | -- | |
629 | ||
630 | --**** | |
631 | -- Signature: | |
632 | -- | |
633 | -- | |
634 | -- Description: | |
635 | -- Sets a contiguous range of memory locations to a single value. | |
636 | -- | |
637 | -- Parameters: | |
638 | -- # ##destination## : an atom, the address starting the range to set. | |
639 | -- # ##byte_value## : an integer, the value to copy at all addresses in the range. | |
640 | -- # ##how_many## : an integer, how many bytes are to be set. | |
641 | -- | |
642 | -- Comments: | |
643 | -- | |
644 | -- The low order 8 bits of ##byte_value## are actually stored in each byte. | |
645 | -- mem_set(destination, byte_value, how_many) is equivalent to: | |
646 | -- poke(destination, repeat(byte_value, how_many)) but is much faster. | |
647 | -- | |
648 | -- Example 1: | |
649 | -- | |
650 | -- destination = allocate(1000) | |
651 | -- mem_set(destination, ' ', 1000) | |
652 | -- -- 1000 consecutive bytes in memory will be set to 32 | |
653 | -- -- (the ASCII code for ' ') | |
654 | -- | |
655 | -- | |
656 | -- See Also: | |
657 | -- [[:peek]], [[:poke]], [[:allocate]], [[:free]], [[:mem_copy]] | |
658 | -- | |
659 | ||
660 | --**** | |
661 | -- Signature: | |
662 | -- | |
663 | -- | |
664 | -- Description: | |
665 | -- Call a machine language routine which was stored in memory prior. | |
666 | -- | |
667 | -- Parameters: | |
668 | -- # ##addr## : an atom, the address at which to transfer execution control. | |
669 | -- | |
670 | -- Comments: | |
671 | -- | |
672 | -- The machine code routine must execute a RET instruction #C3 to return | |
673 | -- control to Euphoria. | |
674 | -- The routine should save and restore any registers that it uses. | |
675 | -- | |
676 | -- You can allocate a block of memory for the routine and then poke in the | |
677 | -- bytes of machine code using ##allocate_code##(). You might allocate other blocks of memory for data | |
678 | -- and parameters that the machine code can operate on using ##allocate##(). The addresses of these | |
679 | -- blocks could be part of the machine code. | |
680 | -- | |
681 | -- If your machine code uses the stack, use ##c_proc##() instead of ##call##(). | |
682 | -- | |
683 | -- Example 1: | |
684 | -- ##demo/callmach.ex## | |
685 | -- | |
686 | -- See Also: | |
687 | -- [[:allocate_code]], [[:free_code]], [[:c_proc]], [[:define_c_proc]] | |
688 | ||
689 | without warning | |
690 | 93 | public integer check_calls = 1 |
691 | ||
692 | --**** | |
693 | -- === Safe memory access | |
694 | ||
695 | --** | |
696 | -- Description: Add a block of memory to the list of safe blocks maintained | |
697 | -- by safe.e (the debug version of memory.e). The block starts at address a. | |
698 | -- The length of the block is i bytes. | |
699 | -- | |
700 | -- Parameters: | |
701 | -- # ##block_addr## : an atom, the start address of the block | |
702 | -- # ##block_len## : an integer, the size of the block. | |
703 | -- # ##protection## : a constant integer, of the memory | |
704 | -- protection constants found in machine.e, that describes | |
705 | -- what access we have to the memory. | |
706 | -- | |
707 | -- Comments: | |
708 | -- | |
709 | -- In memory.e, this procedure does nothing. It is there to simplify | |
710 | -- switching between the normal and debug version of the library. | |
711 | -- | |
712 | -- This routine is only meant to be used for debugging purposes. safe.e | |
713 | -- tracks the blocks of memory that your program is allowed to | |
714 | -- [[:peek]](), [[:poke]](), [[:mem_copy]]() etc. These are normally just the | |
715 | -- blocks that you have allocated using Euphoria's [[:allocate]]() | |
716 | -- routine, and which you have not yet freed using | |
717 | -- Euphoria's [[:free]](). In some cases, you may acquire | |
718 | -- additional, external, blocks of memory, perhaps as a result of calling a | |
719 | -- C routine. | |
720 | -- | |
721 | -- If you are debugging your program using safe.e, you must register these | |
722 | -- external blocks of memory or safe.e will prevent you from accessing them. | |
723 | -- When you are finished using an external block you can unregister it using | |
724 | -- unregister_block(). | |
725 | -- | |
726 | -- Example 1: | |
727 | -- | |
728 | -- atom addr | |
729 | -- | |
730 | -- addr = c_func(x, {}) | |
731 | -- register_block(addr, 5) | |
732 | -- poke(addr, "ABCDE") | |
733 | -- unregister_block(addr) | |
734 | -- | |
735 | -- | |
736 | -- See Also: | |
737 | -- [[:unregister_block]], [[:safe.e]] | |
738 | ||
739 | 0 | |
740 | -- NOP to avoid strict lint | |
741 | 0 | block_addr = block_addr |
742 | 0 | block_len = block_len |
743 | 0 | end procedure |
744 | ||
745 | ||
746 | --** | |
747 | -- Remove a block of memory from the list of safe blocks maintained by safe.e | |
748 | -- (the debug version of memory.e). | |
749 | -- | |
750 | -- Parameters: | |
751 | -- # ##block_addr## : an atom, the start address of the block | |
752 | -- | |
753 | -- Comments: | |
754 | -- | |
755 | -- In memory.e, this procedure does nothing. It is there to simplify | |
756 | -- switching between the normal and debug version of the library. | |
757 | -- | |
758 | -- This routine is only meant to be used for debugging purposes. Use it to | |
759 | -- unregister blocks of memory that you have previously registered using | |
760 | -- [[:register_block]](). By unregistering a block, you remove it from the | |
761 | -- list of safe blocks maintained by safe.e. This prevents your program from | |
762 | -- performing any further reads or writes of memory within the block. | |
763 | -- | |
764 | -- See [[:register_block]]() for further comments and an example. | |
765 | -- | |
766 | -- See Also: | |
767 | -- [[:register_block]], [[:safe.e]] | |
768 | ||
769 | 0 | |
770 | -- NOP to avoid strict lint | |
771 | 0 | block_addr = block_addr |
772 | 0 | end procedure |
773 | ||
774 | --** | |
775 | -- Scans the list of registered blocks for any corruption. | |
776 | -- | |
777 | -- Comments: | |
778 | -- | |
779 | -- safe.e maintains a list of acquired memory blocks. Those gained through | |
780 | -- allocate() are automatically included. Any other block, | |
781 | -- for debugging purposes, must be registered by [[:register_block]]() | |
782 | -- and unregistered by [[:unregister_block]](). | |
783 | -- | |
784 | -- The list is scanned and, if any block shows signs of corruption, it is | |
785 | -- displayed on the screen and the program terminates. Otherwise, nothing | |
786 | -- happens. | |
787 | -- | |
788 | -- In memory.e, this routine does nothing. It is there to make switching | |
789 | -- between debugged and normal version of your program easier. | |
790 | -- | |
791 | -- See Also: | |
792 | -- [[:register_block]], [[:unregister_block]] | |
793 | ||
794 | 4 | |
795 | 4 | return 1 |
796 | end function | |
797 | ||
798 | 0 | |
799 | 0 | end procedure |
800 | ||
801 | 490 | |
802 | 490 | return addr |
803 | end function | |
804 | ||
805 | 93 | export constant BORDER_SPACE = 0 |
806 | 93 | export constant leader = repeat('@', BORDER_SPACE) |
807 | 93 | export constant trailer = repeat('%', BORDER_SPACE) |
808 | ||
809 | 0 | |
810 | 0 | return 1 |
811 | end type | |
812 | ||
813 | ||
814 | with warning | |
815 | ||
816 | --**** | |
817 | --=== Automatic Resource Management | |
818 | -- | |
819 | -- Euphoria objects are automatically garbage collected when they are no | |
820 | -- longer referenced anywhere. Euphoria also provides the ability to manage | |
821 | -- resources associated with euphoria objects. These resources could be open file | |
822 | -- handles, allocated memory, or other euphoria objects. There are two built-in | |
823 | -- routines for managing these external resources. | |
824 | ||
825 | --**** | |
826 | -- Signature: | |
827 | -- | |
828 | -- | |
829 | -- Description: | |
830 | -- Associates a routine for cleaning up after a euphoria object. | |
831 | -- | |
832 | -- Comments: | |
833 | -- delete_routine() associates a euphoria object with a routine id meant | |
834 | -- to clean up any allocated resources. It always returns an atom | |
835 | -- (double) or a sequence, depending on what was passed (integers are | |
836 | -- promoted to atoms). | |
837 | -- | |
838 | -- The routine specified by delete_routine() should be a procedure that | |
839 | -- takes a single parameter, being the object to be cleaned up after. | |
840 | -- Objects are cleaned up under one of two circumstances. The first is | |
841 | -- if it's called as a parameter to delete(). After the call, the | |
842 | -- association with the delete routine is removed. | |
843 | -- | |
844 | -- The second way for the delete routine to be called is when its | |
845 | -- reference count is reduced to 0. Before its memory is freed, the | |
846 | -- delete routine is called. A default delete will be used if the cleanup | |
847 | -- parameter to one of the [[:allocate]] routines is true. | |
848 | -- | |
849 | -- delete_routine() may be called multiple times for the same object. | |
850 | -- In this case, the routines are called in reverse order compared to | |
851 | -- how they were associated. | |
852 | ||
853 | --**** | |
854 | -- Signature: | |
855 | -- | |
856 | -- | |
857 | -- Description: | |
858 | -- Calls the cleanup routines associated with the object, and removes the | |
859 | -- association with those routines. | |
860 | -- | |
861 | -- Comments: | |
862 | -- The cleanup routines associated with the object are called in reverse | |
863 | -- order than they were added. If the object is an integer, or if no | |
864 | -- cleanup routines are associated with the object, then nothing happens. | |
865 | -- | |
866 | -- After the cleanup routines are called, the value of the object is | |
867 | -- unchanged, though the cleanup routine will no longer be associated | |
868 | -- with the object. | |
869 | ||
870 | --** | |
871 | -- Returns 1 if the DEP executing data only memory would cause an exception | |
872 | 0 | |
873 | 0 | ifdef WIN32 then |
874 | return (DEP_really_works and use_DEP) | |
875 | end ifdef | |
876 | ||
877 | 0 | return 0 |
878 | end function | |
879 | ||
880 | export atom VirtualFree_rid | |
881 | ||
882 | 2 | |
883 | 2 | ifdef WIN32 then |
884 | if dep_works() then | |
885 | c_func(VirtualFree_rid, { addr, size*wordsize, MEM_RELEASE }) | |
886 | else | |
887 | machine_proc(M_FREE,addr) | |
888 | end if | |
889 | elsedef | |
890 | 2 | machine_proc(M_FREE,addr) |
891 | end ifdef | |
892 | 2 | end procedure |