2019-06-27 06:29:09 +00:00
|
|
|
// TODO: consider if System can replace Apex itself.
|
|
|
|
// System, being the top class, seems to give very natural way of
|
|
|
|
// offering global system-level functions and interfaces.
|
|
|
|
//
|
|
|
|
// class System(nil) { ... }
|
|
|
|
// class Object(System) { .... }
|
|
|
|
// System at: #
|
|
|
|
// System logNl: 'xxxxx'.
|
|
|
|
// System getUint8(ptr,offset)
|
2017-03-23 16:14:22 +00:00
|
|
|
|
|
|
|
class System(Apex)
|
|
|
|
{
|
2017-10-31 07:13:22 +00:00
|
|
|
var(#class) asyncsg.
|
2019-08-26 14:43:41 +00:00
|
|
|
var(#class) gcfin_sem.
|
|
|
|
var(#class) gcfin_should_exit := false.
|
2019-09-14 02:21:59 +00:00
|
|
|
var(#class) shr.
|
2017-10-31 07:13:22 +00:00
|
|
|
|
2018-10-08 06:51:31 +00:00
|
|
|
pooldic Log
|
|
|
|
{
|
2019-06-27 06:29:09 +00:00
|
|
|
// -----------------------------------------------------------
|
|
|
|
// defines log levels
|
|
|
|
// these items must follow defintions in moo.h
|
|
|
|
// -----------------------------------------------------------
|
2018-10-08 06:51:31 +00:00
|
|
|
|
|
|
|
DEBUG := 1.
|
|
|
|
INFO := 2.
|
|
|
|
WARN := 4.
|
|
|
|
ERROR := 8.
|
|
|
|
FATAL := 16.
|
|
|
|
}
|
|
|
|
|
2019-09-14 02:21:59 +00:00
|
|
|
method(#class) _initialize
|
|
|
|
{
|
|
|
|
self.shr := Dictionary new.
|
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) _cleanup
|
|
|
|
{
|
|
|
|
self.shr := nil.
|
|
|
|
}
|
|
|
|
|
2017-10-31 07:13:22 +00:00
|
|
|
method(#class) addAsyncSemaphore: sem
|
|
|
|
{
|
|
|
|
^self.asyncsg addSemaphore: sem
|
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) removeAsyncSemaphore: sem
|
|
|
|
{
|
|
|
|
^self.asyncsg removeSemaphore: sem
|
|
|
|
}
|
2017-12-17 15:38:38 +00:00
|
|
|
|
2017-10-31 07:13:22 +00:00
|
|
|
method(#class) handleAsyncEvent
|
|
|
|
{
|
|
|
|
^self.asyncsg wait.
|
|
|
|
}
|
|
|
|
|
2017-07-20 16:33:53 +00:00
|
|
|
method(#class) startup(class_name, method_name)
|
|
|
|
{
|
2019-09-09 07:43:14 +00:00
|
|
|
| class ret gcfin_proc ossig_proc |
|
2017-07-20 16:33:53 +00:00
|
|
|
|
2017-10-31 07:13:22 +00:00
|
|
|
self.asyncsg := SemaphoreGroup new.
|
|
|
|
|
2019-06-27 06:29:09 +00:00
|
|
|
class := self at: class_name. // System at: class_name.
|
2017-07-20 16:33:53 +00:00
|
|
|
if (class isError)
|
|
|
|
{
|
2018-06-19 16:11:20 +00:00
|
|
|
self error: ('Cannot find the class - ' & class_name).
|
2017-07-20 16:33:53 +00:00
|
|
|
}.
|
|
|
|
|
2019-09-14 02:21:59 +00:00
|
|
|
self _initialize.
|
|
|
|
|
2019-09-09 07:43:14 +00:00
|
|
|
// start the gc finalizer process and os signal handler process
|
|
|
|
//[ self __gc_finalizer ] fork.
|
2019-08-16 15:29:36 +00:00
|
|
|
//[ self __os_sig_handler ] fork.
|
2019-09-09 07:43:14 +00:00
|
|
|
gcfin_proc := [ self __gc_finalizer ] newProcess.
|
|
|
|
ossig_proc := [ :caller | self __os_sig_handler: caller ] newProcess(thisProcess).
|
|
|
|
|
|
|
|
gcfin_proc resume.
|
|
|
|
ossig_proc resume.
|
2017-07-20 16:33:53 +00:00
|
|
|
|
2019-08-16 16:19:21 +00:00
|
|
|
[
|
|
|
|
// TODO: change the method signature to variadic and pass extra arguments to perform???
|
|
|
|
ret := class perform: method_name.
|
|
|
|
]
|
|
|
|
ensure: [
|
|
|
|
self _setSig: 16rFF.
|
|
|
|
].
|
2017-07-20 16:33:53 +00:00
|
|
|
|
|
|
|
^ret.
|
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) __gc_finalizer
|
|
|
|
{
|
2019-08-26 14:43:41 +00:00
|
|
|
| tmp gc |
|
2017-07-20 16:33:53 +00:00
|
|
|
|
2017-07-21 16:54:43 +00:00
|
|
|
gc := false.
|
2018-05-18 08:10:16 +00:00
|
|
|
|
2019-08-26 14:43:41 +00:00
|
|
|
self.gcfin_should_exit := false.
|
|
|
|
self.gcfin_sem := Semaphore new.
|
|
|
|
self.gcfin_sem signalOnGCFin. // tell VM to signal this semaphore when it schedules gc finalization.
|
2017-07-27 08:32:16 +00:00
|
|
|
|
2017-07-25 15:26:04 +00:00
|
|
|
[
|
|
|
|
while (true)
|
2017-07-20 16:33:53 +00:00
|
|
|
{
|
2017-07-25 15:26:04 +00:00
|
|
|
while ((tmp := self _popCollectable) notError)
|
|
|
|
{
|
2019-08-14 16:24:39 +00:00
|
|
|
if (tmp respondsTo: #finalize)
|
|
|
|
{
|
|
|
|
// finalize is protected with an exception handler.
|
|
|
|
// the exception is ignored except it's logged.
|
|
|
|
[ tmp finalize ] on: Exception do: [:ex | System longNl: "Exception in finalize - " & ex messageText ]
|
|
|
|
}.
|
2017-07-25 15:26:04 +00:00
|
|
|
}.
|
2017-07-20 16:33:53 +00:00
|
|
|
|
2019-06-27 06:29:09 +00:00
|
|
|
//if (Processor total_count == 1)
|
2019-08-26 14:43:41 +00:00
|
|
|
//if (Processor gcfin_should_exit)
|
|
|
|
if (self.gcfin_should_exit)
|
2017-07-25 15:26:04 +00:00
|
|
|
{
|
2019-06-27 06:29:09 +00:00
|
|
|
// exit from this loop when there are no other processes running except this finalizer process
|
2017-07-25 15:26:04 +00:00
|
|
|
if (gc)
|
|
|
|
{
|
2019-08-14 16:24:39 +00:00
|
|
|
System logNl: "Exiting the GC finalization process " & (thisProcess id) asString.
|
2017-12-09 16:04:17 +00:00
|
|
|
break.
|
2017-07-25 15:26:04 +00:00
|
|
|
}.
|
|
|
|
|
2019-08-14 16:24:39 +00:00
|
|
|
System logNl: "Forcing garbage collection before termination in " & (thisProcess id) asString.
|
2017-07-25 15:26:04 +00:00
|
|
|
self collectGarbage.
|
|
|
|
gc := true.
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gc := false.
|
2017-07-24 13:25:25 +00:00
|
|
|
}.
|
2017-07-21 16:54:43 +00:00
|
|
|
|
2019-08-26 14:43:41 +00:00
|
|
|
self.gcfin_sem wait.
|
2017-07-24 13:25:25 +00:00
|
|
|
}
|
2017-07-25 15:26:04 +00:00
|
|
|
] ensure: [
|
2019-08-31 03:08:59 +00:00
|
|
|
self.gcfin_sem signal. // in case the process is stuck in wait.
|
2019-08-26 14:43:41 +00:00
|
|
|
self.gcfin_sem unsignal.
|
2017-07-27 17:29:45 +00:00
|
|
|
System logNl: 'End of GC finalization process ' & (thisProcess id) asString.
|
2017-07-25 15:26:04 +00:00
|
|
|
].
|
2017-07-20 16:33:53 +00:00
|
|
|
}
|
|
|
|
|
2019-08-16 15:29:36 +00:00
|
|
|
method(#class) __os_sig_handler: caller
|
2019-08-12 15:54:09 +00:00
|
|
|
{
|
2019-09-10 15:20:21 +00:00
|
|
|
| os_intr_sem tmp sh |
|
2019-08-12 15:54:09 +00:00
|
|
|
|
2019-08-14 16:24:39 +00:00
|
|
|
os_intr_sem := Semaphore new.
|
2019-08-15 15:55:06 +00:00
|
|
|
os_intr_sem signalOnInput: System _getSigfd.
|
2019-08-12 15:54:09 +00:00
|
|
|
|
|
|
|
[
|
|
|
|
while (true)
|
|
|
|
{
|
2019-08-15 15:55:06 +00:00
|
|
|
while ((tmp := self _getSig) notError)
|
2019-08-14 16:24:39 +00:00
|
|
|
{
|
|
|
|
// TODO: Do i have to protected this in an exception handler???
|
|
|
|
//TODO: Execute Handler for tmp.
|
2019-08-15 15:55:06 +00:00
|
|
|
|
2019-08-14 16:24:39 +00:00
|
|
|
System logNl: 'Interrupt dectected - signal no - ' & tmp asString.
|
2019-08-12 15:54:09 +00:00
|
|
|
|
2019-09-10 15:20:21 +00:00
|
|
|
// user-defined signal handler is not allowed for 16rFF
|
|
|
|
if (tmp == 16rFF) { goto done }.
|
|
|
|
|
|
|
|
/*
|
|
|
|
sh := self.sighandler at: tmp.
|
|
|
|
if (sh isNil)
|
|
|
|
{*/
|
|
|
|
// the default action for sigint(2) is to terminate all processes.
|
|
|
|
if (tmp == 2) { goto done }.
|
|
|
|
/*}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// invoke a user-defined signal handler if available.
|
|
|
|
sh value: tmp.
|
|
|
|
}*/
|
|
|
|
}.
|
2019-08-14 16:24:39 +00:00
|
|
|
os_intr_sem wait.
|
2019-08-16 15:29:36 +00:00
|
|
|
}.
|
|
|
|
done:
|
|
|
|
nil.
|
2019-08-12 15:54:09 +00:00
|
|
|
]
|
|
|
|
ensure: [
|
2019-08-18 17:46:40 +00:00
|
|
|
| pid proc |
|
2019-09-10 15:20:21 +00:00
|
|
|
|
|
|
|
// stop subscribing to signals.
|
2019-08-31 03:08:59 +00:00
|
|
|
os_intr_sem signal.
|
2019-08-14 16:24:39 +00:00
|
|
|
os_intr_sem unsignal.
|
2019-08-16 15:29:36 +00:00
|
|
|
|
|
|
|
// the caller must request to terminate all its child processes..
|
2019-08-18 17:46:40 +00:00
|
|
|
|
2019-09-09 07:43:14 +00:00
|
|
|
// this disables autonomous process switching only.
|
|
|
|
// TODO: check if the ensure block code can trigger process switching?
|
|
|
|
// whap happens if the ensure block creates new processes? this is likely to affect the termination loop below.
|
|
|
|
// even the id of the terminated process may get reused....
|
|
|
|
self _disableProcessSwitching.
|
|
|
|
|
|
|
|
/*
|
|
|
|
0 -> startup <--- this should also be stored in the 'caller' variable.
|
|
|
|
1 -> __gc_finalizer
|
|
|
|
2 -> __os_signal_handler
|
|
|
|
3 .. -> other processes started by application.
|
|
|
|
*/
|
|
|
|
proc := System _findProcessByIdGreaterThan: 2.
|
|
|
|
while (proc notError)
|
2019-08-18 17:46:40 +00:00
|
|
|
{
|
2019-09-09 07:43:14 +00:00
|
|
|
pid := proc id.
|
|
|
|
System logNl: ("Requesting to terminate process of id - " & pid asString).
|
|
|
|
proc terminate.
|
|
|
|
proc := System _findProcessByIdGreaterThan: pid.
|
2019-08-18 17:46:40 +00:00
|
|
|
}.
|
|
|
|
|
2019-09-10 15:20:21 +00:00
|
|
|
System logNl: 'Requesting to terminate the caller process of id ' & (caller id) asString.
|
2019-09-08 15:25:21 +00:00
|
|
|
caller terminate. // terminate the startup process.
|
2019-09-09 07:43:14 +00:00
|
|
|
self _enableProcessSwitching.
|
2019-08-16 15:29:36 +00:00
|
|
|
|
|
|
|
System logNl: '>>>>End of OS signal handler process ' & (thisProcess id) asString.
|
2019-08-26 14:43:41 +00:00
|
|
|
|
|
|
|
self.gcfin_should_exit := true.
|
|
|
|
self.gcfin_sem signal. // wake the gcfin process.
|
2019-09-02 16:23:03 +00:00
|
|
|
|
2019-09-09 07:43:14 +00:00
|
|
|
self _halting. // inform VM that it should get ready for halting.
|
2019-09-14 02:21:59 +00:00
|
|
|
self _cleanup.
|
2019-08-12 15:54:09 +00:00
|
|
|
].
|
|
|
|
}
|
|
|
|
|
2019-08-15 15:55:06 +00:00
|
|
|
method(#class,#primitive) _getSig.
|
|
|
|
method(#class,#primitive) _getSigfd.
|
2019-08-16 15:29:36 +00:00
|
|
|
method(#class,#primitive) _setSig: signo.
|
2019-09-02 16:23:03 +00:00
|
|
|
method(#class,#primitive) _halting.
|
2019-09-09 07:43:14 +00:00
|
|
|
method(#class,#primitive) _enableProcessSwitching.
|
|
|
|
method(#class,#primitive) _disableProcessSwitching.
|
|
|
|
method(#class,#primitive,#lenient) _findProcessById: id.
|
|
|
|
method(#class,#primitive,#lenient) _findProcessByIdGreaterThan: id.
|
2019-08-16 15:29:36 +00:00
|
|
|
|
2017-07-20 16:33:53 +00:00
|
|
|
method(#class,#primitive) _popCollectable.
|
2017-07-21 16:54:43 +00:00
|
|
|
method(#class,#primitive) collectGarbage.
|
2017-12-28 16:12:10 +00:00
|
|
|
method(#class,#primitive) gc.
|
2017-11-21 09:15:22 +00:00
|
|
|
method(#class,#primitive) return: object to: context.
|
2017-11-05 16:47:13 +00:00
|
|
|
|
2019-06-27 06:29:09 +00:00
|
|
|
// =======================================================================================
|
2019-09-14 02:21:59 +00:00
|
|
|
method(#class) registerSignalHandler: block
|
|
|
|
{
|
|
|
|
self.shr add: block.
|
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) removeSignalHandler: block
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-11-05 16:47:13 +00:00
|
|
|
method(#class) sleepForSecs: secs
|
|
|
|
{
|
2019-06-27 06:29:09 +00:00
|
|
|
// -----------------------------------------------------
|
|
|
|
// put the calling process to sleep for given seconds.
|
|
|
|
// -----------------------------------------------------
|
2017-11-05 16:47:13 +00:00
|
|
|
| s |
|
|
|
|
s := Semaphore new.
|
2018-06-19 16:58:04 +00:00
|
|
|
s signalAfterSecs: secs.
|
2017-11-05 16:47:13 +00:00
|
|
|
s wait.
|
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) sleepForSecs: secs nanosecs: nanosecs
|
|
|
|
{
|
2019-06-27 06:29:09 +00:00
|
|
|
// -----------------------------------------------------
|
|
|
|
// put the calling process to sleep for given seconds.
|
|
|
|
// -----------------------------------------------------
|
2017-11-05 16:47:13 +00:00
|
|
|
| s |
|
|
|
|
s := Semaphore new.
|
2018-06-19 16:58:04 +00:00
|
|
|
s signalAfterSecs: secs nanosecs: nanosecs.
|
2017-11-05 16:47:13 +00:00
|
|
|
s wait.
|
|
|
|
}
|
2017-03-23 16:14:22 +00:00
|
|
|
|
2019-06-27 06:29:09 +00:00
|
|
|
// the following methods may not look suitable to be placed
|
|
|
|
// inside a system dictionary. but they are here for quick and dirty
|
|
|
|
// output production from the moo code.
|
|
|
|
// System logNl: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'.
|
|
|
|
//
|
2017-05-21 16:57:21 +00:00
|
|
|
method(#class,#variadic,#primitive) log(level,msg1).
|
2017-10-31 07:13:22 +00:00
|
|
|
|
2019-06-19 12:38:09 +00:00
|
|
|
/*
|
2017-05-21 16:57:21 +00:00
|
|
|
TODO: how to pass all variadic arguments to another variadic methods???
|
|
|
|
method(#class,#variadic) logInfo (msg1)
|
|
|
|
{
|
|
|
|
^self log (System.Log.INFO,msg1)
|
|
|
|
}
|
2019-06-19 12:38:09 +00:00
|
|
|
*/
|
2017-03-23 16:14:22 +00:00
|
|
|
method(#class) atLevel: level log: message
|
|
|
|
{
|
2017-05-21 16:57:21 +00:00
|
|
|
<primitive: #System_log>
|
2019-06-27 06:29:09 +00:00
|
|
|
// do nothing upon logging failure
|
2017-03-23 16:14:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) atLevel: level log: message and: message2
|
|
|
|
{
|
2017-05-21 16:57:21 +00:00
|
|
|
<primitive: #System_log>
|
2019-06-27 06:29:09 +00:00
|
|
|
// do nothing upon logging failure
|
2017-03-23 16:14:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) atLevel: level log: message and: message2 and: message3
|
|
|
|
{
|
2017-05-21 16:57:21 +00:00
|
|
|
<primitive: #System_log>
|
2019-06-27 06:29:09 +00:00
|
|
|
// do nothing upon logging failure
|
2017-03-23 16:14:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) atLevel: level logNl: message
|
|
|
|
{
|
2019-06-27 06:29:09 +00:00
|
|
|
// the #_log primitive accepts an array.
|
|
|
|
// so the following lines should work also.
|
|
|
|
// | x |
|
|
|
|
// x := Array new: 2.
|
|
|
|
// x at: 0 put: message.
|
2019-06-27 08:06:33 +00:00
|
|
|
// x at: 1 put: "\n".
|
2019-06-27 06:29:09 +00:00
|
|
|
// ^self atLevel: level log: x.
|
2017-03-23 16:14:22 +00:00
|
|
|
|
2019-06-27 08:06:33 +00:00
|
|
|
^self atLevel: level log: message and: "\n".
|
2017-03-23 16:14:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) atLevel: level logNl: message and: message2
|
|
|
|
{
|
2019-06-27 08:06:33 +00:00
|
|
|
^self atLevel: level log: message and: message2 and: "\n".
|
2017-03-23 16:14:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) log: message
|
|
|
|
{
|
|
|
|
^self atLevel: System.Log.INFO log: message.
|
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) log: message and: message2
|
|
|
|
{
|
|
|
|
^self atLevel: System.Log.INFO log: message and: message2.
|
|
|
|
}
|
|
|
|
|
2018-01-14 15:11:53 +00:00
|
|
|
method(#class) logNl
|
|
|
|
{
|
2019-06-27 08:06:33 +00:00
|
|
|
^self atLevel: System.Log.INFO log: "\n".
|
2018-01-14 15:11:53 +00:00
|
|
|
}
|
|
|
|
|
2017-03-23 16:14:22 +00:00
|
|
|
method(#class) logNl: message
|
|
|
|
{
|
|
|
|
^self atLevel: System.Log.INFO logNl: message.
|
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) logNl: message and: message2
|
|
|
|
{
|
|
|
|
^self atLevel: System.Log.INFO logNl: message and: message2.
|
|
|
|
}
|
2017-05-21 16:57:21 +00:00
|
|
|
|
2019-07-12 07:24:37 +00:00
|
|
|
method(#class) backtrace
|
|
|
|
{
|
|
|
|
| ctx |
|
|
|
|
// TOOD: IMPROVE THIS EXPERIMENTAL BACKTRACE... MOVE THIS TO System>>backtrace and skip the first method context for backtrace itself.
|
2019-07-12 08:05:44 +00:00
|
|
|
// TODO: make this method atomic? no other process should get scheduled while this function is running?
|
|
|
|
// possible imementation methods:
|
|
|
|
// 1. disable task switching? ->
|
|
|
|
// 2. use a global lock.
|
|
|
|
// 3. make this a primitive function. -> natually no callback.
|
|
|
|
// 4. introduce a new method attribute. e.g. #atomic -> vm disables task switching or uses a lock to achieve atomicity.
|
|
|
|
// >>>> i think it should not be atomic as a while. only logging output should be produeced at one go.
|
|
|
|
|
2019-07-12 07:24:37 +00:00
|
|
|
System logNl: "== BACKTRACE ==".
|
|
|
|
|
|
|
|
//ctx := thisContext.
|
|
|
|
ctx := thisContext sender. // skip the current context. skip to the caller context.
|
|
|
|
while (ctx notNil)
|
|
|
|
{
|
2019-07-12 08:05:44 +00:00
|
|
|
// if (ctx sender isNil) { break }. // to skip the fake top level call context...
|
|
|
|
|
2019-07-12 07:24:37 +00:00
|
|
|
if (ctx class == MethodContext)
|
|
|
|
{
|
2019-07-12 08:05:44 +00:00
|
|
|
System log: " ";
|
|
|
|
log: ctx method owner name;
|
|
|
|
log: ">>";
|
|
|
|
log: ctx method name;
|
|
|
|
log: " (";
|
|
|
|
log: ctx method sourceFile;
|
|
|
|
log: " ";
|
|
|
|
log: (ctx method ipSourceLine: (ctx pc)) asString;
|
|
|
|
logNl: ")".
|
|
|
|
//System logNl: (" " & ctx method owner name & ">>" & ctx method name &
|
|
|
|
// " (" & ctx method sourceFile & " " & (ctx method ipSourceLine: (ctx pc)) asString & ")").
|
2019-07-12 07:24:37 +00:00
|
|
|
}.
|
|
|
|
// TODO: include blockcontext???
|
|
|
|
ctx := ctx sender.
|
|
|
|
}.
|
|
|
|
System logNl: "== END OF BACKTRACE ==".
|
|
|
|
}
|
|
|
|
|
2019-06-19 12:38:09 +00:00
|
|
|
/* nsdic access */
|
2017-03-23 16:14:22 +00:00
|
|
|
method(#class) at: key
|
|
|
|
{
|
|
|
|
^self nsdic at: key
|
|
|
|
}
|
|
|
|
|
|
|
|
method(#class) at: key put: value
|
|
|
|
{
|
|
|
|
^self nsdic at: key put: value
|
|
|
|
}
|
|
|
|
|
2019-06-19 12:38:09 +00:00
|
|
|
/* raw memory allocation */
|
2017-12-08 15:28:51 +00:00
|
|
|
method(#class,#primitive) malloc (size).
|
|
|
|
method(#class,#primitive) calloc (size).
|
|
|
|
method(#class,#primitive) free (rawptr).
|
|
|
|
|
|
|
|
method(#class,#primitive) malloc: size.
|
|
|
|
method(#class,#primitive) calloc: size.
|
|
|
|
method(#class,#primitive) free: rawptr.
|
2017-04-03 05:43:50 +00:00
|
|
|
|
2019-06-19 12:38:09 +00:00
|
|
|
/* raw memory access */
|
2019-06-27 06:29:09 +00:00
|
|
|
method(#class,#primitive) getInt8 (rawptr, offset). // <primitive: #System__getInt8>
|
2017-12-08 15:28:51 +00:00
|
|
|
method(#class,#primitive) getInt16 (rawptr, offset).
|
|
|
|
method(#class,#primitive) getInt32 (rawptr, offset).
|
|
|
|
method(#class,#primitive) getInt64 (rawptr, offset).
|
2019-06-27 06:29:09 +00:00
|
|
|
method(#class,#primitive) getUint8 (rawptr, offset). // <primitive: #System__getUint8>
|
2017-12-08 15:28:51 +00:00
|
|
|
method(#class,#primitive) getUint16 (rawptr, offset).
|
|
|
|
method(#class,#primitive) getUint32 (rawptr, offset).
|
|
|
|
method(#class,#primitive) getUint64 (rawptr, offset).
|
|
|
|
|
|
|
|
method(#class,#primitive) putInt8 (rawptr, offset, value).
|
|
|
|
method(#class,#primitive) putInt16 (rawptr, offset, value).
|
|
|
|
method(#class,#primitive) putInt32 (rawptr, offset, value).
|
|
|
|
method(#class,#primitive) putInt64 (rawptr, offset, value).
|
|
|
|
method(#class,#primitive) putUint8 (rawptr, offset, value).
|
|
|
|
method(#class,#primitive) putUint16 (rawptr, offset, value).
|
|
|
|
method(#class,#primitive) putUint32 (rawptr, offset, value).
|
|
|
|
method(#class,#primitive) putUint64 (rawptr, offset, value).
|
2017-12-09 15:47:43 +00:00
|
|
|
|
|
|
|
method(#class,#primitive) getBytes (rawptr, offset, byte_array, offset_in_buffer, len_in_buffer).
|
|
|
|
method(#class,#primitive) putBytes (rawptr, offset, byte_array, offset_in_buffer, len_in_buffer).
|
2017-03-23 16:14:22 +00:00
|
|
|
}
|
2017-04-03 05:43:50 +00:00
|
|
|
|
|
|
|
|
2019-09-07 18:15:20 +00:00
|
|
|
// TODO: support Pointer arithmetic?
|
2019-09-05 15:55:39 +00:00
|
|
|
class(#limited) SmallPointer(Object)
|
2017-04-03 05:43:50 +00:00
|
|
|
{
|
|
|
|
method(#primitive) asString.
|
2018-11-06 06:24:59 +00:00
|
|
|
|
2017-04-03 13:24:18 +00:00
|
|
|
method(#primitive) getInt8 (offset).
|
|
|
|
method(#primitive) getInt16 (offset).
|
|
|
|
method(#primitive) getInt32 (offset).
|
|
|
|
method(#primitive) getInt64 (offset).
|
|
|
|
method(#primitive) getUint8 (offset).
|
|
|
|
method(#primitive) getUint16 (offset).
|
|
|
|
method(#primitive) getUint32 (offset).
|
|
|
|
method(#primitive) getUint64 (offset).
|
2017-12-08 15:28:51 +00:00
|
|
|
|
2017-04-03 13:24:18 +00:00
|
|
|
method(#primitive) putInt8 (offset, value).
|
|
|
|
method(#primitive) putInt16 (offset, value).
|
|
|
|
method(#primitive) putInt32 (offset, value).
|
|
|
|
method(#primitive) putInt64 (offset, value).
|
|
|
|
method(#primitive) putUint8 (offset, value).
|
|
|
|
method(#primitive) putUint16 (offset, value).
|
|
|
|
method(#primitive) putUint32 (offset, value).
|
|
|
|
method(#primitive) putUint64 (offset, value).
|
2017-12-09 15:47:43 +00:00
|
|
|
|
2017-12-09 16:04:17 +00:00
|
|
|
method(#primitive) getBytes (offset, byte_array, offset_in_buffer, len_in_buffer).
|
|
|
|
method(#primitive) putBytes (offset, byte_array, offset_in_buffer, len_in_buffer).
|
|
|
|
|
2017-04-03 05:43:50 +00:00
|
|
|
method(#primitive) free.
|
|
|
|
}
|
2019-09-05 08:45:04 +00:00
|
|
|
|
2019-09-07 17:48:02 +00:00
|
|
|
class(#limited,#immutable,#word(1)) LargePointer(SmallPointer)
|
2019-09-05 08:45:04 +00:00
|
|
|
{
|
|
|
|
}
|