1 /******************************** -*- C -*- **************************** 2 * 3 * Byte Code interpreter declarations. 4 * 5 * 6 ***********************************************************************/ 7 8 /*********************************************************************** 9 * 10 * Copyright 1988,89,90,91,92,94,95,99,2000,2001,2002,2006,2007,2008,2009 11 * Free Software Foundation, Inc. 12 * Written by Steve Byrne. 13 * 14 * This file is part of GNU Smalltalk. 15 * 16 * GNU Smalltalk is free software; you can redistribute it and/or modify it 17 * under the terms of the GNU General Public License as published by the Free 18 * Software Foundation; either version 2, or (at your option) any later 19 * version. 20 * 21 * Linking GNU Smalltalk statically or dynamically with other modules is 22 * making a combined work based on GNU Smalltalk. Thus, the terms and 23 * conditions of the GNU General Public License cover the whole 24 * combination. 25 * 26 * In addition, as a special exception, the Free Software Foundation 27 * give you permission to combine GNU Smalltalk with free software 28 * programs or libraries that are released under the GNU LGPL and with 29 * independent programs running under the GNU Smalltalk virtual machine. 30 * 31 * You may copy and distribute such a system following the terms of the 32 * GNU GPL for GNU Smalltalk and the licenses of the other code 33 * concerned, provided that you include the source code of that other 34 * code when and as the GNU GPL requires distribution of source code. 35 * 36 * Note that people who make modified versions of GNU Smalltalk are not 37 * obligated to grant this special exception for their modified 38 * versions; it is their choice whether to do so. The GNU General 39 * Public License gives permission to release a modified version without 40 * this exception; this exception also makes it possible to release a 41 * modified version which carries forward this exception. 42 * 43 * GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT 44 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 45 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 46 * more details. 47 * 48 * You should have received a copy of the GNU General Public License along with 49 * GNU Smalltalk; see the file COPYING. If not, write to the Free Software 50 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 51 * 52 ***********************************************************************/ 53 54 55 #ifndef GST_INTERP_H 56 #define GST_INTERP_H 57 58 /* The number of available process priorities */ 59 #define NUM_PRIORITIES 9 60 #define USER_SCHEDULING_PRIORITY 4 61 62 /* Ordering of file operations must match that used in 63 FileStream.st */ 64 enum 65 { 66 PRIM_OPEN_FILE, /* open:mode: */ 67 PRIM_CLOSE_FILE, /* no args */ 68 PRIM_PUT_CHARS, /* data:from:to: */ 69 PRIM_GET_CHARS, /* data:from:to: */ 70 PRIM_FSEEK_SET, /* position: */ 71 PRIM_FTELL, /* no args */ 72 PRIM_FEOF, /* no args */ 73 PRIM_OPEN_PIPE, /* open:mode: */ 74 PRIM_FSEEK_CUR, /* skip: */ 75 PRIM_FSIZE, /* no args */ 76 PRIM_FTRUNCATE, /* no args */ 77 PRIM_FILEIN, /* no args */ 78 PRIM_FILEIN_AT, /* line:file:charPos: */ 79 PRIM_SYNC_POLL, /* read/write/exception */ 80 PRIM_ASYNC_POLL, /* operation:semaphore: */ 81 PRIM_IS_PIPE, /* no args */ 82 PRIM_MK_TEMP, /* base: */ 83 PRIM_GET_CHARS_AT, /* data:from:to:absOfs: */ 84 PRIM_PUT_CHARS_AT, /* data:from:to:absOfs: */ 85 PRIM_SHUTDOWN_WRITE /* shutdown */ 86 }; 87 88 /* These macros are used to quickly compute the number of words needed 89 for a context with a maximum allowable stack depth of DEPTH. */ 90 #define FIXED_CTX_SIZE (sizeof(struct gst_method_context) / sizeof(PTR) - 1) 91 #define CTX_SIZE(depth) (((depth) << DEPTH_SCALE) + FIXED_CTX_SIZE) 92 93 #define DUMMY_NATIVE_IP FROM_INT(0) 94 95 /* The structure of execution context objects. */ 96 typedef struct gst_context_part 97 { 98 OBJ_HEADER; 99 OOP parentContext; 100 OOP native_ip; /* used by JIT */ 101 OOP ipOffset; /* an integer byte index into method */ 102 OOP spOffset; /* an integer index into cur context 103 stack */ 104 OOP receiver; /* the receiver OOP */ 105 OOP method; /* the method that we're executing */ 106 OOP x; /* depends on the subclass */ 107 OOP contextStack[1]; 108 } *gst_context_part; 109 110 typedef struct gst_method_context 111 { 112 OBJ_HEADER; 113 OOP parentContext; 114 OOP native_ip; /* used by JIT */ 115 OOP ipOffset; /* an integer byte index into method */ 116 OOP spOffset; /* an integer index into cur context 117 stack */ 118 OOP receiver; /* the receiver OOP */ 119 OOP method; /* the method that we're executing */ 120 intptr_t flags; /* must be an int to distinguish 121 gst_compiled_block/gst_method_context 122 */ 123 OOP contextStack[1]; 124 } *gst_method_context; 125 126 /* CompiledMethod cache (see descriptions in interp-bc.inl and 127 interp-jit.inl) */ 128 typedef struct method_cache_entry 129 { 130 OOP selectorOOP; 131 OOP startingClassOOP; 132 OOP methodOOP; 133 OOP methodClassOOP; 134 method_header methodHeader; 135 #ifdef ENABLE_JIT_TRANSLATION 136 OOP receiverClass; 137 PTR nativeCode; 138 PTR dummy; /* 32 bytes are usually a sweet spot */ 139 #endif 140 } method_cache_entry; 141 142 143 /* MCF stands for MethodContext Flag. */ 144 145 /* This is always set so that Smalltalk sees the flags member as 146 a SmallInteger. BlockContexts store the outer context there, 147 so it is never a SmallInteger. */ 148 #define MCF_IS_METHOD_CONTEXT 1 149 150 /* Answer whether this context must be skipped when doing a local 151 method return. Contexts are marked this way when an exception 152 occurs or if there is a non-local method return and there are 153 active #ensure: calls. */ 154 #define MCF_IS_DISABLED_CONTEXT 2 155 156 /* Answer whether this context must not be discarded upon a non-local 157 method return. Contexts evaluating #ensure: and/or #ifCurtailed: 158 are marked this way. */ 159 #define MCF_IS_UNWIND_CONTEXT 4 160 161 /* Answer whether execution started from this context (this kind 162 of MethodContext is used to mark call-ins from C to Smalltalk 163 and is placed on top of the context that was executing at the 164 time of the call-in, and is the parent of the called-in method). */ 165 #define MCF_IS_EXECUTION_ENVIRONMENT 8 166 167 168 typedef struct gst_block_context 169 { 170 OBJ_HEADER; 171 OOP parentContext; 172 OOP native_ip; /* used by JIT */ 173 OOP ipOffset; /* an integer byte index into method */ 174 OOP spOffset; /* an integer index into cur context 175 stack */ 176 OOP receiver; /* the receiver OOP */ 177 OOP method; /* the method that we're executing */ 178 OOP outerContext; /* the parent gst_block_context or 179 gst_method_context */ 180 OOP contextStack[1]; 181 } 182 *gst_block_context; 183 184 typedef struct gst_continuation 185 { 186 OBJ_HEADER; 187 OOP stack; 188 } 189 *gst_continuation; 190 191 /* The structure of various objects related to the process system. */ 192 typedef struct gst_semaphore 193 { 194 OBJ_HEADER; 195 OOP firstLink; 196 OOP lastLink; 197 OOP signals; 198 OOP name; 199 } 200 *gst_semaphore; 201 202 #define PROCESS_HEADER \ 203 OBJ_HEADER; \ 204 OOP nextLink; \ 205 OOP suspendedContext; \ 206 OOP priority; \ 207 OOP myList; \ 208 OOP name; \ 209 OOP unwindPoints; \ 210 OOP interrupts; \ 211 OOP interruptLock 212 213 typedef struct gst_process 214 { 215 PROCESS_HEADER; 216 } 217 *gst_process; 218 219 typedef struct gst_callin_process 220 { 221 PROCESS_HEADER; 222 OOP returnedValue; 223 } 224 *gst_callin_process; 225 226 typedef struct gst_processor_scheduler 227 { 228 OBJ_HEADER; 229 OOP processLists; 230 OOP activeProcess; 231 OOP idleTasks; 232 OOP processTimeslice; 233 OOP gcSemaphore; 234 OOP gcArray; 235 } 236 *gst_processor_scheduler; 237 238 /* Some performance counters from the interpreter: these 239 count the number of special returns. */ 240 extern unsigned long _gst_literal_returns 241 ATTRIBUTE_HIDDEN, _gst_inst_var_returns 242 ATTRIBUTE_HIDDEN, 243 _gst_self_returns 244 ATTRIBUTE_HIDDEN; 245 246 /* The number of primitives executed. */ 247 extern unsigned long _gst_primitives_executed 248 ATTRIBUTE_HIDDEN; 249 250 /* The number of bytecodes executed. */ 251 extern unsigned long _gst_bytecode_counter 252 ATTRIBUTE_HIDDEN; 253 254 /* The number of method cache misses */ 255 extern unsigned long _gst_cache_misses 256 ATTRIBUTE_HIDDEN; 257 258 /* The number of cache lookups - either hits or misses */ 259 extern unsigned long _gst_sample_counter 260 ATTRIBUTE_HIDDEN; 261 262 /* If this is true, for each byte code that is executed, we print on 263 stdout the byte index within the current gst_compiled_method and a 264 decoded interpretation of the byte code. If > 1, it applies also 265 to code not invoked by the user. */ 266 extern int _gst_execution_tracing 267 ATTRIBUTE_HIDDEN; 268 269 /* When this is true, and an interrupt occurs (such as SIGSEGV), 270 Smalltalk will terminate itself by making a core dump (normally it 271 produces a backtrace). */ 272 extern mst_Boolean _gst_make_core_file 273 ATTRIBUTE_HIDDEN; 274 275 /* When true, this indicates that there is no top level loop for 276 control to return to, so it causes the system to exit. */ 277 extern mst_Boolean _gst_non_interactive 278 ATTRIBUTE_HIDDEN; 279 280 /* The OOP for a gst_compiled_method or gst_compiled_block that is the 281 currently executing method. */ 282 extern OOP _gst_this_method 283 ATTRIBUTE_HIDDEN; 284 285 /* Physical address of the base of the method temporary variables. 286 Typically a small number of bytes (multiple of 4 since it points to 287 OOPs) lower than sp. */ 288 extern OOP *_gst_temporaries 289 ATTRIBUTE_HIDDEN; 290 291 /* Physical address of the base of the method literals. */ 292 extern OOP *_gst_literals 293 ATTRIBUTE_HIDDEN; 294 295 /* An OOP that is the current receiver of the current message. */ 296 extern OOP _gst_self 297 ATTRIBUTE_HIDDEN; 298 299 /* A gst_block_context or gst_method_context that indicates the 300 context that the interpreter is currently running in. */ 301 extern OOP _gst_this_context_oop 302 ATTRIBUTE_HIDDEN; 303 304 /* The OOP for an IdentityDictionary that stores the raw profile. */ 305 extern OOP _gst_raw_profile 306 ATTRIBUTE_HIDDEN; 307 308 /* A bytecode counter value used while profiling. */ 309 extern unsigned long _gst_saved_bytecode_counter 310 ATTRIBUTE_HIDDEN; 311 312 /* The type used to hold the instruction pointer. For the JIT, this 313 is an offset from a location which is deemed the `base' of 314 native-compiled methods (because this way it will fit in a 315 SmallInteger and can be stored in the returnIP field of the context 316 objects); for the interpreter, this is the physical address of the 317 next executed bytecode (note: the global is usually synchronized at 318 sequence points only). */ 319 #ifdef ENABLE_JIT_TRANSLATION 320 typedef int ip_type; 321 extern char *native_ip; 322 #else /* plain bytecode interpreter */ 323 typedef gst_uchar *ip_type; 324 #endif 325 #define ip _gst_ip 326 327 extern ip_type ip 328 ATTRIBUTE_HIDDEN; 329 330 typedef struct async_queue_entry 331 { 332 void (*func) (OOP); 333 OOP data; 334 struct async_queue_entry *next; 335 } 336 async_queue_entry; 337 338 /* When not NULL, this causes the byte code interpreter to immediately 339 send the message whose selector is here to the current stack 340 top. */ 341 extern const char *_gst_abort_execution 342 ATTRIBUTE_HIDDEN; 343 344 345 /* Set to true when some special action must be done at the next 346 sequence point. */ 347 #ifdef ENABLE_JIT_TRANSLATION 348 extern mst_Boolean _gst_except_flag 349 ATTRIBUTE_HIDDEN; 350 #endif 351 352 /* Create a new Process on the top of the stack, which is specially 353 marked so that it stops the interpreter's execution. This kind 354 of MethodContext is used to mark call-ins from C to Smalltalk 355 and is the parent of the called-in method. Return the Process. */ 356 extern OOP _gst_prepare_execution_environment (void) 357 ATTRIBUTE_HIDDEN; 358 359 /* Sends SELECTOR (which should be a Symbol, otherwise _gst_nil_oop is 360 returned) to RECEIVER. The message arguments should also be OOPs 361 (otherwise, an access violation exception is pretty likely) and are 362 passed in an array ARGS of size NARGS. The value returned from the 363 method is passed back as an OOP to the C program as the result of 364 the function, or _gst_nil_oop if the number of arguments is wrong. */ 365 extern OOP _gst_nvmsg_send (OOP receiver, 366 OOP selector, 367 OOP *args, 368 int nArgs) 369 ATTRIBUTE_HIDDEN; 370 371 /* Start the interpreter, and go on until we terminate PROCESSOOP. */ 372 extern OOP _gst_interpret (OOP processOOP) 373 ATTRIBUTE_HIDDEN; 374 375 /* Internal function for SEND_MESSAGE and for sends to super; send 376 SENDSELECTOR, with SENDARGS arguments, to RECEIVER. Start looking 377 for the method in METHOD_CLASS. 378 379 On entry to this routine, the stack should have the receiver and 380 the arguments pushed on the stack. We need to get a new context, 381 setup things like the IP, SP, and Temporary pointers, and then 382 return. Note that this routine DOES NOT invoke the interpreter; it 383 merely sets up a new context so that calling (or, more typically, 384 returning to) the interpreter will operate properly. This kind of 385 sending is for normal messages only. Things like sending a "value" 386 message to a block context are handled by primitives which do 387 similar things, but they use information from gst_block_closure 388 objects that we don't have available (nor need) here. */ 389 extern void _gst_send_message_internal (OOP sendSelector, 390 int sendArgs, 391 OOP receiver, 392 OOP method_class) 393 ATTRIBUTE_HIDDEN; 394 395 /* Prepare the data structures held by the interpreter. */ 396 extern void _gst_init_interpreter (void) 397 ATTRIBUTE_HIDDEN; 398 399 /* Reset the fast allocator for context objects, telling it that 400 all contexts living there have been tenured and thus the space 401 can be reused. */ 402 extern void _gst_empty_context_pool (void) 403 ATTRIBUTE_HIDDEN; 404 405 /* Return whether there are pending asynchronous calls. */ 406 extern mst_Boolean _gst_have_pending_async_calls (void) 407 ATTRIBUTE_HIDDEN; 408 409 /* Set up so that FUNC will be called, with ARGOOP as its argument, 410 as soon as the next sequence point is reached. */ 411 extern void _gst_async_call (void (*func) (OOP), 412 OOP argOOP) 413 ATTRIBUTE_HIDDEN; 414 415 /* Worker functions for _gst_async_call_internal. */; 416 extern void _gst_do_async_signal (OOP semaphoreOOP) 417 ATTRIBUTE_HIDDEN; 418 extern void _gst_do_async_signal_and_unregister (OOP semaphoreOOP) 419 ATTRIBUTE_HIDDEN; 420 421 /* Set up so that ENTRY->FUNC will be called, with ENTRY->DATA as its 422 argument, as soon as the next sequence point is reached. Async-signal 423 safe version. */ 424 extern void _gst_async_call_internal (async_queue_entry *entry) 425 ATTRIBUTE_HIDDEN; 426 427 /* Signal SEMAPHOREOOP so that one of the processes waiting on that 428 semaphore is waken up. Since a Smalltalk call-in is not an atomic 429 operation, the correct way to signal a semaphore is not to send 430 #signal to the object but, rather, to use this function. The 431 signal request will be processed as soon as the next sequence point 432 is reached. */ 433 extern void _gst_async_signal (OOP semaphoreOOP) 434 ATTRIBUTE_HIDDEN; 435 436 /* Signal SEMAPHOREOOP so that one of the processes waiting on that 437 semaphore is waken up, and remove it from the registry. Since a 438 Smalltalk call-in is not an atomic operation, the correct way to 439 signal a semaphore is not to send #signal to the object but, 440 rather, to use this function. The signal request will be processed 441 as soon as the next sequence point is reached. */ 442 extern void _gst_async_signal_and_unregister (OOP semaphoreOOP) 443 ATTRIBUTE_HIDDEN; 444 445 /* Invalidate all the cached CompiledMethod lookups. This does NOT 446 include inline caches when the JIT compiler is active. */ 447 extern void _gst_invalidate_method_cache (void) 448 ATTRIBUTE_HIDDEN; 449 450 /* Show a backtrace of the current state of the stack of execution 451 contexts. */ 452 extern void _gst_show_backtrace (FILE *) 453 ATTRIBUTE_HIDDEN; 454 455 /* Trap the signals that we care about, basically SIGBUS and 456 SIGSEGV. */ 457 extern void _gst_init_signals (void) 458 ATTRIBUTE_HIDDEN; 459 460 /* Store the context of the VM registers into the currently executing 461 contexts. Since the contexts store relative addresses, these are 462 valid across GCs and we can count on them and on the OOPs (which do 463 not move) to adjust the interior pointers that the VM uses. Note 464 that normally fields such as SP or IP are not valid for the 465 currently executing contexts (they are only used after a message 466 send) so we need a special function to ensure that even that 467 context has the information saved in it. */ 468 extern void _gst_fixup_object_pointers (void) 469 ATTRIBUTE_HIDDEN; 470 471 /* Complementary to _gst_fixup_object_pointers, this function picks 472 the relative addresses stored in the current context and uses 473 them to adjust the VM registers after the heap is compacted or 474 grown. */ 475 extern void _gst_restore_object_pointers (void) 476 ATTRIBUTE_HIDDEN; 477 478 /* This runs before every evaluation and before GC turned on. It creates an 479 initial process if no process is ready to run or if no process has been 480 created yet. */ 481 extern void _gst_init_process_system (void) 482 ATTRIBUTE_HIDDEN; 483 484 /* These function mark or copy all the objects that the interpreter keeps in 485 the root set. These are the semaphores that are held to be 486 signaled by an asynchronous event (note that they *are* in the root 487 set because they could be the only way from which we can get to the 488 suspended process!), the semaphores that are queued to be signaled 489 at the next sequence point (_gst_async_signals queues them) and the 490 currently executing context. Everything else is supposedly 491 reachable from the current context (including the current method, 492 the receiver, the receiver class even if it does not live in a 493 namespace, and all the context on the execution stack) or from 494 Processor (including the current process and the other active 495 processes). Processor itself is reachable from the Smalltalk 496 dictionary. */ 497 extern void _gst_mark_processor_registers (void) 498 ATTRIBUTE_HIDDEN; 499 extern void _gst_copy_processor_registers (void) 500 ATTRIBUTE_HIDDEN; 501 502 /* Print the current state of the lists of ready to run processes for 503 each priority, for debugging purposes. */ 504 extern void _gst_print_process_state (void) 505 ATTRIBUTE_HIDDEN; 506 507 /* Sanity check the process lists that the sole instance of ProcessorScheduler 508 holds. */ 509 extern void _gst_check_process_state (void) 510 ATTRIBUTE_HIDDEN; 511 512 /* Print the objects currently on the stack, for debugging 513 purposes. */ 514 extern void _gst_show_stack_contents (void) 515 ATTRIBUTE_HIDDEN; 516 517 /* Called after the mark phase, but before the sweep phase, so that if 518 a method cache entry is not valid anymore it is cleared. This is 519 because in the JIT case a method cache entry is invalidated not 520 only if the related method does not exist anymore (and this is done 521 by the Smalltalk implementation of the MethodDictionary class) but 522 also if the translation to native code for the method is garbage 523 collected. In particular, this function is called *after* the 524 unused method translations are marked as such, and *before* they 525 are actually freed. */ 526 extern void _gst_validate_method_cache_entries (void) 527 ATTRIBUTE_HIDDEN; 528 529 /* Terminate execution of the given PROCESSOOP. */ 530 extern void _gst_terminate_process (OOP processOOP) 531 ATTRIBUTE_HIDDEN; 532 533 /* This is a further simplified lookup_method which does not care 534 about preparing for #doesNotUnderstand:. */ 535 extern mst_Boolean _gst_find_method (OOP classOOP, OOP sendSelector, 536 method_cache_entry *mce) 537 ATTRIBUTE_HIDDEN; 538 539 /* Similar to _gst_send_message_internal, but forces the specified 540 CompiledMethod to be sent. If it is not valid for the current 541 receiver, well, you are looking for trouble and well deserve it. 542 The number of arguments is looked in METHODOOP. */ 543 extern void _gst_send_method (OOP methodOOP) 544 ATTRIBUTE_HIDDEN; 545 546 /* This functions accepts an OOP for a Semaphore object and puts the 547 current process to sleep, unless the semaphore has excess signals 548 on it. Since a Smalltalk call-in is not an atomic operation, the 549 correct way to signal a semaphore is not to send the wait method to 550 the object but, rather, to use _gst_sync_wait. The `sync' in the 551 name of this function distinguishes it from _gst_async_signal, in 552 that it cannot be called from within a signal handler. */ 553 extern void _gst_sync_wait (OOP semaphoreOOP) 554 ATTRIBUTE_HIDDEN; 555 556 /* Signal the given SEMAPHOREOOP and if processes were queued on it 557 resume the one that has waited for the longest time and is still 558 alive. If INCR is true, increment its value if no processes were 559 queued. Return true if a process was woken. 560 561 This functions also cannot be called from within a signal handler. 562 It can be called from a function that is registered with 563 _gst_async_call, though. */ 564 extern mst_Boolean _gst_sync_signal (OOP semaphoreOOP, 565 mst_Boolean incr_if_empty) 566 ATTRIBUTE_HIDDEN; 567 568 /* Take a CompiledBlock and turn it into a BlockClosure that references 569 thisContext as its static link. */ 570 extern OOP _gst_make_block_closure (OOP blockOOP) 571 ATTRIBUTE_HIDDEN; 572 573 /************************************************* PRIMITIVES ****************/ 574 575 /* The type for a routine providing the definition for one or more 576 primitive methods in the GNU Smalltalk system. They normally 577 remove the arguments to the primitive methods from the stack, but 578 if the primitive fails, the arguments are put back onto the stack 579 and the routine returns true (-1 for the JIT), indicating failure 580 to invoke the primitive. Such a function must execute a primitive, 581 aided in the choice of which by the user-defined parameter ID, 582 popping NUMARGS methods off the stack if they succeed. */ 583 typedef intptr_t (*primitive_func) (int primitive, 584 volatile int numArgs); 585 586 /* Table of primitives, including a primitive and its attributes. */ 587 typedef struct prim_table_entry 588 { 589 const char *name; 590 primitive_func func; 591 int attributes; 592 int id; 593 } 594 prim_table_entry; 595 596 #define PRIM_SUCCEED 0x0001 597 #define PRIM_FAIL 0x0002 598 #define PRIM_RELOAD_IP 0x0004 599 #define PRIM_OUTCOMES 0x0007 600 #define PRIM_CACHE_NEW_IP 0x0008 601 #define PRIM_INLINED 0x0010 602 #define PRIM_CHECK_INTERRUPT 0x0020 603 #define PRIM_RETURN_SMALL_INTEGER 0x0100 /* 31 or 63 bits */ 604 #define PRIM_RETURN_SMALL_SMALLINTEGER 0x0300 /* 30 or 62 bits */ 605 606 /* The checksum of the table of primitive numbers. Right now it is an MD5, 607 computed from part of the C source code of prims.inl. We compare it when 608 loading an image, to avoid having to reload the primitive table. */ 609 extern unsigned char _gst_primitives_md5[16]; 610 611 /* The table of functions that implement the primitives. */ 612 extern prim_table_entry _gst_primitive_table[NUM_PRIMITIVES]; 613 extern prim_table_entry _gst_default_primitive_table[NUM_PRIMITIVES]; 614 615 /* This can be used to obtain information on a particular primitive 616 operations in the GNU Smalltalk system. */ 617 extern prim_table_entry * _gst_get_primitive_attributes (int primitive) 618 ATTRIBUTE_PURE 619 ATTRIBUTE_HIDDEN; 620 621 /* Dually, this maps the primitive number that will be used for running 622 the image, to the entry which was returned by _gst_get_primitive_attributes. 623 If PTE is NULL, the primitive will be invalid. */ 624 extern void _gst_set_primitive_attributes (int primitive, 625 prim_table_entry *pte) 626 ATTRIBUTE_HIDDEN; 627 628 /* Initialize the table of primitives. */ 629 extern void _gst_init_primitives () 630 ATTRIBUTE_HIDDEN; 631 632 /* Get the value of internal variable whose number is INDEX; the 633 list of valid variables is in gstpub.h. Return -1 if the index 634 is invalid. */ 635 extern int _gst_get_var (enum gst_var_index index) 636 ATTRIBUTE_HIDDEN; 637 638 /* Set the value of internal variable whose number is INDEX; the 639 list of valid variables is in gstpub.h. Return -1 if the index 640 is invalid or the value is negative, otherwise return the previous 641 value. */ 642 extern int _gst_set_var (enum gst_var_index index, int value) 643 ATTRIBUTE_HIDDEN; 644 645 #endif /* GST_INTERP_H */ 646