aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/embryo/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/embryo/src/lib')
-rw-r--r--libraries/embryo/src/lib/Embryo.h901
-rw-r--r--libraries/embryo/src/lib/Makefile.am35
-rw-r--r--libraries/embryo/src/lib/Makefile.in682
-rw-r--r--libraries/embryo/src/lib/embryo_amx.c1991
-rw-r--r--libraries/embryo/src/lib/embryo_args.c128
-rw-r--r--libraries/embryo/src/lib/embryo_float.c331
-rw-r--r--libraries/embryo/src/lib/embryo_main.c36
-rw-r--r--libraries/embryo/src/lib/embryo_private.h298
-rw-r--r--libraries/embryo/src/lib/embryo_rand.c36
-rw-r--r--libraries/embryo/src/lib/embryo_str.c485
-rw-r--r--libraries/embryo/src/lib/embryo_time.c93
11 files changed, 5016 insertions, 0 deletions
diff --git a/libraries/embryo/src/lib/Embryo.h b/libraries/embryo/src/lib/Embryo.h
new file mode 100644
index 0000000..ea273cf
--- /dev/null
+++ b/libraries/embryo/src/lib/Embryo.h
@@ -0,0 +1,901 @@
1/**
2@brief Embryo Library
3
4These routines are used for Embryo.
5
6@mainpage Embryo Library Documentation
7
8@image html e_big.png
9
10@version 1.0.0
11@author Carsten Haitzler <raster\@rasterman.com>
12@author Compuphase http://www.compuphase.com
13@date 2004-2011
14
15@section intro What is Embryo?
16
17Embryo is a tiny library designed to interpret limited Small programs
18compiled by the included compiler, @c embryo_cc. It is mostly a cleaned
19up and smaller version of the original Small abstract machine. The
20compiler is mostly untouched.
21
22Small was renamed to Pawn.
23For more information about the Pawn language, see
24@htmlonly <a href=http://www.compuphase.com/pawn/pawn.htm>Pawn</a>
25@endhtmlonly
26@latexonly http://www.compuphase.com/pawn/pawn.htm @endlatexonly
27For the basics about the Small language, see @ref Small_Page.
28
29@section How_to_Use How to Use Embryo?
30
31To use Embryo in your code, you need to do at least the following:
32
33@li Include @ref Embryo.h.
34@li Load the Embryo program using one of the
35 @ref Embryo_Program_Creation_Group.
36@li Set up the native calls with @ref embryo_program_native_call_add.
37@li Create a virtual machine with @ref embryo_program_vm_push.
38@li Then run the program with @ref embryo_program_run.
39
40@todo Clean up compiler code.
41@todo Proper overview of the operation of the interpreter, that is how
42 the heap, stack, virtual machines, etc fit together.
43
44@page Small_Page Brief Introduction to Small
45
46This section describes the basics of Small, as compiled and interpreted
47with Embryo.
48
49This summary assumes that you are familar with C. For a full list of
50differences between C and Small, again, see the full documentation.
51
52@section Small_Variables_Section Variables
53
54@subsection Small_Type_Subsection Types
55
56There is only one type, known as the "cell", which can hold an integer.
57
58@subsection Small_Scope_Subsection Scope
59
60The scope and usage of a variable depends on its declaration.
61
62@li A local variable is normally declared with the @c new keyword. E.g.
63 @code new variable @endcode
64@li A static function variable is defined within a function with the
65 @c static keyword.
66@li A global static variable is one that is only available within the
67 file it was declared in. Again, use the @c static keyword, but outside
68 of any function.
69@li A stock variable is one that may not be compiled into a program if it
70 is not used. It is declared using @c stock.
71@li A public variable is one that can be read by the host program using
72 @ref embryo_program_variable_find. It is declared using @c public
73 keyword.
74
75Remember that the keywords above are to be used on their own. That is,
76for example: @code public testvar @endcode not:
77@code new public testvar @endcode
78
79@subsection Small_Constants_Subsection Constants
80
81You can declare constants in two ways:
82@li Using the preprocessor macro @c \#define.
83@li By inserting @c const between the keyword and variable name of a
84 variable declaration. For example, to declare the variable @c var1
85 constant, you type @code new const var1 = 2 @endcode Now @c var1
86 cannot be changed.
87
88@subsection Small_Arrays_Subsection Arrays
89
90To declare an array, append square brackets to the end of the variable
91name. The following examples show how to declare arrays. Note the
92use of the ellipsis operator, which bases the array based on the last two
93declared values:
94
95@code
96new msg[] = "A message."
97new ints[] = {1, 3, 4}
98new ints2[20] = {1, 3} // All other elements 0.
99new ints3[10] = {1, ... } // All elements = 1
100new ints4[10] = {10, 20, ... } // Elements = 10 -> 100.
101 // The difference can be negative.
102new ints5[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
103@endcode
104
105@note Array initialisers need to be constant.
106
107@section Small_Func_Calls_Section Function Calls
108
109A typical function declaration is as follows:
110
111@code
112testfunc(param) {
113 // Do something ...
114 // over a couple of lines.
115}
116@endcode
117
118You can pass by reference. That is, the parameter you pass is changed
119outside of the function. For example:
120
121@code
122testfunc(&param) {
123 param = 10
124 // The passed variable will be set to 10 outside of the function.
125}
126@endcode
127
128To pass an array:
129
130@code
131testfunc(param[]) {
132 // Do something to the array
133}
134@endcode
135
136@note Arrays are passed by reference.
137
138@section Small_Control_Subsection Control Structures.
139
140Small has the following control structures, which similar to their C
141counterparts:
142@li @code if (expression) statement1 else statement2 @endcode
143@li @code switch (expression) {
144 case 0:
145 statement1 // Can only be one statement. Look Ma, no breaks!
146 case 1..3: // For values between 1 and 3 inclusive.
147 statement2
148 default: // Optional
149 statement3
150}
151@endcode
152@li @code while(expression) statement @endcode
153@li @code do statement while (expression) @endcode
154@li @code for (init_expression; before_iter_test_expression; after_iter_expression) statement @endcode
155
156@section Small_Preprocessor_Section Preprocessor
157
158The following preprocessor directives are available:
159@li @code #assert constant_expression @endcode
160@li @code #define pattern replacement @endcode
161@li @code #define pattern(%1,%2,...) replacement @endcode
162@li @code #include filename @endcode
163@li @code #if constant_expression
164 // Various bits of code
165#else
166 // Other bits of code
167#endif
168@endcode
169@li @code #undef pattern @endcode
170
171
172@page Available_Native_Calls_Page Available Calls
173
174Embryo provides a minimal set of native calls that can be used within
175any Embryo script. Those calls are detailed here.
176
177@note Some of the "core" functions here are also described in the full
178 Small documentation given
179
180@todo Finish this section.
181
182@section Args_ANC_Section Argument Functions
183
184@subsection Numargs_Desc numargs
185
186Returns the number of arguments passed to a function. Useful
187when dealing with variable argument lists.
188
189@subsection Getargs_Desc getarg(arg, index=0)
190
191Retrieves the argument number @c arg. If the argument is an array,
192use @c index to specify the index of the array to return.
193
194@subsection Setargs_Desc setargs(arg, index=0, value)
195
196Sets the argument number @c arg to the given @c arg. @c index specifies
197the index of @c arg to set if @c arg is an array.
198
199@section String_ANC_Section String Functions
200
201Functions that work on strings.
202
203@subsection Atoi_Desc atoi
204
205Translates an number in string form into an integer.
206
207@subsection Fnmatch_Desc fnmatch
208
209Buggered if I know what this does?
210
211@subsection Strcmp_Desc strcmp
212
213String comparing function.
214
215
216@section Float_ANC_Section Float Functions
217
218@subsection Float_Desc float
219
220@subsection Atof_Desc atof
221
222@subsection Float_Mul_Desc float_mul
223
224@subsection Float_Div_Desc float_div
225
226@subsection Float_Add_Desc float_add
227
228@subsection Float_Sub_Desc float_sub
229
230@subsection Fract_Desc fract
231
232@subsection Round_Desc round
233
234@subsection Float_Cmp_Desc float_cmp
235
236@subsection Sqrt_Desc sqrt
237
238@subsection Pow_Desc pow
239
240@subsection Log_Desc log
241
242@subsection Sin_Desc sin
243
244@subsection Cos_Desc cos
245
246@subsection Tan_Desc tan
247
248@subsection Abs_Desc abs
249
250Returns the absolute value of the given float.
251
252@section Time_ANC_Section Time Functions
253
254@subsection Seconds_Desc seconds()
255
256@subsection Date_Desc date
257
258
259@section Rand_ANC_Section Random Functions
260
261@subsection Rand_Desc rand()
262
263Returns a random integer.
264
265@subsection Randf_Desc randf()
266
267Returns a random float.
268
269@file Embryo.h
270@brief Embryo virtual machine library.
271
272This file includes the routines needed for Embryo library interaction.
273This is the @e only file you need to include.
274
275*/
276
277// The following definitions are in Embryo.h, but I did not want to
278// mess up the formatting of the file
279
280/**
281 @def EMBRYO_FUNCTION_NONE
282 An invalid/non-existent function.
283*/
284
285/**
286 @def EMBRYO_FUNCTION_MAIN
287 Start at program entry point. For use with @ref embryo_program_run.
288*/
289
290/**
291 @def EMBRYO_FUNCTION_CONT
292 Continue from last address. For use with @ref embryo_program_run.
293*/
294
295/**
296 @def EMBRYO_PROGRAM_OK
297 Program was run successfully.
298*/
299
300/**
301 @def EMBRYO_PROGRAM_SLEEP
302 The program's execution was interrupted by a Small @c sleep command.
303*/
304
305/**
306 @def EMBRYO_PROGRAM_FAIL
307 An error in the program caused it to fail.
308*/
309
310#ifndef _EMBRYO_H
311#define _EMBRYO_H
312
313#ifdef EAPI
314# undef EAPI
315#endif
316
317#ifdef _WIN32
318# ifdef EFL_EMBRYO_BUILD
319# ifdef DLL_EXPORT
320# define EAPI __declspec(dllexport)
321# else
322# define EAPI
323# endif /* ! DLL_EXPORT */
324# else
325# define EAPI __declspec(dllimport)
326# endif /* ! EFL_EMBRYO_BUILD */
327#else
328# ifdef __GNUC__
329# if __GNUC__ >= 4
330# define EAPI __attribute__ ((visibility("default")))
331# else
332# define EAPI
333# endif
334# else
335# define EAPI
336# endif
337#endif /* ! _WIN32 */
338
339#ifdef __cplusplus
340extern "C" {
341#endif
342
343#define EMBRYO_VERSION_MAJOR 1
344#define EMBRYO_VERSION_MINOR 0
345
346 typedef struct _Embryo_Version
347 {
348 int major;
349 int minor;
350 int micro;
351 int revision;
352 } Embryo_Version;
353
354 EAPI extern Embryo_Version *embryo_version;
355
356 /* potential error values */
357 typedef enum _Embryo_Error
358 {
359 EMBRYO_ERROR_NONE,
360 /* reserve the first 15 error codes for exit codes of the abstract machine */
361 EMBRYO_ERROR_EXIT, /** Forced exit */
362 EMBRYO_ERROR_ASSERT, /** Assertion failed */
363 EMBRYO_ERROR_STACKERR, /** Stack/heap collision */
364 EMBRYO_ERROR_BOUNDS, /** Index out of bounds */
365 EMBRYO_ERROR_MEMACCESS, /** Invalid memory access */
366 EMBRYO_ERROR_INVINSTR, /** Invalid instruction */
367 EMBRYO_ERROR_STACKLOW, /** Stack underflow */
368 EMBRYO_ERROR_HEAPLOW, /** Heap underflow */
369 EMBRYO_ERROR_CALLBACK, /** No callback, or invalid callback */
370 EMBRYO_ERROR_NATIVE, /** Native function failed */
371 EMBRYO_ERROR_DIVIDE, /** Divide by zero */
372 EMBRYO_ERROR_SLEEP, /** Go into sleepmode - code can be restarted */
373
374 EMBRYO_ERROR_MEMORY = 16, /** Out of memory */
375 EMBRYO_ERROR_FORMAT, /** Invalid file format */
376 EMBRYO_ERROR_VERSION, /** File is for a newer version of the Embryo_Program */
377 EMBRYO_ERROR_NOTFOUND, /** Function not found */
378 EMBRYO_ERROR_INDEX, /** Invalid index parameter (bad entry point) */
379 EMBRYO_ERROR_DEBUG, /** Debugger cannot run */
380 EMBRYO_ERROR_INIT, /** Embryo_Program not initialized (or doubly initialized) */
381 EMBRYO_ERROR_USERDATA, /** Unable to set user data field (table full) */
382 EMBRYO_ERROR_INIT_JIT, /** Cannot initialize the JIT */
383 EMBRYO_ERROR_PARAMS, /** Parameter error */
384 EMBRYO_ERROR_DOMAIN, /** Domain error, expression result does not fit in range */
385 } Embryo_Error;
386
387 /* program run return values */
388 typedef enum _Embryo_Status
389 {
390 EMBRYO_PROGRAM_FAIL = 0,
391 EMBRYO_PROGRAM_OK = 1,
392 EMBRYO_PROGRAM_SLEEP = 2,
393 EMBRYO_PROGRAM_BUSY = 3,
394 EMBRYO_PROGRAM_TOOLONG = 4
395 } Embryo_Status;
396
397 typedef unsigned int Embryo_UCell;
398 typedef int Embryo_Cell;
399 /** An invalid cell reference */
400#define EMBRYO_CELL_NONE 0x7fffffff
401
402 typedef struct _Embryo_Program Embryo_Program;
403 typedef int Embryo_Function;
404 /* possible function type values that are enumerated */
405#define EMBRYO_FUNCTION_NONE 0x7fffffff /* An invalid/non existent function */
406#define EMBRYO_FUNCTION_MAIN -1 /* Start at program entry point */
407#define EMBRYO_FUNCTION_CONT -2 /* Continue from last address */
408
409 typedef union
410 {
411 float f;
412 Embryo_Cell c;
413 } Embryo_Float_Cell;
414
415#if defined _MSC_VER || defined __SUNPRO_C
416/** Float to Embryo_Cell */
417# define EMBRYO_FLOAT_TO_CELL(f) (((Embryo_Float_Cell *)&(f))->c)
418/** Embryo_Cell to float */
419# define EMBRYO_CELL_TO_FLOAT(c) (((Embryo_Float_Cell *)&(c))->f)
420#else
421/** Float to Embryo_Cell */
422# define EMBRYO_FLOAT_TO_CELL(f) ((Embryo_Float_Cell) f).c
423/** Embryo_Cell to float */
424# define EMBRYO_CELL_TO_FLOAT(c) ((Embryo_Float_Cell) c).f
425#endif
426
427 /**
428 * @defgroup Embryo_Library_Group Library Maintenance Functions
429 *
430 * Functions that start up and shutdown the Embryo library.
431 */
432
433
434/**
435 * Initialises the Embryo library.
436 * @return The number of times the library has been initialised without being
437 * shut down.
438 * @ingroup Embryo_Library_Group
439 */
440EAPI int embryo_init(void);
441
442/**
443 * Shuts down the Embryo library.
444 * @return The number of times the library has been initialised without being
445 * shutdown.
446 * @ingroup Embryo_Library_Group
447 */
448EAPI int embryo_shutdown(void);
449
450 /**
451 * @defgroup Embryo_Program_Creation_Group Program Creation and Destruction Functions
452 *
453 * Functions that set up programs, and destroy them.
454 */
455
456/**
457 * Creates a new Embryo program, with bytecode data that can be freed.
458 * @param data Pointer to the bytecode of the program.
459 * @param size Number of bytes of bytecode.
460 * @return A new Embryo program.
461 * @ingroup Embryo_Program_Creation_Group
462 */
463EAPI Embryo_Program *embryo_program_new(void *data, int size);
464
465/**
466 * Creates a new Embryo program, with bytecode data that cannot be
467 * freed.
468 * @param data Pointer to the bytecode of the program.
469 * @param size Number of bytes of bytecode.
470 * @return A new Embryo program.
471 * @ingroup Embryo_Program_Creation_Group
472 */
473EAPI Embryo_Program *embryo_program_const_new(void *data, int size);
474
475/**
476 * Creates a new Embryo program based on the bytecode data stored in the
477 * given file.
478 * @param file Filename of the given file.
479 * @return A new Embryo program.
480 * @ingroup Embryo_Program_Creation_Group
481 */
482EAPI Embryo_Program *embryo_program_load(const char *file);
483
484/**
485 * Frees the given Embryo program.
486 * @param ep The given program.
487 * @ingroup Embryo_Program_Creation_Group
488 */
489EAPI void embryo_program_free(Embryo_Program *ep);
490
491/**
492 * Adds a native program call to the given Embryo program.
493 * @param ep The given Embryo program.
494 * @param name The name for the call used in the script.
495 * @param func The function to use when the call is made.
496 * @ingroup Embryo_Func_Group
497 */
498
499/**
500 * @defgroup Embryo_Func_Group Function Functions
501 *
502 * Functions that deal with Embryo program functions.
503 */
504EAPI void embryo_program_native_call_add(Embryo_Program *ep, const char *name, Embryo_Cell (*func) (Embryo_Program *ep, Embryo_Cell *params));
505
506/**
507 * Resets the current virtual machine session of the given program.
508 * @param ep The given program.
509 * @ingroup Embryo_Program_VM_Group
510 */
511
512/**
513 * @defgroup Embryo_Program_VM_Group Virtual Machine Functions
514 *
515 * Functions that deal with creating and destroying virtual machine sessions
516 * for a given program.
517 *
518 * A given embryo program can have multiple virtual machine sessions running.
519 * This is useful when you have a native call that in turn calls a function in
520 * the embryo program. The native call can start a new virtual machine
521 * session to run the function it needs. Once completed, the session can be
522 * popped off the program's stack, and the native call can return its value
523 * to the old session.
524 *
525 * A new virtual machine session is created by pushing a new virtual machine
526 * onto the session stack of a program using @ref embryo_program_vm_push.
527 * The current virtual machine session can be destroyed by calling
528 * @ref embryo_program_vm_pop.
529 */
530EAPI void embryo_program_vm_reset(Embryo_Program *ep);
531
532/**
533 * Starts a new virtual machine session for the given program.
534 *
535 * See @ref Embryo_Program_VM_Group for more information about how this works.
536 *
537 * @param ep The given program.
538 * @ingroup Embryo_Program_VM_Group
539 */
540EAPI void embryo_program_vm_push(Embryo_Program *ep);
541
542/**
543 * Frees the current virtual machine session associated with the given program.
544 *
545 * See @ref Embryo_Program_VM_Group for more information about how this works.
546 * Note that you will need to retrieve any return data or data on the stack
547 * before you pop.
548 *
549 * @param ep The given program.
550 * @ingroup Embryo_Program_VM_Group
551 */
552EAPI void embryo_program_vm_pop(Embryo_Program *ep);
553
554/**
555 * Ensures that the given unsigned short integer is in the small
556 * endian format.
557 * @param v Pointer to the given integer.
558 * @ingroup Embryo_Swap_Group
559 */
560
561/**
562 * @defgroup Embryo_Swap_Group Byte Swapping Functions
563 *
564 * Functions that are used to ensure that integers passed to the
565 * virtual machine are in small endian format. These functions are
566 * used to ensure that the virtual machine operates correctly on big
567 * endian machines.
568 */
569EAPI void embryo_swap_16(unsigned short *v);
570
571/**
572 * Ensures that the given unsigned integer is in the small endian
573 * format.
574 * @param v Pointer to the given integer.
575 * @ingroup Embryo_Swap_Group
576 */
577EAPI void embryo_swap_32(unsigned int *v);
578
579/**
580 * Returns the function in the given program with the given name.
581 * @param ep The given program.
582 * @param name The given function name.
583 * @return The function if successful. Otherwise, @c EMBRYO_FUNCTION_NONE.
584 * @ingroup Embryo_Func_Group
585 */
586EAPI Embryo_Function embryo_program_function_find(Embryo_Program *ep, const char *name);
587
588/**
589 * Retrieves the location of the public variable in the given program
590 * with the given name.
591 * @param ep The given program.
592 * @param name The given name.
593 * @return The address of the variable if found. @c EMBRYO_CELL_NONE
594 * otherwise.
595 * @ingroup Embryo_Public_Variable_Group
596 */
597
598/**
599 * @defgroup Embryo_Public_Variable_Group Public Variable Access Functions
600 *
601 * In an Embryo program, a global variable can be declared public, as
602 * described in @ref Small_Scope_Subsection. The functions here allow
603 * the host program to access these public variables.
604 */
605EAPI Embryo_Cell embryo_program_variable_find(Embryo_Program *ep, const char *name);
606
607/**
608 * Retrieves the number of public variables in the given program.
609 * @param ep The given program.
610 * @return The number of public variables.
611 * @ingroup Embryo_Public_Variable_Group
612 */
613EAPI int embryo_program_variable_count_get(Embryo_Program *ep);
614
615/**
616 * Retrieves the location of the public variable in the given program
617 * with the given identifier.
618 * @param ep The given program.
619 * @param num The identifier of the public variable.
620 * @return The virtual machine address of the variable if found.
621 * @c EMBRYO_CELL_NONE otherwise.
622 * @ingroup Embryo_Public_Variable_Group
623 */
624EAPI Embryo_Cell embryo_program_variable_get(Embryo_Program *ep, int num);
625
626/**
627 * Sets the error code for the given program to the given code.
628 * @param ep The given program.
629 * @param error The given error code.
630 * @ingroup Embryo_Error_Group
631 */
632
633/**
634 * @defgroup Embryo_Error_Group Error Functions
635 *
636 * Functions that set and retrieve error codes in Embryo programs.
637 */
638EAPI void embryo_program_error_set(Embryo_Program *ep, Embryo_Error error);
639
640/**
641 * Retrieves the current error code for the given program.
642 * @param ep The given program.
643 * @return The current error code.
644 * @ingroup Embryo_Error_Group
645 */
646EAPI Embryo_Error embryo_program_error_get(Embryo_Program *ep);
647
648/**
649 * Sets the data associated to the given program.
650 * @param ep The given program.
651 * @param data New bytecode data.
652 * @ingroup Embryo_Program_Data_Group
653 */
654
655/**
656 * @defgroup Embryo_Program_Data_Group Program Data Functions
657 *
658 * Functions that set and retrieve data associated with the given
659 * program.
660 */
661EAPI void embryo_program_data_set(Embryo_Program *ep, void *data);
662
663/**
664 * Retrieves the data associated to the given program.
665 * @param ep The given program.
666 * @ingroup Embryo_Program_Data_Group
667 */
668EAPI void *embryo_program_data_get(Embryo_Program *ep);
669
670/**
671 * Retrieves a string describing the given error code.
672 * @param error The given error code.
673 * @return String describing the given error code. If the given code is not
674 * known, the string "(unknown)" is returned.
675 * @ingroup Embryo_Error_Group
676 */
677EAPI const char *embryo_error_string_get(Embryo_Error error);
678
679/**
680 * Retrieves the length of the string starting at the given cell.
681 * @param ep The program the cell is part of.
682 * @param str_cell Pointer to the first cell of the string.
683 * @return The length of the string. @c 0 is returned if there is an error.
684 * @ingroup Embryo_Data_String_Group
685 */
686
687/**
688 * @defgroup Embryo_Data_String_Group Embryo Data String Functions
689 *
690 * Functions that operate on strings in the memory of a virtual machine.
691 */
692EAPI int embryo_data_string_length_get(Embryo_Program *ep, Embryo_Cell *str_cell);
693
694/**
695 * Copies the string starting at the given cell to the given buffer.
696 * @param ep The program the cell is part of.
697 * @param str_cell Pointer to the first cell of the string.
698 * @param dst The given buffer.
699 * @ingroup Embryo_Data_String_Group
700 */
701EAPI void embryo_data_string_get(Embryo_Program *ep, Embryo_Cell *str_cell, char *dst);
702
703/**
704 * Copies string in the given buffer into the virtual machine memory
705 * starting at the given cell.
706 * @param ep The program the cell is part of.
707 * @param src The given buffer.
708 * @param str_cell Pointer to the first cell to copy the string to.
709 * @ingroup Embryo_Data_String_Group
710 */
711EAPI void embryo_data_string_set(Embryo_Program *ep, const char *src, Embryo_Cell *str_cell);
712
713/**
714 * Retreives a pointer to the address in the virtual machine given by the
715 * given cell.
716 * @param ep The program whose virtual machine address is being queried.
717 * @param addr The given cell.
718 * @return A pointer to the cell at the given address.
719 * @ingroup Embryo_Data_String_Group
720 */
721EAPI Embryo_Cell *embryo_data_address_get(Embryo_Program *ep, Embryo_Cell addr);
722
723/**
724 * Increases the size of the heap of the given virtual machine by the given
725 * number of Embryo_Cells.
726 * @param ep The program with the given virtual machine.
727 * @param cells The given number of Embryo_Cells.
728 * @return The address of the new memory region on success.
729 * @c EMBRYO_CELL_NONE otherwise.
730 * @ingroup Embryo_Heap_Group
731 */
732
733/**
734 * @defgroup Embryo_Heap_Group Heap Functions
735 *
736 * The heap is an area of memory that can be allocated for program
737 * use at runtime. The heap functions here change the amount of heap
738 * memory available.
739 */
740EAPI Embryo_Cell embryo_data_heap_push(Embryo_Program *ep, int cells);
741
742/**
743 * Decreases the size of the heap of the given virtual machine down to the
744 * given size.
745 * @param ep The program with the given virtual machine.
746 * @param down_to The given size.
747 * @ingroup Embryo_Heap_Group
748 */
749EAPI void embryo_data_heap_pop(Embryo_Program *ep, Embryo_Cell down_to);
750
751/**
752 * Returns the number of virtual machines are running for the given program.
753 * @param ep The given program.
754 * @return The number of virtual machines running.
755 * @ingroup Embryo_Run_Group
756 */
757
758/**
759 * @defgroup Embryo_Run_Group Program Run Functions
760 *
761 * Functions that are involved in actually running functions in an
762 * Embryo program.
763 */
764EAPI int embryo_program_recursion_get(Embryo_Program *ep);
765
766/**
767 * Runs the given function of the given Embryo program in the current
768 * virtual machine. The parameter @p fn can be found using
769 * @ref embryo_program_function_find.
770 *
771 * @note For Embryo to be able to run a function, it must have been
772 * declared @c public in the Small source code.
773 *
774 * @param ep The given program.
775 * @param fn The given function. Normally "main", in which case the
776 * constant @c EMBRYO_FUNCTION_MAIN can be used.
777 * @return @c EMBRYO_PROGRAM_OK on success. @c EMBRYO_PROGRAM_SLEEP if the
778 * program is halted by the Small @c sleep call.
779 * @c EMBRYO_PROGRAM_FAIL if there is an error.
780 * @c EMBRYO_PROGRAM_TOOLONG if the program executes for longer than
781 * it is allowed to in abstract machine instruction count.
782 * @ingroup Embryo_Run_Group
783 */
784EAPI Embryo_Status embryo_program_run(Embryo_Program *ep, Embryo_Function func);
785
786/**
787 * Retreives the return value of the last called function of the given
788 * program.
789 * @param ep The given program.
790 * @return An Embryo_Cell representing the return value of the function
791 * that was last called.
792 * @ingroup Embryo_Run_Group
793 */
794EAPI Embryo_Cell embryo_program_return_value_get(Embryo_Program *ep);
795
796/**
797 * Sets the maximum number of abstract machine cycles any given program run
798 * can execute before being put to sleep and returning.
799 *
800 * @param ep The given program.
801 * @param max The number of machine cycles as a limit.
802 *
803 * This sets the maximum number of abstract machine (virtual machine)
804 * instructions that a single run of an embryo function (even if its main)
805 * can use before embryo embryo_program_run() reutrns with the value
806 * EMBRYO_PROGRAM_TOOLONG. If the function fully executes within this number
807 * of cycles, embryo_program_run() will return as normal with either
808 * EMBRYO_PROGRAM_OK, EMBRYO_PROGRAM_FAIL or EMBRYO_PROGRAM_SLEEP. If the
809 * run exceeds this instruction count, then EMBRYO_PROGRAM_TOOLONG will be
810 * returned indicating the program exceeded its run count. If the app wishes
811 * to continue running this anyway - it is free to process its own events or
812 * whatever it wants and continue the function by calling
813 * embryo_program_run(program, EMBRYO_FUNCTION_CONT); which will start the
814 * run again until the instruction count is reached. This can keep being done
815 * to allow the calling program to still be able to control things outside the
816 * embryo function being called. If the maximum run cycle count is 0 then the
817 * program is allowed to run forever only returning when it is done.
818 *
819 * It is important to note that abstract machine cycles are NOT the same as
820 * the host machine cpu cycles. They are not fixed in runtime per cycle, so
821 * this is more of a helper tool than a way to HARD-FORCE a script to only
822 * run for a specific period of time. If the cycle count is set to something
823 * low like 5000 or 1000, then every 1000 (or 5000) cycles control will be
824 * returned to the calling process where it can check a timer to see if a
825 * physical runtime limit has been elapsed and then abort running further
826 * assuming a "runaway script" or keep continuing the script run. This
827 * limits resolution to only that many cycles which do not take a determined
828 * amount of time to execute, as this varies from cpu to cpu and also depends
829 * on how loaded the system is. Making the max cycle run too low will
830 * impact performance requiring the abstract machine to do setup and teardown
831 * cycles too often comapred to cycles actually executed.
832 *
833 * Also note it does NOT include nested abstract machines. IF this abstract
834 * machine run calls embryo script that calls a native function that in turn
835 * calls more embryo script, then the 2nd (and so on) levels are not included
836 * in this run count. They can set their own max instruction count values
837 * separately.
838 *
839 * The default max cycle run value is 0 in any program until set with this
840 * function.
841 *
842 * @ingroup Embryo_Run_Group
843 */
844EAPI void embryo_program_max_cycle_run_set(Embryo_Program *ep, int max);
845
846/**
847 * Retreives the maximum number of abstract machine cycles a program is allowed
848 * to run.
849 * @param ep The given program.
850 * @return The number of cycles a run cycle is allowed to run for this
851 * program.
852 *
853 * This returns the value set by embryo_program_max_cycle_run_set(). See
854 * embryo_program_max_cycle_run_set() for more information.
855 *
856 * @ingroup Embryo_Run_Group
857 */
858EAPI int embryo_program_max_cycle_run_get(Embryo_Program *ep);
859
860/**
861 * Pushes an Embryo_Cell onto the function stack to use as a parameter for
862 * the next function that is called in the given program.
863 * @param ep The given program.
864 * @param cell The Embryo_Cell to push onto the stack.
865 * @return @c 1 if successful. @c 0 otherwise.
866 * @ingroup Embryo_Parameter_Group
867 */
868
869/**
870 * @defgroup Embryo_Parameter_Group Function Parameter Functions
871 *
872 * Functions that set parameters for the next function that is called.
873 */
874EAPI int embryo_parameter_cell_push(Embryo_Program *ep, Embryo_Cell cell);
875
876/**
877 * Pushes a string onto the function stack to use as a parameter for the
878 * next function that is called in the given program.
879 * @param ep The given program.
880 * @param str The string to push onto the stack.
881 * @return @c 1 if successful. @c 0 otherwise.
882 * @ingroup Embryo_Parameter_Group
883 */
884EAPI int embryo_parameter_string_push(Embryo_Program *ep, const char *str);
885
886/**
887 * Pushes an array of Embryo_Cells onto the function stack to be used as
888 * parameters for the next function that is called in the given program.
889 * @param ep The given program.
890 * @param cells The array of Embryo_Cells.
891 * @param num The number of cells in @p cells.
892 * @return @c 1 if successful. @c 0 otherwise.
893 * @ingroup Embryo_Parameter_Group
894 */
895EAPI int embryo_parameter_cell_array_push(Embryo_Program *ep, Embryo_Cell *cells, int num);
896
897#ifdef __cplusplus
898}
899#endif
900
901#endif
diff --git a/libraries/embryo/src/lib/Makefile.am b/libraries/embryo/src/lib/Makefile.am
new file mode 100644
index 0000000..f5c78aa
--- /dev/null
+++ b/libraries/embryo/src/lib/Makefile.am
@@ -0,0 +1,35 @@
1
2MAINTAINERCLEANFILES = Makefile.in
3
4AM_CPPFLAGS = \
5-I. \
6-I$(top_srcdir)/src/lib \
7-I$(top_builddir) \
8-I$(top_srcdir)/src/lib \
9-I$(top_srcdir)/src/lib/include \
10-DPACKAGE_BIN_DIR=\"$(bindir)\" \
11-DPACKAGE_LIB_DIR=\"$(libdir)\" \
12-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
13@EVIL_CFLAGS@ \
14@EMBRYO_CPPFLAGS@ \
15@EFL_EMBRYO_BUILD@
16
17includes_HEADERS = Embryo.h
18includesdir = $(includedir)/embryo-@VMAJ@
19
20lib_LTLIBRARIES = libembryo.la
21
22libembryo_la_SOURCES = \
23embryo_amx.c \
24embryo_args.c \
25embryo_float.c \
26embryo_main.c \
27embryo_rand.c \
28embryo_str.c \
29embryo_time.c
30
31libembryo_la_CFLAGS = @EMBRYO_CFLAGS@
32libembryo_la_LIBADD = @EVIL_LIBS@ -lm
33libembryo_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@
34
35EXTRA_DIST = embryo_private.h
diff --git a/libraries/embryo/src/lib/Makefile.in b/libraries/embryo/src/lib/Makefile.in
new file mode 100644
index 0000000..56e9f26
--- /dev/null
+++ b/libraries/embryo/src/lib/Makefile.in
@@ -0,0 +1,682 @@
1# Makefile.in generated by automake 1.11.1 from Makefile.am.
2# @configure_input@
3
4# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
5# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
6# Inc.
7# This Makefile.in is free software; the Free Software Foundation
8# gives unlimited permission to copy and/or distribute it,
9# with or without modifications, as long as this notice is preserved.
10
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
13# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
14# PARTICULAR PURPOSE.
15
16@SET_MAKE@
17
18
19VPATH = @srcdir@
20pkgdatadir = $(datadir)/@PACKAGE@
21pkgincludedir = $(includedir)/@PACKAGE@
22pkglibdir = $(libdir)/@PACKAGE@
23pkglibexecdir = $(libexecdir)/@PACKAGE@
24am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
25install_sh_DATA = $(install_sh) -c -m 644
26install_sh_PROGRAM = $(install_sh) -c
27install_sh_SCRIPT = $(install_sh) -c
28INSTALL_HEADER = $(INSTALL_DATA)
29transform = $(program_transform_name)
30NORMAL_INSTALL = :
31PRE_INSTALL = :
32POST_INSTALL = :
33NORMAL_UNINSTALL = :
34PRE_UNINSTALL = :
35POST_UNINSTALL = :
36build_triplet = @build@
37host_triplet = @host@
38subdir = src/lib
39DIST_COMMON = $(includes_HEADERS) $(srcdir)/Makefile.am \
40 $(srcdir)/Makefile.in
41ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
42am__aclocal_m4_deps = $(top_srcdir)/m4/ac_attribute.m4 \
43 $(top_srcdir)/m4/efl_binary.m4 $(top_srcdir)/m4/efl_doxygen.m4 \
44 $(top_srcdir)/m4/efl_fnmatch.m4 \
45 $(top_srcdir)/m4/efl_path_max.m4 $(top_srcdir)/m4/libtool.m4 \
46 $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
47 $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
48 $(top_srcdir)/configure.ac
49am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
50 $(ACLOCAL_M4)
51mkinstalldirs = $(install_sh) -d
52CONFIG_HEADER = $(top_builddir)/config.h
53CONFIG_CLEAN_FILES =
54CONFIG_CLEAN_VPATH_FILES =
55am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
56am__vpath_adj = case $$p in \
57 $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
58 *) f=$$p;; \
59 esac;
60am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
61am__install_max = 40
62am__nobase_strip_setup = \
63 srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
64am__nobase_strip = \
65 for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
66am__nobase_list = $(am__nobase_strip_setup); \
67 for p in $$list; do echo "$$p $$p"; done | \
68 sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
69 $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
70 if (++n[$$2] == $(am__install_max)) \
71 { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
72 END { for (dir in files) print dir, files[dir] }'
73am__base_list = \
74 sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
75 sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
76am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)"
77LTLIBRARIES = $(lib_LTLIBRARIES)
78libembryo_la_DEPENDENCIES =
79am_libembryo_la_OBJECTS = libembryo_la-embryo_amx.lo \
80 libembryo_la-embryo_args.lo libembryo_la-embryo_float.lo \
81 libembryo_la-embryo_main.lo libembryo_la-embryo_rand.lo \
82 libembryo_la-embryo_str.lo libembryo_la-embryo_time.lo
83libembryo_la_OBJECTS = $(am_libembryo_la_OBJECTS)
84AM_V_lt = $(am__v_lt_$(V))
85am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
86am__v_lt_0 = --silent
87libembryo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
88 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libembryo_la_CFLAGS) \
89 $(CFLAGS) $(libembryo_la_LDFLAGS) $(LDFLAGS) -o $@
90DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
91depcomp = $(SHELL) $(top_srcdir)/depcomp
92am__depfiles_maybe = depfiles
93am__mv = mv -f
94COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
95 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
96LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
97 $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
98 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
99 $(AM_CFLAGS) $(CFLAGS)
100AM_V_CC = $(am__v_CC_$(V))
101am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
102am__v_CC_0 = @echo " CC " $@;
103AM_V_at = $(am__v_at_$(V))
104am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
105am__v_at_0 = @
106CCLD = $(CC)
107LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
108 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
109 $(AM_LDFLAGS) $(LDFLAGS) -o $@
110AM_V_CCLD = $(am__v_CCLD_$(V))
111am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
112am__v_CCLD_0 = @echo " CCLD " $@;
113AM_V_GEN = $(am__v_GEN_$(V))
114am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
115am__v_GEN_0 = @echo " GEN " $@;
116SOURCES = $(libembryo_la_SOURCES)
117DIST_SOURCES = $(libembryo_la_SOURCES)
118HEADERS = $(includes_HEADERS)
119ETAGS = etags
120CTAGS = ctags
121DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
122ACLOCAL = @ACLOCAL@
123ALLOCA = @ALLOCA@
124AMTAR = @AMTAR@
125AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
126AR = @AR@
127AS = @AS@
128AUTOCONF = @AUTOCONF@
129AUTOHEADER = @AUTOHEADER@
130AUTOMAKE = @AUTOMAKE@
131AWK = @AWK@
132CC = @CC@
133CCDEPMODE = @CCDEPMODE@
134CFLAGS = @CFLAGS@
135CPP = @CPP@
136CPPFLAGS = @CPPFLAGS@
137CYGPATH_W = @CYGPATH_W@
138DEFS = @DEFS@
139DEPDIR = @DEPDIR@
140DLLTOOL = @DLLTOOL@
141DSYMUTIL = @DSYMUTIL@
142DUMPBIN = @DUMPBIN@
143ECHO_C = @ECHO_C@
144ECHO_N = @ECHO_N@
145ECHO_T = @ECHO_T@
146EFL_EMBRYO_BUILD = @EFL_EMBRYO_BUILD@
147EFL_FNMATCH_LIBS = @EFL_FNMATCH_LIBS@
148EGREP = @EGREP@
149EINA_CFLAGS = @EINA_CFLAGS@
150EINA_LIBS = @EINA_LIBS@
151EMBRYO_CC_PRG = @EMBRYO_CC_PRG@
152EMBRYO_CFLAGS = @EMBRYO_CFLAGS@
153EMBRYO_CPPFLAGS = @EMBRYO_CPPFLAGS@
154EVIL_CFLAGS = @EVIL_CFLAGS@
155EVIL_LIBS = @EVIL_LIBS@
156EXEEXT = @EXEEXT@
157FGREP = @FGREP@
158GREP = @GREP@
159INSTALL = @INSTALL@
160INSTALL_DATA = @INSTALL_DATA@
161INSTALL_PROGRAM = @INSTALL_PROGRAM@
162INSTALL_SCRIPT = @INSTALL_SCRIPT@
163INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
164LD = @LD@
165LDFLAGS = @LDFLAGS@
166LIBOBJS = @LIBOBJS@
167LIBS = @LIBS@
168LIBTOOL = @LIBTOOL@
169LIPO = @LIPO@
170LN_S = @LN_S@
171LTLIBOBJS = @LTLIBOBJS@
172MAKEINFO = @MAKEINFO@
173MKDIR_P = @MKDIR_P@
174NM = @NM@
175NMEDIT = @NMEDIT@
176OBJDUMP = @OBJDUMP@
177OBJEXT = @OBJEXT@
178OTOOL = @OTOOL@
179OTOOL64 = @OTOOL64@
180PACKAGE = @PACKAGE@
181PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
182PACKAGE_NAME = @PACKAGE_NAME@
183PACKAGE_STRING = @PACKAGE_STRING@
184PACKAGE_TARNAME = @PACKAGE_TARNAME@
185PACKAGE_URL = @PACKAGE_URL@
186PACKAGE_VERSION = @PACKAGE_VERSION@
187PATH_SEPARATOR = @PATH_SEPARATOR@
188PKG_CONFIG = @PKG_CONFIG@
189PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
190PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
191RANLIB = @RANLIB@
192SED = @SED@
193SET_MAKE = @SET_MAKE@
194SHELL = @SHELL@
195STRIP = @STRIP@
196VERSION = @VERSION@
197VMAJ = @VMAJ@
198abs_builddir = @abs_builddir@
199abs_srcdir = @abs_srcdir@
200abs_top_builddir = @abs_top_builddir@
201abs_top_srcdir = @abs_top_srcdir@
202ac_ct_CC = @ac_ct_CC@
203ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
204am__include = @am__include@
205am__leading_dot = @am__leading_dot@
206am__quote = @am__quote@
207am__tar = @am__tar@
208am__untar = @am__untar@
209bindir = @bindir@
210build = @build@
211build_alias = @build_alias@
212build_cpu = @build_cpu@
213build_os = @build_os@
214build_vendor = @build_vendor@
215builddir = @builddir@
216datadir = @datadir@
217datarootdir = @datarootdir@
218docdir = @docdir@
219dvidir = @dvidir@
220efl_doxygen = @efl_doxygen@
221efl_have_doxygen = @efl_have_doxygen@
222embryoincludedir = @embryoincludedir@
223exec_prefix = @exec_prefix@
224host = @host@
225host_alias = @host_alias@
226host_cpu = @host_cpu@
227host_os = @host_os@
228host_vendor = @host_vendor@
229htmldir = @htmldir@
230includedir = @includedir@
231infodir = @infodir@
232install_sh = @install_sh@
233libdir = @libdir@
234libexecdir = @libexecdir@
235localedir = @localedir@
236localstatedir = @localstatedir@
237lt_ECHO = @lt_ECHO@
238lt_enable_auto_import = @lt_enable_auto_import@
239mandir = @mandir@
240mkdir_p = @mkdir_p@
241oldincludedir = @oldincludedir@
242pdfdir = @pdfdir@
243pkgconfig_requires_private = @pkgconfig_requires_private@
244prefix = @prefix@
245program_transform_name = @program_transform_name@
246psdir = @psdir@
247release_info = @release_info@
248requirement_embryo = @requirement_embryo@
249sbindir = @sbindir@
250sharedstatedir = @sharedstatedir@
251srcdir = @srcdir@
252sysconfdir = @sysconfdir@
253target_alias = @target_alias@
254top_build_prefix = @top_build_prefix@
255top_builddir = @top_builddir@
256top_srcdir = @top_srcdir@
257version_info = @version_info@
258MAINTAINERCLEANFILES = Makefile.in
259AM_CPPFLAGS = \
260-I. \
261-I$(top_srcdir)/src/lib \
262-I$(top_builddir) \
263-I$(top_srcdir)/src/lib \
264-I$(top_srcdir)/src/lib/include \
265-DPACKAGE_BIN_DIR=\"$(bindir)\" \
266-DPACKAGE_LIB_DIR=\"$(libdir)\" \
267-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
268@EVIL_CFLAGS@ \
269@EMBRYO_CPPFLAGS@ \
270@EFL_EMBRYO_BUILD@
271
272includes_HEADERS = Embryo.h
273includesdir = $(includedir)/embryo-@VMAJ@
274lib_LTLIBRARIES = libembryo.la
275libembryo_la_SOURCES = \
276embryo_amx.c \
277embryo_args.c \
278embryo_float.c \
279embryo_main.c \
280embryo_rand.c \
281embryo_str.c \
282embryo_time.c
283
284libembryo_la_CFLAGS = @EMBRYO_CFLAGS@
285libembryo_la_LIBADD = @EVIL_LIBS@ -lm
286libembryo_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@
287EXTRA_DIST = embryo_private.h
288all: all-am
289
290.SUFFIXES:
291.SUFFIXES: .c .lo .o .obj
292$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
293 @for dep in $?; do \
294 case '$(am__configure_deps)' in \
295 *$$dep*) \
296 ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
297 && { if test -f $@; then exit 0; else break; fi; }; \
298 exit 1;; \
299 esac; \
300 done; \
301 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/lib/Makefile'; \
302 $(am__cd) $(top_srcdir) && \
303 $(AUTOMAKE) --gnu src/lib/Makefile
304.PRECIOUS: Makefile
305Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
306 @case '$?' in \
307 *config.status*) \
308 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
309 *) \
310 echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
311 cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
312 esac;
313
314$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
315 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
316
317$(top_srcdir)/configure: $(am__configure_deps)
318 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
319$(ACLOCAL_M4): $(am__aclocal_m4_deps)
320 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
321$(am__aclocal_m4_deps):
322install-libLTLIBRARIES: $(lib_LTLIBRARIES)
323 @$(NORMAL_INSTALL)
324 test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
325 @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
326 list2=; for p in $$list; do \
327 if test -f $$p; then \
328 list2="$$list2 $$p"; \
329 else :; fi; \
330 done; \
331 test -z "$$list2" || { \
332 echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
333 $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
334 }
335
336uninstall-libLTLIBRARIES:
337 @$(NORMAL_UNINSTALL)
338 @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
339 for p in $$list; do \
340 $(am__strip_dir) \
341 echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
342 $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
343 done
344
345clean-libLTLIBRARIES:
346 -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
347 @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
348 dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
349 test "$$dir" != "$$p" || dir=.; \
350 echo "rm -f \"$${dir}/so_locations\""; \
351 rm -f "$${dir}/so_locations"; \
352 done
353libembryo.la: $(libembryo_la_OBJECTS) $(libembryo_la_DEPENDENCIES)
354 $(AM_V_CCLD)$(libembryo_la_LINK) -rpath $(libdir) $(libembryo_la_OBJECTS) $(libembryo_la_LIBADD) $(LIBS)
355
356mostlyclean-compile:
357 -rm -f *.$(OBJEXT)
358
359distclean-compile:
360 -rm -f *.tab.c
361
362@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libembryo_la-embryo_amx.Plo@am__quote@
363@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libembryo_la-embryo_args.Plo@am__quote@
364@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libembryo_la-embryo_float.Plo@am__quote@
365@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libembryo_la-embryo_main.Plo@am__quote@
366@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libembryo_la-embryo_rand.Plo@am__quote@
367@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libembryo_la-embryo_str.Plo@am__quote@
368@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libembryo_la-embryo_time.Plo@am__quote@
369
370.c.o:
371@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
372@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
373@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
374@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
375@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
376@am__fastdepCC_FALSE@ $(COMPILE) -c $<
377
378.c.obj:
379@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
380@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
381@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
382@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
383@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
384@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
385
386.c.lo:
387@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
388@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
389@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
390@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
391@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
392@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
393
394libembryo_la-embryo_amx.lo: embryo_amx.c
395@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -MT libembryo_la-embryo_amx.lo -MD -MP -MF $(DEPDIR)/libembryo_la-embryo_amx.Tpo -c -o libembryo_la-embryo_amx.lo `test -f 'embryo_amx.c' || echo '$(srcdir)/'`embryo_amx.c
396@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libembryo_la-embryo_amx.Tpo $(DEPDIR)/libembryo_la-embryo_amx.Plo
397@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
398@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='embryo_amx.c' object='libembryo_la-embryo_amx.lo' libtool=yes @AMDEPBACKSLASH@
399@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
400@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -c -o libembryo_la-embryo_amx.lo `test -f 'embryo_amx.c' || echo '$(srcdir)/'`embryo_amx.c
401
402libembryo_la-embryo_args.lo: embryo_args.c
403@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -MT libembryo_la-embryo_args.lo -MD -MP -MF $(DEPDIR)/libembryo_la-embryo_args.Tpo -c -o libembryo_la-embryo_args.lo `test -f 'embryo_args.c' || echo '$(srcdir)/'`embryo_args.c
404@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libembryo_la-embryo_args.Tpo $(DEPDIR)/libembryo_la-embryo_args.Plo
405@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
406@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='embryo_args.c' object='libembryo_la-embryo_args.lo' libtool=yes @AMDEPBACKSLASH@
407@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
408@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -c -o libembryo_la-embryo_args.lo `test -f 'embryo_args.c' || echo '$(srcdir)/'`embryo_args.c
409
410libembryo_la-embryo_float.lo: embryo_float.c
411@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -MT libembryo_la-embryo_float.lo -MD -MP -MF $(DEPDIR)/libembryo_la-embryo_float.Tpo -c -o libembryo_la-embryo_float.lo `test -f 'embryo_float.c' || echo '$(srcdir)/'`embryo_float.c
412@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libembryo_la-embryo_float.Tpo $(DEPDIR)/libembryo_la-embryo_float.Plo
413@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
414@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='embryo_float.c' object='libembryo_la-embryo_float.lo' libtool=yes @AMDEPBACKSLASH@
415@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
416@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -c -o libembryo_la-embryo_float.lo `test -f 'embryo_float.c' || echo '$(srcdir)/'`embryo_float.c
417
418libembryo_la-embryo_main.lo: embryo_main.c
419@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -MT libembryo_la-embryo_main.lo -MD -MP -MF $(DEPDIR)/libembryo_la-embryo_main.Tpo -c -o libembryo_la-embryo_main.lo `test -f 'embryo_main.c' || echo '$(srcdir)/'`embryo_main.c
420@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libembryo_la-embryo_main.Tpo $(DEPDIR)/libembryo_la-embryo_main.Plo
421@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
422@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='embryo_main.c' object='libembryo_la-embryo_main.lo' libtool=yes @AMDEPBACKSLASH@
423@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
424@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -c -o libembryo_la-embryo_main.lo `test -f 'embryo_main.c' || echo '$(srcdir)/'`embryo_main.c
425
426libembryo_la-embryo_rand.lo: embryo_rand.c
427@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -MT libembryo_la-embryo_rand.lo -MD -MP -MF $(DEPDIR)/libembryo_la-embryo_rand.Tpo -c -o libembryo_la-embryo_rand.lo `test -f 'embryo_rand.c' || echo '$(srcdir)/'`embryo_rand.c
428@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libembryo_la-embryo_rand.Tpo $(DEPDIR)/libembryo_la-embryo_rand.Plo
429@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
430@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='embryo_rand.c' object='libembryo_la-embryo_rand.lo' libtool=yes @AMDEPBACKSLASH@
431@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
432@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -c -o libembryo_la-embryo_rand.lo `test -f 'embryo_rand.c' || echo '$(srcdir)/'`embryo_rand.c
433
434libembryo_la-embryo_str.lo: embryo_str.c
435@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -MT libembryo_la-embryo_str.lo -MD -MP -MF $(DEPDIR)/libembryo_la-embryo_str.Tpo -c -o libembryo_la-embryo_str.lo `test -f 'embryo_str.c' || echo '$(srcdir)/'`embryo_str.c
436@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libembryo_la-embryo_str.Tpo $(DEPDIR)/libembryo_la-embryo_str.Plo
437@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
438@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='embryo_str.c' object='libembryo_la-embryo_str.lo' libtool=yes @AMDEPBACKSLASH@
439@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
440@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -c -o libembryo_la-embryo_str.lo `test -f 'embryo_str.c' || echo '$(srcdir)/'`embryo_str.c
441
442libembryo_la-embryo_time.lo: embryo_time.c
443@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -MT libembryo_la-embryo_time.lo -MD -MP -MF $(DEPDIR)/libembryo_la-embryo_time.Tpo -c -o libembryo_la-embryo_time.lo `test -f 'embryo_time.c' || echo '$(srcdir)/'`embryo_time.c
444@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libembryo_la-embryo_time.Tpo $(DEPDIR)/libembryo_la-embryo_time.Plo
445@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
446@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='embryo_time.c' object='libembryo_la-embryo_time.lo' libtool=yes @AMDEPBACKSLASH@
447@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
448@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libembryo_la_CFLAGS) $(CFLAGS) -c -o libembryo_la-embryo_time.lo `test -f 'embryo_time.c' || echo '$(srcdir)/'`embryo_time.c
449
450mostlyclean-libtool:
451 -rm -f *.lo
452
453clean-libtool:
454 -rm -rf .libs _libs
455install-includesHEADERS: $(includes_HEADERS)
456 @$(NORMAL_INSTALL)
457 test -z "$(includesdir)" || $(MKDIR_P) "$(DESTDIR)$(includesdir)"
458 @list='$(includes_HEADERS)'; test -n "$(includesdir)" || list=; \
459 for p in $$list; do \
460 if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
461 echo "$$d$$p"; \
462 done | $(am__base_list) | \
463 while read files; do \
464 echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includesdir)'"; \
465 $(INSTALL_HEADER) $$files "$(DESTDIR)$(includesdir)" || exit $$?; \
466 done
467
468uninstall-includesHEADERS:
469 @$(NORMAL_UNINSTALL)
470 @list='$(includes_HEADERS)'; test -n "$(includesdir)" || list=; \
471 files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
472 test -n "$$files" || exit 0; \
473 echo " ( cd '$(DESTDIR)$(includesdir)' && rm -f" $$files ")"; \
474 cd "$(DESTDIR)$(includesdir)" && rm -f $$files
475
476ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
477 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
478 unique=`for i in $$list; do \
479 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
480 done | \
481 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
482 END { if (nonempty) { for (i in files) print i; }; }'`; \
483 mkid -fID $$unique
484tags: TAGS
485
486TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
487 $(TAGS_FILES) $(LISP)
488 set x; \
489 here=`pwd`; \
490 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
491 unique=`for i in $$list; do \
492 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
493 done | \
494 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
495 END { if (nonempty) { for (i in files) print i; }; }'`; \
496 shift; \
497 if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
498 test -n "$$unique" || unique=$$empty_fix; \
499 if test $$# -gt 0; then \
500 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
501 "$$@" $$unique; \
502 else \
503 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
504 $$unique; \
505 fi; \
506 fi
507ctags: CTAGS
508CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
509 $(TAGS_FILES) $(LISP)
510 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
511 unique=`for i in $$list; do \
512 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
513 done | \
514 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
515 END { if (nonempty) { for (i in files) print i; }; }'`; \
516 test -z "$(CTAGS_ARGS)$$unique" \
517 || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
518 $$unique
519
520GTAGS:
521 here=`$(am__cd) $(top_builddir) && pwd` \
522 && $(am__cd) $(top_srcdir) \
523 && gtags -i $(GTAGS_ARGS) "$$here"
524
525distclean-tags:
526 -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
527
528distdir: $(DISTFILES)
529 @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
530 topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
531 list='$(DISTFILES)'; \
532 dist_files=`for file in $$list; do echo $$file; done | \
533 sed -e "s|^$$srcdirstrip/||;t" \
534 -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
535 case $$dist_files in \
536 */*) $(MKDIR_P) `echo "$$dist_files" | \
537 sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
538 sort -u` ;; \
539 esac; \
540 for file in $$dist_files; do \
541 if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
542 if test -d $$d/$$file; then \
543 dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
544 if test -d "$(distdir)/$$file"; then \
545 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
546 fi; \
547 if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
548 cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
549 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
550 fi; \
551 cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
552 else \
553 test -f "$(distdir)/$$file" \
554 || cp -p $$d/$$file "$(distdir)/$$file" \
555 || exit 1; \
556 fi; \
557 done
558check-am: all-am
559check: check-am
560all-am: Makefile $(LTLIBRARIES) $(HEADERS)
561installdirs:
562 for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)"; do \
563 test -z "$$dir" || $(MKDIR_P) "$$dir"; \
564 done
565install: install-am
566install-exec: install-exec-am
567install-data: install-data-am
568uninstall: uninstall-am
569
570install-am: all-am
571 @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
572
573installcheck: installcheck-am
574install-strip:
575 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
576 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
577 `test -z '$(STRIP)' || \
578 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
579mostlyclean-generic:
580
581clean-generic:
582
583distclean-generic:
584 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
585 -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
586
587maintainer-clean-generic:
588 @echo "This command is intended for maintainers to use"
589 @echo "it deletes files that may require special tools to rebuild."
590 -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
591clean: clean-am
592
593clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
594 mostlyclean-am
595
596distclean: distclean-am
597 -rm -rf ./$(DEPDIR)
598 -rm -f Makefile
599distclean-am: clean-am distclean-compile distclean-generic \
600 distclean-tags
601
602dvi: dvi-am
603
604dvi-am:
605
606html: html-am
607
608html-am:
609
610info: info-am
611
612info-am:
613
614install-data-am: install-includesHEADERS
615
616install-dvi: install-dvi-am
617
618install-dvi-am:
619
620install-exec-am: install-libLTLIBRARIES
621
622install-html: install-html-am
623
624install-html-am:
625
626install-info: install-info-am
627
628install-info-am:
629
630install-man:
631
632install-pdf: install-pdf-am
633
634install-pdf-am:
635
636install-ps: install-ps-am
637
638install-ps-am:
639
640installcheck-am:
641
642maintainer-clean: maintainer-clean-am
643 -rm -rf ./$(DEPDIR)
644 -rm -f Makefile
645maintainer-clean-am: distclean-am maintainer-clean-generic
646
647mostlyclean: mostlyclean-am
648
649mostlyclean-am: mostlyclean-compile mostlyclean-generic \
650 mostlyclean-libtool
651
652pdf: pdf-am
653
654pdf-am:
655
656ps: ps-am
657
658ps-am:
659
660uninstall-am: uninstall-includesHEADERS uninstall-libLTLIBRARIES
661
662.MAKE: install-am install-strip
663
664.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
665 clean-libLTLIBRARIES clean-libtool ctags distclean \
666 distclean-compile distclean-generic distclean-libtool \
667 distclean-tags distdir dvi dvi-am html html-am info info-am \
668 install install-am install-data install-data-am install-dvi \
669 install-dvi-am install-exec install-exec-am install-html \
670 install-html-am install-includesHEADERS install-info \
671 install-info-am install-libLTLIBRARIES install-man install-pdf \
672 install-pdf-am install-ps install-ps-am install-strip \
673 installcheck installcheck-am installdirs maintainer-clean \
674 maintainer-clean-generic mostlyclean mostlyclean-compile \
675 mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
676 tags uninstall uninstall-am uninstall-includesHEADERS \
677 uninstall-libLTLIBRARIES
678
679
680# Tell versions [3.59,3.63) of GNU make to not export all variables.
681# Otherwise a system limit (for SysV at least) may be exceeded.
682.NOEXPORT:
diff --git a/libraries/embryo/src/lib/embryo_amx.c b/libraries/embryo/src/lib/embryo_amx.c
new file mode 100644
index 0000000..4fa84c5
--- /dev/null
+++ b/libraries/embryo/src/lib/embryo_amx.c
@@ -0,0 +1,1991 @@
1/* Abstract Machine for the Small compiler
2 *
3 * Copyright (c) ITB CompuPhase, 1997-2003
4 * Portions Copyright (c) Carsten Haitzler, 2004-2010 <raster@rasterman.com>
5 *
6 * This software is provided "as-is", without any express or implied warranty.
7 * In no event will the authors be held liable for any damages arising from
8 * the use of this software.
9 *
10 * Permission is granted to anyone to use this software for any purpose,
11 * including commercial applications, and to alter it and redistribute it
12 * freely, subject to the following restrictions:
13 *
14 * 1. The origin of this software must not be misrepresented; you must not
15 * claim that you wrote the original software. If you use this software in
16 * a product, an acknowledgment in the product documentation would be
17 * appreciated but is not required.
18 * 2. Altered source versions must be plainly marked as such, and must not be
19 * misrepresented as being the original software.
20 * 3. This notice may not be removed or altered from any source distribution.
21 */
22
23
24#ifdef HAVE_CONFIG_H
25# include "config.h"
26#endif
27
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31
32#include "Embryo.h"
33#include "embryo_private.h"
34
35
36#define JUMPABS(base, ip) ((Embryo_Cell *)(code + (*ip)))
37
38#ifdef WORDS_BIGENDIAN
39static void _embryo_byte_swap_16 (unsigned short *v);
40static void _embryo_byte_swap_32 (unsigned int *v);
41#endif
42static int _embryo_native_call (Embryo_Program *ep, Embryo_Cell index, Embryo_Cell *result, Embryo_Cell *params);
43static int _embryo_func_get (Embryo_Program *ep, int index, char *funcname);
44static int _embryo_var_get (Embryo_Program *ep, int index, char *varname, Embryo_Cell *ep_addr);
45static int _embryo_program_init (Embryo_Program *ep, void *code);
46
47#ifdef WORDS_BIGENDIAN
48static void
49_embryo_byte_swap_16(unsigned short *v)
50{
51 unsigned char *s, t;
52
53 s = (unsigned char *)v;
54 t = s[0]; s[0] = s[1]; s[1] = t;
55}
56
57static void
58_embryo_byte_swap_32(unsigned int *v)
59{
60 unsigned char *s, t;
61
62 s = (unsigned char *)v;
63 t = s[0]; s[0] = s[3]; s[3] = t;
64 t = s[1]; s[1] = s[2]; s[2] = t;
65}
66#endif
67
68static int
69_embryo_native_call(Embryo_Program *ep, Embryo_Cell index, Embryo_Cell *result, Embryo_Cell *params)
70{
71 Embryo_Header *hdr;
72 Embryo_Func_Stub *func_entry;
73 Embryo_Native f;
74
75 hdr = (Embryo_Header *)ep->base;
76 func_entry = GETENTRY(hdr, natives, index);
77 if ((func_entry->address <= 0) ||
78 (func_entry->address > ep->native_calls_size))
79 {
80 ep->error = EMBRYO_ERROR_CALLBACK;
81 return ep->error;
82 }
83 f = ep->native_calls[func_entry->address - 1];
84 if (!f)
85 {
86 ep->error = EMBRYO_ERROR_CALLBACK;
87 return ep->error;
88 }
89 ep->error = EMBRYO_ERROR_NONE;
90 *result = f(ep, params);
91 return ep->error;
92}
93
94static int
95_embryo_func_get(Embryo_Program *ep, int index, char *funcname)
96{
97 Embryo_Header *hdr;
98 Embryo_Func_Stub *func;
99
100 hdr = (Embryo_Header *)ep->code;
101 if (index >= (Embryo_Cell)NUMENTRIES(hdr, publics, natives))
102 return EMBRYO_ERROR_INDEX;
103
104 func = GETENTRY(hdr, publics, index);
105 strcpy(funcname, GETENTRYNAME(hdr, func));
106 return EMBRYO_ERROR_NONE;
107}
108
109static int
110_embryo_var_get(Embryo_Program *ep, int index, char *varname, Embryo_Cell *ep_addr)
111{
112
113 Embryo_Header *hdr;
114 Embryo_Func_Stub *var;
115
116 hdr=(Embryo_Header *)ep->base;
117 if (index >= (Embryo_Cell)NUMENTRIES(hdr, pubvars, tags))
118 return EMBRYO_ERROR_INDEX;
119
120 var = GETENTRY(hdr, pubvars, index);
121 strcpy(varname, GETENTRYNAME(hdr, var));
122 *ep_addr = var->address;
123 return EMBRYO_ERROR_NONE;
124}
125
126static int
127_embryo_program_init(Embryo_Program *ep, void *code)
128{
129 Embryo_Header *hdr;
130
131 if ((ep->flags & EMBRYO_FLAG_RELOC)) return 1;
132 ep->code = (unsigned char *)code;
133 hdr = (Embryo_Header *)ep->code;
134#ifdef WORDS_BIGENDIAN
135 embryo_swap_32((unsigned int *)&hdr->size);
136 embryo_swap_16((unsigned short *)&hdr->magic);
137 embryo_swap_16((unsigned short *)&hdr->flags);
138 embryo_swap_16((unsigned short *)&hdr->defsize);
139 embryo_swap_32((unsigned int *)&hdr->cod);
140 embryo_swap_32((unsigned int *)&hdr->dat);
141 embryo_swap_32((unsigned int *)&hdr->hea);
142 embryo_swap_32((unsigned int *)&hdr->stp);
143 embryo_swap_32((unsigned int *)&hdr->cip);
144 embryo_swap_32((unsigned int *)&hdr->publics);
145 embryo_swap_32((unsigned int *)&hdr->natives);
146 embryo_swap_32((unsigned int *)&hdr->libraries);
147 embryo_swap_32((unsigned int *)&hdr->pubvars);
148 embryo_swap_32((unsigned int *)&hdr->tags);
149 embryo_swap_32((unsigned int *)&hdr->nametable);
150#endif
151
152 if (hdr->magic != EMBRYO_MAGIC) return 0;
153 if ((hdr->file_version < MIN_FILE_VERSION) ||
154 (hdr->ep_version > CUR_FILE_VERSION)) return 0;
155 if ((hdr->defsize != sizeof(Embryo_Func_Stub)) &&
156 (hdr->defsize != (2 * sizeof(unsigned int)))) return 0;
157 if (hdr->defsize == (2 * sizeof(unsigned int)))
158 {
159 unsigned short *len;
160
161 len = (unsigned short*)((unsigned char*)ep->code + hdr->nametable);
162#ifdef WORDS_BIGENDIAN
163 embryo_swap_16((unsigned short *)len);
164#endif
165 if (*len > sNAMEMAX) return 0;
166 }
167 if (hdr->stp <= 0) return 0;
168 if ((hdr->flags & EMBRYO_FLAG_COMPACT)) return 0;
169
170#ifdef WORDS_BIGENDIAN
171 {
172 Embryo_Func_Stub *fs;
173 int i, num;
174
175 /* also align all addresses in the public function, public variable and */
176 /* public tag tables */
177 fs = GETENTRY(hdr, publics, 0);
178 num = NUMENTRIES(hdr, publics, natives);
179 for (i = 0; i < num; i++)
180 {
181 embryo_swap_32(&(fs->address));
182 fs = (Embryo_Func_Stub *)((unsigned char *)fs + hdr->defsize);
183 }
184
185 fs = GETENTRY(hdr, pubvars, 0);
186 num = NUMENTRIES(hdr, pubvars, tags);
187 for (i = 0; i < num; i++)
188 {
189 embryo_swap_32(&(fs->address));
190 fs = (Embryo_Func_Stub *)((unsigned char *)fs + hdr->defsize);
191 }
192
193 fs = GETENTRY(hdr, tags, 0);
194 num = NUMENTRIES(hdr, tags, nametable);
195 for (i = 0; i < num; i++)
196 {
197 embryo_swap_32(&(fs->address));
198 fs = (Embryo_Func_Stub *)((unsigned char *)fs + hdr->defsize);
199 }
200 }
201#endif
202 ep->flags = EMBRYO_FLAG_RELOC;
203
204 {
205 Embryo_Cell cip, code_size, cip_end;
206 Embryo_Cell *code;
207
208 code_size = hdr->dat - hdr->cod;
209 code = (Embryo_Cell *)((unsigned char *)ep->code + (int)hdr->cod);
210 cip_end = code_size / sizeof(Embryo_Cell);
211 for (cip = 0; cip < cip_end; cip++)
212 {
213/* move this here - later we probably want something that verifies opcodes
214 * are valid and ok...
215 */
216#ifdef WORDS_BIGENDIAN
217 embryo_swap_32(&(code[cip]));
218#endif
219
220 }
221 }
222 /* init native api for handling floating point - default in embryo */
223 _embryo_args_init(ep);
224 _embryo_fp_init(ep);
225 _embryo_rand_init(ep);
226 _embryo_str_init(ep);
227 _embryo_time_init(ep);
228 return 1;
229}
230
231/*** EXPORTED CALLS ***/
232
233EAPI Embryo_Program *
234embryo_program_new(void *data, int size)
235{
236 Embryo_Program *ep;
237 void *code_data;
238
239 if (size < (int)sizeof(Embryo_Header)) return NULL;
240
241 ep = calloc(1, sizeof(Embryo_Program));
242 if (!ep) return NULL;
243
244 code_data = malloc(size);
245 if (!code_data)
246 {
247 free(ep);
248 return NULL;
249 }
250 memcpy(code_data, data, size);
251 if (_embryo_program_init(ep, code_data)) return ep;
252 free(code_data);
253 free(ep);
254 return NULL;
255}
256
257EAPI Embryo_Program *
258embryo_program_const_new(void *data, int size)
259{
260 Embryo_Program *ep;
261
262 if (size < (int)sizeof(Embryo_Header)) return NULL;
263
264 ep = calloc(1, sizeof(Embryo_Program));
265 if (!ep) return NULL;
266
267 if (_embryo_program_init(ep, data))
268 {
269 ep->dont_free_code = 1;
270 return ep;
271 }
272 free(ep);
273 return NULL;
274}
275
276EAPI Embryo_Program *
277embryo_program_load(const char *file)
278{
279 Embryo_Program *ep;
280 Embryo_Header hdr;
281 FILE *f;
282 void *program = NULL;
283 int program_size = 0;
284
285 f = fopen(file, "rb");
286 if (!f) return NULL;
287 fseek(f, 0, SEEK_END);
288 program_size = ftell(f);
289 fseek(f, 0L, SEEK_SET);
290 if (program_size < (int)sizeof(Embryo_Header))
291 {
292 fclose(f);
293 return NULL;
294 }
295 if (fread(&hdr, sizeof(Embryo_Header), 1, f) != 1)
296 {
297 fclose(f);
298 return NULL;
299 }
300 fseek(f, 0L, SEEK_SET);
301#ifdef WORDS_BIGENDIAN
302 embryo_swap_32((unsigned int *)(&hdr.size));
303#endif
304 if ((int)hdr.size < program_size) program_size = hdr.size;
305 program = malloc(program_size);
306 if (!program)
307 {
308 fclose(f);
309 return NULL;
310 }
311 if (fread(program, program_size, 1, f) != 1)
312 {
313 free(program);
314 fclose(f);
315 return NULL;
316 }
317 ep = embryo_program_new(program, program_size);
318 free(program);
319 fclose(f);
320 return ep;
321}
322
323EAPI void
324embryo_program_free(Embryo_Program *ep)
325{
326 int i;
327
328 if (ep->base) free(ep->base);
329 if ((!ep->dont_free_code) && (ep->code)) free(ep->code);
330 if (ep->native_calls) free(ep->native_calls);
331 for (i = 0; i < ep->params_size; i++)
332 {
333 if (ep->params[i].string) free(ep->params[i].string);
334 if (ep->params[i].cell_array) free(ep->params[i].cell_array);
335 }
336 if (ep->params) free(ep->params);
337 free(ep);
338}
339
340
341EAPI void
342embryo_program_native_call_add(Embryo_Program *ep, const char *name, Embryo_Cell (*func) (Embryo_Program *ep, Embryo_Cell *params))
343{
344 Embryo_Func_Stub *func_entry;
345 Embryo_Header *hdr;
346 int i, num;
347
348 if ((!ep ) || (!name) || (!func)) return;
349 if (strlen(name) > sNAMEMAX) return;
350
351 hdr = (Embryo_Header *)ep->code;
352 if (hdr->defsize < 1) return;
353 num = NUMENTRIES(hdr, natives, libraries);
354 if (num <= 0) return;
355
356 ep->native_calls_size++;
357 if (ep->native_calls_size > ep->native_calls_alloc)
358 {
359 Embryo_Native *calls;
360
361 ep->native_calls_alloc += 32;
362 calls = realloc(ep->native_calls,
363 ep->native_calls_alloc * sizeof(Embryo_Native));
364 if (!calls)
365 {
366 ep->native_calls_size--;
367 ep->native_calls_alloc -= 32;
368 return;
369 }
370 ep->native_calls = calls;
371 }
372 ep->native_calls[ep->native_calls_size - 1] = func;
373
374 func_entry = GETENTRY(hdr, natives, 0);
375 for (i = 0; i < num; i++)
376 {
377 if (func_entry->address == 0)
378 {
379 char *entry_name;
380
381 entry_name = GETENTRYNAME(hdr, func_entry);
382 if ((entry_name) && (!strcmp(entry_name, name)))
383 {
384 func_entry->address = ep->native_calls_size;
385 /* FIXME: embryo_cc is putting in multiple native */
386 /* function call entries - so we need to fill in all */
387 /* of them!!! */
388 /* return; */
389 }
390 }
391 func_entry =
392 (Embryo_Func_Stub *)((unsigned char *)func_entry + hdr->defsize);
393 }
394}
395
396
397EAPI void
398embryo_program_vm_reset(Embryo_Program *ep)
399{
400 Embryo_Header *hdr;
401
402 if ((!ep) || (!ep->base)) return;
403 hdr = (Embryo_Header *)ep->code;
404 memcpy(ep->base, hdr, hdr->size);
405 *(Embryo_Cell *)(ep->base + (int)hdr->stp - sizeof(Embryo_Cell)) = 0;
406
407 ep->hlw = hdr->hea - hdr->dat; /* stack and heap relative to data segment */
408 ep->stp = hdr->stp - hdr->dat - sizeof(Embryo_Cell);
409 ep->hea = ep->hlw;
410 ep->stk = ep->stp;
411}
412
413EAPI void
414embryo_program_vm_push(Embryo_Program *ep)
415{
416 Embryo_Header *hdr;
417
418 if (!ep) return;
419 ep->pushes++;
420 if (ep->pushes > 1)
421 {
422 embryo_program_vm_reset(ep);
423 return;
424 }
425 hdr = (Embryo_Header *)ep->code;
426 ep->base = malloc(hdr->stp);
427 if (!ep->base)
428 {
429 ep->pushes = 0;
430 return;
431 }
432 embryo_program_vm_reset(ep);
433}
434
435EAPI void
436embryo_program_vm_pop(Embryo_Program *ep)
437{
438 if ((!ep) || (!ep->base)) return;
439 ep->pushes--;
440 if (ep->pushes >= 1) return;
441 free(ep->base);
442 ep->base = NULL;
443}
444
445
446EAPI void
447embryo_swap_16(unsigned short *v
448#ifndef WORDS_BIGENDIAN
449 __UNUSED__
450#endif
451 )
452{
453#ifdef WORDS_BIGENDIAN
454 _embryo_byte_swap_16(v);
455#endif
456}
457
458EAPI void
459embryo_swap_32(unsigned int *v
460#ifndef WORDS_BIGENDIAN
461 __UNUSED__
462#endif
463 )
464{
465#ifdef WORDS_BIGENDIAN
466 _embryo_byte_swap_32(v);
467#endif
468}
469
470EAPI Embryo_Function
471embryo_program_function_find(Embryo_Program *ep, const char *name)
472{
473 int first, last, mid, result;
474 char pname[sNAMEMAX + 1];
475 Embryo_Header *hdr;
476
477 if (!ep) return EMBRYO_FUNCTION_NONE;
478 hdr = (Embryo_Header *)ep->code;
479 last = NUMENTRIES(hdr, publics, natives) - 1;
480 first = 0;
481 /* binary search */
482 while (first <= last)
483 {
484 mid = (first + last) / 2;
485 if (_embryo_func_get(ep, mid, pname) == EMBRYO_ERROR_NONE)
486 result = strcmp(pname, name);
487 else
488 return EMBRYO_FUNCTION_NONE;
489/* result = -1;*/
490 if (result > 0) last = mid - 1;
491 else if (result < 0) first = mid + 1;
492 else return mid;
493 }
494 return EMBRYO_FUNCTION_NONE;
495}
496
497
498EAPI Embryo_Cell
499embryo_program_variable_find(Embryo_Program *ep, const char *name)
500{
501 int first, last, mid, result;
502 char pname[sNAMEMAX + 1];
503 Embryo_Cell paddr;
504 Embryo_Header *hdr;
505
506 if (!ep) return EMBRYO_CELL_NONE;
507 if (!ep->base) return EMBRYO_CELL_NONE;
508 hdr = (Embryo_Header *)ep->base;
509 last = NUMENTRIES(hdr, pubvars, tags) - 1;
510 first = 0;
511 /* binary search */
512 while (first <= last)
513 {
514 mid = (first + last) / 2;
515 if (_embryo_var_get(ep, mid, pname, &paddr) == EMBRYO_ERROR_NONE)
516 result = strcmp(pname, name);
517 else
518 return EMBRYO_CELL_NONE;
519/* result = -1;*/
520 if (result > 0) last = mid - 1;
521 else if (result < 0) first = mid + 1;
522 else return paddr;
523 }
524 return EMBRYO_CELL_NONE;
525}
526
527EAPI int
528embryo_program_variable_count_get(Embryo_Program *ep)
529{
530 Embryo_Header *hdr;
531
532 if (!ep) return 0;
533 if (!ep->base) return 0;
534 hdr = (Embryo_Header *)ep->base;
535 return NUMENTRIES(hdr, pubvars, tags);
536}
537
538EAPI Embryo_Cell
539embryo_program_variable_get(Embryo_Program *ep, int num)
540{
541 Embryo_Cell paddr;
542 char pname[sNAMEMAX + 1];
543
544 if (!ep) return EMBRYO_CELL_NONE;
545 if (!ep->base) return EMBRYO_CELL_NONE;
546 if (_embryo_var_get(ep, num, pname, &paddr) == EMBRYO_ERROR_NONE)
547 return paddr;
548 return EMBRYO_CELL_NONE;
549}
550
551
552EAPI void
553embryo_program_error_set(Embryo_Program *ep, Embryo_Error error)
554{
555 if (!ep) return;
556 ep->error = error;
557}
558
559EAPI Embryo_Error
560embryo_program_error_get(Embryo_Program *ep)
561{
562 if (!ep) return EMBRYO_ERROR_NONE;
563 return ep->error;
564}
565
566
567EAPI void
568embryo_program_data_set(Embryo_Program *ep, void *data)
569{
570 if (!ep) return;
571 ep->data = data;
572}
573
574EAPI void *
575embryo_program_data_get(Embryo_Program *ep)
576{
577 if (!ep) return NULL;
578 return ep->data;
579}
580
581EAPI const char *
582embryo_error_string_get(Embryo_Error error)
583{
584 const char *messages[] =
585 {
586 /* EMBRYO_ERROR_NONE */ "(none)",
587 /* EMBRYO_ERROR_EXIT */ "Forced exit",
588 /* EMBRYO_ERROR_ASSERT */ "Assertion failed",
589 /* EMBRYO_ERROR_STACKERR */ "Stack/heap collision (insufficient stack size)",
590 /* EMBRYO_ERROR_BOUNDS */ "Array index out of bounds",
591 /* EMBRYO_ERROR_MEMACCESS */ "Invalid memory access",
592 /* EMBRYO_ERROR_INVINSTR */ "Invalid instruction",
593 /* EMBRYO_ERROR_STACKLOW */ "Stack underflow",
594 /* EMBRYO_ERROR_HEAPLOW */ "Heap underflow",
595 /* EMBRYO_ERROR_CALLBACK */ "No (valid) native function callback",
596 /* EMBRYO_ERROR_NATIVE */ "Native function failed",
597 /* EMBRYO_ERROR_DIVIDE */ "Divide by zero",
598 /* EMBRYO_ERROR_SLEEP */ "(sleep mode)",
599 /* 13 */ "(reserved)",
600 /* 14 */ "(reserved)",
601 /* 15 */ "(reserved)",
602 /* EMBRYO_ERROR_MEMORY */ "Out of memory",
603 /* EMBRYO_ERROR_FORMAT */ "Invalid/unsupported P-code file format",
604 /* EMBRYO_ERROR_VERSION */ "File is for a newer version of the Embryo_Program",
605 /* EMBRYO_ERROR_NOTFOUND */ "Native/Public function is not found",
606 /* EMBRYO_ERROR_INDEX */ "Invalid index parameter (bad entry point)",
607 /* EMBRYO_ERROR_DEBUG */ "Debugger cannot run",
608 /* EMBRYO_ERROR_INIT */ "Embryo_Program not initialized (or doubly initialized)",
609 /* EMBRYO_ERROR_USERDATA */ "Unable to set user data field (table full)",
610 /* EMBRYO_ERROR_INIT_JIT */ "Cannot initialize the JIT",
611 /* EMBRYO_ERROR_PARAMS */ "Parameter error",
612 };
613 if (((int)error < 0) ||
614 ((int)error >= (int)(sizeof(messages) / sizeof(messages[0]))))
615 return (const char *)"(unknown)";
616 return messages[error];
617}
618
619
620EAPI int
621embryo_data_string_length_get(Embryo_Program *ep, Embryo_Cell *str_cell)
622{
623 int len;
624 Embryo_Header *hdr;
625
626 if ((!ep) || (!ep->base)) return 0;
627 hdr = (Embryo_Header *)ep->base;
628 if ((!str_cell) ||
629 ((void *)str_cell >= (void *)(ep->base + hdr->stp)) ||
630 ((void *)str_cell < (void *)ep->base))
631 return 0;
632 for (len = 0; str_cell[len] != 0; len++);
633 return len;
634}
635
636EAPI void
637embryo_data_string_get(Embryo_Program *ep, Embryo_Cell *str_cell, char *dst)
638{
639 int i;
640 Embryo_Header *hdr;
641
642 if (!dst) return;
643 if ((!ep) || (!ep->base))
644 {
645 dst[0] = 0;
646 return;
647 }
648 hdr = (Embryo_Header *)ep->base;
649 if ((!str_cell) ||
650 ((void *)str_cell >= (void *)(ep->base + hdr->stp)) ||
651 ((void *)str_cell < (void *)ep->base))
652 {
653 dst[0] = 0;
654 return;
655 }
656 for (i = 0; str_cell[i] != 0; i++)
657 {
658#ifdef WORDS_BIGENDIAN
659 {
660 Embryo_Cell tmp;
661
662 tmp = str_cell[i];
663 _embryo_byte_swap_32(&tmp);
664 dst[i] = tmp;
665 }
666#else
667 dst[i] = str_cell[i];
668#endif
669 }
670 dst[i] = 0;
671}
672
673EAPI void
674embryo_data_string_set(Embryo_Program *ep, const char *src, Embryo_Cell *str_cell)
675{
676 int i;
677 Embryo_Header *hdr;
678
679 if (!ep) return;
680 if (!ep->base) return;
681 hdr = (Embryo_Header *)ep->base;
682 if ((!str_cell) ||
683 ((void *)str_cell >= (void *)(ep->base + hdr->stp)) ||
684 ((void *)str_cell < (void *)ep->base))
685 return;
686 if (!src)
687 {
688 str_cell[0] = 0;
689 return;
690 }
691 for (i = 0; src[i] != 0; i++)
692 {
693 if ((void *)(&(str_cell[i])) >= (void *)(ep->base + hdr->stp)) return;
694 else if ((void *)(&(str_cell[i])) == (void *)(ep->base + hdr->stp - 1))
695 {
696 str_cell[i] = 0;
697 return;
698 }
699#ifdef WORDS_BIGENDIAN
700 {
701 Embryo_Cell tmp;
702
703 tmp = src[i];
704 _embryo_byte_swap_32(&tmp);
705 str_cell[i] = tmp;
706 }
707#else
708 str_cell[i] = src[i];
709#endif
710 }
711 str_cell[i] = 0;
712}
713
714EAPI Embryo_Cell *
715embryo_data_address_get(Embryo_Program *ep, Embryo_Cell addr)
716{
717 Embryo_Header *hdr;
718 unsigned char *data;
719
720 if ((!ep) || (!ep->base)) return NULL;
721 hdr = (Embryo_Header *)ep->base;
722 data = ep->base + (int)hdr->dat;
723 if ((addr < 0) || (addr >= hdr->stp)) return NULL;
724 return (Embryo_Cell *)(data + (int)addr);
725}
726
727
728EAPI Embryo_Cell
729embryo_data_heap_push(Embryo_Program *ep, int cells)
730{
731 Embryo_Header *hdr;
732 Embryo_Cell addr;
733
734 if ((!ep) || (!ep->base)) return EMBRYO_CELL_NONE;
735 hdr = (Embryo_Header *)ep->base;
736 if (ep->stk - ep->hea - (cells * sizeof(Embryo_Cell)) < STKMARGIN)
737 return EMBRYO_CELL_NONE;
738 addr = ep->hea;
739 ep->hea += (cells * sizeof(Embryo_Cell));
740 return addr;
741}
742
743EAPI void
744embryo_data_heap_pop(Embryo_Program *ep, Embryo_Cell down_to)
745{
746 if (!ep) return;
747 if (down_to < 0) down_to = 0;
748 if (ep->hea > down_to) ep->hea = down_to;
749}
750
751
752EAPI int
753embryo_program_recursion_get(Embryo_Program *ep)
754{
755 return ep->run_count;
756}
757
758#ifdef __GNUC__
759#if 1
760#define EMBRYO_EXEC_JUMPTABLE
761#endif
762#endif
763
764/* jump table optimization - only works for gcc though */
765#ifdef EMBRYO_EXEC_JUMPTABLE
766#define SWITCH(x) while (1) { goto *switchtable[x];
767#define SWITCHEND break; }
768#define CASE(x) SWITCHTABLE_##x:
769#define BREAK break;
770#else
771#define SWITCH(x) switch (x) {
772#define SWITCHEND }
773#define CASE(x) case x:
774#define BREAK break
775#endif
776
777EAPI Embryo_Status
778embryo_program_run(Embryo_Program *ep, Embryo_Function fn)
779{
780 Embryo_Header *hdr;
781 Embryo_Func_Stub *func;
782 unsigned char *code, *data;
783 Embryo_Cell pri, alt, stk, frm, hea, hea_start;
784 Embryo_Cell reset_stk, reset_hea, *cip;
785 Embryo_UCell codesize;
786 int i;
787 unsigned char op;
788 Embryo_Cell offs;
789 int num;
790 int max_run_cycles;
791 int cycle_count;
792#ifdef EMBRYO_EXEC_JUMPTABLE
793 /* we limit the jumptable to 256 elements. why? above we forced "op" to be
794 * a unsigned char - that means 256 max values. we limit opcode overflow
795 * here, so eliminating crashes on table lookups with bad/corrupt bytecode.
796 * no need to atuall do compares, branches etc. the datatype does the work
797 * for us. so that means EXCESS elements are all declared as OP_NONE to
798 * keep them innocuous.
799 */
800 static const void *switchtable[256] =
801 {
802 &&SWITCHTABLE_EMBRYO_OP_NONE,
803 &&SWITCHTABLE_EMBRYO_OP_LOAD_PRI,
804 &&SWITCHTABLE_EMBRYO_OP_LOAD_ALT,
805 &&SWITCHTABLE_EMBRYO_OP_LOAD_S_PRI,
806 &&SWITCHTABLE_EMBRYO_OP_LOAD_S_ALT,
807 &&SWITCHTABLE_EMBRYO_OP_LREF_PRI,
808 &&SWITCHTABLE_EMBRYO_OP_LREF_ALT,
809 &&SWITCHTABLE_EMBRYO_OP_LREF_S_PRI,
810 &&SWITCHTABLE_EMBRYO_OP_LREF_S_ALT,
811 &&SWITCHTABLE_EMBRYO_OP_LOAD_I,
812 &&SWITCHTABLE_EMBRYO_OP_LODB_I,
813 &&SWITCHTABLE_EMBRYO_OP_CONST_PRI,
814 &&SWITCHTABLE_EMBRYO_OP_CONST_ALT,
815 &&SWITCHTABLE_EMBRYO_OP_ADDR_PRI,
816 &&SWITCHTABLE_EMBRYO_OP_ADDR_ALT,
817 &&SWITCHTABLE_EMBRYO_OP_STOR_PRI,
818 &&SWITCHTABLE_EMBRYO_OP_STOR_ALT,
819 &&SWITCHTABLE_EMBRYO_OP_STOR_S_PRI,
820 &&SWITCHTABLE_EMBRYO_OP_STOR_S_ALT,
821 &&SWITCHTABLE_EMBRYO_OP_SREF_PRI,
822 &&SWITCHTABLE_EMBRYO_OP_SREF_ALT,
823 &&SWITCHTABLE_EMBRYO_OP_SREF_S_PRI,
824 &&SWITCHTABLE_EMBRYO_OP_SREF_S_ALT,
825 &&SWITCHTABLE_EMBRYO_OP_STOR_I,
826 &&SWITCHTABLE_EMBRYO_OP_STRB_I,
827 &&SWITCHTABLE_EMBRYO_OP_LIDX,
828 &&SWITCHTABLE_EMBRYO_OP_LIDX_B,
829 &&SWITCHTABLE_EMBRYO_OP_IDXADDR,
830 &&SWITCHTABLE_EMBRYO_OP_IDXADDR_B,
831 &&SWITCHTABLE_EMBRYO_OP_ALIGN_PRI,
832 &&SWITCHTABLE_EMBRYO_OP_ALIGN_ALT,
833 &&SWITCHTABLE_EMBRYO_OP_LCTRL,
834 &&SWITCHTABLE_EMBRYO_OP_SCTRL,
835 &&SWITCHTABLE_EMBRYO_OP_MOVE_PRI,
836 &&SWITCHTABLE_EMBRYO_OP_MOVE_ALT,
837 &&SWITCHTABLE_EMBRYO_OP_XCHG,
838 &&SWITCHTABLE_EMBRYO_OP_PUSH_PRI,
839 &&SWITCHTABLE_EMBRYO_OP_PUSH_ALT,
840 &&SWITCHTABLE_EMBRYO_OP_PUSH_R,
841 &&SWITCHTABLE_EMBRYO_OP_PUSH_C,
842 &&SWITCHTABLE_EMBRYO_OP_PUSH,
843 &&SWITCHTABLE_EMBRYO_OP_PUSH_S,
844 &&SWITCHTABLE_EMBRYO_OP_POP_PRI,
845 &&SWITCHTABLE_EMBRYO_OP_POP_ALT,
846 &&SWITCHTABLE_EMBRYO_OP_STACK,
847 &&SWITCHTABLE_EMBRYO_OP_HEAP,
848 &&SWITCHTABLE_EMBRYO_OP_PROC,
849 &&SWITCHTABLE_EMBRYO_OP_RET,
850 &&SWITCHTABLE_EMBRYO_OP_RETN,
851 &&SWITCHTABLE_EMBRYO_OP_CALL,
852 &&SWITCHTABLE_EMBRYO_OP_CALL_PRI,
853 &&SWITCHTABLE_EMBRYO_OP_JUMP,
854 &&SWITCHTABLE_EMBRYO_OP_JREL,
855 &&SWITCHTABLE_EMBRYO_OP_JZER,
856 &&SWITCHTABLE_EMBRYO_OP_JNZ,
857 &&SWITCHTABLE_EMBRYO_OP_JEQ,
858 &&SWITCHTABLE_EMBRYO_OP_JNEQ,
859 &&SWITCHTABLE_EMBRYO_OP_JLESS,
860 &&SWITCHTABLE_EMBRYO_OP_JLEQ,
861 &&SWITCHTABLE_EMBRYO_OP_JGRTR,
862 &&SWITCHTABLE_EMBRYO_OP_JGEQ,
863 &&SWITCHTABLE_EMBRYO_OP_JSLESS,
864 &&SWITCHTABLE_EMBRYO_OP_JSLEQ,
865 &&SWITCHTABLE_EMBRYO_OP_JSGRTR,
866 &&SWITCHTABLE_EMBRYO_OP_JSGEQ,
867 &&SWITCHTABLE_EMBRYO_OP_SHL,
868 &&SWITCHTABLE_EMBRYO_OP_SHR,
869 &&SWITCHTABLE_EMBRYO_OP_SSHR,
870 &&SWITCHTABLE_EMBRYO_OP_SHL_C_PRI,
871 &&SWITCHTABLE_EMBRYO_OP_SHL_C_ALT,
872 &&SWITCHTABLE_EMBRYO_OP_SHR_C_PRI,
873 &&SWITCHTABLE_EMBRYO_OP_SHR_C_ALT,
874 &&SWITCHTABLE_EMBRYO_OP_SMUL,
875 &&SWITCHTABLE_EMBRYO_OP_SDIV,
876 &&SWITCHTABLE_EMBRYO_OP_SDIV_ALT,
877 &&SWITCHTABLE_EMBRYO_OP_UMUL,
878 &&SWITCHTABLE_EMBRYO_OP_UDIV,
879 &&SWITCHTABLE_EMBRYO_OP_UDIV_ALT,
880 &&SWITCHTABLE_EMBRYO_OP_ADD,
881 &&SWITCHTABLE_EMBRYO_OP_SUB,
882 &&SWITCHTABLE_EMBRYO_OP_SUB_ALT,
883 &&SWITCHTABLE_EMBRYO_OP_AND,
884 &&SWITCHTABLE_EMBRYO_OP_OR,
885 &&SWITCHTABLE_EMBRYO_OP_XOR,
886 &&SWITCHTABLE_EMBRYO_OP_NOT,
887 &&SWITCHTABLE_EMBRYO_OP_NEG,
888 &&SWITCHTABLE_EMBRYO_OP_INVERT,
889 &&SWITCHTABLE_EMBRYO_OP_ADD_C,
890 &&SWITCHTABLE_EMBRYO_OP_SMUL_C,
891 &&SWITCHTABLE_EMBRYO_OP_ZERO_PRI,
892 &&SWITCHTABLE_EMBRYO_OP_ZERO_ALT,
893 &&SWITCHTABLE_EMBRYO_OP_ZERO,
894 &&SWITCHTABLE_EMBRYO_OP_ZERO_S,
895 &&SWITCHTABLE_EMBRYO_OP_SIGN_PRI,
896 &&SWITCHTABLE_EMBRYO_OP_SIGN_ALT,
897 &&SWITCHTABLE_EMBRYO_OP_EQ,
898 &&SWITCHTABLE_EMBRYO_OP_NEQ,
899 &&SWITCHTABLE_EMBRYO_OP_LESS,
900 &&SWITCHTABLE_EMBRYO_OP_LEQ,
901 &&SWITCHTABLE_EMBRYO_OP_GRTR,
902 &&SWITCHTABLE_EMBRYO_OP_GEQ,
903 &&SWITCHTABLE_EMBRYO_OP_SLESS,
904 &&SWITCHTABLE_EMBRYO_OP_SLEQ,
905 &&SWITCHTABLE_EMBRYO_OP_SGRTR,
906 &&SWITCHTABLE_EMBRYO_OP_SGEQ,
907 &&SWITCHTABLE_EMBRYO_OP_EQ_C_PRI,
908 &&SWITCHTABLE_EMBRYO_OP_EQ_C_ALT,
909 &&SWITCHTABLE_EMBRYO_OP_INC_PRI,
910 &&SWITCHTABLE_EMBRYO_OP_INC_ALT,
911 &&SWITCHTABLE_EMBRYO_OP_INC,
912 &&SWITCHTABLE_EMBRYO_OP_INC_S,
913 &&SWITCHTABLE_EMBRYO_OP_INC_I,
914 &&SWITCHTABLE_EMBRYO_OP_DEC_PRI,
915 &&SWITCHTABLE_EMBRYO_OP_DEC_ALT,
916 &&SWITCHTABLE_EMBRYO_OP_DEC,
917 &&SWITCHTABLE_EMBRYO_OP_DEC_S,
918 &&SWITCHTABLE_EMBRYO_OP_DEC_I,
919 &&SWITCHTABLE_EMBRYO_OP_MOVS,
920 &&SWITCHTABLE_EMBRYO_OP_CMPS,
921 &&SWITCHTABLE_EMBRYO_OP_FILL,
922 &&SWITCHTABLE_EMBRYO_OP_HALT,
923 &&SWITCHTABLE_EMBRYO_OP_BOUNDS,
924 &&SWITCHTABLE_EMBRYO_OP_SYSREQ_PRI,
925 &&SWITCHTABLE_EMBRYO_OP_SYSREQ_C,
926 &&SWITCHTABLE_EMBRYO_OP_FILE,
927 &&SWITCHTABLE_EMBRYO_OP_LINE,
928 &&SWITCHTABLE_EMBRYO_OP_SYMBOL,
929 &&SWITCHTABLE_EMBRYO_OP_SRANGE,
930 &&SWITCHTABLE_EMBRYO_OP_JUMP_PRI,
931 &&SWITCHTABLE_EMBRYO_OP_SWITCH,
932 &&SWITCHTABLE_EMBRYO_OP_CASETBL,
933 &&SWITCHTABLE_EMBRYO_OP_SWAP_PRI,
934 &&SWITCHTABLE_EMBRYO_OP_SWAP_ALT,
935 &&SWITCHTABLE_EMBRYO_OP_PUSHADDR,
936 &&SWITCHTABLE_EMBRYO_OP_NOP,
937 &&SWITCHTABLE_EMBRYO_OP_SYSREQ_D,
938 &&SWITCHTABLE_EMBRYO_OP_SYMTAG,
939 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
940 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
941 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
942 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
943 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
944 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
945 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
946 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
947 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
948 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
949 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
950 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
951 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
952 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
953 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
954 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
955 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
956 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
957 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
958 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
959 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
960 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
961 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE,
962 &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE
963 };
964#endif
965 if (!ep) return EMBRYO_PROGRAM_FAIL;
966 if (!(ep->flags & EMBRYO_FLAG_RELOC))
967 {
968 ep->error = EMBRYO_ERROR_INIT;
969 return EMBRYO_PROGRAM_FAIL;
970 }
971 if (!ep->base)
972 {
973 ep->error = EMBRYO_ERROR_INIT;
974 return EMBRYO_PROGRAM_FAIL;
975 }
976 if (ep->run_count > 0)
977 {
978 /* return EMBRYO_PROGRAM_BUSY; */
979 /* FIXME: test C->vm->C->vm recursion more fully */
980 /* it seems to work... just fine!!! - strange! */
981 }
982
983 /* set up the registers */
984 hdr = (Embryo_Header *)ep->base;
985 codesize = (Embryo_UCell)(hdr->dat - hdr->cod);
986 code = ep->base + (int)hdr->cod;
987 data = ep->base + (int)hdr->dat;
988 hea_start = hea = ep->hea;
989 stk = ep->stk;
990 reset_stk = stk;
991 reset_hea = hea;
992 frm = alt = pri = 0;
993
994 /* get the start address */
995 if (fn == EMBRYO_FUNCTION_MAIN)
996 {
997 if (hdr->cip < 0)
998 {
999 ep->error = EMBRYO_ERROR_INDEX;
1000 return EMBRYO_PROGRAM_FAIL;
1001 }
1002 cip = (Embryo_Cell *)(code + (int)hdr->cip);
1003 }
1004 else if (fn == EMBRYO_FUNCTION_CONT)
1005 {
1006 /* all registers: pri, alt, frm, cip, hea, stk, reset_stk, reset_hea */
1007 frm = ep->frm;
1008 stk = ep->stk;
1009 hea = ep->hea;
1010 pri = ep->pri;
1011 alt = ep->alt;
1012 reset_stk = ep->reset_stk;
1013 reset_hea = ep->reset_hea;
1014 cip = (Embryo_Cell *)(code + (int)ep->cip);
1015 }
1016 else if (fn < 0)
1017 {
1018 ep->error = EMBRYO_ERROR_INDEX;
1019 return EMBRYO_PROGRAM_FAIL;
1020 }
1021 else
1022 {
1023 if (fn >= (Embryo_Cell)NUMENTRIES(hdr, publics, natives))
1024 {
1025 ep->error = EMBRYO_ERROR_INDEX;
1026 return EMBRYO_PROGRAM_FAIL;
1027 }
1028 func = GETENTRY(hdr, publics, fn);
1029 cip = (Embryo_Cell *)(code + (int)func->address);
1030 }
1031 /* check values just copied */
1032 CHKSTACK();
1033 CHKHEAP();
1034
1035 if (fn != EMBRYO_FUNCTION_CONT)
1036 {
1037 int i;
1038
1039 for (i = ep->params_size - 1; i >= 0; i--)
1040 {
1041 Embryo_Param *pr;
1042
1043 pr = &(ep->params[i]);
1044 if (pr->string)
1045 {
1046 int len;
1047 Embryo_Cell ep_addr, *addr;
1048
1049 len = strlen(pr->string);
1050 ep_addr = embryo_data_heap_push(ep, len + 1);
1051 if (ep_addr == EMBRYO_CELL_NONE)
1052 {
1053 ep->error = EMBRYO_ERROR_HEAPLOW;
1054 return EMBRYO_PROGRAM_FAIL;
1055 }
1056 addr = embryo_data_address_get(ep, ep_addr);
1057 if (addr)
1058 embryo_data_string_set(ep, pr->string, addr);
1059 else
1060 {
1061 ep->error = EMBRYO_ERROR_HEAPLOW;
1062 return EMBRYO_PROGRAM_FAIL;
1063 }
1064 PUSH(ep_addr);
1065 free(pr->string);
1066 }
1067 else if (pr->cell_array)
1068 {
1069 int len;
1070 Embryo_Cell ep_addr, *addr;
1071
1072 len = pr->cell_array_size;
1073 ep_addr = embryo_data_heap_push(ep, len + 1);
1074 if (ep_addr == EMBRYO_CELL_NONE)
1075 {
1076 ep->error = EMBRYO_ERROR_HEAPLOW;
1077 return EMBRYO_PROGRAM_FAIL;
1078 }
1079 addr = embryo_data_address_get(ep, ep_addr);
1080 if (addr)
1081 memcpy(addr, pr->cell_array,
1082 pr->cell_array_size * sizeof(Embryo_Cell));
1083 else
1084 {
1085 ep->error = EMBRYO_ERROR_HEAPLOW;
1086 return EMBRYO_PROGRAM_FAIL;
1087 }
1088 PUSH(ep_addr);
1089 free(pr->cell_array);
1090 }
1091 else
1092 {
1093 PUSH(pr->cell);
1094 }
1095 }
1096 PUSH(ep->params_size * sizeof(Embryo_Cell));
1097 PUSH(0);
1098 if (ep->params)
1099 {
1100 free(ep->params);
1101 ep->params = NULL;
1102 }
1103 ep->params_size = ep->params_alloc = 0;
1104 }
1105 /* check stack/heap before starting to run */
1106 CHKMARGIN();
1107
1108 /* track recursion depth */
1109 ep->run_count++;
1110
1111 max_run_cycles = ep->max_run_cycles;
1112 /* start running */
1113 for (cycle_count = 0;;)
1114 {
1115 if (max_run_cycles > 0)
1116 {
1117 if (cycle_count >= max_run_cycles)
1118 {
1119 TOOLONG(ep);
1120 }
1121 cycle_count++;
1122 }
1123 op = (Embryo_Opcode)*cip++;
1124 SWITCH(op);
1125 CASE(EMBRYO_OP_LOAD_PRI);
1126 GETPARAM(offs);
1127 pri = *(Embryo_Cell *)(data + (int)offs);
1128 BREAK;
1129 CASE(EMBRYO_OP_LOAD_ALT);
1130 GETPARAM(offs);
1131 alt = *(Embryo_Cell *)(data + (int)offs);
1132 BREAK;
1133 CASE(EMBRYO_OP_LOAD_S_PRI);
1134 GETPARAM(offs);
1135 pri = *(Embryo_Cell *)(data + (int)frm + (int)offs);
1136 BREAK;
1137 CASE(EMBRYO_OP_LOAD_S_ALT);
1138 GETPARAM(offs);
1139 alt = *(Embryo_Cell *)(data + (int)frm + (int)offs);
1140 BREAK;
1141 CASE(EMBRYO_OP_LREF_PRI);
1142 GETPARAM(offs);
1143 offs = *(Embryo_Cell *)(data + (int)offs);
1144 pri = *(Embryo_Cell *)(data + (int)offs);
1145 BREAK;
1146 CASE(EMBRYO_OP_LREF_ALT);
1147 GETPARAM(offs);
1148 offs = *(Embryo_Cell *)(data + (int)offs);
1149 alt = *(Embryo_Cell *)(data + (int)offs);
1150 BREAK;
1151 CASE(EMBRYO_OP_LREF_S_PRI);
1152 GETPARAM(offs);
1153 offs = *(Embryo_Cell *)(data + (int)frm + (int)offs);
1154 pri = *(Embryo_Cell *)(data + (int)offs);
1155 BREAK;
1156 CASE(EMBRYO_OP_LREF_S_ALT);
1157 GETPARAM(offs);
1158 offs = *(Embryo_Cell *)(data + (int)frm + (int)offs);
1159 alt = *(Embryo_Cell *)(data + (int)offs);
1160 BREAK;
1161 CASE(EMBRYO_OP_LOAD_I);
1162 CHKMEM(pri);
1163 pri = *(Embryo_Cell *)(data + (int)pri);
1164 BREAK;
1165 CASE(EMBRYO_OP_LODB_I);
1166 GETPARAM(offs);
1167 CHKMEM(pri);
1168 switch (offs)
1169 {
1170 case 1:
1171 pri = *(data + (int)pri);
1172 break;
1173 case 2:
1174 pri = *(unsigned short *)(data + (int)pri);
1175 break;
1176 case 4:
1177 pri = *(unsigned int *)(data + (int)pri);
1178 break;
1179 default:
1180 ABORT(ep, EMBRYO_ERROR_INVINSTR);
1181 break;
1182 }
1183 BREAK;
1184 CASE(EMBRYO_OP_CONST_PRI);
1185 GETPARAM(pri);
1186 BREAK;
1187 CASE(EMBRYO_OP_CONST_ALT);
1188 GETPARAM(alt);
1189 BREAK;
1190 CASE(EMBRYO_OP_ADDR_PRI);
1191 GETPARAM(pri);
1192 pri += frm;
1193 BREAK;
1194 CASE(EMBRYO_OP_ADDR_ALT);
1195 GETPARAM(alt);
1196 alt += frm;
1197 BREAK;
1198 CASE(EMBRYO_OP_STOR_PRI);
1199 GETPARAM(offs);
1200 *(Embryo_Cell *)(data + (int)offs) = pri;
1201 BREAK;
1202 CASE(EMBRYO_OP_STOR_ALT);
1203 GETPARAM(offs);
1204 *(Embryo_Cell *)(data + (int)offs) = alt;
1205 BREAK;
1206 CASE(EMBRYO_OP_STOR_S_PRI);
1207 GETPARAM(offs);
1208 *(Embryo_Cell *)(data + (int)frm + (int)offs) = pri;
1209 BREAK;
1210 CASE(EMBRYO_OP_STOR_S_ALT);
1211 GETPARAM(offs);
1212 *(Embryo_Cell *)(data + (int)frm + (int)offs) = alt;
1213 BREAK;
1214 CASE(EMBRYO_OP_SREF_PRI);
1215 GETPARAM(offs);
1216 offs = *(Embryo_Cell *)(data + (int)offs);
1217 *(Embryo_Cell *)(data + (int)offs) = pri;
1218 BREAK;
1219 CASE(EMBRYO_OP_SREF_ALT);
1220 GETPARAM(offs);
1221 offs = *(Embryo_Cell *)(data + (int)offs);
1222 *(Embryo_Cell *)(data + (int)offs) = alt;
1223 BREAK;
1224 CASE(EMBRYO_OP_SREF_S_PRI);
1225 GETPARAM(offs);
1226 offs = *(Embryo_Cell *)(data + (int)frm + (int)offs);
1227 *(Embryo_Cell *)(data + (int)offs) = pri;
1228 BREAK;
1229 CASE(EMBRYO_OP_SREF_S_ALT);
1230 GETPARAM(offs);
1231 offs = *(Embryo_Cell *)(data + (int)frm + (int)offs);
1232 *(Embryo_Cell *)(data + (int)offs) = alt;
1233 BREAK;
1234 CASE(EMBRYO_OP_STOR_I);
1235 CHKMEM(alt);
1236 *(Embryo_Cell *)(data + (int)alt) = pri;
1237 BREAK;
1238 CASE(EMBRYO_OP_STRB_I);
1239 GETPARAM(offs);
1240 CHKMEM(alt);
1241 switch (offs)
1242 {
1243 case 1:
1244 *(data + (int)alt) = (unsigned char)pri;
1245 break;
1246 case 2:
1247 *(unsigned short *)(data + (int)alt) = (unsigned short)pri;
1248 break;
1249 case 4:
1250 *(unsigned int *)(data + (int)alt) = (unsigned int)pri;
1251 break;
1252 default:
1253 ABORT(ep, EMBRYO_ERROR_INVINSTR);
1254 break;
1255 }
1256 BREAK;
1257 CASE(EMBRYO_OP_LIDX);
1258 offs = (pri * sizeof(Embryo_Cell)) + alt;
1259 CHKMEM(offs);
1260 pri = *(Embryo_Cell *)(data + (int)offs);
1261 BREAK;
1262 CASE(EMBRYO_OP_LIDX_B);
1263 GETPARAM(offs);
1264 offs = (pri << (int)offs) + alt;
1265 CHKMEM(offs);
1266 pri = *(Embryo_Cell *)(data + (int)offs);
1267 BREAK;
1268 CASE(EMBRYO_OP_IDXADDR);
1269 pri = (pri * sizeof(Embryo_Cell)) + alt;
1270 BREAK;
1271 CASE(EMBRYO_OP_IDXADDR_B);
1272 GETPARAM(offs);
1273 pri = (pri << (int)offs) + alt;
1274 BREAK;
1275 CASE(EMBRYO_OP_ALIGN_PRI);
1276 GETPARAM(offs);
1277#ifdef WORDS_BIGENDIAN
1278 if ((size_t)offs < sizeof(Embryo_Cell))
1279 pri ^= sizeof(Embryo_Cell) - offs;
1280#endif
1281 BREAK;
1282 CASE(EMBRYO_OP_ALIGN_ALT);
1283 GETPARAM(offs);
1284#ifdef WORDS_BIGENDIAN
1285 if ((size_t)offs < sizeof(Embryo_Cell))
1286 alt ^= sizeof(Embryo_Cell) - offs;
1287#endif
1288 BREAK;
1289 CASE(EMBRYO_OP_LCTRL);
1290 GETPARAM(offs);
1291 switch (offs)
1292 {
1293 case 0:
1294 pri = hdr->cod;
1295 break;
1296 case 1:
1297 pri = hdr->dat;
1298 break;
1299 case 2:
1300 pri = hea;
1301 break;
1302 case 3:
1303 pri = ep->stp;
1304 break;
1305 case 4:
1306 pri = stk;
1307 break;
1308 case 5:
1309 pri = frm;
1310 break;
1311 case 6:
1312 pri = (Embryo_Cell)((unsigned char *)cip - code);
1313 break;
1314 default:
1315 ABORT(ep, EMBRYO_ERROR_INVINSTR);
1316 break;
1317 }
1318 BREAK;
1319 CASE(EMBRYO_OP_SCTRL);
1320 GETPARAM(offs);
1321 switch (offs)
1322 {
1323 case 0:
1324 case 1:
1325 case 2:
1326 hea = pri;
1327 break;
1328 case 3:
1329 /* cannot change these parameters */
1330 break;
1331 case 4:
1332 stk = pri;
1333 break;
1334 case 5:
1335 frm = pri;
1336 break;
1337 case 6:
1338 cip = (Embryo_Cell *)(code + (int)pri);
1339 break;
1340 default:
1341 ABORT(ep, EMBRYO_ERROR_INVINSTR);
1342 break;
1343 }
1344 BREAK;
1345 CASE(EMBRYO_OP_MOVE_PRI);
1346 pri = alt;
1347 BREAK;
1348 CASE(EMBRYO_OP_MOVE_ALT);
1349 alt = pri;
1350 BREAK;
1351 CASE(EMBRYO_OP_XCHG);
1352 offs = pri; /* offs is a temporary variable */
1353 pri = alt;
1354 alt = offs;
1355 BREAK;
1356 CASE(EMBRYO_OP_PUSH_PRI);
1357 PUSH(pri);
1358 BREAK;
1359 CASE(EMBRYO_OP_PUSH_ALT);
1360 PUSH(alt);
1361 BREAK;
1362 CASE(EMBRYO_OP_PUSH_C);
1363 GETPARAM(offs);
1364 PUSH(offs);
1365 BREAK;
1366 CASE(EMBRYO_OP_PUSH_R);
1367 GETPARAM(offs);
1368 while (offs--) PUSH(pri);
1369 BREAK;
1370 CASE(EMBRYO_OP_PUSH);
1371 GETPARAM(offs);
1372 PUSH(*(Embryo_Cell *)(data + (int)offs));
1373 BREAK;
1374 CASE(EMBRYO_OP_PUSH_S);
1375 GETPARAM(offs);
1376 PUSH(*(Embryo_Cell *)(data + (int)frm + (int)offs));
1377 BREAK;
1378 CASE(EMBRYO_OP_POP_PRI);
1379 POP(pri);
1380 BREAK;
1381 CASE(EMBRYO_OP_POP_ALT);
1382 POP(alt);
1383 BREAK;
1384 CASE(EMBRYO_OP_STACK);
1385 GETPARAM(offs);
1386 alt = stk;
1387 stk += offs;
1388 CHKMARGIN();
1389 CHKSTACK();
1390 BREAK;
1391 CASE(EMBRYO_OP_HEAP);
1392 GETPARAM(offs);
1393 alt = hea;
1394 hea += offs;
1395 CHKMARGIN();
1396 CHKHEAP();
1397 BREAK;
1398 CASE(EMBRYO_OP_PROC);
1399 PUSH(frm);
1400 frm = stk;
1401 CHKMARGIN();
1402 BREAK;
1403 CASE(EMBRYO_OP_RET);
1404 POP(frm);
1405 POP(offs);
1406 if ((Embryo_UCell)offs >= codesize)
1407 ABORT(ep, EMBRYO_ERROR_MEMACCESS);
1408 cip = (Embryo_Cell *)(code + (int)offs);
1409 BREAK;
1410 CASE(EMBRYO_OP_RETN);
1411 POP(frm);
1412 POP(offs);
1413 if ((Embryo_UCell)offs >= codesize)
1414 ABORT(ep, EMBRYO_ERROR_MEMACCESS);
1415 cip = (Embryo_Cell *)(code + (int)offs);
1416 stk += *(Embryo_Cell *)(data + (int)stk) + sizeof(Embryo_Cell); /* remove parameters from the stack */
1417 ep->stk = stk;
1418 BREAK;
1419 CASE(EMBRYO_OP_CALL);
1420 PUSH(((unsigned char *)cip - code) + sizeof(Embryo_Cell));/* skip address */
1421 cip = JUMPABS(code, cip); /* jump to the address */
1422 BREAK;
1423 CASE(EMBRYO_OP_CALL_PRI);
1424 PUSH((unsigned char *)cip - code);
1425 cip = (Embryo_Cell *)(code + (int)pri);
1426 BREAK;
1427 CASE(EMBRYO_OP_JUMP);
1428 /* since the GETPARAM() macro modifies cip, you cannot
1429 * do GETPARAM(cip) directly */
1430 cip = JUMPABS(code, cip);
1431 BREAK;
1432 CASE(EMBRYO_OP_JREL);
1433 offs = *cip;
1434 cip = (Embryo_Cell *)((unsigned char *)cip + (int)offs + sizeof(Embryo_Cell));
1435 BREAK;
1436 CASE(EMBRYO_OP_JZER);
1437 if (pri == 0)
1438 cip = JUMPABS(code, cip);
1439 else
1440 cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
1441 BREAK;
1442 CASE(EMBRYO_OP_JNZ);
1443 if (pri != 0)
1444 cip = JUMPABS(code, cip);
1445 else
1446 cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
1447 BREAK;
1448 CASE(EMBRYO_OP_JEQ);
1449 if (pri==alt)
1450 cip = JUMPABS(code, cip);
1451 else
1452 cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
1453 BREAK;
1454 CASE(EMBRYO_OP_JNEQ);
1455 if (pri != alt)
1456 cip = JUMPABS(code, cip);
1457 else
1458 cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
1459 BREAK;
1460 CASE(EMBRYO_OP_JLESS);
1461 if ((Embryo_UCell)pri < (Embryo_UCell)alt)
1462 cip = JUMPABS(code, cip);
1463 else
1464 cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
1465 BREAK;
1466 CASE(EMBRYO_OP_JLEQ);
1467 if ((Embryo_UCell)pri <= (Embryo_UCell)alt)
1468 cip = JUMPABS(code, cip);
1469 else
1470 cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
1471 BREAK;
1472 CASE(EMBRYO_OP_JGRTR);
1473 if ((Embryo_UCell)pri > (Embryo_UCell)alt)
1474 cip = JUMPABS(code, cip);
1475 else
1476 cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
1477 BREAK;
1478 CASE(EMBRYO_OP_JGEQ);
1479 if ((Embryo_UCell)pri >= (Embryo_UCell)alt)
1480 cip = JUMPABS(code, cip);
1481 else
1482 cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
1483 BREAK;
1484 CASE(EMBRYO_OP_JSLESS);
1485 if (pri < alt)
1486 cip = JUMPABS(code, cip);
1487 else
1488 cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
1489 BREAK;
1490 CASE(EMBRYO_OP_JSLEQ);
1491 if (pri <= alt)
1492 cip = JUMPABS(code, cip);
1493 else
1494 cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
1495 BREAK;
1496 CASE(EMBRYO_OP_JSGRTR);
1497 if (pri > alt)
1498 cip = JUMPABS(code, cip);
1499 else
1500 cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
1501 BREAK;
1502 CASE(EMBRYO_OP_JSGEQ);
1503 if (pri >= alt)
1504 cip = JUMPABS(code, cip);
1505 else
1506 cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
1507 BREAK;
1508 CASE(EMBRYO_OP_SHL);
1509 pri <<= alt;
1510 BREAK;
1511 CASE(EMBRYO_OP_SHR);
1512 pri = (Embryo_UCell)pri >> (int)alt;
1513 BREAK;
1514 CASE(EMBRYO_OP_SSHR);
1515 pri >>= alt;
1516 BREAK;
1517 CASE(EMBRYO_OP_SHL_C_PRI);
1518 GETPARAM(offs);
1519 pri <<= offs;
1520 BREAK;
1521 CASE(EMBRYO_OP_SHL_C_ALT);
1522 GETPARAM(offs);
1523 alt <<= offs;
1524 BREAK;
1525 CASE(EMBRYO_OP_SHR_C_PRI);
1526 GETPARAM(offs);
1527 pri = (Embryo_UCell)pri >> (int)offs;
1528 BREAK;
1529 CASE(EMBRYO_OP_SHR_C_ALT);
1530 GETPARAM(offs);
1531 alt = (Embryo_UCell)alt >> (int)offs;
1532 BREAK;
1533 CASE(EMBRYO_OP_SMUL);
1534 pri *= alt;
1535 BREAK;
1536 CASE(EMBRYO_OP_SDIV);
1537 if (alt == 0) ABORT(ep, EMBRYO_ERROR_DIVIDE);
1538 /* divide must always round down; this is a bit
1539 * involved to do in a machine-independent way.
1540 */
1541 offs = ((pri % alt) + alt) % alt; /* true modulus */
1542 pri = (pri - offs) / alt; /* division result */
1543 alt = offs;
1544 BREAK;
1545 CASE(EMBRYO_OP_SDIV_ALT);
1546 if (pri == 0) ABORT(ep, EMBRYO_ERROR_DIVIDE);
1547 /* divide must always round down; this is a bit
1548 * involved to do in a machine-independent way.
1549 */
1550 offs = ((alt % pri) + pri) % pri; /* true modulus */
1551 pri = (alt - offs) / pri; /* division result */
1552 alt = offs;
1553 BREAK;
1554 CASE(EMBRYO_OP_UMUL);
1555 pri = (Embryo_UCell)pri * (Embryo_UCell)alt;
1556 BREAK;
1557 CASE(EMBRYO_OP_UDIV);
1558 if (alt == 0) ABORT(ep, EMBRYO_ERROR_DIVIDE);
1559 offs = (Embryo_UCell)pri % (Embryo_UCell)alt; /* temporary storage */
1560 pri = (Embryo_UCell)pri / (Embryo_UCell)alt;
1561 alt = offs;
1562 BREAK;
1563 CASE(EMBRYO_OP_UDIV_ALT);
1564 if (pri == 0) ABORT(ep, EMBRYO_ERROR_DIVIDE);
1565 offs = (Embryo_UCell)alt % (Embryo_UCell)pri; /* temporary storage */
1566 pri = (Embryo_UCell)alt / (Embryo_UCell)pri;
1567 alt = offs;
1568 BREAK;
1569 CASE(EMBRYO_OP_ADD);
1570 pri += alt;
1571 BREAK;
1572 CASE(EMBRYO_OP_SUB);
1573 pri -= alt;
1574 BREAK;
1575 CASE(EMBRYO_OP_SUB_ALT);
1576 pri = alt - pri;
1577 BREAK;
1578 CASE(EMBRYO_OP_AND);
1579 pri &= alt;
1580 BREAK;
1581 CASE(EMBRYO_OP_OR);
1582 pri |= alt;
1583 BREAK;
1584 CASE(EMBRYO_OP_XOR);
1585 pri ^= alt;
1586 BREAK;
1587 CASE(EMBRYO_OP_NOT);
1588 pri = !pri;
1589 BREAK;
1590 CASE(EMBRYO_OP_NEG);
1591 pri = -pri;
1592 BREAK;
1593 CASE(EMBRYO_OP_INVERT);
1594 pri = ~pri;
1595 BREAK;
1596 CASE(EMBRYO_OP_ADD_C);
1597 GETPARAM(offs);
1598 pri += offs;
1599 BREAK;
1600 CASE(EMBRYO_OP_SMUL_C);
1601 GETPARAM(offs);
1602 pri *= offs;
1603 BREAK;
1604 CASE(EMBRYO_OP_ZERO_PRI);
1605 pri = 0;
1606 BREAK;
1607 CASE(EMBRYO_OP_ZERO_ALT);
1608 alt = 0;
1609 BREAK;
1610 CASE(EMBRYO_OP_ZERO);
1611 GETPARAM(offs);
1612 *(Embryo_Cell *)(data + (int)offs) = 0;
1613 BREAK;
1614 CASE(EMBRYO_OP_ZERO_S);
1615 GETPARAM(offs);
1616 *(Embryo_Cell *)(data + (int)frm + (int)offs) = 0;
1617 BREAK;
1618 CASE(EMBRYO_OP_SIGN_PRI);
1619 if ((pri & 0xff) >= 0x80) pri |= ~(Embryo_UCell)0xff;
1620 BREAK;
1621 CASE(EMBRYO_OP_SIGN_ALT);
1622 if ((alt & 0xff) >= 0x80) alt |= ~(Embryo_UCell)0xff;
1623 BREAK;
1624 CASE(EMBRYO_OP_EQ);
1625 pri = (pri == alt) ? 1 : 0;
1626 BREAK;
1627 CASE(EMBRYO_OP_NEQ);
1628 pri = (pri != alt) ? 1 : 0;
1629 BREAK;
1630 CASE(EMBRYO_OP_LESS);
1631 pri = ((Embryo_UCell)pri < (Embryo_UCell)alt) ? 1 : 0;
1632 BREAK;
1633 CASE(EMBRYO_OP_LEQ);
1634 pri = ((Embryo_UCell)pri <= (Embryo_UCell)alt) ? 1 : 0;
1635 BREAK;
1636 CASE(EMBRYO_OP_GRTR);
1637 pri = ((Embryo_UCell)pri > (Embryo_UCell)alt) ? 1 : 0;
1638 BREAK;
1639 CASE(EMBRYO_OP_GEQ);
1640 pri = ((Embryo_UCell)pri >= (Embryo_UCell)alt) ? 1 : 0;
1641 BREAK;
1642 CASE(EMBRYO_OP_SLESS);
1643 pri = (pri < alt) ? 1 : 0;
1644 BREAK;
1645 CASE(EMBRYO_OP_SLEQ);
1646 pri = (pri <= alt) ? 1 : 0;
1647 BREAK;
1648 CASE(EMBRYO_OP_SGRTR);
1649 pri = (pri > alt) ? 1 : 0;
1650 BREAK;
1651 CASE(EMBRYO_OP_SGEQ);
1652 pri = (pri >= alt) ? 1 : 0;
1653 BREAK;
1654 CASE(EMBRYO_OP_EQ_C_PRI);
1655 GETPARAM(offs);
1656 pri = (pri == offs) ? 1 : 0;
1657 BREAK;
1658 CASE(EMBRYO_OP_EQ_C_ALT);
1659 GETPARAM(offs);
1660 pri = (alt == offs) ? 1 : 0;
1661 BREAK;
1662 CASE(EMBRYO_OP_INC_PRI);
1663 pri++;
1664 BREAK;
1665 CASE(EMBRYO_OP_INC_ALT);
1666 alt++;
1667 BREAK;
1668 CASE(EMBRYO_OP_INC);
1669 GETPARAM(offs);
1670 *(Embryo_Cell *)(data + (int)offs) += 1;
1671 BREAK;
1672 CASE(EMBRYO_OP_INC_S);
1673 GETPARAM(offs);
1674 *(Embryo_Cell *)(data + (int)frm + (int)offs) += 1;
1675 BREAK;
1676 CASE(EMBRYO_OP_INC_I);
1677 *(Embryo_Cell *)(data + (int)pri) += 1;
1678 BREAK;
1679 CASE(EMBRYO_OP_DEC_PRI);
1680 pri--;
1681 BREAK;
1682 CASE(EMBRYO_OP_DEC_ALT);
1683 alt--;
1684 BREAK;
1685 CASE(EMBRYO_OP_DEC);
1686 GETPARAM(offs);
1687 *(Embryo_Cell *)(data + (int)offs) -= 1;
1688 BREAK;
1689 CASE(EMBRYO_OP_DEC_S);
1690 GETPARAM(offs);
1691 *(Embryo_Cell *)(data + (int)frm + (int)offs) -= 1;
1692 BREAK;
1693 CASE(EMBRYO_OP_DEC_I);
1694 *(Embryo_Cell *)(data + (int)pri) -= 1;
1695 BREAK;
1696 CASE(EMBRYO_OP_MOVS);
1697 GETPARAM(offs);
1698 CHKMEM(pri);
1699 CHKMEM(pri + offs);
1700 CHKMEM(alt);
1701 CHKMEM(alt + offs);
1702 memcpy(data+(int)alt, data+(int)pri, (int)offs);
1703 BREAK;
1704 CASE(EMBRYO_OP_CMPS);
1705 GETPARAM(offs);
1706 CHKMEM(pri);
1707 CHKMEM(pri + offs);
1708 CHKMEM(alt);
1709 CHKMEM(alt + offs);
1710 pri = memcmp(data + (int)alt, data + (int)pri, (int)offs);
1711 BREAK;
1712 CASE(EMBRYO_OP_FILL);
1713 GETPARAM(offs);
1714 CHKMEM(alt);
1715 CHKMEM(alt + offs);
1716 for (i = (int)alt;
1717 (size_t)offs >= sizeof(Embryo_Cell);
1718 i += sizeof(Embryo_Cell), offs -= sizeof(Embryo_Cell))
1719 *(Embryo_Cell *)(data + i) = pri;
1720 BREAK;
1721 CASE(EMBRYO_OP_HALT);
1722 GETPARAM(offs);
1723 ep->retval = pri;
1724 /* store complete status */
1725 ep->frm = frm;
1726 ep->stk = stk;
1727 ep->hea = hea;
1728 ep->pri = pri;
1729 ep->alt = alt;
1730 ep->cip = (Embryo_Cell)((unsigned char*)cip - code);
1731 if (offs == EMBRYO_ERROR_SLEEP)
1732 {
1733 ep->reset_stk = reset_stk;
1734 ep->reset_hea = reset_hea;
1735 ep->run_count--;
1736 return EMBRYO_PROGRAM_SLEEP;
1737 }
1738 OK(ep, (int)offs);
1739 CASE(EMBRYO_OP_BOUNDS);
1740 GETPARAM(offs);
1741 if ((Embryo_UCell)pri > (Embryo_UCell)offs)
1742 ABORT(ep, EMBRYO_ERROR_BOUNDS);
1743 BREAK;
1744 CASE(EMBRYO_OP_SYSREQ_PRI);
1745 /* save a few registers */
1746 ep->cip = (Embryo_Cell)((unsigned char *)cip - code);
1747 ep->hea = hea;
1748 ep->frm = frm;
1749 ep->stk = stk;
1750 num = _embryo_native_call(ep, pri, &pri, (Embryo_Cell *)(data + (int)stk));
1751 if (num != EMBRYO_ERROR_NONE)
1752 {
1753 if (num == EMBRYO_ERROR_SLEEP)
1754 {
1755 ep->pri = pri;
1756 ep->alt = alt;
1757 ep->reset_stk = reset_stk;
1758 ep->reset_hea = reset_hea;
1759 ep->run_count--;
1760 return EMBRYO_PROGRAM_SLEEP;
1761 }
1762 ABORT(ep, num);
1763 }
1764 BREAK;
1765 CASE(EMBRYO_OP_SYSREQ_C);
1766 GETPARAM(offs);
1767 /* save a few registers */
1768 ep->cip = (Embryo_Cell)((unsigned char *)cip - code);
1769 ep->hea = hea;
1770 ep->frm = frm;
1771 ep->stk = stk;
1772 num = _embryo_native_call(ep, offs, &pri, (Embryo_Cell *)(data + (int)stk));
1773 if (num != EMBRYO_ERROR_NONE)
1774 {
1775 if (num == EMBRYO_ERROR_SLEEP)
1776 {
1777 ep->pri = pri;
1778 ep->alt = alt;
1779 ep->reset_stk = reset_stk;
1780 ep->reset_hea = reset_hea;
1781 ep->run_count--;
1782 return EMBRYO_PROGRAM_SLEEP;
1783 }
1784 {
1785 Embryo_Header *hdr;
1786 int i, num;
1787 Embryo_Func_Stub *func_entry;
1788
1789 hdr = (Embryo_Header *)ep->code;
1790 num = NUMENTRIES(hdr, natives, libraries);
1791 func_entry = GETENTRY(hdr, natives, 0);
1792 for (i = 0; i < num; i++)
1793 {
1794 char *entry_name;
1795
1796 entry_name = GETENTRYNAME(hdr, func_entry);
1797 if (i == offs)
1798 printf("EMBRYO: CALL [%i] %s() non-existent!\n", i, entry_name);
1799 func_entry =
1800 (Embryo_Func_Stub *)((unsigned char *)func_entry + hdr->defsize);
1801 }
1802 }
1803 ABORT(ep, num);
1804 }
1805 BREAK;
1806 CASE(EMBRYO_OP_SYSREQ_D);
1807 GETPARAM(offs);
1808 /* save a few registers */
1809 ep->cip = (Embryo_Cell)((unsigned char *)cip - code);
1810 ep->hea = hea;
1811 ep->frm = frm;
1812 ep->stk = stk;
1813 num = _embryo_native_call(ep, offs, &pri, (Embryo_Cell *)(data + (int)stk));
1814 if (num != EMBRYO_ERROR_NONE)
1815 {
1816 if (num == EMBRYO_ERROR_SLEEP)
1817 {
1818 ep->pri = pri;
1819 ep->alt = alt;
1820 ep->reset_stk = reset_stk;
1821 ep->reset_hea = reset_hea;
1822 ep->run_count--;
1823 return EMBRYO_PROGRAM_SLEEP;
1824 }
1825 ABORT(ep, ep->error);
1826 }
1827 BREAK;
1828 CASE(EMBRYO_OP_JUMP_PRI);
1829 cip = (Embryo_Cell *)(code + (int)pri);
1830 BREAK;
1831 CASE(EMBRYO_OP_SWITCH);
1832 {
1833 Embryo_Cell *cptr;
1834
1835 /* +1, to skip the "casetbl" opcode */
1836 cptr = (Embryo_Cell *)(code + (*cip)) + 1;
1837 /* number of records in the case table */
1838 num = (int)(*cptr);
1839 /* preset to "none-matched" case */
1840 cip = (Embryo_Cell *)(code + *(cptr + 1));
1841 for (cptr += 2;
1842 (num > 0) && (*cptr != pri);
1843 num--, cptr += 2);
1844 /* case found */
1845 if (num > 0)
1846 cip = (Embryo_Cell *)(code + *(cptr + 1));
1847 }
1848 BREAK;
1849 CASE(EMBRYO_OP_SWAP_PRI);
1850 offs = *(Embryo_Cell *)(data + (int)stk);
1851 *(Embryo_Cell *)(data + (int)stk) = pri;
1852 pri = offs;
1853 BREAK;
1854 CASE(EMBRYO_OP_SWAP_ALT);
1855 offs = *(Embryo_Cell *)(data + (int)stk);
1856 *(Embryo_Cell *)(data + (int)stk) = alt;
1857 alt = offs;
1858 BREAK;
1859 CASE(EMBRYO_OP_PUSHADDR);
1860 GETPARAM(offs);
1861 PUSH(frm + offs);
1862 BREAK;
1863 CASE(EMBRYO_OP_NOP);
1864 BREAK;
1865 CASE(EMBRYO_OP_NONE);
1866 CASE(EMBRYO_OP_FILE);
1867 CASE(EMBRYO_OP_LINE);
1868 CASE(EMBRYO_OP_SYMBOL);
1869 CASE(EMBRYO_OP_SRANGE);
1870 CASE(EMBRYO_OP_CASETBL);
1871 CASE(EMBRYO_OP_SYMTAG);
1872 BREAK;
1873#ifndef EMBRYO_EXEC_JUMPTABLE
1874 default:
1875 ABORT(ep, EMBRYO_ERROR_INVINSTR);
1876#endif
1877 SWITCHEND;
1878 }
1879 ep->max_run_cycles = max_run_cycles;
1880 ep->run_count--;
1881 ep->hea = hea_start;
1882 return EMBRYO_PROGRAM_OK;
1883}
1884
1885EAPI Embryo_Cell
1886embryo_program_return_value_get(Embryo_Program *ep)
1887{
1888 if (!ep) return 0;
1889 return ep->retval;
1890}
1891
1892EAPI void
1893embryo_program_max_cycle_run_set(Embryo_Program *ep, int max)
1894{
1895 if (!ep) return;
1896 if (max < 0) max = 0;
1897 ep->max_run_cycles = max;
1898}
1899
1900EAPI int
1901embryo_program_max_cycle_run_get(Embryo_Program *ep)
1902{
1903 if (!ep) return 0;
1904 return ep->max_run_cycles;
1905}
1906
1907
1908EAPI int
1909embryo_parameter_cell_push(Embryo_Program *ep, Embryo_Cell cell)
1910{
1911 Embryo_Param *pr;
1912
1913 ep->params_size++;
1914 if (ep->params_size > ep->params_alloc)
1915 {
1916 ep->params_alloc += 8;
1917 pr = realloc(ep->params, ep->params_alloc * sizeof(Embryo_Param));
1918 if (!pr) return 0;
1919 ep->params = pr;
1920 }
1921 pr = &(ep->params[ep->params_size - 1]);
1922 pr->string = NULL;
1923 pr->cell_array = NULL;
1924 pr->cell_array_size = 0;
1925 pr->cell = 0;
1926 pr->cell = cell;
1927 return 1;
1928}
1929
1930EAPI int
1931embryo_parameter_string_push(Embryo_Program *ep, const char *str)
1932{
1933 Embryo_Param *pr;
1934 char *str_dup;
1935
1936 if (!str)
1937 return embryo_parameter_string_push(ep, "");
1938 str_dup = strdup(str);
1939 if (!str_dup) return 0;
1940 ep->params_size++;
1941 if (ep->params_size > ep->params_alloc)
1942 {
1943 ep->params_alloc += 8;
1944 pr = realloc(ep->params, ep->params_alloc * sizeof(Embryo_Param));
1945 if (!pr)
1946 {
1947 free(str_dup);
1948 return 0;
1949 }
1950 ep->params = pr;
1951 }
1952 pr = &(ep->params[ep->params_size - 1]);
1953 pr->string = NULL;
1954 pr->cell_array = NULL;
1955 pr->cell_array_size = 0;
1956 pr->cell = 0;
1957 pr->string = str_dup;
1958 return 1;
1959}
1960
1961EAPI int
1962embryo_parameter_cell_array_push(Embryo_Program *ep, Embryo_Cell *cells, int num)
1963{
1964 Embryo_Param *pr;
1965 Embryo_Cell *cell_array;
1966
1967 if ((!cells) || (num <= 0))
1968 return embryo_parameter_cell_push(ep, 0);
1969 cell_array = malloc(num * sizeof(Embryo_Cell));
1970 ep->params_size++;
1971 if (ep->params_size > ep->params_alloc)
1972 {
1973 ep->params_alloc += 8;
1974 pr = realloc(ep->params, ep->params_alloc * sizeof(Embryo_Param));
1975 if (!pr)
1976 {
1977 free(cell_array);
1978 return 0;
1979 }
1980 ep->params = pr;
1981 }
1982 pr = &(ep->params[ep->params_size - 1]);
1983 pr->string = NULL;
1984 pr->cell_array = NULL;
1985 pr->cell_array_size = 0;
1986 pr->cell = 0;
1987 pr->cell_array = cell_array;
1988 pr->cell_array_size = num;
1989 memcpy(pr->cell_array, cells, num * sizeof(Embryo_Cell));
1990 return 1;
1991}
diff --git a/libraries/embryo/src/lib/embryo_args.c b/libraries/embryo/src/lib/embryo_args.c
new file mode 100644
index 0000000..0c0089e
--- /dev/null
+++ b/libraries/embryo/src/lib/embryo_args.c
@@ -0,0 +1,128 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#ifdef HAVE_ALLOCA_H
6# include <alloca.h>
7#elif defined __GNUC__
8# define alloca __builtin_alloca
9#elif defined _AIX
10# define alloca __alloca
11#elif defined _MSC_VER
12# include <malloc.h>
13# define alloca _alloca
14#else
15# include <stddef.h>
16# ifdef __cplusplus
17extern "C"
18# endif
19void *alloca (size_t);
20#endif
21
22#include "Embryo.h"
23#include "embryo_private.h"
24
25#define STRSET(ep, par, str) { \
26 Embryo_Cell *___cptr; \
27 if ((___cptr = embryo_data_address_get(ep, par))) { \
28 embryo_data_string_set(ep, str, ___cptr); \
29 } }
30
31/* exported args api */
32
33static Embryo_Cell
34_embryo_args_numargs(Embryo_Program *ep, Embryo_Cell *params __UNUSED__)
35{
36 Embryo_Header *hdr;
37 unsigned char *data;
38 Embryo_Cell bytes;
39
40 hdr = (Embryo_Header *)ep->base;
41 data = ep->base + (int)hdr->dat;
42 bytes = *(Embryo_Cell *)(data + (int)ep->frm +
43 (2 * sizeof(Embryo_Cell)));
44 return bytes / sizeof(Embryo_Cell);
45}
46
47static Embryo_Cell
48_embryo_args_getarg(Embryo_Program *ep, Embryo_Cell *params)
49{
50 Embryo_Header *hdr;
51 unsigned char *data;
52 Embryo_Cell val;
53
54 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
55 hdr = (Embryo_Header *)ep->base;
56 data = ep->base + (int)hdr->dat;
57 val = *(Embryo_Cell *)(data + (int)ep->frm +
58 (((int)params[1] + 3) * sizeof(Embryo_Cell)));
59 val += params[2] * sizeof(Embryo_Cell);
60 val = *(Embryo_Cell *)(data + (int)val);
61 return val;
62}
63
64static Embryo_Cell
65_embryo_args_setarg(Embryo_Program *ep, Embryo_Cell *params)
66{
67 Embryo_Header *hdr;
68 unsigned char *data;
69 Embryo_Cell val;
70
71 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
72 hdr = (Embryo_Header *)ep->base;
73 data = ep->base + (int)hdr->dat;
74 val = *(Embryo_Cell *)(data + (int)ep->frm +
75 (((int)params[1] + 3) * sizeof(Embryo_Cell)));
76 val += params[2] * sizeof(Embryo_Cell);
77 if ((val < 0) || ((val >= ep->hea) && (val < ep->stk))) return 0;
78 *(Embryo_Cell *)(data + (int)val) = params[3];
79 return 1;
80}
81
82static Embryo_Cell
83_embryo_args_getsarg(Embryo_Program *ep, Embryo_Cell *params)
84{
85 Embryo_Header *hdr;
86 unsigned char *data;
87 Embryo_Cell base_cell;
88 char *s;
89 int i = 0;
90
91 /* params[1] = arg_no */
92 /* params[2] = buf */
93 /* params[3] = buflen */
94 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
95 if (params[3] <= 0) return 0; /* buflen must be > 0 */
96 hdr = (Embryo_Header *)ep->base;
97 data = ep->base + (int)hdr->dat;
98 base_cell = *(Embryo_Cell *)(data + (int)ep->frm +
99 (((int)params[1] + 3) * sizeof(Embryo_Cell)));
100
101 s = alloca(params[3]);
102
103 while (i < params[3])
104 {
105 int offset = base_cell + (i * sizeof(Embryo_Cell));
106
107 s[i] = *(Embryo_Cell *)(data + offset);
108 if (!s[i++]) break;
109 }
110
111 s[i - 1] = 0;
112 STRSET(ep, params[2], s);
113
114 return i - 1; /* characters written minus terminator */
115}
116
117/* functions used by the rest of embryo */
118
119void
120_embryo_args_init(Embryo_Program *ep)
121{
122 embryo_program_native_call_add(ep, "numargs", _embryo_args_numargs);
123 embryo_program_native_call_add(ep, "getarg", _embryo_args_getarg);
124 embryo_program_native_call_add(ep, "setarg", _embryo_args_setarg);
125 embryo_program_native_call_add(ep, "getfarg", _embryo_args_getarg);
126 embryo_program_native_call_add(ep, "setfarg", _embryo_args_setarg);
127 embryo_program_native_call_add(ep, "getsarg", _embryo_args_getsarg);
128}
diff --git a/libraries/embryo/src/lib/embryo_float.c b/libraries/embryo/src/lib/embryo_float.c
new file mode 100644
index 0000000..608be9d
--- /dev/null
+++ b/libraries/embryo/src/lib/embryo_float.c
@@ -0,0 +1,331 @@
1/* Float arithmetic for the Small AMX engine
2 *
3 * Copyright (c) Artran, Inc. 1999
4 * Written by Greg Garner (gmg@artran.com)
5 * Portions Copyright (c) Carsten Haitzler, 2004 <raster@rasterman.com>
6 *
7 * This software is provided "as-is", without any express or implied warranty.
8 * In no event will the authors be held liable for any damages arising from
9 * the use of this software.
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, subject to the following restrictions:
14 *
15 * 1. The origin of this software must not be misrepresented; you must not
16 * claim that you wrote the original software. If you use this software in
17 * a product, an acknowledgment in the product documentation would be
18 * appreciated but is not required.
19 * 2. Altered source versions must be plainly marked as such, and must not be
20 * misrepresented as being the original software.
21 * 3. This notice may not be removed or altered from any source distribution.
22 */
23
24/* CHANGES -
25 * 2002-08-27: Basic conversion of source from C++ to C by Adam D. Moss
26 * <adam@gimp.org> <aspirin@icculus.org>
27 * 2003-08-29: Removal of the dynamic memory allocation and replacing two
28 * type conversion functions by macros, by Thiadmer Riemersma
29 * 2003-09-22: Moved the type conversion macros to AMX.H, and simplifications
30 * of some routines, by Thiadmer Riemersma
31 * 2003-11-24: A few more native functions (geometry), plus minor modifications,
32 * mostly to be compatible with dynamically loadable extension
33 * modules, by Thiadmer Riemersma
34 * 2004-03-20: Cleaned up and reduced size for Embryo, Modified to conform to
35 * E coding style. Added extra parameter checks.
36 * Carsten Haitzler, <raster@rasterman.com>
37 */
38
39
40#ifdef HAVE_CONFIG_H
41# include "config.h"
42#endif
43
44#include <stdlib.h>
45#include <math.h>
46
47#include "Embryo.h"
48#include "embryo_private.h"
49
50#define PI 3.1415926535897932384626433832795f
51
52/* internally useful calls */
53
54static float
55_embryo_fp_degrees_to_radians(float angle, int radix)
56{
57 switch (radix)
58 {
59 case 1: /* degrees, sexagesimal system (technically: degrees/minutes/seconds) */
60 return (angle * PI / 180.0f);
61 case 2: /* grades, centesimal system */
62 return (angle * PI / 200.0f);
63 default: /* assume already radian */
64 break;
65 }
66 return angle;
67}
68
69/* exported float api */
70
71static Embryo_Cell
72_embryo_fp(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
73{
74 /* params[1] = long value to convert to a float */
75 float f;
76
77 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
78 f = (float)params[1];
79 return EMBRYO_FLOAT_TO_CELL(f);
80}
81
82static Embryo_Cell
83_embryo_fp_str(Embryo_Program *ep, Embryo_Cell *params)
84{
85 /* params[1] = virtual string address to convert to a float */
86 char buf[64];
87 Embryo_Cell *str;
88 float f;
89 int len;
90
91 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
92 str = embryo_data_address_get(ep, params[1]);
93 len = embryo_data_string_length_get(ep, str);
94 if ((len == 0) || (len >= (int)sizeof(buf))) return 0;
95 embryo_data_string_get(ep, str, buf);
96 f = (float)atof(buf);
97 return EMBRYO_FLOAT_TO_CELL(f);
98}
99
100static Embryo_Cell
101_embryo_fp_mul(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
102{
103 /* params[1] = float operand 1 */
104 /* params[2] = float operand 2 */
105 float f;
106
107 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
108 f = EMBRYO_CELL_TO_FLOAT(params[1]) * EMBRYO_CELL_TO_FLOAT(params[2]);
109 return EMBRYO_FLOAT_TO_CELL(f);
110}
111
112static Embryo_Cell
113_embryo_fp_div(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
114{
115 /* params[1] = float dividend (top) */
116 /* params[2] = float divisor (bottom) */
117 float f;
118
119 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
120 f = EMBRYO_CELL_TO_FLOAT(params[1]) / EMBRYO_CELL_TO_FLOAT(params[2]);
121 return EMBRYO_FLOAT_TO_CELL(f);
122}
123
124static Embryo_Cell
125_embryo_fp_add(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
126{
127 /* params[1] = float operand 1 */
128 /* params[2] = float operand 2 */
129 float f;
130
131 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
132 f = EMBRYO_CELL_TO_FLOAT(params[1]) + EMBRYO_CELL_TO_FLOAT(params[2]);
133 return EMBRYO_FLOAT_TO_CELL(f);
134}
135
136static Embryo_Cell
137_embryo_fp_sub(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
138{
139 /* params[1] = float operand 1 */
140 /* params[2] = float operand 2 */
141 float f;
142
143 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
144 f = EMBRYO_CELL_TO_FLOAT(params[1]) - EMBRYO_CELL_TO_FLOAT(params[2]);
145 return EMBRYO_FLOAT_TO_CELL(f);
146}
147
148/* Return fractional part of float */
149static Embryo_Cell
150_embryo_fp_fract(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
151{
152 /* params[1] = float operand */
153 float f;
154
155 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
156 f = EMBRYO_CELL_TO_FLOAT(params[1]);
157 f -= (floorf(f));
158 return EMBRYO_FLOAT_TO_CELL(f);
159}
160
161/* Return integer part of float, rounded */
162static Embryo_Cell
163_embryo_fp_round(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
164{
165 /* params[1] = float operand */
166 /* params[2] = Type of rounding (cell) */
167 float f;
168
169 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
170 f = EMBRYO_CELL_TO_FLOAT(params[1]);
171 switch (params[2])
172 {
173 case 1: /* round downwards (truncate) */
174 f = (floorf(f));
175 break;
176 case 2: /* round upwards */
177 f = (ceilf(f));
178 break;
179 case 3: /* round towards zero */
180 if (f >= 0.0) f = (floorf(f));
181 else f = (ceilf(f));
182 break;
183 default: /* standard, round to nearest */
184 f = (floorf(f + 0.5));
185 break;
186 }
187 return (Embryo_Cell)f;
188}
189
190static Embryo_Cell
191_embryo_fp_cmp(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
192{
193 /* params[1] = float operand 1 */
194 /* params[2] = float operand 2 */
195 float f, ff;
196
197 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
198 f = EMBRYO_CELL_TO_FLOAT(params[1]);
199 ff = EMBRYO_CELL_TO_FLOAT(params[2]);
200 if (f == ff) return 0;
201 else if (f > ff) return 1;
202 return -1;
203}
204
205static Embryo_Cell
206_embryo_fp_sqroot(Embryo_Program *ep, Embryo_Cell *params)
207{
208 /* params[1] = float operand */
209 float f;
210
211 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
212 f = EMBRYO_CELL_TO_FLOAT(params[1]);
213 f = sqrtf(f);
214 if (f < 0)
215 {
216 embryo_program_error_set(ep, EMBRYO_ERROR_DOMAIN);
217 return 0;
218 }
219 return EMBRYO_FLOAT_TO_CELL(f);
220}
221
222static Embryo_Cell
223_embryo_fp_power(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
224{
225 /* params[1] = float operand 1 */
226 /* params[2] = float operand 2 */
227 float f, ff;
228
229 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
230 f = EMBRYO_CELL_TO_FLOAT(params[1]);
231 ff = EMBRYO_CELL_TO_FLOAT(params[2]);
232 f = powf(f, ff);
233 return EMBRYO_FLOAT_TO_CELL(f);
234}
235
236static Embryo_Cell
237_embryo_fp_log(Embryo_Program *ep, Embryo_Cell *params)
238{
239 /* params[1] = float operand 1 (value) */
240 /* params[2] = float operand 2 (base) */
241 float f, ff;
242
243 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
244 f = EMBRYO_CELL_TO_FLOAT(params[1]);
245 ff = EMBRYO_CELL_TO_FLOAT(params[2]);
246 if ((f <= 0.0) || (ff <= 0.0))
247 {
248 embryo_program_error_set(ep, EMBRYO_ERROR_DOMAIN);
249 return 0;
250 }
251 if (ff == 10.0) f = log10f(f);
252 else f = (logf(f) / logf(ff));
253 return EMBRYO_FLOAT_TO_CELL(f);
254}
255
256static Embryo_Cell
257_embryo_fp_sin(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
258{
259 /* params[1] = float operand 1 (angle) */
260 /* params[2] = float operand 2 (radix) */
261 float f;
262
263 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
264 f = EMBRYO_CELL_TO_FLOAT(params[1]);
265 f = _embryo_fp_degrees_to_radians(f, params[2]);
266 f = sinf(f);
267 return EMBRYO_FLOAT_TO_CELL(f);
268}
269
270static Embryo_Cell
271_embryo_fp_cos(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
272{
273 /* params[1] = float operand 1 (angle) */
274 /* params[2] = float operand 2 (radix) */
275 float f;
276
277 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
278 f = EMBRYO_CELL_TO_FLOAT(params[1]);
279 f = _embryo_fp_degrees_to_radians(f, params[2]);
280 f = cosf(f);
281 return EMBRYO_FLOAT_TO_CELL(f);
282}
283
284static Embryo_Cell
285_embryo_fp_tan(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
286{
287 /* params[1] = float operand 1 (angle) */
288 /* params[2] = float operand 2 (radix) */
289 float f;
290
291 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
292 f = EMBRYO_CELL_TO_FLOAT(params[1]);
293 f = _embryo_fp_degrees_to_radians(f, params[2]);
294 f = tanf(f);
295 return EMBRYO_FLOAT_TO_CELL(f);
296}
297
298static Embryo_Cell
299_embryo_fp_abs(Embryo_Program *ep __UNUSED__, Embryo_Cell *params)
300{
301 /* params[1] = float operand */
302 float f;
303
304 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
305 f = EMBRYO_CELL_TO_FLOAT(params[1]);
306 f = (f >= 0) ? f : -f;
307 return EMBRYO_FLOAT_TO_CELL(f);
308}
309
310/* functions used by the rest of embryo */
311
312void
313_embryo_fp_init(Embryo_Program *ep)
314{
315 embryo_program_native_call_add(ep, "float", _embryo_fp);
316 embryo_program_native_call_add(ep, "atof", _embryo_fp_str);
317 embryo_program_native_call_add(ep, "float_mul", _embryo_fp_mul);
318 embryo_program_native_call_add(ep, "float_div", _embryo_fp_div);
319 embryo_program_native_call_add(ep, "float_add", _embryo_fp_add);
320 embryo_program_native_call_add(ep, "float_sub", _embryo_fp_sub);
321 embryo_program_native_call_add(ep, "fract", _embryo_fp_fract);
322 embryo_program_native_call_add(ep, "round", _embryo_fp_round);
323 embryo_program_native_call_add(ep, "float_cmp", _embryo_fp_cmp);
324 embryo_program_native_call_add(ep, "sqrt", _embryo_fp_sqroot);
325 embryo_program_native_call_add(ep, "pow", _embryo_fp_power);
326 embryo_program_native_call_add(ep, "log", _embryo_fp_log);
327 embryo_program_native_call_add(ep, "sin", _embryo_fp_sin);
328 embryo_program_native_call_add(ep, "cos", _embryo_fp_cos);
329 embryo_program_native_call_add(ep, "tan", _embryo_fp_tan);
330 embryo_program_native_call_add(ep, "abs", _embryo_fp_abs);
331}
diff --git a/libraries/embryo/src/lib/embryo_main.c b/libraries/embryo/src/lib/embryo_main.c
new file mode 100644
index 0000000..0b01b11
--- /dev/null
+++ b/libraries/embryo/src/lib/embryo_main.c
@@ -0,0 +1,36 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <stdlib.h>
6#include <time.h>
7
8#include "Embryo.h"
9#include "embryo_private.h"
10
11static Embryo_Version _version = { VMAJ, VMIN, VMIC, VREV };
12EAPI Embryo_Version *embryo_version = &_version;
13
14static int _embryo_init_count = 0;
15
16/*** EXPORTED CALLS ***/
17
18EAPI int
19embryo_init(void)
20{
21 if (++_embryo_init_count != 1)
22 return _embryo_init_count;
23
24 srand(time(NULL));
25
26 return _embryo_init_count;
27}
28
29EAPI int
30embryo_shutdown(void)
31{
32 if (--_embryo_init_count != 0)
33 return _embryo_init_count;
34
35 return _embryo_init_count;
36}
diff --git a/libraries/embryo/src/lib/embryo_private.h b/libraries/embryo/src/lib/embryo_private.h
new file mode 100644
index 0000000..a4205e1
--- /dev/null
+++ b/libraries/embryo/src/lib/embryo_private.h
@@ -0,0 +1,298 @@
1#ifndef _EMBRYO_PRIVATE_H
2#define _EMBRYO_PRIVATE_H
3
4
5#ifdef __GNUC__
6# if __GNUC__ >= 4
7// BROKEN in gcc 4 on amd64
8//# pragma GCC visibility push(hidden)
9# endif
10#endif
11
12typedef enum _Embryo_Opcode Embryo_Opcode;
13
14enum _Embryo_Opcode
15{
16 EMBRYO_OP_NONE,
17 EMBRYO_OP_LOAD_PRI,
18 EMBRYO_OP_LOAD_ALT,
19 EMBRYO_OP_LOAD_S_PRI,
20 EMBRYO_OP_LOAD_S_ALT,
21 EMBRYO_OP_LREF_PRI,
22 EMBRYO_OP_LREF_ALT,
23 EMBRYO_OP_LREF_S_PRI,
24 EMBRYO_OP_LREF_S_ALT,
25 EMBRYO_OP_LOAD_I,
26 EMBRYO_OP_LODB_I,
27 EMBRYO_OP_CONST_PRI,
28 EMBRYO_OP_CONST_ALT,
29 EMBRYO_OP_ADDR_PRI,
30 EMBRYO_OP_ADDR_ALT,
31 EMBRYO_OP_STOR_PRI,
32 EMBRYO_OP_STOR_ALT,
33 EMBRYO_OP_STOR_S_PRI,
34 EMBRYO_OP_STOR_S_ALT,
35 EMBRYO_OP_SREF_PRI,
36 EMBRYO_OP_SREF_ALT,
37 EMBRYO_OP_SREF_S_PRI,
38 EMBRYO_OP_SREF_S_ALT,
39 EMBRYO_OP_STOR_I,
40 EMBRYO_OP_STRB_I,
41 EMBRYO_OP_LIDX,
42 EMBRYO_OP_LIDX_B,
43 EMBRYO_OP_IDXADDR,
44 EMBRYO_OP_IDXADDR_B,
45 EMBRYO_OP_ALIGN_PRI,
46 EMBRYO_OP_ALIGN_ALT,
47 EMBRYO_OP_LCTRL,
48 EMBRYO_OP_SCTRL,
49 EMBRYO_OP_MOVE_PRI,
50 EMBRYO_OP_MOVE_ALT,
51 EMBRYO_OP_XCHG,
52 EMBRYO_OP_PUSH_PRI,
53 EMBRYO_OP_PUSH_ALT,
54 EMBRYO_OP_PUSH_R,
55 EMBRYO_OP_PUSH_C,
56 EMBRYO_OP_PUSH,
57 EMBRYO_OP_PUSH_S,
58 EMBRYO_OP_POP_PRI,
59 EMBRYO_OP_POP_ALT,
60 EMBRYO_OP_STACK,
61 EMBRYO_OP_HEAP,
62 EMBRYO_OP_PROC,
63 EMBRYO_OP_RET,
64 EMBRYO_OP_RETN,
65 EMBRYO_OP_CALL,
66 EMBRYO_OP_CALL_PRI,
67 EMBRYO_OP_JUMP,
68 EMBRYO_OP_JREL,
69 EMBRYO_OP_JZER,
70 EMBRYO_OP_JNZ,
71 EMBRYO_OP_JEQ,
72 EMBRYO_OP_JNEQ,
73 EMBRYO_OP_JLESS,
74 EMBRYO_OP_JLEQ,
75 EMBRYO_OP_JGRTR,
76 EMBRYO_OP_JGEQ,
77 EMBRYO_OP_JSLESS,
78 EMBRYO_OP_JSLEQ,
79 EMBRYO_OP_JSGRTR,
80 EMBRYO_OP_JSGEQ,
81 EMBRYO_OP_SHL,
82 EMBRYO_OP_SHR,
83 EMBRYO_OP_SSHR,
84 EMBRYO_OP_SHL_C_PRI,
85 EMBRYO_OP_SHL_C_ALT,
86 EMBRYO_OP_SHR_C_PRI,
87 EMBRYO_OP_SHR_C_ALT,
88 EMBRYO_OP_SMUL,
89 EMBRYO_OP_SDIV,
90 EMBRYO_OP_SDIV_ALT,
91 EMBRYO_OP_UMUL,
92 EMBRYO_OP_UDIV,
93 EMBRYO_OP_UDIV_ALT,
94 EMBRYO_OP_ADD,
95 EMBRYO_OP_SUB,
96 EMBRYO_OP_SUB_ALT,
97 EMBRYO_OP_AND,
98 EMBRYO_OP_OR,
99 EMBRYO_OP_XOR,
100 EMBRYO_OP_NOT,
101 EMBRYO_OP_NEG,
102 EMBRYO_OP_INVERT,
103 EMBRYO_OP_ADD_C,
104 EMBRYO_OP_SMUL_C,
105 EMBRYO_OP_ZERO_PRI,
106 EMBRYO_OP_ZERO_ALT,
107 EMBRYO_OP_ZERO,
108 EMBRYO_OP_ZERO_S,
109 EMBRYO_OP_SIGN_PRI,
110 EMBRYO_OP_SIGN_ALT,
111 EMBRYO_OP_EQ,
112 EMBRYO_OP_NEQ,
113 EMBRYO_OP_LESS,
114 EMBRYO_OP_LEQ,
115 EMBRYO_OP_GRTR,
116 EMBRYO_OP_GEQ,
117 EMBRYO_OP_SLESS,
118 EMBRYO_OP_SLEQ,
119 EMBRYO_OP_SGRTR,
120 EMBRYO_OP_SGEQ,
121 EMBRYO_OP_EQ_C_PRI,
122 EMBRYO_OP_EQ_C_ALT,
123 EMBRYO_OP_INC_PRI,
124 EMBRYO_OP_INC_ALT,
125 EMBRYO_OP_INC,
126 EMBRYO_OP_INC_S,
127 EMBRYO_OP_INC_I,
128 EMBRYO_OP_DEC_PRI,
129 EMBRYO_OP_DEC_ALT,
130 EMBRYO_OP_DEC,
131 EMBRYO_OP_DEC_S,
132 EMBRYO_OP_DEC_I,
133 EMBRYO_OP_MOVS,
134 EMBRYO_OP_CMPS,
135 EMBRYO_OP_FILL,
136 EMBRYO_OP_HALT,
137 EMBRYO_OP_BOUNDS,
138 EMBRYO_OP_SYSREQ_PRI,
139 EMBRYO_OP_SYSREQ_C,
140 EMBRYO_OP_FILE,
141 EMBRYO_OP_LINE,
142 EMBRYO_OP_SYMBOL,
143 EMBRYO_OP_SRANGE,
144 EMBRYO_OP_JUMP_PRI,
145 EMBRYO_OP_SWITCH,
146 EMBRYO_OP_CASETBL,
147 EMBRYO_OP_SWAP_PRI,
148 EMBRYO_OP_SWAP_ALT,
149 EMBRYO_OP_PUSHADDR,
150 EMBRYO_OP_NOP,
151 EMBRYO_OP_SYSREQ_D,
152 EMBRYO_OP_SYMTAG,
153 /* ----- */
154 EMBRYO_OP_NUM_OPCODES
155};
156
157#define NUMENTRIES(hdr, field, nextfield) \
158(int)(((hdr)->nextfield - (hdr)->field) / (hdr)->defsize)
159#define GETENTRY(hdr, table, index) \
160(Embryo_Func_Stub *)((unsigned char*)(hdr) + \
161(int)(hdr)->table + index * (hdr)->defsize)
162#ifdef WORDS_BIGENDIAN
163static int __inline __entryswap32(int v)
164{int vv; vv = v; embryo_swap_32((unsigned int *)&vv); return vv;}
165# define GETENTRYNAME(hdr, entry) \
166(((hdr)->defsize == 2 * sizeof(unsigned int)) \
167? (char *)((unsigned char*)(hdr) + \
168__entryswap32(*((unsigned int *)(entry) + 1))) \
169: (entry)->name)
170#else
171# define GETENTRYNAME(hdr, entry) \
172(((hdr)->defsize == 2 * sizeof(unsigned int)) \
173? (char *)((unsigned char*)(hdr) + *((unsigned int *)(entry) + 1)) \
174: (entry)->name)
175#endif
176
177#define CUR_FILE_VERSION 7 /* current file version; also the current Embryo_Program version */
178#define MIN_FILE_VERSION 7 /* lowest supported file format version for the current Embryo_Program version */
179#define MIN_AMX_VERSION 7 /* minimum Embryo_Program version needed to support the current file format */
180#define sEXPMAX 19 /* maximum name length for file version <= 6 */
181#define sNAMEMAX 31 /* maximum name length of symbol name */
182#define EMBRYO_MAGIC 0xf1e0 /* magic byte pattern */
183#define EMBRYO_FLAG_COMPACT 0x04 /* compact encoding */
184#define EMBRYO_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
185#define GETPARAM(v) (v = *(Embryo_Cell *)cip++)
186#define PUSH(v) (stk -= sizeof(Embryo_Cell), *(Embryo_Cell *)(data + (int)stk) = v)
187#define POP(v) (v = *(Embryo_Cell *)(data + (int)stk), stk += sizeof(Embryo_Cell))
188#define ABORT(ep,v) {(ep)->stk = reset_stk; (ep)->hea = reset_hea; (ep)->run_count--; ep->error = v; (ep)->max_run_cycles = max_run_cycles; return EMBRYO_PROGRAM_FAIL;}
189#define OK(ep,v) {(ep)->stk = reset_stk; (ep)->hea = reset_hea; (ep)->run_count--; ep->error = v; (ep)->max_run_cycles = max_run_cycles; return EMBRYO_PROGRAM_OK;}
190#define TOOLONG(ep) {(ep)->pri = pri; (ep)->cip = (Embryo_Cell)((unsigned char *)cip - code); (ep)->alt = alt; (ep)->frm = frm; (ep)->stk = stk; (ep)->hea = hea; (ep)->reset_stk = reset_stk; (ep)->reset_hea = reset_hea; (ep)->run_count--; (ep)->max_run_cycles = max_run_cycles; return EMBRYO_PROGRAM_TOOLONG;}
191#define STKMARGIN ((Embryo_Cell)(16 * sizeof(Embryo_Cell)))
192#define CHKMARGIN() if ((hea + STKMARGIN) > stk) {ep->error = EMBRYO_ERROR_STACKERR; return 0;}
193#define CHKSTACK() if (stk > ep->stp) {ep->run_count--; ep->error = EMBRYO_ERROR_STACKLOW; return 0;}
194#define CHKHEAP() if (hea < ep->hlw) {ep->run_count--; ep->error = EMBRYO_ERROR_HEAPLOW; return 0;}
195#define CHKMEM(x) if ((((x) >= hea) && ((x) < stk)) || ((Embryo_UCell)(x) >= (Embryo_UCell)ep->stp)) ABORT(ep, EMBRYO_ERROR_MEMACCESS);
196
197typedef struct _Embryo_Param Embryo_Param;
198typedef struct _Embryo_Header Embryo_Header;
199typedef struct _Embryo_Func_Stub Embryo_Func_Stub;
200
201typedef Embryo_Cell (*Embryo_Native)(Embryo_Program *ep, Embryo_Cell *params);
202
203struct _Embryo_Param
204{
205 char *string;
206 Embryo_Cell *cell_array;
207 int cell_array_size;
208 Embryo_Cell cell;
209};
210
211struct _Embryo_Program
212{
213 unsigned char *base; /* points to the Embryo_Program header ("ephdr") plus the code, optionally also the data */
214 int pushes; /* number of pushes - pops */
215 /* for external functions a few registers must be accessible from the outside */
216 Embryo_Cell cip; /* instruction pointer: relative to base + ephdr->cod */
217 Embryo_Cell frm; /* stack frame base: relative to base + ephdr->dat */
218 Embryo_Cell hea; /* top of the heap: relative to base + ephdr->dat */
219 Embryo_Cell hlw; /* bottom of the heap: relative to base + ephdr->dat */
220 Embryo_Cell stk; /* stack pointer: relative to base + ephdr->dat */
221 Embryo_Cell stp; /* top of the stack: relative to base + ephdr->dat */
222 int flags; /* current status */
223 /* native functions can raise an error */
224 int error;
225 /* the sleep opcode needs to store the full Embryo_Program status */
226 Embryo_Cell pri;
227 Embryo_Cell alt;
228 Embryo_Cell reset_stk;
229 Embryo_Cell reset_hea;
230 Embryo_Cell *syscall_d; /* relocated value/address for the SYSCALL.D opcode */
231
232 /* extended stuff */
233 Embryo_Native *native_calls;
234 int native_calls_size;
235 int native_calls_alloc;
236
237 unsigned char *code;
238 unsigned char dont_free_code : 1;
239 Embryo_Cell retval;
240
241 Embryo_Param *params;
242 int params_size;
243 int params_alloc;
244
245 int run_count;
246
247 int max_run_cycles;
248
249 void *data;
250};
251
252#if defined (_MSC_VER) || (defined (__SUNPRO_C) && __SUNPRO_C < 0x5100)
253# pragma pack(1)
254# define EMBRYO_STRUCT_PACKED
255#elif defined (__GNUC__) || (defined (__SUNPRO_C) && __SUNPRO_C >= 0x5100)
256# define EMBRYO_STRUCT_PACKED __attribute__((packed))
257#else
258# define EMBRYO_STRUCT_PACKED
259#endif
260
261struct _Embryo_Func_Stub
262{
263 int address;
264 char name[sEXPMAX+1];
265} EMBRYO_STRUCT_PACKED;
266
267struct _Embryo_Header
268{
269 unsigned int size; /* size of the "file" */
270 unsigned short magic; /* signature */
271 char file_version; /* file format version */
272 char ep_version; /* required version of the Embryo_Program */
273 short flags;
274 short defsize; /* size of a definition record */
275 int cod; /* initial value of COD - code block */
276 int dat; /* initial value of DAT - data block */
277 int hea; /* initial value of HEA - start of the heap */
278 int stp; /* initial value of STP - stack top */
279 int cip; /* initial value of CIP - the instruction pointer */
280 int publics; /* offset to the "public functions" table */
281 int natives; /* offset to the "native functions" table */
282 int libraries; /* offset to the table of libraries */
283 int pubvars; /* the "public variables" table */
284 int tags; /* the "public tagnames" table */
285 int nametable; /* name table, file version 7 only */
286} EMBRYO_STRUCT_PACKED;
287
288#if defined _MSC_VER || (defined (__SUNPRO_C) && __SUNPRO_C < 0x5100)
289# pragma pack()
290#endif
291
292void _embryo_args_init(Embryo_Program *ep);
293void _embryo_fp_init(Embryo_Program *ep);
294void _embryo_rand_init(Embryo_Program *ep);
295void _embryo_str_init(Embryo_Program *ep);
296void _embryo_time_init(Embryo_Program *ep);
297
298#endif
diff --git a/libraries/embryo/src/lib/embryo_rand.c b/libraries/embryo/src/lib/embryo_rand.c
new file mode 100644
index 0000000..627f7ed
--- /dev/null
+++ b/libraries/embryo/src/lib/embryo_rand.c
@@ -0,0 +1,36 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <stdlib.h>
6
7#include "Embryo.h"
8#include "embryo_private.h"
9
10/* exported random number api */
11
12static Embryo_Cell
13_embryo_rand_rand(Embryo_Program *ep __UNUSED__, Embryo_Cell *params __UNUSED__)
14{
15 return (Embryo_Cell)(rand() & 0xffff);
16}
17
18static Embryo_Cell
19_embryo_rand_randf(Embryo_Program *ep __UNUSED__, Embryo_Cell *params __UNUSED__)
20{
21 double r;
22 float f;
23
24 r = (double)(rand() & 0xffff) / 65535.0;
25 f = (float)r;
26 return EMBRYO_FLOAT_TO_CELL(f);
27}
28
29/* functions used by the rest of embryo */
30
31void
32_embryo_rand_init(Embryo_Program *ep)
33{
34 embryo_program_native_call_add(ep, "rand", _embryo_rand_rand);
35 embryo_program_native_call_add(ep, "randf", _embryo_rand_randf);
36}
diff --git a/libraries/embryo/src/lib/embryo_str.c b/libraries/embryo/src/lib/embryo_str.c
new file mode 100644
index 0000000..46a3284
--- /dev/null
+++ b/libraries/embryo/src/lib/embryo_str.c
@@ -0,0 +1,485 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <string.h>
8#include <fnmatch.h>
9
10#ifdef HAVE_ALLOCA_H
11# include <alloca.h>
12#elif defined __GNUC__
13# define alloca __builtin_alloca
14#elif defined _AIX
15# define alloca __alloca
16#elif defined _MSC_VER
17# include <malloc.h>
18# define alloca _alloca
19#else
20# include <stddef.h>
21# ifdef __cplusplus
22extern "C"
23# endif
24void *alloca (size_t);
25#endif
26
27#include "Embryo.h"
28#include "embryo_private.h"
29
30#define STRGET(ep, str, par) { \
31 Embryo_Cell *___cptr; \
32 str = NULL; \
33 if ((___cptr = embryo_data_address_get(ep, par))) { \
34 int ___l; \
35 ___l = embryo_data_string_length_get(ep, ___cptr); \
36 (str) = alloca(___l + 1); \
37 if (str) embryo_data_string_get(ep, ___cptr, str); \
38 } }
39#define STRSET(ep, par, str) { \
40 Embryo_Cell *___cptr; \
41 if ((___cptr = embryo_data_address_get(ep, par))) { \
42 embryo_data_string_set(ep, str, ___cptr); \
43 } }
44
45/* exported string api */
46
47static Embryo_Cell
48_embryo_str_atoi(Embryo_Program *ep, Embryo_Cell *params)
49{
50 char *s1;
51
52 /* params[1] = str */
53 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
54 STRGET(ep, s1, params[1]);
55 if (!s1) return 0;
56 return (Embryo_Cell)atoi(s1);
57}
58
59static Embryo_Cell
60_embryo_str_fnmatch(Embryo_Program *ep, Embryo_Cell *params)
61{
62 char *s1, *s2;
63
64 /* params[1] = glob */
65 /* params[2] = str */
66 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
67 STRGET(ep, s1, params[1]);
68 STRGET(ep, s2, params[2]);
69 if ((!s1) || (!s2)) return -1;
70 return (Embryo_Cell)fnmatch(s1, s2, 0);
71}
72
73static Embryo_Cell
74_embryo_str_strcmp(Embryo_Program *ep, Embryo_Cell *params)
75{
76 char *s1, *s2;
77
78 /* params[1] = str1 */
79 /* params[2] = str2 */
80 if (params[0] != (2 * sizeof(Embryo_Cell))) return -1;
81 STRGET(ep, s1, params[1]);
82 STRGET(ep, s2, params[2]);
83 if ((!s1) || (!s2)) return -1;
84 return (Embryo_Cell)strcmp(s1, s2);
85}
86
87static Embryo_Cell
88_embryo_str_strncmp(Embryo_Program *ep, Embryo_Cell *params)
89{
90 char *s1, *s2;
91
92 /* params[1] = str1 */
93 /* params[2] = str2 */
94 /* params[3] = n */
95 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
96 if (params[3] < 0) params[3] = 0;
97 STRGET(ep, s1, params[1]);
98 STRGET(ep, s2, params[2]);
99 if ((!s1) || (!s2)) return -1;
100 return (Embryo_Cell)strncmp(s1, s2, (size_t)params[3]);
101}
102
103static Embryo_Cell
104_embryo_str_strcpy(Embryo_Program *ep, Embryo_Cell *params)
105{
106 char *s1;
107
108 /* params[1] = dst */
109 /* params[2] = str */
110 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
111 STRGET(ep, s1, params[2]);
112 if (!s1) return 0;
113 STRSET(ep, params[1], s1);
114 return 0;
115}
116
117static Embryo_Cell
118_embryo_str_strncpy(Embryo_Program *ep, Embryo_Cell *params)
119{
120 char *s1;
121 int l;
122
123 /* params[1] = dst */
124 /* params[2] = str */
125 /* params[3] = n */
126 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
127 if (params[3] < 0) params[3] = 0;
128 STRGET(ep, s1, params[2]);
129 if (!s1) return 0;
130 l = strlen(s1);
131 if (l > params[3]) s1[params[3]] = 0;
132 STRSET(ep, params[1], s1);
133 return 0;
134}
135
136static Embryo_Cell
137_embryo_str_strlen(Embryo_Program *ep, Embryo_Cell *params)
138{
139 char *s1;
140
141 /* params[1] = str */
142 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
143 STRGET(ep, s1, params[1]);
144 if (!s1) return 0;
145 return (Embryo_Cell)strlen(s1);
146}
147
148static Embryo_Cell
149_embryo_str_strcat(Embryo_Program *ep, Embryo_Cell *params)
150{
151 char *s1, *s2, *s3;
152
153 /* params[1] = dsr */
154 /* params[2] = str */
155 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
156 STRGET(ep, s1, params[1]);
157 STRGET(ep, s2, params[2]);
158 if ((!s1) || (!s2)) return 0;
159 s3 = alloca(strlen(s1) + strlen(s2) + 1);
160 if (!s3) return 0;
161 strcpy(s3, s1);
162 strcat(s3, s2);
163 STRSET(ep, params[1], s3);
164 return 0;
165}
166
167static Embryo_Cell
168_embryo_str_strncat(Embryo_Program *ep, Embryo_Cell *params)
169{
170 char *s1, *s2, *s3;
171 int l1, l2;
172
173 /* params[1] = dst */
174 /* params[2] = str */
175 /* params[3] = n */
176 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
177 if (params[3] < 0) params[3] = 0;
178 STRGET(ep, s1, params[1]);
179 STRGET(ep, s2, params[2]);
180 if ((!s1) || (!s2)) return 0;
181 l1 = strlen(s1);
182 l2 = strlen(s2);
183 s3 = alloca(l1 + l2 + 1);
184 if (!s3) return 0;
185 strcpy(s3, s1);
186 strncat(s3, s2, params[3]);
187 if (l2 >= params[3]) s3[l1 + params[3]] = 0;
188 STRSET(ep, params[1], s3);
189 return 0;
190}
191
192static Embryo_Cell
193_embryo_str_strprep(Embryo_Program *ep, Embryo_Cell *params)
194{
195 char *s1, *s2, *s3;
196
197 /* params[1] = dst */
198 /* params[2] = str */
199 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
200 STRGET(ep, s1, params[1]);
201 STRGET(ep, s2, params[2]);
202 if ((!s1) || (!s2)) return 0;
203 s3 = alloca(strlen(s1) + strlen(s2) + 1);
204 if (!s3) return 0;
205 strcpy(s3, s2);
206 strcat(s3, s1);
207 STRSET(ep, params[1], s3);
208 return 0;
209}
210
211static Embryo_Cell
212_embryo_str_strnprep(Embryo_Program *ep, Embryo_Cell *params)
213{
214 char *s1, *s2, *s3;
215 int l1, l2;
216
217 /* params[1] = dst */
218 /* params[2] = str */
219 /* params[3] = n */
220 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
221 if (params[3] < 0) params[3] = 0;
222 STRGET(ep, s1, params[1]);
223 STRGET(ep, s2, params[2]);
224 if ((!s1) || (!s2)) return 0;
225 l1 = strlen(s1);
226 l2 = strlen(s2);
227 s3 = alloca(l1 + l2 + 1);
228 if (!s3) return 0;
229 strncpy(s3, s2, params[3]);
230 if (params[3] <= l2) s3[params[3]] = 0;
231 strcat(s3, s1);
232 STRSET(ep, params[1], s3);
233 return 0;
234}
235
236static Embryo_Cell
237_embryo_str_strcut(Embryo_Program *ep, Embryo_Cell *params)
238{
239 char *s1, *s2;
240 int l1;
241
242 /* params[1] = dst */
243 /* params[2] = str */
244 /* params[3] = n */
245 /* params[4] = n2 */
246 if (params[0] != (4 * sizeof(Embryo_Cell))) return 0;
247 if (params[3] < 0) params[3] = 0;
248 if (params[4] < params[3]) params[4] = params[3];
249 STRGET(ep, s1, params[2]);
250 if (!s1) return 0;
251 l1 = strlen(s1);
252 if (params[3] >= l1) params[3] = l1;
253 if (params[4] >= l1) params[4] = l1;
254 if (params[4] == params[3])
255 {
256 STRSET(ep, params[1], "");
257 return 0;
258 }
259 s2 = alloca(params[4] - params[3] + 1);
260 strncpy(s2, s1 + params[3], params[4] - params[3]);
261 s2[params[4] - params[3]] = 0;
262 STRSET(ep, params[1], s2);
263 return 0;
264}
265
266static Embryo_Cell
267_embryo_str_snprintf(Embryo_Program *ep, Embryo_Cell *params)
268{
269 char *s1, *s2;
270 int i, o;
271 int inesc = 0;
272 int insub = 0;
273 int p, pnum;
274
275 /* params[1] = buf */
276 /* params[2] = bufsize */
277 /* params[3] = format_string */
278 /* params[4] = first arg ... */
279 if (params[0] < (Embryo_Cell)(3 * sizeof(Embryo_Cell))) return 0;
280 if (params[2] <= 0) return 0;
281 STRGET(ep, s1, params[3]);
282 if (!s1) return -1;
283 s2 = alloca(params[2] + 1);
284 if (!s2) return -1;
285 s2[0] = 0;
286 pnum = (params[0] / sizeof(Embryo_Cell)) - 3;
287 for (p = 0, o = 0, i = 0; (s1[i]) && (o < (params[2] - 1)) && (p < (pnum + 1)); i++)
288 {
289 if ((!inesc) && (!insub))
290 {
291 if (s1[i] == '\\') inesc = 1;
292 else if (s1[i] == '%') insub = 1;
293 if ((!inesc) && (!insub))
294 {
295 s2[o] = s1[i];
296 o++;
297 }
298 }
299 else
300 {
301 Embryo_Cell *cptr;
302
303 if (inesc)
304 {
305 switch (s1[i])
306 {
307 case 't':
308 s2[o] = '\t';
309 o++;
310 break;
311 case 'n':
312 s2[o] = '\n';
313 o++;
314 break;
315 default:
316 s2[o] = s1[i];
317 o++;
318 break;
319 }
320 inesc = 0;
321 }
322 if ((insub) && (s1[i] == '%')) pnum++;
323 if ((insub) && (p < pnum))
324 {
325 switch (s1[i])
326 {
327 case '%':
328 s2[o] = '%';
329 o++;
330 break;
331 case 'c':
332 cptr = embryo_data_address_get(ep, params[4 + p]);
333 if (cptr) s2[o] = (char)(*cptr);
334 p++;
335 o++;
336 break;
337 case 'i':
338 case 'd':
339 case 'x':
340 case 'X':
341 {
342 char fmt[10] = "";
343 char tmp[256] = "";
344 int l;
345
346 if (s1[i] == 'i') strcpy(fmt, "%i");
347 else if (s1[i] == 'd') strcpy(fmt, "%d");
348 else if (s1[i] == 'x') strcpy(fmt, "%x");
349 else if (s1[i] == 'X') strcpy(fmt, "%08x");
350 cptr = embryo_data_address_get(ep, params[4 + p]);
351 if (cptr) snprintf(tmp, sizeof(tmp), fmt, (int)(*cptr));
352 l = strlen(tmp);
353 if ((o + l) > (params[2] - 1))
354 {
355 l = params[2] - 1 - o;
356 if (l < 0) l = 0;
357 tmp[l] = 0;
358 }
359 strcpy(s2 + o, tmp);
360 o += l;
361 p++;
362 }
363 break;
364 case 'f':
365 {
366 char tmp[256] = "";
367 int l;
368
369 cptr = embryo_data_address_get(ep, params[4 + p]);
370 if (cptr) snprintf(tmp, sizeof(tmp), "%f", (double)EMBRYO_CELL_TO_FLOAT(*cptr));
371 l = strlen(tmp);
372 if ((o + l) > (params[2] - 1))
373 {
374 l = params[2] - 1 - o;
375 if (l < 0) l = 0;
376 tmp[l] = 0;
377 }
378 strcpy(s2 + o, tmp);
379 o += l;
380 p++;
381 }
382 break;
383 case 's':
384 {
385 char *tmp;
386 int l;
387
388 STRGET(ep, tmp, params[4 + p]);
389 l = strlen(tmp);
390 if ((o + l) > (params[2] - 1))
391 {
392 l = params[2] - 1 - o;
393 if (l < 0) l = 0;
394 tmp[l] = 0;
395 }
396 strcpy(s2 + o, tmp);
397 o += l;
398 p++;
399 }
400 break;
401 default:
402 break;
403 }
404 insub = 0;
405 }
406 else if (insub)
407 insub = 0;
408 }
409 }
410 s2[o] = 0;
411
412 STRSET(ep, params[1], s2);
413 return o;
414}
415
416static Embryo_Cell
417_embryo_str_strstr(Embryo_Program *ep, Embryo_Cell *params)
418{
419 char *s1, *s2, *p;
420
421 /* params[1] = str */
422 /* params[2] = ndl */
423 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
424 STRGET(ep, s1, params[1]);
425 STRGET(ep, s2, params[2]);
426 if ((!s1) || (!s2)) return -1;
427 p = strstr(s1, s2);
428 if (!p) return -1;
429 return (Embryo_Cell)(p - s1);
430}
431
432static Embryo_Cell
433_embryo_str_strchr(Embryo_Program *ep, Embryo_Cell *params)
434{
435 char *s1, *s2, *p;
436
437 /* params[1] = str */
438 /* params[2] = ch */
439 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
440 STRGET(ep, s1, params[1]);
441 STRGET(ep, s2, params[2]);
442 if ((!s1) || (!s2)) return -1;
443 p = strchr(s1, s2[0]);
444 if (!p) return -1;
445 return (Embryo_Cell)(p - s1);
446}
447
448static Embryo_Cell
449_embryo_str_strrchr(Embryo_Program *ep, Embryo_Cell *params)
450{
451 char *s1, *s2, *p;
452
453 /* params[1] = str */
454 /* params[2] = ch */
455 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
456 STRGET(ep, s1, params[1]);
457 STRGET(ep, s2, params[2]);
458 if ((!s1) || (!s2)) return -1;
459 p = strrchr(s1, s2[0]);
460 if (!p) return -1;
461 return (Embryo_Cell)(p - s1);
462}
463
464/* functions used by the rest of embryo */
465
466void
467_embryo_str_init(Embryo_Program *ep)
468{
469 embryo_program_native_call_add(ep, "atoi", _embryo_str_atoi);
470 embryo_program_native_call_add(ep, "fnmatch", _embryo_str_fnmatch);
471 embryo_program_native_call_add(ep, "strcmp", _embryo_str_strcmp);
472 embryo_program_native_call_add(ep, "strncmp", _embryo_str_strncmp);
473 embryo_program_native_call_add(ep, "strcpy", _embryo_str_strcpy);
474 embryo_program_native_call_add(ep, "strncpy", _embryo_str_strncpy);
475 embryo_program_native_call_add(ep, "strlen", _embryo_str_strlen);
476 embryo_program_native_call_add(ep, "strcat", _embryo_str_strcat);
477 embryo_program_native_call_add(ep, "strncat", _embryo_str_strncat);
478 embryo_program_native_call_add(ep, "strprep", _embryo_str_strprep);
479 embryo_program_native_call_add(ep, "strnprep", _embryo_str_strnprep);
480 embryo_program_native_call_add(ep, "strcut", _embryo_str_strcut);
481 embryo_program_native_call_add(ep, "snprintf", _embryo_str_snprintf);
482 embryo_program_native_call_add(ep, "strstr", _embryo_str_strstr);
483 embryo_program_native_call_add(ep, "strchr", _embryo_str_strchr);
484 embryo_program_native_call_add(ep, "strrchr", _embryo_str_strrchr);
485}
diff --git a/libraries/embryo/src/lib/embryo_time.c b/libraries/embryo/src/lib/embryo_time.c
new file mode 100644
index 0000000..8392ec3
--- /dev/null
+++ b/libraries/embryo/src/lib/embryo_time.c
@@ -0,0 +1,93 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#ifndef HAVE_GETTIMEOFDAY
6# error "Your platform isn't supported yet"
7#endif
8
9#include <sys/time.h>
10#include <time.h>
11
12#ifdef _MSC_VER
13# include <winsock2.h>
14#endif
15
16#ifdef HAVE_EVIL
17# include <Evil.h>
18#endif
19
20#include "Embryo.h"
21#include "embryo_private.h"
22
23/* exported time api */
24
25static Embryo_Cell
26_embryo_time_seconds(Embryo_Program *ep __UNUSED__, Embryo_Cell *params __UNUSED__)
27{
28 struct timeval timev;
29 double t;
30 float f;
31
32 gettimeofday(&timev, NULL);
33 t = (double)(timev.tv_sec - ((timev.tv_sec / (60 * 60 * 24)) * (60 * 60 * 24)))
34 + (((double)timev.tv_usec) / 1000000);
35 f = (float)t;
36 return EMBRYO_FLOAT_TO_CELL(f);
37}
38
39static Embryo_Cell
40_embryo_time_date(Embryo_Program *ep, Embryo_Cell *params)
41{
42 static time_t last_tzset = 0;
43 struct timeval timev;
44 struct tm *tm;
45 time_t tt;
46
47 if (params[0] != (8 * sizeof(Embryo_Cell))) return 0;
48 gettimeofday(&timev, NULL);
49 tt = (time_t)(timev.tv_sec);
50 if ((tt > (last_tzset + 1)) ||
51 (tt < (last_tzset - 1)))
52 {
53 last_tzset = tt;
54 tzset();
55 }
56 tm = localtime(&tt);
57 if (tm)
58 {
59 Embryo_Cell *cptr;
60 double t;
61 float f;
62
63 cptr = embryo_data_address_get(ep, params[1]);
64 if (cptr) *cptr = tm->tm_year + 1900;
65 cptr = embryo_data_address_get(ep, params[2]);
66 if (cptr) *cptr = tm->tm_mon + 1;
67 cptr = embryo_data_address_get(ep, params[3]);
68 if (cptr) *cptr = tm->tm_mday;
69 cptr = embryo_data_address_get(ep, params[4]);
70 if (cptr) *cptr = tm->tm_yday;
71 cptr = embryo_data_address_get(ep, params[5]);
72 if (cptr) *cptr = (tm->tm_wday + 6) % 7;
73 cptr = embryo_data_address_get(ep, params[6]);
74 if (cptr) *cptr = tm->tm_hour;
75 cptr = embryo_data_address_get(ep, params[7]);
76 if (cptr) *cptr = tm->tm_min;
77 cptr = embryo_data_address_get(ep, params[8]);
78 t = (double)tm->tm_sec + (((double)timev.tv_usec) / 1000000);
79 f = (float)t;
80 if (cptr) *cptr = EMBRYO_FLOAT_TO_CELL(f);
81
82 }
83 return 0;
84}
85
86/* functions used by the rest of embryo */
87
88void
89_embryo_time_init(Embryo_Program *ep)
90{
91 embryo_program_native_call_add(ep, "seconds", _embryo_time_seconds);
92 embryo_program_native_call_add(ep, "date", _embryo_time_date);
93}