This file is indexed.

/usr/include/spl.h is in spl-dev 1.0~pre6-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
/*
 *  SPL - The SPL Programming Language
 *  Copyright (C) 2004, 2005  Clifford Wolf <clifford@clifford.at>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  spl.h: Everything you need to embed SPL in your programs is here.
 */

#ifndef SPL_H
#define SPL_H

#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>

#ifdef  __cplusplus
extern "C" {
#endif

/* Signature for SPL bytecode and dump files */
// ---------------------- 0123456789abcdef
#define SPL_SIGNATURE "\374SPL-BytecodeV2"

/* Checksum of this header for ABI checksum */
#define SPL_ABICKSUM 2414976518
#define SPL_ABI(sym) (SPL_ABI_2414976518_ ## sym)

struct spl_string {
	struct spl_string *left, *right;
	unsigned int left_offset, left_len;
	unsigned int right_offset, right_len;
	struct spl_code *code;
	char *text;
	int ref_counter, flags;
	unsigned int text_len, total_len;
};

#define SPL_STRING_STATIC	0x0001
#define SPL_STRING_DOTCAT	0x0002
#define SPL_STRING_UTF8		0x0004

#define SPL_STRING_NOAUTOGET	0x0100

struct spl_node {
	struct spl_node *ctx, *cls;
	struct spl_node *gc_left, *gc_right;
	struct spl_node_sub *subs_begin;
	struct spl_node_sub *subs_end;
	struct spl_node_sub **subs_hash;
	int subs_counter;
	int subs_hash_size;
	int subs_next_idx;
	struct spl_code *code;
	int code_ip;
	int ctx_type;
	int ref_counter;
	int dump_tag;
	int value;
	struct spl_string *value_string;
	int value_int;
	double value_float;
	char *hnode_name;
	void *hnode_data;
	char *hnode_dump;
	int flags;
	char *path;
	int path_metric;
	struct spl_node *path_parent;
};

#define SPL_VALUE_STRING	0x01
#define SPL_VALUE_INT		0x02
#define SPL_VALUE_FLOAT		0x04

struct spl_node_sub {
	struct spl_node_sub *last;
	struct spl_node_sub *next;
	struct spl_node_sub *hash_next;
	struct spl_node *node;
	char *module, *key;
};

/* There are three different context types in SPL. */
/* Don't think about it - usually it just does what you would expect. */

/* Lookups go thru, Creates only stop here if new or declared local */
#define SPL_CTX_FUNCTION 1
#define SPL_CTX_OBJECT 2

/* Only stop if keyword is already defined or declared local */
#define SPL_CTX_LOCAL 3

/* Always stop here (automatically, because there is no next ctx) */
#define SPL_CTX_ROOT 4

#define SPL_NODE_FLAG_FUNCTION	0x00001
#define SPL_NODE_FLAG_METHOD	0x00002
#define SPL_NODE_FLAG_RETINFO	0x00004
#define SPL_NODE_FLAG_STATIC	0x00008
#define SPL_NODE_FLAG_CLASS	0x00010
#define SPL_NODE_FLAG_CLNULL	0x00020
#define SPL_NODE_FLAG_CLEXCEPT	0x00040
#define SPL_NODE_FLAG_EXCEPTION	0x00080
#define SPL_NODE_FLAG_TRY	0x00100
#define SPL_NODE_FLAG_CATCH	0x00200
#define SPL_NODE_FLAG_RERES	0x00400
#define SPL_NODE_FLAG_ARGC	0x00800
#define SPL_NODE_FLAG_IS_INT	0x01000
#define SPL_NODE_FLAG_IS_FLOAT	0x02000

#define SPL_NODE_FLAG_GC	0x10000

struct spl_node_stack {
	struct spl_node *node;
	struct spl_node_stack *next;
};

struct spl_task {
	char *id;
	struct spl_task *next;
	struct spl_node_stack *stack;
	struct spl_node_stack *cleanup;
	struct spl_node *ctx;
	struct spl_code *code;
	struct spl_vm *vm;
	char *debug_str;
	char *module;
	int code_ip;
	int debug;
	int dump_tag;
	int flags;
	int goterr;
};

#define SPL_TASK_FLAG_SYSTEM	0x0001
#define SPL_TASK_FLAG_PAUSED	0x0002
#define SPL_TASK_FLAG_ZOMBIE	0x0004
#define SPL_TASK_FLAG_PUBLIC	0x0008
#define SPL_TASK_FLAG_BUSY	0x0010

typedef int spl_runloop_function(struct spl_vm *vm, struct spl_task *wait_task);

typedef struct spl_node *spl_clib_function(struct spl_task *task, void *data);

struct spl_clib {
	struct spl_clib *next;
	spl_clib_function *handler;
	void *data;
	char *name;
};

struct spl_hnode_args {
	int action;
	const char *key;
	int flags;
	struct spl_node *value;
};

#define SPL_HNODE_ACTION_LOOKUP	0x1
#define SPL_HNODE_ACTION_CREATE	0x2
#define SPL_HNODE_ACTION_DELETE	0x3
#define SPL_HNODE_ACTION_NEXT	0x4
#define SPL_HNODE_ACTION_PREV	0x5
#define SPL_HNODE_ACTION_COPY	0x6
#define SPL_HNODE_ACTION_PUT	0x7
#define SPL_HNODE_ACTION_DUMP	0x8

typedef void spl_hnode_function(struct spl_task *task, struct spl_vm *vm,
		struct spl_node *node, struct spl_hnode_args *args, void *data);

struct spl_hnode {
	struct spl_hnode *next;
	spl_hnode_function *handler;
	void *data;
	char *name;
};

struct spl_module;
typedef void spl_module_init_func(struct spl_vm *vm, struct spl_module *mod, int restore);
typedef void spl_module_done_func(struct spl_vm *vm, struct spl_module *mod);

struct spl_module {
	struct spl_module *next;
	spl_module_done_func *donefunc;
	void *dlhandle;
	void *data;
	char *name;
};

struct spl_builtin_module {
	struct spl_builtin_module *next;
	spl_module_init_func *initfunc;
	spl_module_done_func *donefunc;
	char *name;
};

extern struct spl_builtin_module *spl_builtin_module_list;

#define SPL_REGISTER_BUILTIN_MODULE(mod)				\
	do {								\
		extern spl_module_init_func SPL_ABI(spl_mod_ ## mod ## _init);	\
		extern spl_module_done_func SPL_ABI(spl_mod_ ## mod ## _done);	\
		struct spl_builtin_module *m =				\
			malloc(sizeof(struct spl_builtin_module));	\
		m->next = spl_builtin_module_list;			\
		m->initfunc = SPL_ABI(spl_mod_ ## mod ## _init);	\
		m->donefunc = SPL_ABI(spl_mod_ ## mod ## _done);	\
		m->name = #mod;						\
		spl_builtin_module_list = m;				\
	} while (0)

#define SPL_FREE_BUILTIN_MODULES()					\
	do {								\
		struct spl_builtin_module *m;				\
		while (spl_builtin_module_list) {			\
			m = spl_builtin_module_list->next;		\
			free(spl_builtin_module_list);			\
			spl_builtin_module_list = m;			\
		}							\
	} while (0)

struct spl_vm {
	struct spl_node *root;
	struct spl_node *gc_list;
	struct spl_task *task_list;
	struct spl_clib **clib_hash;
	int clib_hash_size;
	int clib_hash_count;
	struct spl_hnode *hnode_list;
	struct spl_module *module_list;
	int gc_last_ic, ic;
	int gc_last_treesize;
	int gc_last_allsize;
	struct spl_node_stack *free_node_stack_elements;

	spl_runloop_function *runloop;
	int destroy_in_progress;

	int undumpable;
	const char *undumpable_info;
	int undumpable_info_counter;

	/* the following stuff must be provided by the
	 * host application but is free'd automatically
	 * by spl_vm_destroy().
	 */
	char *current_dir_name;
	char *codecache_dir;
	char *path;

	/* the following stuff must be provided and
	 * managed by the host application or modules
	 */
	struct cgi_context *cgi_ctx;
	struct sql_backend *sql_backends;
	int sdl_initialized;
};

struct spl_code {
	char *id, *sha1;
	int size;
	unsigned char *code;
	int code_type;
	int ref_counter;
	int dump_tag;
};

#define SPL_CODE_STATIC   1
#define SPL_CODE_MALLOCED 2
#define SPL_CODE_MAPPED   3

struct spl_asm_label {
	struct spl_asm_label *next;
	int ref[1024], refc;
	int position;
	char *name;
};

struct spl_asm {
	unsigned char *text;
	char *data;
	int text_size_roof, text_size;
	int data_size_roof, data_size;
	struct spl_asm_label *labels;
	struct spl_vm *vm;
};


/* state.c functions */

extern struct spl_vm *spl_vm_create(void);
extern void spl_vm_destroy(struct spl_vm *vm);
extern struct spl_node_stack *spl_vm_malloc_node_stack_element(struct spl_vm *vm);
extern void spl_vm_free_node_stack_element(struct spl_vm *vm, struct spl_node_stack * const n);

extern void spl_undumpable_inc(struct spl_vm *vm, const char *info);
extern void spl_undumpable_dec(struct spl_vm *vm, const char *info);

extern struct spl_code *spl_code_get(struct spl_code *code);
extern void spl_code_put(struct spl_code *code);
extern const char *spl_code_sha1(struct spl_code *code);

unsigned int spl_subs_hash(const char *key, int max_hash);

extern struct spl_task *spl_task_lookup(struct spl_vm *vm, const char *id);
extern struct spl_task *spl_task_create(struct spl_vm *vm, const char *id);
extern void spl_task_destroy(struct spl_vm *vm, struct spl_task *task);
extern void spl_task_setcode(struct spl_task *task, struct spl_code *code);

extern void spl_subs_hash_check(struct spl_node *node);
extern struct spl_node_sub *spl_sub_lookup(struct spl_node *node, const char *key);

extern struct spl_node *spl_lookup(struct spl_task *task, struct spl_node *node, const char *key, int flags);
extern struct spl_node *spl_create(struct spl_task *task, struct spl_node *node, const char *key, struct spl_node *newnode, int flags);
extern void spl_delete(struct spl_task *task, struct spl_node *node, const char *key);

#define SPL_LOOKUP_TEST		0x0001
#define SPL_LOOKUP_NOCTX	0x0002
#define SPL_LOOKUP_CLS		0x0004
#define SPL_LOOKUP_NOSTATIC	0x0010

#define SPL_CREATE_LOCAL	0x0100
#define SPL_CREATE_BEGIN	0x0200
#define SPL_CREATE_NOSTATIC	0x0400
#define SPL_CREATE_FUNCLOCAL	0x1000

#define SPL_TYPE_NONE	0x00
#define SPL_TYPE_INT	0x01
#define SPL_TYPE_FLOAT	0x02
#define SPL_TYPE_OBJ	0x03

extern int spl_get_int(struct spl_node *node);
extern double spl_get_float(struct spl_node *node);
extern char *spl_get_string(struct spl_node *node);
extern struct spl_string *spl_get_spl_string(struct spl_node *node);
extern char *spl_get_value(struct spl_node *node);
extern int spl_get_type(struct spl_node *node);

extern struct spl_node *spl_set_int(struct spl_node *node, int value);
extern struct spl_node *spl_set_float(struct spl_node *node, double value);
extern struct spl_node *spl_set_string(struct spl_node *node, char *value);
extern struct spl_node *spl_set_spl_string(struct spl_node *node, struct spl_string *value);

extern struct spl_node *spl_push(struct spl_task *task, struct spl_node *node);
extern struct spl_node *spl_pop(struct spl_task *task);
extern struct spl_node *spl_tos(struct spl_task *task);

extern struct spl_node *spl_get(struct spl_node *node);
extern void spl_put(struct spl_vm *vm, struct spl_node *node);
extern struct spl_node *spl_cleanup(struct spl_task *task, struct spl_node *node);
extern struct spl_node *spl_copy(struct spl_vm *vm, struct spl_node *node, struct spl_node *cls);

extern char *spl_hash_encode(const char *source);
extern char *spl_hash_decode(const char *source);

/* state.c gc debugging counter */

extern void spl_state_counter_malloc_inc();
extern int spl_state_counter_malloc_get();

extern void spl_state_counter_free_inc();
extern int spl_state_counter_free_get();

/* report.c functions */

typedef void spl_report_func(int type, void *desc, const char *fmt, ...)
	__attribute__ ((format (printf, 3, 4)));

extern spl_report_func *spl_report;

extern void spl_set_report_func(spl_report_func *f);

#define SPL_REPORT_HOST		0x0001	// desc = spl_vm
#define SPL_REPORT_ASSEMBLER	0x0002  // desc = spl_asm
#define SPL_REPORT_COMPILER	0x0003	// desc = spl_asm
#define SPL_REPORT_LEXER	0x0004	// desc = spl_asm
#define SPL_REPORT_RUNTIME	0x0005	// desc = spl_task
#define SPL_REPORT_RESTORE	0x0006	// desc = spl_vm

#define SPL_REPORT_WARNING	0x0010
#define SPL_REPORT_DEBUG	0x0020

extern char *spl_report_type2txt(int type);

extern void spl_report_file(FILE *f, int type, void *desc, const char *fmt, va_list ap)
	__attribute__ ((format (printf, 4, 0)));

extern char *spl_report_string(int type, void *desc, const char *fmt, va_list ap)
	__attribute__ ((format (printf, 3, 0)));

extern void spl_report_func_stderr(int type, void *desc, const char *fmt, ...)
	__attribute__ ((format (printf, 3, 4)));
extern void spl_report_func_stdout(int type, void *desc, const char *fmt, ...)
	__attribute__ ((format (printf, 3, 4)));

/* some macros and inline functions */
#define SPL_NEW_INT(__v)        spl_set_int(spl_get(0), (__v))
#define SPL_NEW_FLOAT(__v)      spl_set_float(spl_get(0), (__v))
#define SPL_NEW_SPL_STRING(__v) spl_set_spl_string(spl_get(0), (__v))
#define SPL_NEW_STRING(__v)     spl_set_string(spl_get(0), (__v))
#define SPL_NEW_STRING_DUP(__v) spl_set_string(spl_get(0), strdup(__v))

#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#  define SPL_NEW_PRINTF(...) \
	(SPL_NEW_SPL_STRING(spl_string_printf(0, 0, 0, ## __VA_ARGS__)))
#endif

#define SPL_POP_CLEANUP(__t) \
	spl_cleanup(__t, spl_pop(__t))

/* moddir.c function */

extern const char *spl_system_modules_dir(void);

/* exec.c function */

extern int spl_exec(struct spl_task *task);

/* gc.c function */

extern int spl_gc(struct spl_vm *vm);
extern int spl_gc_maybe(struct spl_vm *vm);

/* spl_op.c functions */

struct spl_asm_op {
	const char * const name;
	const unsigned char op;
	const char          optype;
};
extern const struct spl_asm_op spl_ops[];

/* asm.c functions */

static inline void spl_int_to_bytes(int value, int c, unsigned char *pos)
{
	while (c-->0) {
		*(pos+c) = value & 0xff;
		value = value >> 8;
	}
}

static inline int spl_bytes_to_int(int c, const unsigned char *pos)
{
	int value = *pos >= 0x80 ? ~0 : 0;
	while (c-->0)
		value = value << 8 | *(pos++);
	return value;
}

extern struct spl_asm *spl_asm_create(void);
extern void spl_asm_destroy(struct spl_asm *as);
extern int spl_asm_newdata(struct spl_asm *as, const char *arg);
extern int spl_asm_add(struct spl_asm *as, unsigned char op, const char *arg);
extern void spl_asm_setaddr(struct spl_asm *as, int pos, int addr);
extern int spl_asm_write(struct spl_asm *as, int fd);
extern struct spl_code *spl_asm_dump(struct spl_asm *as);

extern const char *spl_asm_op2txt(int op);
extern int spl_asm_txt2op(const char *txt);
extern void spl_asm_print(struct spl_asm *as, int print_data_seg);

/* va_args: [ int size, int from_pos, int to_pos, [...] ], -1 */
extern void spl_asm_shuffle(struct spl_asm *as, ...);

extern int spl_asm_setlabel(struct spl_asm *as, char *label, int pos);
extern void spl_asm_reflabel(struct spl_asm *as, char *label, int pos);
extern int spl_asm_resolve_labels(struct spl_asm *as);

extern int spl_asm_parse_line(struct spl_asm *as, const char *line);

/* optimizer.c function */

extern int spl_optype(int opcode);
extern void spl_optimizer(struct spl_asm *as);

/* compiler.y function */

extern int spl_yydebug;
extern int spl_dump_translatable_strings;

typedef void *spl_malloc_file_function(const char *filename, int *size);
extern int spl_compiler(struct spl_asm *a, const char *prog, const char *name, spl_malloc_file_function *malloc_file_func, int gen_debug_info);

/* treedump.c functions */

extern void spl_treedump(struct spl_vm *vm, FILE *file, int flags, const char *prefix);
extern char *spl_treedump_string(struct spl_vm *vm, int flags, const char *prefix);

#define SPL_TREEDUMP_FLAG_ALL ~0

#define SPL_TREEDUMP_FLAG_ADDR		0x0001
#define SPL_TREEDUMP_FLAG_VALUE		0x0002
#define SPL_TREEDUMP_FLAG_CTX		0x0004
#define SPL_TREEDUMP_FLAG_CLS		0x0008
#define SPL_TREEDUMP_FLAG_LINK		0x0010
#define SPL_TREEDUMP_FLAG_MODS		0x0020
#define SPL_TREEDUMP_FLAG_TASKS		0x0040
#define SPL_TREEDUMP_FLAG_FLAGS		0x0080
#define SPL_TREEDUMP_FLAG_CTXTYPE	0x0100
#define SPL_TREEDUMP_FLAG_HNODE		0x0200

extern void spl_backtrace(struct spl_task *task, FILE *file);
extern char *spl_backtrace_string(struct spl_task *task);

/* debug.c function */

extern void spl_debug_reset(void);
extern int spl_debug_exec(struct spl_task *task);

/* rccheck.c function */

extern void spl_rccheck(struct spl_vm *vm);

/* dump.c function */

extern int spl_dump_ascii(struct spl_vm *vm, FILE *file);

/* restore.c function */

extern struct spl_vm* spl_restore_ascii(struct spl_vm*, FILE *file);

/* clib.c functions */

extern void spl_clib_reg(struct spl_vm *vm, const char *name, spl_clib_function *handler, void *data);
extern int spl_clib_call(struct spl_task *task, const char *name);
extern int spl_clib_check(struct spl_vm *vm, const char *unparsed_name);

extern int spl_clib_get_argc(struct spl_task *task);
extern struct spl_node *spl_clib_get_hargs(struct spl_task *task);
extern struct spl_node *spl_clib_get_node(struct spl_task *task);
extern int spl_clib_get_int(struct spl_task *task);
extern double spl_clib_get_float(struct spl_task *task);
extern char *spl_clib_get_string(struct spl_task *task);

// vaargs: [ const char *member_name, struct spl_node *member, [ .. ] ], NULL
extern struct spl_node *spl_clib_new(struct spl_task *task, const char *classname, ...);
extern void spl_clib_exception(struct spl_task *task, const char *classname, ...);

extern struct spl_task *spl_clib_callback_task(struct spl_vm *vm);
extern int spl_clib_callback_run(struct spl_task *task);

extern int spl_module_load(struct spl_vm *vm, const char *name, int restore);
extern void spl_module_unload_all(struct spl_vm *vm);

/* hnode.c functions */

void spl_hnode_reg(struct spl_vm *vm, const char *name, spl_hnode_function *handler, void *data);
void spl_hnode(struct spl_vm *vm, struct spl_node *node, const char *key, const char *handler, struct spl_module *mod);

void spl_hnode_call(struct spl_task *task, struct spl_vm *vm, struct spl_node *node, struct spl_hnode_args *args);

struct spl_node *spl_hnode_lookup(struct spl_task *task, struct spl_node *node, const char *key, int flags);
struct spl_node *spl_hnode_create(struct spl_task *task, struct spl_node *node, const char *key, struct spl_node *newnode, int flags);
void spl_hnode_delete(struct spl_task *task, struct spl_node *node, const char *key);
struct spl_node *spl_hnode_next(struct spl_task *task, struct spl_node *node, const char *key);
struct spl_node *spl_hnode_prev(struct spl_task *task, struct spl_node *node, const char *key);
struct spl_node *spl_hnode_copy(struct spl_vm *vm, struct spl_node *node);
void spl_hnode_put(struct spl_vm *vm, struct spl_node *node);
void spl_hnode_dump(struct spl_vm *vm, struct spl_node *node);

/* string.c functions */

extern struct spl_string *spl_string_new(int flags, struct spl_string *left, struct spl_string *right, char *text, struct spl_code *code);

extern struct spl_string *spl_string_printf(int flags, struct spl_string *left, struct spl_string *right, const char *fmt, ...) __attribute__ ((format (printf, 4, 5)));

extern struct spl_string *spl_string_split(struct spl_string *s, unsigned int offset, unsigned int len);

extern struct spl_string *spl_string_get(struct spl_string *s);
extern void spl_string_put(struct spl_string *s);

extern char *spl_string(struct spl_string *s);

/* util.c functions */

extern int spl_eval(struct spl_vm *vm, struct spl_node *ctx, char *module, const char *program);
extern int spl_eval_bytecode(struct spl_vm *vm, struct spl_node *ctx, char *module, struct spl_code *bytecode);

extern struct spl_task *spl_schedule(struct spl_task *task);
extern int spl_simple_runloop(struct spl_vm *vm, struct spl_task *wait_task);

extern void *spl_mmap_file(const char *filename, int *size);
extern void *spl_malloc_file(const char *filename, int *size);

/* utf8.c functions */

const char *spl_utf8_check(const char *text);
char *spl_utf8_import(const char *text, const char *charset);
char *spl_utf8_export(const char *text, const char *charset);

/* builtins.c functions */

extern struct spl_node *spl_builtin_write(struct spl_task *task, void *data);
extern struct spl_node *spl_builtin_read(struct spl_task *task, void *data);

extern struct spl_node *spl_builtin_chr(struct spl_task *task, void *data);
extern struct spl_node *spl_builtin_ord(struct spl_task *task, void *data);

extern struct spl_node *spl_builtin_hex(struct spl_task *task, void *data);
extern struct spl_node *spl_builtin_oct(struct spl_task *task, void *data);
extern struct spl_node *spl_builtin_bin(struct spl_task *task, void *data);
extern struct spl_node *spl_builtin_fmt(struct spl_task *task, void *data);

extern struct spl_node *spl_builtin_math1_wrapper(struct spl_task *task, void *data);
extern struct spl_node *spl_builtin_math2_wrapper(struct spl_task *task, void *data);

extern void spl_builtin_register_all(struct spl_vm *vm);

/* sha1.c function */

extern void spl_sha1(unsigned char *buffer, unsigned int buffer_len, unsigned char *digest);

/* moddir.c function */

extern const char *spl_system_modules_dir(void);

/**** instruction opcodes with addr argument (0x00 - 0x1f) ****/

#define SPL_OP_JUMP		0x00		// JUMP
#define SPL_OP_REGF		0x04		// BRANCH
#define SPL_OP_REGM		0x08		// BRANCH
#define SPL_OP_ENTER		0x0c		// BRANCH

#define SPL_OP_GOTO		0x10		// JUMP
#define SPL_OP_CATCH		0x14		// BRANCH

// 2 free opcodes with addr argument

/**** instruction opcodes with string argument (0x20 - 0x5f) ****/

#define SPL_OP_PUSH		0x20
#define SPL_OP_PUSHC		0x24		// STATICOP
#define SPL_OP_POP		0x28

// 1 free opcode with string argument

#define SPL_OP_PUSHA		0x30
#define SPL_OP_PUSHAC		0x34
#define SPL_OP_POPA		0x38

// 1 free opcode with string argument

#define SPL_OP_CLIB		0x40
#define SPL_OP_DCALL		0x44

#define SPL_OP_DBGSYM		0x48

#define SPL_OP_OBJOP		0x4c

// 4 free opcodes with string argument

/**** instruction opcodes without argument (0x60 - 0xff) ****/

// 16 free opcodes

#define SPL_OP_ZERO		0x70		// STATICOP
#define SPL_OP_ONE		0x71		// STATICOP
#define SPL_OP_UNDEF		0x72		// STATICOP

// 1 free opcode

#define SPL_OP_REMATCH		0x74
#define SPL_OP_RESUBST		0x75

// 2 free opcodes

#define SPL_OP_DEFINED		0x78
#define SPL_OP_DECLARED		0x79

// 2 free opcodes

#define SPL_OP_NEXT		0x7c
#define SPL_OP_PREV		0x7d

#define SPL_OP_HGETA		0x7e
#define SPL_OP_HSETA		0x7f

#define SPL_OP_CALL		0x80
#define SPL_OP_BEGIN		0x81
#define SPL_OP_END		0x82
#define SPL_OP_RETURN		0x83		// ENDBRANCH
#define SPL_OP_OBJECT		0x84
#define SPL_OP_ENDOBJ		0x85
#define SPL_OP_IMPORT		0x86
#define SPL_OP_LIFTCALL		0x87

#define SPL_OP_IF		0x88		// CONDIT
#define SPL_OP_UNLESS		0x89		// CONDIT

#define SPL_OP_TRY		0x8a
#define SPL_OP_THROW		0x8b		// ENDBRANCH

#define SPL_OP_NEW		0x8c
#define SPL_OP_SETCTX		0x8d

// 2 free opcodes

#define SPL_OP_GETVAL		0x90
#define SPL_OP_COPY		0x91
#define SPL_OP_DROP		0x92

// 1 free opcode

#define SPL_OP_POPI		0x94
#define SPL_OP_POPIC		0x95
#define SPL_OP_POPL		0x96
#define SPL_OP_POPLC		0x97
#define SPL_OP_POPS		0x98
#define SPL_OP_POPSC		0x99
#define SPL_OP_POPU		0x9a
#define SPL_OP_POPUC		0x9b

#define SPL_OP_PUSHAV		0x9c
#define SPL_OP_CLEARA		0x9d

#define SPL_OP_APUSHA		0x9e
#define SPL_OP_APOPA		0x9f

#define SPL_OP_HENC		0xa0		// UNARYOP
#define SPL_OP_HDEC		0xa1		// UNARYOP
#define SPL_OP_CAT		0xa2		// BINARYOP
#define SPL_OP_DOTCAT		0xa3		// BINARYOP

#define SPL_OP_APOP		0xa4
#define SPL_OP_ASHIFT		0xa5

#define SPL_OP_APUSH		0xa6
#define SPL_OP_AUNSHIFT		0xa7

#define SPL_OP_APUSHREF		0xa8
#define SPL_OP_APUSHREFID	0xa9

#define SPL_OP_LENGTH		0xaa		// UNARYOP
#define SPL_OP_ELEMENTS		0xab

#define SPL_OP_LAND		0xac		// BINARYOP
#define SPL_OP_LOR		0xad		// BINARYOP
#define SPL_OP_LNOT		0xae		// UNARYOP
#define SPL_OP_NEG		0xaf		// UNARYOP

#define SPL_OP_EQ		0xb0		// BINARYOP
#define SPL_OP_NE		0xb1		// BINARYOP
#define SPL_OP_LT		0xb2		// BINARYOP
#define SPL_OP_GT		0xb3		// BINARYOP
#define SPL_OP_LE		0xb4		// BINARYOP
#define SPL_OP_GE		0xb5		// BINARYOP

// 2 free opcodes

#define SPL_OP_ADD		0xb8		// BINARYOP
#define SPL_OP_SUB		0xb9		// BINARYOP
#define SPL_OP_MUL		0xba		// BINARYOP
#define SPL_OP_DIV		0xbb		// BINARYOP
#define SPL_OP_MOD		0xbc		// BINARYOP
#define SPL_OP_POW		0xbd		// BINARYOP

// 2 free opcodes

#define SPL_OP_IEQ		0xc0		// BINARYOP
#define SPL_OP_INE		0xc1		// BINARYOP
#define SPL_OP_ILT		0xc2		// BINARYOP
#define SPL_OP_IGT		0xc3		// BINARYOP
#define SPL_OP_ILE		0xc4		// BINARYOP
#define SPL_OP_IGE		0xc5		// BINARYOP

// 2 free opcodes

#define SPL_OP_IADD		0xc8		// BINARYOP
#define SPL_OP_ISUB		0xc9		// BINARYOP
#define SPL_OP_IMUL		0xca		// BINARYOP
#define SPL_OP_IDIV		0xcb		// BINARYOP
#define SPL_OP_IMOD		0xcc		// BINARYOP
#define SPL_OP_IPOW		0xcd		// BINARYOP

// 2 free opcodes

#define SPL_OP_FEQ		0xd0		// BINARYOP
#define SPL_OP_FNE		0xd1		// BINARYOP
#define SPL_OP_FLT		0xd2		// BINARYOP
#define SPL_OP_FGT		0xd3		// BINARYOP
#define SPL_OP_FLE		0xd4		// BINARYOP
#define SPL_OP_FGE		0xd5		// BINARYOP

// 2 free opcodes

#define SPL_OP_FADD		0xd8		// BINARYOP
#define SPL_OP_FSUB		0xd9		// BINARYOP
#define SPL_OP_FMUL		0xda		// BINARYOP
#define SPL_OP_FDIV		0xdb		// BINARYOP
#define SPL_OP_FMOD		0xdc		// BINARYOP
#define SPL_OP_FPOW		0xdd		// BINARYOP

// 2 free opcodes

#define SPL_OP_SEQ		0xe0		// BINARYOP
#define SPL_OP_SNE		0xe1		// BINARYOP
#define SPL_OP_SLT		0xe2		// BINARYOP
#define SPL_OP_SGT		0xe3		// BINARYOP
#define SPL_OP_SLE		0xe4		// BINARYOP
#define SPL_OP_SGE		0xe5		// BINARYOP

#define SPL_OP_PEQ		0xe6

// 1 free opcode

#define SPL_OP_POSTINC		0xe8
#define SPL_OP_POSTDEC		0xe9
#define SPL_OP_PREINC		0xea
#define SPL_OP_PREDEC		0xeb

#define SPL_OP_TOINT		0xec
#define SPL_OP_TOFLOAT		0xed

// 2 free opcodes

#define SPL_OP_NOP		0xf0
#define SPL_OP_DELETE		0xf1
#define SPL_OP_RLRET		0xf2
#define SPL_OP_CHECKP		0xf3
#define SPL_OP_LOAD		0xf4
#define SPL_OP_XCHG		0xf5
#define SPL_OP_EVAL		0xf6
#define SPL_OP_LXCHG		0xf7

#define SPL_OP_DEBUG		0xf8
#define SPL_OP_WARNING		0xf9
#define SPL_OP_ERROR		0xfa

// 1 free opcode

#define SPL_OP_SIG		0xfc

// 3 free opcodes

#define SPL_OP_HALT		0xff		// ENDBRANCH

#ifdef __cplusplus
}
#endif

#endif