|
ByteThings
About ByteThings, Casting, call()/apply() and Mutability
IntroductionA byteThing in GPSEE is a specialized native data type. From script, they are interesting because they represent 8-bit data (in only 8 bits per byte) and are interchangeable in many circumstances. These characterstics make them suitable for implementing low-level interfaces with C code, I/O, and other "close to the metal" operations. From the C API perspective, this data type has a private slot struct with members buffer, length, btFlags, and memoryOwner.
Currently implemented ByteThingsbinary module
gffi module
MutabilityByteThings are considered mutable by default. This means that, from script, you are not guaranteed the same answer for the same property access if you have run any code between the property accesses. Immutable byteThings do guarantee identical property access will yield equivalent results (there is no guarantee that they will be equal). Imutable byteThings also agree to never modify buffer, buffer's contents, length, btFlags, or memoryOwner. CastingCasting in GPSEE refers to the act of reinterpreting underlying data and presenting it with a new JavaScript interface. It is subtly different from a C cast and somewhat similar to a C++ reinterpret-cast. Casting is performed by using a byteThing constructor as a function. Casting to or from a mutable byteThing will always perform a memory-level copy. Casting to and from an immutable byteThing allows an internal optimization which re-uses the backing store. This closely resembles a C cast and is a very inexpensive operation. Casting from other JavaScript types is dependent on the casting function. Generally, instances of String, the null object, and maybe numbers will be special-cased. Strings will normally be converted to C character arrays (UTF-8 encoded when GPSEE is UTF-8 aware), and the resultant character array will be treated as a byteThing buffer. The null object will often be treated as the C NULL pointer. Classes like Memory(), which wrap malloc(), will treat numbers as pointers. Note: not all pointers can be presented by numbers; however, -1 and and 0 are safe). call() / apply()These two JavaScript functions allow a method to be executed on a foreign object. During a call to call() or apply(), we essentially have a period of limited immutability, and so can relax the mutable copying rules. For example, a method from an immutable byteThing can be applied to a mutable byteThing; for example, to read C data encoded in UTF-8 and return it as a UTF-16 JavaScript String. Many byteThing methods are available to other byteThings via .call and .apply. Any method which
Note: call() and apply() are not safe to call when two threads of JavaScript, acting on the same mutable objects, are in play. The JavaScript programmer must provide external serialization (i.e. with a mutex) in order to safely using call() and apply() on mutable byteThings. |