]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | /* |
2 | * Proxy built-in (ES6) | |
3 | */ | |
4 | ||
5 | #include "duk_internal.h" | |
6 | ||
7 | #if defined(DUK_USE_ES6_PROXY) | |
8 | DUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx) { | |
9 | duk_hobject *h_target; | |
10 | duk_hobject *h_handler; | |
11 | ||
12 | if (!duk_is_constructor_call(ctx)) { | |
13 | return DUK_RET_TYPE_ERROR; | |
14 | } | |
15 | ||
16 | /* Reject a proxy object as the target because it would need | |
17 | * special handler in property lookups. (ES6 has no such restriction) | |
18 | */ | |
19 | h_target = duk_require_hobject_or_lfunc_coerce(ctx, 0); | |
20 | DUK_ASSERT(h_target != NULL); | |
21 | if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h_target)) { | |
22 | return DUK_RET_TYPE_ERROR; | |
23 | } | |
24 | ||
25 | /* Reject a proxy object as the handler because it would cause | |
26 | * potentially unbounded recursion. (ES6 has no such restriction) | |
27 | */ | |
28 | h_handler = duk_require_hobject_or_lfunc_coerce(ctx, 1); | |
29 | DUK_ASSERT(h_handler != NULL); | |
30 | if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h_handler)) { | |
31 | return DUK_RET_TYPE_ERROR; | |
32 | } | |
33 | ||
34 | /* XXX: the returned value is exotic in ES6, but we use a | |
35 | * simple object here with no prototype. Without a prototype, | |
36 | * [[DefaultValue]] coercion fails which is abit confusing. | |
37 | * No callable check/handling in the current Proxy subset. | |
38 | */ | |
39 | (void) duk_push_object_helper_proto(ctx, | |
40 | DUK_HOBJECT_FLAG_EXTENSIBLE | | |
41 | DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ | | |
42 | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT), | |
43 | NULL); | |
44 | DUK_ASSERT_TOP(ctx, 3); | |
45 | ||
46 | /* Make _Target and _Handler non-configurable and non-writable. | |
47 | * They can still be forcibly changed by C code (both user and | |
48 | * Duktape internal), but not by Ecmascript code. | |
49 | */ | |
50 | ||
51 | /* Proxy target */ | |
52 | duk_dup(ctx, 0); | |
53 | duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE); | |
54 | ||
55 | /* Proxy handler */ | |
56 | duk_dup(ctx, 1); | |
57 | duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_HANDLER, DUK_PROPDESC_FLAGS_NONE); | |
58 | ||
59 | return 1; /* replacement handler */ | |
60 | } | |
61 | #else /* DUK_USE_ES6_PROXY */ | |
62 | DUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx) { | |
63 | DUK_UNREF(ctx); | |
64 | return DUK_RET_UNSUPPORTED_ERROR; | |
65 | } | |
66 | #endif /* DUK_USE_ES6_PROXY */ |