/* * $Id$ */ /* * Las siguientes partes son derechos adquiridos de sus autores individuales. * www - http://www.harbour-project.org * * Copyright 2001 Antonio Linares * Documentaci¢n en Ingl‚s de vm.txt * * Copyright 2001 Alejandro de G rate * Traducci¢n al Espa¤ol de vm.txt * * Vea doc/license.txt por los t‚rminos de la licencia. * */ La M quina Virtual de Harbour (Virtual Machine ¢ VM) ==================================================== La VM es un bucle de ejecuci¢n infinita mientras se ejecute el programa. La VM esta formada por el bucle principal de ejecuci¢n y varios subsistemas, cada uno de los cuales puede ser te¢ricamente reemplazado, suponiendo que Ud. respete la interfaz de cada subsistema. El bucle principal de ejecuci¢n esta definido en una funcion de C llamada VirtualMachine(), la cual recibe 2 parametros: la intrucciones pcode para ejecutar y la tabla local de s¡mbolos (una porci¢n de la tabla de s¡mbolos OBJs (estatica) ) usada para ese pcode. Por favor revise hbpcode.h para la implementacion actual de los pcode de los opcodes. VM( pcode, local symbols ) La VM puede invocar a la VM de nuevo (a s¡ misma). Esto permite al lenguaje Clipper acceder a funciones y metodos Clipper y funciones externas en lenguaje C una vez y otra vez. La VM organiza estos m£ltiples accesos en una forma ordenada y totalmente controlada e implementa servicios para acceder a esos m£ltiples niveles de ejecuci¢n (ProcName(), ProcLine(), depuraci¢n y acceso a las variables de la pila). Los subsistemas VM son continuamente usados por el bucle principal de ejecuci¢n. Vamos a revisar esos subsistemas VM. El Arranque: La Pila (stack): La tabla est tica de s¡mbolos: La tabla din mica de s¡mbolos: Variables est ticas y p£blicas: La memoria: El sistema extendido: Arrays Multidimensionales: El motor de Objetos: El subsistema macro: El subsistema de areas de trabajo: El Arranque: ============ Controla la inicializaci¢n de los diferentes subsistemas de la VM, esta es invocada al principio de la aplicaci¢n. Esta tambi‚n controla la salida de la aplicaci¢n. La Pila (stack): ================ La VM No usa la pila de la computadora directamente, esta usa en su lugar su propia pila para manipular valores (parametros, valores retornados y s¡mbolos) como lo hace la pila de hardware. La tabla est tica de s¡mbolos: ============================= Es creada por el compilador en tiempo de compilaci¢n y agrupada por el enlazador (linker) en los OBJs, Este subsistema es responsable por un inmediato acceso a la ubicaci¢n de las funciones y est  altamente relacionada a la tabla din mica de s¡mbolos en tiempo de ejecuci¢n. Esta tabla contiene muchos s¡mbolos duplicados que ser n optimizados por la tabla din mica de s¡mbolos. La tabla din mica de s¡mbolos: ============================== Es din micamente generada desde el subsistema de inicio al principio de la aplicaci¢n. Esta organiza en una forma eficiente la tabla est tica de s¡mbolos creando un ¡ndice alfabetico que permite, una b£squeda dicotomica de los s¡mbolos. Este subsistema es responsable por el r pido acceso a los s¡mbolos (funciones, variables, campos y alias de las  reas de trabajo). Variables est ticas y p£blicas: =============================== Responsable por el almacenamiento de variables p£blicas y est ticas. La memoria: =========== Responsable por la ubicaci¢n, reubicaci¢n, bloqueo, desbloqueo y liberaci¢n de memoria. El sistema extendido: ===================== Define la interfaz (_parc(), ..., _retc() ) desde un bajo nivel (lenguaje C) hasta un alto nivel (lenguaje Clipper). Este subsistema es responsable por conectar en una forma adecuada las funciones en lenguaje C a la aplicaci¢n entera. Arrays Multidimensionales: ========================== Este subsistema permite la creaci¢n de arrays, y los servicios para manipular estos en todas sus formas. Los arrays son extensivamente usados por el lenguaje Clipper y tambi‚n ellos son la fundaci¢n de los Objetos (los Objetos son s¢lo arrays referidos a una Clase espec¡fica). El motor de Objetos: ==================== Responsable por la creaci¢n de Clases y Objetos. Este tambi‚n define la forma de acceso a un m‚todo espec¡fico de clase para ser invocados por la VM y provee todo tipo de informaci¢n de clases que pueden ser requeridos al tiempo de la ejecuci¢n. El subsistema macro: ==================== Este implementa un compilador reducido que puede ser usado en tiempo de ejecuci¢n para generar pcodes para ser usados por la aplicaci¢n. En efecto esta es una parte de la especificaciones de yacc (Bison) para Harbour. El subsistema de  reas de trabajo: ================================== Responsable por el manejo de las bases de datos. Este subsistema define la ubicaci¢n donde las areas de trabajos ser n almacenadas y provee todas las funciones de acceso a esas areas de trabajo. Este tambi‚n implementa la interfaz para el controlador de base de datos reemplazable. Pregunta: Los opcodes de Harbour imitar n a los de Clipper ? (habr  una relaci¢n 1:1 entre ellos) Si es as¡, est n los opcodes de Clipper descriptos en alg£n lado ?. Respuesta: Lenguaje Clipper pcode de opcodes DEFINE NOMBRE VALOR BYTES #define NOP 0x00 1 #define PUSHC 0x01 3 + literal #define PUSHN 0x05 3 #define POPF 0x06 3 #define POPM 0x07 3 #define POPQF 0x08 3 #define PUSHA 0x09 3 #define PUSHF 0x0A 3 #define PUSHM 0x0B 3 #define PUSHMR 0x0C 3 #define PUSHP 0x0D 3 #define PUSHQF 0x0E 3 #define PUSHV 0x0F 3 #define SFRAME 0x10 3 #define SINIT 0x11 3 #define SYMBOL 0x12 3 #define SYMF 0x13 3 #define BEGIN_SEQ 0x19 3 #define JDBG 0x1A 3 #define JF 0x1B 3 #define JFPT 0x1C 3 #define JISW 0x1D 3 #define JMP 0x1E 3 #define JNEI 0x1F 3 #define JT 0x20 3 #define JTPF 0x21 3 #define PUSHBL 0x23 3 #define ARRAYATI 0x24 3 #define ARRAYPUTI 0x25 3 #define CALL 0x26 3 #define DO 0x27 3 #define FRAME 0x28 3 #define FUNC 0x29 3 #define LINE 0x2A 3 #define MAKEA 0x2B 3 #define MAKELA 0x2C 3 #define PARAMS 0x2D 3 #define POPFL 0x2E 3 #define POPL 0x2F 3 #define POPS 0x30 3 #define PRIVATES 0x31 3 #define PUBLICS 0x33 3 #define PUSHFL 0x34 3 #define PUSHFLR 0x35 3 #define PUSHI 0x36 3 #define PUSHL 0x37 3 #define PUSHLR 0x38 3 #define PUSHS 0x39 3 #define PUSHSR 0x3A 3 #define PUSHW 0x3B 3 #define SEND 0x3C 3 #define XBLOCK 0x3D 3 #define MPOPF 0x4A 5 #define MPOPM 0x4B 5 #define MPOPQF 0x4C 5 #define MPUSHA 0x4D 5 #define MPUSHF 0x4E 5 #define MPUSHM 0x4F 5 #define MPUSHMR 0x50 5 #define MPUSHP 0x51 5 #define MPUSHQF 0x52 5 #define MPUSHV 0x53 5 #define MSYMBOL 0x54 5 #define MSYMF 0x55 5 #define ABS 0x56 1 #define AND 0x57 1 #define ARRAYAT 0x58 1 #define ARRAYPUT 0x59 1 #define BREAK 0x5A 1 #define DEC 0x5B 1 #define DIVIDE 0x5C 1 #define DOOP 0x5D 1 #define EEQ 0x5E 1 #define ENDBLOCK 0x5F 1 #define ENDPROC 0x60 1 #define END_SEQ 0x61 1 #define EQ 0x62 1 #define EVENTS 0x63 1 #define FALSE 0x64 1 #define GE 0x65 1 #define GT 0x66 1 #define INC 0x67 1 #define LE 0x68 1 #define LT 0x69 1 #define MINUS 0x6A 1 #define MULT 0x6B 1 #define NE 0x6C 1 #define NEGATE 0x6E 1 #define NOP2 0x6F 1 #define NOT 0x70 1 #define NULL 0x71 1 #define ONE1 0x72 1 #define OR 0x73 1 #define PCOUNT 0x74 1 #define PLUS 0x75 1 #define POP 0x76 1 #define PUSHRV 0x77 1 #define QSELF 0x78 1 #define SAVE_RET 0x79 1 #define TRUE 0x7A 1 #define UNDEF 0x7B 1 #define ZER0 0x7C 1 #define ZZBLOCK 0x7D 1 #define AXPRIN 0x7E 1 #define AXPROUT 0x7F 1 #define BOF 0x80 1 #define DELETED 0x81 1 #define EOF 0x82 1 #define FCOUNT 0x83 1 #define FIELDNAME 0x84 1 #define FLOCK 0x85 1 #define FOUND 0x86 1 #define FSELECT0 0x87 1 #define FSELECT1 0x88 1 #define LASTREC 0x89 1 #define LOCK 0x8A 1 #define RECNO 0x8B 1 #define BNAMES 0x8C 1 #define LNAMES 0x8D 1 #define SNAMES 0x8E 1 #define SRCNAME 0x8F 1 #define TYPE 0x90 1 #define WAVE 0x91 1 #define WAVEA 0x92 1 #define WAVEF 0x93 1 #define WAVEL 0x94 1 #define WAVEP 0x95 1 #define WAVEPOP 0x96 1 #define WAVEPOPF 0x97 1 #define WAVEPOPQ 0x98 1 #define WAVEQ 0x99 1 #define WSYMBOL 0x9A 1 #define AADD 0x9B 1 #define ASC 0x9C 1 #define AT 0x9D 1 #define CDOW 0x9E 1 #define CHR 0x9F 1 #define CMONTH 0xA0 1 #define CTOD 0xA1 1 #define DATE 0xA2 1 #define DAY 0xA3 1 #define DOW 0xA4 1 #define DTOC 0xA5 1 #define DTOS 0xA6 1 #define EMPTY 0xA7 1 #define QEXP 0xA8 1 #define EXPON 0xA9 1 #define INSTR 0xAA 1 #define INT 0xAB 1 #define LEFT 0xAC 1 #define LEN 0xAD 1 #define LOGQ 0xAE 1 #define LOWER 0xAF 1 #define LTRIM 0xB0 1 #define MAX 0xB1 1 #define MIN 0xB2 1 #define MODULUS 0xB3 1 #define MONTH 0xB4 1 #define REPLICATE 0xB5 1 #define ROUND 0xB6 1 #define SECONDS 0xB7 1 #define SPACE 0xB8 1 #define QSQRT 0xB9 1 #define STR1 0xBA 1 #define STR2 0xBB 1 #define STR3 0xBC 1 #define SUB2 0xBD 1 #define SUB3 0xBE 1 #define TIME 0xBF 1 #define TRIM 0xC0 1 #define UPPER 0xC1 1 #define VAL 0xC2 1 #define VALTYPE 0xC3 1 #define WORD 0xC4 1 #define YEAR 0xC5 1 #define TRANS 0xC6 1 #define COL 0xC7 1 #define DEVPOS 0xC8 1 #define INKEY0 0xC9 1 #define INKEY1 0xCA 1 #define PCOL 0xCB 1 #define PROW 0xCC 1 #define ROW 0xCD 1 #define SETPOS 0xCE 1 #define SETPOSBS 0xCF 1 Harbour no implementar  todos ellos porque nosotros queremos proveer la mayor libertad a los programadores para extender y modificar Harbour tanto como se necesite. Por ejemplo: El lenguaje Clipper usa opcodes para Row(), Col(), Upper(), Space(), Replicate(), InKey(), Year(), Month(), etc... donde nosotros s¢lo queremos llamar a una funci¢n estandar de lenguaje C, que use el sistema extendido est ndar y que pueda ser facilmente modificada. As¡ Harbour usar  muchos menos opcodes que el lenguaje Clippper. Esto ayudar  a tener un compilador y una VM m s simple y f cil de mantener. Pregunta: He visto que, por ejemplo Clipper tiene un opcode llamado "PUSHWORD" (06), mientras Valkyirie lo llama "PUSHW"(3B): Diferentes nombres, diferentes c¢digos. No es deseable que el pCode de Harbour sea binario-compatible con Clipper ?. Si fuera as¡ la VM de Harbour podr¡a interpretar c¢digo de Clipper y viceversa. Respuesta: Los opcodes de Harbour estan definidos en hbpcode.h Nosotros estamos tratando que los mnem¢nicos sean muy f ciles de usar, as¡ PUSHWORD parece mas f cil que PUSHW. Los valores de los opcodes son de poco valor porque ellos son solo usados por una sentencia switch del lenguaje C (en realidad hay una poderosa optimizaci¢n la cual es: usar el mismo pcode de los opcodes como un ¡ndice al array de punteros de las funciones de la VM, as¡ la velocidad de ejecuci¢n de la VM puede incrementarse). Clipper usa esto. Nosotros no estamos implementando totalmente el modelo de OBJs del lenguaje Clipper (por ej. para proveer identificadores de nombre de longitud mayor a 10 caracteres) as¡ los OBJ de Harbour no ser n soportados por Clipper y viceversa.