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.
 
 
 
 
 
 

705 lines
23 KiB

<h1 id="duktapebuiltins">Duktape built-ins</h1>
<p>This section describes Duktape-specific built-in objects, methods, and
values.</p>
<h2>Additional global object properties</h2>
<table>
<thead>
<tr>
<th>Property</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr><td class="propname">Duktape</td><td>The Duktape built-in object. Contains miscellaneous implementation specific stuff.</td></tr>
<tr><td class="propname">Proxy</td><td>Proxy constructor borrowed from ES6 draft (not part of Ecmascript E5/E5.1).</td></tr>
<tr><td class="propname">print</td><td>Non-standard, browser-like function for writing to <code>stdout</code>.</td></tr>
<tr><td class="propname">alert</td><td>Non-standard, browser-like function for writing to <code>stderr</code>.</td></tr>
</tbody>
</table>
<h3>print and alert</h3>
<p><code>print()</code> writes to <code>stdout</code> with an automatic
flush afterwards. The bytes written depend on the arguments:</p>
<ul>
<li>If given a single buffer argument, the contents of that buffer are
written to <code>stdout</code> as is. This allows raw byte streams
to be reliably written.</li>
<li>Otherwise arguments are string coerced, joined with a single space
character, a newline (0x0a) is appended, and the result is written
to <code>stdout</code>. For instance, <code>print('foo', 'bar')</code>
would write the bytes <code>66 6f 6f 20 62 61 72 0a</code>. Non-ASCII
characters are written directly in their internal extended UTF-8
representation; for most strings this means that output data is
properly UTF-8 encoded. Terminal encoding, locale, platform newline
conventions etc. have no effect on the output.</li>
</ul>
<p><code>alert()</code> behaves the same way, but writes to
<code>stderr</code>. Unlike a browser <code>alert()</code>, the call
does not block.</p>
<h2>The Duktape object</h2>
<table>
<thead>
<tr>
<th>Property</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr><td class="propname">version</td><td>Duktape version number: <code>(major * 10000) + (minor * 100) + patch</code>.</td></tr>
<tr><td class="propname">env</td><td>Cryptic, version dependent summary of most important effective options like endianness and architecture.</td></tr>
<tr><td class="propname">fin</td><td>Set or get finalizer of an object.</td></tr>
<tr><td class="propname">enc</td><td>Encode a value (hex, base-64, JX, JC): <code>Duktape.enc('hex', 'foo')</code>.</td></tr>
<tr><td class="propname">dec</td><td>Decode a value (hex, base-64, JX, JC): <code>Duktape.dec('base64', 'Zm9v')</code>.</td></tr>
<tr><td class="propname">info</td><td>Get internal information (such as heap address and alloc size) of a value in a version specific format.</td></tr>
<tr><td class="propname">line</td><td>Get current line number.</td></tr>
<tr><td class="propname">act</td><td>Get information about call stack entry.</td></tr>
<tr><td class="propname">gc</td><td>Trigger mark-and-sweep garbage collection.</td></tr>
<tr><td class="propname">compact</td><td>Compact the memory allocated for a value (object).</td></tr>
<tr><td class="propname">errCreate</td><td>Callback to modify/replace a created error.</td></tr>
<tr><td class="propname">errThrow</td><td>Callback to modify/replace an error about to be thrown.</td></tr>
<tr><td class="propname">modSearch</td><td>Module search function, must be provided by user code if using modules.</td></tr>
<tr><td class="propname">modLoaded</td><td>Internal tracking table for loaded modules, maps resolved identifier to exported symbols.</td></tr>
<tr><td class="propname">Buffer</td><td>Buffer constructor (function).</td></tr>
<tr><td class="propname">Pointer</td><td>Pointer constructor (function).</td></tr>
<tr><td class="propname">Thread</td><td>Thread constructor (function).</td></tr>
<tr><td class="propname">Logger</td><td>Logger constructor (function).</td></tr>
</tbody>
</table>
<h3>version</h3>
<p>The <code>version</code> property allows version-based feature detection and
behavior. Version numbers can be compared directly: a logically higher version
will also be numerically higher. For example:</p>
<pre class="ecmascript-code">
if (typeof Duktape !== 'object') {
print('not Duktape');
} else if (Duktape.version &gt;= 10203) {
print('Duktape 1.2.3 or higher');
} else if (Duktape.version &gt;= 800) {
print('Duktape 0.8.0 or higher (but lower than 1.2.3)');
} else {
print('Duktape lower than 0.8.0');
}
</pre>
<p>Unofficial development snapshots have patch level set to 99. For example,
version 0.11.99 (1199) would be a development snapshot after 0.11.0 but before
the next official release.</p>
<p>Remember to check for existence of <code>Duktape</code> when doing feature
detection. Your code should typically work on as many engines as possible.
Avoid the common pitfall of using a direct identifier reference in the check:</p>
<pre class="ecmascript-code">
// Bad idea: ReferenceError if missing
if (!Duktape) {
print('not Duktape');
}
// Better: check through 'this' (bound to global)
if (!this.Duktape) {
print('not Duktape');
}
// Better: use typeof to check also type explicitly
if (typeof Duktape !== 'object') {
print('not Duktape');
}
</pre>
<h3>env</h3>
<p><code>env</code> summarizes the most important effective compile options
in a version specific, quite cryptic manner. The format is version specific
and is not intended to be parsed programmatically. This is mostly useful for
developers (see <code>duk_hthread_builtins.c</code> for the code which sets
the value).</p>
<p>Example from Duktape 0.10.0:</p>
<pre class="ecmascript-code">
ll u p2 a4 x64 // l|b|m integer endianness, l|b|m double endianness,
// p|u packed/unpacked tval, p1|p2 prop memory layout,
// a1/a4/a8 align target, arch
</pre>
<h3>fin()</h3>
<p>When called with a single argument, gets the current finalizer of an object:</p>
<pre class="ecmascript-code">
var currFin = Duktape.fin(o);
</pre>
<p>When called with two arguments, sets the finalizer of an object (returns undefined):</p>
<pre class="ecmascript-code">
Duktape.fin(o, function(x) { print('finalizer called'); });
Duktape.fin(o, undefined); // disable
</pre>
<h3>enc()</h3>
<p><code>enc()</code> encodes its argument value into chosen format.
The first argument is a format (currently supported are "hex", "base64",
"jx" and "jc"), second argument is the value to encode, and any further
arguments are format specific.</p>
<p>For "hex" and "base64", buffer values are encoded as is, other values
are string coerced and the internal byte representation (extended UTF-8)
is then encoded. The result is a string. For example, to encode a string
into base64:</p>
<pre class="ecmascript-code">
var result = Duktape.enc('base64', 'foo');
print(result); // prints 'Zm9v'
</pre>
<p>For "jx" and "jc" the argument list following the format name is the
same as for <code>JSON.stringify()</code>: value, replacer (optional),
space (optional). For example:</p>
<pre class="ecmascript-code">
var result = Duktape.enc('jx', { foo: 123 }, null, 4);
print(result); // prints JX encoded {foo:123} with 4-space indent
</pre>
<h3>dec()</h3>
<p><code>dec()</code> provides the reverse function of <code>enc()</code>.</p>
<p>For "hex" and "base64" the input value is first string coerced (it only
really makes sense to decode strings). The result is always a buffer. For example:</p>
<pre class="ecmascript-code">
var result = Duktape.dec('base64', 'Zm9v');
print(typeof result, result); // prints 'buffer foo'
</pre>
<p>If you wish to get back a string value, you can simply:</p>
<pre class="ecmascript-code">
var result = String(Duktape.dec('base64', 'Zm9v'));
print(typeof result, result); // prints 'string foo'
</pre>
<p>For "jx" and "jc" the argument list following the format name is the same
as for <code>JSON.parse()</code>: text, reviver (optional). For example:</p>
<pre class="ecmascript-code">
var result = Duktape.dec('jx', "{foo:123}");
print(result.foo); // prints 123
</pre>
<h3>info()</h3>
<p>When given an arbitrary input value, <code>Duktape.info()</code> returns an
array of values with internal information related to the value. The format of
of the values in the array is version specific. This is mainly useful for
debugging and diagnosis, e.g. when estimating rough memory usage of objects.</p>
<p>The current result array format is described in the table below. Notes:</p>
<ul>
<li>Memory sizes do not include any heap overhead (which may be 8-16 bytes or
more, depending on what kind of allocation algorithm is used).</li>
<li>Reference counts are not adjusted in any way, and include references to
the value caused by the <code>info()</code> call.</li>
<li>"type tag" is a number matching <code>DUK_TYPE_xxx</code> from <code>duktape.h</code>.</li>
<li>The number of entries allocated for object properties is given by
"prop entry count", while "prop entry used" indicates how many of the
entries are in used. If an array part is present, "prop array count"
indicates the number of entries currently allocated (there is no value
to indicate the number of used array part entries). Finally, "prop hash count"
indicates the number of entries in a hash lookup table if present (it is
not present for typical, small objects). These numbers are counts, not
byte sizes.</li>
<li>Function data contains bytecode instructions, constants, etc. It is
shared between all instances (closures) of a certain function template.</li>
</ul>
<div class="table-wrap">
<table>
<thead>
<tr><th>Type</th><th>0</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th></tr>
</thead>
<tbody>
<tr>
<td>undefined</td>
<td>type tag</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>null</td>
<td>type tag</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>boolean</td>
<td>type tag</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>number</td>
<td>type tag</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>string</td>
<td>type tag</td>
<td>heap ptr</td>
<td>refcount</td>
<td>heap hdr size</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>object, Ecmascript function</td>
<td>type tag</td>
<td>heap ptr</td>
<td>refcount</td>
<td>heap hdr size</td>
<td>prop alloc size</td>
<td>prop entry count</td>
<td>prop entry used</td>
<td>prop array count</td>
<td>prop hash count</td>
<td>func data size</td>
</tr>
<tr>
<td>object, Duktape/C function</td>
<td>type tag</td>
<td>heap ptr</td>
<td>refcount</td>
<td>heap hdr size</td>
<td>prop alloc size</td>
<td>prop entry count</td>
<td>prop entry used</td>
<td>prop array count</td>
<td>prop hash count</td>
<td>-</td>
</tr>
<tr>
<td>object, thread</td>
<td>type tag</td>
<td>heap ptr</td>
<td>refcount</td>
<td>heap hdr size</td>
<td>prop alloc size</td>
<td>prop entry count</td>
<td>prop entry used</td>
<td>prop array count</td>
<td>prop hash count</td>
<td>-</td>
</tr>
<tr>
<td>object, other</td>
<td>type tag</td>
<td>heap ptr</td>
<td>refcount</td>
<td>heap hdr size</td>
<td>prop alloc size</td>
<td>prop entry count</td>
<td>prop entry used</td>
<td>prop array count</td>
<td>prop hash count</td>
<td>-</td>
</tr>
<tr>
<td>buffer, fixed</td>
<td>type tag</td>
<td>heap ptr</td>
<td>refcount</td>
<td>heap hdr size</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>buffer, dynamic</td>
<td>type tag</td>
<td>heap ptr</td>
<td>refcount</td>
<td>heap hdr size</td>
<td>curr buf size</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>pointer</td>
<td>type tag</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
</tbody>
</table>
</div>
<h3>line()</h3>
<p>Get the line number of the call site. This may be useful for debugging, e.g.:</p>
<pre class="ecmascript-code">
log.info('reached line:', Duktape.line());
</pre>
<div class="note">
As <code>Duktape.act()</code> provides more information, this function
will probably be removed.
</div>
<h3>act()</h3>
<p>Get information about a call stack entry. Takes a single number argument
indicating depth in the call stack: -1 is the top entry, -2 is the one below
that etc. Returns an object describing the call stack entry, or <code>undefined</code>
if the entry doesn't exist. Example:</p>
<pre class="ecmascript-code">
function dump() {
var i, t;
for (i = -1; ; i--) {
t = Duktape.act(i);
if (!t) { break; }
print(i, t.lineNumber, t.function.name, Duktape.enc('jx', t));
}
}
dump();
</pre>
<p>The example, when executed with the command line tool, currently prints
something like:</p>
<pre>
-1 0 act {lineNumber:0,pc:0,function:{_func:true}}
-2 4 dump {lineNumber:4,pc:16,function:{_func:true}}
-3 10 global {lineNumber:10,pc:5,function:{_func:true}}
</pre>
<p>The interesting entries are <code>lineNumber</code> and <code>function</code>
which provides e.g. the function name.</p>
<p>You can also implement a helper to get the current line number using
<code>Duktape.act()</code>:</p>
<pre class="ecmascript-code">
function getCurrentLine() {
// indices: -1 = Duktape.act, -2 = getCurrentLine, -3 = caller
var a = Duktape.act(-3) || {};
return a.lineNumber;
}
print('running on line:', getCurrentLine());
</pre>
<div class="note">
The properties provided for call stack entries may change between versions.
</div>
<h3>gc()</h3>
<p>Trigger a forced mark-and-sweep collection. If mark-and-sweep is disabled,
this call is a no-op.</p>
<h3>compact()</h3>
<p>Minimize the memory allocated for a target object. Same as the C API call
<code>duk_compact()</code> but accessible from Ecmascript code. If called with
a non-object argument, this call is a no-op. The argument value is returned by
the function, which allows code such as:</p>
<pre class="ecmascript-code">
var obj = {
foo: Duktape.compact({ bar:123 })
}
</pre>
<p>This call is useful when you know that an object is unlikely to gain new
properties, but you don't want to seal or freeze the object in case it does.</p>
<h3>errCreate() and errThrow()</h3>
<p>These can be set by user code to process/replace errors when they are created
(<code>errCreate</code>) or thrown (<code>errThrow</code>). Both values are
initially non-existent.</p>
<p>See
<a href="#error-handlers">Error handlers (errCreate and errThrow)</a> for
details.</p>
<h3>modSearch() and modLoaded</h3>
<p><code>modSearch()</code> is a module search function which must be provided
by user code to support module loading.
<code>modLoaded</code> is an internal module loading tracking table
maintained by Duktape which maps a resolved absolute module identifier to the
module's <code>exports</code> object for modules which are either fully loaded
or currently being loaded.</p>
<p>See <a href="#modules">Modules</a> for details.</p>
<h2>Duktape.Buffer (constructor)</h2>
<table>
<thead>
<tr>
<th>Property</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr><td class="propname">prototype</td><td>Prototype for Buffer objects.</td></tr>
</tbody>
</table>
<p>The Buffer constructor is a function which returns a plain buffer when
called as a normal function and a Buffer object when called as a
constructor. Otherwise the behavior is the same:</p>
<ul>
<li>If the first argument is a plain buffer, the buffer is used as is (a new
buffer is not created). The second argument is ignored. This form
can be used to wrap a plain buffer value into a Buffer object.</li>
<li>If the first argument is a Buffer object, the internal plain buffer value
of the argument is used (a new buffer is not created). The second argument
is again ignored. If called as a constructor, a new Buffer object is
returned, but it will internally point to the same plain buffer value.</li>
<li>If the first argument is a string, a new buffer is created and the bytes
from the string's internal extended UTF-8 representation are copied to the
buffer. The second argument (if present) indicates whether or not the new
buffer should be dynamic (resizable); the default value is false.</li>
<li>If the first argument is a number, a new buffer is created and filled with
zero. The second argument (if present) indicates whether or not the new
buffer should be dynamic. Zero filling the buffer is the default behavior,
but this can be disabled with a feature option; if disabled, the contents
will be unpredictable.</li>
<li>When called as a constructor, the result is converted into a Buffer
object whose internal value is the plain buffer. The internal prototype
of the newly created Buffer will be the
<code>Duktape.Buffer.prototype</code> object.</li>
</ul>
<div class="note">
There is currently (in Duktape 0.10.0) no way direct way to create a copy of
a buffer (i.e. a new buffer with the same contents but a separate underlying
buffer). This will be added in Duktape 0.11.0; for now you can make a copy
inefficiently e.g. as <code>Duktape.Buffer(String(orig_buf))</code>. Buffers
are currently mostly intended to be operated with from C code.
</div>
<h2>Duktape.Buffer.prototype</h2>
<table>
<thead>
<tr>
<th>Property</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr><td class="propname">toString</td><td>Convert Buffer to a printable string.</td></tr>
<tr><td class="propname">valueOf</td><td>Return the primitive buffer value held by Buffer.</td></tr>
</tbody>
</table>
<p><code>toString()</code> and <code>valueOf</code> accept both plain buffers and
Buffer objects as their <code>this</code> binding. This allows code such as:</p>
<pre class="ecmascript-code">
var plain_buf = Duktape.Buffer('test');
print(plain_buf.toString());
</pre>
<h2>Duktape.Pointer (constructor)</h2>
<table>
<thead>
<tr>
<th>Property</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr><td class="propname">prototype</td><td>Prototype for Pointer objects.</td></tr>
</tbody>
</table>
<p>The Pointer constructor is a function which can be called both as an
ordinary function and as a constructor:</p>
<ul>
<li>When called as a function, coerces the first argument to a pointer using
the custom <code>ToPointer</code> coercion. The return value is a plain
pointer (not a Pointer object).</li>
<li>When called as a constructor, coerces the first argument to a pointer
using the custom <code>ToPointer</code> coercion. Returns a Pointer object
whose internal value is the pointer resulting from the coercion. The
internal prototype of the newly created Pointer will be the
<code>Duktape.Pointer.prototype</code> object.</li>
</ul>
<h2>Duktape.Pointer.prototype</h2>
<table>
<thead>
<tr>
<th>Property</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr><td class="propname">toString</td><td>Convert Pointer to a printable string.</td></tr>
<tr><td class="propname">valueOf</td><td>Return the primitive pointer value held by Pointer.</td></tr>
</tbody>
</table>
<p><code>toString()</code> and <code>valueOf</code> accept both plain pointers and
Pointer objects as their <code>this</code> binding. This allows code such as:</p>
<pre class="ecmascript-code">
var plain_ptr = Duktape.Pointer({ test: 'object' });
print(plain_ptr.toString());
</pre>
<h2>Duktape.Thread (constructor)</h2>
<table>
<thead>
<tr>
<th>Property</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr><td class="propname">prototype</td><td>Prototype for Thread objects.</td></tr>
<tr><td class="propname">resume</td><td>Resume target thread with a value or an error.
Arguments: target thread, value, flag indicating whether value is to be thrown (optional, default false).</td></tr>
<tr><td class="propname">yield</td><td>Yield a value or an error from current thread.
Arguments: value, flag indicating whether value is to be thrown (optional, default false).</td></tr>
<tr><td class="propname">current</td><td>Get currently running Thread object.</td></tr>
</tbody>
</table>
<p>The Thread constructor is a function which can be called both as an
ordinary function and as a constructor. The behavior is the same in both
cases:</p>
<ul>
<li>The first argument is checked to be a function (if not, a <code>TypeError</code>
is thrown). The return value is a new thread whose initial function is
recorded to be the argument function (this function will start executing
when the new thread is first resumed). The internal prototype of the
newly created Thread will be the <code>Duktape.Thread.prototype</code> object.</li>
</ul>
<h2>Duktape.Thread.prototype</h2>
<table>
<thead>
<tr>
<th>Property</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr><td colspan="2">No properties at the moment.</td></tr>
</tbody>
</table>
<h2>Duktape.Logger (constructor)</h2>
<table>
<thead>
<tr>
<th>Property</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr><td class="propname">prototype</td><td>Prototype for Logger objects.</td></tr>
<tr><td class="propname">clog</td><td>Representative logger for log entries written from C code.</td></tr>
</tbody>
</table>
<p>Called as a constructor, creates a new Logger object with a specified name
(first argument). If the name is omitted, Logger will automatically assign
a name based on the calling function's <code>fileName</code>.
If called as a normal function, throws a <code>TypeError</code>.</p>
<p>Logger instances have the following properties:</p>
<ul>
<li><code>n</code>: logger name; the property will be missing if (a) the given
name is not a string, or (b) no name is given and the automatic assignment
fails. The logger will then inherit a value from the Logger prototype.
You can manually set this property later to whatever value is desired.</li>
<li><code>l</code>: log level, indicates the minimum log level to output.
This property is not assigned by default and the logger inherits a default
level from the Logger prototype. You can manually set this property to
another value to control log level on a per-logger basis.</li>
</ul>
<p>To write log entries:</p>
<pre class="ecmascript-code">
var logger = new Duktape.Logger();
logger.info('three values:', val1, val2, val3);
</pre>
<p>For now, see the
<a href="https://github.com/svaarala/duktape/blob/master/doc/logging.txt">internal documentation</a>
on logging for more info.</p>
<div class="fixme">
Tail calling might theoretically affect the automatic name assignment (i.e.
when logger name argument is omitted). However, constructor calls are never
converted to tail calls, so this is not a practical issue.
</div>
<h2>Duktape.Logger.prototype</h2>
<table>
<thead>
<tr>
<th>Property</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr><td class="propname">raw</td><td>Output a formatted log line (buffer value), by default writes to <code>stderr</code>.</td></tr>
<tr><td class="propname">fmt</td><td>Format a single (object) argument.</td></tr>
<tr><td class="propname">trace</td><td>Write a trace level (level 0, TRC) log entry.</td></tr>
<tr><td class="propname">debug</td><td>Write a debug level (level 1, DBG) log entry.</td></tr>
<tr><td class="propname">info</td><td>Write an info level (level 2, INF) log entry.</td></tr>
<tr><td class="propname">warn</td><td>Write a warn level (level 3, WRN) log entry.</td></tr>
<tr><td class="propname">error</td><td>Write an error level (level 4, ERR) log entry.</td></tr>
<tr><td class="propname">fatal</td><td>Write a fatal level (level 5, FTL) log entry.</td></tr>
<tr><td class="propname">l</td><td>Default log level, initial value is 2 (info).</td></tr>
<tr><td class="propname">n</td><td>Default logger name, initial value is "anon".</td></tr>
</tbody>
</table>