exarray.asm
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:12k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. page 49,132
  2. TITLE exarray - Array statement executors
  3. ;***
  4. ;exarray.asm - interpreter specific array support.
  5. ;
  6. ; Copyright <C> 1986, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ;
  10. ;   This module includes:
  11. ;   - DIM, REDIM, and OPTION BASE executors.
  12. ;
  13. ;
  14. ;****************************************************************************
  15. .xlist
  16. include  version.inc
  17. EXARRAY_ASM = ON
  18. IncludeOnce architec
  19. IncludeOnce context
  20. IncludeOnce executor
  21. IncludeOnce exint
  22. IncludeOnce extort
  23. IncludeOnce opid
  24. IncludeOnce opintrsc
  25. IncludeOnce opstmt
  26. IncludeOnce pcode
  27. IncludeOnce scanner
  28. IncludeOnce ui
  29. IncludeOnce variable
  30. .list
  31. assumes cs, CODE
  32. assumes es, NOTHING
  33. assumes ss, DATA
  34. extrn ScanExExit:far
  35. extrn B$ERAS:far
  36.     extrn   B$ADIM:far
  37. sBegin DATA
  38. extrn SsScanExSrc:word
  39. public DimAtScanType
  40. DimAtScanType db SSDIM_EXECUTE ; Type of Dim initiated by scanner
  41. sEnd DATA
  42. sBegin CODE
  43. ;***
  44. ;exStOptionBase<0|1>
  45. ;Purpose:
  46. ; Handled at scan time so it doesn't need to be executed
  47. ;
  48. ;***************************************************************************
  49. MakeExe exStOptionBase0,opStOptionBase0
  50. SkipExHeader
  51. MakeExe exStOptionBase1,opStOptionBase1
  52. jmp short Disp1
  53. ;***
  54. ;exDimOptionBase - executor to push current option base
  55. ;Purpose:
  56. ; Emit the current OPTION BASE setting.
  57. ; One use for this executor is as follows:
  58. ; Array dimension clauses in DIM and REMDIM may or may not use the
  59. ; TO keyword.  This executor is used in cases where TO is not used
  60. ; so that DIM and REDIM executors always get both the lower and upper
  61. ; bound for each dimension.
  62. ;Input:
  63. ; none
  64. ;Output:
  65. ; stack contains current OPTION BASE (ET_I2).
  66. ;Modifies:
  67. ; none
  68. ;***************************************************************************
  69. MakeExe exDimOptionBase,opDimOptionBase
  70. GETRS_SEG es,bx,<SIZE,LOAD>
  71. mov bx,[grs.GRS_oMrsCur]
  72. RS_BASE add,bx
  73. xor ax,ax
  74. test BPTRRS[bx.MRS_flags],FM_OptionBase1  
  75. je OptBase0 ;brif Current OPTION BASE setting is 0
  76. inc ax ;else it is 1
  77. OptBase0:
  78. push ax ;Return result on stack
  79. Disp1:
  80. jmp DispMov  ; refresh es and dispatch
  81. subttl Value Table Reference Ids
  82. page
  83. ;***
  84. ;exAVtRf - variable table reference executor
  85. ;
  86. ;Purpose:
  87. ;
  88. ;   This executor is used in the Dim, COMMON, SHARED, STATIC, Auto,
  89. ;   and Public statements.  The only executable statement in the
  90. ;   group is Dim and this is only executable with FV_QB4LANG.
  91. ;
  92. ;   There are two possible situations for these executors to be
  93. ;   executed.  The first is during scan time, these can be dispatched
  94. ;   to allocate the storage for the array.  Currently, this occurs for
  95. ;   $Static Common arrays only and then during the Dim statement processing.
  96. ;   The second situation is during normal execution with FV_QB4LANG.  In this
  97. ;   case, the array is checked if $Static or $Dynamic. If $Static, no
  98. ;   action is taken if already allocated.  If $Dynamic, allocation occurs.
  99. ;
  100. ;Input:
  101. ;Output:
  102. ;Modifies:
  103. ;***************************************************************************
  104. MakeExe exAVtRfSD,opAVtRf,ET_SD
  105. SkipExHeader
  106. MakeExe exAVtRfR8,opAVtRf,ET_R8
  107. SkipExHeader
  108. MakeExe exAVtRfI4,opAVtRf,ET_I4
  109. SkipExHeader
  110. MakeExe exAVtRfR4,opAVtRf,ET_R4
  111. SkipExHeader
  112. MakeExe exAVtRfI2,opAVtRf,ET_I2
  113. SkipExHeader
  114. MakeExe exAVtRfImp,opAVtRf,ET_Imp
  115. inc si ; Ignore argument count
  116. inc si
  117. LODSWTX
  118. xchg ax,bx ;BX = oVar
  119. DoDim:
  120. xor cx,cx ;Indicate Dim
  121.     jmp     short DimReDim ;Jump into shared code
  122. public DimImplicit
  123. DimImplicit:
  124. GETRS_SEG es
  125.     mov     bx,[grs.GRS_oMrsCur]
  126.     RS_BASE add,bx
  127. mov al,BPTRRS[bx.MRS_flags] ;Low bound is option base
  128. .erre FM_OptionBase1 EQ 1
  129. and ax,FM_OptionBase1 ;AX = option base (0 or 1)
  130. mov dx,10 ;Upper bound is 10
  131. call GetEsDi  ;Setup to access pcode
  132. mov cx,PTRTX[si] ;CX = cDims
  133. mov bx,PTRTX[si+2] ;BX = oVar
  134. @@:
  135. push ax ;Push low bound
  136. push dx ;Push upper bound
  137. loop @B ;Brif more dimensions
  138. mov [DimAtScanType],SSDIM_STATIC
  139. jmp short DoDim
  140. page
  141. ;***
  142. ;exStReDimTo - REDIM executors.
  143. ;
  144. ;Purpose:
  145. ;
  146. ;   For DIM:
  147. ;   =======
  148. ;      Syntax: DIM <id>(x TO y,...) or DIM <id>(x,...)
  149. ;      Runtime Entry Point for DIM for arrays.
  150. ;      DIM Statement for dynamic arrays.  If the array is
  151. ;      already defined, an error is returned.
  152. ;
  153. ;   For REDIM:
  154. ;   =========
  155. ;      Syntax: REDIM <id>(x TO y,...) or REDIM <id>(x,...)
  156. ;      Runtime Entry Point for REDIM for arrays.
  157. ;      This algorithm depends on:
  158. ;      1. VarMgr setting up an array template, even for dynamic or common
  159. ;   variables.
  160. ;      2. Scanner verifying correctness of index argument count
  161. ;
  162. ;Input:
  163. ;
  164. ;   Stack contains:
  165. ; Variable Table Offset
  166. ; Index count
  167. ; count index arguments, consisting of lower and upper bounds
  168. ;
  169. ;Output:
  170. ;
  171. ;   none
  172. ;
  173. ;Modifies:
  174. ;
  175. ;*************************************************************************
  176. MakeExe exStReDimTo,opStReDimTo
  177. pop cx ; cx = pAD.  This is never 0!!!
  178. DbAssertRel cx,ne,0,CODE,<exStReDimTo: pAD == 0>
  179. mov bx,PTRTX[si-4] ; Get Offset to Variable table
  180. DimReDim:
  181. DbChk oVar,bx  ;Verify that this is a variable
  182. mov dx,[pVarBx-VAR_value].VAR_flags 
  183. mov ax,dx
  184. and ax,FV_TYP_MASK
  185. jz RecArray
  186. .erre ET_MAX LT 100h ; Assure we can use AL
  187. cmp al,ET_FS ;[9]
  188. jb HavOTyp 
  189.     .erre   ET_FS EQ ET_MaxStr ;[9]
  190.     if     ET_MaxStr NE ET_MAX 
  191. ja HavOTyp 
  192.     endif ; ET_MaxStr NE ET_MAX
  193.     push    ax ; Save oTyp
  194. push [pVarBx-VAR_Value].VAR_cbFixed ; Push length
  195. jmp short HaveSize
  196. RecArray:
  197. mov ax,[pVarBx-VAR_value].VAR_oTyp ; Get type while we have pVt
  198. HavOTyp:
  199.     push    ax ; Save oTyp
  200. call OTypCbTyp ;ax = bytes in oType passed in ax
  201. push ax ;push cbElement
  202. HaveSize:
  203.     ;Look for $STATIC array in COMMON
  204.     cmp     [DimAtScanType],SSDIM_COMMON
  205.     jne     NotStaticCommon ; Brif not Dim'ing $Static common
  206.     pop     cx ; cbElement
  207.     pop     ax ; oTyp
  208.     push    cx ; Restore cbElement
  209.     mov     dl,[pVarBx].ACOM_cDims  
  210.     mov     dh,FADF_STATIC+FADF_NEAR
  211.     cmp     ax,ET_SD ;See if string
  212.     jne     @F
  213.     or     dh,FADF_SD ;Tell runtime this is a string array
  214. @@:
  215.     push    dx ;Push flags/cDims
  216.     push    [SsScanExSrc] ;Push pAd
  217.     ;Compute size of $Static array and set up array descriptor
  218.     call    B$ADIM ;Compute array size, don't allocate
  219.     mov     [SsScanExSrc],ax ;Save return value
  220.     jmp     short DimXds ;Return to scanner
  221. NotStaticCommon:
  222. jcxz @F ; Brif Dim
  223. mov bx,cx ; DI:BX = sbAd:oAd
  224. mov cx,1 ; Needed below
  225. jmp short GotPAd
  226. @@:
  227. call oVarToPAd ;on exit bx = pAd
  228. ; sets FADF_STATIC & cDims in array desc
  229. GotPAd: 
  230. ;It's OK to execute a single $STATIC DIM more than once.  Multiple DIMs
  231. ;are caught at scan time.  However, DIM of a $STATIC array passed as a
  232. ;parameter is illegal. In EB this test is not necessary because Dim
  233. ;statements are not executable.  Therefore, a $Static array will
  234. ;never be allocated more than once.
  235.     TestX   dx,FVFORMAL  ;Passed as parameter?
  236.     pop     dx ; cbElement
  237.     pop     ax ;AX = oTyp
  238.     push    dx ; Restore cbElement
  239. mov dx,word ptr [bx].AD_cDims ;get flags byte & cDimensions (set up
  240.   ;  by oVarToPAd)
  241.     jnz     @F ;Brif parameter, always attempt Dim
  242.     ;Allow multiple DIM of $STATIC arrays
  243.     test    dh,FADF_STATIC ;$STATIC array?
  244.     jz     @F ;If not, always DIM it
  245.     cmp     [bx].FHD_hData,0 ;Space allocated to $STATIC array?
  246.     jnz     CleanUp ;If so, don't DIM again, no error
  247. @@:
  248. ;ax = oTyp
  249. ;ds:bx = pAD
  250. ;cx = 0 for DIM, 1 for REDIM
  251. ;dh = Feature flags
  252. ;dl = cDims
  253. ;Stack has cbElement followed by bounds
  254. cmp ax,ET_SD
  255. je SetSD
  256.     or     dh,FADF_FAR  ;Assume array is far not huge
  257.     test    dh,FADF_STATIC ;$STATIC array?
  258.     jnz     @F ;They can never be huge
  259.     test    [cmdSwitches],CMD_SW_HAR
  260.     jz     @F ;Brif /AH switch not specified
  261.     or     dh,FADF_HUGE ;Set Huge indicator for runtime
  262. @@:
  263. Flags_Set:
  264. push dx ;flags/cDims
  265. push bx ;pAD
  266. SizeSet:
  267. jcxz Dim_The_Array ;Brif Dim
  268. CALLRT B$RDIM,Mov ;ReDim array via runtime code
  269. jmp short After_Dim
  270. SetSD:
  271.     or     dh,FADF_SD OR FADF_NEAR ;Tell runtime this is a string array
  272.     jmp     short Flags_Set
  273. CleanUp:
  274.     mov     dh,0 ;dx=cDims
  275.     shl     dx,1 ;Two words/dimension
  276.     inc     dx ; Plus one word for cbElement
  277.     shl     dx,1 ;Two bytes/index
  278.     add     sp,dx ;Clear indices off stack
  279.     jmp     short DimX
  280. Dim_The_Array:
  281. CALLRT B$DDIM,Mov ;Dimension array via runtime code
  282. After_Dim:
  283. DimXds:
  284. ;Determine how to return.
  285. mov al,SSDIM_EXECUTE
  286. xchg al,[DimAtScanType] ;Get Dim type and reset
  287. cmp al,SSDIM_EXECUTE ;Is this execute scan time Dim?
  288. jne DimAtScanExit ;Brif not
  289. ;Exit for case that DIM executed as part of normal pcode execution
  290. DimX:
  291. DispMac
  292. ;Exit for a Dim that was executed at scan time for a $Static array
  293. DimAtScanExit:
  294. jmp ScanExExit ; Exit
  295. subttl exStErase
  296. page
  297. ;***
  298. ;exStErase - erase one or more arrays
  299. ;
  300. ;Purpose:
  301. ;
  302. ;   Support for ERASE statement.
  303. ;
  304. ;Input:
  305. ;
  306. ;   es:si = pcode address of argument count
  307. ;   count pAD arguments on the stack
  308. ;
  309. ;Output:
  310. ;
  311. ;   none
  312. ;
  313. ;************************************************************************
  314. MakeExe exStErase,opStErase
  315. LODSWTX  ;Load argument count
  316. mov di,ax ;Arg count to di
  317. EraseNext:
  318. call B$ERAS ;erase this array descriptor
  319. ;Note: this CAN cause heap movement
  320. dec di
  321. jnz EraseNext ;Go erase next array
  322. jmp DispMov
  323. subttl UnlinkArray
  324. page
  325. ;***
  326. ;UnlinkArray
  327. ;
  328. ;Purpose:
  329. ;
  330. ;   This routine unlinks Auto non-string arrays from the owners frame
  331. ;
  332. ;Input:
  333. ;
  334. ;   sbAd:pAd on stack
  335. ;
  336. ;Output:
  337. ;
  338. ;   none
  339. ;
  340. ;Preserves:
  341. ;
  342. ;   DI
  343. ;
  344. ;************************************************************************
  345. ;***
  346. ;exFn<U|L>bound<1|2>
  347. ;
  348. ;Purpose:
  349. ;
  350. ;   Support for LBOUND function
  351. ;
  352. ;Input:
  353. ;
  354. ;   pAD on the stack
  355. ;   iDim on stack   (exFnLbound2 only)
  356. ;
  357. ;Output:
  358. ;
  359. ;   none
  360. ;
  361. ;************************************************************************
  362. ;
  363. MakeExe ExFnLbound1,opFnLbound1
  364. PushI ax,1
  365. SkipExHeader
  366. MakeExe ExFnLbound2,opFnLbound2
  367. CALLRT B$LBND,DispAx
  368. MakeExe ExFnUbound1,opFnUbound1
  369. PushI ax,1
  370. SkipExHeader
  371. MakeExe ExFnUbound2,opFnUbound2
  372. CALLRT B$UBND,DispAx
  373. ;=============================================================================
  374. subttl Utilities
  375. page
  376. ;***
  377. ;OTypCbTyp
  378. ;Purpose:
  379. ; This routine returns the number of bytes of data required for
  380. ; the input type.
  381. ; Significantly rewritten for revision [7].
  382. ;
  383. ;Input:
  384. ; ax = oTyp
  385. ;Output:
  386. ; ax = cbTyp
  387. ;Modifies:
  388. ; none
  389. ;Preserves:
  390. ; all
  391. ;***************************************************************************
  392. mpCbTyp equ $-1
  393. .erre ET_I2 EQ ($-mpCbTyp)
  394. DB 2 ;ET_I2
  395. .erre ET_I4 EQ ($-mpCbTyp)
  396. DB 4 ;ET_I4
  397. .erre ET_R4 EQ ($-mpCbTyp)
  398. DB 4 ;ET_R4
  399. .erre ET_R8 EQ ($-mpCbTyp)
  400. DB 8 ;ET_R8
  401. .erre ET_SD EQ ($-mpCbTyp)
  402.     db     SIZE SD
  403. OTypCbTyp:
  404. push bx
  405. DbChk oTyp,ax  ;sanity check on input oTyp
  406. cmp ax,ET_MAX ;Is it a fundamental type?
  407. ja NotPredefinedType ;  brif not - user defined
  408.     DbAssertRel ax,be,ET_SD,CODE,<OTypCbTyp: Invalid oTyp>
  409. mov bx,offset cs:mpCbTyp ;base of lookup table in CS
  410. xlat byte ptr cs:[bx] ;al == desired size
  411. OTypCbTyp_Exit:
  412. pop bx
  413. ret
  414. NotPredefinedType:
  415. push cx
  416. push dx
  417. push es
  418. cCall CbTypFar,<ax>
  419. pop es
  420. pop dx
  421. pop cx
  422. jmp OTypCbTyp_Exit
  423. sEnd CODE
  424. end