mirror of https://github.com/svaarala/duktape.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
4.2 KiB
111 lines
4.2 KiB
==========================
|
|
Lightweight function value
|
|
==========================
|
|
|
|
Overview
|
|
========
|
|
|
|
This document describes the changes necessary to support a lightweight
|
|
function value type, which refers to a native Duktape/C function without
|
|
needing a representative Ecmascript Function object. This is useful to
|
|
minimize footprint of typical Duktape/C binding functions.
|
|
|
|
Changes needed
|
|
==============
|
|
|
|
* Add a new tagged type, DUK_TAG_LIGHTFUNC, which points to a Duktape/C
|
|
function.
|
|
|
|
- A lightweight function can be a constructor, but will never have an
|
|
automatic prototype object (a property slot would be needed to store it).
|
|
A lightweight constructor function can create a replacement object from
|
|
scratch and discard the automatically created instance object.
|
|
|
|
* The representation depends on the ``duk_tval`` layout:
|
|
|
|
- For 8-byte packed type: 32-bit function pointer (pointing to the
|
|
Duktape/C function) and 16 bits for function metadata.
|
|
|
|
- For unpacked type: function pointer and 16 bits options field.
|
|
|
|
* The options field should contain:
|
|
|
|
- Function argument count / varargs indicator. Also used to deduce
|
|
a virtual "length" property.
|
|
|
|
- Depending on how many functions there are with a "length" property
|
|
different from their internal "nargs" property, perhaps a field for
|
|
external "length" virtual property.
|
|
|
|
- A small magic value, often needed in internals.
|
|
|
|
* Add support in call handling for calling such a function.
|
|
|
|
* Add support in traceback handling.
|
|
|
|
* Add virtual object properties so that lightweight functions will appear
|
|
like ordinary Function objects to some extent, e.g.:
|
|
|
|
- "length": based on argument count, 0 if vararg.
|
|
|
|
- "name": as no name can be stored, this should maybe be some useful
|
|
string containing the function pointer, e.g. "lightfunc:0xdeadbeef".
|
|
|
|
- "fileName": as no name can be stored, this should maybe be something
|
|
like "lightfunc", or perhaps same as "name".
|
|
|
|
- Perhaps some virtual properties like "caller" and "arguments", as
|
|
given to strict Ecmascript functions.
|
|
|
|
* It would be nice to be able to convert a lightweight function to a
|
|
normal function object (which would be non-unique) if necessary.
|
|
|
|
* Add an option to change built-in functions into lightweight functions
|
|
instead of Function objects. This should not be active by default,
|
|
because this change makes the built-ins strictly non-compliant. However,
|
|
this is quite useful in RAM constrained environments.
|
|
|
|
* Extend the public API to allow the user to push lightweight function
|
|
pointers in addition to ordinary ones. Or perhaps make the default
|
|
behavior to push a lightweight function (arguments permitting).
|
|
|
|
Motivation
|
|
==========
|
|
|
|
Normal function representation
|
|
------------------------------
|
|
|
|
In Duktape 0.11.0 functions are represented as:
|
|
|
|
* A ``duk_hcompiledfunction`` (a superset of ``duk_hobject``): represents
|
|
an Ecmascript function which may have a set of properties, and points to
|
|
the function's data area (bytecode, constants, inner function refs).
|
|
|
|
* A ``duk_hnativefunction`` (a superset of ``duk_hobject``): represents
|
|
a Duktape/C function which may also have a set of properties. A pointer
|
|
to the C function is inside the ``duk_hnativefunction`` structure.
|
|
|
|
This heavyweight representation is a RAM footprint issue, as discussed below.
|
|
|
|
Ecmascript functions
|
|
--------------------
|
|
|
|
An ordinary Ecmascript function takes over 200 bytes of RAM. There are
|
|
two objects: the function itself and its automatic prototype object.
|
|
The function contains a ``.prototype`` property while the prototype
|
|
contains a ``.constructor`` property, so that both functions require a
|
|
property table. This is the case even for the majority of user functions
|
|
which will never be used as constructors; built-in functions are oddly
|
|
exempt from having an automatic prototype. Taken together these four
|
|
allocations take over 200 bytes.
|
|
|
|
Duktape/C functions
|
|
-------------------
|
|
|
|
A Duktape/C function takes about 70-80 bytes of RAM. Unlike Ecmascript
|
|
functions, Duktape/C function are already stripped of unnecessary properties
|
|
and don't have an automatic prototype object.
|
|
|
|
Even so, there are close to 200 built-in functions, so the footprint of
|
|
the ``duk_hnativefunction`` objects is around 16kB, not taking into account
|
|
allocator overhead.
|
|
|