Node addon boilerplate. Calls a C function.
This commit is contained in:
commit
6bfd5c5b15
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
build/
|
6
binding.gyp
Normal file
6
binding.gyp
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"targets": [{
|
||||
"target_name": "hello",
|
||||
"sources": [ "./src/hello.c" ]
|
||||
}]
|
||||
}
|
279
hello.asm
Normal file
279
hello.asm
Normal file
@ -0,0 +1,279 @@
|
||||
|
||||
build/Release/hello.node: file format elf64-x86-64
|
||||
|
||||
|
||||
Disassembly of section .init:
|
||||
|
||||
00000000000007b8 <_init>:
|
||||
7b8: 48 83 ec 08 sub $0x8,%rsp
|
||||
7bc: 48 8b 05 2d 08 20 00 mov 0x20082d(%rip),%rax # 200ff0 <__gmon_start__>
|
||||
7c3: 48 85 c0 test %rax,%rax
|
||||
7c6: 74 02 je 7ca <_init+0x12>
|
||||
7c8: ff d0 callq *%rax
|
||||
7ca: 48 83 c4 08 add $0x8,%rsp
|
||||
7ce: c3 retq
|
||||
|
||||
Disassembly of section .plt:
|
||||
|
||||
00000000000007d0 <.plt>:
|
||||
7d0: ff 35 32 08 20 00 pushq 0x200832(%rip) # 201008 <_GLOBAL_OFFSET_TABLE_+0x8>
|
||||
7d6: ff 25 34 08 20 00 jmpq *0x200834(%rip) # 201010 <_GLOBAL_OFFSET_TABLE_+0x10>
|
||||
7dc: 0f 1f 40 00 nopl 0x0(%rax)
|
||||
|
||||
00000000000007e0 <napi_get_cb_info@plt>:
|
||||
7e0: ff 25 32 08 20 00 jmpq *0x200832(%rip) # 201018 <napi_get_cb_info>
|
||||
7e6: 68 00 00 00 00 pushq $0x0
|
||||
7eb: e9 e0 ff ff ff jmpq 7d0 <.plt>
|
||||
|
||||
00000000000007f0 <napi_set_named_property@plt>:
|
||||
7f0: ff 25 2a 08 20 00 jmpq *0x20082a(%rip) # 201020 <napi_set_named_property>
|
||||
7f6: 68 01 00 00 00 pushq $0x1
|
||||
7fb: e9 d0 ff ff ff jmpq 7d0 <.plt>
|
||||
|
||||
0000000000000800 <napi_module_register@plt>:
|
||||
800: ff 25 22 08 20 00 jmpq *0x200822(%rip) # 201028 <napi_module_register>
|
||||
806: 68 02 00 00 00 pushq $0x2
|
||||
80b: e9 c0 ff ff ff jmpq 7d0 <.plt>
|
||||
|
||||
0000000000000810 <napi_create_int32@plt>:
|
||||
810: ff 25 1a 08 20 00 jmpq *0x20081a(%rip) # 201030 <napi_create_int32>
|
||||
816: 68 03 00 00 00 pushq $0x3
|
||||
81b: e9 b0 ff ff ff jmpq 7d0 <.plt>
|
||||
|
||||
0000000000000820 <napi_get_value_int32@plt>:
|
||||
820: ff 25 12 08 20 00 jmpq *0x200812(%rip) # 201038 <napi_get_value_int32>
|
||||
826: 68 04 00 00 00 pushq $0x4
|
||||
82b: e9 a0 ff ff ff jmpq 7d0 <.plt>
|
||||
|
||||
0000000000000830 <napi_throw_error@plt>:
|
||||
830: ff 25 0a 08 20 00 jmpq *0x20080a(%rip) # 201040 <napi_throw_error>
|
||||
836: 68 05 00 00 00 pushq $0x5
|
||||
83b: e9 90 ff ff ff jmpq 7d0 <.plt>
|
||||
|
||||
0000000000000840 <napi_create_function@plt>:
|
||||
840: ff 25 02 08 20 00 jmpq *0x200802(%rip) # 201048 <napi_create_function>
|
||||
846: 68 06 00 00 00 pushq $0x6
|
||||
84b: e9 80 ff ff ff jmpq 7d0 <.plt>
|
||||
|
||||
Disassembly of section .plt.got:
|
||||
|
||||
0000000000000850 <.plt.got>:
|
||||
850: ff 25 7a 07 20 00 jmpq *0x20077a(%rip) # 200fd0 <__cxa_finalize@GLIBC_2.2.5>
|
||||
856: 66 90 xchg %ax,%ax
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0000000000000860 <_register_hello>:
|
||||
860: 55 push %rbp
|
||||
861: 48 8d 3d 18 08 20 00 lea 0x200818(%rip),%rdi # 201080 <_module>
|
||||
868: 48 89 e5 mov %rsp,%rbp
|
||||
86b: 5d pop %rbp
|
||||
86c: e9 8f ff ff ff jmpq 800 <napi_module_register@plt>
|
||||
871: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
|
||||
878: 00 00 00
|
||||
87b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
|
||||
|
||||
0000000000000880 <deregister_tm_clones>:
|
||||
880: 48 8d 3d 41 08 20 00 lea 0x200841(%rip),%rdi # 2010c8 <_edata>
|
||||
887: 48 8d 05 41 08 20 00 lea 0x200841(%rip),%rax # 2010cf <_edata+0x7>
|
||||
88e: 55 push %rbp
|
||||
88f: 48 29 f8 sub %rdi,%rax
|
||||
892: 48 89 e5 mov %rsp,%rbp
|
||||
895: 48 83 f8 0e cmp $0xe,%rax
|
||||
899: 76 15 jbe 8b0 <deregister_tm_clones+0x30>
|
||||
89b: 48 8b 05 46 07 20 00 mov 0x200746(%rip),%rax # 200fe8 <_ITM_deregisterTMCloneTable>
|
||||
8a2: 48 85 c0 test %rax,%rax
|
||||
8a5: 74 09 je 8b0 <deregister_tm_clones+0x30>
|
||||
8a7: 5d pop %rbp
|
||||
8a8: ff e0 jmpq *%rax
|
||||
8aa: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
|
||||
8b0: 5d pop %rbp
|
||||
8b1: c3 retq
|
||||
8b2: 0f 1f 40 00 nopl 0x0(%rax)
|
||||
8b6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
|
||||
8bd: 00 00 00
|
||||
|
||||
00000000000008c0 <register_tm_clones>:
|
||||
8c0: 48 8d 3d 01 08 20 00 lea 0x200801(%rip),%rdi # 2010c8 <_edata>
|
||||
8c7: 48 8d 35 fa 07 20 00 lea 0x2007fa(%rip),%rsi # 2010c8 <_edata>
|
||||
8ce: 55 push %rbp
|
||||
8cf: 48 29 fe sub %rdi,%rsi
|
||||
8d2: 48 89 e5 mov %rsp,%rbp
|
||||
8d5: 48 c1 fe 03 sar $0x3,%rsi
|
||||
8d9: 48 89 f0 mov %rsi,%rax
|
||||
8dc: 48 c1 e8 3f shr $0x3f,%rax
|
||||
8e0: 48 01 c6 add %rax,%rsi
|
||||
8e3: 48 d1 fe sar %rsi
|
||||
8e6: 74 18 je 900 <register_tm_clones+0x40>
|
||||
8e8: 48 8b 05 09 07 20 00 mov 0x200709(%rip),%rax # 200ff8 <_ITM_registerTMCloneTable>
|
||||
8ef: 48 85 c0 test %rax,%rax
|
||||
8f2: 74 0c je 900 <register_tm_clones+0x40>
|
||||
8f4: 5d pop %rbp
|
||||
8f5: ff e0 jmpq *%rax
|
||||
8f7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
|
||||
8fe: 00 00
|
||||
900: 5d pop %rbp
|
||||
901: c3 retq
|
||||
902: 0f 1f 40 00 nopl 0x0(%rax)
|
||||
906: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
|
||||
90d: 00 00 00
|
||||
|
||||
0000000000000910 <__do_global_dtors_aux>:
|
||||
910: 80 3d b1 07 20 00 00 cmpb $0x0,0x2007b1(%rip) # 2010c8 <_edata>
|
||||
917: 75 27 jne 940 <__do_global_dtors_aux+0x30>
|
||||
919: 48 83 3d af 06 20 00 cmpq $0x0,0x2006af(%rip) # 200fd0 <__cxa_finalize@GLIBC_2.2.5>
|
||||
920: 00
|
||||
921: 55 push %rbp
|
||||
922: 48 89 e5 mov %rsp,%rbp
|
||||
925: 74 0c je 933 <__do_global_dtors_aux+0x23>
|
||||
927: 48 8b 3d 32 07 20 00 mov 0x200732(%rip),%rdi # 201060 <__dso_handle>
|
||||
92e: e8 1d ff ff ff callq 850 <.plt.got>
|
||||
933: e8 48 ff ff ff callq 880 <deregister_tm_clones>
|
||||
938: 5d pop %rbp
|
||||
939: c6 05 88 07 20 00 01 movb $0x1,0x200788(%rip) # 2010c8 <_edata>
|
||||
940: f3 c3 repz retq
|
||||
942: 0f 1f 40 00 nopl 0x0(%rax)
|
||||
946: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
|
||||
94d: 00 00 00
|
||||
|
||||
0000000000000950 <frame_dummy>:
|
||||
950: 48 8d 3d 61 04 20 00 lea 0x200461(%rip),%rdi # 200db8 <__JCR_END__>
|
||||
957: 48 83 3f 00 cmpq $0x0,(%rdi)
|
||||
95b: 75 0b jne 968 <frame_dummy+0x18>
|
||||
95d: e9 5e ff ff ff jmpq 8c0 <register_tm_clones>
|
||||
962: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
|
||||
968: 48 8b 05 71 06 20 00 mov 0x200671(%rip),%rax # 200fe0 <_Jv_RegisterClasses>
|
||||
96f: 48 85 c0 test %rax,%rax
|
||||
972: 74 e9 je 95d <frame_dummy+0xd>
|
||||
974: 55 push %rbp
|
||||
975: 48 89 e5 mov %rsp,%rbp
|
||||
978: ff d0 callq *%rax
|
||||
97a: 5d pop %rbp
|
||||
97b: e9 40 ff ff ff jmpq 8c0 <register_tm_clones>
|
||||
|
||||
0000000000000980 <MyFunction>:
|
||||
980: 55 push %rbp
|
||||
981: 45 31 c9 xor %r9d,%r9d
|
||||
984: 45 31 c0 xor %r8d,%r8d
|
||||
987: 48 89 e5 mov %rsp,%rbp
|
||||
98a: 53 push %rbx
|
||||
98b: 48 89 fb mov %rdi,%rbx
|
||||
98e: 48 8d 4d e0 lea -0x20(%rbp),%rcx
|
||||
992: 48 8d 55 d8 lea -0x28(%rbp),%rdx
|
||||
996: 48 83 ec 28 sub $0x28,%rsp
|
||||
99a: 48 c7 45 d8 01 00 00 movq $0x1,-0x28(%rbp)
|
||||
9a1: 00
|
||||
9a2: c7 45 d4 00 00 00 00 movl $0x0,-0x2c(%rbp)
|
||||
9a9: e8 32 fe ff ff callq 7e0 <napi_get_cb_info@plt>
|
||||
9ae: 85 c0 test %eax,%eax
|
||||
9b0: 0f 85 c4 00 00 00 jne a7a <MyFunction+0xfa>
|
||||
9b6: 48 8b 75 e0 mov -0x20(%rbp),%rsi
|
||||
9ba: 48 8d 55 d4 lea -0x2c(%rbp),%rdx
|
||||
9be: 48 89 df mov %rbx,%rdi
|
||||
9c1: e8 5a fe ff ff callq 820 <napi_get_value_int32@plt>
|
||||
9c6: 85 c0 test %eax,%eax
|
||||
9c8: 0f 85 89 00 00 00 jne a57 <MyFunction+0xd7>
|
||||
9ce: 44 8b 5d d4 mov -0x2c(%rbp),%r11d
|
||||
9d2: 41 83 fb 01 cmp $0x1,%r11d
|
||||
9d6: 0f 8e 9a 00 00 00 jle a76 <MyFunction+0xf6>
|
||||
9dc: 41 83 eb 01 sub $0x1,%r11d
|
||||
9e0: 45 31 c9 xor %r9d,%r9d
|
||||
9e3: 31 f6 xor %esi,%esi
|
||||
9e5: 45 31 d2 xor %r10d,%r10d
|
||||
9e8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
|
||||
9ef: 00
|
||||
9f0: 41 83 f9 02 cmp $0x2,%r9d
|
||||
9f4: 41 8d 79 01 lea 0x1(%r9),%edi
|
||||
9f8: 41 b8 01 00 00 00 mov $0x1,%r8d
|
||||
9fe: b9 02 00 00 00 mov $0x2,%ecx
|
||||
a03: 76 1b jbe a20 <MyFunction+0xa0>
|
||||
a05: 0f 1f 00 nopl (%rax)
|
||||
a08: 89 f8 mov %edi,%eax
|
||||
a0a: 99 cltd
|
||||
a0b: f7 f9 idiv %ecx
|
||||
a0d: 85 d2 test %edx,%edx
|
||||
a0f: 45 0f 44 c2 cmove %r10d,%r8d
|
||||
a13: 83 c1 01 add $0x1,%ecx
|
||||
a16: 41 39 c9 cmp %ecx,%r9d
|
||||
a19: 75 ed jne a08 <MyFunction+0x88>
|
||||
a1b: 45 84 c0 test %r8b,%r8b
|
||||
a1e: 74 03 je a23 <MyFunction+0xa3>
|
||||
a20: 83 c6 01 add $0x1,%esi
|
||||
a23: 44 39 df cmp %r11d,%edi
|
||||
a26: 41 89 f9 mov %edi,%r9d
|
||||
a29: 75 c5 jne 9f0 <MyFunction+0x70>
|
||||
a2b: 48 8d 55 e8 lea -0x18(%rbp),%rdx
|
||||
a2f: 48 89 df mov %rbx,%rdi
|
||||
a32: e8 d9 fd ff ff callq 810 <napi_create_int32@plt>
|
||||
a37: 85 c0 test %eax,%eax
|
||||
a39: 74 11 je a4c <MyFunction+0xcc>
|
||||
a3b: 48 8d 15 f0 00 00 00 lea 0xf0(%rip),%rdx # b32 <_fini+0x26>
|
||||
a42: 31 f6 xor %esi,%esi
|
||||
a44: 48 89 df mov %rbx,%rdi
|
||||
a47: e8 e4 fd ff ff callq 830 <napi_throw_error@plt>
|
||||
a4c: 48 8b 45 e8 mov -0x18(%rbp),%rax
|
||||
a50: 48 83 c4 28 add $0x28,%rsp
|
||||
a54: 5b pop %rbx
|
||||
a55: 5d pop %rbp
|
||||
a56: c3 retq
|
||||
a57: 48 8d 15 32 01 00 00 lea 0x132(%rip),%rdx # b90 <_fini+0x84>
|
||||
a5e: 31 f6 xor %esi,%esi
|
||||
a60: 48 89 df mov %rbx,%rdi
|
||||
a63: e8 c8 fd ff ff callq 830 <napi_throw_error@plt>
|
||||
a68: 44 8b 5d d4 mov -0x2c(%rbp),%r11d
|
||||
a6c: 41 83 fb 01 cmp $0x1,%r11d
|
||||
a70: 0f 8f 66 ff ff ff jg 9dc <MyFunction+0x5c>
|
||||
a76: 31 f6 xor %esi,%esi
|
||||
a78: eb b1 jmp a2b <MyFunction+0xab>
|
||||
a7a: 48 8d 15 97 00 00 00 lea 0x97(%rip),%rdx # b18 <_fini+0xc>
|
||||
a81: 31 f6 xor %esi,%esi
|
||||
a83: 48 89 df mov %rbx,%rdi
|
||||
a86: e8 a5 fd ff ff callq 830 <napi_throw_error@plt>
|
||||
a8b: e9 26 ff ff ff jmpq 9b6 <MyFunction+0x36>
|
||||
|
||||
0000000000000a90 <Init>:
|
||||
a90: 55 push %rbp
|
||||
a91: 45 31 c0 xor %r8d,%r8d
|
||||
a94: 31 d2 xor %edx,%edx
|
||||
a96: 48 89 e5 mov %rsp,%rbp
|
||||
a99: 41 54 push %r12
|
||||
a9b: 53 push %rbx
|
||||
a9c: 4c 8d 4d e8 lea -0x18(%rbp),%r9
|
||||
aa0: 49 89 f4 mov %rsi,%r12
|
||||
aa3: 31 f6 xor %esi,%esi
|
||||
aa5: 48 83 ec 10 sub $0x10,%rsp
|
||||
aa9: 48 8b 0d 28 05 20 00 mov 0x200528(%rip),%rcx # 200fd8 <MyFunction@@Base+0x200658>
|
||||
ab0: 48 89 fb mov %rdi,%rbx
|
||||
ab3: e8 88 fd ff ff callq 840 <napi_create_function@plt>
|
||||
ab8: 85 c0 test %eax,%eax
|
||||
aba: 75 3c jne af8 <Init+0x68>
|
||||
abc: 48 8b 4d e8 mov -0x18(%rbp),%rcx
|
||||
ac0: 48 8d 15 89 00 00 00 lea 0x89(%rip),%rdx # b50 <_fini+0x44>
|
||||
ac7: 4c 89 e6 mov %r12,%rsi
|
||||
aca: 48 89 df mov %rbx,%rdi
|
||||
acd: e8 1e fd ff ff callq 7f0 <napi_set_named_property@plt>
|
||||
ad2: 85 c0 test %eax,%eax
|
||||
ad4: 74 11 je ae7 <Init+0x57>
|
||||
ad6: 48 8d 15 7f 00 00 00 lea 0x7f(%rip),%rdx # b5c <_fini+0x50>
|
||||
add: 31 f6 xor %esi,%esi
|
||||
adf: 48 89 df mov %rbx,%rdi
|
||||
ae2: e8 49 fd ff ff callq 830 <napi_throw_error@plt>
|
||||
ae7: 48 83 c4 10 add $0x10,%rsp
|
||||
aeb: 4c 89 e0 mov %r12,%rax
|
||||
aee: 5b pop %rbx
|
||||
aef: 41 5c pop %r12
|
||||
af1: 5d pop %rbp
|
||||
af2: c3 retq
|
||||
af3: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
|
||||
af8: 48 8d 15 b9 00 00 00 lea 0xb9(%rip),%rdx # bb8 <_fini+0xac>
|
||||
aff: 31 f6 xor %esi,%esi
|
||||
b01: 48 89 df mov %rbx,%rdi
|
||||
b04: e8 27 fd ff ff callq 830 <napi_throw_error@plt>
|
||||
b09: eb b1 jmp abc <Init+0x2c>
|
||||
|
||||
Disassembly of section .fini:
|
||||
|
||||
0000000000000b0c <_fini>:
|
||||
b0c: 48 83 ec 08 sub $0x8,%rsp
|
||||
b10: 48 83 c4 08 add $0x8,%rsp
|
||||
b14: c3 retq
|
34
hello.js
Normal file
34
hello.js
Normal file
@ -0,0 +1,34 @@
|
||||
const addon = require('./build/Release/hello');
|
||||
const COUNT = 10000;
|
||||
|
||||
const primes = count => {
|
||||
let total = 0;
|
||||
for (let i = 1; i < count; i++) {
|
||||
|
||||
let prime = true;
|
||||
for (let z = 2; z < i - 1; z++) {
|
||||
if (i % z === 0) prime = false;
|
||||
}
|
||||
|
||||
if (prime) total++;
|
||||
// if (prime === true) console.log(`${i} is prime`);
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
console.log('starting...');
|
||||
|
||||
(async () => {
|
||||
for (let a = 1; a < 10; a++) {
|
||||
|
||||
console.time(`primes (c${a})`);
|
||||
console.log(`total primes from 1 to ${COUNT} in c: ${await addon.my_function(COUNT)}`);
|
||||
console.timeEnd(`primes (c${a})`);
|
||||
|
||||
console.time(`primes (js${a})`);
|
||||
console.log(`total primes from 1 to ${COUNT} in js: ${primes(COUNT)}`);
|
||||
console.timeEnd(`primes (js${a})`);
|
||||
|
||||
}
|
||||
})();
|
14
package.json
Normal file
14
package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "hello",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"install": "node-gyp rebuild",
|
||||
"start": "node-gyp configure build && node --napi-modules hello.js"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"gypfile": true
|
||||
}
|
73
src/hello.c
Normal file
73
src/hello.c
Normal file
@ -0,0 +1,73 @@
|
||||
#include <stdio.h>
|
||||
#include <node_api.h>
|
||||
/* typedef enum { false, true } bool; */
|
||||
#include <stdbool.h>
|
||||
|
||||
napi_value MyFunction(napi_env env, napi_callback_info info) {
|
||||
napi_status status;
|
||||
size_t argc = 1;
|
||||
int COUNT = 0;
|
||||
napi_value argv[1];
|
||||
status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
||||
if (status != napi_ok) {
|
||||
napi_throw_error(env, NULL, "Failed to parse arguments");
|
||||
}
|
||||
|
||||
status = napi_get_value_int32(env, argv[0], &COUNT);
|
||||
if (status != napi_ok) {
|
||||
napi_throw_error(env, NULL, "Invalid number was passed as argument");
|
||||
}
|
||||
|
||||
napi_value Return;
|
||||
|
||||
int i, z, total = 0;
|
||||
|
||||
for (i = 1; i < COUNT; i++) {
|
||||
|
||||
bool prime = true;
|
||||
for (z = 2; z < i - 1; z++) {
|
||||
if (i % z == 0) prime = false;
|
||||
}
|
||||
if (prime == true) total++;
|
||||
|
||||
/* if (prime == true) printf("%d is prime\n", i); */
|
||||
}
|
||||
|
||||
status = napi_create_int32(env, total, &Return);
|
||||
if (status != napi_ok) {
|
||||
napi_throw_error(env, NULL, "Unable to create return value");
|
||||
}
|
||||
|
||||
return Return;
|
||||
}
|
||||
|
||||
napi_value Init(napi_env env, napi_value exports) {
|
||||
napi_status status;
|
||||
napi_value fn;
|
||||
|
||||
status = napi_create_function(env, NULL, 0, MyFunction, NULL, &fn);
|
||||
if (status != napi_ok) {
|
||||
napi_throw_error(env, NULL, "Unable to wrap native function");
|
||||
}
|
||||
|
||||
status = napi_set_named_property(env, exports, "my_function", fn);
|
||||
if (status != napi_ok) {
|
||||
napi_throw_error(env, NULL, "Unable to populate exports");
|
||||
}
|
||||
|
||||
return exports;
|
||||
}
|
||||
|
||||
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
|
||||
|
||||
/* int main() { */
|
||||
/* char *fruit = "apple"; */
|
||||
/* int quantity = 1; */
|
||||
|
||||
/* printf("Oh, hey, I have %d %s%s.", quantity, fruit, (quantity > 1 ? "s" : "")); */
|
||||
|
||||
|
||||
/* printf("\n"); */
|
||||
/* return 0; */
|
||||
/* } */
|
||||
|
Loading…
Reference in New Issue
Block a user