forked from svaarala/duktape
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest-dev-cmodule-guide.c
More file actions
162 lines (128 loc) · 3.46 KB
/
test-dev-cmodule-guide.c
File metadata and controls
162 lines (128 loc) · 3.46 KB
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
* Module example from guide, as a more concrete test case.
*/
/* Include duktape.h and whatever platform headers are needed. */
#include "duktape.h"
/* No longer applicable because module framework is no longer built in. */
/*---
{
"skip": true
}
---*/
static duk_ret_t my_print(duk_context *ctx) {
duk_push_string(ctx, " ");
duk_insert(ctx, 0);
duk_join(ctx, duk_get_top(ctx) - 1);
printf("%s\n", duk_safe_to_string(ctx, -1));
return 0;
}
/*
* Duktape/C functions providing module functionality.
*/
static duk_ret_t my_func_1(duk_context *ctx) {
printf("my_func_1() called\n");
return 0;
}
static duk_ret_t my_func_2(duk_context *ctx) {
printf("my_func_2() called\n");
return 0;
}
/*
* Module initialization
*/
static const duk_function_list_entry my_module_funcs[] = {
{ "func1", my_func_1, 3 /*nargs*/ },
{ "func2", my_func_2, DUK_VARARGS /*nargs*/ },
{ NULL, NULL, 0 }
};
static const duk_number_list_entry my_module_consts[] = {
{ "FLAG_FOO", (double) (1 << 0) },
{ NULL, 0.0 }
};
static duk_ret_t dukopen_my_module(duk_context *ctx) {
duk_push_object(ctx);
duk_put_function_list(ctx, -1, my_module_funcs);
duk_put_number_list(ctx, -1, my_module_consts);
return 1;
}
/*
* Calling code
*/
/*===
*** test_use_module (duk_safe_call)
my_func_2() called
final top: 0
==> rc=0, result='undefined'
===*/
static duk_ret_t test_use_module(duk_context *ignored_ctx, void *udata) {
duk_context *ctx;
(void) udata;
ctx = duk_create_heap_default();
if (!ctx) {
printf("Failed to create heap\n");
return 0;
}
duk_push_c_function(ctx, dukopen_my_module, 0);
duk_call(ctx, 0);
duk_put_global_string(ctx, "my_module");
duk_eval_string_noresult(ctx, "my_module.func2()");
printf("final top: %ld\n", (long) duk_get_top(ctx));
duk_destroy_heap(ctx);
return 0;
}
/*
* Example of how a modSearch() function can use module.exports to return
* the C module initialization value.
*/
/*===
*** test_modsearch_module (duk_safe_call)
1
my_func_1() called
final top: 0
==> rc=0, result='undefined'
===*/
static duk_ret_t my_modsearch(duk_context *ctx) {
/* Arguments: id, require, exports, module.
*
* The 'id' is ignored in this example, normally you'd use 'id' to
* select which module to initialize.
*/
/* Initialize the C module. */
duk_push_c_function(ctx, dukopen_my_module, 0);
duk_call(ctx, 0);
/* Result is now on stack top. Overwrite module.exports to make
* that value come out from require().
*/
/* [ id require exports module c_module ] */
duk_put_prop_string(ctx, 3 /*module*/, "exports"); /* module.exports = c_module; */
return 0; /* return undefined, no ECMAScript source code */
}
static duk_ret_t test_modsearch_module(duk_context *ignored_ctx, void *udata) {
duk_context *ctx;
(void) udata;
ctx = duk_create_heap_default();
if (!ctx) {
printf("Failed to create heap\n");
return 0;
}
/* Dummy print() binding. */
duk_push_c_function(ctx, my_print, 1);
duk_put_global_string(ctx, "print");
/* Register Duktape.modSearch. */
duk_eval_string(ctx, "(function (fun) { Duktape.modSearch = fun; })");
duk_push_c_function(ctx, my_modsearch, 4 /*nargs*/);
duk_call(ctx, 1);
duk_pop(ctx);
/* Require test. */
duk_eval_string_noresult(ctx, "var mod = require('my_module'); print(mod.FLAG_FOO); mod.func1();");
printf("final top: %ld\n", (long) duk_get_top(ctx));
duk_destroy_heap(ctx);
return 0;
}
/*
* Main
*/
void test(duk_context *ctx) {
TEST_SAFE_CALL(test_use_module);
TEST_SAFE_CALL(test_modsearch_module);
}