1 // Copyright 2017 The Emscripten Authors.  All rights reserved.
2 // Emscripten is available under two separate licenses, the MIT license and the
3 // University of Illinois/NCSA Open Source License.  Both these licenses can be
4 // found in the LICENSE file.
5 
6 #include <emscripten.h>
7 #include <stdio.h>
8 
main()9 int main()
10 {
11   printf("EM_ASM: Simple expression without trailing semicolon\n");
12   EM_ASM(console.log('1. expression without trailing semicolon'));
13   EM_ASM("console.log('2. expression without trailing semicolon')");
14   EM_ASM({"console.log('3. expression without trailing semicolon')"});
15   EM_ASM({console.log('4. expression without trailing semicolon')});
16   EM_ASM("{console.log('5. expression without trailing semicolon')}");
17 
18   printf("\nEM_ASM: Double quotes\n");
19   EM_ASM(console.log("1. string in double quotes"));
20   EM_ASM("console.log(\"2. string in double quotes\")");
21   EM_ASM({"console.log(\"3. string in double quotes\")"});
22   EM_ASM({console.log("4. string in double quotes")});
23   EM_ASM("{console.log(\"5. string in double quotes\")}");
24 
25   printf("\nEM_ASM: Double quotes inside a string\n");
26   EM_ASM(console.log('1. this is \"double\" \"quotes\"'));
27   EM_ASM(console.log('2. this is "double" "quotes" without escaping'));
28   EM_ASM("console.log('3. this is \"double\" \"quotes\"')");
29   EM_ASM({"console.log('4. this is \"double\" \"quotes\"')"});
30   EM_ASM({console.log('5. this is \"double\" \"quotes\"')});
31   EM_ASM({console.log('6. this is "double" "quotes" without esacping')});
32   EM_ASM("{console.log('7. this is \"double\" \"quotes\"')}");
33 
34   printf("\nEM_ASM: Pass a string\n");
35   EM_ASM(console.log('1. hello ' + UTF8ToString($0)), "world!");
36   EM_ASM("console.log('2. hello ' + UTF8ToString($0))", "world!");
37   EM_ASM({"console.log('3. hello ' + UTF8ToString($0))"}, "world!");
38   EM_ASM({console.log('4. hello ' + UTF8ToString($0))}, "world!");
39   EM_ASM("{console.log('5. hello ' + UTF8ToString($0))}", "world!");
40 
41   printf("\nEM_ASM: Simple expression without trailing semicolon, wrap code block in extra parentheses\n");
42   EM_ASM((console.log('1. expression without trailing semicolon, in parentheses')));
43   EM_ASM(("console.log('2. expression without trailing semicolon, in parentheses')"));
44   EM_ASM(({"console.log('3. expression without trailing semicolon, in parentheses')"}));
45   EM_ASM(({console.log('4. expression without trailing semicolon, in parentheses')}));
46   EM_ASM(("{console.log('5. expression without trailing semicolon, in parentheses')}"));
47 
48   printf("\nEM_ASM: Two statements, separated with a semicolon\n");
49   EM_ASM(console.log('1. two'); console.log('1. statements'););
50   EM_ASM("console.log('2. two'); console.log('2. statements 2');");
51   EM_ASM({"console.log('3. two'); console.log('3. statements 3');"});
52   EM_ASM({console.log('4. two'); console.log('4. statements 4');});
53   EM_ASM("{console.log('5. two'); console.log('5. statements 5');}");
54 
55   printf("\nEM_ASM: Pass an integer\n");
56   EM_ASM(console.log('1. int ' + $0), 42);
57   EM_ASM("console.log('2. int ' + $0)", 43);
58   EM_ASM({"console.log('3. int ' + $0)"}, 44);
59   EM_ASM({console.log('4. int ' + $0)}, 45);
60   EM_ASM("{console.log('5. int ' + $0)}", 46);
61 
62   printf("\nEM_ASM: Evaluate an anonymous function\n");
63   EM_ASM((function() {console.log('1. evaluating anonymous function ' + $0)})(), 42);
64   EM_ASM("(function() {console.log('2. evaluating anonymous function ' + $0)})()", 42);
65   EM_ASM({"(function() {console.log('3. evaluating anonymous function ' + $0)})()"}, 42);
66   EM_ASM({(function() {console.log('4. evaluating anonymous function ' + $0)})()}, 42);
67   EM_ASM("{(function() {console.log('5. evaluating anonymous function ' + $0)})()}", 42);
68 
69   printf("\nEM_ASM: Pass an integer and a double\n");
70   EM_ASM(console.log('1. int and double ' + $0 + ' ' + $1), 42, 43.5);
71   EM_ASM("console.log('2. int and double ' + $0 + ' ' + $1)", 42, 43.5);
72   EM_ASM({"console.log('3. int and double ' + $0 + ' ' + $1)"}, 42, 43.5);
73   EM_ASM({console.log('4. int and double ' + $0 + ' ' + $1)}, 42, 43.5);
74   EM_ASM("{console.log('5. int and double ' + $0 + ' ' + $1)}", 42, 43.5);
75 
76   int i;
77 
78   printf("\nEM_ASM_INT: Pass an integer, return an integer back\n");
79   i = EM_ASM_INT(console.log('1. got int ' + $0); return 3.5;, 42); printf("1. returned int %d\n", i);
80   i = EM_ASM_INT("console.log('2. got int ' + $0); return 4.5;", 42); printf("2. returned int %d\n", i);
81   i = EM_ASM_INT({"console.log('3. got int ' + $0); return 5.5;"}, 42); printf("3. returned int %d\n", i);
82   i = EM_ASM_INT({console.log('4. got int ' + $0); return 6.5;}, 42); printf("4. returned int %d\n", i);
83   i = EM_ASM_INT("{console.log('5. got int ' + $0); return 7.5;}", 42); printf("5. returned int %d\n", i);
84 
85   printf("\nEM_ASM_INT: Pass an integer, return an integer back, wrap code block in extra parentheses\n");
86   i = EM_ASM_INT((console.log('1. got int, extra parentheses ' + $0); return 3.5;), 42); printf("1. returned int, extra parentheses %d\n", i);
87   i = EM_ASM_INT(("console.log('2. got int, extra parentheses ' + $0); return 4.5;"), 42); printf("2. returned int, extra parentheses %d\n", i);
88   i = EM_ASM_INT(({"console.log('3. got int, extra parentheses ' + $0); return 5.5;"}), 42); printf("3. returned int, extra parentheses %d\n", i);
89   i = EM_ASM_INT(({console.log('4. got int, extra parentheses ' + $0); return 6.5;}), 42); printf("4. returned int, extra parentheses %d\n", i);
90   i = EM_ASM_INT(("{console.log('5. got int, extra parentheses ' + $0); return 7.5;}"), 42); printf("5. returned int, extra parentheses %d\n", i);
91 
92   printf("\nEM_ASM_INT: More imaginable ways for user to wrap in extra parentheses\n");
93   i = EM_ASM_INT({("console.log('1. got int, extra extra parentheses ' + $0); return 5.5;")}, 42); printf("1. returned int, extra extra parentheses %d\n", i);
94   i = EM_ASM_INT({(console.log('2. got int, extra extra parentheses ' + $0); return 6.5;)}, 42); printf("2. returned int, extra extra parentheses %d\n", i);
95   i = EM_ASM_INT(((((((((((console.log('3. got int, extra extra extra parentheses ' + $0); return 6.5;)))))))))), 42); printf("3. returned int, extra extra extra parentheses %d\n", i);
96 
97   printf("\nEM_ASM_INT: Return an integer back.\n");
98   i = EM_ASM_INT(console.log('1. got int ' + $0); return 3.5;, 42); printf("1. returned int %d\n", i);
99   i = EM_ASM_INT("console.log('2. got int ' + $0); return 4.5;", 42); printf("2. returned int %d\n", i);
100   i = EM_ASM_INT({"console.log('3. got int ' + $0); return 5.5;"}, 42); printf("3. returned int %d\n", i);
101   i = EM_ASM_INT({console.log('4. got int ' + $0); return 6.5;}, 42); printf("4. returned int %d\n", i);
102   i = EM_ASM_INT("{console.log('5. got int ' + $0); return 7.5;}", 42); printf("5. returned int %d\n", i);
103 
104   printf("\nEM_ASM_INT: Return an integer in a single brief statement.\n");
105   i = EM_ASM_INT(return HEAP8.length); printf("1. returned statement %d\n", i);
106   i = EM_ASM_INT("return HEAP8.length+1"); printf("2. returned statement %d\n", i);
107   i = EM_ASM_INT({"return HEAP8.length+2"}); printf("3. returned statement %d\n", i);
108   i = EM_ASM_INT({return HEAP8.length+3}); printf("4. returned statement %d\n", i);
109   i = EM_ASM_INT("return HEAP8.length+4"); printf("5. returned statement %d\n", i);
110 
111   // Note that expressions do not evaluate to return values, but the "return" keyword is needed. That is, the following line would return undefined and store i <- 0.
112   // i = EM_ASM_INT(HEAP8.length); printf("returned statement %d\n", i);
113 
114   double d;
115 
116   printf("\nEM_ASM_DOUBLE: Pass no parameters, return a double.\n");
117   d = EM_ASM_DOUBLE(console.log('1. returning double'); return 3.5;); printf("1. got double %f\n", d);
118   d = EM_ASM_DOUBLE("console.log('2. returning double'); return 4.5;"); printf("2. got double %f\n", d);
119   d = EM_ASM_DOUBLE({"console.log('3. returning double'); return 5.5;"}); printf("3. got double %f\n", d);
120   d = EM_ASM_DOUBLE({console.log('4. returning double'); return 6.5;}); printf("4. got double %f\n", d);
121   d = EM_ASM_DOUBLE("{console.log('5. returning double'); return 7.5;}"); printf("5. got double %f\n", d);
122 
123   printf("\nEM_ASM_DOUBLE: Pass an integer, return a double.\n");
124   d = EM_ASM_DOUBLE(console.log('1. got int ' + $0); return 3.5;, 42); printf("1. returned double %f\n", d);
125   d = EM_ASM_DOUBLE("console.log('2. got int ' + $0); return 4.5;", 42); printf("2. returned double %f\n", d);
126   d = EM_ASM_DOUBLE({"console.log('3. got int ' + $0); return 5.5;"}, 42); printf("3. returned double %f\n", d);
127   d = EM_ASM_DOUBLE({console.log('4. got int ' + $0); return 6.5;}, 42); printf("4. returned double %f\n", d);
128   d = EM_ASM_DOUBLE("{console.log('5. got int ' + $0); return 7.5;}", 42); printf("5. returned double %f\n", d);
129 
130   printf("\nEM_ASM_DOUBLE: Pass a double and an integer, return a double.\n");
131   d = EM_ASM_DOUBLE(console.log('1. got double and int ' + $0 + ' ' + $1); return 3.5;, 5.5, 42); printf("1. returned double %f\n", d);
132   d = EM_ASM_DOUBLE("console.log('2. got double and int ' + $0 + ' ' + $1); return 4.5;", 5.5, 42); printf("2. returned double %f\n", d);
133   d = EM_ASM_DOUBLE({"console.log('3. got double and int ' + $0 + ' ' + $1); return 5.5;"}, 5.5, 42); printf("3. returned double %f\n", d);
134   d = EM_ASM_DOUBLE({console.log('4. got double and int ' + $0 + ' ' + $1); return 6.5;}, 5.5, 42); printf("4. returned double %f\n", d);
135   d = EM_ASM_DOUBLE("{console.log('5. got double and int ' + $0 + ' ' + $1); return 7.5;}", 5.5, 42); printf("5. returned double %f\n", d);
136 
137   printf("\nEM_ASM_INT: A comma character (,) inside the code block may need extra parentheses\n");
138 // i = EM_ASM_INT(console.log('1. comma in em_asm'); var foo = { a: 5, b: $0 }; return foo.a + foo.b, 10); printf("1. returned %d\n", i); // This would not compile: use of undeclared identifier 'b'
139   i = EM_ASM_INT((console.log('1. comma in em_asm'); var foo = { a: 5, b: $0 }; return foo.a + foo.b), 10); printf("1. returned %d\n", i); // However by wrapping the code block inside parentheses, it will be ok
140   i = EM_ASM_INT("console.log('2. comma in em_asm'); var foo = { a: 5, b: $0 }; return foo.a + foo.b", 10); printf("2. returned %d\n", i);
141   i = EM_ASM_INT({"console.log('3. comma in em_asm'); var foo = { a: 5, b: $0 }; return foo.a + foo.b"}, 10); printf("3. returned %d\n", i);
142 // i = EM_ASM_INT({console.log('4. comma in em_asm'); var foo = { a: 5, b: $0 }; return foo.a + foo.b}, 10); printf("4. returned %d\n", i); // This would also not compile: use of undeclared identifier 'b'
143   i = EM_ASM_INT(({console.log('4. comma in em_asm'); var foo = { a: 5, b: $0 }; return foo.a + foo.b}), 10); printf("4. returned %d\n", i); // Again by wrapping the code block inside parentheses, it will work
144   i = EM_ASM_INT("{console.log('5. comma in em_asm'); var foo = { a: 5, b: $0 }; return foo.a + foo.b}", 10); printf("5. returned %d\n", i);
145 
146   printf("\nEM_ASM: Expression contains a tab character\n");
147   EM_ASM(console.log('1. the following word is delimited by tab characters: H\tE\tL\tL\tO\tT\tA\tB\tS'));
148   EM_ASM("console.log('2. the following word is delimited by tab characters: H\tE\tL\tL\tO\tT\tA\tB\tS')");
149   EM_ASM({"console.log('3. the following word is delimited by tab characters: H\tE\tL\tL\tO\tT\tA\tB\tS')"});
150   EM_ASM({console.log('4. the following word is delimited by tab characters: H\tE\tL\tL\tO\tT\tA\tB\tS')});
151   EM_ASM("{console.log('5. the following word is delimited by tab characters: H\tE\tL\tL\tO\tT\tA\tB\tS')}");
152 }
153