Files
harbour-core/harbour/doc/es/vm.txt
2002-01-22 22:23:33 +00:00

380 lines
15 KiB
Plaintext

/*
* $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 <alex_degarate@hotmail.com>
* 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 mayora 10 caracteres) así los OBJ de Harbour no serán
soportados por Clipper y viceversa.