Mercurial > molko
annotate extern/libduktape/duk_module_duktape.c @ 377:bc01bb8ee870
js: add support for commonJS modules
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 02 Nov 2021 16:02:54 +0100 |
parents | |
children |
rev | line source |
---|---|
377
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
1 /* |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
2 * Duktape 1.x compatible module loading framework |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
3 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
4 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
5 #include "duktape.h" |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
6 #include "duk_module_duktape.h" |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
7 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
8 /* (v)snprintf() is missing before MSVC 2015. Note that _(v)snprintf() does |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
9 * NOT NUL terminate on truncation, but that's OK here. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
10 * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
11 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
12 #if defined(_MSC_VER) && (_MSC_VER < 1900) |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
13 #define snprintf _snprintf |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
14 #endif |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
15 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
16 #if 0 /* Enable manually */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
17 #define DUK__ASSERT(x) do { \ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
18 if (!(x)) { \ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
19 fprintf(stderr, "ASSERTION FAILED at %s:%d: " #x "\n", __FILE__, __LINE__); \ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
20 fflush(stderr); \ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
21 } \ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
22 } while (0) |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
23 #define DUK__ASSERT_TOP(ctx,val) do { \ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
24 DUK__ASSERT(duk_get_top((ctx)) == (val)); \ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
25 } while (0) |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
26 #else |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
27 #define DUK__ASSERT(x) do { (void) (x); } while (0) |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
28 #define DUK__ASSERT_TOP(ctx,val) do { (void) ctx; (void) (val); } while (0) |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
29 #endif |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
30 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
31 static void duk__resolve_module_id(duk_context *ctx, const char *req_id, const char *mod_id) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
32 duk_uint8_t buf[DUK_COMMONJS_MODULE_ID_LIMIT]; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
33 duk_uint8_t *p; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
34 duk_uint8_t *q; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
35 duk_uint8_t *q_last; /* last component */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
36 duk_int_t int_rc; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
37 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
38 DUK__ASSERT(req_id != NULL); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
39 /* mod_id may be NULL */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
40 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
41 /* |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
42 * A few notes on the algorithm: |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
43 * |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
44 * - Terms are not allowed to begin with a period unless the term |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
45 * is either '.' or '..'. This simplifies implementation (and |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
46 * is within CommonJS modules specification). |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
47 * |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
48 * - There are few output bound checks here. This is on purpose: |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
49 * the resolution input is length checked and the output is never |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
50 * longer than the input. The resolved output is written directly |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
51 * over the input because it's never longer than the input at any |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
52 * point in the algorithm. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
53 * |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
54 * - Non-ASCII characters are processed as individual bytes and |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
55 * need no special treatment. However, U+0000 terminates the |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
56 * algorithm; this is not an issue because U+0000 is not a |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
57 * desirable term character anyway. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
58 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
59 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
60 /* |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
61 * Set up the resolution input which is the requested ID directly |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
62 * (if absolute or no current module path) or with current module |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
63 * ID prepended (if relative and current module path exists). |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
64 * |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
65 * Suppose current module is 'foo/bar' and relative path is './quux'. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
66 * The 'bar' component must be replaced so the initial input here is |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
67 * 'foo/bar/.././quux'. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
68 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
69 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
70 if (mod_id != NULL && req_id[0] == '.') { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
71 int_rc = snprintf((char *) buf, sizeof(buf), "%s/../%s", mod_id, req_id); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
72 } else { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
73 int_rc = snprintf((char *) buf, sizeof(buf), "%s", req_id); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
74 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
75 if (int_rc >= (duk_int_t) sizeof(buf) || int_rc < 0) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
76 /* Potentially truncated, NUL not guaranteed in any case. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
77 * The (int_rc < 0) case should not occur in practice. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
78 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
79 goto resolve_error; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
80 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
81 DUK__ASSERT(strlen((const char *) buf) < sizeof(buf)); /* at most sizeof(buf) - 1 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
82 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
83 /* |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
84 * Resolution loop. At the top of the loop we're expecting a valid |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
85 * term: '.', '..', or a non-empty identifier not starting with a period. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
86 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
87 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
88 p = buf; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
89 q = buf; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
90 for (;;) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
91 duk_uint_fast8_t c; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
92 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
93 /* Here 'p' always points to the start of a term. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
94 * |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
95 * We can also unconditionally reset q_last here: if this is |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
96 * the last (non-empty) term q_last will have the right value |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
97 * on loop exit. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
98 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
99 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
100 DUK__ASSERT(p >= q); /* output is never longer than input during resolution */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
101 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
102 q_last = q; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
103 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
104 c = *p++; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
105 if (c == 0) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
106 goto resolve_error; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
107 } else if (c == '.') { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
108 c = *p++; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
109 if (c == '/') { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
110 /* Term was '.' and is eaten entirely (including dup slashes). */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
111 goto eat_dup_slashes; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
112 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
113 if (c == '.' && *p == '/') { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
114 /* Term was '..', backtrack resolved name by one component. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
115 * q[-1] = previous slash (or beyond start of buffer) |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
116 * q[-2] = last char of previous component (or beyond start of buffer) |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
117 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
118 p++; /* eat (first) input slash */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
119 DUK__ASSERT(q >= buf); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
120 if (q == buf) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
121 goto resolve_error; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
122 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
123 DUK__ASSERT(*(q - 1) == '/'); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
124 q--; /* Backtrack to last output slash (dups already eliminated). */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
125 for (;;) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
126 /* Backtrack to previous slash or start of buffer. */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
127 DUK__ASSERT(q >= buf); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
128 if (q == buf) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
129 break; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
130 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
131 if (*(q - 1) == '/') { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
132 break; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
133 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
134 q--; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
135 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
136 goto eat_dup_slashes; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
137 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
138 goto resolve_error; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
139 } else if (c == '/') { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
140 /* e.g. require('/foo'), empty terms not allowed */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
141 goto resolve_error; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
142 } else { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
143 for (;;) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
144 /* Copy term name until end or '/'. */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
145 *q++ = c; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
146 c = *p++; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
147 if (c == 0) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
148 /* This was the last term, and q_last was |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
149 * updated to match this term at loop top. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
150 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
151 goto loop_done; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
152 } else if (c == '/') { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
153 *q++ = '/'; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
154 break; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
155 } else { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
156 /* write on next loop */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
157 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
158 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
159 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
160 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
161 eat_dup_slashes: |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
162 for (;;) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
163 /* eat dup slashes */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
164 c = *p; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
165 if (c != '/') { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
166 break; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
167 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
168 p++; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
169 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
170 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
171 loop_done: |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
172 /* Output #1: resolved absolute name. */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
173 DUK__ASSERT(q >= buf); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
174 duk_push_lstring(ctx, (const char *) buf, (size_t) (q - buf)); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
175 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
176 /* Output #2: last component name. */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
177 DUK__ASSERT(q >= q_last); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
178 DUK__ASSERT(q_last >= buf); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
179 duk_push_lstring(ctx, (const char *) q_last, (size_t) (q - q_last)); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
180 return; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
181 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
182 resolve_error: |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
183 (void) duk_type_error(ctx, "cannot resolve module id: %s", (const char *) req_id); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
184 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
185 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
186 /* Stack indices for better readability. */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
187 #define DUK__IDX_REQUESTED_ID 0 /* module id requested */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
188 #define DUK__IDX_REQUIRE 1 /* current require() function */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
189 #define DUK__IDX_REQUIRE_ID 2 /* the base ID of the current require() function, resolution base */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
190 #define DUK__IDX_RESOLVED_ID 3 /* resolved, normalized absolute module ID */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
191 #define DUK__IDX_LASTCOMP 4 /* last component name in resolved path */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
192 #define DUK__IDX_DUKTAPE 5 /* Duktape object */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
193 #define DUK__IDX_MODLOADED 6 /* Duktape.modLoaded[] module cache */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
194 #define DUK__IDX_UNDEFINED 7 /* 'undefined', artifact of lookup */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
195 #define DUK__IDX_FRESH_REQUIRE 8 /* new require() function for module, updated resolution base */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
196 #define DUK__IDX_EXPORTS 9 /* default exports table */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
197 #define DUK__IDX_MODULE 10 /* module object containing module.exports, etc */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
198 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
199 static duk_ret_t duk__require(duk_context *ctx) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
200 const char *str_req_id; /* requested identifier */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
201 const char *str_mod_id; /* require.id of current module */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
202 duk_int_t pcall_rc; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
203 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
204 /* NOTE: we try to minimize code size by avoiding unnecessary pops, |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
205 * so the stack looks a bit cluttered in this function. DUK__ASSERT_TOP() |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
206 * assertions are used to ensure stack configuration is correct at each |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
207 * step. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
208 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
209 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
210 /* |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
211 * Resolve module identifier into canonical absolute form. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
212 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
213 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
214 str_req_id = duk_require_string(ctx, DUK__IDX_REQUESTED_ID); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
215 duk_push_current_function(ctx); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
216 duk_get_prop_string(ctx, -1, "id"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
217 str_mod_id = duk_get_string(ctx, DUK__IDX_REQUIRE_ID); /* ignore non-strings */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
218 duk__resolve_module_id(ctx, str_req_id, str_mod_id); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
219 str_req_id = NULL; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
220 str_mod_id = NULL; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
221 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
222 /* [ requested_id require require.id resolved_id last_comp ] */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
223 DUK__ASSERT_TOP(ctx, DUK__IDX_LASTCOMP + 1); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
224 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
225 /* |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
226 * Cached module check. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
227 * |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
228 * If module has been loaded or its loading has already begun without |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
229 * finishing, return the same cached value (module.exports). The |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
230 * value is registered when module load starts so that circular |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
231 * references can be supported to some extent. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
232 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
233 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
234 duk_push_global_stash(ctx); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
235 duk_get_prop_string(ctx, -1, "\xff" "module:Duktape"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
236 duk_remove(ctx, -2); /* Lookup stashed, original 'Duktape' object. */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
237 duk_get_prop_string(ctx, DUK__IDX_DUKTAPE, "modLoaded"); /* Duktape.modLoaded */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
238 duk_require_type_mask(ctx, DUK__IDX_MODLOADED, DUK_TYPE_MASK_OBJECT); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
239 DUK__ASSERT_TOP(ctx, DUK__IDX_MODLOADED + 1); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
240 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
241 duk_dup(ctx, DUK__IDX_RESOLVED_ID); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
242 if (duk_get_prop(ctx, DUK__IDX_MODLOADED)) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
243 /* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded Duktape.modLoaded[id] ] */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
244 duk_get_prop_string(ctx, -1, "exports"); /* return module.exports */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
245 return 1; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
246 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
247 DUK__ASSERT_TOP(ctx, DUK__IDX_UNDEFINED + 1); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
248 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
249 /* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined ] */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
250 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
251 /* |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
252 * Module not loaded (and loading not started previously). |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
253 * |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
254 * Create a new require() function with 'id' set to resolved ID |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
255 * of module being loaded. Also create 'exports' and 'module' |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
256 * tables but don't register exports to the loaded table yet. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
257 * We don't want to do that unless the user module search callbacks |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
258 * succeeds in finding the module. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
259 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
260 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
261 /* Fresh require: require.id is left configurable (but not writable) |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
262 * so that is not easy to accidentally tweak it, but it can still be |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
263 * done with Object.defineProperty(). |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
264 * |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
265 * XXX: require.id could also be just made non-configurable, as there |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
266 * is no practical reason to touch it (at least from ECMAScript code). |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
267 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
268 duk_push_c_function(ctx, duk__require, 1 /*nargs*/); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
269 duk_push_string(ctx, "name"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
270 duk_push_string(ctx, "require"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
271 duk_def_prop(ctx, DUK__IDX_FRESH_REQUIRE, DUK_DEFPROP_HAVE_VALUE); /* not writable, not enumerable, not configurable */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
272 duk_push_string(ctx, "id"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
273 duk_dup(ctx, DUK__IDX_RESOLVED_ID); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
274 duk_def_prop(ctx, DUK__IDX_FRESH_REQUIRE, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_CONFIGURABLE); /* a fresh require() with require.id = resolved target module id */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
275 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
276 /* Module table: |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
277 * - module.exports: initial exports table (may be replaced by user) |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
278 * - module.id is non-writable and non-configurable, as the CommonJS |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
279 * spec suggests this if possible |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
280 * - module.filename: not set, defaults to resolved ID if not explicitly |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
281 * set by modSearch() (note capitalization, not .fileName, matches Node.js) |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
282 * - module.name: not set, defaults to last component of resolved ID if |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
283 * not explicitly set by modSearch() |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
284 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
285 duk_push_object(ctx); /* exports */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
286 duk_push_object(ctx); /* module */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
287 duk_push_string(ctx, "exports"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
288 duk_dup(ctx, DUK__IDX_EXPORTS); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
289 duk_def_prop(ctx, DUK__IDX_MODULE, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE); /* module.exports = exports */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
290 duk_push_string(ctx, "id"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
291 duk_dup(ctx, DUK__IDX_RESOLVED_ID); /* resolved id: require(id) must return this same module */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
292 duk_def_prop(ctx, DUK__IDX_MODULE, DUK_DEFPROP_HAVE_VALUE); /* module.id = resolved_id; not writable, not enumerable, not configurable */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
293 duk_compact(ctx, DUK__IDX_MODULE); /* module table remains registered to modLoaded, minimize its size */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
294 DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 1); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
295 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
296 /* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module ] */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
297 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
298 /* Register the module table early to modLoaded[] so that we can |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
299 * support circular references even in modSearch(). If an error |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
300 * is thrown, we'll delete the reference. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
301 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
302 duk_dup(ctx, DUK__IDX_RESOLVED_ID); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
303 duk_dup(ctx, DUK__IDX_MODULE); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
304 duk_put_prop(ctx, DUK__IDX_MODLOADED); /* Duktape.modLoaded[resolved_id] = module */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
305 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
306 /* |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
307 * Call user provided module search function and build the wrapped |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
308 * module source code (if necessary). The module search function |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
309 * can be used to implement pure Ecmacsript, pure C, and mixed |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
310 * ECMAScript/C modules. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
311 * |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
312 * The module search function can operate on the exports table directly |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
313 * (e.g. DLL code can register values to it). It can also return a |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
314 * string which is interpreted as module source code (if a non-string |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
315 * is returned the module is assumed to be a pure C one). If a module |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
316 * cannot be found, an error must be thrown by the user callback. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
317 * |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
318 * Because Duktape.modLoaded[] already contains the module being |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
319 * loaded, circular references for C modules should also work |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
320 * (although expected to be quite rare). |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
321 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
322 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
323 duk_push_string(ctx, "(function(require,exports,module){"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
324 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
325 /* Duktape.modSearch(resolved_id, fresh_require, exports, module). */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
326 duk_get_prop_string(ctx, DUK__IDX_DUKTAPE, "modSearch"); /* Duktape.modSearch */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
327 duk_dup(ctx, DUK__IDX_RESOLVED_ID); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
328 duk_dup(ctx, DUK__IDX_FRESH_REQUIRE); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
329 duk_dup(ctx, DUK__IDX_EXPORTS); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
330 duk_dup(ctx, DUK__IDX_MODULE); /* [ ... Duktape.modSearch resolved_id last_comp fresh_require exports module ] */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
331 pcall_rc = duk_pcall(ctx, 4 /*nargs*/); /* -> [ ... source ] */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
332 DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 3); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
333 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
334 if (pcall_rc != DUK_EXEC_SUCCESS) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
335 /* Delete entry in Duktape.modLoaded[] and rethrow. */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
336 goto delete_rethrow; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
337 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
338 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
339 /* If user callback did not return source code, module loading |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
340 * is finished (user callback initialized exports table directly). |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
341 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
342 if (!duk_is_string(ctx, -1)) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
343 /* User callback did not return source code, so module loading |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
344 * is finished: just update modLoaded with final module.exports |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
345 * and we're done. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
346 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
347 goto return_exports; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
348 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
349 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
350 /* Finish the wrapped module source. Force module.filename as the |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
351 * function .fileName so it gets set for functions defined within a |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
352 * module. This also ensures loggers created within the module get |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
353 * the module ID (or overridden filename) as their default logger name. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
354 * (Note capitalization: .filename matches Node.js while .fileName is |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
355 * used elsewhere in Duktape.) |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
356 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
357 duk_push_string(ctx, "\n})"); /* Newline allows module last line to contain a // comment. */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
358 duk_concat(ctx, 3); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
359 if (!duk_get_prop_string(ctx, DUK__IDX_MODULE, "filename")) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
360 /* module.filename for .fileName, default to resolved ID if |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
361 * not present. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
362 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
363 duk_pop(ctx); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
364 duk_dup(ctx, DUK__IDX_RESOLVED_ID); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
365 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
366 pcall_rc = duk_pcompile(ctx, DUK_COMPILE_EVAL); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
367 if (pcall_rc != DUK_EXEC_SUCCESS) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
368 goto delete_rethrow; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
369 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
370 pcall_rc = duk_pcall(ctx, 0); /* -> eval'd function wrapper (not called yet) */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
371 if (pcall_rc != DUK_EXEC_SUCCESS) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
372 goto delete_rethrow; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
373 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
374 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
375 /* Module has now evaluated to a wrapped module function. Force its |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
376 * .name to match module.name (defaults to last component of resolved |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
377 * ID) so that it is shown in stack traces too. Note that we must not |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
378 * introduce an actual name binding into the function scope (which is |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
379 * usually the case with a named function) because it would affect the |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
380 * scope seen by the module and shadow accesses to globals of the same name. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
381 * This is now done by compiling the function as anonymous and then forcing |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
382 * its .name without setting a "has name binding" flag. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
383 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
384 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
385 duk_push_string(ctx, "name"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
386 if (!duk_get_prop_string(ctx, DUK__IDX_MODULE, "name")) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
387 /* module.name for .name, default to last component if |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
388 * not present. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
389 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
390 duk_pop(ctx); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
391 duk_dup(ctx, DUK__IDX_LASTCOMP); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
392 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
393 duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_FORCE); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
394 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
395 /* |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
396 * Call the wrapped module function. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
397 * |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
398 * Use a protected call so that we can update Duktape.modLoaded[resolved_id] |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
399 * even if the module throws an error. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
400 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
401 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
402 /* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module mod_func ] */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
403 DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 2); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
404 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
405 duk_dup(ctx, DUK__IDX_EXPORTS); /* exports (this binding) */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
406 duk_dup(ctx, DUK__IDX_FRESH_REQUIRE); /* fresh require (argument) */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
407 duk_get_prop_string(ctx, DUK__IDX_MODULE, "exports"); /* relookup exports from module.exports in case it was changed by modSearch */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
408 duk_dup(ctx, DUK__IDX_MODULE); /* module (argument) */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
409 DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 6); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
410 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
411 /* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module mod_func exports fresh_require exports module ] */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
412 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
413 pcall_rc = duk_pcall_method(ctx, 3 /*nargs*/); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
414 if (pcall_rc != DUK_EXEC_SUCCESS) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
415 /* Module loading failed. Node.js will forget the module |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
416 * registration so that another require() will try to load |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
417 * the module again. Mimic that behavior. |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
418 */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
419 goto delete_rethrow; |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
420 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
421 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
422 /* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module result(ignored) ] */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
423 DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 2); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
424 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
425 /* fall through */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
426 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
427 return_exports: |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
428 duk_get_prop_string(ctx, DUK__IDX_MODULE, "exports"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
429 duk_compact(ctx, -1); /* compact the exports table */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
430 return 1; /* return module.exports */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
431 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
432 delete_rethrow: |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
433 duk_dup(ctx, DUK__IDX_RESOLVED_ID); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
434 duk_del_prop(ctx, DUK__IDX_MODLOADED); /* delete Duktape.modLoaded[resolved_id] */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
435 (void) duk_throw(ctx); /* rethrow original error */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
436 return 0; /* not reachable */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
437 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
438 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
439 void duk_module_duktape_init(duk_context *ctx) { |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
440 /* Stash 'Duktape' in case it's modified. */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
441 duk_push_global_stash(ctx); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
442 duk_get_global_string(ctx, "Duktape"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
443 duk_put_prop_string(ctx, -2, "\xff" "module:Duktape"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
444 duk_pop(ctx); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
445 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
446 /* Register `require` as a global function. */ |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
447 duk_eval_string(ctx, |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
448 "(function(req){" |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
449 "var D=Object.defineProperty;" |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
450 "D(req,'name',{value:'require'});" |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
451 "D(this,'require',{value:req,writable:true,configurable:true});" |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
452 "D(Duktape,'modLoaded',{value:Object.create(null),writable:true,configurable:true});" |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
453 "})"); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
454 duk_push_c_function(ctx, duk__require, 1 /*nargs*/); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
455 duk_call(ctx, 1); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
456 duk_pop(ctx); |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
457 } |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
458 |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
459 #undef DUK__ASSERT |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
460 #undef DUK__ASSERT_TOP |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
461 #undef DUK__IDX_REQUESTED_ID |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
462 #undef DUK__IDX_REQUIRE |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
463 #undef DUK__IDX_REQUIRE_ID |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
464 #undef DUK__IDX_RESOLVED_ID |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
465 #undef DUK__IDX_LASTCOMP |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
466 #undef DUK__IDX_DUKTAPE |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
467 #undef DUK__IDX_MODLOADED |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
468 #undef DUK__IDX_UNDEFINED |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
469 #undef DUK__IDX_FRESH_REQUIRE |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
470 #undef DUK__IDX_EXPORTS |
bc01bb8ee870
js: add support for commonJS modules
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
471 #undef DUK__IDX_MODULE |