This avoids the need for a function call and up to two property lookups
for a `Math.pow()` invocation, as well as allowing expressions like
`2 ** 16` to be inlined at compile time.
Exponentiation uses the same internal handler as `Math.pow()`, per the
ES7 specification.
Usage:
x = base ** exp;
x **= 2;
Optimization to avoid a temporary for x <op>= y works for any RHS
which doesn't emit code when evaluated to an ivalue, e.g.:
* A plain constant or any expression which constant folds to a
constant, e.g.: x += 4 and x += 'foo' + 'bar'.
* A register-bound variable, e.g. x += y.
The optimization doesn't have enough state to detect safe cases
such as register bound 'y' in: x += y + 1.
Saves a few hundred bytes of footprint:
* duk_dup_0() = duk_dup(ctx, 0), duk_dup_1() = duk_dup(ctx, 1), etc.
* duk_dup_m2() = duk_dup(ctx, -2), etc.
* duk_dup_m1() is not added, because duk_dup_top() is the same thing
* Add genconfig.py support for producing an "active options" JSON file at the
end of genconfig processing. The JSON file indicates which config options
are known to be present (any non-false value) or absent (false or #undef).
* Add support for 'present_if' keys for objects and properties. If the
corresponding config option is certain to be false, drop the object/property
as if it was disabled.
* Remove objects from "needs bidx" list if they're disabled.
Limitations:
* The active options scanning is based on config metadata defaults and forced
overrides. It doesn't account for fixups which cannot be handled reliably
because fixups may include further headers that tweak DUK_USE_xxx options.
A small improvement would be to base "active options" on scanning the final
header for #define's and #undef's and figure out which were certain to be
unconditional.