1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
/*
* Boolean built-ins
*/
#include "duk_internal.h"
/* Shared helper to provide toString() and valueOf(). Checks 'this', gets
* the primitive value to stack top, and optionally coerces with ToString().
*/
DUK_INTERNAL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_context *ctx) {
duk_tval *tv;
duk_hobject *h;
duk_small_int_t coerce_tostring = duk_get_current_magic(ctx);
/* XXX: there is room to use a shared helper here, many built-ins
* check the 'this' type, and if it's an object, check its class,
* then get its internal value, etc.
*/
duk_push_this(ctx);
tv = duk_get_tval(ctx, -1);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_BOOLEAN(tv)) {
goto type_ok;
} else if (DUK_TVAL_IS_OBJECT(tv)) {
h = DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(h != NULL);
if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_BOOLEAN) {
duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INT_VALUE);
DUK_ASSERT(duk_is_boolean(ctx, -1));
goto type_ok;
}
}
return DUK_RET_TYPE_ERROR;
type_ok:
if (coerce_tostring) {
duk_to_string(ctx, -1);
}
return 1;
}
DUK_INTERNAL duk_ret_t duk_bi_boolean_constructor(duk_context *ctx) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_hobject *h_this;
DUK_UNREF(thr);
duk_to_boolean(ctx, 0);
if (duk_is_constructor_call(ctx)) {
/* XXX: helper; rely on Boolean.prototype as being non-writable, non-configurable */
duk_push_this(ctx);
h_this = duk_get_hobject(ctx, -1);
DUK_ASSERT(h_this != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]);
DUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_BOOLEAN);
duk_dup(ctx, 0); /* -> [ val obj val ] */
duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); /* XXX: proper flags? */
} /* unbalanced stack */
return 1;
}
|