diff --git a/Core/Inc/stm32f4xx_it.h b/Core/Inc/stm32f4xx_it.h index c129be3..a86a0fb 100644 --- a/Core/Inc/stm32f4xx_it.h +++ b/Core/Inc/stm32f4xx_it.h @@ -52,6 +52,7 @@ void MemManage_Handler(void); void BusFault_Handler(void); void UsageFault_Handler(void); void DebugMon_Handler(void); +void USART1_IRQHandler(void); void TIM6_DAC_IRQHandler(void); void DMA2_Stream3_IRQHandler(void); void OTG_FS_IRQHandler(void); diff --git a/Core/Src/main.c b/Core/Src/main.c index 013170c..53b7c76 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -33,6 +33,7 @@ #include "bsp.h" #include "board.h" #include "app.h" + /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ diff --git a/Core/Src/stm32f4xx_it.c b/Core/Src/stm32f4xx_it.c index 4a1f66e..9244184 100644 --- a/Core/Src/stm32f4xx_it.c +++ b/Core/Src/stm32f4xx_it.c @@ -58,6 +58,7 @@ extern PCD_HandleTypeDef hpcd_USB_OTG_FS; extern DMA_HandleTypeDef hdma_sdio_rx; extern DMA_HandleTypeDef hdma_sdio_tx; +extern UART_HandleTypeDef huart1; extern TIM_HandleTypeDef htim6; /* USER CODE BEGIN EV */ @@ -162,6 +163,20 @@ void DebugMon_Handler(void) /* please refer to the startup file (startup_stm32f4xx.s). */ /******************************************************************************/ +/** + * @brief This function handles USART1 global interrupt. + */ +void USART1_IRQHandler(void) +{ + /* USER CODE BEGIN USART1_IRQn 0 */ + + /* USER CODE END USART1_IRQn 0 */ + HAL_UART_IRQHandler(&huart1); + /* USER CODE BEGIN USART1_IRQn 1 */ + + /* USER CODE END USART1_IRQn 1 */ +} + /** * @brief This function handles TIM6 global interrupt, DAC1 and DAC2 underrun error interrupts. */ diff --git a/Core/Src/usart.c b/Core/Src/usart.c index f499c31..0c5b73d 100644 --- a/Core/Src/usart.c +++ b/Core/Src/usart.c @@ -80,6 +80,9 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) GPIO_InitStruct.Alternate = GPIO_AF7_USART1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + /* USART1 interrupt Init */ + HAL_NVIC_SetPriority(USART1_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ @@ -103,6 +106,8 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); + /* USART1 interrupt Deinit */ + HAL_NVIC_DisableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE END USART1_MspDeInit 1 */ @@ -112,7 +117,7 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) /* USER CODE BEGIN 1 */ int fputc(int ch, FILE *f) { - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100); // 发送单字节数据 + HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100); // 发?单字节数据 return (ch); } /* USER CODE END 1 */ diff --git a/MDK-ARM/freertos_f407.uvoptx b/MDK-ARM/freertos_f407.uvoptx index 0e2624d..41e1ef1 100644 --- a/MDK-ARM/freertos_f407.uvoptx +++ b/MDK-ARM/freertos_f407.uvoptx @@ -217,7 +217,7 @@ 1 1 0 - 1 + 0 0 0 1 @@ -867,7 +867,7 @@ User/application - 0 + 1 0 0 0 @@ -1315,7 +1315,7 @@ User/system/lib/lcd - 0 + 1 0 0 0 @@ -1477,6 +1477,74 @@ + + User/system/little_shell + 1 + 0 + 0 + 0 + + 18 + 91 + 1 + 0 + 0 + 0 + ..\User\system\letter_shell\shell.c + shell.c + 0 + 0 + + + 18 + 92 + 1 + 0 + 0 + 0 + ..\User\system\letter_shell\shell_cmd_list.c + shell_cmd_list.c + 0 + 0 + + + 18 + 93 + 1 + 0 + 0 + 0 + ..\User\system\letter_shell\shell_companion.c + shell_companion.c + 0 + 0 + + + 18 + 94 + 1 + 0 + 0 + 0 + ..\User\system\letter_shell\shell_ext.c + shell_ext.c + 0 + 0 + + + 18 + 95 + 1 + 0 + 0 + 0 + ..\User\system\letter_shell\shell_port.c + shell_port.c + 0 + 0 + + + ::CMSIS 0 diff --git a/MDK-ARM/freertos_f407.uvprojx b/MDK-ARM/freertos_f407.uvprojx index 04f7e9e..1b50b6a 100644 --- a/MDK-ARM/freertos_f407.uvprojx +++ b/MDK-ARM/freertos_f407.uvprojx @@ -16,7 +16,7 @@ STM32F407ZGTx STMicroelectronics - Keil.STM32F4xx_DFP.2.8.0 + Keil.STM32F4xx_DFP.2.12.0 http://www.keil.com/pack IRAM(0x20000000-0x2001BFFF) IRAM2(0x2001C000-0x2001FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) FPU2 CPUTYPE("Cortex-M4") TZ @@ -339,7 +339,7 @@ --diag_suppress=68 --diag_suppress=111 --diag_suppress=188 --diag_suppress=223 --diag_suppress=546 --diag_suppress=1295 STM32,USE_HAL_DRIVER,STM32F407xx - ../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../User/application;../User/board;../User/system;../User/system/lib/inc;../User/system/bsp;../FATFS/Target;../FATFS/App;../Middlewares/Third_Party/FatFs/src;../User/system/lib/lcd;../User/system/lib/lcd/gui/Config;../User/system/lib/lcd/gui/Core;../USB_DEVICE/App;../USB_DEVICE/Target;../Middlewares/ST/STM32_USB_Device_Library/Core/Inc;../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc + ../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../User/application;../User/board;../User/system;../User/system/lib/inc;../User/system/bsp;../FATFS/Target;../FATFS/App;../Middlewares/Third_Party/FatFs/src;../User/system/lib/lcd;../User/system/lib/lcd/gui/Config;../User/system/lib/lcd/gui/Core;../USB_DEVICE/App;../USB_DEVICE/Target;../Middlewares/ST/STM32_USB_Device_Library/Core/Inc;../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc;../User/system/letter_shell @@ -3591,6 +3591,36 @@ + + User/system/little_shell + + + shell.c + 1 + ..\User\system\letter_shell\shell.c + + + shell_cmd_list.c + 1 + ..\User\system\letter_shell\shell_cmd_list.c + + + shell_companion.c + 1 + ..\User\system\letter_shell\shell_companion.c + + + shell_ext.c + 1 + ..\User\system\letter_shell\shell_ext.c + + + shell_port.c + 1 + ..\User\system\letter_shell\shell_port.c + + + ::CMSIS @@ -3602,6 +3632,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/MDK-ARM/freertos_f407/freertos_f407.hex b/MDK-ARM/freertos_f407/freertos_f407.hex index a840909..0becd95 100644 --- a/MDK-ARM/freertos_f407/freertos_f407.hex +++ b/MDK-ARM/freertos_f407/freertos_f407.hex @@ -1,8 +1,8 @@ :020000040800F2 -:100000007814012061020008F5410008F13D000864 -:10001000F141000855090008B18300080000000004 +:10000000F017012061020008814700087D430008C5 +:100010007D4700089D090008218C000800000000B1 :10002000000000000000000000000000A101000826 -:100030006B0B000800000000FD010008B955000826 +:10003000B30B000800000000FD010008455B00084C :100040007B0200087B0200087B0200087B0200089C :100050007B0200087B0200087B0200087B0200088C :100060007B0200087B0200087B0200087B0200087C @@ -12,19 +12,19 @@ :1000A0007B0200087B0200087B0200087B0200083C :1000B0007B0200087B0200087B0200087B0200082C :1000C0007B0200087B0200087B0200087B0200081C -:1000D0007B0200087B0200087B0200087B0200080C +:1000D0007B0200082D6200087B0200087B020008FA :1000E0007B0200087B0200087B0200087B020008FC :1000F0007B0200087B0200087B0200087B020008EC :100100007B0200087B0200087B0200087B020008DB -:100110007B0200087B020008B95600087B02000839 -:100120007B0200087B0200087B020008410A0008ED +:100110007B0200087B020008455C00087B020008A7 +:100120007B0200087B0200087B020008890A0008A5 :100130007B0200087B0200087B0200087B020008AB -:100140007B0200087B0200087B020008F9410008DE -:100150007B020008510A00087B0200087B020008AD +:100140007B0200087B0200087B020008854700084C +:100150007B020008990A00087B0200087B02000865 :100160007B0200087B0200087B0200087B0200087B :100170007B0200087B0200087B02000800000000F0 -:100180007B0200087B020008DFF810D000F02CFB97 -:1001900000480047B19C0008AFF3008078140120AC +:100180007B0200087B020008DFF810D000F050FB73 +:100190000048004751A50008AFF30080F017012088 :1001A0002C4B19680868B0E8F04F80F30988BFF35A :1001B0006F8F4FF0000080F311887047000000003F :1001C00008480068006880F308884FF0000080F35A @@ -33,4742 +33,5409 @@ :1001F00070010160704700BF88ED00E0EFF30980F7 :10020000BFF36F8F134B1A681EF0100F08BF20ED5D :10021000108A20E9F04F106009B44FF0500080F3CD -:100220001188BFF34F8FBFF36F8F0AF0A5FF4FF018 +:100220001188BFF34F8FBFF36F8F0DF0BDF84FF004 :10023000000080F3118809BC19680868B0E8F04F25 :100240001EF0100F08BFB0EC108A80F30988BFF3CE :100250006F8F704714000020EFF305807047000097 :100260000648804706480047FEE7FEE7FEE7FEE750 -:10027000FEE7FEE7FEE7FEE7FEE7FEE7A55600081D +:10027000FEE7FEE7FEE7FEE7FEE7FEE7315C00088B :10028000890100082DE9F05F0546002092469B4653 :1002900088460646814640241BE02846414647469C -:1002A000224600F082F953465A46C01A914110D3B3 -:1002B00011461846224600F069F92D1A67EB01082D -:1002C0004F4622460120002100F060F917EB00099B +:1002A000224600F0A6F953465A46C01A914110D38F +:1002B00011461846224600F08DF92D1A67EB010809 +:1002C0004F4622460120002100F084F917EB000977 :1002D0004E41201EA4F10104DFDC484631462A4687 :1002E0004346BDE8F09F40EA01039B0703D009E0C5 :1002F00008C9121F08C0042AFAD203E011F8013B12 :1003000000F8013B521EF9D27047D2B201E000F86A :10031000012B491EFBD270470022F6E710B51346A9 -:100320000A4604461946FFF7F0FF204610BD2DE9A6 -:10033000FE4F804681EA0300C00F0C46009021F07A -:10034000004123F00045B8EB0200A94105D2404628 -:10035000214690461C460B46024623F000401043BF -:1003600047D0270DC7F30A00C3F30A510290401A81 -:10037000019040286BDAC3F3130040F4801B00980F -:10038000924620B10023D2EB030A63EB0B0B0198DA -:100390005946C0F14002504600F0F8F806460D46B6 -:1003A00050465946019A00F010F910EB08006141DF -:1003B000002487EA115284EAE7731A4340D0009A76 -:1003C00062B3019A012A4FEA075215DC001B61EB68 -:1003D00002014FF0004202EA0752CDE90042001C40 -:1003E00041F5801132462B4600F010F903B0BDE80C -:1003F000F08F40462146F9E7001B61EB0201001C2B -:1004000041F5801300185B412018A2F5001747EB57 -:10041000030140EAD570B6196D4111E06D084FEA4D -:10042000360645EAC0754FEA0752001B61EB020130 -:10043000001C41F5801149084FEA30000019514174 -:1004400032462B4603B0BDE8F04F00F0D0B800981C -:10045000012240000023D0EB020263EBE07300981E -:1004600021464FEAE074B8EB000061EB0401E9E7D4 -:1004700083F000435BE781F0004158E72DE9FE4F30 -:1004800081EA030404F0004421F0004100944FF09D -:10049000000B23F0004350EA01045ED052EA03044B -:1004A0005BD0C3F30A54C1F30A552C44A4F2F334CD -:1004B0000194A0FB0254C1F3130141F48011C3F372 -:1004C000130343F4801301FB024400FB034E840A30 -:1004D000970A44EA815447EA8357A4FB07680295C8 -:1004E0008D0A05FB07854FEA932C04FB0C54270566 -:1004F000029D4FEA065847EA1637B5EB08056EEB42 -:10050000070C870E920E47EA811742EA8312A7FB77 -:100510000201B6EB0B0164EB00042B0D43EA0C3334 -:100520005E1844EB1C50DA465146E7FB0201C5F366 -:1005300013044FEA0B3343EA14534FEA0432019C8D -:1005400043EA0603A4F10C040294009CCDE900B434 -:1005500000F05CF803B0BDE8F08F00200146F9E739 -:1005600030B50B46014600202022012409E021FA83 -:1005700002F59D4205D303FA02F5491B04FA02F580 -:100580002844151EA2F10102F1DC30BD202A04DB53 -:10059000203A00FA02F1002070479140C2F1200396 -:1005A00020FA03F3194390407047202A04DB203AD5 -:1005B00021FA02F00021704721FA02F3D040C2F183 -:1005C00020029140084319467047202A06DBCB17CA -:1005D000203A41FA02F043EAE07306E041FA02F3FE -:1005E000D040C2F12002914008431946704710B52F -:1005F000141E73F1000408DA401C41F10001921846 -:100600005B411A4301D120F0010010BD2DE9F04DEE -:1006100092469B4611B1B1FA81F202E0B0FA80F243 -:1006200020329046FFF7B2FF04460F4640EA0A0028 -:1006300041EA0B0153465A46084313D0114653EA88 -:10064000010019D0C8F140025046FFF7AEFF054641 -:100650000E46504659464246FFF798FF084305D0DC -:10066000012004E020463946BDE8F08D0020054316 -:1006700046EAE0762C4337430A986305E40AA0EB88 -:1006800008000022FD0A44EA47540A3002D500203F -:100690000146E9E7010510196941DDE9084500193E -:1006A0006941BDE8F04DA2E72DE9F04D81EA030470 -:1006B00004F0004B21F0004514464FF0000A23F0EF -:1006C000004150EA050220D054EA01021DD0C5F3D2 -:1006D0000A570246C5F31303C1F31300C1F30A56C8 -:1006E00040F4801543F48013A7EB0608101BD64690 -:1006F00008F2FD3873EB050002D308F1010801E0B0 -:1007000092185B41B8F1000F03DA00200146BDE802 -:10071000F08D00204FF48011064684460EE0171B32 -:1007200073EB050705D3121B63EB050306434CEA85 -:10073000010C49084FEA300092185B4150EA01076A -:10074000EDD152EA030012D082EA040083EA0501E7 -:10075000084305D0101BAB4106D20122002306E05E -:1007600000224FF0004302E06FF0010253101AEB39 -:1007700006004CEB085110EB0A0041EB0B01BDE801 -:10078000F04DFFF734BFC1F30A52C1F3130140F239 -:10079000FF3341F480119A4202DA0020014670478B -:1007A00040F233439A42A2F2334202DC5242FFF754 -:1007B000FCBEFFF7EBBE000030B5041E71F1000473 -:1007C00004DB4FF00044404264EB0101141E73F15E -:1007D000000405DB1C464FF00043524263EB040368 -:1007E000994208BF904230BD064C074D06E0E068D4 -:1007F00040F0010394E8070098471034AC42F6D368 -:10080000FFF7C6FCA8280108D828010870B58C1885 -:1008100010F8015B15F0070301D110F8013B2A1114 -:1008200006D110F8012B03E010F8016B01F8016B01 -:100830005B1EF9D12B0705D40023521E0DD401F8FD -:10084000013BFAE710F8013BCB1A921C03E013F8C6 -:10085000015B01F8015B521EF9D5A142D8D30020FB -:1008600070BD000010B50124A102034800F0C0FCD7 -:1008700000B10024204610BD0004024010B504461B -:100880002146024802F062FC10BD0000A8040020CE -:1008900010B5044802F06DFC042801D0012010BD01 -:1008A0000020FCE7A804002010B5002400F014F894 -:1008B000012801D0012010BD064802F06CFC04465E -:1008C00034B94FF40061034802F0F6FA00B1012494 -:1008D0002046F0E7A804002008B501200090FFF7AB -:1008E000C1FF08B9002000909DF8000008BD00007D -:1008F0002DE9F04104460D461646002733462A46A8 -:100900002146044802F07CFD00B101273846BDE8CD -:10091000F0810000A804002010B500220121024847 -:10092000006809F089FB10BDA80000202DE9F04106 -:1009300004460D461646002733462A4621460448FB -:1009400002F00CFE00B101273846BDE8F08100003E -:10095000A804002000BFFEE70346042B15D007DCE7 -:100960007BB1012B0ED0022B0DD0032B12D10BE04B -:10097000202B0BD0212B0AD0222B09D0232B09D1DD -:1009800007E008E007E006E005E004E003E002E03D -:1009900001E000E000BF00BF00207047002070476A -:1009A00010B500220449054805F0ABFA0449034894 -:1009B00005F098FA002010BD4C01012070F40020D1 -:1009C0004CF9002070B504460D46204629680AF00F -:1009D000C9F92146034805F085FA024805F04EFAA8 -:1009E000002070BD70F4002010B503460C460021B5 -:1009F000084610BD2DE9F04104460D4600260A4880 -:100A0000D0F8BC72D7F8140210B10120BDE8F08113 -:100A10002A462146044805F074FA034805F024FBF1 -:100A200006463046F2E7000070F40020024600BFA0 -:100A30001AB901E000BF00BFFCE700BF012070470A -:100A400010B5024800F0E6F810BD00002C050020AB -:100A500010B5024800F0DEF810BD00008C05002043 -:100A60000146087810381823B0FBF3F20848805C80 -:100A7000C865032A05D908686FF30900001D886559 -:100A800003E008686FF309008865886D704700000F -:100A9000CCBF0008014600208A6A8B69CBB932B10D -:100AA000012A0DD0022A03D0032A10D10EE000BF84 -:100AB000CB6A03F08073B3F1807F00D1012007E09F -:100AC000CB6AB3F1C07F00D1012001E000E000BF9C -:100AD00034E08B69B3F5005F1AD132B1012A07D037 -:100AE000022A03D0032A11D10AE000BF01200EE040 -:100AF000CB6A03F08073B3F1807F00D1012006E060 -:100B0000CB6AB3F1C07F00D1012000E000BF15E047 -:100B100032B1012A05D0022A04D0032A0CD103E005 -:100B200000BF00BF012008E0CB6A03F08073B3F17F -:100B3000807F00D1012000E000BF00BF704730B5CA -:100B40000468246824F4802405682C6004686360C9 -:100B50008468402C04D10468A2600468E16003E06A -:100B60000468A1600468E26030BD704772B600BFDF -:100B7000FEE730B504460D4600222946204600F027 -:100B800001F830BDF0B50346012500241148807BF3 -:100B900002281CDA00200F4EB67B0E4FB85538469F -:100BA000867B001D40F82630001F867B0C30825566 -:100BB0003E46B07B461CBE73044604F1300008700C -:100BC0003A2048702F2088700020C87000252846E1 -:100BD000F0BD000060F4002070B50A480468001DF4 -:100BE0000568001D0668344454B1082206492046B1 -:100BF00003F000F9042204491031284603F0FAF802 -:100C000070BD0000107AFF1F660100200146486D8C -:100C100070470000F8B50446002000908C4800683A -:100C20004FF41651B0FBF1F7A56D2E6894F85C10E7 -:100C300008208840304098B12068006800F0040027 -:100C400070B12068006820F004002168086094F802 -:100C50005C1008208840A860606D40F0010060656D -:100C600094F85C1001208840304068B120684069E9 -:100C700000F0800040B194F85C1001208840A8602A -:100C8000606D40F00200606594F85C1004208840BC -:100C9000304068B12068006800F0020040B194F86C -:100CA0005C1004208840A860606D40F0040060651E -:100CB00094F85C1010208840304078B320680068B9 -:100CC00000F0080050B394F85C1010208840A86031 -:100CD0002068006800F4802080B12068006800F47B -:100CE000002028B9206CC8B12046216C884715E047 -:100CF000A06C98B12046A16C88470FE0206800687E -:100D000000F4807028B92068006820F0080021688D -:100D10000860206C10B12046216C884794F85C1064 -:100D2000202088403040002865D02068006800F00E -:100D3000100000285FD094F85C1020208840A86044 -:100D400094F83500052828D12068006820F01600A6 -:100D5000216808602068406920F0800021684861AF -:100D6000206C08B9A06C28B12068006820F0080049 -:100D70002168086094F85C103F208840A86001203A -:100D800084F8350000BF002084F8340000BF206DD7 -:100D900010B12046216D8847F8BD2068006800F436 -:100DA000802080B12068006800F4002028B9606CC1 -:100DB00010B12046616C88471DE0E06BD8B1204639 -:100DC000E16B884717E02068006800F4807068B91C -:100DD0002068006820F0100021680860012084F875 -:100DE000350000BF002084F8340000BFE06B10B174 -:100DF0002046E16B8847606D38B3606D00F00100FC -:100E0000F0B1052084F835002068006820F001006A -:100E10002168086000BF0098401C0090B84200D9CB -:100E200005E02068006800F001000028F3D100BF51 -:100E3000012084F8350000BF002084F8340000BF92 -:100E4000E06C10B12046E16C884700BFA4E70000C9 -:100E5000100000202DE9F0410446002500F0E0F9E3 -:100E6000074614B90120BDE8F081606A00B100BFF7 -:100E7000022084F8350000BF002084F8340000BF51 -:100E80002068006820F00100216808600AE000F096 -:100E9000C7F9C01B052805D920206065032084F808 -:100EA0003500E0E72068006800F001000028EED17E -:100EB0002068056821480540D4E901010843E1683C -:100EC00008432169084361690843A1690843E1694E -:100ED0000843216A08430543606A042803D1D4E922 -:100EE0000B0108430543206805602068456925F02B -:100EF0000705606A0543606A04280DD1A06A0543AE -:100F0000E06A48B12046FFF7C5FD28B14020606582 -:100F1000012084F83500A6E7206845612046FFF7E8 -:100F20009FFD064694F85C103F208840B06000208A -:100F30006065012084F83500002094E73F8010F0C0 -:100F40002DE9F04704460D4616461F464FF00008AF -:100F5000D4F8589000BF94F83400012802D1022040 -:100F6000BDE8F087012084F8340000BF94F8350014 -:100F7000012825D1022084F83500002060653B4619 -:100F8000324629462046FFF7DAFD94F85C103F20F0 -:100F90008840C9F808002068006840F01600216801 -:100FA0000860206C28B12068006840F008002168C3 -:100FB00008602068006840F001002168086006E0D1 -:100FC00000BF002084F8340000BF4FF00208404604 -:100FD000C6E7000070B5044600F022F90646254633 -:100FE000681C10B104480078054400BF00F018F9EF -:100FF000801BA842FAD370BD0C000020F8B5024651 -:101000000B460025002400200021D6E0012606FA28 -:1010100001F51E6806EA0504AC4274D11E7906F09B -:101020000306012E04D01E7906F00306022E13D10A -:1010300090684F000326BE40B0434F00DE68BE40BC -:1010400030439060506801268E40B0431E79C6F34D -:1010500000168E40304350601E7906F00306032EC2 -:1010600009D0D0684F000326BE40B0434F009E68B1 -:10107000BE403043D0601E7906F00306022E13D125 -:10108000CF0802F1200656F827004E07F70E0F266C -:10109000BE40B0434F07FF0E1E69BE403043CF082D -:1010A00002F1200646F8270010684F000326BE40D4 -:1010B000B0431E7906F003064F00BE403043106077 -:1010C0005E6806F44036002E76D000BF00260096FB -:1010D0003C4E366846F480463A4F3E603E4636689F -:1010E00006F48046009600BF00BF374E8F0856F8C2 -:1010F00027008E07370F0F26BE40B043334EB24253 -:1011000002D1002624E057E0314EB24201D101263F -:101110001EE0304EB24201D1022619E02E4EB242FC -:1011200001D1032614E02D4EB24201D104260FE076 -:101130002B4EB24201D105260AE02A4EB24201D11D -:10114000062605E0284EB24201D1072600E0082617 -:101150008F073F0FBE4030431B4E8F0846F82700D5 -:10116000224E3068A0435E6806F4801606B1204324 -:101170001E4E3060361D3068A0435E6806F40016CF -:1011800006B12043194E361D3060184E361F3068A8 -:10119000A0435E6806F4003606B12043134E361FA6 -:1011A0003060361F3068A0435E6806F4803606B1B2 -:1011B00020430E4E083E3060491C1029FFF426AF34 -:1011C000F8BD0000443802400838014000000240E9 -:1011D0000004024000080240000C024000100240DF -:1011E0000014024000180240001C0240083C01406C -:1011F000024613690B400BB1012000E0002070474C -:1012000010B5426921EA020302EA010443EA0443F9 -:10121000836110BD0AB1816101E00B0483617047F5 -:10122000014800687047000004000020034800687F -:101230000349097808440149086070470400002008 -:101240000C00002010B50D48006840F400700B49F8 -:1012500008600846006840F480600860084600683E -:1012600040F480700860032000F0DCF8042000F0F7 -:1012700007F800F05FF8002010BD0000003C0240BD -:101280002DE9F04188B004460027B84600BF002091 -:1012900001902348006840F010002149086008468A -:1012A000006800F01000019000BF00BF02A903A871 -:1012B00001F052F9069F1FB901F076F9054602E0E8 -:1012C00001F072F945001748B5FBF0F0A0F10108F4 -:1012D00015481649086040F2E7311448C160C0F86B -:1012E0000480002101618160816102F0A0FB06465B -:1012F00096B90E4802F0D0FB06466EB9362000F0D3 -:1013000043F8102C07D200222146362000F04CF87A -:101310000748046000E00126304608B0BDE8F081CF -:101320004038024040420F00001000408806002074 -:101330000800002008B500BF002000901148006898 -:1013400040F480400F4908600846006800F480407F -:10135000009000BF00BF00BF00200090081F006881 -:1013600040F08050091F08600846006800F0805077 -:10137000009000BF00BF00220F21901E00F014F863 -:1013800008BD00004438024001460846002809DB39 -:1013900000F01F0301229A4043099B0003F1E02360 -:1013A000C3F8002100BF70472DE9F05F80460D466D -:1013B0001646002707F02CF8074639462A463346DA -:1013C00001F00700C0F1070ABAF1040F02D94FF08B -:1013D000040A01E0C0F1070AD14600F1040ABAF19B -:1013E000070F02D24FF0000A01E0A0F1030AD44631 -:1013F0004FF0010A0AFA09FAAAF1010A0AEA020AF6 -:101400000AFA0CFA4FF0010B0BFA0CFBABF1010BD3 -:101410000BEA030B4AEA0B042146404607F000F8AA -:10142000BDE8F09F00BF00F00702064B19684FF6B9 -:10143000FF031940044B0B4343EA0221014B19609F -:1014400000BF70470CED00E00000FA05704702464F -:101450001068416200207047F0B5034615461868D1 -:10146000446A21B944EA05401E68B06219E0186870 -:10147000806A04EB1044002208E0186800F58270CE -:1014800050F8220004EB1044501CC2B2481E904297 -:10149000F3D844EA0547186800F582704E1E40F8FC -:1014A00026700020F0BD10B50446D4F8080505F0FC -:1014B00046FA10BD70B504460D4605EBC50304F1B0 -:1014C0003C0101EB83010A692946D4F8080505F0BF -:1014D00031F970BD70B504460D4605EBC50304F542 -:1014E0001F7101EB83010A692946D4F8080505F04C -:1014F000A5F970BD10B50446D4F8080505F022FA28 -:1015000010BD2DE9F04104460D4605F0800080280D -:1015100008D105F00F0000EBC00104F13C0000EB26 -:10152000810607E005F00F0000EBC00104F51F7015 -:1015300000EB81063146206806F0F6FC0746384687 -:10154000BDE8F08170B504460E4606F080008028A4 -:101550000AD106F00F0000EBC00104F13C0000EBE3 -:1015600081050120687009E006F00F0000EBC00162 -:1015700004F51F7000EB81050020687006F00F0075 -:10158000287000BF94F8BC04012801D1022070BD6E -:10159000012084F8BC0400BF2946206805F0A4FFA0 -:1015A00000BF002084F8BC0400BF00BFEFE770B5A7 -:1015B00004460E4606F00F006168884201D90120FA -:1015C00070BD06F0800080280AD106F00F0000EB05 -:1015D000C00104F13C0000EB81050120687009E0C6 -:1015E00006F00F0000EBC00104F51F7000EB810551 -:1015F000002068700020A87006F00F00287000BF5F -:1016000094F8BC04012801D10220D9E7012084F814 -:10161000BC0400BF2946206806F04EFA00BF002037 -:1016200084F8BC0400BF00BFCAE7024601F00F0007 -:1016300000EBC00302F51F7000EB8300006A7047E7 -:101640002DE9F04705460E4690461F464FF000092B -:1016500006F0800080280AD106F00F0000EBC001E0 -:1016600005F13C0000EB81040120607009E006F008 -:101670000F0000EBC00105F51F7000EB8104002096 -:10168000607006F00F002070C4F80C80277160783D -:1016900008B120782081022F01D10020607100BFA5 -:1016A00095F8BC04012802D10220BDE8F087012092 -:1016B00085F8BC0400BF2146286805F02BFE00BF5A -:1016C000002085F8BC0400BF4846EEE72DE9F04154 -:1016D00004460E461746984606F00F0000EBC00180 -:1016E00004F51F7000EB81052F61C5F818800020FC -:1016F0002862687006F00F0028702069012800D168 -:101700006F6106F00F0028B9227C2946206806F098 -:10171000ADF804E0227C2946206806F061FA00203A -:10172000BDE8F08170B504460D4605F00F00616814 -:10173000884201D9012070BD05F0800080280AD1BF -:1017400005F00F0000EBC00104F13C0000EB810646 -:101750000120707007E005EBC50104F51F7000EB78 -:101760008106002070700120B07005F00F0030700D -:1017700000BF94F8BC04012801D10220DBE701205E -:1017800084F8BC0400BF3146206806F0DCF905F09F -:101790000F0028B9217C04F2C442206806F054F9F5 -:1017A00000BF002084F8BC0400BF00BFC3E72DE9E0 -:1017B000F04104460E461746984606F00F0000EB2F -:1017C000C00104F13C0000EB81052F61C5F81880D1 -:1017D000002028620120687006F00F002870206940 -:1017E000012800D16F6106F00F0028B9227C29463C -:1017F000206806F03BF804E0227C2946206806F0C9 -:10180000EFF90020BDE8F0812DE9FE4F0446D4F841 -:1018100000B05E46206806F06EFC002874D1206897 -:1018200006F0A8FC08B9BDE8FE8F40F60800805914 -:10183000C0F30D20C4F8FC04206806F09BFC00F007 -:101840000200022805D12068406900F002002168EA -:101850004861206806F08EFC00F01000102845D189 -:101860002068806920F0100021688861DBF82090F2 -:1018700009F00F0000EBC00104F51F7000EB810AB6 -:10188000C9F3434002281AD147F6F07009EA000074 -:1018900030B3C9F30A125846DAF8101006F06FFC9C -:1018A000C9F30A11DAF810000844CAF81000C9F3A5 -:1018B0000A11DAF820000844CAF8200010E0C9F341 -:1018C000434006280CD1082204F2C441584606F0D1 -:1018D00056FCC9F30A11DAF820000844CAF82000BF -:1018E0002068806940F0100021688861206806F057 -:1018F00041FC00F40020B0F5002F7BD100252068CA -:1019000006F008FC029072E0E1E2029800F00100AB -:10191000002868D0E9B2206806F01FFC804608F075 -:10192000010048B1012106F5306000EB45108160EF -:101930002946204602F09AFC08F00800082809D140 -:10194000082106F5306000EB4510816029462046ED -:1019500002F05AFC08F01000102805D1102106F5FD -:10196000306000EB4510816008F00200022824D1AD -:10197000DBF8140000F08000802807D140F6040056 -:10198000805940F4806140F60400815105EBC501A7 -:1019900004F51F7000EB810A9AF80300012806D1B4 -:1019A00000208AF80300E9B2204600F09BFA0221E9 -:1019B00006F5306000EB4510816008F0200020281B -:1019C00005D1202106F5306000EB4510816008F458 -:1019D0000050B0F5005F06D14FF4005106F53060BD -:1019E00000EB451081606D1C02984008029002983F -:1019F00000288AD1206806F0BDFB00F48020B0F5F5 -:101A0000802F7DD1206806F07BFB029000259AE0B4 -:101A1000029800F00100002873D0E9B2206806F0B7 -:101A200083FB804608F00100F0B305F00F010120B0 -:101A30008840019040F634008159019821EA000065 -:101A400040F634018851012106F5106000EB451085 -:101A500081602069012824D105EBC50104F13C0017 -:101A600000EB810005EBC502016904F13C0000EBCD -:101A70008200C068014405EBC50204F13C0000EBA4 -:101A8000820001616DB905EBC50104F13C0000EB7A -:101A90008100806928B904F2C4420121206805F060 -:101AA000D3FFE9B2204600E001E0FFF703FD08F0B4 -:101AB0000800082805D1082106F5106000EB451044 -:101AC000816008F01000102805D1102106F5106083 -:101AD00000EB4510816008F04000402805D140210E -:101AE00006F5106000EB4510816008F00200022846 -:101AF0001DD12946584606F0BFFA05EBC50101E0A5 -:101B000025E01CE004F13C0000EB810A9AF8030098 -:101B1000012806D100208AF80300E9B2204600F02F -:101B2000D8F9022106F5106000EB4510816008F03D -:101B30008000802803D12946204602F039FC6D1C24 -:101B4000029840080290029800287FF461AF206854 -:101B500006F010FB00F00040B0F1004F1CD140F641 -:101B60000400805920F0010140F60400815194F8EE -:101B7000F404012807D1002084F8F4040021204651 -:101B8000FFF764FC02E0204600F0D4FA20684069C8 -:101B900000F0004021684861206806F0EBFA00F48C -:101BA0000060B0F5006F0ED140F60800805900F0DB -:101BB000010010B1204600F015FB2068406900F4D8 -:101BC000006021684861206806F0D4FA00F4805073 -:101BD000B0F5805F7ED140F60400805920F001010D -:101BE00040F6040081511021206806F045FA0027D4 -:101BF00032E04FF67F3106F5106000EB4710816050 -:101C000006F5106000EB4710006820F4001106F59F -:101C1000106000EB471001604FF67F3106F5306031 -:101C200000EB4710816006F5306000EB471000685C -:101C300020F4001106F5306000EB4710016006F556 -:101C4000306000EB4710006840F0006106F530603E -:101C500000EB471001607F1C6068B842C9D840F6AD -:101C60001C00805940F0011140F61C008151206B8E -:101C700070B1D6F8840840F00B01C6F8841840F61D -:101C80004400805940F00B0140F6440081510FE0C0 -:101C900040F61400805942F22B01084340F614012B -:101CA0008851081F805940F00B014FF401608151A9 -:101CB000D6F8000820F4FE60C6F80008217C04F283 -:101CC000C442206805F0C0FE2068406900F48050DE -:101CD000216800E000E04861206806F04BFA00F45B -:101CE0000050B0F5005F17D1206805F07BFB20683D -:101CF00006F0EEF9E06000F051FC0090227B2068D5 -:101D0000009906F0BFFA204600F0FCF9206840690F -:101D100000F4005021684861206806F02BFA00F0BA -:101D20000800082808D1204600F00BFA2068406916 -:101D300000F0080021684861206806F01BFA00F0F6 -:101D40008000802818D1DBF8180020F08000CBF844 -:101D5000180001250DE005EBC50104F51F7000EB2F -:101D60008100C078012803D1E9B22046FFF7C9FB02 -:101D70006D1C6068A842EED8206806F0FBF900F4FC -:101D80008010B0F5801F2DD1012522E006F51060EE -:101D900000EB4510D0F8009005EBC50104F13C00C4 -:101DA00000EB81000079012812D109F00040B0F168 -:101DB000004F0DD1012105EBC50204F13C0000EB01 -:101DC0008200C170E8B240F080012046FFF799FB25 -:101DD0006D1C6068A842D9D82068406900F4801062 -:101DE00021684861206806F0C5F900F40010B0F5DC -:101DF000001F44D1012538E006F5306000EB4510A6 -:101E0000D0F8009005EBC50104F51F7000EB8100D0 -:101E10000079012828D109F00040B0F1004F23D10A -:101E200009F4803094F8FC1401F0010188421BD1C0 -:101E3000012105EBC50204F51F7000EB8200C170A3 -:101E4000DBF8180040F08000CBF81800DBF8140035 -:101E500000F0800040B940F60400805940F4007161 -:101E600040F60400815103E06D1C6068A842C3D8AD -:101E700000BF2068406900F40010216848612068B4 -:101E800006F078F900F08040B0F1804F08D120468C -:101E9000FFF709FB2068406900F080402168486135 -:101EA000206806F067F900F0040004280FD12068CC -:101EB000D0F8049009F00400042802D12046FFF76E -:101EC00019FB2068406840EA09002168486000BFAB -:101ED000A9E470B504460D462946D4F8080504F077 -:101EE0009DFD70BD70B504460D462946D4F8080521 -:101EF00004F0B8FD70BD70B58AB0044614B9012075 -:101F00000AB070BD266894F8BD0428B9002084F892 -:101F1000BC04204600F0A2F8032084F8BD04F06B56 -:101F200000F4807008B900212161206805F096FC5A -:101F3000282204F110016846FEF7D5F994E80F0055 -:101F400005F064FA20B1022084F8BD040120D7E72F -:101F50000021206806F043F9002531E0012105EB5E -:101F6000C50204F13C0000EB8200417005EBC501A5 -:101F700004F13C0000F8215005EBC50100EB8100A5 -:101F80000581002105EBC50204F13C0000EB820055 -:101F9000017105EBC50204F13C0000EB8200C16059 -:101FA00005EBC50204F13C0000EB8200016105EB8A -:101FB000C50204F13C0000EB82008161681CC5B2DF -:101FC0006068A842CAD800252AE0002105EBC502B6 -:101FD00004F51F7000EB8200417005EBC50104F5AC -:101FE0001F7000F82150002105EBC50200EB8200B4 -:101FF000017105EBC50204F51F7000EB8200C160A2 -:1020000005EBC50204F51F7000EB8200016105EBD2 -:10201000C50204F51F7000EB82008161681CC5B227 -:102020006068A842D1D8282204F110016846FEF762 -:102030005AF994E80F0005F021FB20B1022084F842 -:10204000BD0401205CE7002084F83800012084F8FA -:10205000BD04206805F000FB002051E710B586B0F4 -:102060000446142101A8FEF757F92068B0F1A04FEB -:1020700042D100BF002000902048006840F00100DD -:102080001E4908600846006800F00100009000BF8B -:1020900000BF4FF4C0500190022002900020039036 -:1020A000032004900A20059001A91548FEF7A6FF19 -:1020B00000BF1248001D006840F080000F49091D54 -:1020C000086000BF002000900C481430006840F405 -:1020D00080400A49143108600846006800F48040D6 -:1020E000009000BF00BF00BF002205214320FFF782 -:1020F0005BF94320FFF748F906B010BD30380240C5 -:102100000000024070B504460125E06808B90025CA -:1021100006E0E068022801D1012501E0FEF726FD76 -:102120002946D4F8080504F046FDD4F8080504F063 -:10213000EDFC70BD10B50446D4F8080504F01CFD94 -:1021400010BD10B50446D4F8080504F020FD10BDFC -:1021500070B504460D4600BF94F8BC04012801D1B7 -:10216000022070BD012084F8BC0400BF84F8385000 -:102170002946206806F067F800BF002084F8BC04F8 -:1021800000BF00BFEDE710B5044604F2C441D4F827 -:10219000080504F027FD10BD70B50446256800BF92 -:1021A00094F8BC04012801D1022070BD012084F8FC -:1021B000BC0400BFA06A012806D1A069012803D091 -:1021C000A86B40F48030A863206805F023FF2068E6 -:1021D00005F030FA00BF002084F8BC0400BF00BF47 -:1021E000E3E7000010B50446D4F8080504F057FDF5 -:1021F0002068D0F8000E40F001002168C1F8000E00 -:10220000206A28B10348006840F0060001490860D0 -:1022100010BD000010ED00E008B501200349086280 -:1022200003480068009000BF08BD000000000E4297 -:1022300000700040F8B5044600250026207800F024 -:10224000010020B9207800F0040004282FD10020DC -:102250005B498866FEF7E4FF054606E0FEF7E0FF0F -:10226000401B022801D90320F8BD56480068C0F37E -:10227000C0600028F2D160688101207A41EA0070D4 -:1022800050498431086001204D498866FEF7C8FF37 -:10229000054606E0FEF7C4FF401B022801D90320D3 -:1022A000E2E748480068C0F3C0600028F2D0207818 -:1022B00000F0020002287DD100BF002000904148BC -:1022C0004030006840F080503E4940310860084688 -:1022D000006800F08050009000BF00BF3A480068DE -:1022E00040F4807038490860FEF79AFF054606E022 -:1022F000FEF796FF401B022801D90320B4E73248BD -:10230000006800F480700028F2D02E487030006819 -:1023100000F440764EB3A08900F44070B04224D05F -:1023200028487030006820F4407601202749086072 -:1023300000200860234870300660006800F001004B -:1023400098B1FEF76DFF054608E0FEF769FF401BF8 -:1023500041F28831884201D9032085E7194870305D -:102360000068C0F340000028EFD000BFA08900F44F -:102370004070B0F5407F0CD112480830006820F45E -:10238000F810134AE168114008430E49083108600B -:1023900007E00C480830006820F4F81009490831BB -:1023A0000860084870300068A189C1F30B01084338 -:1023B000044900E002E07031086000BF002053E7EC -:1023C000000047420038024000700040400E474283 -:1023D000FFFCFF0F70B504460D460CB9012070BD1F -:1023E0005848006800F00700A84209D255490D700E -:1023F0000846006800F00700A84201D00120EEE77F -:10240000207800F0020002281DD1207800F004009E -:10241000042805D14C48006840F4E0504A4908605F -:10242000207800F00800082805D14748006840F4EB -:102430006040454908604448006820F0F000A16809 -:10244000084341490860207800F00100A8B36068A3 -:10245000012807D13C4808380068C0F34040B8B9AB -:102460000120BCE76068022802D06068032807D119 -:10247000354808380068C0F3406048B90120AEE72D -:10248000314808380068C0F3400008B90120A6E7C9 -:102490002D48006820F00300616808432A4908605D -:1024A000FEF7BEFE064609E0FEF7BAFE801B41F2CB -:1024B0008831884202D9032091E707E0224800686A -:1024C00000F00C006168B0EB810FEDD11D48006891 -:1024D00000F00700A84209D91A490D7008460068A3 -:1024E00000F00700A84201D0012078E7207800F032 -:1024F0000400042807D11448006820F4E050E16883 -:10250000084311490860207800F00800082808D125 -:102510000D48006820F46040216940EAC1000A4982 -:10252000086000F061F808490968C1F30311074A1F -:10253000515CC8400649086006480068FEF7A0FEE6 -:1025400000204CE7003C024008380240D4BF00089D -:1025500010000020080000200F2202600D4A1268BF -:1025600002F0030242600B4A126802F0F00282603D -:10257000084A126802F4E052C260064A126802F485 -:102580006042D2080261044A126802F007020A603F -:102590007047000008380240003C024001480068D3 -:1025A000704700001000002000B5FFF7F7FF044956 -:1025B0000968C1F38221034A515CC84000BD000094 -:1025C00008380240E4BF000800B5FFF7E7FF044900 -:1025D0000968C1F34231034A515CC84000BD0000A4 -:1025E00008380240E4BF00082DE9F0470024002528 -:1025F0000026A1462548006800F00C0020B1042800 -:1026000005D008283AD105E0DFF8849039E0DFF8FA -:10261000849036E01D48001F006800F03F041B480E -:10262000001F006800F4800078B11A481749091F9C -:102630000968C1F38811A0FB0170014622460023FE -:102640003846FDF71FFE05460EE011480F49091FE9 -:102650000968C1F38811A0FB0170014622460023DE -:102660003846FDF70FFE05460848001F0068C0F316 -:102670000140401C4600B5FBF6F902E0DFF810907F -:1026800000BF00BF4846BDE8F087000008380240A0 -:102690000024F40000127A00F8B504460CB90120B9 -:1026A000F8BD207800F00100002874D0F9480068D7 -:1026B00000F00C0004280DD0F648006800F00C0073 -:1026C000082813D1F348001F006800F48000B0F51B -:1026D000800F0BD1EF4808380068C0F34040002855 -:1026E00059D06068002856D10120D9E700BF606842 -:1026F000B0F5803F08D1E7480838006840F48030E2 -:10270000E449083908601EE06068B0F5A02F0DD1DB -:10271000E0480838006840F48020DE490839086045 -:102720000846006840F4803008600CE0D94808385A -:10273000006820F48030D7490839086008460068EE -:1027400020F48020086000BF606890B1FEF768FD4B -:10275000054606E0FEF764FD401B642801D903200E -:102760009EE7CC4808380068C0F340400028F1D00C -:1027700011E0FEF755FD054606E0FEF751FD401B52 -:10278000642801D903208BE7C24808380068C0F3E9 -:1027900040400028F1D1207800F0020002285FD1EB -:1027A000BC48006800F00C0058B1BA48006800F05E -:1027B0000C0008281CD1B748001F006800F48000F6 -:1027C000B0B9B44808380068C0F3400020B1E068F0 -:1027D000012801D0012063E7AE480838006820F0E6 -:1027E000F800216940EAC100AA490839086037E0C9 -:1027F000E06800B30120A8490860FEF711FD054616 -:1028000006E0FEF70DFD401B022801D9032047E733 -:10281000A04808380068C0F340000028F1D09D4867 -:102820000838006820F0F800216940EAC1009949A1 -:102830000839086014E0002097490860FEF7F0FCB2 -:10284000054606E0FEF7ECFC401B022801D90320F8 -:1028500026E7904808380068C0F340000028F1D10E -:10286000207800F0080008282CD16069A8B1012068 -:102870008A490860FEF7D4FC054606E0FEF7D0FC66 -:10288000401B022801D903200AE782486C30006807 -:10289000C0F340000028F1D014E000207F49086018 -:1028A000FEF7BEFC054606E0FEF7BAFC401B022818 -:1028B00001D90320F4E677486C300068C0F340008B -:1028C0000028F1D1207800F00400042870D10027FE -:1028D00070483830006800F0805090B900BF002088 -:1028E00000906C483830006840F0805069493831B9 -:1028F00008600846006800F08050009000BF00BFEC -:1029000001276748006800F48070B0B96448006827 -:1029100040F4807062490860FEF782FC054606E0DC -:10292000FEF77EFC401B022801D90320B8E65C4874 -:10293000006800F480700028F2D000BFA068012871 -:1029400008D154486830006840F0010051496831AE -:1029500008601DE0A06805280DD14E486830006869 -:1029600040F004004B49683108600846006840F0B8 -:10297000010008600CE047486830006820F0010062 -:102980004449683108600846006820F00400086087 -:1029900000BFA068A8B1FEF743FC054609E0FEF7BA -:1029A0003FFC401B41F28831884202D9032077E680 -:1029B00026E0384868300068C0F340000028EED0B8 -:1029C00013E0FEF72DFC054608E0FEF729FC401B4E -:1029D00041F28831884201D9032061E62D486830F0 -:1029E0000068C0F340000028EFD1012F07D129482B -:1029F0003830006820F0805026493831086000BF28 -:102A0000A069002845D02348006800F00C00082881 -:102A10005DD0A069022845D100201F490866FEF755 -:102A2000FFFB054606E0FEF7FBFB401B022801D931 -:102A3000032035E6174808380068C0F340600028D6 -:102A4000F1D1D4E907010843616A40EA811101220A -:102A5000A06AC2EB500041EA00412C20005D41EA2F -:102A600000600C49091F086001200B490866FEF749 -:102A7000D7FB054606E0FEF7D3FB401B022801D931 -:102A800003200DE6034808380068C0F340600028C2 -:102A9000F1D049E00838024000004742800E47422A -:102AA00000700040002021490866FEF7B9FB05468A -:102AB00006E0FEF7B5FB401B022801D90320EFE535 -:102AC0001B480068C0F340600028F2D12CE0A069E8 -:102AD000012800D1E4E51648001D0668A069012818 -:102AE00020D006F48001E06981421BD106F03F014D -:102AF000206A814216D147F6C0703040616AB0EB5F -:102B0000811F0FD106F440310122A06AC2EB5000B0 -:102B1000B1EB004F06D106F070612C20005DB1EBE7 -:102B2000006F01D00120BBE50020B9E5000047425D -:102B30000038024010B50023046804F1500303EB91 -:102B400081031A6010BD000070B505460B4616469D -:102B50000024286840680E4900EA0104200CD8705F -:102B6000C4F30420587004F03F009870C4F342305E -:102B700018705EB9D87801F076FCD870587801F0FA -:102B800072FC5870987801F06EFC9870002070BD4F -:102B90003FFFFF0070B504460B461646002520682F -:102BA000806A586020680069C0F30E009860206851 -:102BB00000680E4900EA0105C5F305401870C5F329 -:102BC0000620587005F07F009870A80DD8705EB987 -:102BD000187801F048FC1870587801F044FC5870DF -:102BE000987801F040FC9870002070BD7F7F7F00D6 -:102BF00070B5044601250CB9012070BD607F20B975 -:102C000000202077204600F045F80220607700BFC2 -:102C1000CA202168486253202168486200BF2046CC -:102C200001F03AFC0546EDB9206880681849084073 -:102C300021688860216960680843616908432168E8 -:102C400089680843216888602168E0680861206815 -:102C50000169208941EA004021680861204601F0AD -:102C600040FC05466DB92068006C20F48020216886 -:102C700008642068006CA169084321680864012089 -:102C8000607700BFFF202168486200BF2846B4E794 -:102C9000BFFF8FFF1FB504460020009001900290F7 -:102CA00003900949206888420CD102200090C0019D -:102CB00003906846FFF7BEFA08B1FDF757FF012001 -:102CC000024908601FBD0000002800403C0E47423A -:102CD0002DE9F04105460C4617464FF0000800BFAD -:102CE000287F012802D10220BDE8F0810120287749 -:102CF00000BF022068774FB9607800F010001028FC -:102D000004D1607800F0EF000A30607087B9E07895 -:102D100001F0B4FB0304607801F0B0FB43EA002348 -:102D2000A07801F0ABFB0343207843EA403809E088 -:102D3000E0780004617840EA0120A1780843217816 -:102D400040EA413800BFCA202968486253202968F8 -:102D5000486200BF284601F09FFB064646B90B4873 -:102D600008EA000029684860284601F0BAFB0646D8 -:102D70000EB90120687700BFFF202968486200BFB4 -:102D800000BF0020287700BF3046ADE73FFFFF00BF -:102D90002DE9F04104460D4617464FF0000800BFEC -:102DA000207F012802D10220BDE8F0810120207798 -:102DB00000BF02206077CFB92068806800F0400033 -:102DC00000B102E00020E87000BF287801F056FB57 -:102DD0000304687801F052FB43EA0023A87801F06D -:102DE0004DFB0343E87843EA805812E0206880688E -:102DF00000F0400000B102E00020E87000BF287839 -:102E00000004697840EA0120A9780843E97840EA9B -:102E1000815800BFCA202168486253202168486257 -:102E200000BF204601F038FB0646B6B9124808EA52 -:102E30000000216808602068806820F480202168F4 -:102E40008860D5E90301084321688968084321683F -:102E50008860204601F045FB06460EB901206077E8 -:102E600000BFFF202168486200BF00BF002020771C -:102E700000BF304698E700007F7F7F0070B50446B2 -:102E800000252068C06820F0A0002168C860FEF717 -:102E9000C7F9054607E0FEF7C3F9401BB0F57A7F96 -:102EA00001D9032070BD2068C06800F02000002810 -:102EB000F1D00020F6E70000F0B589B004460E46D8 -:102EC0000027032084F83400606C032820D0B6F576 -:102ED000805F04D1A06B40F08050A0631CE0B6F589 -:102EE000006F07D1204602F08DF90546A06B2843FC -:102EF000A06311E03EB9204602F050F90546A06BF0 -:102F00002843A06308E0A06B40F00060A06303E0EA -:102F1000A06B40F08050A063A06B38B117482168C7 -:102F20008863012084F83400012713E0606803906F -:102F3000A0680490E0680590069660690790A06913 -:102F4000089006A807C88DE80700206803A90EC9E5 -:102F500001F003FB4FF40071206801F06FFB0546A0 -:102F600035B1064821688863A06B2843A063012718 -:102F7000012084F83400384609B0F0BDFF05400058 -:102F80007047000010B50246506E800F0870506EFA -:102F9000C0F383604870506EC0F301608870506E5B -:102FA000000CC870B2F86400000A087192F864005E -:102FB0004871906E000DC880906EC0F30340087297 -:102FC0006820805AC0F3C03048726820805AC0F32D -:102FD000803088726820805AC0F34030C872682000 -:102FE000805AC0F30030087300204873506C0028EA -:102FF00036D16820805A8005030DD06E43EA907068 -:103000000861D06EC0F3C2600875D06EC0F3026074 -:103010004875D06EC0F342508875D06EC0F38240C0 -:10302000C875D06EC0F3C23008760869401C506580 -:103030000B7E506D03F007039B1C01249C406043F2 -:103040005065087A00F00F03012098409065D2E99E -:1030500015035B0A5843D0654FF40073136621E0F3 -:10306000506C012813D16820805C8006830AD06EE2 -:1030700043EA104008610869401C83025365536DA0 -:10308000D3654FF400739365936D13660AE02E4881 -:1030900013689863906B40F080509063012082F831 -:1030A000340010BD6C20805AC0F3803001F8190F35 -:1030B0006C20805AC0F3C61048706C20805C00F011 -:1030C0007F008870106FC00FC870106FC0F3417020 -:1030D0000871106FC0F382604871106FC0F38350A5 -:1030E0008871106FC0F34050C87100200872106FD3 -:1030F000C0F3004048727020805AC0F3C03088721C -:103100007020805AC0F38030C8727020805AC0F39B -:10311000403008737020805AC0F30030487370202C -:10312000805AC0F3812088737020805AC0F3012038 -:10313000C8737020805CC0F3460008740120487496 -:1031400019390020ADE70000FF0540000246506C31 -:103150000860906C4860D06C8860106DC860506DDD -:103160000861906D4861D06D8861106EC861002063 -:103170007047F8B50446002000906946204601F0EB -:10318000F5FF054615B1A06B2843A0630098C0F376 -:1031900043263046F8BD10B504460CB9012010BDD9 -:1031A00094F8340020B900202077204600F06AF817 -:1031B000032084F83400204600F00CF808B1012008 -:1031C000EDE70020A0632063012084F83400002094 -:1031D000E5E7000070B58AB0044600200490059031 -:1031E0000690079008907620099007A807C88DE8F8 -:1031F0000700206804A90EC901F0AFF9064616B110 -:1032000001200AB070BD00201C490860206801F050 -:10321000BEF901201949A039C1F8A0000220FDF72C -:10322000D9FE204601F03CFF05463DB1012084F85F -:103230003400A06B2843A0630120E2E7204601F0A0 -:10324000ADFE05463DB1012084F83400A06B284353 -:10325000A0630120D5E74FF40071206801F0EEF97A -:1032600005464DB1064821688863A06B2843A063DA -:10327000012084F83400C4E70020C2E7A080254282 -:10328000FF05400010B586B00446142101A8FDF7E3 -:1032900043F85449206888427ED100BF0020009046 -:1032A0005148006840F400604F49086008460068D3 -:1032B00000F40060009000BF00BF00BF002000903D -:1032C00049481438006840F0040047491439086040 -:1032D0000846006800F00400009000BF00BF00BF77 -:1032E000002000900846006840F00800086008468A -:1032F000006800F00800009000BF00BF4FF4F850D5 -:1033000001900220029001200390022004900C20E2 -:10331000059001A93548FDF771FE042001900220B7 -:10332000029001200390022004900C20059001A936 -:103330002F48FDF763FE2F482F4908604FF00060CB -:10334000486000212C488160C1604FF480610161B8 -:1033500089004161890081612021C16100210162F0 -:1033600004214162032181624FF40001C16289108E -:103370000163FDF76FFD08B1FDF7F8FB00BF1E48C4 -:103380002064846300BF1B4848301C4908604FF02C -:1033900000604860402100E021E018488160002181 -:1033A000C1604FF4806101618900416189008161E0 -:1033B0002021C16100210162042141620321816257 -:1033C0004FF40001C16289100163FDF743FD08B1AC -:1033D000FDF7CCFB00BF0948E063846300BF06B083 -:1033E00010BD0000002C014044380240000802409B -:1033F000000C0240586402402C0500208C0500207F -:103400002DE9F04387B004460F4691461D46C84655 -:103410003FB9A06B40F00060A063012007B0BDE899 -:10342000F08394F8340001287ED10020A06308EBDB -:103430000501E06D814205D9A06B40F00070A063EA -:103440000120EBE7032084F8340000202168C862E3 -:103450002068C06B40F22A3108432168C8633848AD -:10346000216CC8633748216CC8640020216C086552 -:103470000021206C8160206C0068006820F0C00092 -:10348000216C89680843216C096808606A02930806 -:10349000226802F180013A46206CFDF751FD80B1AF -:1034A0002068C06B20F495702168C86326482168A5 -:1034B0008863A06B40F08040A063012084F8340052 -:1034C000ACE7012021490860606C012801D04FEA77 -:1034D00048284FF0FF30019068020290902003903E -:1034E00002200490002005900120069001A9206888 -:1034F00001F00EF8012D07D9822020634146206893 -:1035000001F004F9064606E0812020634146206868 -:1035100001F018F9064676B10B4821688863A06B64 -:103520003043A063012000E007E084F8340000206D -:103530002063012072E7002070E702206EE70000A0 -:10354000014E00088D4D0008FF0540008C85254286 -:1035500010B50446FDF7E0F910BD00002DE9F04379 -:1035600087B00446884691461D464F46B8F1000F85 -:1035700007D1A06B40F00060A063012007B0BDE858 -:10358000F08394F83400012874D10020A0637919E5 -:10359000E06D814205D9A06B40F00070A06301206E -:1035A000ECE7032084F8340000202168C86220681A -:1035B000C06B40F21A2108432168C8633848E16BA8 -:1035C000C8633848E16BC8640020E16B0865606C33 -:1035D000012800D07F02012D07D9A02020633946A1 -:1035E000206801F08DF9064606E0902020633946F8 -:1035F000206801F0A1F9064666B12B48216888636E -:10360000A06B3043A063012084F8340000202063C5 -:103610000120B3E70120254908604021E06B81606B -:10362000E06B0068006820F0C000E16B8968084327 -:10363000E16B0968086069028B08216801F180026A -:103640004146E06BFDF77CFCA8B12068C06B40F2FE -:103650001A2188432168C863134821688863A06BD6 -:1036600040F08040A063012084F8340000202063F3 -:10367000012083E711E04FF0FF30019068020290D3 -:10368000902003900020049005900120069001A94D -:10369000206800F03DFF002070E702206EE7000088 -:1036A000494E00088D4D0008FF0540008C852542DD -:1036B00010B504460CB9012010BD606A38B96068C5 -:1036C000B0F5827F00D105E00021E16102E0002138 -:1036D000216161610021A16294F8510028B90020A4 -:1036E00084F85000204600F047F8022084F851008A -:1036F0002068006820F0400021680860A08800F47D -:103700008270218901F404410843A18901F4006118 -:103710000843217C01F002010843217D01F00101F1 -:103720000843218B01F400710843217F01F0380127 -:1037300008432021095D01F080010843218D01F437 -:1037400000510843216808600421A06901EA104083 -:1037500094F8241001F010010843216848602068A3 -:10376000C06920F400602168C86100206065012004 -:1037700084F8510000209FE710B586B0044614215C -:1037800001A8FCF7C9FD1B49206888422FD100BF62 -:10379000002000901848006840F400401649086076 -:1037A0000846006800F40040009000BF00BF00BF62 -:1037B0000020009010481038006840F002000E49C8 -:1037C000103908600846006800F00200009000BF51 -:1037D00000BF3820019002200290002003900320B7 -:1037E00004900620059001A90448FDF707FC06B0E7 -:1037F00010BD0000003C0040403802400004024080 -:103800002DE9FF5F0446884691461D460E9E012025 -:1038100002900020019000BF94F85000012803D1CD -:10382000022004B0BDE8F09F012084F8500000BFE2 -:10383000FDF7F6FC074694F851B060680390AA467D -:10384000BBF1010F0BD00398B0F5827F04D1A068C3 -:1038500010B9BBF1040F02D002200190DBE0B8F1F7 -:10386000000F03D0B9F1000F00D015B9012001906D -:10387000D1E094F85100042802D0052084F85100CA -:1038800000206065C4F83890E587A587C4F83080CB -:10389000E586A586206460642068006800F040002A -:1038A000402805D02068006840F04000216808608A -:1038B000E068B0F5006F4AD1606810B1BAF1010F4D -:1038C00009D1206B00882168C860206B801C2063B0 -:1038D000E08E401EE08633E02068806800F0020041 -:1038E000022810D1E08E70B1029801280BD1206B14 -:1038F00000882168C860206B801C2063E08E401E19 -:10390000E086002002902068806800F0010068B125 -:10391000E08F58B12068C068A16B0880A06B801C44 -:10392000A063E08F401EE08701200290FDF778FC45 -:10393000C01BB04204D3701C10B1032001906AE098 -:10394000E08E0028C8D1E08F0028C5D14AE0606829 -:1039500010B1BAF1010F09D1206B0078216808730A -:10396000206B401C2063E08E401EE08634E020681F -:10397000806800F00200022810D1E08E70B1029839 -:1039800001280BD1206B007821680873206B401C44 -:103990002063E08E401EE086002002902068806850 -:1039A00000F0010068B1E08F58B12068C068A16BD9 -:1039B0000870A06B401CA063E08F401EE0870120D0 -:1039C0000290FDF72DFCC01BB04201D3701C00B962 -:1039D00016B9032001901EE0E08E0028C7D1E08FC9 -:1039E0000028C4D13A463146204601F033FD20B1CB -:1039F00001200190202060650DE0A06850B900BF53 -:103A0000002000902068C0680090206880680090C6 -:103A100000BF00BF00BF012084F8510000BF00209C -:103A200084F8500000BF0198FBE67047704710B55E -:103A300004460CB9012010BD94F83D0028B90020BF -:103A400084F83C00204600F025F8022084F83D0070 -:103A5000211D206801F038FE012084F8460000BFD7 -:103A600084F83E0001213F200155402001554120AE -:103A7000015500BF00BF012084F8420043200155DA -:103A8000442001554520015500BF012084F83D0028 -:103A90000020D0E770470000014691F83D00012862 -:103AA00001D001207047022081F83D000868C068FD -:103AB00040F001000B68D8601A4B086898421BD090 -:103AC0000868B0F1804F17D0174B0868984213D0A0 -:103AD000164B086898420FD0154B086898420BD0D7 -:103AE000144B0868984207D0134B0868984203D0DB -:103AF000124B086898420CD10868806800F00702F1 -:103B0000062A0CD00868006840F001000B681860B5 -:103B100005E00868006840F001000B6818600020AC -:103B2000C0E7000000000140000400400008004021 -:103B3000000C00400004014000400140001800401B -:103B4000704710B5044620680069C0F34000D8B142 -:103B50002068C068C0F34000B0B16FF00200216877 -:103B60000861012020772068806900F0030018B107 -:103B70002046FFF7E5FF05E0204600F0ADF82046BF -:103B800000F0ABF80020207720680069C0F38000C7 -:103B9000D8B12068C068C0F38000B0B16FF00400F5 -:103BA00021680861022020772068806900F4407055 -:103BB00018B12046FFF7C4FF05E0204600F08CF85E -:103BC000204600F08AF80020207720680069C0F3C2 -:103BD000C000D8B12068C068C0F3C000B0B16FF0B9 -:103BE000080021680861042020772068C06900F07F -:103BF000030018B12046FFF7A3FF05E0204600F0C0 -:103C00006BF8204600F069F80020207720680069F2 -:103C1000C0F30010D8B12068C068C0F30010B0B184 -:103C20006FF0100021680861082020772068C069C3 -:103C300000F4407018B12046FFF782FF05E02046EF -:103C400000F04AF8204600F048F80020207720686D -:103C5000006900F0010058B12068C06800F0010060 -:103C600030B16FF0010021680861204600F036F89D -:103C700020680069C0F3C01058B12068C068C0F364 -:103C8000C01030B16FF08000216808612046FFF756 -:103C9000CCFE20680069C0F3801058B12068C0686D -:103CA000C0F3801030B16FF04000216808612046F9 -:103CB00000F020F820680069C0F3401058B1206877 -:103CC000C068C0F3401030B16FF020002168086177 -:103CD0002046FFF7ABFE10BD7047704710B5044695 -:103CE00003492068884201D1FDF7A0FA10BD000009 -:103CF00000100040704710B504460CB9012010BDFB -:103D0000A06900B100E000BF94F83D0028B9002090 -:103D100084F83C00204600F027F8242084F83D0079 -:103D20002068C06820F400502168C860204601F077 -:103D300037FD2068006920F4904021680861206800 -:103D4000406920F02A00216848612068C06840F47A -:103D500000502168C86000202064202084F83D00C5 -:103D600084F83E000020CAE710B586B0044614214E -:103D700001A8FCF7D1FA1B492068884230D100BF66 -:103D8000002000901848006840F0100016490860B4 -:103D90000846006800F01000009000BF00BF00BFA0 -:103DA0000020009010481438006840F001000E49CF -:103DB000143908600846006800F00100009000BF58 -:103DC00000BF4FF4C06001900220029000200390D9 -:103DD000032004900720059001A90448FDF70EF97F -:103DE00006B010BD001001404438024000000240FF -:103DF00000BFFEE730B50B46002100BF16E00A24E5 -:103E0000B4EB107F05D9302404EB107403F8114093 -:103E100005E0412404EB10740A3C03F81140000152 -:103E200000254C00641C1D554C1CE1B29142E6DBA0 -:103E300030BD000008B500BF002000900E480068AB -:103E400040F480000C4908600846006800F48000D7 -:103E5000009000BF00BF00220F213B20FDF7A4FA15 -:103E60003B20FDF791FA00220F214520FDF79CFA37 -:103E70004520FDF789FA08BD3038024010B50349E6 -:103E80000348FCF776FE0349087010BDAD00002022 -:103E900054C00008AC00002000B587B01C220649C1 -:103EA0006846FCF720FA0021684606F0F5F8034959 -:103EB000086007B000BD0000B0BF0008000000208F -:103EC00000B587B0142102A8FCF726FA00BF002035 -:103ED00001907F48006840F010007D490860084666 -:103EE000006800F01000019000BF00BF00BF00207C -:103EF00001900846006840F0040008600846006829 -:103F000000F00400019000BF00BF00BF002001903E -:103F10000846006840F0200008600846006800F08D -:103F20002000019000BF00BF00BF002001900846A4 -:103F3000006840F0800008600846006800F08000DB -:103F4000019000BF00BF00BF00200190084600683C -:103F500040F0010008600846006800F00100019090 -:103F600000BF00BF00BF002001900846006840F07D -:103F7000020008600846006800F00200019000BFDF -:103F800000BF00BF002001900846006840F04000DC -:103F900008600846006800F04000019000BF00BFC4 -:103FA00000BF002001900846006840F0080008604B -:103FB0000846006800F00800019000BF00BF002222 -:103FC0004FF400514348FDF725F900224FF4C0514A -:103FD0004148FDF71FF94FF6FF7002900320039050 -:103FE0000020049002A93D48FDF708F84FF4005066 -:103FF00002900120039000200490059002A935480A -:10400000FCF7FCFF4FF6FF700290032003900020A6 -:10401000049002A93248FCF7F1FFFF200290032030 -:1040200003900020049002A92A48FCF7E7FF48F219 -:10403000FF100290032003900020049002A9294859 -:10404000FCF7DCFF4FF6C7300290032003900020FE -:10405000049002A92448FCF7D1FF4FF6FF700290AC -:10406000032003900020049002A92048FCF7C6FF1B -:104070004FF48060029000200390049002A91A4837 -:10408000FCF7BCFF4CF2FB70029003200390002071 -:10409000049002A91048FCF7B1FF4FF4C050029001 -:1040A0000120039000200490059002A90A48FCF723 -:1040B000A5FF4FF4005002904FF4881003900020A9 -:1040C000049002A90448FCF799FF07B000BD000066 -:1040D0003038024000080240000C0240001002404C -:1040E0000014024000000240000402400018024098 -:1040F00010B50A480A490860002048607F21084836 -:104100008160FF21C1600021016141618161FEF791 -:104110006FFD08B1FCF72AFD10BD0000002800402B -:10412000880400207047000010B50E480E49086052 -:104130004FF48270486000210B488160C1600161CA -:1041400041614FF4007181610021C16101624162EE -:1041500081620A21C162FFF7ABFA08B1FCF706FDE4 -:1041600010BD0000003C0040EC05002010B50B48DD -:104170000B4908604FF4E130486000210848816035 -:10418000C16001610C21416100218161C161FFF7C2 -:10419000B2FD08B1FCF7EAFC10BD000000100140C0 -:1041A0004406002010B500220D490E4802F07FFAA7 -:1041B00008B1FCF7DBFC0C490A4802F0ADFD08B180 -:1041C000FCF7D4FC0949074801F080FE08B1FCF770 -:1041D000CDFC044802F0A2FE08B1FCF7C7FC10BDFC -:1041E0003001002070F40020A40100208001002094 -:1041F00000BFFEE700BFFEE710B50248FDF704FB75 -:1042000010BD00004C0901202DE9F04704460D4681 -:1042100026683746D6F8408007F5306000EB451039 -:10422000D0F80890104880450BD909F40040B0F54B -:10423000004F06D14FF4004107F5306000EB451008 -:1042400081602046FDF79FFF0748804508D9206917 -:10425000012805D104F2C4420121206803F0F4FBD7 -:104260000020BDE8F08700000A30544F2DE9F047E8 -:1042700005460C46D5F800904E46D9F840A006F504 -:10428000306000EB4410D0F808802869012855D12F -:1042900008F0080008280FD1434882450BD908F4DC -:1042A0000040B0F5004F7BD14FF4004106F530607F -:1042B00000EB4410816073E008F02000202806D154 -:1042C000202106F5306000EB4410816068E008F0C2 -:1042D0002800002864D1344882450CD908F40040F5 -:1042E000B0F5004F07D14FF4004106F5306000EB08 -:1042F0004410816054E004EBC40105F51F7000EB2D -:10430000810706F5306000EB4410F9690069C0F3DD -:104310001200081A386264B9B86930B905F2C442AB -:104320000121286803F090FB03E0396A38690844EA -:104330003861E1B22846FDF7CDF831E01B488245EF -:104340001BD108F40040B0F5004F07D14FF40041F5 -:1043500006F5306000EB4410816021E008F0200099 -:10436000202805D1202106F5306000EB4410816043 -:10437000E1B22846FDF7AEF812E06CB904EBC401D7 -:1043800005F51F7000EB8100806928B905F2C44271 -:104390000021286803F058FBE1B22846FDF79AF89F -:1043A0000020BDE8F08700000A30544F0A31544F16 -:1043B0002DE9F84F07460E46D7F80090C84606EBA1 -:1043C000C60107F13C0000EB8104A169206A884224 -:1043D00002D90120BDE8F88F216AA069451AE0687A -:1043E000A84200D2E568E81C4FEA900A17E0216A6B -:1043F000A069451AE068A84200D2E568E81C4FEAC7 -:10440000900A387CABB2F2B200904846216903F0C2 -:10441000ADFF206928442061206A2844206208F505 -:10442000106000EB4610806980B2504506D3A16948 -:10443000206A884202D2A0690028D8D1216AA069E6 -:1044400088420ED806F00F01012000FA01FB40F669 -:10445000340050F8080020EA0B0040F6340141F81F -:1044600008000020B6E7014600BF080900EB800005 -:10447000420001F00F001044C0B270470146002214 -:1044800004E0501CC2B2A1F10A00C1B20A29F8D25C -:10449000100741EA1060704770B5044600260025F9 -:1044A0002068C06800F04000C8B92068C06840F0CB -:1044B00080002168C860FCF7B3FE064608E0FCF700 -:1044C000AFFE801BB0F57A7F02D90420607701250A -:1044D0002068C06800F0400008B9012DEFD12846DF -:1044E00070BD70B5044600252068C06820F08000CB -:1044F0002168C8602068806800F0200030B920463C -:10450000FEF7BCFC10B1042060770125284670BD81 -:1045100010B5024600230868506248689062D1E9ED -:10452000020420430C6920434C6920430343D06AB2 -:1045300020F0F7001843D062002010BD0146086942 -:10454000C0B270470146086800F003007047024699 -:1045500002F114004318186870470FB410B50446F0 -:104560000021DDE903021043059A1043069A104327 -:10457000079A1043089A10430143606847F6FF62A8 -:10458000904308436060002010BC5DF814FB0146B6 -:1045900003200860002070470146D1F88000704772 -:1045A00010B50246002308689060D1E90104204359 -:1045B000CC6820430C6920430343D0686FF30B00A1 -:1045C0001843D060002010BD70B585B005460C467C -:1045D00000943720019040200290002003904FF477 -:1045E0008060049069462846FFF7DAFF41F288327E -:1045F0003721284600F0DCF90646304605B070BD8C -:1046000070B585B005460C460B4820430090292024 -:10461000019040200290002003904FF480600490AD -:1046200069462846FFF7BCFF284600F0C9FA06464F -:10463000304605B070BD00000000108070B585B038 -:1046400005460C4600941020019040200290002066 -:1046500003904FF48060049069462846FFF7A0FF5E -:1046600041F288321021284600F0A2F90646304671 -:1046700005B070BD70B585B005460C4600940620A7 -:10468000019040200290002003904FF4806004903D -:1046900069462846FFF784FF41F288320621284602 -:1046A00000F086F90646304605B070BD30B585B0DD -:1046B0000446002000900190029003904FF4806027 -:1046C000049069462046FFF76BFF204600F050F942 -:1046D0000546284605B030BD30B585B004464FF4D8 -:1046E000D570009008200190402002900020039097 -:1046F0004FF48060049069462046FFF751FF204642 -:1047000000F0E6FA0546284605B030BD70B585B024 -:1047100005460C4600941220019040200290002093 -:1047200003904FF48060049069462846FFF738FFF5 -:1047300041F288321221284600F03AF90646304606 -:1047400005B070BD70B585B005460C4600941120CB -:10475000019040200290002003904FF4806004906C -:1047600069462846FFF71CFF41F28832112128468E -:1047700000F01EF90646304605B070BDF0B585B0B4 -:10478000064614461D4600940720019040200290E2 -:10479000002003904FF48060049069463046FFF794 -:1047A000FFFE41F288320721304600F001F907464A -:1047B000384605B0F0BD30B585B004460020009005 -:1047C00002200190C0200290002003904FF48060EE -:1047D000049069462046FFF7E3FE204600F0BEF94C -:1047E0000546284605B030BD70B585B005460C4677 -:1047F000009409200190C0200290002003904FF403 -:104800008060049069462846FFF7CAFE284600F0FB -:10481000A5F90646304605B070BD30B585B00446F2 -:10482000002000903320019040200290002003904F -:104830004FF48060049069462046FFF7B1FE41F2D4 -:1048400088323321204600F0B3F80546284605B0EB -:1048500030BD70B585B005460C4600940D20019022 -:1048600040200290002003904FF48060049069463D -:104870002846FFF795FE41F288320D21284600F0C8 -:1048800097F80646304605B070BD70B585B0054650 -:104890000C46002000900320019040200290002050 -:1048A00003904FF48060049069462846FFF778FE35 -:1048B00022460321284600F0AFF90646304605B0EF -:1048C00070BD000030B585B00446002000900C207B -:1048D000019040200290002003904FF480600490EB -:1048E00069462046FFF75CFE044A0C21204600F092 -:1048F0005FF80546284605B030BD000000E1F5052B -:1049000070B585B005460C460094192001904020F2 -:104910000290002003904FF480600490694628467E -:10492000FFF73EFE41F288321921284600F040F898 -:104930000646304605B070BD70B585B005460C46DC -:1049400000941820019040200290002003904FF422 -:104950008060049069462846FFF722FE41F28832C3 -:104960001821284600F024F80646304605B070BDF0 -:1049700001460E480068C0084FF47A73B0FBF3F0AC -:1049800041F2883300FB03F200BF101EA2F10102C6 -:1049900002D14FF000407047486B00F080000028C3 -:1049A000F3D0C52088630020F5E700001000002048 -:1049B0002DE9F04305460F46904666480068C0085A -:1049C0004FF47A71B0FBF1F000FB08F900BFB9F1C8 -:1049D0000000A9F1010903D14FF00040BDE8F083C8 -:1049E0006E6B06F045000028F1D006F40060002848 -:1049F000EDD1686B00F0040010B10420A863EDE76E -:104A0000686B00F0010010B10120A863E6E7C52043 -:104A1000A8632846FFF792FDB84201D00120DDE7E8 -:104A200000212846FFF793FD04464B48204008B973 -:104A30000020D3E704F00040B0F1004F02D14FF066 -:104A40000070CBE704F08040B0F1804F01D14020EE -:104A5000C4E704F00050B0F1005F01D18020BDE751 -:104A600004F08050B0F1805F02D14FF48070B5E760 -:104A700004F00060B0F1006F02D14FF40070ADE7B8 -:104A800004F08060B0F1806F02D14FF48060A5E740 -:104A900004F08070B0F1807F02D14FF400609DE798 -:104AA00004F40000B0F5000F02D14FF4805095E7F8 -:104AB00004F48000B0F5800F02D14FF400508DE770 -:104AC00004F40010B0F5001F02D14FF4804085E7D8 -:104AD00004F48010B0F5801F02D14FF400407DE750 -:104AE00004F48020B0F5802F02D14FF4003075E738 -:104AF00004F40030B0F5003F02D14FF480206DE7A0 -:104B000004F48030B0F5803F02D14FF4002065E717 -:104B100004F40040B0F5004F02D14FF480105DE77F -:104B200004F48040B0F5804F02D14FF4001055E7F7 -:104B300004F40050B0F5005F02D14FF480004DE75F -:104B400004F00800082801D1000547E74FF4803041 -:104B500044E700001000002008E0FFFD10B501460A -:104B600016480068C0084FF47A74B0FBF4F041F2C4 -:104B7000883400FB04F300BF181EA3F1010302D127 -:104B80004FF0004010BD4A6B02F045000028F3D002 -:104B900002F400600028EFD1486B00F0040010B16F -:104BA00004208863EEE7486B00F0010010B101209B -:104BB0008863E7E7C52088630020E3E71000002052 -:104BC00010B5014613480068C0084FF47A74B0FB72 -:104BD000F4F041F2883400FB04F300BF181EA3F187 -:104BE000010302D14FF0004010BD4A6B02F04500B6 -:104BF0000028F3D002F400600028EFD1486B00F0E9 -:104C0000040010B104208863EEE7C520886300200B -:104C1000EAE70000100000202DE9F04304460F46AB -:104C200090462A480068C0084FF47A71B0FBF1F052 -:104C300041F2883100FB01F900BFB9F10000A9F190 -:104C4000010903D14FF00040BDE8F083666B06F028 -:104C500045000028F1D006F400600028EDD1606B1B -:104C600000F0040010B10420A063EDE7606B00F0D9 -:104C7000010010B10120A063E6E72046FFF75EFCCB -:104C8000B84201D00120DFE7C520A0630021204603 -:104C9000FFF75DFC054605F4604020B9280CA8F834 -:104CA00000000020D0E705F48040B0F5804F02D12D -:104CB0004FF40050C8E705F40040B0F5004F02D1B2 -:104CC0004FF48050C0E74FF48030BDE71000002063 -:104CD00010B5014618480068C0084FF47A74B0FB5C -:104CE000F4F041F2883400FB04F300BF181EA3F176 -:104CF000010302D14FF0004010BD4A6B02F04500A5 -:104D00000028F3D002F400600028EFD1486B00F0D7 -:104D1000040010B104208863EEE7486B00F0010046 -:104D200010B101208863E7E7486B00F0400008B14C -:104D3000402088630020DFE71000002010B5044603 -:104D4000012007490870FBF7A3FD28B90448007843 -:104D500020F00100024908700148007810BD0000F1 -:104D6000A400002070B5044605F0FAF8054604E0FA -:104D7000FBF78EFD08B9002070BD05F0F1F8401B6F -:104D8000A042F5D34FF0FF30F6E700002DE9F041E7 -:104D90000646B46B3046FBF739FF02282CD0206C56 -:104DA000476DE06BD0F85480012F02D0B8F1010FAD -:104DB0001FD11248216888632068C06B20F49D7061 -:104DC0002168C863A06B40F08040A0632046FEF7D6 -:104DD000D0F90546062D01D0052D05D12068FFF735 -:104DE00071FDA16B0843A063012084F8340000200A -:104DF00020632046FEF7C4F8BDE8F081FF054000BF -:104E000070B50646B46B206B82280AD12068FFF784 -:104E100059FD05462DB1A06B2843A0632046FEF73F -:104E2000AFF82068C06A20F008002168C86240F22C -:104E30003A5021688863012084F834000020206300 -:104E40002046FEF785FB70BD0146886B0268D26B79 -:104E500042F480720368DA6370472DE9F04389B049 -:104E600004460F46FCF7DCF981464FF000080020AD -:104E7000019002903E4608212068FFF7DFFB0546BF -:104E80001DB1284609B0BDE8F0835022125B110421 -:104E90002068FFF799FB05460DB12846F2E74FF071 -:104EA000FF300390082004903020059002200690E7 -:104EB000002007900120089003A92068FFF728FB35 -:104EC0002068FFF7AAFC05460DB12846DAE71CE08A -:104ED0002068406B00F4001040B12068FFF75CFBD5 -:104EE00001A941F8280008F1010805E02068406B9D -:104EF00000F4005000B90EE0FCF792F9A0EB0900B5 -:104F0000401C10B94FF00040BCE72068406B00F037 -:104F10002A000028DCD000BF2068406B00F00800A9 -:104F200018B1082021688863ACE72068406B00F066 -:104F3000020018B1022021688863A3E72068406B53 -:104F400000F0200018B12020216888639AE740F221 -:104F50003A502168886302980006029901F47F4163 -:104F600040EA0120029901F47F0140EA11200299F0 -:104F700040EA11603060361D01980006019901F485 -:104F80007F4140EA0120019901F47F0140EA1120AC -:104F9000019940EA11603060002073E730B58FB0AE -:104FA0000446012003902068FFF7CCFA18B94FF0AF -:104FB00080600FB030BD606C03281BD02068FFF705 -:104FC000FAFB05460DB12846F3E700212068FFF7FC -:104FD000BEFA606704212068FFF7B9FAA0670821CC -:104FE0002068FFF7B4FAE0670C212068FFF7AFFAFA -:104FF00080210851606C032807D003A92068FFF7BF -:1050000044FC05460DB12846D3E7606C032820D048 -:10501000BDF80C1021655022125B11042068FFF7C7 -:10502000E3FB05460DB12846C3E700212068FFF7E2 -:105030008EFA606604212068FFF789FAA0660821CD -:105040002068FFF784FAE0660C212068FFF77FFAFA -:10505000206704212068FFF77AFA010DE16404A9B2 -:105060002046FDF78FFF10B14FF08050A1E7502090 -:10507000005B01040A4600232068FFF77FFB05461A -:105080000DB1284695E7D4E90412A069CDE90012D4 -:10509000029094E80F00FFF760FA002089E7000013 -:1050A000F8B5044600200090002600272068FFF78E -:1050B000FDFA05460DB12846F8BD2068FFF70CFB48 -:1050C000054645B10021A1642068FFF7EFFA0546C7 -:1050D0001DB12846F0E70121A164A06C012808D188 -:1050E00000212068FFF770FA054615B14FF0805097 -:1050F000E2E71DE000212068FFF766FA05460DB1E2 -:105100002846D9E718492068FFF77AFA054615B10D -:105110004FF08050D0E700212068FFF718FA0646CC -:10512000012080EAD67080F001070098401C0090B2 -:105130004FF6FF710098884201D2002FDAD04FF667 -:10514000FF710098884202D34FF08070B4E706F0F8 -:105150008040B0F1804F02D10120606401E0002066 -:1051600060640020A8E70000000010C170B504468C -:105170000D4615B94FF0006070BD5022125B11044E -:105180002068FFF766FB06460EB13046F4E70021C3 -:105190002068FFF7DCF928600020EDE77CB50446C5 -:1051A00000200090019000212068FFF7D0F900F066 -:1051B0000070B0F1007F02D14FF400607CBD694601 -:1051C0002046FFF74AFE05460DB12846F6E701984E -:1051D00000F4803098B15022125B11042068FFF770 -:1051E000F3F905460DB12846E8E700212068FFF7EE -:1051F00041FA05460DB12846E0E70020DEE74FF012 -:105200008060DBE77CB5044600200090019000211F -:105210002068FFF79CF900F00070B0F1007F02D128 -:105220004FF400607CBD69462046FFF716FE054638 -:105230000DB12846F6E7019800F4802098B150227D -:10524000125B11042068FFF7BFF905460DB128462F -:10525000E8E702212068FFF70DFA05460DB1284660 -:10526000E0E70020DEE74FF08060DBE71FB5044693 -:1052700001201649087004F065FE10B3FBF714FB1B -:1052800020B92046FFF75AFD104908700F480078F2 -:10529000012816D00E48006850B90E4B0FCB8DE890 -:1052A0000F000021684604F065FE0949086000BF50 -:1052B0000748006828B90548007840F00100034914 -:1052C00008700248007804B010BD0000A40000205F -:1052D000A800002068C00008F0B589B007460D4658 -:1052E000144601261648007800F0010010B1032092 -:1052F00009B0F0BD35B1012D06D0022D0BD0032D24 -:1053000018D10FE0002617E001A8FBF7B7FA0798BD -:105310002060002610E001A8FBF7B0FA0898208072 -:10532000002609E001A8FBF7A9FA0898400A2060C6 -:10533000002601E0042600BF00BF3046D8E7000089 -:10534000A40000202DE9F04786B082460E4617469D -:1053500098464FF0010947F23050FFF703FD00284F -:1053600003DA484606B0BDE8F08742463946304683 -:10537000FBF7BEFA044614BB47F2305211480168ED -:10538000684604F00BFE9DE8070003AB07C30398D3 -:10539000102814D10498012811D104F0E1FD05462C -:1053A00005E0FBF775FA10B94FF0000906E004F0CC -:1053B000D7FD401B47F230518842F2D300BF484628 -:1053C000D0E70000A800002010B504462046FFF7F3 -:1053D000B5FC10BD2DE9F04387B081460D46164659 -:1053E0001F464FF0010847F23050FFF7BBFC002882 -:1053F00003DA404607B0BDE8F0833A463146284616 -:10540000FBF794FA10BB47F230521148016801A82B -:1054100004F0C4FD01A807C804AB07C30498102812 -:1054200014D10598022811D104F09AFD044605E034 -:10543000FBF72EFA10B94FF0000806E004F090FDDB -:10544000001B47F230518842F2D300BF4046D1E7FB -:10545000A80000207CB504460D4616461648006894 -:105460001821B0FBF1F01549B0FBF1F04FF47A715F -:10547000484301906068B0F5827F0DD12B46002231 -:1054800080212046009600F01BF898B1606D40F036 -:105490002000606503207CBD00BF019800B908E0D2 -:1054A0000198401E019020688068C0F3C010002859 -:1054B000F3D100BF0020EEE71000002040420F00B3 -:1054C0002DE9F84F04460D4690461E46DDF828901B -:1054D000FBF7A6FEA0EB0900371AFBF7A1FE8246F8 -:1054E0002C480068C0F3CB307843009045E0701C36 -:1054F000002842D0FBF794FEA0EB0A00B84200D28D -:10550000A7BB2068406820F0E00021684860606820 -:10551000B0F5827F0DD1A068B0F5004F03D0A06830 -:10552000B0F5806F05D12068006820F04000216848 -:105530000860A06AB0F5005F0DD100BF2068006868 -:1055400020F40050216808602068006840F4005092 -:105550002168086000BF012084F8510000BF0020CE -:1055600084F8500000BF0320BDE8F88FFFE70098E3 -:1055700000B900270098401E0090206880682840ED -:10558000A84201D1012000E000204045AFD1002019 -:10559000EAE700001000002030B501460A46137803 -:1055A000521C147843EA042030BDFEF7FBFD00BF17 -:1055B000012004F0BBFCFBE710B500BF502080F3D6 -:1055C0001188BFF34F8FBFF36F8F00BF06F01AFB38 -:1055D00018B14FF080500449086000BF002080F3EC -:1055E000118800BF10BD000004ED00E000B593B0CD -:1055F000302107A8FAF790FE142102A8FAF78CFED2 -:1056000000BF002001902548006840F080502349E9 -:1056100008600846006800F08050019000BF00BF9D -:1056200000BF002001901E48006840F480401C49E3 -:1056300008600846006800F48040019000BF00BF89 -:10564000052007904FF48030089001200990022037 -:105650000D9041050E9104210F91A8211091022176 -:1056600011910721129107A8FDF716F808B1FBF771 -:105670007DFA0F20029002200390002004904FF446 -:10568000A05005904FF480500690052102A8FCF729 -:10569000A1FE08B1FBF76AFA13B000BD4038024022 -:1056A000007000400348006840F470000149086041 -:1056B0007047000088ED00E010B50248FEF741FA9F -:1056C00010BD00008806002010B50268294B9842E2 -:1056D0000ED0B0F1804F0BD0274B984208D0274B0B -:1056E000984205D0264B984202D0264B984203D1CF -:1056F00022F070024B681A431E4B984220D0B0F142 -:10570000804F1DD01C4B98421AD01C4B984217D08A -:105710001B4B984214D01B4B984211D01A4B984205 -:105720000ED01A4B98420BD0194B984208D0194B07 -:10573000984205D0184B984202D0184B984203D19A -:1057400022F44072CB681A4322F080034C6943EA8A -:10575000040202608B68C3620B688362054B984247 -:1057600002D0084B984201D10B69036301234361C6 -:1057700010BD00000000014000040040000800408F -:10578000000C004000040140004001400044014082 -:105790000048014000180040001C0040002000406C -:1057A0002DE9F84F04462068006920F44050E16874 -:1057B0000843216808612169A068084361690843BA -:1057C000E169084300902068C06849F20C61884391 -:1057D000009908432168C8602068406920F440703F -:1057E000A16908432168486176492068884203D04E -:1057F00075492068884203D1FCF7E6FE814602E045 -:10580000FCF7D2FE8146E069B0F5004F6CD1022072 -:105810006168A0FB015003461920A9FB00700146F6 -:105820002A463846FAF72EFD6421B0FBF1F04FEA24 -:10583000001A02206168A0FB01510B461920A9FB48 -:1058400000712A463846FAF71DFD8346022061683A -:10585000A0FB015003461920A9FB00712A463846D7 -:10586000FAF710FD6421B0FBF1F000EBC00101EB91 -:105870000010ABEB8000322101EBC0006421B0FBD3 -:10588000F1F000F0F8000AEB400A02206168A0FB8A -:10589000015003461920A9FB007001462A463846EC -:1058A000FAF7F0FC834602206168A0FB0150034632 -:1058B0001920A9FB00712A463846FAF7E3FC642157 -:1058C000B0FBF1F000EBC00101EB0010ABEB80008E -:1058D000322101EBC0006421B0FBF1F000F00700C1 -:1058E0005044216888606AE004206168A0FB015090 -:1058F00003461920A9FB007001462A463846FAF7EC -:10590000C1FC824604206168A0FB015003461920B7 -:10591000A9FB007001462A463846FAF7B3FC642119 -:10592000B0FBF1F000EBC00101EB0010AAEB80002E -:10593000322101EB00106421B0FBF1F000F0F00A1D -:1059400004206168A0FB017003461920A9FB0051E7 -:105950003A462846FAF796FC6421B0FBF1F00AEBD0 -:10596000001A04206168A0FB01510B461920A9FB15 -:1059700000712A463846FAF785FC834604206168A0 -:10598000A0FB015003461920A9FB007001462A46DE -:105990003846FAF777FC6421B0FBF1F000EBC00168 -:1059A00001EB0010ABEB8000322101EB0010642111 -:1059B000B0FBF1F000F00F00504421688860BDE8B2 -:1059C000F88F000000100140001401402DE9F04163 -:1059D00004460D46D4F8C87204F53070D4F8D412D9 -:1059E00050F8210010B90320BDE8F08104F53070B3 -:1059F000D4F8D41250F8216005F00F0000EB8001BC -:105A000004F1140000EB8100406838B305F00F008A -:105A100000EB800104F1140000EB8100416805F007 -:105A20000F0000EBC00207F13C0000EB8200C068F1 -:105A3000B1FBF0F200FB121080B9002105F00F005D -:105A400000EB800204F1140000EB820041600023AF -:105A50001A462946204601F02CF917E00020C6F826 -:105A6000140204F53170D4F8D41250F82100006902 -:105A700060B1D6F8080204F53171D4F8D42251F897 -:105A800022102A460B6906F5047198470020ABE7FF -:105A900070B504460E4604F53070D4F8D41250F8B0 -:105AA0002150D4F8D41250F8210008B9032070BD59 -:105AB0003146204600F059FFC5F80C02D5F8040223 -:105AC00004F53171D4F8D43251F82310CA6805F5C1 -:105AD000037190470020EAE770B504460D46304850 -:105AE0000178204600F013FE00212D48007800F0D8 -:105AF0000F0000EB800204F1140000EB8200018231 -:105B000028480178204600F002FE00212548007850 -:105B100000F00F0000EB800204F5AA7000EB820099 -:105B2000018221480178204600F0F1FD00211E4845 -:105B3000007800F00F0000EB800204F1140000EB8D -:105B4000820001821848007800F00F0000EB80020C -:105B500004F1140000EB8200418204F53070D4F8A7 -:105B6000D41250F82100C8B104F53171D4F8D42210 -:105B700051F822104868804704F53071D4F8D422D7 -:105B800051F8220001F0BEFB002104F53070D4F87A -:105B9000D42240F822100020C4F8BC02002070BDBE -:105BA0001F020020200200202102002070B50446C0 -:105BB00004F53070D4F8D41250F821500DB90320F8 -:105BC00070BD04F53170D4F8D41250F8210098B1AA -:105BD00095F80002FF280FD095F8012295F80002F1 -:105BE00004F53171D4F8D46251F826108B68294637 -:105BF0009847FF2085F800020020E1E701460A20CF -:105C00000880014870470000980100202DE9F0410C -:105C1000044682210D4800F0A0FC054601210B48F6 -:105C200000F09BFC06468121084800F096FC0746E0 -:105C30000DB11020A8710EB14020B0800FB14020EE -:105C4000B880432020800148BDE8F081DC010020BD -:105C50002DE9F041044682210E4800F07EFC054605 -:105C600001210C4800F079FC06468121094800F02A -:105C700074FC07460DB11020A87116B14FF40070E6 -:105C8000B08017B14FF40070B880432020800148E5 -:105C9000BDE8F081DC0100202DE9F04104468221BD -:105CA0000D4800F05AFC054601210B4800F055FC58 -:105CB00006468121084800F050FC07460DB110202F -:105CC000A8710EB14020B0800FB14020B8804320B1 -:105CD00020800148BDE8F081DC01002070B5044659 -:105CE0000E464FF4077001F00FFB054645B9002141 -:105CF00004F53070D4F8D42240F82210022070BD90 -:105D00004FF407712846FAF707FB04F53070D4F812 -:105D1000D41240F82150D4F8D41250F82100C4F81D -:105D2000BC02207C98BB4FF40073022250480178DB -:105D3000204600F0BBFE01214D48007800F00F0026 -:105D400000EB800204F1140000EB820001824B02A0 -:105D5000022248480178204600F0A8FE012145486B -:105D6000007800F00F0000EB800204F5AA7000EB51 -:105D70008200018210214048007800F00F0000EB03 -:105D8000800204F1140000EB8200418232E0FFE760 -:105D90004023022236480178204600F087FE012188 -:105DA0003348007800F00F0000EB800204F114008B -:105DB00000EB82000182402302222E480178204617 -:105DC00000F074FE01212B48007800F00F0000EB7A -:105DD000800204F5AA7000EB82000182102126489F -:105DE000007800F00F0000EB800204F1140000EBDB -:105DF00082004182082303221F480178204600F0D8 -:105E000055FE01211C48007800F00F0000EB8002D5 -:105E100004F1140000EB820001820020C5F80402A6 -:105E200004F53171D4F8D42251F822100868804763 -:105E30000020C5F81402C5F81802D5F8040208B904 -:105E400002205CE7207C48B94FF4007309480178D0 -:105E50002046D5F8042200F041FE07E04023054823 -:105E600001782046D5F8042200F038FE002046E7ED -:105E70001F020020200200202102002070B50446ED -:105E800004F53070D4F8D41250F82150D4F8D4125C -:105E900050F8210008B9032070BD207C48B94FF4A8 -:105EA0000073094801782046D5F8042200F016FE58 -:105EB00007E04023044801782046D5F8042200F08A -:105EC0000DFE0020E8E7000020020020024609B98C -:105ED0000320704702F53170D2F8D43240F8231015 -:105EE0000020F6E710B5024602F53070D2F8D44231 -:105EF00050F824300BB9032010BDC3F80412002061 -:105F0000FAE730B503460C4603F53070D3F8D452A7 -:105F100050F8251009B9032030BDC1F80842C1F876 -:105F200010220020F8E72DE9FC4105460C4605F556 -:105F30003070D5F8D41250F8216000200190009004 -:105F4000804616B90320BDE8FC81207800F060008F -:105F500000283DD020287CD1E08868B3207800F06C -:105F60008000B8B1E288607805F53171D5F8D4C207 -:105F700051F82C108B6831469847E088072801D9E2 -:105F8000072000E0E08807463A463146284600F000 -:105F900015F91CE0607886F80002E088402801D2FC -:105FA000E08800E0402086F8010296F801223146A0 -:105FB000284600F0E2F80AE0607805F53171D5F87E -:105FC000D42251F8221000228B682146984747E0DE -:105FD000607830B1012832D00A2813D00B282FD195 -:105FE00021E095F89C02032805D102226946284643 -:105FF00000F0E4F805E02146284600F0B2F84FF042 -:10600000030824E095F89C02032805D1012201A988 -:10601000284600F0D3F805E02146284600F0A1F814 -:106020004FF0030813E095F89C02032805D02146A1 -:10603000284600F096F84FF0030808E009E006E073 -:106040002146284600F08DF84FF0030800BF00BF3E -:1060500006E02146284600F084F84FF0030800BF10 -:1060600000BF40466FE7000070B5044604F530708D -:10607000D4F8D41250F821500126D4F8D41250F894 -:10608000210008B9032070BDD5F81402C8B9012059 -:10609000C5F814020C48007800F00F0000EB8002F5 -:1060A00004F1140000EB8200D5F81012416006489C -:1060B00001782046D5F81032D5F8082200F0F9FD15 -:1060C00000263046DFE700001F02002070B50446BE -:1060D0000D460026D4F8B80229464268204690476B -:1060E00000B10326304670BD70B504460D4694F8E5 -:1060F0009C02012804D0022803D003280CD101E01F -:1061000000BF00BF6888012805D10020C4F8A402A0 -:10611000204600F064F804E02946204600F021F80B -:1061200000BF00BF70BD024600207047024600203D -:10613000704770B506460C4615462B462246002190 -:10614000304600F0CBFC002070BD70B506460C4612 -:1061500015462B4622460021304600F0AAFD0020BD -:1061600070BD70B504460D468021204600F075FDD7 -:106170000021204600F071FD70BD70B504460E464A -:1061800015460320C4F894024FF4AC700551001D6D -:1061900005512B4632460021204600F09FFC00208E -:1061A00070BD10B504460520C4F8940200231A46B9 -:1061B0001946204600F092FC002010BD70B5044640 -:1061C0000E4615460220C4F89402A561E5612B46EF -:1061D00032460021204600F06CFD002070BD10B555 -:1061E00004460420C4F8940200231A4619462046A7 -:1061F00000F05FFD002010BD70B505460C462DB9BE -:106200002246064906A000F012FA04E0224603499D -:1062100003A000F00CFA014870BD00004CF700200C -:1062200043444320436F6E666967000002461220B4 -:1062300008800148704700004C01002070B50546F9 -:106240000C462DB92246064906A000F0F0F904E0FC -:106250002246034903A000F0EAF9014870BD00009E -:106260004CF7002043444320496E746572666163B5 -:1062700065000000024604200880014870470000C5 -:106280006001002070B505460C462246024903A075 -:1062900000F0CDF9004870BD4CF7002053544D6913 -:1062A00063726F656C656374726F6E69637300000F -:1062B00070B505460C462DB92246064906A000F0E9 -:1062C000B6F904E02246034903A000F0B0F9014802 -:1062D00070BD00004CF7002053544D3332205669F6 -:1062E000727475616C20436F6D506F7274000000A2 -:1062F00070B505460C461A202080FAF76DFC01485F -:1063000070BD00006401002070B504460D46E888A9 -:10631000012804D029462046FFF723FF1EE094F809 -:106320009C02012804D0022803D0032810D109E0E0 -:1063300000BF0020A060012204F108012046FFF701 -:106340003DFF0AE00122211D2046FFF737FF04E050 -:1063500029462046FFF705FF00BF00BF70BDF8B516 -:1063600004460E4600200090002700257088001289 -:10637000082875D2DFE800F0C7040C20C7C7A5B510 -:10638000207CD4F8B4120A68694690470746C1E0F9 -:10639000207C40B9D4F8B802816A6846884707462D -:1063A0000220787007E0D4F8B802C16A68468847CE -:1063B000074602207870ADE0B078062878D2DFE892 -:1063C00000F00316293C5063D4F8B402406838B199 -:1063D000207CD4F8B4124A6869469047074605E025 -:1063E00031462046FFF7BDFE681CC5B267E0D4F811 -:1063F000B402806838B1207CD4F8B4128A68694647 -:106400009047074605E031462046FFF7AAFE681C84 -:10641000C5B254E0D4F8B402C06838B1207CD4F8D6 -:10642000B412CA6869469047074605E031462046DF -:10643000FFF797FE681CC5B241E0D4F8B4020069CA -:1064400038B1207CD4F8B4120A69694690470746EF -:1064500005E031462046FFF784FE681CC5B22EE0F9 -:1064600051E0D4F8B402406938B1207CD4F8B412B9 -:106470004A6969469047074605E031462046FFF7DE -:1064800070FE681CC5B21AE0D4F8B402806940B14D -:10649000207CD4F8B4128A6969469047074606E022 -:1064A00006E031462046FFF75CFE681CC5B206E0F8 -:1064B00031462046FFF755FE681CC5B200BF00BF3D -:1064C00028E0207C30B9D4F8B802416B6846884790 -:1064D000074605E031462046FFF743FE681CC5B27B -:1064E00018E0207C40B9D4F8B802016B68468847B0 -:1064F00007460720787005E031462046FFF731FE59 -:10650000681CC5B206E031462046FFF72AFE681C2B -:10651000C5B200BF00BF05B1F8BDF088C0B1BDF87D -:10652000000080B1F088BDF80010884202DDBDF89F -:10653000000000E0F0880090BDF8002039462046B9 -:10654000FFF73CFE07E031462046FFF70AFE02E077 -:106550002046FFF744FE00BFDEE72DE9F84105467F -:106560000F462C462E464FF000087088317888423E -:1065700018DD307800900FE06946204600F020F8E2 -:1065800004466078052807D1A04698F80200B84272 -:1065900000D106E04FF000087088BDF80010884276 -:1065A000EADC00BF4046BDE8F881014600200A460B -:1065B00002E0431CD8B2521C1378002BF9D170476B -:1065C00010B5024610460B88047823440B800378EC -:1065D000981810BD70B504460D4694F89C02012829 -:1065E00004D0022803D003281AD101E000BF00BF65 -:1065F000E888022804D029462046FFF7B2FD14E0BF -:106600000120E060D4F8A40218B1E06840F0020074 -:10661000E060022204F10C012046FFF7CFFD04E008 -:1066200029462046FFF79DFD00BF00BF70BD2DE944 -:10663000F04107460D46904600240FB9BDE8F081B1 -:106640003E463046FFF7B1FF022101EB4000A8F8BB -:10665000000098F800002855601CC4B2032028559B -:10666000601CC4B208E030782855761C601CC4B2A7 -:1066700000202855601CC4B230780028F3D100BF38 -:10668000DCE70146002031B1012906D0022906D0FD -:10669000032908D105E0002007E0032005E00120E0 -:1066A00003E0032001E0032000BF00BF70472DE995 -:1066B000F04104460D46164614B90320BDE8F081AA -:1066C0000020C4F8B802C4F8C402C4F8D0020DB166 -:1066D000C4F8B452012084F89C022670204600F0D1 -:1066E0004DF907463846E9E72DE9F04104460D46E5 -:1066F000002600272946D4F8C802FAF758FF0646B4 -:106700003046FFF7BEFF07463846BDE8F0812DE969 -:10671000F04104460D46002600272946D4F8C80259 -:10672000FAF710FF06463046FFF7ABFF074638463C -:10673000BDE8F0812DE9F04704460F469146002F51 -:1067400056D104F11405D4F89402022846D1D5E9B3 -:10675000020188420FD9D5E90201401AA8604946D2 -:106760002046AA68FFF7F1FC00231A461946204686 -:1067700000F0B4F932E0D5E90210884217D1E96897 -:106780006868884213D36868D4F8981288420ED299 -:10679000002211462046FFF7D8FC0020C4F89802DA -:1067A00000231A461946204600F098F916E094F89E -:1067B0009C0203280BD1D4F8B802C06838B100207D -:1067C000C4F8D402D4F8B802C168204688478021B2 -:1067D000204600F042FA2046FFF7E3FC94F8A002BE -:1067E00050B3204600F0BCFA002084F8A00223E059 -:1067F00047F080012046FFF796FC0646FF2E1BD08F -:10680000D6B994F89C02032816D104F52E7050F8DE -:106810002600406980B1C4F8D46204F52E7050F8A7 -:10682000260039464269204690478046B8F1000F5D -:1068300002D04046BDE8F0870020FBE72DE9F04795 -:1068400005460F4690464FF00009002F51D105F53F -:10685000AA76D5F8940203286FD1D6E902018842BE -:1068600010D9D6E90201401AB060D6E90201884287 -:1068700001D2B06800E0F068024641462846FFF7C2 -:1068800058FC5AE095F8AA0200F01F0020B1012838 -:1068900004D0022812D109E0002411E040F2AE2019 -:1068A000415D2846FFF742FC044609E040F2AE2075 -:1068B000415D2846FFF737FC044601E0002400BF95 -:1068C00000BF94B995F89C0203280ED105F52E70EF -:1068D00050F82400006940B1C5F8D44205F52E7087 -:1068E00050F824000169284688472846FFF777FCBE -:1068F00023E007F07F012846FFF715FC0446FF2C34 -:106900001BD0D4B995F89C02032810D105F52E7040 -:1069100050F82400806950B1C5F8D44205F52E70B6 -:1069200050F8240039468269284690478146B9F1DB -:10693000000F02D04846BDE8F0870020FBE7014683 -:106940000020704770B504460025012084F89C02A1 -:10695000D4F8B80238B12179D4F8B8024268204698 -:10696000904700B10325284670BD70B504460D461A -:106970002946D4F8C802FAF758FE70BD10B504468F -:10698000207800282AD11648C0F80845C4F8C80263 -:106990004FF0A040124908600420486002211048CE -:1069A000C16000210161022181610021C161016298 -:1069B0004162C1620163FBF79EFA08B1FAF7D6F8AB -:1069C00080210748FAF743FD402200210448FAF7E6 -:1069D00043FD802201210248FAF73EFD002010BD50 -:1069E0004C09012010B50246D2F8C83201F08000EF -:1069F000802809D101F07F0000EBC00403F13C00C6 -:106A000000EB8400807810BD01F07F0000EBC00433 -:106A100003F51F7000EB84008078F4E770B504463E -:106A20000D4604F52E70D4F8D41250F8210008B9A0 -:106A3000032070BD94F89C02032811D104F52E7038 -:106A4000D4F8D41250F82100006A48B104F52E7031 -:106A5000D4F8D41250F821002946026A2046904703 -:106A60000020E6E770B504460D4604F52E70D4F814 -:106A7000D41250F8210008B9032070BD94F89C028C -:106A8000032811D104F52E70D4F8D41250F8210047 -:106A9000406A48B104F52E70D4F8D41250F82100A1 -:106AA0002946426A204690470020E6E72DE9F04754 -:106AB00004460F4615461E464FF00008C1462B46B9 -:106AC00032463946D4F8C802FAF7BAFD8046404645 -:106AD000FFF7D7FD81464846BDE8F0872DE9F0472E -:106AE00004460D4616461F464FF00008C1463B4679 -:106AF00032462946D4F8C802FAF7E8FD80464046F7 -:106B0000FFF7BFFD81464846BDE8F08770B50446F3 -:106B10000025012084F89C020020C4F894026060E3 -:106B2000C4F8A40284F8A002D4F8B80258B1D4F88A -:106B3000B802406838B12179D4F8B80242682046DA -:106B4000904700B103254023002211462046FFF75D -:106B5000ADFF01214FF4B27001534021001F0151DC -:106B60004023002280212046FFF7A0FF0121A184BD -:106B700040212162284670BD014691F89C020428FC -:106B800003D191F89D0281F89C020020704710B556 -:106B9000044694F89C0203280BD1D4F8B80240B103 -:106BA000D4F8B802C06920B1D4F8B802C16920464F -:106BB0008847002010BD02461174002070472DE95F -:106BC000F04104460D46002600272946D4F8C802A5 -:106BD000FBF7BEFA06463046FFF753FD0746384638 -:106BE000BDE8F08170B504460D46294604F2AA209E -:106BF00000F077F80120C4F894024FF42C70005B89 -:106C0000C4F8980294F8AA0200F01F0020B10128ED -:106C100009D0022815D10DE004F2AA21204600F087 -:106C200083F9064616E004F2AA21204600F013FB81 -:106C300006460FE004F2AA21204600F0CCF90646F1 -:106C400008E094F8AA0200F08001204600F005F860 -:106C5000064600BF00BF304670BD2DE9F041044636 -:106C60000D46002600272946D4F8C802FAF75AFD37 -:106C700006463046FFF705FD07463846BDE8F08179 -:106C800070B5044600250026D4F8C802FBF784FA44 -:106C900005462846FFF7F5FC0646304670BD01461E -:106CA00091F89C0281F89D02042081F89C0200204A -:106CB00070472DE9F04704460D4616461F464FF033 -:106CC0000008C1463B4632462946D4F8C802FAF7C6 -:106CD0006EFD80464046FFF7D4FC81464846BDE83D -:106CE000F08770B505460E46344620782870641C3F -:106CF00020786870641C2046FEF74EFC6880641C97 -:106D0000641C2046FEF748FCA880641C641C2046D6 -:106D1000FEF742FCE88070BD38B504460D46002001 -:106D200000900DB9032038BDC4F8B85204F52E7098 -:106D3000D4F8D41250F82100C06A50B104F52E7076 -:106D4000D4F8D42250F82200C16A68468847C4F8B3 -:106D5000D002D4F8D802401CC4F8D8020020E2E7E0 -:106D600001460020704770B504460D46A88810BB48 -:106D7000E88800BB688880281DD2A87800F07F06CC -:106D800094F89C02032804D129462046FFF7E9F92C -:106D900015E084F89E6231462046FFF710FF20463A -:106DA000FFF71DFA1EB1022084F89C0207E00120C3 -:106DB00084F89C0203E029462046FFF7D2F970BD13 -:106DC00070B504460D460026D4F8B80230B1D4F8A8 -:106DD000B80229460268204690470646304670BDF4 -:106DE00070B504460E460025B0783D490870084647 -:106DF0000078012805D931462046FFF7B2F9032073 -:106E000070BD94F89C02022802D0032859D11FE0DB -:106E100033480078C0B1324800786060304801786B -:106E20002046FFF7CDFF05463DB131462046FFF72E -:106E300098F9022084F89C0209E02046FFF7CFF978 -:106E4000032084F89C0202E02046FFF7C8F943E0E3 -:106E50002348007870B9022084F89C02204800780A -:106E600060601F4801782046FFF730F92046FFF7A1 -:106E7000B6F925E01A490978606888421DD0217961 -:106E80002046FFF723F9164800786060144801781F -:106E90002046FFF795FF05465DB131462046FFF7D6 -:106EA00060F921792046FFF711F9022084F89C024D -:106EB00006E02046FFF793F902E02046FFF78FF93E -:106EC0000AE031462046FFF74CF905480178204694 -:106ED000FFF7FCF8032500BF00BF284690E700003D -:106EE0009401002070B505460C466088012805D144 -:106EF000C5F8A4022846FFF772F90EE06088022860 -:106F000007D1A088001285F8A0022846FFF767F98C -:106F100003E021462846FFF724F970BD10B504466A -:106F20002046FFF7ADFE10BD70B504460D460026A5 -:106F3000287800F0600088B1202802D0402842D193 -:106F400000E000BF04F52E70D4F8D41250F82100F0 -:106F50002946826820469047064639E068780A2824 -:106F60002AD2DFE800F01A24291F290A0529150F63 -:106F700029462046FFF7F3F923E029462046FFF78C -:106F8000F2FE1EE029462046FFF72AFF064618E0DB -:106F900029462046FFF7B8F913E029462046FFF7B7 -:106FA00019FB0EE029462046FFF79CFF09E0294621 -:106FB0002046FFF799F804E029462046FFF7D1F86C -:106FC00000BF00BF04E029462046FFF7CAF800BF13 -:106FD00000BF304670BD2DE9F04705460F464FF023 -:106FE00000093C79387800F06000F8B1202802D020 -:106FF00040287DD100E000BF21462846FFF793F8E6 -:107000000646FF2E11D086B9C5F8D46205F52E705C -:1070100050F82600806840B105F52E7050F8260023 -:107020003946826828469047814610E178780028E2 -:107030007AD001282FD003286ED195F89C0202281F -:1070400002D0032820D110E054B1802C08D0214672 -:107050002846FFF702FE80212846FFF7FEFD03E0E9 -:1070600039462846FFF77DF813E0788840B93CB1EF -:10707000802C05D0F88818B921462846FFF7EDFD89 -:107080002846FFF7ACF804E039462846FFF769F8D0 -:1070900000BF00BFD4E095F89C02022802D003286C -:1070A0003BD110E054B1802C08D021462846FFF790 -:1070B000D4FD80212846FFF7D0FD03E0394628465D -:1070C000FFF74FF82EE0788820BB04F07F0018B15E -:1070D00021462846FFF708FB2846FFF780F821469F -:1070E0002846FFF720F80646FF2E13D096B900E099 -:1070F000A8E0C5F8D46205F52E7050F82600806827 -:1071000040B105F52E7050F82600394682682846B1 -:107110009047814606E007E08DE039462846FFF7B4 -:1071200020F800BF00BF8BE095F89C02022802D037 -:10713000032879D126E034B1802C04D03946284682 -:10714000FFF70FF875E004F08000802808D104F004 -:107150007F0000EB800105F1140000EB810007E0E7 -:1071600004F07F0000EB800105F5AA7000EB8100C0 -:1071700080460020C8F80000022241462846FFF75A -:107180001DF856E004F0800080280ED104F00F00B6 -:1071900000EB800105F1140000EB8100008A98B932 -:1071A00039462846FEF7DDFF43E004F00F0000EB10 -:1071B000800105F5AA7000EB8100008A20B93946EC -:1071C0002846FEF7CEFF34E004F08000802808D186 -:1071D00004F07F0000EB800105F1140000EB81005A -:1071E00007E004F07F0000EB800105F5AA7000EBDA -:1071F000810080460CB1802C03D10020C8F800002B -:107200000CE021462846FFF7EDFB20B10120C8F82D -:10721000000003E008E00020C8F800000222414618 -:107220002846FEF7CBFF04E039462846FEF799FFD3 -:1072300000BF00BF04E039462846FEF792FF00BFBA -:1072400000BF04E039462846FEF78BFF00BF00BFB1 -:107250004846BDE8F0872DE9F04105460E46002777 -:10726000307800F0600030B1202802D0402840D1B2 -:1072700000E000BF00BF95F89C02012804D002285E -:1072800003D003282ED101E000BF00BF30790128D0 -:1072900023D831792846FEF749FF0446FF2C14D045 -:1072A0009CB905F52E7050F82400806858B1C5F8D7 -:1072B000D44205F52E7050F82400314682682846E5 -:1072C0009047074602E0032700E00327F08840B913 -:1072D0003FB92846FEF783FF03E031462846FEF714 -:1072E00040FF04E031462846FEF73BFF00BF00BFE9 -:1072F00004E031462846FEF734FF00BF00BF3846A1 -:10730000BDE8F08170470000014601487047000069 -:10731000580E012070B504460B462246197858785D -:1073200001282CD140F61C0080581D7805F00F066E -:107330000125B540ADB2284340F61C05A85002F522 -:10734000106000EB4110006800F40040F0BB988929 -:10735000C0F30A001D7940EA854040EA815040F0C0 -:10736000805040F4004002F5106505EB41152D6892 -:10737000284302F5106505EB411528602DE040F625 -:107380001C0080581D7805F00F060125B540144EED -:1073900006EA0545284340F61C05A85002F5306072 -:1073A00000EB4110006800F4004078B99889C0F300 -:1073B0000A001D7940EA854040F0805040F40040CA -:1073C00002F5306505EB41152D6800E005E0284326 -:1073D00002F5306505EB41152860002070BD000006 -:1073E0000000FFFF01460A464FF410608058C30AB0 -:1073F000DB024FF41060835040F60400805840F4E4 -:10740000807340F604008350002070470FB470B5BD -:1074100004460A98012817D1A06B20F48030A0639D -:10742000E0681A490840E060E06820F44010E0603D -:107430001198012803D1E06840F48010E0602046F4 -:1074400000F026F8054612E0E06840F04000E060F9 -:10745000204600F01DF805460E9820B9A06B40F4B8 -:107460008030A06303E0A06B20F48030A063089814 -:10747000012807D1A06840F00600A060A06840F095 -:107480002000A060284670BC5DF814FBBFFFBDFF64 -:1074900008B501460020009000BF0098401C0090F5 -:1074A000104A0098904201D9032008BD086900F0F5 -:1074B00000400028F1D000200090086940F0010051 -:1074C000086100BF0098401C0090064A0098904256 -:1074D00001D90320E9E7086900F001000028F1D193 -:1074E00000BFE2E7400D030070B504460B4622469C -:1074F00019785878012848D102F5106000EB411046 -:10750000006800F00040B0F1004F17D102F51060A4 -:1075100000EB4110006840F0006502F5106000EBE0 -:107520004110056002F5106000EB4110006840F06A -:10753000804502F5106000EB4110056040F63C000C -:1075400080581D7805F00F060125B540ADB2A8435F -:1075500040F63C05A85040F61C0080581D7805F008 -:107560000F060125B540ADB2A84340F61C05A85052 -:1075700002F5106000EB411000682B4D284002F529 -:10758000106505EB411528604BE002F5306000EB1B -:107590004110006800F00040B0F1004F17D102F533 -:1075A000306000EB4110006840F0006502F530608B -:1075B00000EB4110056002F5306000EB41100068FF -:1075C00040F0804502F5306000EB4110056040F668 -:1075D0003C0080581D7805F00F060125B540134E7C -:1075E00006EA0545A84340F63C05A85040F61C00B5 -:1075F0008558187800F00F060120B0400B4E06EABF -:107600000040854340F61C00855002F5306000EBD9 -:1076100041100068064D284002F5306505EB411524 -:107620002860002070BD0000007833EC0000FFFFF0 -:107630000078F3EF01460A46D2F8000E20F003006E -:10764000C2F8000E40F60400805820F0020340F615 -:10765000040083500020704701460A46D2F8000E0D -:1076600020F00300C2F8000E40F60400805840F0FD -:10767000020340F604008350002070470FB4F0B5B9 -:10768000054600272E46002405E0002105F58270FE -:1076900040F82410641C0F2CF7D31098A0B940F6C2 -:1076A0000400805940F0020140F604008151A86BAB -:1076B00040F40010A863A86B20F40020A863A86B16 -:1076C00020F48020A86307E0A86B20F40010A863D2 -:1076D000A86B40F40020A8630020C6F8000ED6F87E -:1076E0000008C6F800080B9801280BD1089820B9AB -:1076F0000021284600F0BCFD08E00121284600F0EA -:10770000B7FD03E00321284600F0B2FD1021284612 -:1077100000F0B2FC00B10127284600F083FC00B164 -:10772000012700214FF401608151001D815140F675 -:107730001C00815100242EE006F5106000EB44107F -:10774000006800F00040B0F1004F10D13CB94FF09C -:10775000006106F5106000EB441001600DE04FF091 -:10776000904106F5106000EB4410016005E0002137 -:1077700006F5106000EB44100160002106F5106072 -:1077800000EB441001614FF67F3106F5106000EB0D -:1077900044108160641C0698A042CDD800242EE0DD -:1077A00006F5306000EB4410006800F00040B0F1D6 -:1077B000004F10D13CB94FF0006106F5306000EB8E -:1077C000441001600DE04FF0904106F5306000EB91 -:1077D0004410016005E0002106F5306000EB441024 -:1077E0000160002106F5306000EB441001614FF6A6 -:1077F0007F3106F5306000EB44108160641C069810 -:10780000A042CDD84FF40160805920F480714FF42C -:10781000016081510020A8616FF080406861099883 -:1078200018B9A86940F01000A861A869094908437F -:10783000A8610C9818B1A86940F00800A8611098D8 -:10784000012803D1A86904490843A8613846F0BC5F -:107850005DF814FB00383C80040000400146886855 -:1078600020F001008860002070470000F0B5054658 -:107870000B4614462A4619785878012875D198691C -:1078800020BB02F5106000EB411000696D4E3040E6 -:1078900002F5106606EB4116306102F5106000EB50 -:1078A0004110006940F4002602F5106000EB411021 -:1078B000066102F5106000EB41100069C60CF60489 -:1078C00002F5106000EB4110066137E002F5106030 -:1078D00000EB41100069C60CF60402F5106000EBE5 -:1078E0004110066102F5106000EB41100069554E31 -:1078F000304002F5106606EB41163061DE6898698B -:10790000B04201D9D868986102F5106000EB4110CF -:10791000006940F4002602F5106000EB411006619A -:1079200002F5106000EB411000699E69C6F3120673 -:10793000304302F5106606EB41163061012C15D17B -:10794000586928B102F5106000EB41105E6946618C -:1079500002F5106000EB4110006840F0044602F5AB -:10796000106000EB411006606AE01BE002F5106059 -:1079700000EB4110006840F0044602F5106000EB97 -:1079800041100660986900285AD040F634008058AB -:107990001E7806F00F070126BE40304340F634063D -:1079A000B0504DE002F5306000EB41100069C60CAC -:1079B000F60402F5306000EB4110066102F530601C -:1079C00000EB411000691F4E304002F5306606EBB7 -:1079D00041163061986908B1D8689861D868D86153 -:1079E00002F5306000EB4110006940F4002602F51A -:1079F000306000EB4110066102F5306000EB411091 -:107A00000069DE69C6F31206304302F5306606EB04 -:107A100041163061012C07D1186928B102F5306098 -:107A200000EB41101E69466102F5306000EB411029 -:107A3000006840F0044602F5306000EB411006603B -:107A40000020F0BDFFFF07E070B503460C46194665 -:107A50001D6C1848854209D94FF43060405800F039 -:107A60000040B0F1004F01D1002070BD0026C1F8E8 -:107A7000106BD1F8100B40F40026C1F8106BD1F850 -:107A8000100B40F01806C1F8106BD1F8100B40F045 -:107A9000C046C1F8106B012C09D1C1F8142B4FF46A -:107AA0003060405840F080264FF43060465000204F -:107AB000DBE700000A30544F30B504460B4622463F -:107AC0001978587801281ED102F5106000EB41109A -:107AD000006820F4001502F5106000EB411005600D -:107AE0001879032802D0187902282AD102F51060EB -:107AF00000EB4110006840F0805502F5106000EB8B -:107B0000411005601DE002F5306000EB4110006897 -:107B100020F4001502F5306000EB41100560187983 -:107B2000032802D0187902280BD102F5306000EB4F -:107B30004110006840F0805502F5306000EB4110C4 -:107B40000560002030BD30B504460B46224619784A -:107B50005878012821D102F5106000EB411000682F -:107B600000F0004060B959B102F5106000EB41101F -:107B7000006820F0804502F5106000EB41100560C0 -:107B800002F5106000EB4110006840F4001502F5AA -:107B9000106000EB4110056020E002F5306000EB62 -:107BA0004110006800F0004060B959B102F5306042 -:107BB00000EB4110006820F0804502F5306000EBDA -:107BC0004110056002F5306000EB4110006840F4A0 -:107BD000001502F5306000EB41100560002030BD5B -:107BE0002DE9F84381460E4617464D4634787078A5 -:107BF00001287DD1B06920BB05F5106000EB441071 -:107C00000069C849084005F5106101EB441108619D -:107C100005F5106000EB4410006940F4002105F503 -:107C2000106000EB4410016105F5106000EB44109A -:107C30000069C10CC90405F5106000EB4410016136 -:107C400055E005F5106000EB44100069C10CC90453 -:107C500005F5106000EB4410016105F5106000EBC4 -:107C600044100069AF49084005F5106101EB44116B -:107C70000861F168B0690844401EB0FBF1F0A94901 -:107C8000C94301EAC04005F5106101EB44110969DF -:107C9000084305F5106101EB4411086105F510601A -:107CA00000EB44100069B169C1F31201084305F506 -:107CB000106101EB441108613079012817D105F5F5 -:107CC000106000EB4410006920F0C04105F5106021 -:107CD00000EB4410016105F5106000EB44100069F1 -:107CE00040F0005105F5106000EB4410016100E028 -:107CF0007FE0012F36D1706928B105F5106000EBE7 -:107D0000441071694161307901281ED140F60800A4 -:107D1000405900F4807060B905F5106000EB441024 -:107D2000006840F0005105F5106000EB4410016060 -:107D30000BE005F5106000EB4410006840F0805146 -:107D400005F5106000EB4410016005F5106000EBD4 -:107D50004410006840F0044105F5106000EB441049 -:107D60000160DCE005F5106000EB4410006840F0B5 -:107D7000044105F5106000EB4410016030790128E2 -:107D80000FD0B0690028ECD040F63400405931786B -:107D900001F00F0201219140084340F6340148519F -:107DA000BDE040F60800405900F4807060B905F568 -:107DB000106000EB4410006840F0005105F51060C1 -:107DC00000EB441001600BE005F5106000EB44107F -:107DD000006840F0805105F5106000EB4410016030 -:107DE0000097308B83B232784846316900F0BEFA92 -:107DF00095E005F5306000EB44100069C10CC90442 -:107E000005F5306000EB4410016105F5306000EBD2 -:107E1000441000694349084005F5306101EB441105 -:107E20000861B069D0B905F5306000EB4410006915 -:107E3000F168C1F31201084305F5306101EB44110B -:107E4000086105F5306000EB4410006940F4002142 -:107E500005F5306000EB4410016128E0F168B0697D -:107E60000844401EB0FBF1F01FFA80F8F06800FBF8 -:107E700008F0F06105F5306000EB44100069294915 -:107E8000C94301EAC841084305F5306101EB4411DB -:107E9000086105F5306000EB44100069F169C1F339 -:107EA0001201084305F5306101EB44110861012F0F -:107EB00007D1306928B105F5306000EB4410316915 -:107EC0004161307901281ED140F60800405900F484 -:107ED000807060B905F5306000EB4410006840F038 -:107EE000005105F5306000EB441001600BE005F532 -:107EF000306000EB4410006840F0805105F53060C0 -:107F000000EB4410016005F5306000EB44100068A0 -:107F100040F0044105F5306000EB441001600020A2 -:107F2000BDE8F883FFFF07E078B50346002400941E -:107F300000201A464C78012C35D10C7802F51065DA -:107F400005EB4414246804F00044B4F1004F60D100 -:107F50000C7805EB4414246844F000660C7805EBBB -:107F6000441426600C7805EB4414246844F08046E1 -:107F70000C7805EB4414266000BF009C641C009440 -:107F800042F21075009CAC4201D901200AE00C7845 -:107F900002F5106505EB4414246804F00044B4F1C4 -:107FA000004FEAD035E00C7802F5306505EB44145B -:107FB000246804F00044B4F1004F2AD10C7805EB9A -:107FC0004414246844F000660C7805EB44142660E1 -:107FD0000C7805EB4414246844F080460C7805EBDB -:107FE0004414266000BF009C641C009442F210758B -:107FF000009CAC4201D901200AE00C7802F5306502 -:1080000005EB4414246804F00044B4F1004FEAD0B6 -:1080100000BF78BD0146886840F0010088600020FC -:108020007047000008B501460020009000BF00988E -:10803000401C00900F4A0098904201D9032008BDCF -:10804000086900F000400028F1D0002000901020C6 -:10805000086100BF0098401C0090064A00989042BA -:1080600001D90320EBE7086900F010001028F1D0D7 -:108070000020E4E7400D030008B502460020009010 -:1080800000BF0098401C0090104B0098984201D906 -:10809000032008BD106900F000400028F1D0002046 -:1080A0000090202040EA8110106100BF0098401C21 -:1080B0000090064B0098984201D90320E9E7106927 -:1080C00000F020002028F1D00020E2E7400D03005E -:1080D00010B501460B4640F60804E45804F00602C9 -:1080E0000AB9002006E0022A01D0062A01D10220A6 -:1080F00000E00F2010BD0146486900F00100704704 -:1081000001460B4640F61800C258001DC0580240F8 -:1081100090B2704701460B4640F61800C258001D49 -:10812000C0580240100C704770B5024613464FF419 -:108130000166F45840F63406F55801F00F0625FAAA -:1081400006F606F0010644EAC61403F5106606EBCF -:108150004116B66806EA040070BD10B50246134623 -:1081600003F5306404EB4114A06840F61404E458AD -:10817000204010BD014648698A69104070472DE9CA -:10818000F04104460D46274628464FEA920C02F07D -:10819000030300210AE04FF4805858F80780C0F824 -:1081A0000080401C401C401C401C491C6145F2D30F -:1081B0009BB100214FF4805858F8076000BF4FEA88 -:1081C000C10826FA08F880F80080491C401CA3F179 -:1081D00001081FFA88F3002BF1D1BDE8F08170B5DA -:1081E00004460E460025E06820F0C040E060012E05 -:1081F00010D1E06840F00050E06000BF0120F8F7C7 -:10820000E9FE6D1C2046FFF776FF012815D0322DC0 -:10821000F4D312E07EB9E06840F08040E06000BF37 -:108220000120F8F7D7FE6D1C2046FFF764FF20B150 -:10823000322DF5D301E0012070BD322D01D1012096 -:10824000FAE70020F8E710B502460B461146D1F8D0 -:10825000000820F4FE60C1F80008D1F800084FF4CF -:10826000FE6404EA03142043C1F80008002010BD96 -:1082700002461346D3F800080843C3F8000800205C -:108280007047000030B503461446022C49D12D48F2 -:10829000814204D32C48814201D20F2245E02A4872 -:1082A000814204D32948814201D20E223DE0274871 -:1082B000814204D32648814201D20D2235E0244870 -:1082C000814204D32348814201D20C222DE021486F -:1082D000814204D32048814201D20B2225E01E486E -:1082E000814204D31D48814201D20A221DE01B486D -:1082F000814204D31A48814201D2092215E018486C -:10830000814204D31748814201D208220DE015486A -:10831000814204D31448814201D2072205E006229B -:1083200003E00CB9092200E00922D86820F470505B -:10833000D860D8684FF4705505EA82252843D86084 -:10834000002030BDC0ACD800C0E1E4000024F4003F -:1083500080730601A0491A01002D310140A44C018F -:1083600000366E0120ABA6010048E8012DE9F0437C -:1083700004460D461E46DDF81CC0A0462946BCF149 -:10838000000F12D1F01C870800230CE0D1F80090F8 -:1083900008F5805000EB0230C0F80090491C491CE1 -:1083A000491C491C5B1CBB42F0D30020BDE8F08394 -:1083B00000BFFEE70FB4084B10B504A902AA03984A -:1083C00000F046FC044602A9002001F061F92046B5 -:1083D00010BC5DF814FB0000919600087CB50C0001 -:1083E0001D461646014601D0601E00E00020CDE982 -:1083F0000010064B6A462946304600F029FC002C46 -:1084000002D0009A002111707CBD000099950008EF -:1084100002480068C0F30220704700000CED00E045 -:1084200010B5002804DB0A07130E054A135406E0B2 -:108430000A07140E034A00F00F031B1FD45410BD8B -:1084400000E400E018ED00E002E008C8121F08C1D7 -:10845000002AFAD170477047002001E001C1121FC5 -:10846000002AFBD170472DE9FC410446A089401E3B -:1084700080B200906089401E83B2002211462046DF -:10848000266FB0472068006A006800684FF6BF7129 -:1084900008402168096A096808602068006A006865 -:1084A000006840F400602168096A09680860206873 -:1084B000006A0068006840F040002168096A0968A5 -:1084C000086020680169D1E90401CDE90001206854 -:1084D0000669F7683B4696E80700B847002508E0BC -:1084E000608A2168096A0968C860206801F0E8F8B4 -:1084F0006D1C6089A1894843A842F1D8206801F029 -:10850000D6F820680169D1E90401CDE900012068AD -:108510000669D6E902733A46D6E90001B8472068F1 -:10852000006A006800684FF6BF7108402168096A58 -:10853000096808602068006A006800684FF2FF71EF -:1085400008402168096A096808602068006A0068B4 -:10855000006840F040002168096A09680860BDE8C9 -:10856000FC8100002DE9FE4F0446884691461D46D9 -:108570000026B2460027B346A5F12000C5B2206808 -:108580000169D1E90401CDE900012068D0F810E0CB -:10859000DEF80CC063469EE80700E04700BF33E00A -:1085A000A0690068A169098905FB0161405C02902E -:1085B0004FF0000A22E0029800F0010028B1A08AE2 -:1085C0002249096821F8170004E0608A1F490968F8 -:1085D00021F81700029840100290781C87B20BF126 -:1085E00001001FFA80FBA0698088584502D14FF036 -:1085F000000B06E00AF101001FFA80FABAF1080F39 -:10860000D9DB00BF701C86B2A0690089B042C7DC0C -:10861000A069C0884844401E80B20090A06980884C -:108620004044401E83B24A4641462046D4F870C0BA -:10863000E047A0698088A169C988484382B203489D -:108640000168204601F045F8BDE8FE8F2C010020AE -:108650002DE9FE4F0446884691461E460025002718 -:108660000020029083461BE0E06902680089691CD3 -:108670004843105C317888420BD1E0690289016877 -:10868000681C00FB021040787178884201D1AA462C -:1086900007E0A81C85B2E0694089A84200DC00E040 -:1086A000E2E700BF0025002733E0E0690068E169E8 -:1086B00009890AFB0100C05D01900020029022E0C0 -:1086C000019800F0010028B1A08A2349096821F827 -:1086D000150004E0608A2049096821F81500681C2B -:1086E00085B20198401001900BF101001FFA80FB48 -:1086F000E0698088584502D14FF0000B06E00298EF -:10870000401C80B2029002980828D9DB00BF781C78 -:1087100087B2E0690089B842C7DCE069C088484494 -:10872000401E80B20090E06980884044401E83B2C1 -:108730004A4641462046D4F870C0E047E069808848 -:10874000E169C988484382B203480168204600F0C5 -:10875000C0FFBDE8FE8F00002C0100202DE9F04194 -:1087600005460E4617461C4619E020787F280BDC8C -:1087700023783A4631462846FFF7F4FEA8698088F8 -:10878000304486B2641C0AE023463A463146284605 -:10879000FFF75EFFE8698088304486B2A41C207829 -:1087A0000028E2D1BDE8F0812DE9FF5F82B0002111 -:1087B000DDE90430020DDDF840B0034318D044F683 -:1087C0001050A2F2FF3242431514119801281FD015 -:1087D000A5EB0B00401C5FEA000A4FF000064E4F6D -:1087E000DFF83891B046504615D5CAF1000413E0C1 -:1087F000119801244AA3012801D16FEA0B010298C4 -:10880000119AC0E90031C0E9024206B0BDE8F09F0C -:10881000CBF10000DFE704460021404A491842EB53 -:108820000450CDE9001012E0E00707D032463B4685 -:1088300040464946F7F722FE8046894632463B4687 -:1088400010461946F7F71AFE06460F466410002C2C -:10885000EAD1DDE90401DDE90023BAF1000F06DA0F -:10886000F7F70CFE42464B46F7F708FE05E0F7F730 -:108870001BFF42464B46F7F717FF04460E46002201 -:10888000284BF7F799FF03D84FF0FF30014607E078 -:108890000022254B20463146F7F749FDF7F773FFD5 -:1088A000102409E0002C0ADB0A220023F7F7EAFC77 -:1088B000039B30321A55641E50EA0102F2D1641C47 -:1088C000039AC4F111031444119A012A03D001221E -:1088D00008430DD10AE0084304D000204FF0110BEB -:1088E000119072E7A3EB0B056D1E0DE05B4504DDF7 -:1088F0004FF0000205F1010504E003DA4FF0000239 -:10890000A5F10105002AECD002981199C0E90231C5 -:10891000C0E9004579E70000000014400000F03F86 -:10892000300000000000F0430000E03F30B50022BE -:108930000023002401F478052A0A01F47C456B0920 -:10894000C1F3C40442EA03052543458230BD00005B -:10895000014601F1100000E0001D02681AB9024A48 -:1089600012689042F8D370478400002070B5044626 -:108970000D460CB1012100E00021084640F205112E -:10898000F8F754F80DB1012100E0002108464FF43A -:108990008371F8F74BF8002084F831002562206AD3 -:1089A0000068006840F04000216A0968086070BDF6 -:1089B0007CB504460A20F8F70DFB4FF48055294694 -:1089C000012001F095FA9749086008460068A06206 -:1089D00020680169D1E90401CDE900012068056939 -:1089E000EE68334695E80700B0473621206800F06E -:1089F000E5FE0021206800F01BFF3A21206800F00E -:108A0000DDFE0521206800F013FFB221206800F090 -:108A1000D5FE0C21206800F00BFF0C21206800F02F -:108A200007FF0021206800F003FF3321206800F0D9 -:108A3000FFFE3321206800F0FBFEB721206800F024 -:108A4000BDFE3521206800F0F3FEBB21206800F058 -:108A5000B5FE1921206800F0EBFEC021206800F06F -:108A6000ADFE2C21206800F0E3FEC221206800F05A -:108A7000A5FE0121206800F0DBFEC321206800F084 -:108A80009DFE1221206800F0D3FEC421206800F072 -:108A900095FE2021206800F0CBFEC621206800F062 -:108AA0008DFE0F21206800F0C3FED021206800F069 -:108AB00085FEA421206800F0BBFEA121206800F003 -:108AC000B7FEE021206800F079FED021206800F098 -:108AD000AFFE0421206800F0ABFE0D21206800F0FD -:108AE000A7FE1121206800F0A3FE1321206800F0EA -:108AF0009FFE2B21206800F09BFE3F21206800F0A4 -:108B000097FE5421206800F093FE4C21206800F06D -:108B10008FFE1821206800F08BFE0D21206800F0E8 -:108B200087FE0B21206800F083FE1F21206800F0E3 -:108B30007FFE2321206800F07BFEE121206800F009 -:108B40003DFED021206800F073FE0421206800F073 -:108B50006FFE0C21206800F06BFE1121206800F0F0 -:108B600067FE1321206800F063FE2C21206800F0CE -:108B70005FFE3F21206800F05BFE4421206800F08A -:108B800057FE5121206800F053FE2F21206800F08D -:108B90004FFE1F21206800F04BFE1F21206800F0CF -:108BA00047FE2021206800F043FE2321206800F0CA -:108BB0003FFE2121206800F001FE1121206800F015 -:108BC000FDFD7820F8F706FA2921206800F0F6FD6F -:108BD000206800F06CFD20680169D1E90401CDE94D -:108BE000000120680569D5E902633246D5E9000134 -:108BF000B04702212046E26D904700212046E26EF8 -:108C000090476FF07F412046226E90472046616F6B -:108C10008847842002590449204690470020A075C7 -:108C20007CBD00002C010020FC00002010B506488F -:108C3000046803E02046FFF78BFE04460348006803 -:108C40008442F7D310BD0000800000208400002083 -:108C50002DE9FF4F95B09A46884606460025EEE17D -:108C6000252877D100242746F94A0121039400E002 -:108C7000044316F8013F203B01FA03F01042F7D1FC -:108C800030782A2811D06FF02F033078A0F130020D -:108C9000092A16D8039A44F0020402EB820203EB7D -:108CA00042021044761C0390EFE758F8042B03921D -:108CB000002A03DA504244F40054039044F00204C2 -:108CC000761C30782E2816D116F8010F44F00404D3 -:108CD0002A280DD06FF02F023078A0F13003092B35 -:108CE00009D807EB870302EB4303C718761CF3E7A9 -:108CF00058F8047B761C30786C280FD006DC4C28A2 -:108D000017D068280DD06A2814D104E0742810D038 -:108D10007A280FD10DE044F400140AE044F48014E2 -:108D200001E044F440147278824202D104F58014C8 -:108D3000761C761C307866280BD013DC582877D048 -:108D400009DC002875D04528F6D04628F4D04728FD -:108D50001AD193E118E0632835D0642879D06528CA -:108D600012D18BE1702873D008DC6728F1D0692814 -:108D70006FD06E280DD06F2806D1ACE073282CD0B0 -:108D8000752874D0782853D05246179990476D1C97 -:108D900054E1C4F30250022809D003280DD0D8F8BA -:108DA000001004280DD00D6008F1040846E1D8F841 -:108DB0000010EA17C1E90052F6E7D8F800100D805C -:108DC000F2E70D70F0E718F8041B8DF80010002092 -:108DD0008DF80100EB46012003E058F804BB4FF08A -:108DE000FF3061074FF0000102D40DE009F10101ED -:108DF0008946B9420FDA8145F8DB1BF809100029D2 -:108E0000F4D108E009F1010189468142FADB1BF83F -:108E100009100029F6D103985346A0EB0907214613 -:108E20003846179A00F080FA284400EB090507E05D -:108E300044E008E10DE01BF8010B524617999047FA -:108E4000B9F10109F7D2534621463846179AF2E0A4 -:108E500039E00A21C4F302524FF0000B0091022ABC -:108E600006D058F8040BC117032A09D00AE023E002 -:108E700008F1070020F00702F2E80201904605E041 -:108E800000B2C117042A01D140B2C117002906DA85 -:108E90000A460021404261EB02012D2202E0220538 -:108EA00004D52B228DF80420012203E0E20701D033 -:108EB0002022F7E7914657E00A2100E010214FF009 -:108EC000000B00910BE010214FF0000B44F0040464 -:108ED0000827009103E008204FF0000B0090C4F336 -:108EE0000252022A05D058F8040B0021032A08D0A8 -:108EF00008E008F1070020F00702F2E802019046BE -:108F000003E080B2042A00D1C0B24FF0000922076A -:108F10002AD53278702A07D0DDF800C08CF0100C0A -:108F20005CEA0B0C05D00EE040228DF804200122F3 -:108F300008E050EA010306D030238DF804308DF8A4 -:108F4000052002229146009B83F0080353EA0B039D -:108F50000AD150EA010201D1620705D530228DF80D -:108F600004204FF001097F1E3278582A04D039A21C -:108F70000C920CAA02920BE03BA2F9E75B46009A26 -:108F8000F7F780F90C9B9B5C029A521E02921370B9 -:108F900050EA0102F2D1029804A9081A00F1200B4C -:108FA000600702D524F4803400E001275F4502DD2C -:108FB000A7EB0B0000E0002000EB0B0100900398F2 -:108FC0004944401A0390E00306D453462146179AB9 -:108FD000039800F0A9F90544002706E001A85246CD -:108FE000C05D179990476D1C7F1C4F45F6DBE00371 -:108FF0000CD553462146179A039800F095F905447D -:1090000004E030205246179990476D1C0099481E85 -:1090100000900029F5DC08E0029802995246007899 -:10902000491C0291179990476D1CBBF10001ABF1EF -:10903000010BF1DC5BE100F065F90544761C30784A -:1090400000287FF40DAE19B02846BDE8F08F00006F -:10905000092801003031323334353637383961620E -:1090600063646566000000003031323334353637D2 -:10907000383941424344454600000000600700D4AF -:10908000062708F1070020F00700F0E802238046D9 -:1090900003F0004C5FEA0C0001D097A009E0200526 -:1090A00001D596A005E0E00701D095A001E0AFF260 -:1090B0004C001390307823F0004365280CD006DC78 -:1090C000452809D046281DD047287FD13BE0662897 -:1090D00018D067287AD136E00021112F01DB11204A -:1090E00000E0781CCDE9000104A90CA8FFF75CFBA7 -:1090F000DDE90D010C9A4FF0000B07F10109109208 -:1091000000914EE04FF000400097CDE9011004A916 -:109110000CA8FFF749FBDDE90D020C9B0F994FF0FE -:10912000000B91461093009211B9791C00EB0109D4 -:10913000B7EB090003D4C0F1FF3B07F10109A9EB2C -:109140000700019042E0012F00DA01270021112FD2 -:1091500001DD112000E03846CDE9000104A90CA88A -:10916000FFF722FBDDE90D010C9A00914FF0000B97 -:10917000B946109221070FD4009A4A4503DA914666 -:1091800001E0A9F10109B9F1010F05DD109AA9F17A -:109190000101515C3029F4D0B84202DA10F1040F19 -:1091A00003DA0121CDE9011010E0002803DC83443B -:1091B000A9EB000102E0411C494500DD8946A0EB16 -:1091C0000B00401C01904FF000400290200705D496 -:1091D0000198484502DB4FF0FF30019000208DF8E8 -:1091E0004B0002980DF14B07B0F1004F25D0022043 -:1091F0000C902B200D90029800280CDA404202902F -:109200002D200D9007E00A210298F7F7A9F93031D7 -:10921000029007F8011D0C99481E0C900029F2DC01 -:1092200002980028EFD1791E0D980870307800F070 -:10923000200040F0450007F8020D11A8C01BC01D1A -:1092400002901398007800B1012000EB0901019809 -:1092500001EBE071029801440398401A401E03900C -:10926000E00306D453462146179A039800F05CF8B1 -:1092700005441398007818B15246179990476D1C11 -:10928000E00323D553462146179A039800F04CF883 -:1092900005441BE0BBF1000F07DB0098584504DDD7 -:1092A0001098179910F80B0001E0179930205246DA -:1092B000904701980BF1010B401E05F1010501904B -:1092C00004D12E205246179990476D1CB9F1000128 -:1092D000A9F10109DEDC05E017F8010B52461799E8 -:1092E00090476D1C0299481E02900029F4DC5346F9 -:1092F0002146179A03989EE62D0000002B000000DF -:10930000200000002DE9F041044600251E461746C6 -:10931000880404D405E039462020B0476D1C641E43 -:10932000F9D52846BDE8F0812DE9F0410446002535 -:109330001E469046C80301D5302700E02027880448 -:1093400004D505E041463846B0476D1C641EF9D58A -:109350002846BDE8F0810FB410B5BDF80C10029896 -:10936000F7F746FF012802D110BC5DF814FB00207E -:10937000FAE70FB410B5BDF80C1000220298F7F709 -:1093800049FF10BC5DF814FB0FB410B5BDF80C100C -:1093900001220298F7F73EFF10BC5DF814FB2DE99F -:1093A000FC4704460D4616461F46DDF82880206817 -:1093B0000169D1E90401CDE900012068D0F810C0AD -:1093C000DCF80C904B469CE80700C8472A2120682F -:1093D00000F0F4F9E2892A4491B2206800F017FA0B -:1093E000E2893A4491B2206800F011FA2B212068FA -:1093F00000F0E4F9228A324491B2206800F007FAC2 -:10940000228A424491B2206800F001FA2C2120689F -:1094100000F0D4F9206800F04AF920680169D1E928 -:109420000401CDE900012068D0F810C0DCE9029306 -:109430004A46DCE90001C847BDE8FC878161704706 -:1094400030B500220023002401F478052A0A01F433 -:109450007C456B09C1F3C40442EA030525438582B8 -:1094600030BD2DE9FC4104460D4625722068016996 -:10947000D1E90401CDE9000120680669F7683B469F -:1094800096E80700B8475DB93621206800F096F9E4 -:109490007021206800F0CCF90020E08120822AE0D1 -:1094A000022D0BD13621206800F088F900212068B8 -:1094B00000F0BEF90020E08120821CE0012D0CD1DB -:1094C0003621206800F07AF9A021206800F0B0F978 -:1094D0005020E081002020820DE0032D0BD13621A9 -:1094E000206800F06BF9C021206800F0A1F900208D -:1094F000E08150202082206800F0D9F820680169BE -:10950000D1E90401CDE9000120680669D6E90273BA -:109510003A46D6E90001B847BDE8FC8170B504467B -:109520000D46E561A888142816D004DC0C2807D065 -:10953000102823D10AE0182814D020281ED117E0C3 -:10954000842002590F492046904718E08420025990 -:109550000D492046904712E0842002590B492046CD -:1095600090470CE08420025909492046904706E0C4 -:109570008420025907492046904700E000BF00BF01 -:1095800070BD00002001002014010020080100200F -:10959000FC000020F00000204A68002A06D00A687B -:1095A000531C0B6010704868401E486070472DE9DE -:1095B000FC4105460E4600270DB1012100E00021C7 -:1095C0000846DD21F7F732FA2C460CB1012100E004 -:1095D000002108463621F7F729FAA06960B1A16990 -:1095E000D1E90401CDE90001D4F818C0DCF80C8001 -:1095F00043469CE80700C04700BF284601F088FAB0 -:109600003146284601F0B5FA0746284601F064FACB -:109610003846BDE8FC812DE9FC4705460E46174655 -:109620004FF000080DB1012100E000210846F021B3 -:10963000F7F7FCF92C460CB1012100E000210846A7 -:109640002821F7F7F3F9A06960B1A169D1E9040114 -:10965000CDE90001D4F818C0DCE902934A46DCE900 -:109660000001C84700BF284601F052FA002407E075 -:109670003178284601F07DFA8046761C601C84B261 -:10968000BC42F5DB284601F027FA4046BDE8FC87DE -:109690000A68531C0B60107070470FB410B5BDF80A -:1096A0000C100298F7F7ACFD10BC5DF814FB00BF7E -:1096B000016A0968896801F080010029F8D17047C2 -:1096C00000BF016A0968896801F002010029F8D029 -:1096D00070472DE9FC4104460E4617462068006A93 -:1096E000006800684FF6BF7108402168096A096880 -:1096F00008602068006A0068006840F40060216823 -:10970000096A096808602068006A0068006840F01B -:1097100040002168096A0968086020680169D1E988 -:109720000401CDE900012068D0F810C0DCF80C80FD -:1097300043469CE80700C047002509E036F81500BD -:109740002168096A0968C8602068FFF7B9FF6D1CC5 -:10975000BD42F3D32068FFF7AAFF20680169D1E971 -:109760000401CDE900012068D0F810C0DCE90283D3 -:109770004246DCE90001C0472068006A00680068D2 -:109780004FF6BF7108402168096A096808602068BF -:10979000006A006800684FF2FF7108402168096A9A -:1097A000096808602068006A0068006840F04000AE -:1097B0002168096A09680860BDE8FC812DE9FC415F -:1097C00004460D462046FFF772FFE169D1E9040126 -:1097D000CDE90001E669F7683B4696E80700B8471F -:1097E000206A0068C5602046FFF76AFF2046FFF741 -:1097F0005EFFE169D1E90401CDE90001E669D6E93E -:1098000002733A46D6E90001B847BDE8FC8170B55D -:1098100004460D462812216A0968C8602046FFF7F1 -:109820004FFF206A0068C5602046FFF749FF70BD02 -:1098300070B504460D46206A0068C5602046FFF7F3 -:109840003FFF70BD1CB50548012100238A02CDE908 -:10985000001003A1064802F025F91CBD7C00002081 -:10986000627573696E6573735F7461736B0000007A -:109870008598000810B500F0BBF800F0FDFF01F07E -:10988000C7F810BD00BF01F07DF800F039F90020E5 -:1098900000F000FA4FF47A7001F0B2FBF3E7F0B594 -:1098A00003460024012901D0022904D101F10C0052 -:1098B000C1B2581E83B24D1C05EB4505052695FB2C -:1098C000F6F5022606FB012635441D441846DE1730 -:1098D00003EB967605EBA605642693FBF6F6AD1B27 -:1098E0004FF4C87693FBF6F63544072695FBF6F75A -:1098F00006FB1755ECB2601CC0B2F0BD2DE9F0417B -:1099000005460E4618273946002000F0F1FA0446B5 -:109910000CB1012100E0002108463621F7F786F856 -:109920002560A6800548A0600548E06005482061E4 -:10993000054860612046BDE8F08100008993000879 -:10994000739300089B9600085793000800BFEFF33D -:10995000058008B1012070470020FCE70FB470B506 -:1099600098252946002000F0C3FA04460CB10121D5 -:1099700000E0002108461C21F7F758F8204604A90A -:10998000382203E011F8013B00F8013B131EA2F15D -:109990000105AAB2F6D100BF012184F8941002207B -:1099A00020B1012803D0022807D101E00CE00BE030 -:1099B00004F1380000F03EF906E0204600F007F818 -:1099C000002070BC5DF814FB00BF2046F9E710B51D -:1099D00004460CB1012100E0002108461421F7F7EC -:1099E00025F800BF2146002000F058FA00BF10BD46 -:1099F00030B5ADB04FF400613D48FFF77FFF2990CF -:109A00004FF480513A48FFF779FF2C9038223949BA -:109A100018A8F6F768FC0020049029A80FC88DE864 -:109A20000F00012026A90EC901F014F8189018980B -:109A30003149C26A9047232218A90AA8F6F753FCB5 -:109A40009DF883008DF84B00142221A913A8F6F786 -:109A50004AFC28220EA96846F6F745FC0AA80FC85A -:109A6000FFF77CFF25490861096909B1012100E080 -:109A7000002108464FF48771F6F7D8FF1F480069A8 -:109A80000068C169D1E90401CDE900011B48006902 -:109A90000068C469194800690068C069856894E86D -:109AA0000F00A8471548006900680169D1E9040161 -:109AB000CDE9000111480069006804690F48006998 -:109AC00000680069856894E80F00A84700224FF4F9 -:109AD00000510748F7F79EFB084A10691269916B1D -:109AE0008847012251030248F7F794FB2DB030BD9F -:109AF000000C0240ECBF0008EC050020C043002031 -:109B000030B5A5B0802105A8F6F706FC33490869F1 -:109B10000969D1F8882032499047304908690969B4 -:109B2000CA6E002190472D49086909690A6E6FF0D5 -:109B30007F41904746242949086909690A6E2949E5 -:109B4000904726490869096927A322468D6E0D2191 -:109B5000A8472249086909690A6E274990471F49A1 -:109B60000969C969C98821448AB21C490869096917 -:109B700022A38D6E0D21A8471849086909690A6E4C -:109B800023499047154908690969D1F8842021497A -:109B900090471248007B1149C97A104A927A0F4BBC -:109BA000DB79CDE90032CDE902100C488379808859 -:109BB00000F5FA6218A105A8FEF7FCFB0749096940 -:109BC000C969C98804EB41018AB204490869096975 -:109BD00005AB8D6E0D21A84725B030BDC0430020D8 -:109BE000D8000020FF80800053544D33322052545F -:109BF00043B2E2CAD400000080FFFF00C6C1C4BB6C -:109C0000B7D6B1E6C2CA3A3234302A323430000014 -:109C10008080FF000801002025642D253032642D4E -:109C20002530326420253032643A253032643A25BA -:109C30003032640010B504460CB1012100E000216F -:109C4000084640F2AF11F6F7F1FE094820600948D6 -:109C500060620948A0620948A0630948E0640948B5 -:109C60002065094820630948E0630948606310BD26 -:109C7000B189000863940008419400089F9300088C -:109C80003D9400081D9500085D8700086784000862 -:109C90002D89000810B504462CB94FF40051034833 -:109CA000F7F7AEFA00E000BF00BF10BD00080240A9 -:109CB000F7F7C8FAFBF79AFCFAF702F9FAF7BAF8DD -:109CC000FAF716FAFAF72EFAFAF7D8F8FAF74EFA80 -:109CD000FAF72AFA002000F04BF8012000F048F8CB -:109CE000FFF7C8FDFFF7AEFDFAF7D6F800F033F93D -:109CF00000BFFEE701460020842901D0CA1C1044A1 -:109D0000704700002DE9F04104460E461548005DFD -:109D100038B9144818380168204688470120BDE842 -:109D2000F081114850F82400B04219D90F4850F87A -:109D30002400B6FBF0F70B48083850F8240030F840 -:109D40001780002508E000210648083850F8240054 -:109D50007A1920F812106D1C4545F4DB0020DEE76F -:109D60000120DCE7A00000204CC0000844C000082F -:109D700010B504460C4951F824104A000B4951F81B -:109D80002400002100F0C8F8094951F824200749AF -:109D9000083951F82400002100F0BEF801210348E1 -:109DA0000830015510BD00003CC00008980000209C -:109DB0004CC000082DE9F04704460F460025A9468F -:109DC0002348005D20B9224818380168204688479A -:109DD0001FB94FF0FF30BDE8F0871E4850F824004F -:109DE000B7FBF0F61B4850F82400B7FBF0F100FB7E -:109DF000117000B1761C184850F82400451E22E06E -:109E00001348083850F8240030F8150010B909F14B -:109E1000010901E04FF00009B14513D14FF00008EE -:109E200009E00B48083850F8240005EB080220F838 -:109E3000126008F10108B045F3D3064850F8240039 -:109E40006843C8E76D1E002DDADA4FF0FF30C2E735 -:109E5000A000002044C000083CC0000810B5014626 -:109E60000023002207E00B4850F8210030F81200D0 -:109E700000B15B1C521C084850F821009042F2D8F7 -:109E800064205843044C54F82140B0FBF4F0C0B2B5 -:109E900010BD0000980000203CC000082DE9F041F2 -:109EA00004460D460DB9BDE8F0810F4850F8240076 -:109EB0002E1A0E4850F82400B6FBF0F10A4808307C -:109EC00050F8240030F81100084951F8241000FB24 -:109ED00001F73A460021284600F01EF83146204698 -:109EE000FFF710FF00BFDEE79000002044C000082D -:109EF00070B504460E4631462046FFF75BFF054627 -:109F0000681C08B9002070BD024850F8240028449D -:109F1000F9E700009000002030B5034601E003F8A7 -:109F2000011B141EA2F10102F9D130BD70B5044627 -:109F300025460DB1294600E00121084601F060F8F0 -:109F4000002070BD10B501F03DFE012801D10020B8 -:109F500010BD0120FCE710B501F0AEF8002010BDE7 -:109F600010B5FFF7F3FC10B101F042FE10BD01F097 -:109F700039FEFBE7F8B504460D46A06840B1E0683D -:109F800030B10020009094E80F0001F01CFAF8BDF9 -:109F90000022D4E9000101F0E9F9F8E72DE9FF41D9 -:109FA00007460D4614460295002001903DB98020D9 -:109FB00000909DE8070087E80700BDE8FF810020CA -:109FC00003900026601C08B9761E03E014B12646F3 -:109FD00006B90126FFF7BAFCB0B103AA01A92846C9 -:109FE00001F0B4FC012802D11020009001E0002013 -:109FF00000900398B8B14FF080500E490860BFF34D -:10A000004F8FBFF36F8F0EE0324601A9284601F053 -:10A01000E9FB012802D11020009004E00EB90020D5 -:10A0200000E0402000909DE8070087E8070000BF9F -:10A03000C3E7000004ED00E077B581B006461446A2 -:10A0400000200090254605B90125FFF77FFCA8B147 -:10A0500000236A4602A9304601F046FB012802D0DF -:10A06000FF2004B070BD009890B14FF080500949B6 -:10A070000860BFF34F8FBFF36F8F09E000232A46BC -:10A0800002A9304601F05CFA012801D0FF20E8E780 -:10A090000020E6E704ED00E07FB504460D46606968 -:10A0A00098B1A06988B1B4F90800FFF723FE06460D -:10A0B000D4E90510CDE9006102902B462269D4E96C -:10A0C000001001F021FD039013E0B4F90800FFF740 -:10A0D00011FE064603A8CDE90060238A9AB22B46FA -:10A0E000D4E9001001F0DEFC012802D0002004B009 -:10A0F00070BD0398FBE700002DE9F04105460E46D0 -:10A100001C4807681C480068001D00F039FE50B963 -:10A110001948006890F82C100120884017490968F8 -:10A12000814316480160681C38B936B1124801688D -:10A13000091D134800F06EFE1AE07C190E480068F5 -:10A140004460BC4207D20C480168091D0D480068F4 -:10A1500000F046FE0CE008480168091D0A48006846 -:10A1600000F03EFE09480068844201D207480460BE -:10A17000BDE8F08128000020140000202C00002001 -:10A18000AC0700201C000020180000204400002024 -:10A1900010B5044600F04AFE23480068401C2249DE -:10A1A00008602248006840B92048046008460068FA -:10A1B00001280DD100F0A6F90AE01D48006838B961 -:10A1C0001A480068C06AE16A884201D817480460EA -:10A1D00018480068401C1749086094F82C100120AA -:10A1E000884015490968084313490860E16A01EB92 -:10A1F0008101124A02EB8100211D00F00BFE00F0EC -:10A200003FFE0B48006868B108480068C06AE16A10 -:10A21000884207D24FF0805009490860BFF34F8F42 -:10A22000BFF36F8F10BD0000240000201400002039 -:10A2300030000020400000202C000020D00600202C -:10A2400004ED00E010B516E000F0F0FD0C48C06829 -:10A25000C468201D00F094FD0A480068401E0949AA -:10A26000086009480068401E0749086000F008FEC1 -:10A27000204600F05FF8044800680028E4D110BDD3 -:10A2800098070020240000202000002070B504461C -:10A290000D46206C70B1216CE0680144E160D4E9A6 -:10A2A0000210884201D32168E1602846226CE168EF -:10A2B000F6F719F870BD2DE9F04104460F46154632 -:10A2C0004FF00008A66B206C48B9206800282CD1FC -:10A2D000A06801F03BFD80460020A06025E07DB92C -:10A2E0003946226C6068F5F7FEFF216C606808440F -:10A2F0006060D4E90101884217D32068606014E0EF -:10A300003946226CE068F5F7EEFF216CE068411AEF -:10A31000E1602168E068884203D2216CA068411A9C -:10A32000E160022D01D106B1761E701CA06340468B -:10A33000BDE8F08110B5044694F8510030B9206BA7 -:10A3400000F0BCFD204600F0B9FD1AE094F8510081 -:10A35000012803D1204600F0B1FD12E094F851002D -:10A36000022801D1012000E0002050B900BF502098 -:10A3700080F31188BFF34F8FBFF36F8F00BF00BF13 -:10A38000FEE710BD30B54FF47053174800F00704D6 -:10A390002CB1C01D20F00700134C041B1B1B0246F0 -:10A3A000124C22600024114D6C60D018083820F047 -:10A3B00007000F4C206000240D4D2D686C600C4D83 -:10A3C0002D682C601146441A4C60094C24680C60BE -:10A3D000084D4C682C60084D4C682C604FF00044D0 -:10A3E000064D2C6030BD0000C0070020500000204A -:10A3F00058000020600000205C0000206C0000205D -:10A4000000BFFFF71FFF064800680128F9D94FF089 -:10A41000805004490860BFF34F8FBFF36F8FF0E7A0 -:10A42000D006002004ED00E02DE9F04106460D467F -:10A4300017469846069C0DB9246000E02760E66345 -:10A4400025640121204601F02FF8BDE8F0812DE9B7 -:10A45000FF5F81460E469246DDE90E7B109CAAF115 -:10A460000100216B01EB800828F0070808F00700C5 -:10A4700008B9012000E0002050B900BF502080F34F -:10A480001188BFF34F8FBFF36F8F00BF00BFFEE790 -:10A4900086B1002507E0715D04F134004155705D1F -:10A4A00000B902E06D1C102DF5D300BF0021432040 -:10A4B000015502E0002084F83400072F00D306275E -:10A4C000E76267640020A064201D00F086FC04F1B0 -:10A4D000180000F082FC2461C7F10700A0616462EB -:10A4E0000020E06484F8500049464046039A00F09A -:10A4F000ADF92060BBF1000F01D0CBF80040BDE802 -:10A50000FF9F000010B5002407E004EB84010F4A10 -:10A5100002EB810000F054FC641C072CF5D30C48BE -:10A5200000F04EFC0B4800F04BFC0B4800F048FCE0 -:10A530000A4800F045FC0A4800F042FC044809497A -:10A54000086004480849086010BD0000D0060020DB -:10A550005C07002070070020840700209807002077 -:10A56000AC070020180000201C00002010B5014698 -:10A57000164800E0006803688B42FBD3024643683C -:10A5800013448B4204D143684C6823444360014622 -:10A590000A464B6813440468A34211D10C4C03686B -:10A5A0002468A34208D04B680468646823444B6065 -:10A5B00003681B680B6005E0054B1B680B6001E03E -:10A5C00003680B60884200D0016010BD500000207D -:10A5D0005800002070B5054600F028FCA86B08B9AB -:10A5E000012400E0002400F04BFC204670BD70B553 -:10A5F000054600F01BFCA86BE96B884201D10124E1 -:10A6000000E0002400F03CFC204670BD0A490968C7 -:10A61000096809B9012100E0002121B14FF0FF31A3 -:10A62000064A116006E004490968C968C868034A17 -:10A6300041681160704700001800002044000020AD -:10A640000E480068401C08B9012000E0002050B905 -:10A6500000BF502080F31188BFF34F8FBFF36F8F7F -:10A6600000BF00BFFEE700BF502080F31188BFF39A -:10A670004F8FBFF36F8F00BF00BFFEE77000002059 -:10A6800070B5044600F0D2FB94F9455010E0606AC2 -:10A6900008B9012000E0002038B904F1240001F0DD -:10A6A000B9FB18B100F0E6FC00E003E0681E45B21B -:10A6B000002DECDC00BFFF2084F8450000F0E0FB3B -:10A6C00000F0B4FB94F9445010E0206908B901206F -:10A6D00000E0002048B904F1100001F09BFB08B134 -:10A6E00000F0C8FC681E45B200E001E0002DECDC83 -:10A6F00000BFFF2084F8440000F0C2FB70BD0000E2 -:10A700002DE9F04104464FF0000800F02DFD4948C6 -:10A71000006808B9FFF736FE474800682040002867 -:10A7200070D1D4B1083404F00700B0B104F00700D0 -:10A73000C0F10800044404F0070008B9012000E05B -:10A74000002050B900BF502080F31188BFF34F8F15 -:10A75000BFF36F8F00BF00BFFEE7002C52D0374819 -:10A76000006884424ED8364E3046056801E02E46D9 -:10A770002D686868A04202D228680028F7D12D48C9 -:10A78000006885423ED0306800F1080828683060D3 -:10A790006868001B102819D92F1907F0070008B99D -:10A7A000012000E0002050B900BF502080F3118844 -:10A7B000BFF34F8FBFF36F8F00BF00BFFEE7686826 -:10A7C000001B78606C603846FFF7D0FE1B49686854 -:10A7D0000968081A19490860084600681949096893 -:10A7E000884203D215480068164908601249686813 -:10A7F0000968084368600020286013480068401C0E -:10A800001149086001F052FB08F0070008B9012067 -:10A8100000E0002050B900BF502080F31188BFF342 -:10A820004F8FBFF36F8F00BF00BFFEE74046BDE80C -:10A83000F0810000580000206C0000205C00002027 -:10A84000500000206000002064000020001F4FF036 -:10A8500080730360001F21F001030360001F054B9C -:10A86000036014380260001F6FF002030360203899 -:10A870007047000041A600083EB50024002000F00B -:10A8800035F884B245F2500084422CD0401C8442FA -:10A8900029D01920ADF8040001208DF806008DF8AC -:10A8A00007009DF807209DF80610BDF8043003F559 -:10A8B000FA6398B2FEF7F3FF8DF8080000208DF8D8 -:10A8C00000008DF801008DF802000021009800F0D2 -:10A8D00037F8DDE9010100F013F845F251010020DD -:10A8E00000F07AF800BF01203EBD000001460022C2 -:10A8F000024800EB810210687047000050280040B9 -:10A9000003B581B09DF806008DF801009DF80700A1 -:10A910008DF80200BDF80400C0B28DF803009DF868 -:10A9200008008DF80000002269460448F8F7D0F9C5 -:10A9300008B901200EBD0020FCE7000088040020BB -:10A9400013B586B00C469DF818008DF804009DF8EC -:10A9500019008DF805009DF81A008DF806008DF895 -:10A960000740002004900590002201A90448F8F750 -:10A970000FFA10B9012008B010BD0020FBE700005D -:10A980008804002000B587B0002201A91048F8F71C -:10A9900001F9002206A90E48F8F7D6F89DF8040040 -:10A9A0000C4988729DF805100A48C1729DF806107E -:10A9B00001739DF8181001729DF8191081719DF8AE -:10A9C0001A10C1719DF81B000249888007B000BDB4 -:10A9D00088040020C043002070B504460D46F7F7F8 -:10A9E0001BFC2A4621460248F8F7A4F870BD000077 -:10A9F0008804002010B588B069460448F8F7A6FB23 -:10AA000004460CB108B010BD00BFFBE7D4430020E2 -:10AA100010B50E480E4908600020486000210C481F -:10AA20008160C1600161416104218161F8F7B3FB7C -:10AA300008B1F6F79BF84FF400610548F8F73CFAC7 -:10AA400008B1F6F793F8FFF7D5FF10BD002C0140D1 -:10AA5000D44300200FB42DE9F04105460E9F022D8E -:10AA600001DA012100E0002108464FF48771F5F773 -:10AA7000DDFF342631460020FFF73AFA044600BFD6 -:10AA8000201D07A91C2203E011F8013B00F8013B3F -:10AA9000131EA2F10106B2B2F6D100BF278084F8DE -:10AAA00030500A49E1625DB1012D04D1084860626D -:10AAB0000849A16204E040F21F110020F5F7B6FF3B -:10AAC0002046BDE8F0015DF814FB00006D89000828 -:10AAD000AF950008179600087CB504460CB101211B -:10AAE00000E0002108464421F5F7A0FF206970B17D -:10AAF0002169D1E90401CDE900012569D5E90263A5 -:10AB00003246D5E90001B047204600F01CF87CBD74 -:10AB10007CB504460CB1012100E000210846532118 -:10AB2000F5F784FF206968B12169D1E90401CDE915 -:10AB300000012569EE68334695E80700B0472046D6 -:10AB400000F001F87CBD70B5044600250CB1012170 -:10AB500000E0002108460D21F5F768FF2588002D4B -:10AB600006DD00E000BF281EA5F101018DB2F9D17C -:10AB700070BD2DE9F34182B00446FF270CB10121DD -:10AB800000E000210846A921F5F750FF94F83100B4 -:10AB900001287ED100269AE025460DB1012100E072 -:10ABA000002108468C21F5F741FFE86860B1E968AB -:10ABB000D1E90401CDE90001D5F80CC0DCF80C8026 -:10ABC00043469CE80700C04700BF2046FFF7BBFF95 -:10ABD0009DF80C0000F08000C8B125460DB10121A0 -:10ABE00000E0002108466221F5F720FF686860B1A7 -:10ABF0006968D1E90401CDE90001D5F804C0DCE9B8 -:10AC000002834246DCE90001C04700BF19E0254647 -:10AC10000DB1012100E0002108467021F5F706FF83 -:10AC2000686860B16968D1E90401CDE90001D5F82F -:10AC300004C0DCF80C8043469CE80700C04700BF16 -:10AC400000BF2046FFF77FFF25460DB1012100E040 -:10AC5000002108467E21F5F7E9FEE86860B1E96861 -:10AC6000D1E90401CDE90001D5F80CC0DCE902838B -:10AC70004246DCE90001C04700BF2046FFF763FF02 -:10AC80009DF80C004006000E03907806070EA068A1 -:10AC900000E023E00068C0B125460DB1012100E0CD -:10ACA000002108469A21F5F7C1FEA968D1E90401FF -:10ACB000CDE90001D5F808C0DCF814809CE80F004D -:10ACC000C047012801D1781CC7B2701CC6B2082E3B -:10ACD000FFF662AF384604B0BDE8F0810020019075 -:10ACE0004FF4FA600090012301AA03A9206AF8F743 -:10ACF00087FD08B1FF20EEE79DF80400EBE70000B8 -:10AD00000FB4F8B507A800904FF400611348009BFA -:10AD1000069AFDF763FB05460020009003261048C5 -:10AD200090F89C02032812D10D48D0F8BC72F6F7B7 -:10AD300077FA044605E0F6F773FA001BB04200D933 -:10AD400003E0D7F814020028F5D100BF00BFA9B274 -:10AD50000248F5F74FFEF8BC5DF814FB4C010120EA -:10AD600070F4002070B505460C46214601A0FFF79F -:10AD7000C7FF70BD6C656E203D2025640D0A000084 -:10AD800001460A69D1E901309860D1E901035860B0 -:10AD90005068884201D188685060002008611068BE -:10ADA000401E106010687047034B0360034B0B603C -:10ADB00080231360704700003402002088020020C6 -:10ADC00000F1080141604FF0FF31816000F108019E -:10ADD000C16001610021016070470021016170477D -:10ADE00010B502460B685C1C0CB9106907E002F153 -:10ADF000080000E04068446824689C42FAD944682E -:10AE00004C604C68A160886041600A611468641CF1 -:10AE1000146010BD42684A6093688B609368596003 -:10AE20009160086103685B1C0360704700BF50209D -:10AE300080F31188BFF34F8FBFF36F8F00BF0E48B1 -:10AE40000068401C0C49086008460068012812D1BF -:10AE50000A480068C0B208B9012000E0002050B9DB -:10AE600000BF502080F31188BFF34F8FBFF36F8F67 -:10AE700000BF00BFFEE770477000002004ED00E057 -:10AE80000D48006850B900BF502080F31188BFF30F -:10AE90004F8FBFF36F8F00BF00BFFEE7064800680B -:10AEA000401E054908600846006820B9002080F36C -:10AEB000118800BF00BF70477000002070B50646C3 -:10AEC0003546002E44D0083D2C462249606809686A -:10AED000084008B1012000E0002050B900BF502018 -:10AEE00080F31188BFF34F8FBFF36F8F00BF00BF98 -:10AEF000FEE7206808B9012000E0002050B900BF3B -:10AF0000502080F31188BFF34F8FBFF36F8F00BFC6 -:10AF100000BFFEE70F49606809680840C0B12068BB -:10AF2000B0B90C49606809688843606000F01CF99A -:10AF30000949606809680844074908602046FFF726 -:10AF400015FB06480068401C0449086000F0AEFF8D -:10AF500070BD00006C0000205C0000206800002034 -:10AF600000204FF0E02108618861064800684FF436 -:10AF70007A71B0FBF1F0401E4FF0E02148610720EC -:10AF8000086170471000002070B5F5F765F90446B8 -:10AF9000102C16D304F1E02090F8F05315480078F7 -:10AFA000854201DB012000E0002050B900BF5020A5 -:10AFB00080F31188BFF34F8FBFF36F8F00BF00BFC7 -:10AFC000FEE70D48006800F4E0600C49096888421B -:10AFD00001D8012000E0002050B900BF502080F3CC -:10AFE0001188BFF34F8FBFF36F8F00BF00BFFEE725 -:10AFF00070BD0000740000200CED00E0780000201F -:10B0000070B504460025D4B11248006808B9012083 -:10B0100000E0002050B900BF502080F31188BFF33A -:10B020004F8FBFF36F8F00BF00BFFEE700F09CF8AB -:10B0300000212046FFF760F800F038FF05463DB9D3 -:10B040004FF0805004490860BFF34F8FBFF36F8FFC -:10B0500070BD00004C00002004ED00E003490968C9 -:10B060000160034909684160704700003C0000200E -:10B0700028000020012001490860704738000020A6 -:10B0800070B504460D4654B900BF502080F31188B6 -:10B09000BFF34F8FBFF36F8F00BF00BFFEE70548C0 -:10B0A000016818312046FFF79BFE01212846FFF773 -:10B0B00023F870BD1400002010B586B00020059064 -:10B0C000049003AA04A905A8FFF76EFE0022DDE99B -:10B0D00004101346CDE9002102901CA11D48039ADB -:10B0E00000F012FD1C4908600846006808B1012400 -:10B0F00000E00024012C15D100BF502080F31188FE -:10B10000BFF34F8FBFF36F8F00BF4FF0FF30134976 -:10B11000086001201249086000201249086000F010 -:10B1200071F810E0601C08B1012000E0002050B967 -:10B1300000BF502080F31188BFF34F8FBFF36F8F94 -:10B1400000BF00BFFEE706B010BD000049444C45FB -:10B150000000000001A40008480000204400002076 -:10B16000300000202800002002480068401C0149EF -:10B17000086070474C0000201D48006818B101208D -:10B180001C49086032E000201A4908601A4800682B -:10B19000B0FA80F0C0F11F0101EB8100174A52F8AC -:10B1A000200008B1012000E0002050B900BF50206D -:10B1B00080F31188BFF34F8FBFF36F8F00BF00BFC5 -:10B1C000FEE701EB81020D4B03EB820042685268FF -:10B1D000426000F108024368934202D1426852681B -:10B1E00042604268D268064B1A6000BF7047000098 -:10B1F0004C000020380000202C000020D006002049 -:10B20000140000201CB5524800685249884201D001 -:10B21000012000E0002050B900BF502080F31188C9 -:10B22000BFF34F8FBFF36F8F00BF00BFFEE74848EB -:10B2300000684849491E884201D0012000E00020F2 -:10B2400050B900BF502080F31188BFF34F8FBFF378 -:10B250006F8F00BF00BFFEE73F49084600780190AE -:10B26000FF200A4610700846007800909DF8000004 -:10B2700000F0F0009DF80020904201D1012000E094 -:10B28000002050B900BF502080F31188BFF34F8FCA -:10B29000BFF36F8F00BF00BFFEE79DF8000000F016 -:10B2A00050002E4A107007202D4A106009E02C48EB -:10B2B0000068401E2A4A10609DF800004006000EFB -:10B2C00000909DF8000000F080008028EFD0244816 -:10B2D0000068C0F10700042801D1012000E000202F -:10B2E00050B900BF502080F31188BFF34F8FBFF3D8 -:10B2F0006F8F00BF00BFFEE7194800680002184AC0 -:10B3000010601046008800F4E0601060124A019856 -:10B3100010700F482030006840F470000C49203154 -:10B3200008600846006840F070400860FFF718FEAB -:10B3300000200C490860F4F757FF0B48006840F004 -:10B34000404009490860F4F73BFF00201CBD0000A5 -:10B3500000ED00E071C20F4100E400E07400002045 -:10B36000780000207000002034EF00E02DE9F84361 -:10B3700005460E4617460DB1012000E0002050B9E9 -:10B3800000BF502080F31188BFF34F8FBFF36F8F42 -:10B3900000BF00BFFEE705FB06F808F14800FFF715 -:10B3A000AFF9044664B1A14609F14809002084F8C8 -:10B3B00046003B464A46314628460094FFF734F89B -:10B3C0002046BDE8F8832DE9F84380460E4617462F -:10B3D0001D46DDF82090B8F1000F01D0012000E0FB -:10B3E000002050B900BF502080F31188BFF34F8F69 -:10B3F000BFF36F8F00BF00BFFEE70DB1012000E07B -:10B40000002050B900BF502080F31188BFF34F8F48 -:10B41000BFF36F8F00BF00BFFEE707B10EB1012081 -:10B4200000E0002050B900BF502080F31188BFF326 -:10B430004F8FBFF36F8F00BF00BFFEE707B90EB994 -:10B44000012000E0002050B900BF502080F3118897 -:10B45000BFF34F8FBFF36F8F00BF00BFFEE74820E1 -:10B4600000900098482801D1012000E0002050B948 -:10B4700000BF502080F31188BFF34F8FBFF36F8F51 -:10B4800000BF00BFFEE700BF2C464CB1012084F88E -:10B4900046004B463A46314640460094FEF7C4FF0C -:10B4A0002046BDE8F883000070B505460E462C46E0 -:10B4B00054B900BF502080F31188BFF34F8FBFF302 -:10B4C0006F8F00BF00BFFEE7FFF7B0FCD4E90F129B -:10B4D000206801FB0200A0600020A063206860607B -:10B4E000E06B401E226C216800FB0211E160FF202E -:10B4F00084F8440084F845009EB9206908B9012009 -:10B5000000E00020A8B904F1100000F083FC80B135 -:10B510004FF0805009490860BFF34F8FBFF36F8F22 -:10B5200007E004F11000FFF74BFC04F12400FFF7E3 -:10B5300047FCFFF7A5FC012070BD000004ED00E012 -:10B540002DE9FF4383B0064688461D464FF00009AB -:10B55000344654B900BF502080F31188BFF34F8F99 -:10B56000BFF36F8F00BF00BFFEE7B8F1000F01D13E -:10B57000206C08B9012000E0002050B900BF502025 -:10B5800080F31188BFF34F8FBFF36F8F00BF00BFF1 -:10B59000FEE7022D02D1E06B012801D1012000E07D -:10B5A000002050B900BF502080F31188BFF34F8FA7 -:10B5B000BFF36F8F00BF00BFFEE700F003FB08B9C9 -:10B5C000059808B9012000E0002050B900BF5020C4 -:10B5D00080F31188BFF34F8FBFF36F8F00BF00BFA1 -:10B5E000FEE700BFFFF722FCA06BE16B884201D3AE -:10B5F000022D28D12A4641462046FEF75CFE07462A -:10B60000606A08B9012000E0002068B904F1240054 -:10B6100000F000FC88B14FF0805032490860BFF361 -:10B620004F8FBFF36F8F08E03FB14FF080502D492F -:10B630000860BFF34F8FBFF36F8FFFF721FC01202E -:10B6400007B0BDE8F083059818B9FFF719FC002092 -:10B65000F6E7B9F1000F04D101A8FFF7FFFC4FF0A6 -:10B660000109FFF70DFCFFF77FFDFFF7DFFB94F902 -:10B670004400401C10B9002084F8440094F94500AF -:10B68000401C10B9002084F84500FFF7F9FB05A91C -:10B6900001A800F0C1F9F0B92046FEF7A8FFA0B15B -:10B6A00004F110000599FFF7EBFC2046FEF7E8FFD8 -:10B6B00000F0FCFB002895D14FF08050094908604C -:10B6C000BFF34F8FBFF36F8F8CE72046FEF7D8FF95 -:10B6D00000F0ECFB86E72046FEF7D2FF00F0E6FB29 -:10B6E0000020ADE704ED00E02DE9F84F07468A465B -:10B6F00090461E463C4654B900BF502080F3118846 -:10B70000BFF34F8FBFF36F8F00BF00BFFEE7BAF1EB -:10B71000000F01D1206C08B9012000E0002050B9D1 -:10B7200000BF502080F31188BFF34F8FBFF36F8F9E -:10B7300000BF00BFFEE7022E02D1E06B012801D15D -:10B74000012000E0002050B900BF502080F3118894 -:10B75000BFF34F8FBFF36F8F00BF00BFFEE7FFF750 -:10B7600013FC00BF5021EFF3118081F31188BFF368 -:10B770004F8FBFF36F8F00BF0546A06BE16B884210 -:10B7800001D3022E25D194F945B0A06B009032462A -:10B7900051462046FEF78FFD0BF1010088B9606A23 -:10B7A00008B9012000E0002050B904F1240000F0A5 -:10B7B00031FB28B1B8F1000F02D00120C8F8000019 -:10B7C00004E00BF1010040B284F845004FF001099C -:10B7D00001E04FF0000900BF85F3118800BF484623 -:10B7E000BDE8F88F2DE9F74183B005460E464FF0CE -:10B7F00000082C4654B900BF502080F31188BFF3D5 -:10B800004F8FBFF36F8F00BF00BFFEE70EB9206CF4 -:10B8100008B9012000E0002050B900BF502080F39B -:10B820001188BFF34F8FBFF36F8F00BF00BFFEE7DC -:10B8300000F0C8F908B9059808B9012000E0002017 -:10B8400050B900BF502080F31188BFF34F8FBFF372 -:10B850006F8F00BF00BFFEE700BFFFF7E7FAA76BDF -:10B86000F7B131462046FEF711FD781EA06320692E -:10B8700008B9012000E0002060B904F1100000F0D8 -:10B88000C9FA38B14FF080502F490860BFF34F8F8D -:10B89000BFF36F8FFFF7F4FA012006B0BDE8F08127 -:10B8A000059818B9FFF7ECFA0020F6E7B8F1000F99 -:10B8B00004D101A8FFF7D2FB4FF00108FFF7E0FA2F -:10B8C000FFF752FCFFF7B2FA94F94400401C10B99C -:10B8D000002084F8440094F94500401C10B9002071 -:10B8E00084F84500FFF7CCFA05A901A800F094F808 -:10B8F000F0B92046FEF76EFEA0B104F124000599D0 -:10B90000FFF7BEFB2046FEF7BBFE00F0CFFA002893 -:10B91000A3D14FF080500C490860BFF34F8FBFF3A5 -:10B920006F8F9AE72046FEF7ABFE00F0BFFA94E770 -:10B930002046FEF7A5FE00F0B9FA2046FEF74AFEC3 -:10B9400000288AD00020A8E704ED00E02DE9F05F90 -:10B95000064689461746344654B900BF502080F346 -:10B960001188BFF34F8FBFF36F8F00BF00BFFEE79B -:10B97000B9F1000F01D1206C08B9012000E00020CE -:10B9800050B900BF502080F31188BFF34F8FBFF331 -:10B990006F8F00BF00BFFEE7FFF7F6FA00BF502130 -:10B9A000EFF3118081F31188BFF34F8FBFF36F8FD7 -:10B9B00000BF0546D4F838A0BAF1000F22D094F9A0 -:10B9C00044B049462046FEF761FCAAF10100A0639D -:10B9D0000BF1010070B9206908B9012000E00020D6 -:10B9E00068B904F1100000F015FA40B13FB1012030 -:10B9F000386004E00BF1010040B284F844004FF0DD -:10BA0000010801E04FF0000800BF85F3118800BF76 -:10BA10004046BDE8F09F000070B505460C4655B99C -:10BA200000BF502080F31188BFF34F8FBFF36F8F9B -:10BA300000BF00BFFEE754B900BF502080F311885B -:10BA4000BFF34F8FBFF36F8F00BF00BFFEE7FFF75D -:10BA5000EDF9124802686868131A2068401C08B99A -:10BA6000002617E00E4928680968884204D06868F3 -:10BA7000904201D801260DE02068984207D920683D -:10BA8000C01A20602846FFF7E9FA002602E00020ED -:10BA900020600126FFF7F4F9304670BD2800002031 -:10BAA0003C0000202DE9FF4F85B0804689461746AF -:10BAB000DDE912ABB800FEF723FE064656B154206E -:10BAC000FEF71EFE04460CB1266304E03046FFF785 -:10BAD000F5F900E000248CB1002084F85100CDE994 -:10BAE00000ABCDE902403A4649464046089BFEF786 -:10BAF000AEFC2046FEF74CFB012501E04FF0FF3580 -:10BB0000284609B0BDE8F08F2DE9F04F85B0074613 -:10BB1000884691469A46DDE90EB6109C0EB101208A -:10BB200000E0002050B900BF502080F31188BFF31F -:10BB30004F8FBFF36F8F00BF00BFFEE70CB1012036 -:10BB400000E0002050B900BF502080F31188BFF3FF -:10BB50004F8FBFF36F8F00BF00BFFEE754200390ED -:10BB60000398542801D1012000E0002050B900BF03 -:10BB7000502080F31188BFF34F8FBFF36F8F00BF4A -:10BB800000BFFEE700BFB4B1AEB125462C462E6320 -:10BB9000022085F85100002004A953464A46CDE909 -:10BBA00000B1CDE9025041463846FEF750FC284628 -:10BBB000FEF7EEFA01E000200490049805B0BDE81D -:10BBC000F08F00000549096809B9012005E0044922 -:10BBD000096809B9022000E0002070473000002009 -:10BBE0004C00002001490868704700002800002030 -:10BBF00070B5FFF7C9F9002501480468204670BDFB -:10BC0000280000202DE9F0414FF00008444800686A -:10BC100000287CD143480068451C4248056015BB9C -:10BC200041480068006808B9012000E0002050B9D0 -:10BC300000BF502080F31188BFF34F8FBFF36F8F89 -:10BC400000BF00BFFEE7384807683848006836493B -:10BC500008603648076036480068401C3449086070 -:10BC6000FEF7D4FC00BF3348006885423CD300BFD8 -:10BC70002D480068006808B9012000E0002020B1CC -:10BC80004FF0FF302B4908602DE027480068C0685E -:10BC9000C4686668B54202D22648066023E0201DCB -:10BCA000FFF76EF8A06A18B104F11800FFF768F802 -:10BCB00094F82C10012088401F49096808431E4948 -:10BCC0000860E16A01EB81011C4A02EB8100211D41 -:10BCD000FFF7A0F81A49E06A0968C96A8842C7D321 -:10BCE0004FF00108C4E700BF15480068C06A00EBC8 -:10BCF0008000124951F82000012801D94FF00108B5 -:10BD00001048006808B14FF0010805E0FFE70E4851 -:10BD10000068401C0C4908604046BDE8F081000006 -:10BD20004C00002028000020180000201C000020EB -:10BD30003C000020440000202C000020D006002001 -:10BD400014000020380000203400002070B50546A3 -:10BD50002C460026002D55D02B480068844201D186 -:10BD6000012000E0002050B900BF502080F311886E -:10BD7000BFF34F8FBFF36F8F00BF00BFFEE7A06C14 -:10BD800050B900BF502080F31188BFF34F8FBFF32D -:10BD90006F8F00BF00BFFEE7A06C401EA064616C07 -:10BDA000E06A88422ED0A06C60BB201DFEF7E8FF41 -:10BDB00078B9E06A00EB8000144951F8200040B9DE -:10BDC00094F82C10012088401149096881431048DB -:10BDD0000160606CE062E06AC0F10700A06194F865 -:10BDE0002C10012088400A49096808430849086066 -:10BDF000E16A01EB8101054A02EB8100211DFFF799 -:10BE000009F80126304670BD14000020D00600203D -:10BE10002C00002070B50646F068C46854B900BF15 -:10BE2000502080F31188BFF34F8FBFF36F8F00BF97 -:10BE300000BFFEE704F11800FEF7A2FF15480068F6 -:10BE4000A8B9201DFEF79CFF94F82C100120884013 -:10BE500011490968084310490860E16A01EB810152 -:10BE60000E4A02EB8100211DFEF7D4FF04E004F12D -:10BE700018010B48FEF7CEFF0A49E06A0968C96A53 -:10BE8000884204D9012501200749086000E0002507 -:10BE9000284670BD4C0000202C000020D006002059 -:10BEA00084070020140000203800002070B5002412 -:10BEB00000263648006850B900BF502080F3118832 -:10BEC000BFF34F8FBFF36F8F00BF00BFFEE7FEF7DA -:10BED000ADFF2E480068401E2C49086008460068E7 -:10BEE00000284FD12A48006800284BD024E0294878 -:10BEF000C068C46804F11800FEF742FF201DFEF779 -:10BF00003FFF94F82C10012088402349096808431A -:10BF100021490860E16A01EB8101204A02EB8100BE -:10BF2000211DFEF777FF1E49E06A0968C96A884249 -:10BF300002D301201B4908601648006808B9012097 -:10BF400000E000200028D2D00CB1FEF75FFB1648BD -:10BF5000056865B100BFFFF755FE10B1012011491A -:10BF600008606D1E002DF6D100200F4908600D48B5 -:10BF7000006838B1012630070C490860BFF34F8FC5 -:10BF8000BFF36F8FFEF77CFF304670BD4C00002082 -:10BF900024000020840700202C000020D006002070 -:10BFA00014000020380000203400002004ED00E0E0 -:10BFB0009C280108AB5500080000000000000000AC -:10BFC00080000000000000000000000000061016C5 -:10BFD000000610160000000000000000010203042B -:10BFE0000607080900000000010203040000000029 -:10BFF000000000000200F000F0000000000000005F -:10C00000000000000000000000000000000003002D -:10C010000000000000000000000000000000000020 -:10C02000000000005F6C697374006C6973742061B8 -:10C030006C6C20636F6D6D616E6400000010000019 -:10C040000008000008000000080000000080000058 -:10C05000004000006D520008C95300084553000815 -:10C06000D5530008D95200080A0000000200000061 -:10C0700000000000000000004000FE079200FE07E4 -:10C080009204FE0702008A04BA028A01AA04190770 -:10C09000C2B9200000000000000000000000000005 -:10C0A0000000000000000000200020002000200010 -:10C0B000240124022202220421042000200038004E -:10C0C000D0A12000000000000000000000000000DF -:10C0D00000000000000000002000A70722012A0144 -:10C0E0002A012F01AA072601220116011301C80700 -:10C0F000B0E0200000000000000000000000000090 -:10C1000000000000000000000801270144010401B4 -:10C110003F0144010E011607E50104010401040179 -:10C12000BFC620000000000000000000000000006A -:10C13000000000000000000084008400F4078F006D -:10C140008400F4032C0227024401840044013606D3 -:10C15000BCBC200000000000000000000000000047 -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C25000000000000000000080000001FC7F44049A -:10C260004404FC3F44244424FC3F14021422F41AE6 -:10C2700012061222D122303CC2B920000000000078 -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000080008000800080009E -:10C2A0008000880888108820842084408240814053 -:10C2B00080008000A0004000D0A12000000000000D -:10C2C000000000000000000000000000000000006E -:10C2D0000000000000000000000100011F7D44116B -:10C2E0004411441144115F7D4411241104119C1028 -:10C2F0008710427C20001000B0E020000000000009 -:10C30000000000000000000000000000000000002D -:10C3100000000000000000001008B8080F0908091C -:10C320000808BF0808091C092C080A78CA0F090860 -:10C330000808080808080808BFC620000000000018 -:10C3400000000000000000000000000000000000ED -:10C350000000000000000000080408040804C87F72 -:10C360003F0408040804A83F18210C110B12080A06 -:10C370000804080A8A116460BCBC200000000000A8 -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D0000000000000000000000000000400000C4C -:10C4E00000F8EE03081100081100F8FF010811011F -:10C4F000081101F8F701080801C81001489001C8A7 -:10C500007300481002481402441302C4F0030200EE -:10C5100000000000C2B92000000000000000000080 -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000040000040000040000040000CB -:10C56000040040040060240020C400208401100462 -:10C570000308040308040204040200040000040089 -:10C58000000400800700000200000000D0A120008D -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C0000000000000000000000000000400EC0477 -:10C5D0000010BC031044001044001044001045003B -:10C5E000FC450010E503904400104400104400D0C6 -:10C5F00042003042000E410082F807400000300047 -:10C6000000000000B0E0200000000000000000007A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C64000000000008000C081003C800020880020A5 -:10C650009000209000FC8100208000608800B09055 -:10C660000030810728F90024870022800020800004 -:10C67000208000208000208000000000BFC6200035 -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000010100030200A -:10C6C00000202000202000FCFF032020002020006C -:10C6D000202000E0F8013804012684002088002092 -:10C6E00048002070002030002048003C8603900164 -:10C6F00002000000BCBC20000000000000000000A0 -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C73000000000000000000000000000000000FCFD -:10C74000FF03000000000000000000000000F8FFF0 -:10C7500001000000000000000000000000000000D8 -:10C76000FEFF07000000000000000000C8FD2000E0 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B00000000000000000102000FEFF011020001B -:10C7C000F03F00102000F03F00102000FFFF03109A -:10C7D0002100FCFF00030103FEFF01000000000038 -:10C7E00000000000BBF92000000000000000000075 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C8200000000000000000000000000000000040C8 -:10C830000000F01F00181800040C00FFFF00048225 -:10C8400000048200FCFF00048000040000040002D9 -:10C85000F8FF01000000000000000000C9AB20004C -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C980000000000000000000000000001000003067 -:10C9900010F0FF3F104200104200104200F0FF1F55 -:10C9A000104208104208104208F0FF0F10200890B3 -:10C9B000C00090410890410E904F0398C1008841FB -:10C9C0001088491084473084C13F020000000000F5 -:10C9D000C2B92000000000000000000000000000BC -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA100000000000000000000000000000000018FE -:10CA200000001800001000001000001000001000AE -:10CA3000809000801101C0100240100460101C3072 -:10CA400010181010300810300410200010000010D2 -:10CA500000001000001900001E00000C0000000083 -:10CA6000D0A1200000000000000000000000000035 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000001000003046 -:10CAB00000FED13F201002201002201002201002A0 -:10CAC000201402FC150220140220D63F201202205E -:10CAD0001202201002A009026008021C08020604CB -:10CAE0000200020200F13FC0000020000000000030 -:10CAF000B0E0200000000000000000000000000086 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000040007EA -:10CB40000CF80004C00004C06004C0C004C00004AD -:10CB5000FE0704C00004C02004E06004E04304F0C9 -:10CB60004624D04474C8800FC87804C40404C200AA -:10CB700004C00004C00004C00004C000044000045D -:10CB8000BFC6200000000000000000000000000000 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC00000000000000000000000002080006080E5 -:10CBD00001608000608000608000FEFF3F60800098 -:10CBE000608000608000608200E0FD1F7010086EB1 -:10CBF000100C6420046020066040026040036080E6 -:10CC00000160400364300E780C7C200310000000AB -:10CC1000BCBC20000000000000000000000000007C -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC6000000000000000C0F8FFC018C0CC18C0CC05 -:10CC7000F8FFCC18C0CC180CCC180CCCD8FFCCD8F2 -:10CC8000CCCCD8CCCCD8CCCCCCCCC0CCCCC004FC7C -:10CC9000C0060C7E00000000000000000000000044 -:10CCA000CBA22000000000000000000000000000F7 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF00000000000000000F8FF7F180060180060CE -:10CD0000F8FF7F180666180C06180803D8FF7F186E -:10CD10000C06180C06F8FFFF0C0C060C0C0604069B -:10CD200006060306030106000000000000000000E4 -:10CD3000C6C120000000000000000000000000004C -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD8000000000000200C084FFCC9CC1CC88C1CC54 -:10CD900080D9CC83D9CC8ED9CC98D9CC80D9CC8031 -:10CDA000D9CC88D9CC98CDCC0C0CCC0C36C00C632B -:10CDB000C0C6C1C074807D000000000000000000FB -:10CDC000B2E22000000000000000000000000000AF -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000002001B0C0073180043380003E0 -:10CE200080FFFF0000031F000318000398FF031892 -:10CE30001802181806981806D8188678188C38F82A -:10CE40008D9C0F980800F00000000000000000001A -:10CE5000CAD4200000000000000000000000000014 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA00000000000008301FEFFFF008301F0FF3F50 -:10CEB000300030F0FF3F300030F0FF3F300C3000EA -:10CEC0000600FEFFFFC0300CF8FF7F67309860302F -:10CED0001860301F0030000000000000000000005B -:10CEE000C4BB2000000000000000000000000000A3 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF30000000000000630080C100C08001600003A9 -:10CF400030000618001C0E00700200C0F8FF0F0031 -:10CF5000030E00030E800106800106C0000660007B -:10CF60000738FC030E000000000000000000000075 -:10CF7000B7D6200000000000000000000000000004 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000018600C306018306010FEE1FF00600057 -:10CFD00082EDC1C46C636C6C36FE65FF3066183040 -:10CFE0006618306018FEB1FF3030183818181C1C55 -:10CFF000180E0E18020218000000000000000000C9 -:10D00000B1E6200000000000000000000000000069 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000003800007000FFFFFF003800F3 -:10D06000064E608C6338D03F08001C00202604F870 -:10D07000C31CCFFFF1023041003000FFFFFF003042 -:10D080000000300000300000000000000000000040 -:10D09000C2CA2000000000000000000000000000E4 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000030800030800130000330FEFFFE06C0BB -:10D0F0003086C4304018303030301860F00FC03EF9 -:10D10000F87F3000033000033000033000033000AC -:10D110000330FFFF1E0000000000000000000000C0 -:10D12000BFD8200000000000000000000000000048 -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D17000000000008001609801608C0163FC3F6347 -:10D18000860163820163FFFF63800163800163FCAA -:10D190007F638C61638C61638C61608C61608C3DAA -:10D1A0006080013F0000000000000000000000005F -:10D1B000D6C62000000000000000000000000000B3 -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D2000000000000000000FCC77F0CC6600CC66078 -:10D21000FCC77F0CC660003006FEFFFF006E0000FA -:10D22000C701F0010F1F00F8FCC77F0CC6600CC6D9 -:10D2300060FCC77F0CC6600000000000000000001A -:10D24000C6F7200000000000000000000000000001 -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D2900000000800001800003000FEFFFF0600C07C -:10D2A0000600C0E0FF0F00000700800100E0000062 -:10D2B0003000FFFFFF003000003000003000003081 -:10D2C00000801F00000000000000000000000000BF -:10D2D000D7D6200000000000000000000000000081 -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D320000020800130C000F8DFFFC8600684710C67 -:10D3300002390801100060000C70000CB8FFFF3CBF -:10D34000000C36040C320C0C30180C30100C300071 -:10D350000C30000C30E0070000000000000000006E -:10D36000B7FB2000000000000000000000000000EB -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B00000000000C0300060E000F0FFFF386000B7 -:10D3C000F6FFFF336000F0FFFF306000F0FFFF303A -:10D3D0000000003000003000FEFFFF00FE01803141 -:10D3E000077030380F30C00000000000000000005F -:10D3F000BCAF2000000000000000000000000000A2 -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D44000000000000018000018000018000018007C -:10D45000FCFF7F0C18600C18600C18600C18600C36 -:10D460001860FCFF7F0C18600018000018000018FE -:10D47000000018000018000000000000000000007C -:10D48000D6D02000000000000000000000000000D6 -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D00000001C00003800006000FFFFFF60000C2F -:10D4E00060000CC00006C00006800103008301003C -:10D4F000C700006C0000380000EE00C08307780011 -:10D500003C0600E0000000000000000000000000F9 -:10D51000CEC4200000000000000000000000000059 -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000F8FF3F180030180030F5 -:10D57000F8FF3F180030180030F8FF3F1800300463 -:10D58000C62008C63018C63830C61820C60800C6DF -:10D5900000FEFFFF0000000000000000000000008F -:10D5A000CFD42000000000000000000000000000B8 -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F00000000000000000FCFF7F000000000000B1 -:10D60000000000000000FFFFFF0030002030043069 -:10D61000300C3830181830300C30600630C0023012 -:10D6200080003000801F00000000000000000000AB -:10D63000CABE200000000000000000000000000042 -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D6800000000000000000FEFFFF0030000030003E -:10D6900000300030300030300030300030F07F306B -:10D6A000300030300030300030300030300030306A -:10D6B00000FFFFFF0000000000000000000000006D -:10D6C000D5FD200000000000000000000000000068 -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D7100000000000000300800100C0FF076000035C -:10D720003880010C6000F4FF3F3000303030303082 -:10D73000303030303030303030303030F8300098E9 -:10D740000300070EE001781E00C00000000000008A -:10D75000B8BA200000000000000000000000000037 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A00000000000003000003000003000003000B9 -:10D7B00060300630300C30301C1830381830300CE7 -:10D7C00030600E30E00630C00230800030000030A3 -:10D7D00000C01F000000000000000000000000006A -:10D7E000D0A12000000000000000000000000000A8 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000C00003C60C01C48601C080FFC8 -:10D84000FECF60E0C060F8E360CCFE31C3983130B9 -:10D850008031FF0F1B0C0C1B06060E3C070EE0036D -:10D860001BE0C3313C76E007188000000000000098 -:10D87000CAFD2000000000000000000000000000C1 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000030000330000330FEFF30000392 -:10D8D000300003FFFD7F300C6030FC7F300C603087 -:10D8E000FC7F300C60B0FD7F780C6007FFFF0060AC -:10D8F0001C001CF08003000000000000000000007D -:10D90000CCEE20000000000000000000000000003D -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000800001800003800FFFFFF72 -:10D96000000E00808301C0000770000CFCFF3F0028 -:10D97000C32000C30080C10080C1C0E0C0C038C067 -:10D98000C007807F000000000000000000000000D1 -:10D99000B3E42000000000000000000000000000D0 -:10D9A0000000000000000000000000000000000077 -:10D9B0000000000000000000000000000000000067 -:10D9C0000000000000000000000000000000000057 -:10D9D0000000000000000000000000000000000047 -:10D9E00000000000003800007000FEFFFF0600C0CD -:10D9F0000686C3C0011E3800700600C0000000F893 -:10DA0000FF3F001800001800001800001800001860 -:10DA100000FEFFFF0000000000000000000000000A -:10DA2000BFD5200000000000000000000000000042 -:10DA300000000000000000000000000000000000E6 -:10DA400000000000000000000000000000000000D6 -:10DA500000000000000000000000000000000000C6 -:10DA600000000000000000000000000000000000B6 -:10DA70000000000030600030300030F07F307870FF -:10DA8000FF5B3830CC0CF88007B8C10F3C7A783691 -:10DA90000EC033F87F3118603018603018603018CD -:10DAA0006030F87F301860000000000000000000C7 -:10DAB000B8F120000000000000000000000000009D -:10DAC0000000000000000000000000000000000056 -:10DAD0000000000000000000000000000000000046 -:10DAE0000000000000000000000000000000000036 -:10DAF0000000000000000000000000000000000026 -:10DB00000000000000000000000000000000000015 -:10DB10000000000000000000000000000000000005 -:10DB200000000000000000000000000000000000F5 -:10DB300000000000000000000000000000000000E5 -:10DB400000000000000000000000000000000000D5 -:10DB500000000000000000000000000000000000C5 -:10DB600000000000000000000000000000000000B5 -:10DB700000000000000000000000000000000000A5 -:10DB80000000000000000000000000000000000095 -:10DB90000000000000000000000000000000000085 -:10DBA0000000000000000000000000000000000075 -:10DBB0000000000000000000000000000000000065 -:10DBC0000000000000000000000000000000000055 -:10DBD00000000000000000000080000000000300C2 -:10DBE000000003002000020CE0FFFF1F60300C006B -:10DBF00060300C0060300C04E0FFFF0F60300C045C -:10DC000060300C0460300C0460300C04E0FFFF074F -:10DC1000600000046000040060041C00600C0C0440 -:10DC200060040C0F60C48C0320FCED0020041C0079 -:10DC300030040C0010040D0810C40C0808340C1833 -:10DC4000081E1838040CF81F020000000000000035 -:10DC5000C2B9200000000000000000000000000029 -:10DC600000000000000000000000000000000000B4 -:10DC700000000000000000000000000000000000A4 -:10DC80000000000000000000000000000000000094 -:10DC90000000000000000000000000000000000084 -:10DCA0000000000000000000000000000000000074 -:10DCB0000000000000000000000000000000000064 -:10DCC0000000000000000000000000000000000054 -:10DCD000000000000000000000800000008007003D -:10DCE0000080010000800100008001000080010030 -:10DCF000008001000080010000820100008E2100F0 -:10DD0000008641000087810000838101808101033A -:10DD100080810106C080010E4080011C6080011CD2 -:10DD20003080011810800118088001100480010063 -:10DD3000008001000080010000800100008C0100D3 -:10DD400000F0010000E000000040000000000000C2 -:10DD5000D0A1200000000000000000000000000032 -:10DD600000000000000000000000000000000000B3 -:10DD700000000000000000000000000000000000A3 -:10DD80000000000000000000000000000000000093 -:10DD90000000000000000000000000000000000083 -:10DDA0000000000000000000000000000000000073 -:10DDB0000000000000000000000000000000000063 -:10DDC0000000000000000000000000000000000053 -:10DDD000000000000000000000000100000007003B -:10DDE000000C0318FC1FFF3FC0008301C00083012B -:10DDF000C0008301C0008301C0008301C000830113 -:10DE0000C0248301FC2F8301C0208309C020FF1F91 -:10DE1000C0308301C0188101C0008101C0008101B0 -:10DE2000C0908101C08C8101C0838001F0C080015D -:10DE30003E4080010C208001003080110008FE3F30 -:10DE40000006000000010000C0000000000000000B -:10DE5000B0E0200000000000000000000000000012 -:10DE600000000000000000000000000000000000B2 -:10DE700000000000000000000000000000000000A2 -:10DE80000000000000000000000000000000000092 -:10DE90000000000000000000000000000000000082 -:10DEA0000000000000000000000000000000000072 -:10DEB0000000000000000000000000000000000062 -:10DEC0000000000000000000000000000000000052 -:10DED000000000000000000000000001003000070A -:10DEE000003C0003E00700031C03000300030603DB -:10DEF00000030C03000318030003180300230003AE -:10DF0000FC7F0003000300030003020380030603F9 -:10DF1000800F0C03C03B0803403300336023003FF5 -:10DF20002023F00310830F0308630003040300039E -:10DF300002030003000300030003000300030003C7 -:10DF400000030003000300030001000100000000C3 -:10DF5000BFC620000000000000000000000000001C -:10DF600000000000000000000000000000000000B1 -:10DF700000000000000000000000000000000000A1 -:10DF80000000000000000000000000000000000091 -:10DF90000000000000000000000000000000000081 -:10DFA0000000000000000000000000000000000071 -:10DFB0000000000000000000000000000000000061 -:10DFC0000000000000000000000000000000000051 -:10DFD00000000000000000008000100080037000BE -:10DFE000800130008001300080013000800130006D -:10DFF00080193018FCFFFF3F8001300080013000A5 -:10E0000080013000800130008031300480CDFF0F6E -:10E0100080030106F0010106BC0102038C0102032A -:10E0200080018601800184018001CC0080016800AC -:10E0300080017000800178008001EC008001C7033E -:10E04000F881011FE071003E400C0000000000005C -:10E05000BCBC200000000000000000000000000028 -:10E0600000000000000000000000000000000000B0 -:10E0700000000000000000000000000000000000A0 -:10E080000000000000000000000000000000000090 -:10E090000000000000000000000000000000000080 -:10E0A0000000000000000000000000000000000070 -:10E0B0000000000000000000000000000000000060 -:10E0C0000000000000000000000000000000000050 -:10E0D0000000000000000000000000000000000040 -:10E0E0000000000000000000000000000000000030 -:10E0F0000000000000000000000000000000000020 -:10E10000000000000000000000000000000000000F -:10E1100000000000000000000000000000000000FF -:10E1200000000000000000000000000000000000EF -:10E1300000000000000000000000000000000000DF -:10E1400000000000000000000000000000000000CF -:10E1500000000000000000000000000000000000BF -:10E1600000000000000000000000000000000000AF -:10E17000000000000000000000000000000000009F -:10E18000000000000000000000000000000000008F -:10E19000000000000000000000000000000000007F -:10E1A000000000000000000000000000000000006F -:10E1B000000000000000000000000000000000005F -:10E1C000000000000000000000000000000000004F -:10E1D000000000000000000000000000000000003F -:10E1E000000000000000000000000000000000002F -:10E1F000000000000000000000000000000000001F -:10E20000000000000000000000000000000000000E -:10E2100000000000000000000000000000000000FE -:10E2200000000000000000000000000000000000EE -:10E2300000000000000000000000000000000000DE -:10E2400000000000000000000000000000000000CE -:10E2500000000000000000000000000000000000BE -:10E2600000000000000000000000000000000000AE -:10E27000000000000000000000000000000000009E -:10E28000000000000000000000000000000000008E -:10E29000000000000000000000000000000000007E -:10E2A000000000000000000000000000000000006E -:10E2B000000000000000000000000000000000005E -:10E2C000000000000000000000000000000000004E -:10E2D000000000000000000000000000000000003E -:10E2E000000000000000000000000000000000002E -:10E2F000000000000000000000000000000000001E -:10E30000000000000000000000000000000000000D -:10E3100000000000000000000000000000000000FD -:10E3200000000000000000000000000000000000ED -:10E3300000000000000000000000000000000000DD -:10E3400000000000000000000000000000000000CD -:10E3500000000000000000000000000000000000BD -:10E3600000000000000000000000000000000000AD -:10E37000000000000000000000000000000000009D -:10E38000000000000000000000000000000000008D -:10E39000000000000000000000000000000000007D -:10E3A000000000000000000000000000000000006D -:10E3B000000000000000000000000000000000005D -:10E3C000000000000000000000000000000000004D -:10E3D000000000000000000000000000000000003D -:10E3E000000000000000000000000000000000002D -:10E3F000000000000000000000000000000000001D -:10E40000000000000000000000000000000000000C -:10E4100000000000000000000000000000000000FC -:10E4200000000000000000000000000000000000EC -:10E4300000000000000000000000000000000000DC -:10E4400000000000000000000000000000000000CC -:10E4500000000000000000000000000000000000BC -:10E4600000000000000000000000000000000000AC -:10E47000000000000000000000000000000000009C -:10E48000000000000000000000000000000000008C -:10E49000000000000000000000000000000000007C -:10E4A000000000000000000000000000000000006C -:10E4B000000000000000000000000000000000005C -:10E4C000000000000000000000000000000000004C +:100320000A4604461946FFF7F0FF204610BD421C5E +:1003300010F8011B0029FBD1801A704710B500226C +:1003400000E0521C835C8C5CA34201D1002BF8D1ED +:10035000D8B2E1B2401A10BD30B5054600200346C0 +:1003600000E05B1C934205D2EC5CC85C201A01D112 +:10037000002CF6D130BD2DE9FE4F804681EA030006 +:10038000C00F0C46009021F0004123F00045B8EB6F +:100390000200A94105D24046214690461C460B4624 +:1003A000024623F00040104347D0270DC7F30A0050 +:1003B000C3F30A510290401A019040286BDAC3F34C +:1003C000130040F4801B0098924620B10023D2EB2A +:1003D000030A63EB0B0B01985946C0F140025046EB +:1003E00000F0F8F806460D4650465946019A00F0CE +:1003F00010F910EB08006141002487EA115284EAE9 +:10040000E7731A4340D0009A62B3019A012A4FEA77 +:10041000075215DC001B61EB02014FF0004202EABB +:100420000752CDE90042001C41F5801132462B46AF +:1004300000F010F903B0BDE8F08F40462146F9E71F +:10044000001B61EB0201001C41F5801300185B41A9 +:100450002018A2F5001747EB030140EAD570B61942 +:100460006D4111E06D084FEA360645EAC0754FEA66 +:100470000752001B61EB0201001C41F58011490885 +:100480004FEA30000019514132462B4603B0BDE817 +:10049000F04F00F0D0B80098012240000023D0EBCC +:1004A000020263EBE073009821464FEAE074B8EB78 +:1004B000000061EB0401E9E783F000435BE781F0B2 +:1004C000004158E72DE9FE4F81EA030404F000449F +:1004D00021F0004100944FF0000B23F0004350EA5C +:1004E00001045ED052EA03045BD0C3F30A54C1F3A3 +:1004F0000A552C44A4F2F3340194A0FB0254C1F336 +:10050000130141F48011C3F3130343F4801301FB7F +:10051000024400FB034E840A970A44EA815447EAE6 +:100520008357A4FB076802958D0A05FB07854FEAF0 +:10053000932C04FB0C542705029D4FEA065847EA0A +:100540001637B5EB08056EEB070C870E920E47EADF +:10055000811742EA8312A7FB0201B6EB0B0164EBA1 +:1005600000042B0D43EA0C335E1844EB1C50DA46B2 +:100570005146E7FB0201C5F313044FEA0B3343EA8C +:1005800014534FEA0432019C43EA0603A4F10C041D +:100590000294009CCDE900B400F05CF803B0BDE823 +:1005A000F08F00200146F9E730B50B4601460020E8 +:1005B0002022012409E021FA02F59D4205D303FA25 +:1005C00002F5491B04FA02F52844151EA2F10102A6 +:1005D000F1DC30BD202A04DB203A00FA02F10020D1 +:1005E00070479140C2F1200320FA03F31943904071 +:1005F0007047202A04DB203A21FA02F000217047DC +:1006000021FA02F3D040C2F120029140084319467A +:100610007047202A06DBCB17203A41FA02F043EA62 +:10062000E07306E041FA02F3D040C2F120029140AB +:1006300008431946704710B5141E73F1000408DA18 +:10064000401C41F1000192185B411A4301D120F096 +:10065000010010BD2DE9F04D92469B4611B1B1FA53 +:1006600081F202E0B0FA80F220329046FFF7B2FF4A +:1006700004460F4640EA0A0041EA0B0153465A4637 +:10068000084313D0114653EA010019D0C8F14002C3 +:100690005046FFF7AEFF05460E46504659464246C5 +:1006A000FFF798FF084305D0012004E020463946B3 +:1006B000BDE8F08D0020054346EAE0762C43374341 +:1006C0000A986305E40AA0EB08000022FD0A44EA48 +:1006D00047540A3002D500200146E9E70105101908 +:1006E0006941DDE9084500196941BDE8F04DA2E71F +:1006F0002DE9F04D81EA030404F0004B21F00045A0 +:1007000014464FF0000A23F0004150EA050220D0C1 +:1007100054EA01021DD0C5F30A570246C5F313037C +:10072000C1F31300C1F30A5640F4801543F480135B +:10073000A7EB0608101BD64608F2FD3873EB050040 +:1007400002D308F1010801E092185B41B8F1000FF3 +:1007500003DA00200146BDE8F08D00204FF480113F +:10076000064684460EE0171B73EB050705D3121BE4 +:1007700063EB050306434CEA010C49084FEA3000DD +:1007800092185B4150EA0107EDD152EA030012D002 +:1007900082EA040083EA0501084305D0101BAB413F +:1007A00006D20122002306E000224FF0004302E0BF +:1007B0006FF0010253101AEB06004CEB085110EBDE +:1007C0000A0041EB0B01BDE8F04DFFF734BFC1F368 +:1007D0000A52C1F3130140F2FF3341F480119A42EF +:1007E00002DA00200146704740F233439A42A2F2F7 +:1007F000334202DC5242FFF7FCBEFFF7EBBE0000C3 +:1008000030B5041E71F1000404DB4FF00044404297 +:1008100064EB0101141E73F1000405DB1C464FF06C +:100820000043524263EB0403994208BF904230BD3B +:10083000064C074D06E0E06840F0010394E807002D +:1008400098471034AC42F6D3FFF7A2FCF0500108F1 +:100850002051010870B58C1810F8015B15F00703E2 +:1008600001D110F8013B2A1106D110F8012B03E049 +:1008700010F8016B01F8016B5B1EF9D12B0705D451 +:100880000023521E0DD401F8013BFAE710F8013B9A +:10089000CB1A921C03E013F8015B01F8015B521EB6 +:1008A000F9D5A142D8D3002070BD000010B50124B5 +:1008B000A102034800F02AFD00B10024204610BD2B +:1008C0000004024010B504462146024802F0CCFC68 +:1008D00010BD00001005002010B5044802F0D7FC40 +:1008E000042801D0012010BD0020FCE710050020E5 +:1008F00010B5002400F014F8012801D0012010BD2B +:10090000064802F0D6FC044634B94FF400610348AF +:1009100002F060FB00B101242046F0E71005002042 +:1009200008B501200090FFF7C1FF08B90020009032 +:100930009DF8000008BD00002DE9F04104460D4679 +:100940001646002733462A462146044802F0E6FDB3 +:1009500000B101273846BDE8F081000010050020F5 +:1009600010B5002201210248006809F0B5FF10BD52 +:10097000AC0000202DE9F04104460D461646002744 +:1009800033462A462146044802F076FE00B101278C +:100990003846BDE8F08100001005002000BFFEE7EA +:1009A0000346042B15D007DC7BB1012B0ED0022BA4 +:1009B0000DD0032B12D10BE0202B0BD0212B0AD012 +:1009C000222B09D0232B09D107E008E007E006E03D +:1009D00005E004E003E002E001E000E000BF00BF4A +:1009E000002070470020704710B5002204490548D8 +:1009F00005F0BFFE0449034805F0ACFE002010BD21 +:100A0000AC010120D0F40020ACF9002070B5044600 +:100A10000D46204629680CF0CBF92146034805F025 +:100A200099FE024805F062FE002070BDD0F400205F +:100A300010B503460C460021084610BD2DE9F041D3 +:100A400004460D4600260A48D0F8BC72D7F81402B6 +:100A500010B10120BDE8F0812A462146044805F086 +:100A600088FE034805F038FF06463046F2E70000EE +:100A7000D0F40020024600BF1AB901E000BF00BF59 +:100A8000FCE700BF0120704710B5024800F050F9A4 +:100A900010BD00009405002010B5024800F048F990 +:100AA00010BD0000F4050020014608781038182316 +:100AB000B0FBF3F20848805CC865032A05D90868D2 +:100AC0006FF30900001D886503E008686FF30900F3 +:100AD0008865886D704700008CE40008014600209E +:100AE0008A6A8B69CBB932B1012A0DD0022A03D0B0 +:100AF000032A10D10EE000BFCB6A03F08073B3F17C +:100B0000807F00D1012007E0CB6AB3F1C07F00D124 +:100B1000012001E000E000BF34E08B69B3F5005F25 +:100B20001AD132B1012A07D0022A03D0032A11D1E7 +:100B30000AE000BF01200EE0CB6A03F08073B3F13E +:100B4000807F00D1012006E0CB6AB3F1C07F00D1E5 +:100B5000012000E000BF15E032B1012A05D0022AD1 +:100B600004D0032A0CD103E000BF00BF012008E03D +:100B7000CB6A03F08073B3F1807F00D1012000E0E5 +:100B800000BF00BF704730B50468246824F4802497 +:100B900005682C60046863608468402C04D1046894 +:100BA000A2600468E16003E00468A1600468E26098 +:100BB00030BD704772B600BFFEE730B504460D4643 +:100BC00000222946204600F001F830BDF0B503466A +:100BD000012500241148807B02281CDA00200F4EDA +:100BE000B67B0E4FB8553846867B001D40F8263040 +:100BF000001F867B0C3082553E46B07B461CBE7380 +:100C0000044604F1300008703A2048702F208870A4 +:100C10000020C87000252846F0BD0000C0F4002068 +:100C200070B50A480468001D0568001D0668344454 +:100C300054B108220649204603F0A2FB04220449CD +:100C40001031284603F09CFB70BD0000107AFF1F96 +:100C50006A01002070B50446A56D00F06FFB0646E2 +:100C600094F83500022808D08020606500BF00207D +:100C700084F8340000BF012070BD2068006820F0B7 +:100C80001600216808602068406920F08000216813 +:100C90004861206C08B9A06C28B12068006820F079 +:100CA0000800216808602068006820F001002168C1 +:100CB000086010E000F042FB801B05280BD92020C3 +:100CC0006065032084F8350000BF002084F83400FC +:100CD00000BF0320D0E72068006800F00100002872 +:100CE000E8D194F85C103F208840A860012084F887 +:100CF000350000BF002084F8340000BF00BFBBE710 +:100D0000014691F83500022803D080204865012073 +:100D10007047052081F835000868006820F0010060 +:100D20000A6810600020F3E70146486D7047000034 +:100D3000F8B50446002000908C4800684FF4165126 +:100D4000B0FBF1F7A56D2E6894F85C100820884080 +:100D5000304098B12068006800F0040070B120684D +:100D6000006820F004002168086094F85C100820F6 +:100D70008840A860606D40F00100606594F85C10E8 +:100D800001208840304068B12068406900F0800050 +:100D900040B194F85C1001208840A860606D40F07C +:100DA0000200606594F85C1004208840304068B10F +:100DB0002068006800F0020040B194F85C10042044 +:100DC0008840A860606D40F00400606594F85C1095 +:100DD00010208840304078B32068006800F0080098 +:100DE00050B394F85C1010208840A8602068006818 +:100DF00000F4802080B12068006800F4002028B949 +:100E0000206CC8B12046216C884715E0A06C98B1D1 +:100E10002046A16C88470FE02068006800F48070CD +:100E200028B92068006820F0080021680860206C5C +:100E300010B12046216C884794F85C10202088402F +:100E40003040002865D02068006800F010000028BD +:100E50005FD094F85C1020208840A86094F835009A +:100E6000052828D12068006820F016002168086055 +:100E70002068406920F0800021684861206C08B932 +:100E8000A06C28B12068006820F008002168086084 +:100E900094F85C103F208840A860012084F8350059 +:100EA00000BF002084F8340000BF206D10B1204640 +:100EB000216D8847F8BD2068006800F4802080B16B +:100EC0002068006800F4002028B9606C10B120464A +:100ED000616C88471DE0E06BD8B12046E16B884724 +:100EE00017E02068006800F4807068B92068006826 +:100EF00020F0100021680860012084F8350000BF50 +:100F0000002084F8340000BFE06B10B12046E16B94 +:100F10008847606D38B3606D00F00100F0B10520C6 +:100F200084F835002068006820F00100216808601E +:100F300000BF0098401C0090B84200D905E020682E +:100F4000006800F001000028F3D100BF012084F800 +:100F5000350000BF002084F8340000BFE06C10B101 +:100F60002046E16C884700BFA4E700001000002085 +:100F70002DE9F0410446002500F0E0F9074614B9D8 +:100F80000120BDE8F081606A00B100BF022084F852 +:100F9000350000BF002084F8340000BF20680068DE +:100FA00020F00100216808600AE000F0C7F9C01BCA +:100FB000052805D920206065032084F83500E0E786 +:100FC0002068006800F001000028EED12068056864 +:100FD00021480540D4E901010843E168084321693B +:100FE000084361690843A1690843E1690843216A2C +:100FF00008430543606A042803D1D4E90B01084380 +:101000000543206805602068456925F00705606A8A +:101010000543606A04280DD1A06A0543E06A48B11F +:101020002046FFF75BFD28B140206065012084F871 +:101030003500A6E7206845612046FFF735FD0646E6 +:1010400094F85C103F208840B0600020606501206B +:1010500084F83500002094E73F8010F02DE9F04738 +:1010600004460D4616461F464FF00008D4F8589027 +:1010700000BF94F83400012802D10220BDE8F087B7 +:10108000012084F8340000BF94F83500012825D1F0 +:10109000022084F83500002060653B463246294630 +:1010A0002046FFF770FD94F85C103F208840C9F897 +:1010B00008002068006840F0160021680860206C75 +:1010C00028B12068006840F00800216808602068A6 +:1010D000006840F001002168086006E000BF0020C1 +:1010E00084F8340000BF4FF002084046C6E7000015 +:1010F00070B5044600F022F906462546681C10B17A +:1011000004480078054400BF00F018F9801BA8428D +:10111000FAD370BD0C000020F8B502460B4600253E +:10112000002400200021D6E0012606FA01F51E6801 +:1011300006EA0504AC4274D11E7906F00306012EBE +:1011400004D01E7906F00306022E13D190684F00DA +:101150000326BE40B0434F00DE68BE40304390607F +:10116000506801268E40B0431E79C6F300168E40AB +:10117000304350601E7906F00306032E09D0D06874 +:101180004F000326BE40B0434F009E68BE40304330 +:10119000D0601E7906F00306022E13D1CF0802F1AB +:1011A000200656F827004E07F70E0F26BE40B04324 +:1011B0004F07FF0E1E69BE403043CF0802F12006E4 +:1011C00046F8270010684F000326BE40B0431E7942 +:1011D00006F003064F00BE40304310605E6806F420 +:1011E0004036002E76D000BF002600963C4E366872 +:1011F00046F480463A4F3E603E46366806F48046E6 +:10120000009600BF00BF374E8F0856F827008E07A4 +:10121000370F0F26BE40B043334EB24202D10026F4 +:1012200024E057E0314EB24201D101261EE0304E9B +:10123000B24201D1022619E02E4EB24201D103265C +:1012400014E02D4EB24201D104260FE02B4EB242E3 +:1012500001D105260AE02A4EB24201D1062605E058 +:10126000284EB24201D1072600E008268F073F0F23 +:10127000BE4030431B4E8F0846F82700224E306890 +:10128000A0435E6806F4801606B120431E4E30600F +:10129000361D3068A0435E6806F4001606B1204390 +:1012A000194E361D3060184E361F3068A0435E68F8 +:1012B00006F4003606B12043134E361F3060361F49 +:1012C0003068A0435E6806F4803606B120430E4EB7 +:1012D000083E3060491C1029FFF426AFF8BD00001D +:1012E0004438024008380140000002400004024037 +:1012F00000080240000C02400010024000140240AE +:1013000000180240001C0240083C014002461369DC +:101310000B400BB1012000E00020704710B542697E +:1013200021EA020302EA010443EA0443836110BD97 +:101330000AB1816101E00B048361704701480068D4 +:101340007047000004000020034800680349097842 +:101350000844014908607047040000200C00002088 +:1013600010B50D48006840F400700B49086008464D +:10137000006840F4806008600846006840F48070AF +:101380000860032000F0DCF8042000F007F800F00B +:101390005FF8002010BD0000003C02402DE9F04144 +:1013A00088B004460027B84600BF002001902348BB +:1013B000006840F01000214908600846006800F00D +:1013C0001000019000BF00BF02A903A801F052F96C +:1013D000069F1FB901F076F9054602E001F072F9A7 +:1013E00045001748B5FBF0F0A0F101081548164973 +:1013F000086040F2E7311448C160C0F80480002161 +:1014000001618160816102F0A0FB064696B90E4839 +:1014100002F0D0FB06466EB9362000F043F8102CDF +:1014200007D200222146362000F04CF8074804601D +:1014300000E00126304608B0BDE8F08140380240A7 +:1014400040420F0000100040F0060020080000207D +:1014500008B500BF002000901148006840F48040AB +:101460000F4908600846006800F48040009000BF03 +:1014700000BF00BF00200090081F006840F08050AF +:10148000091F08600846006800F08050009000BF07 +:1014900000BF00220F21901E00F014F808BD0000CC +:1014A0004438024001460846002809DB00F01F03CB +:1014B00001229A4043099B0003F1E023C3F8002175 +:1014C00000BF70472DE9F05F80460D4616460027A5 +:1014D00007F0D6FB074639462A46334601F0070097 +:1014E000C0F1070ABAF1040F02D94FF0040A01E073 +:1014F000C0F1070AD14600F1040ABAF1070F02D27F +:101500004FF0000A01E0A0F1030AD4464FF0010AAF +:101510000AFA09FAAAF1010A0AEA020A0AFA0CFA14 +:101520004FF0010B0BFA0CFBABF1010B0BEA030BB9 +:101530004AEA0B042146404607F0AAFBBDE8F09FAB +:1015400000BF00F00702064B19684FF6FF03194071 +:10155000044B0B4343EA0221014B196000BF704763 +:101560000CED00E00000FA05704702461068416289 +:1015700000207047F0B5034615461868446A21B943 +:1015800044EA05401E68B06219E01868806A04EBFE +:101590001044002208E0186800F5827050F822001C +:1015A00004EB1044501CC2B2481E9042F3D844EAE7 +:1015B0000547186800F582704E1E40F8267000201E +:1015C000F0BD10B50446D4F8080505F0F0FD10BDD7 +:1015D00070B504460D4605EBC50304F13C0101EB73 +:1015E00083010A692946D4F8080505F0DBFC70BDC3 +:1015F00070B504460D4605EBC50304F51F7101EBFC +:1016000083010A692946D4F8080505F04FFD70BD2D +:1016100010B50446D4F8080505F0CCFD10BD2DE941 +:10162000F04104460D4605F08000802808D105F001 +:101630000F0000EBC00104F13C0000EB810607E065 +:1016400005F00F0000EBC00104F51F7000EB8106F0 +:101650003146206807F0A0F807463846BDE8F0811B +:1016600070B504460E4606F0800080280AD106F0C8 +:101670000F0000EBC00104F13C0000EB81050120EC +:10168000687009E006F00F0000EBC00104F51F7060 +:1016900000EB81050020687006F00F00287000BF85 +:1016A00094F8BC04012801D1022070BD012084F807 +:1016B000BC0400BF2946206806F04EFB00BF002096 +:1016C00084F8BC0400BF00BFEFE770B504460E46C7 +:1016D00006F00F006168884201D9012070BD06F054 +:1016E000800080280AD106F00F0000EBC00104F151 +:1016F0003C0000EB81050120687009E006F00F0056 +:1017000000EBC00104F51F7000EB8105002068703C +:101710000020A87006F00F00287000BF94F8BC04E9 +:10172000012801D10220D9E7012084F8BC0400BFC0 +:101730002946206806F0F8FD00BF002084F8BC04AC +:1017400000BF00BFCAE7024601F00F0000EBC00374 +:1017500002F51F7000EB8300006A70472DE9F04727 +:1017600005460E4690461F464FF0000906F08000E1 +:1017700080280AD106F00F0000EBC00105F13C0003 +:1017800000EB81040120607009E006F00F0000EB1F +:10179000C00105F51F7000EB81040020607006F0A9 +:1017A0000F002070C4F80C802771607808B1207891 +:1017B0002081022F01D10020607100BF95F8BC0488 +:1017C000012802D10220BDE8F087012085F8BC0481 +:1017D00000BF2146286806F0D5F900BF002085F833 +:1017E000BC0400BF4846EEE72DE9F04104460E4632 +:1017F0001746984606F00F0000EBC00104F51F7075 +:1018000000EB81052F61C5F8188000202862687000 +:1018100006F00F0028702069012800D16F6106F0E2 +:101820000F0028B9227C2946206806F057FC04E006 +:10183000227C2946206806F00BFE0020BDE8F081DE +:1018400070B504460D4605F00F006168884201D965 +:10185000012070BD05F0800080280AD105F00F003E +:1018600000EBC00104F13C0000EB81060120707028 +:1018700007E005EBC50104F51F7000EB81060020B1 +:1018800070700120B07005F00F00307000BF94F848 +:10189000BC04012801D10220DBE7012084F8BC044C +:1018A00000BF3146206806F086FD05F00F0028B91C +:1018B000217C04F2C442206806F0FEFC00BF002038 +:1018C00084F8BC0400BF00BFC3E72DE9F041044623 +:1018D0000E461746984606F00F0000EBC00104F1D3 +:1018E0003C0000EB81052F61C5F8188000202862BC +:1018F0000120687006F00F0028702069012800D1CF +:101900006F6106F00F0028B9227C2946206806F096 +:10191000E5FB04E0227C2946206806F099FD0020C2 +:10192000BDE8F0812DE9FE4F0446D4F800B05E46D4 +:10193000206807F018F8002874D1206807F052F8E2 +:1019400008B9BDE8FE8F40F608008059C0F30D20AD +:10195000C4F8FC04206807F045F800F002000228F3 +:1019600005D12068406900F00200216848612068C4 +:1019700007F038F800F01000102845D12068806981 +:1019800020F0100021688861DBF8209009F00F003A +:1019900000EBC00104F51F7000EB810AC9F343405E +:1019A00002281AD147F6F07009EA000030B3C9F3F3 +:1019B0000A125846DAF8101007F019F8C9F30A119C +:1019C000DAF810000844CAF81000C9F30A11DAF86E +:1019D00020000844CAF8200010E0C9F3434006285C +:1019E0000CD1082204F2C441584607F000F8C9F3AC +:1019F0000A11DAF820000844CAF82000206880693B +:101A000040F0100021688861206806F0EBFF00F4C8 +:101A10000020B0F5002F7BD10025206806F0B2FF32 +:101A2000029072E0E1E2029800F00100002868D024 +:101A3000E9B2206806F0C9FF804608F0010048B10D +:101A4000012106F5306000EB4510816029462046F3 +:101A500002F0D2FE08F00800082809D1082106F596 +:101A6000306000EB451081602946204602F092FE6E +:101A700008F01000102805D1102106F5306000EBA9 +:101A80004510816008F00200022824D1DBF8140020 +:101A900000F08000802807D140F60400805940F40F +:101AA000806140F60400815105EBC50104F51F700B +:101AB00000EB810A9AF80300012806D100208AF879 +:101AC0000300E9B2204600F09BFA022106F53060DF +:101AD00000EB4510816008F02000202805D120216E +:101AE00006F5306000EB4510816008F40050B0F559 +:101AF000005F06D14FF4005106F5306000EB451051 +:101B000081606D1C029840080290029800288AD1DA +:101B1000206806F067FF00F48020B0F5802F7DD1AB +:101B2000206806F025FF029000259AE0029800F058 +:101B30000100002873D0E9B2206806F02DFF80462E +:101B400008F00100F0B305F00F010120884001907A +:101B500040F634008159019821EA000040F6340132 +:101B60008851012106F5106000EB45108160206965 +:101B7000012824D105EBC50104F13C0000EB8100F4 +:101B800005EBC502016904F13C0000EB8200C0686E +:101B9000014405EBC50204F13C0000EB8200016149 +:101BA0006DB905EBC50104F13C0000EB81008069D3 +:101BB00028B904F2C4420121206806F07DFBE9B295 +:101BC000204600E001E0FFF703FD08F008000828C8 +:101BD00005D1082106F5106000EB4510816008F082 +:101BE0001000102805D1102106F5106000EB4510FB +:101BF000816008F04000402805D1402106F51060C2 +:101C000000EB4510816008F0020002281DD1294632 +:101C1000584606F069FE05EBC50101E025E01CE031 +:101C200004F13C0000EB810A9AF80300012806D178 +:101C300000208AF80300E9B2204600F0D8F902211A +:101C400006F5106000EB4510816008F080008028E8 +:101C500003D12946204602F071FE6D1C029840080F +:101C60000290029800287FF461AF206806F0BAFE67 +:101C700000F00040B0F1004F1CD140F60400805944 +:101C800020F0010140F60400815194F8F404012889 +:101C900007D1002084F8F40400212046FFF764FCFB +:101CA00002E0204600F0D4FA2068406900F00040CD +:101CB00021684861206806F095FE00F40060B0F5E8 +:101CC000006F0ED140F60800805900F0010010B1FD +:101CD000204600F015FB2068406900F40060216890 +:101CE0004861206806F07EFE00F48050B0F5805F09 +:101CF0007ED140F60400805920F0010140F6040036 +:101D000081511021206806F0EFFD002732E04FF6E8 +:101D10007F3106F5106000EB4710816006F510601A +:101D200000EB4710006820F4001106F5106000EB8E +:101D3000471001604FF67F3106F5306000EB471029 +:101D4000816006F5306000EB4710006820F4001158 +:101D500006F5306000EB4710016006F5306000EBDF +:101D60004710006840F0006106F5306000EB471056 +:101D700001607F1C6068B842C9D840F61C008059D9 +:101D800040F0011140F61C008151206B70B1D6F873 +:101D9000840840F00B01C6F8841840F644008059CE +:101DA00040F00B0140F6440081510FE040F6140072 +:101DB000805942F22B01084340F614018851081F54 +:101DC000805940F00B014FF401608151D6F80008B2 +:101DD00020F4FE60C6F80008217C04F2C4422068AA +:101DE00006F06AFA2068406900F48050216800E03B +:101DF00000E04861206806F0F5FD00F40050B0F501 +:101E0000005F17D1206805F025FF206806F098FDD7 +:101E1000E06000F051FC0090227B2068009906F001 +:101E200069FE204600F0FCF92068406900F400508B +:101E300021684861206806F0D5FD00F008000828F8 +:101E400008D1204600F00BFA2068406900F0080035 +:101E500021684861206806F0C5FD00F080008028F8 +:101E600018D1DBF8180020F08000CBF8180001250D +:101E70000DE005EBC50104F51F7000EB8100C07893 +:101E8000012803D1E9B22046FFF7C9FB6D1C606849 +:101E9000A842EED8206806F0A5FD00F48010B0F549 +:101EA000801F2DD1012522E006F5106000EB4510C2 +:101EB000D0F8009005EBC50104F13C0000EB810077 +:101EC0000079012812D109F00040B0F1004F0DD186 +:101ED000012105EBC50204F13C0000EB8200C1705A +:101EE000E8B240F080012046FFF799FB6D1C606866 +:101EF000A842D9D82068406900F480102168486160 +:101F0000206806F06FFD00F40010B0F5001F44D10A +:101F1000012538E006F5306000EB4510D0F8009060 +:101F200005EBC50104F51F7000EB81000079012865 +:101F300028D109F00040B0F1004F23D109F48030DE +:101F400094F8FC1401F0010188421BD1012105EB3A +:101F5000C50204F51F7000EB8200C170DBF81800A9 +:101F600040F08000CBF81800DBF8140000F080008F +:101F700040B940F60400805940F4007140F6040076 +:101F8000815103E06D1C6068A842C3D800BF20687F +:101F9000406900F4001021684861206806F022FDC5 +:101FA00000F08040B0F1804F08D12046FFF709FBD8 +:101FB0002068406900F0804021684861206806F090 +:101FC00011FD00F0040004280FD12068D0F804901F +:101FD00009F00400042802D12046FFF719FB20680D +:101FE000406840EA09002168486000BFA9E470B574 +:101FF00004460D462946D4F8080505F047F970BD9A +:1020000070B504460D462946D4F8080505F062F976 +:1020100070BD70B58AB0044614B901200AB070BD15 +:10202000266894F8BD0428B9002084F8BC04204632 +:1020300000F0A2F8032084F8BD04F06B00F4807077 +:1020400008B900212161206806F040F8282204F137 +:1020500010016846FEF747F994E80F0005F00EFE00 +:1020600020B1022084F8BD040120D7E700212068B8 +:1020700006F0EDFC002531E0012105EBC50204F17D +:102080003C0000EB8200417005EBC50104F13C000F +:1020900000F8215005EBC50100EB8100058100210E +:1020A00005EBC50204F13C0000EB8200017105EB79 +:1020B000C50204F13C0000EB8200C16005EBC502E3 +:1020C00004F13C0000EB8200016105EBC50204F164 +:1020D0003C0000EB82008161681CC5B26068A842C8 +:1020E000CAD800252AE0002105EBC50204F51F70BF +:1020F00000EB8200417005EBC50104F51F7000F88C +:102100002150002105EBC50200EB8200017105EBB7 +:10211000C50204F51F7000EB8200C16005EBC5022B +:1021200004F51F7000EB8200016105EBC50204F5A8 +:102130001F7000EB82008161681CC5B26068A84214 +:10214000D1D8282204F110016846FEF7CCF894E8B3 +:102150000F0005F0CBFE20B1022084F8BD04012061 +:102160005CE7002084F83800012084F8BD04206872 +:1021700005F0AAFE002051E710B586B004461421F0 +:1021800001A8FEF7C9F82068B0F1A04F42D100BF06 +:10219000002000902048006840F001001E490860BF +:1021A0000846006800F00100009000BF00BF4FF437 +:1021B000C050019002200290002003900320049060 +:1021C0000A20059001A91548FEF7A6FF00BF124896 +:1021D000001D006840F080000F49091D086000BF25 +:1021E000002000900C481430006840F480400A49F8 +:1021F000143108600846006800F48040009000BF79 +:1022000000BF00BF002205214320FFF75BF94320F8 +:10221000FFF748F906B010BD303802400000024018 +:1022200070B504460125E06808B9002506E0E068BD +:10223000022801D1012501E0FEF7BCFC2946D4F8B3 +:10224000080505F0F0F8D4F8080505F097F870BD1A +:1022500010B50446D4F8080505F0C6F810BD10B551 +:102260000446D4F8080505F0CAF810BD70B5044658 +:102270000D4600BF94F8BC04012801D1022070BDB6 +:10228000012084F8BC0400BF84F838502946206837 +:1022900006F011FC00BF002084F8BC0400BF00BFA2 +:1022A000EDE710B5044604F2C441D4F8080505F082 +:1022B000D1F810BD70B50446256800BF94F8BC0481 +:1022C000012801D1022070BD012084F8BC0400BFA8 +:1022D000A06A012806D1A069012803D0A86B40F4A8 +:1022E0008030A863206806F0CDFA206805F0DAFD9A +:1022F00000BF002084F8BC0400BF00BFE3E700007B +:1023000010B50446D4F8080505F001F92068D0F8A6 +:10231000000E40F001002168C1F8000E206A28B1CB +:102320000348006840F006000149086010BD000045 +:1023300010ED00E008B50120034908620348006879 +:10234000009000BF08BD000000000E420070004079 +:10235000F8B5044600250026207800F0010020B9D9 +:10236000207800F0040004282FD100205B49886603 +:10237000FEF7E4FF054606E0FEF7E0FF401B0228FB +:1023800001D90320F8BD56480068C0F3C06000289A +:10239000F2D160688101207A41EA007050498431AD +:1023A000086001204D498866FEF7C8FF054606E033 +:1023B000FEF7C4FF401B022801D90320E2E748488A +:1023C0000068C0F3C0600028F2D0207800F002005E +:1023D00002287DD100BF00200090414840300068B5 +:1023E00040F080503E49403108600846006800F0E7 +:1023F0008050009000BF00BF3A48006840F48070F1 +:1024000038490860FEF79AFF054606E0FEF796FF9A +:10241000401B022801D90320B4E73248006800F4C9 +:1024200080700028F2D02E487030006800F44076AA +:102430004EB3A08900F44070B04224D028487030D8 +:10244000006820F4407601202749086000200860D9 +:10245000234870300660006800F0010098B1FEF774 +:102460006DFF054608E0FEF769FF401B41F2883129 +:10247000884201D9032085E7194870300068C0F30D +:1024800040000028EFD000BFA08900F44070B0F5F4 +:10249000407F0CD112480830006820F4F810134A2D +:1024A000E168114008430E490831086007E00C4814 +:1024B0000830006820F4F81009490831086008481D +:1024C00070300068A189C1F30B010843044900E0A2 +:1024D00002E07031086000BF002053E7000047426F +:1024E0000038024000700040400E4742FFFCFF0FE2 +:1024F00070B504460D460CB9012070BD58480068FF +:1025000000F00700A84209D255490D70084600683E +:1025100000F00700A84201D00120EEE7207800F08B +:10252000020002281DD1207800F00400042805D103 +:102530004C48006840F4E0504A490860207800F0B8 +:102540000800082805D14748006840F46040454924 +:1025500008604448006820F0F000A1680843414941 +:102560000860207800F00100A8B36068012807D156 +:102570003C4808380068C0F34040B8B90120BCE7C7 +:102580006068022802D06068032807D135480838FF +:102590000068C0F3406048B90120AEE73148083810 +:1025A0000068C0F3400008B90120A6E72D48006884 +:1025B00020F00300616808432A490860FEF7BEFE68 +:1025C000064609E0FEF7BAFE801B41F288318842D8 +:1025D00002D9032091E707E02248006800F00C00D0 +:1025E0006168B0EB810FEDD11D48006800F0070075 +:1025F000A84209D91A490D700846006800F0070082 +:10260000A84201D0012078E7207800F004000428D7 +:1026100007D11448006820F4E050E16808431149EC +:102620000860207800F00800082808D10D480068EC +:1026300020F46040216940EAC1000A49086000F0C6 +:1026400061F808490968C1F30311074A515CC840A1 +:102650000649086006480068FEF7A0FE00204CE727 +:10266000003C02400838024094E4000810000020BA +:10267000080000200F2202600D4A126802F00302D7 +:1026800042600B4A126802F0F0028260084A126847 +:1026900002F4E052C260064A126802F46042D208B4 +:1026A0000261044A126802F007020A6070470000E3 +:1026B00008380240003C02400148006870470000B2 +:1026C0001000002000B5FFF7F7FF04490968C1F3C7 +:1026D0008221034A515CC84000BD00000838024016 +:1026E000A4E4000800B5FFF7E7FF04490968C1F357 +:1026F0004231034A515CC84000BD00000838024026 +:10270000A4E400082DE9F047002400250026A14696 +:102710002548006800F00C0020B1042805D00828E6 +:102720003AD105E0DFF8849039E0DFF8849036E0B4 +:102730001D48001F006800F03F041B48001F006890 +:1027400000F4800078B11A481749091F0968C1F3DD +:102750008811A0FB01700146224600233846FDF790 +:1027600091FD05460EE011480F49091F0968C1F3A4 +:102770008811A0FB01700146224600233846FDF770 +:1027800081FD05460848001F0068C0F30140401C59 +:102790004600B5FBF6F902E0DFF8109000BF00BF7D +:1027A0004846BDE8F0870000083802400024F400E5 +:1027B00000127A00F8B504460CB90120F8BD207863 +:1027C00000F00100002874D0F948006800F00C0007 +:1027D00004280DD0F648006800F00C00082813D13A +:1027E000F348001F006800F48000B0F5800F0BD1A3 +:1027F000EF4808380068C0F34040002859D06068AE +:10280000002856D10120D9E700BF6068B0F5803FAD +:1028100008D1E7480838006840F48030E4490839B6 +:1028200008601EE06068B0F5A02F0DD1E0480838C0 +:10283000006840F48020DE490839086008460068D6 +:1028400040F4803008600CE0D9480838006820F473 +:102850008030D749083908600846006820F4802095 +:10286000086000BF606890B1FEF768FD054606E0AD +:10287000FEF764FD401B642801D903209EE7CC4885 +:1028800008380068C0F340400028F1D011E0FEF79E +:1028900055FD054606E0FEF751FD401B642801D9B1 +:1028A00003208BE7C24808380068C0F34040002886 +:1028B000F1D1207800F0020002285FD1BC48006806 +:1028C00000F00C0058B1BA48006800F00C0008286D +:1028D0001CD1B748001F006800F48000B0B9B448AC +:1028E00008380068C0F3400020B1E068012801D03A +:1028F000012063E7AE480838006820F0F80021693D +:1029000040EAC100AA490839086037E0E06800B32E +:102910000120A8490860FEF711FD054606E0FEF714 +:102920000DFD401B022801D9032047E7A0480838C5 +:102930000068C0F340000028F1D09D4808380068C6 +:1029400020F0F800216940EAC1009949083908607F +:1029500014E0002097490860FEF7F0FC054606E009 +:10296000FEF7ECFC401B022801D9032026E7904823 +:1029700008380068C0F340000028F1D1207800F04A +:10298000080008282CD16069A8B101208A49086094 +:10299000FEF7D4FC054606E0FEF7D0FC401B0228FB +:1029A00001D903200AE782486C300068C0F3400078 +:1029B0000028F1D014E000207F490860FEF7BEFC3B +:1029C000054606E0FEF7BAFC401B022801D90320A9 +:1029D000F4E677486C300068C0F340000028F1D17D +:1029E000207800F00400042870D1002770483830A7 +:1029F000006800F0805090B900BF002000906C4843 +:102A00003830006840F08050694938310860084625 +:102A1000006800F08050009000BF00BF01276748A9 +:102A2000006800F48070B0B96448006840F48070B9 +:102A300062490860FEF782FC054606E0FEF77EFC70 +:102A4000401B022801D90320B8E65C48006800F466 +:102A500080700028F2D000BFA068012808D1544837 +:102A60006830006840F001005149683108601DE09D +:102A7000A06805280DD14E486830006840F0040079 +:102A80004B49683108600846006840F00100086062 +:102A90000CE047486830006820F001004449683184 +:102AA00008600846006820F00400086000BFA068C5 +:102AB000A8B1FEF743FC054609E0FEF73FFC401BCA +:102AC00041F28831884202D9032077E626E038486F +:102AD00068300068C0F340000028EED013E0FEF735 +:102AE0002DFC054608E0FEF729FC401B41F2883129 +:102AF000884201D9032061E62D4868300068C0F3A0 +:102B000040000028EFD1012F07D129483830006854 +:102B100020F0805026493831086000BFA0690028A5 +:102B200045D02348006800F00C0008285DD0A0695B +:102B3000022845D100201F490866FEF7FFFB054625 +:102B400006E0FEF7FBFB401B022801D9032035E617 +:102B5000174808380068C0F340600028F1D1D4E974 +:102B600007010843616A40EA81110122A06AC2EBB1 +:102B7000500041EA00412C20005D41EA00600C4910 +:102B8000091F086001200B490866FEF7D7FB0546C0 +:102B900006E0FEF7D3FB401B022801D903200DE617 +:102BA000034808380068C0F340600028F1D049E0CD +:102BB0000838024000004742800E47420070004043 +:102BC000002021490866FEF7B9FB054606E0FEF73E +:102BD000B5FB401B022801D90320EFE51B48006824 +:102BE000C0F340600028F2D12CE0A069012800D198 +:102BF000E4E51648001D0668A069012820D006F407 +:102C00008001E06981421BD106F03F01206A8142C8 +:102C100016D147F6C0703040616AB0EB811F0FD10A +:102C200006F440310122A06AC2EB5000B1EB004F24 +:102C300006D106F070612C20005DB1EB006F01D071 +:102C40000120BBE50020B9E5000047420038024002 +:102C500010B50023046804F1500303EB81031A60EC +:102C600010BD000070B505460B46164600242868C6 +:102C700040680E4900EA0104200CD870C4F3042017 +:102C8000587004F03F009870C4F3423018705EB979 +:102C9000D87801F0AEFED870587801F0AAFE5870CE +:102CA000987801F0A6FE9870002070BD3FFFFF00ED +:102CB00070B504460B46164600252068806A5860A9 +:102CC00020680069C0F30E009860206800680E4913 +:102CD00000EA0105C5F305401870C5F306205870D9 +:102CE00005F07F009870A80DD8705EB9187801F0D3 +:102CF00080FE1870587801F07CFE5870987801F0CA +:102D000078FE9870002070BD7F7F7F0070B504460C +:102D100001250CB9012070BD607F20B9002020770B +:102D2000204600F045F80220607700BFCA202168E5 +:102D3000486253202168486200BF204601F072FEBD +:102D40000546EDB920688068184908402168886008 +:102D500021696068084361690843216889680843FC +:102D6000216888602168E06808612068016920891D +:102D700041EA004021680861204601F078FE0546DE +:102D80006DB92068006C20F48020216808642068F8 +:102D9000006CA1690843216808640120607700BFC6 +:102DA000FF202168486200BF2846B4E7BFFF8FFFBD +:102DB0001FB504460020009001900290039009493D +:102DC000206888420CD102200090C0010390684620 +:102DD000FFF7BEFA08B1FDF7EDFE012002490860D9 +:102DE0001FBD0000002800403C0E47422DE9F04185 +:102DF00005460C4617464FF0000800BF287F012803 +:102E000002D10220BDE8F0810120287700BF022016 +:102E100068774FB9607800F01000102804D160780E +:102E200000F0EF000A30607087B9E07801F0ECFD47 +:102E30000304607801F0E8FD43EA0023A07801F084 +:102E4000E3FD0343207843EA403809E0E0780004DA +:102E5000617840EA0120A1780843217840EA4138AE +:102E600000BFCA202968486253202968486200BF11 +:102E7000284601F0D7FD064646B90B4808EA00008F +:102E800029684860284601F0F2FD06460EB9012087 +:102E9000687700BFFF202968486200BF00BF00209C +:102EA000287700BF3046ADE73FFFFF002DE9F04136 +:102EB00004460D4617464FF0000800BF207F01284A +:102EC00002D10220BDE8F0810120207700BF02205E +:102ED0006077CFB92068806800F0400000B102E060 +:102EE0000020E87000BF287801F08EFD03046878A8 +:102EF00001F08AFD43EA0023A87801F085FD034331 +:102F0000E87843EA805812E02068806800F04000CA +:102F100000B102E00020E87000BF28780004697862 +:102F200040EA0120A9780843E97840EA815800BFC7 +:102F3000CA202168486253202168486200BF2046A9 +:102F400001F070FD0646B6B9124808EA0000216893 +:102F500008602068806820F4802021688860D5E9B6 +:102F60000301084321688968084321688860204676 +:102F700001F07DFD06460EB90120607700BFFF20FD +:102F80002168486200BF00BF0020207700BF3046A4 +:102F900098E700007F7F7F0070B504460025206819 +:102FA000C06820F0A0002168C860FEF7C7F9054698 +:102FB00007E0FEF7C3F9401BB0F57A7F01D9032083 +:102FC00070BD2068C06800F020000028F1D000200B +:102FD000F6E70000F0B589B004460E46002703204E +:102FE00084F83400606C032820D0B6F5805F04D1EB +:102FF000A06B40F08050A0631CE0B6F5006F07D1D5 +:10300000204602F0C5FB0546A06B2843A06311E0F3 +:103010003EB9204602F088FB0546A06B2843A0631A +:1030200008E0A06B40F00060A06303E0A06B40F0FC +:103030008050A063A06B38B11748216888630120D5 +:1030400084F83400012713E060680390A0680490BE +:10305000E0680590069660690790A069089006A848 +:1030600007C88DE80700206803A90EC901F03BFDE1 +:103070004FF40071206801F0A7FD054635B1064800 +:1030800021688863A06B2843A0630127012084F88E +:103090003400384609B0F0BDFF054000704700001D +:1030A00010B50246506E800F0870506EC0F38360FA +:1030B0004870506EC0F301608870506E000CC8708C +:1030C000B2F86400000A087192F864004871906ECA +:1030D000000DC880906EC0F3034008726820805ACB +:1030E000C0F3C03048726820805AC0F380308872C4 +:1030F0006820805AC0F34030C8726820805AC0F3FC +:103100000030087300204873506C002836D16820C6 +:10311000805A8005030DD06E43EA90700861D06E2E +:10312000C0F3C2600875D06EC0F302604875D06EFF +:10313000C0F342508875D06EC0F38240C875D06E1F +:10314000C0F3C23008760869401C50650B7E506D94 +:1031500003F007039B1C01249C4060435065087AE0 +:1031600000F00F03012098409065D2E915035B0A37 +:103170005843D0654FF40073136621E0506C01286A +:1031800013D16820805C8006830AD06E43EA104029 +:1031900008610869401C83025365536DD3654FF481 +:1031A00000739365936D13660AE02E481368986365 +:1031B000906B40F080509063012082F8340010BD85 +:1031C0006C20805AC0F3803001F8190F6C20805AAF +:1031D000C0F3C61048706C20805C00F07F008870DF +:1031E000106FC00FC870106FC0F341700871106F7E +:1031F000C0F382604871106FC0F383508871106F04 +:10320000C0F34050C87100200872106FC0F3004036 +:1032100048727020805AC0F3C03088727020805A83 +:10322000C0F38030C8727020805AC0F340300873F9 +:103230007020805AC0F3003048737020805AC0F369 +:10324000812088737020805AC0F30120C8737020D9 +:10325000805CC0F3460008740120487419390020CE +:10326000ADE70000FF0540000246506C0860906C1E +:103270004860D06C8860106DC860506D0861906DBA +:103280004861D06D8861106EC86100207047F8B544 +:103290000446002000906946204602F02DFA0546BB +:1032A00015B1A06B2843A0630098C0F343263046B5 +:1032B000F8BD10B504460CB9012010BD94F83400D7 +:1032C00020B900202077204600F06AF8032084F817 +:1032D0003400204600F00CF808B10120EDE7002092 +:1032E000A0632063012084F834000020E5E700009B +:1032F00070B58AB0044600200490059006900790AF +:1033000008907620099007A807C88DE80700206874 +:1033100004A90EC901F0E7FB064616B101200AB068 +:1033200070BD00201C490860206801F0F6FB0120F8 +:103330001949A039C1F8A0000220FDF7D9FE2046A6 +:1033400002F074F905463DB1012084F83400A06B09 +:103350002843A0630120E2E7204602F0E5F8054695 +:103360003DB1012084F83400A06B2843A063012004 +:10337000D5E74FF40071206801F026FC05464DB1F9 +:10338000064821688863A06B2843A063012084F865 +:103390003400C4E70020C2E7A0802542FF054000BA +:1033A00010B586B00446142101A8FCF7B5FF5449B6 +:1033B000206888427ED100BF0020009051480068FC +:1033C00040F400604F4908600846006800F400605F +:1033D000009000BF00BF00BF002000904948143893 +:1033E000006840F004004749143908600846006846 +:1033F00000F00400009000BF00BF00BF002000905C +:103400000846006840F0080008600846006800F0C0 +:103410000800009000BF00BF4FF4F8500190022058 +:10342000029001200390022004900C20059001A935 +:103430003548FDF771FE0420019002200290012022 +:103440000390022004900C20059001A92F48FDF75D +:1034500063FE2F482F4908604FF00060486000214C +:103460002C488160C1604FF4806101618900416135 +:10347000890081612021C161002101620421416232 +:10348000032181624FF40001C16289100163FDF7DD +:103490006FFD08B1FDF78EFB00BF1E4820648463FA +:1034A00000BF1B4848301C4908604FF0006048606E +:1034B000402100E021E0184881600021C1604FF404 +:1034C0008061016189004161890081612021C161C0 +:1034D0000021016204214162032181624FF4000155 +:1034E000C16289100163FDF743FD08B1FDF762FB7E +:1034F00000BF0948E063846300BF06B010BD000050 +:10350000002C01404438024000080240000C0240F8 +:103510005864024094050020F40500202DE9F04392 +:1035200087B004460F4691461D46C8463FB9A06B7A +:1035300040F00060A063012007B0BDE8F08394F87C +:10354000340001287ED10020A06308EB0501E06D66 +:10355000814205D9A06B40F00070A0630120EBE729 +:10356000032084F8340000202168C8622068C06B02 +:1035700040F22A3108432168C8633848216CC86387 +:103580003748216CC8640020216C08650021206C3C +:103590008160206C0068006820F0C000216C8968A0 +:1035A0000843216C096808606A029308226802F1E6 +:1035B00080013A46206CFDF751FD80B12068C06B58 +:1035C00020F495702168C863264821688863A06B41 +:1035D00040F08040A063012084F83400ACE7012073 +:1035E00021490860606C012801D04FEA48284FF05B +:1035F000FF30019068020290902003900220049016 +:10360000002005900120069001A9206801F046FAEB +:10361000012D07D9822020634146206801F03CFB40 +:10362000064606E0812020634146206801F050FBF9 +:10363000064676B10B4821688863A06B3043A063CF +:10364000012000E007E084F834000020206301201E +:1036500072E7002070E702206EE700008D5300083B +:1036600019530008FF0540008C85254210B504461B +:10367000FDF776F910BD00002DE9F04387B0044650 +:10368000884691461D464F46B8F1000F07D1A06B02 +:1036900040F00060A063012007B0BDE8F08394F81B +:1036A0003400012874D10020A0637919E06D8142B3 +:1036B00005D9A06B40F00070A0630120ECE7032067 +:1036C00084F8340000202168C8622068C06B40F292 +:1036D0001A2108432168C8633848E16BC863384839 +:1036E000E16BC8640020E16B0865606C012800D0C4 +:1036F0007F02012D07D9A02020633946206801F000 +:10370000C5FB064606E0902020633946206801F09C +:10371000D9FB064666B12B4821688863A06B30430D +:10372000A063012084F83400002020630120B3E767 +:103730000120254908604021E06B8160E06B006852 +:10374000006820F0C000E16B89680843E16B0968FC +:10375000086069028B08216801F180024146E06B34 +:10376000FDF77CFCA8B12068C06B40F21A218843A9 +:103770002168C863134821688863A06B40F08040CB +:10378000A063012084F8340000202063012083E737 +:1037900011E04FF0FF3001906802029090200390FA +:1037A0000020049005900120069001A9206801F0F6 +:1037B00075F9002070E702206EE70000D55300087D +:1037C00019530008FF0540008C85254210B50446BA +:1037D0000CB9012010BD606A38B96068B0F5827F0D +:1037E00000D105E00021E16102E000212161616179 +:1037F0000021A16294F8510028B9002084F85000FB +:10380000204600F047F8022084F851002068006844 +:1038100020F0400021680860A08800F482702189AF +:1038200001F404410843A18901F400610843217CAB +:1038300001F002010843217D01F001010843218BC1 +:1038400001F400710843217F01F038010843202171 +:10385000095D01F080010843218D01F40051084306 +:10386000216808600421A06901EA104094F824103E +:1038700001F010010843216848602068C06920F405 +:1038800000602168C86100206065012084F8510053 +:1038900000209FE710B586B00446142101A8FCF76C +:1038A0003BFD1B49206888422FD100BF00200090BB +:1038B0001848006840F4004016490860084600684F +:1038C00000F40040009000BF00BF00BF0020009047 +:1038D00010481038006840F002000E4910390860A6 +:1038E0000846006800F00200009000BF00BF3820CA +:1038F00001900220029000200390032004900620F3 +:10390000059001A90448FDF707FC06B010BD0000B2 +:10391000003C004040380240000402402DE9FF5FB7 +:103920000446884691461D460E9E012002900020C6 +:10393000019000BF94F85000012803D1022004B088 +:10394000BDE8F09F012084F8500000BFFDF7F6FCB1 +:10395000074694F851B060680390AA46BBF1010F86 +:103960000BD00398B0F5827F04D1A06810B9BBF1E9 +:10397000040F02D002200190DBE0B8F1000F03D069 +:10398000B9F1000F00D015B901200190D1E094F8F1 +:103990005100042802D0052084F851000020606501 +:1039A000C4F83890E587A587C4F83080E586A586F9 +:1039B000206460642068006800F04000402805D062 +:1039C0002068006840F0400021680860E068B0F5B9 +:1039D000006F4AD1606810B1BAF1010F09D1206BB4 +:1039E00000882168C860206B801C2063E08E401E28 +:1039F000E08633E02068806800F00200022810D1E1 +:103A0000E08E70B1029801280BD1206B00882168EC +:103A1000C860206B801C2063E08E401EE086002082 +:103A200002902068806800F0010068B1E08F58B112 +:103A30002068C068A16B0880A06B801CA063E08F29 +:103A4000401EE08701200290FDF778FCC01BB042C9 +:103A500004D3701C10B1032001906AE0E08E0028AE +:103A6000C8D1E08F0028C5D14AE0606810B1BAF132 +:103A7000010F09D1206B007821680873206B401C6E +:103A80002063E08E401EE08634E02068806800F00D +:103A90000200022810D1E08E70B1029801280BD1EB +:103AA000206B007821680873206B401C2063E08E37 +:103AB000401EE086002002902068806800F001002F +:103AC00068B1E08F58B12068C068A16B0870A06B26 +:103AD000401CA063E08F401EE08701200290FDF7AC +:103AE0002DFCC01BB04201D3701C00B916B90320D5 +:103AF00001901EE0E08E0028C7D1E08F0028C4D1DD +:103B00003A463146204601F06BFF20B1012001907A +:103B1000202060650DE0A06850B900BF0020009033 +:103B20002068C068009020688068009000BF00BFD7 +:103B300000BF012084F8510000BF002084F850002D +:103B400000BF0198FBE67047704710B504460CB9FA +:103B5000012010BD94F83D0028B9002084F83C00F5 +:103B6000204600F025F8022084F83D00211D206841 +:103B700002F070F8012084F8460000BF84F83E008F +:103B800001213F200155402001554120015500BF32 +:103B900000BF012084F84200432001554420015514 +:103BA0004520015500BF012084F83D000020D0E7EA +:103BB00070470000014691F83D00012801D0012026 +:103BC0007047022081F83D000868C06840F001009D +:103BD0000B68D8601A4B086898421BD00868B0F18F +:103BE000804F17D0174B0868984213D0164B0868BF +:103BF00098420FD0154B086898420BD0144B0868B8 +:103C0000984207D0134B0868984203D0124B0868BB +:103C100098420CD10868806800F00702062A0CD090 +:103C20000868006840F001000B68186005E008684B +:103C3000006840F001000B6818600020C0E7000039 +:103C4000000001400004004000080040000C00405B +:103C5000000401400040014000180040704710B5CA +:103C6000044620680069C0F34000D8B12068C068ED +:103C7000C0F34000B0B16FF002002168086101207C +:103C800020772068806900F0030018B12046FFF714 +:103C9000E5FF05E0204600F0ADF8204600F0ABF867 +:103CA0000020207720680069C0F38000D8B1206828 +:103CB000C068C0F38000B0B16FF0040021680861F3 +:103CC000022020772068806900F4407018B12046F7 +:103CD000FFF7C4FF05E0204600F08CF8204600F016 +:103CE0008AF80020207720680069C0F3C000D8B1AE +:103CF0002068C068C0F3C000B0B16FF00800216850 +:103D00000861042020772068C06900F0030018B122 +:103D10002046FFF7A3FF05E0204600F06BF82046A1 +:103D200000F069F80020207720680069C0F30010D7 +:103D3000D8B12068C068C0F30010B0B16FF01000B7 +:103D400021680861082020772068C06900F440706D +:103D500018B12046FFF782FF05E0204600F04AF840 +:103D6000204600F048F8002020772068006900F025 +:103D7000010058B12068C06800F0010030B16FF058 +:103D8000010021680861204600F036F820680069CB +:103D9000C0F3C01058B12068C068C0F3C01030B183 +:103DA0006FF08000216808612046FFF7CCFE206894 +:103DB0000069C0F3801058B12068C068C0F380105B +:103DC00030B16FF0400021680861204600F020F813 +:103DD00020680069C0F3401058B12068C068C0F383 +:103DE000401030B16FF02000216808612046FFF7D5 +:103DF000ABFE10BD7047704710B5044603492068FC +:103E0000884201D1FDF7A0FA10BD0000001000406B +:103E100070477047704700002DE9F84F044620684E +:103E200005682068C668206847694FF00009CA46DF +:103E300005F00F09B9F1000F0AD105F0200038B1E3 +:103E400006F0200020B1204601F0C0FFBDE8F88F49 +:103E5000B9F1000F7CD007F0010018B906F490709A +:103E6000002875D005F0010030B106F4807018B15B +:103E7000206C40F00100206405F0040030B107F030 +:103E8000010018B1206C40F00200206405F002002F +:103E900030B107F0010018B1206C40F0040020643C +:103EA00005F0080048B106F0200010B907F0010045 +:103EB00018B1206C40F008002064206C002846D027 +:103EC00005F0200028B106F0200010B1204601F0D6 +:103ED0007DFF20684069C0F3801A206C00F0080064 +:103EE00010B9BAF1000F2DD0204601F029FF20684B +:103EF000406900F04000402820D100BF00BF216889 +:103F0000143151E8001F21F040002168143141E8CC +:103F10000002002AF3D100BFA06B50B17548A16B1D +:103F20000865A06BFCF7ECFE88B1A06B016D8847BB +:103F30000DE02046FFF76EFF09E009E02046FFF79D +:103F400069FF04E02046FFF765FF002020647DE75D +:103F5000206B012876D105F01000002872D006F001 +:103F600010000028FAD000BF0020009020680068F0 +:103F7000009020684068009000BF00BF2068406942 +:103F800000F0400040285ED1A06B006840681FFA36 +:103F900080F8B8F1000F54D0A08D404551DDA4F851 +:103FA0002E80A06BC069B0F5807F43D000BF00BFFA +:103FB00021680C3151E8001F21F4807021680C3118 +:103FC00041E80002002AF3D100BF00BF00BF216812 +:103FD000143151E8001F21F001002168143141E83B +:103FE0000002002AF3D100BF00BF00BF21681431D6 +:103FF00051E8001F21F040002168143141E800021F +:10400000002AF3D100BF202084F83E000020206366 +:1040100000BF00BF21680C3151E8001F21F01000E3 +:1040200021680C3141E80002002AF3D100BFA06BE7 +:10403000FCF710FEA08DE28D801A81B22046FFF7BA +:10404000E8FE03E740E0A08DE18D401A1FFA80F8FA +:10405000E08DC0B3B8F1000F35D000BF00BF2168BC +:104060000C3151E8001F21F4907021680C3141E8B7 +:104070000002002AF3D100BF00BF00BF2168143145 +:1040800051E8001F21F001002168143141E80002CD +:10409000002AF3D100BF202084F83E0000202063D6 +:1040A00000BF00BF21680C3151E8001F21F0100053 +:1040B00021680C3141E80002002AF3D100BF4146DB +:1040C0002046FFF7A6FEC1E605F0800030B106F0FD +:1040D000800018B1204602F030F8B7E605F0400045 +:1040E00030B106F0400018B1204601F05FFEADE6A9 +:1040F00000BFABE62D5D000810B504460CB90120E9 +:1041000010BDA06900B100E000BF94F83D0028B9DF +:10411000002084F83C00204600F028F8242084F891 +:104120003D002068C06820F400502168C860204627 +:1041300001F0C8FE2068006920F490402168086101 +:104140002068406920F02A00216848612068C06822 +:1041500040F400502168C86000202064202084F8CA +:104160003D0084F83E000020CAE7000010B586B08C +:104170000446142101A8FCF7CFF81F4920688842A3 +:1041800038D100BF002000901C48006840F01000AB +:104190001A4908600846006800F01000009000BF4F +:1041A00000BF00BF0020009014481438006840F0A1 +:1041B00001001249143908600846006800F0010047 +:1041C000009000BF00BF4FF4C06001900220029039 +:1041D00000200390032004900720059001A90848BF +:1041E000FCF79AFF002205212520FDF76BF9252019 +:1041F000FDF758F906B010BD0010014044380240E8 +:104200000000024070B504460D46164694F83E0084 +:10421000202816D105B10EB9012070BD00BF94F859 +:104220003C00012801D10220F7E7012084F83C007E +:1042300000BF0020206332462946204601F058FF87 +:10424000EBE70220E9E7000070B50446104920685A +:1042500088421BD10F490988481CC11700EB5161E6 +:10426000C911A0EBC1118DB20B480088854207D05F +:104270000A4800780A49074A128888540548058088 +:10428000012206490748FFF7BDFF00BF70BD0000CF +:1042900000100140840200208602002088020020D5 +:1042A0006C130120AC0600202DE9F84F04460E46A1 +:1042B000174699464FF0000A94F83D0020285AD13D +:1042C00006B117B90120BDE8F88F00BF94F83C0093 +:1042D000012801D10220F6E7012084F83C0000BF4C +:1042E00000202064212084F83D00FDF727F8824655 +:1042F000A784E784A068B0F5805F04D1206910B975 +:104300000025B04602E035464FF0000800BF00200F +:1043100084F83C0000BF1BE0534600228021204669 +:10432000CDF8009001F039FF08B10320CBE745B983 +:10433000B8F80000C0F308002168486008F10208DE +:1043400003E02878216848606D1CE08C401EE08402 +:10435000E08C0028E0D15346002240212046CDF8D1 +:10436000009001F01AFF08B10320ACE7202084F888 +:104370003D000020A7E70220A5E7704700BFFEE749 +:1043800030B50B46002100BF16E00A24B4EB107FC5 +:1043900005D9302404EB107403F8114005E04124E2 +:1043A00004EB10740A3C03F81140000100254C0096 +:1043B000641C1D554C1CE1B29142E6DB30BD00008F +:1043C00008B500BF002000900E48006840F480004F +:1043D0000C4908600846006800F48000009000BFA7 +:1043E00000BF00220F213B20FDF76CF83B20FDF7BA +:1043F00059F800220F214520FDF764F84520FDF70C +:1044000051F808BD3038024010B503490348FCF7A5 +:10441000D4FB0349087010BDB100002014E500086A +:10442000B000002000B587B01C2206496846FBF7A3 +:104430005AFF0021684606F07FFA0349086007B07A +:1044400000BD000070E400080000002000B587B047 +:10445000142102A8FBF760FF00BF002001907F48F5 +:10446000006840F010007D4908600846006800F0D0 +:104470001000019000BF00BF00BF0020019008465F +:10448000006840F0040008600846006800F004007E +:10449000019000BF00BF00BF0020019008460068E7 +:1044A00040F0200008600846006800F020000190FD +:1044B00000BF00BF00BF002001900846006840F028 +:1044C000800008600846006800F08000019000BF8E +:1044D00000BF00BF002001900846006840F00100C6 +:1044E00008600846006800F00100019000BF00BFAE +:1044F00000BF002001900846006840F002000860FC +:104500000846006800F00200019000BF00BF00BF35 +:10451000002001900846006840F04000086008460E +:10452000006800F04000019000BF00BF00BF002005 +:1045300001900846006840F00800086008460068DE +:1045400000F00800019000BF00BF00224FF40051AE +:104550004348FCF7EDFE00224FF4C0514148FCF700 +:10456000E7FE4FF6FF7002900320039000200490B6 +:1045700002A93D48FCF7D0FD4FF400500290012005 +:10458000039000200490059002A93548FCF7C4FD73 +:104590004FF6FF700290032003900020049002A9C0 +:1045A0003248FCF7B9FDFF20029003200390002061 +:1045B000049002A92A48FCF7AFFD48F2FF100290D0 +:1045C000032003900020049002A92948FCF7A4FDD1 +:1045D0004FF6C7300290032003900020049002A9F8 +:1045E0002448FCF799FD4FF6FF70029003200390DA +:1045F0000020049002A92048FCF78EFD4FF4806053 +:10460000029000200390049002A91A48FCF784FD50 +:104610004CF2FB700290032003900020049002A94A +:104620001048FCF779FD4FF4C05002900120039030 +:1046300000200490059002A90A48FCF76DFD4FF494 +:10464000005002904FF4881003900020049002A9BB +:104650000448FCF761FD07B000BD0000303802409F +:1046600000080240000C024000100240001402400A +:1046700000000240000402400018024010B50A4841 +:104680000A490860002048607F2108488160FF21B6 +:10469000C1600021016141618161FEF737FB08B112 +:1046A000FCF788FA10BD000000280040F00400204C +:1046B0007047000010B50E480E4908604FF4827034 +:1046C000486000210B488160C160016141614FF485 +:1046D000007181610021C1610162416281620A2130 +:1046E000C162FFF773F808B1FCF764FA10BD00006F +:1046F000003C00405406002010B50B480B490860F0 +:104700004FF4E1304860002108488160C1600161D8 +:104710000C21416100218161C161FFF7EDFC08B10D +:10472000FCF748FA10BD000000100140AC06002064 +:1047300010B500220D490E4802F0F1FB08B1FCF75C +:1047400039FA0C490A4802F01FFF08B1FCF732FAA7 +:104750000949074801F0F2FF08B1FCF72BFA0448B9 +:1047600003F014F808B1FCF725FA10BD340100205D +:10477000D0F40020A80100208401002000BFFEE743 +:1047800000BFFEE710B50248FDF7CCF810BD0000F1 +:10479000AC0901202DE9F04704460D46266837464E +:1047A000D6F8408007F5306000EB4510D0F808904F +:1047B000104880450BD909F40040B0F5004F06D1F0 +:1047C0004FF4004107F5306000EB45108160204652 +:1047D000FDF767FD0748804508D92069012805D104 +:1047E00004F2C4420121206803F066FD0020BDE808 +:1047F000F08700000A30544F2DE9F04705460C467B +:10480000D5F800904E46D9F840A006F5306000EB90 +:104810004410D0F808802869012855D108F0080014 +:1048200008280FD1434882450BD908F40040B0F561 +:10483000004F7BD14FF4004106F5306000EB44108F +:10484000816073E008F02000202806D1202106F5C1 +:10485000306000EB4410816068E008F02800002818 +:1048600064D1344882450CD908F40040B0F5004FBB +:1048700007D14FF4004106F5306000EB4410816031 +:1048800054E004EBC40105F51F7000EB810706F549 +:10489000306000EB4410F9690069C0F31200081A97 +:1048A000386264B9B86930B905F2C4420121286898 +:1048B00003F002FD03E0396A386908443861E1B267 +:1048C0002846FCF795FE31E01B4882451BD108F4D1 +:1048D0000040B0F5004F07D14FF4004106F53060BD +:1048E00000EB4410816021E008F02000202805D171 +:1048F000202106F5306000EB44108160E1B22846CB +:10490000FCF776FE12E06CB904EBC40105F51F70EC +:1049100000EB8100806928B905F2C44200212868B3 +:1049200003F0CAFCE1B22846FCF762FE0020BDE8B5 +:10493000F08700000A30544F0A31544F2DE9F84FE8 +:1049400007460E46D7F80090C84606EBC60107F1A9 +:104950003C0000EB8104A169206A884202D9012051 +:10496000BDE8F88F216AA069451AE068A84200D224 +:10497000E568E81C4FEA900A17E0216AA069451A29 +:10498000E068A84200D2E568E81C4FEA900A387C4B +:10499000ABB2F2B200904846216904F01FF92069D9 +:1049A00028442061206A2844206208F5106000EB4A +:1049B0004610806980B2504506D3A169206A8842BA +:1049C00002D2A0690028D8D1216AA06988420ED8F5 +:1049D00006F00F01012000FA01FB40F6340050F808 +:1049E000080020EA0B0040F6340141F808000020DE +:1049F000B6E7014600BF080900EB8000420001F065 +:104A00000F001044C0B270470146002204E0501C61 +:104A1000C2B2A1F10A00C1B20A29F8D2100741EAD4 +:104A20001060704770B50446002600252068C068F5 +:104A300000F04000C8B92068C06840F080002168DC +:104A4000C860FCF77BFC064608E0FCF777FC801B9F +:104A5000B0F57A7F02D90420607701252068C0680C +:104A600000F0400008B9012DEFD1284670BD70B5A7 +:104A7000044600252068C06820F080002168C860D6 +:104A80002068806800F0200030B92046FEF784FAE4 +:104A900010B1042060770125284670BD10B502468C +:104AA00000230868506248689062D1E902042043FC +:104AB0000C6920434C6920430343D06A20F0F7007F +:104AC0001843D062002010BD01460869C0B270478B +:104AD0000146086800F003007047024602F1140026 +:104AE0004318186870470FB410B504460021DDE97B +:104AF00003021043059A1043069A1043079A104385 +:104B0000089A10430143606847F6FF6290430843E8 +:104B10006060002010BC5DF814FB014603200860B3 +:104B2000002070470146D1F88000704710B502465A +:104B3000002308689060D1E901042043CC68204339 +:104B40000C6920430343D0686FF30B001843D06017 +:104B5000002010BD70B585B005460C460094372086 +:104B6000019040200290002003904FF48060049058 +:104B700069462846FFF7DAFF41F288323721284696 +:104B800000F0DCF90646304605B070BD70B585B062 +:104B900005460C460B4820430090292001904020F8 +:104BA0000290002003904FF48060049069462846EC +:104BB000FFF7BCFF284600F0C9FA0646304605B0AC +:104BC00070BD00000000108070B585B005460C4631 +:104BD00000941020019040200290002003904FF498 +:104BE0008060049069462846FFF7A0FF41F28832B2 +:104BF0001021284600F0A2F90646304605B070BDE7 +:104C000070B585B005460C46009406200190402002 +:104C10000290002003904FF480600490694628467B +:104C2000FFF784FF41F288320621284600F086F91A +:104C30000646304605B070BD30B585B0044600204C +:104C400000900190029003904FF4806004906946B8 +:104C50002046FFF76BFF204600F050F90546284636 +:104C600005B030BD30B585B004464FF4D570009026 +:104C70000820019040200290002003904FF48060B3 +:104C8000049069462046FFF751FF204600F0E6FAFF +:104C90000546284605B030BD70B585B005460C46C2 +:104CA00000941220019040200290002003904FF4C5 +:104CB0008060049069462846FFF738FF41F2883249 +:104CC0001221284600F03AF90646304605B070BD7C +:104CD00070B585B005460C46009411200190402027 +:104CE0000290002003904FF48060049069462846AB +:104CF000FFF71CFF41F288321121284600F01EF90F +:104D00000646304605B070BDF0B585B0064614467F +:104D10001D4600940720019040200290002003903F +:104D20004FF48060049069463046FFF7FFFE41F281 +:104D300088320721304600F001F90746384605B0B1 +:104D4000F0BD30B585B004460020009002200190EF +:104D5000C0200290002003904FF4806004906946C8 +:104D60002046FFF7E3FE204600F0BEF90546284640 +:104D700005B030BD70B585B005460C4600940920DD +:104D80000190C0200290002003904FF480600490B6 +:104D900069462846FFF7CAFE284600F0A5F90646F0 +:104DA000304605B070BD30B585B004460020009097 +:104DB0003320019040200290002003904FF4806047 +:104DC000049069462046FFF7B1FE41F28832332154 +:104DD000204600F0B3F80546284605B030BD70B552 +:104DE00085B005460C4600940D20019040200290AD +:104DF000002003904FF48060049069462846FFF736 +:104E000095FE41F288320D21284600F097F80646BB +:104E1000304605B070BD70B585B005460C46002023 +:104E200000900320019040200290002003904FF456 +:104E30008060049069462846FFF778FE22460321E9 +:104E4000284600F0AFF90646304605B070BD0000B8 +:104E500030B585B00446002000900C200190402021 +:104E60000290002003904FF4806004906946204631 +:104E7000FFF75CFE044A0C21204600F05FF805466F +:104E8000284605B030BD000000E1F50570B585B0DD +:104E900005460C4600941920019040200290002005 +:104EA00003904FF48060049069462846FFF73EFE69 +:104EB00041F288321921284600F040F80646304673 +:104EC00005B070BD70B585B005460C46009418203D +:104ED000019040200290002003904FF480600490E5 +:104EE00069462846FFF722FE41F2883218212846FB +:104EF00000F024F80646304605B070BD01460E4865 +:104F00000068C0084FF47A73B0FBF3F041F28833C5 +:104F100000FB03F200BF101EA2F1010202D14FF00C +:104F200000407047486B00F080000028F3D0C52097 +:104F300088630020F5E70000100000202DE9F04311 +:104F400005460F46904666480068C0084FF47A71DF +:104F5000B0FBF1F000FB08F900BFB9F10000A9F1C6 +:104F6000010903D14FF00040BDE8F0836E6B06F0FD +:104F700045000028F1D006F400600028EDD1686BF0 +:104F800000F0040010B10420A863EDE7686B00F0A6 +:104F9000010010B10120A863E6E7C520A8632846F8 +:104FA000FFF792FDB84201D00120DDE7002128463D +:104FB000FFF793FD04464B48204008B90020D3E793 +:104FC00004F00040B0F1004F02D14FF00070CBE789 +:104FD00004F08040B0F1804F01D14020C4E704F0DC +:104FE0000050B0F1005F01D18020BDE704F0805097 +:104FF000B0F1805F02D14FF48070B5E704F000603B +:10500000B0F1006F02D14FF40070ADE704F08060A2 +:10501000B0F1806F02D14FF48060A5E704F080709A +:10502000B0F1807F02D14FF400609DE704F40000EE +:10503000B0F5000F02D14FF4805095E704F48000E2 +:10504000B0F5800F02D14FF400508DE704F400104A +:10505000B0F5001F02D14FF4804085E704F48010C2 +:10506000B0F5801F02D14FF400407DE704F48020AA +:10507000B0F5802F02D14FF4003075E704F4003012 +:10508000B0F5003F02D14FF480206DE704F480308A +:10509000B0F5803F02D14FF4002065E704F40040F2 +:1050A000B0F5004F02D14FF480105DE704F480406A +:1050B000B0F5804F02D14FF4001055E704F40050D2 +:1050C000B0F5005F02D14FF480004DE704F0080016 +:1050D000082801D1000547E74FF4803044E700007D +:1050E0001000002008E0FFFD10B5014616480068DA +:1050F000C0084FF47A74B0FBF4F041F2883400FB3E +:1051000004F300BF181EA3F1010302D14FF00040C9 +:1051100010BD4A6B02F045000028F3D002F4006095 +:105120000028EFD1486B00F0040010B10420886320 +:10513000EEE7486B00F0010010B101208863E7E75B +:10514000C52088630020E3E71000002010B5014669 +:1051500013480068C0084FF47A74B0FBF4F041F2D1 +:10516000883400FB04F300BF181EA3F1010302D131 +:105170004FF0004010BD4A6B02F045000028F3D00C +:1051800002F400600028EFD1486B00F0040010B179 +:1051900004208863EEE7C52088630020EAE700006A +:1051A000100000202DE9F04304460F4690462A489F +:1051B0000068C0084FF47A71B0FBF1F041F2883119 +:1051C00000FB01F900BFB9F10000A9F1010903D109 +:1051D0004FF00040BDE8F083666B06F04500002804 +:1051E000F1D006F400600028EDD1606B00F00400FF +:1051F00010B10420A063EDE7606B00F0010010B176 +:105200000120A063E6E72046FFF75EFCB84201D02C +:105210000120DFE7C520A06300212046FFF75DFCE9 +:10522000054605F4604020B9280CA8F800000020CD +:10523000D0E705F48040B0F5804F02D14FF4005024 +:10524000C8E705F40040B0F5004F02D14FF480509C +:10525000C0E74FF48030BDE71000002010B50146D4 +:1052600018480068C0084FF47A74B0FBF4F041F2BB +:10527000883400FB04F300BF181EA3F1010302D120 +:105280004FF0004010BD4A6B02F045000028F3D0FB +:1052900002F400600028EFD1486B00F0040010B168 +:1052A00004208863EEE7486B00F0010010B1012094 +:1052B0008863E7E7486B00F0400008B1402088634E +:1052C0000020DFE71000002010B504460120074948 +:1052D0000870FBF701FB28B90448007820F00100B2 +:1052E000024908700148007810BD0000A8000020A5 +:1052F00070B5044605F084FA054604E0FBF7ECFAC5 +:1053000008B9002070BD05F07BFA401BA042F5D320 +:105310004FF0FF30F6E700002DE9F0410646B46B90 +:105320003046FBF701FD02282CD0206C476DE06B66 +:10533000D0F85480012F02D0B8F1010F1FD11248CC +:10534000216888632068C06B20F49D702168C86361 +:10535000A06B40F08040A0632046FDF798FF054613 +:10536000062D01D0052D05D12068FFF771FDA16B39 +:105370000843A063012084F8340000202063204605 +:10538000FDF78CFEBDE8F081FF05400070B50646D4 +:10539000B46B206B82280AD12068FFF759FD0546BF +:1053A0002DB1A06B2843A0632046FDF777FE20684F +:1053B000C06A20F008002168C86240F23A502168B3 +:1053C0008863012084F83400002020632046FEF723 +:1053D0004DF970BD0146886B0268D26B42F4807251 +:1053E0000368DA6370472DE9F04389B004460F463D +:1053F000FBF7A4FF81464FF00008002001900290C7 +:105400003E4608212068FFF7DFFB05461DB1284610 +:1054100009B0BDE8F0835022125B11042068FFF749 +:1054200099FB05460DB12846F2E74FF0FF30039097 +:10543000082004903020059002200690002007905C +:105440000120089003A92068FFF728FB2068FFF7D8 +:10545000AAFC05460DB12846DAE71CE02068406B3F +:1054600000F4001040B12068FFF75CFB01A941F88F +:10547000280008F1010805E02068406B00F40050A6 +:1054800000B90EE0FBF75AFFA0EB0900401C10B971 +:105490004FF00040BCE72068406B00F02A00002875 +:1054A000DCD000BF2068406B00F0080018B1082075 +:1054B00021688863ACE72068406B00F0020018B1F7 +:1054C000022021688863A3E72068406B00F0200079 +:1054D00018B12020216888639AE740F23A50216889 +:1054E000886302980006029901F47F4140EA012096 +:1054F000029901F47F0140EA1120029940EA11600B +:105500003060361D01980006019901F47F4140EAA0 +:105510000120019901F47F0140EA1120019940EA3C +:1055200011603060002073E730B58FB00446012071 +:1055300003902068FFF7CCFA18B94FF080600FB0E5 +:1055400030BD606C03281BD02068FFF7FAFB0546CE +:105550000DB12846F3E700212068FFF7BEFA606727 +:1055600004212068FFF7B9FAA06708212068FFF737 +:10557000B4FAE0670C212068FFF7AFFA80210851E8 +:10558000606C032807D003A92068FFF744FC054698 +:105590000DB12846D3E7606C032820D0BDF80C106D +:1055A00021655022125B11042068FFF7E3FB0546DA +:1055B0000DB12846C3E700212068FFF78EFA606628 +:1055C00004212068FFF789FAA06608212068FFF708 +:1055D00084FAE0660C212068FFF77FFA2067042137 +:1055E0002068FFF77AFA010DE16404A92046FDF76F +:1055F00057FD10B14FF08050A1E75020005B01042F +:105600000A4600232068FFF77FFB05460DB12846B8 +:1056100095E7D4E90412A069CDE90012029094E85C +:105620000F00FFF760FA002089E70000F8B5044694 +:1056300000200090002600272068FFF7FDFA0546AD +:105640000DB12846F8BD2068FFF70CFB054645B1B3 +:105650000021A1642068FFF7EFFA05461DB1284636 +:10566000F0E70121A164A06C012808D10021206885 +:10567000FFF770FA054615B14FF08050E2E71DE0E4 +:1056800000212068FFF766FA05460DB12846D9E7E4 +:1056900018492068FFF77AFA054615B14FF0805097 +:1056A000D0E700212068FFF718FA0646012080EABB +:1056B000D67080F001070098401C00904FF6FF71F3 +:1056C0000098884201D2002FDAD04FF6FF7100987F +:1056D000884202D34FF08070B4E706F08040B0F10A +:1056E000804F02D10120606401E00020606400204E +:1056F000A8E70000000010C170B504460D4615B9BA +:105700004FF0006070BD5022125B11042068FFF75B +:1057100066FB06460EB13046F4E700212068FFF72D +:10572000DCF928600020EDE77CB5044600200090FD +:10573000019000212068FFF7D0F900F00070B0F16F +:10574000007F02D14FF400607CBD69462046FFF720 +:105750004AFE05460DB12846F6E7019800F4803070 +:1057600098B15022125B11042068FFF7F3F9054647 +:105770000DB12846E8E700212068FFF741FA054609 +:105780000DB12846E0E70020DEE74FF08060DBE760 +:105790007CB5044600200090019000212068FFF7AE +:1057A0009CF900F00070B0F1007F02D14FF400606E +:1057B0007CBD69462046FFF716FE05460DB128461A +:1057C000F6E7019800F4802098B15022125B110492 +:1057D0002068FFF7BFF905460DB12846E8E702212A +:1057E0002068FFF70DFA05460DB12846E0E70020D6 +:1057F000DEE74FF08060DBE71FB504460120164965 +:10580000087004F0EFFF10B3FBF772F820B92046E0 +:10581000FFF75AFD104908700F480078012816D08C +:105820000E48006850B90E4B0FCB8DE80F000021D9 +:10583000684604F0EFFF0949086000BF07480068A8 +:1058400028B90548007840F0010003490870024873 +:10585000007804B010BD0000A8000020AC000020BB +:1058600028E50008F0B589B007460D461446012624 +:105870001648007800F0010010B1032009B0F0BD17 +:1058800035B1012D06D0022D0BD0032D18D10FE01C +:10589000002617E001A8FBF715F8079820600026FE +:1058A00010E001A8FBF70EF808982080002609E018 +:1058B00001A8FBF707F80898400A2060002601E0DD +:1058C000042600BF00BF3046D8E70000A800002033 +:1058D0002DE9F04786B082460E46174698464FF0AF +:1058E000010947F23050FFF703FD002803DA48466C +:1058F00006B0BDE8F087424639463046FBF71CF853 +:10590000044614BB47F2305211480168684604F05F +:1059100095FF9DE8070003AB07C30398102814D137 +:105920000498012811D104F06BFF054605E0FAF751 +:10593000D3FF10B94FF0000906E004F061FF401BEF +:1059400047F230518842F2D300BF4846D0E700000A +:10595000AC00002010B504462046FFF7B5FC10BD92 +:105960002DE9F04387B081460D4616461F464FF09D +:10597000010847F23050FFF7BBFC002803DA40462D +:1059800007B0BDE8F0833A4631462846FAF7F2FF01 +:1059900010BB47F230521148016801A804F04EFFD5 +:1059A00001A807C804AB07C30498102814D10598B0 +:1059B000022811D104F024FF044605E0FAF78CFF19 +:1059C00010B94FF0000806E004F01AFF001B47F280 +:1059D00030518842F2D300BF4046D1E7AC000020EE +:1059E0007CB504460D461646164800681821B0FBE3 +:1059F000F1F01549B0FBF1F04FF47A714843019092 +:105A00006068B0F5827F0DD12B46002280212046B0 +:105A1000009600F01BF898B1606D40F020006065C2 +:105A200003207CBD00BF019800B908E00198401E2A +:105A3000019020688068C0F3C0100028F3D100BF37 +:105A40000020EEE71000002040420F002DE9F84F43 +:105A500004460D4690461E46DDF82890FBF76EFC86 +:105A6000A0EB0900371AFBF769FC82462C48006856 +:105A7000C0F3CB307843009045E0701C002842D042 +:105A8000FBF75CFCA0EB0A00B84200D2A7BB206881 +:105A9000406820F0E000216848606068B0F5827FCF +:105AA0000DD1A068B0F5004F03D0A068B0F5806FAD +:105AB00005D12068006820F0400021680860A06AD5 +:105AC000B0F5005F0DD100BF2068006820F40050E1 +:105AD000216808602068006840F400502168086070 +:105AE00000BF012084F8510000BF002084F850005E +:105AF00000BF0320BDE8F88FFFE7009800B900273A +:105B00000098401E0090206880682840A84201D17B +:105B1000012000E000204045AFD10020EAE700006E +:105B20001000002030B501460A461378521C147844 +:105B300043EA042030BDFEF7FBFD00BF012004F066 +:105B400045FEFBE710B500BF502080F31188BFF37E +:105B50004F8FBFF36F8F00BF08F058FA18B14FF0A6 +:105B600080500449086000BF002080F3118800BF06 +:105B700010BD000004ED00E000B593B0302107A88F +:105B8000FAF7CAFB142102A8FAF7C6FB00BF0020EF +:105B900001902548006840F080502349086008467D +:105BA000006800F08050019000BF00BF00BF0020DF +:105BB00001901E48006840F480401C490860084677 +:105BC000006800F48040019000BF00BF05200790EE +:105BD0004FF4803008900120099002200D9041057B +:105BE0000E9104210F91A8211091022111910721FA +:105BF000129107A8FCF7DEFD08B1FAF7DBFF0F20D2 +:105C0000029002200390002004904FF4A0500590D1 +:105C10004FF480500690052102A8FCF769FC08B1FA +:105C2000FAF7C8FF13B000BD4038024000700040D2 +:105C30000348006840F470000149086070470000A4 +:105C400088ED00E010B50248FEF709F810BD00002D +:105C5000F006002010B50268294B98420ED0B0F132 +:105C6000804F0BD0274B984208D0274B984205D045 +:105C7000264B984202D0264B984203D122F0700264 +:105C80004B681A431E4B984220D0B0F1804F1DD074 +:105C90001C4B98421AD01C4B984217D01B4B984271 +:105CA00014D01B4B984211D01A4B98420ED01A4B6D +:105CB00098420BD0194B984208D0194B984205D006 +:105CC000184B984202D0184B984203D122F44072EC +:105CD000CB681A4322F080034C6943EA0402026055 +:105CE0008B68C3620B688362054B984202D0084BF5 +:105CF000984201D10B6903630123436110BD000089 +:105D0000000001400004004000080040000C00407A +:105D100000040140004001400044014000480140AF +:105D200000180040001C00400020004070B50546EF +:105D3000AC6B0020E085E0842046FEF76BF870BD78 +:105D400000BF00BF02680C3252E8002F22F49071AD +:105D500002680C3242E80013002BF3D100BF00BFF1 +:105D600000BF0268143252E8002F22F001010268DD +:105D7000143242E80013002BF3D100BF016B01295C +:105D80000ED100BF00BF02680C3252E8002F22F093 +:105D9000100102680C3242E80013002BF3D100BF5F +:105DA000202180F83E1000210163704710B50446A1 +:105DB0002068C06820F040002168C860202084F876 +:105DC0003D002046FEF7D9FA002010BDF8B5044684 +:105DD00094F83E00222873D1A068B0F5805F0CD102 +:105DE000206950B90025A66A20684068C0F3080001 +:105DF0003080A06A801CA06215E0A56A0026A06819 +:105E0000B0F5805F03D0A06828B9206918B9206870 +:105E10004068287004E02068406800F07F00287027 +:105E2000A06A401CA062E08D401E80B2E085002880 +:105E300044D12068C06820F020002168C860206834 +:105E4000C06820F480702168C8602068406920F034 +:105E5000010021684861202084F83E00206B012861 +:105E600026D10020206300BF00BF21680C3151E81B +:105E7000001F21F0100021680C3141E80002002AC7 +:105E8000F3D100BF2068006800F0100010280AD18C +:105E900000BF0020009020680068009020684068E3 +:105EA000009000BF00BFA18D2046FDF7B2FF02E0C9 +:105EB0002046FEF7C9F90020F8BD01E00020FBE70D +:105EC0000220F9E72DE9F84F04462068006920F424 +:105ED0004050E1680843216808612169A0680843CF +:105EE00061690843E169084300902068C06849F28D +:105EF0000C618843009908432168C86020684069A4 +:105F000020F44070A16908432168486176492068FF +:105F1000884203D075492068884203D1FCF7E2FB30 +:105F2000814602E0FCF7CEFB8146E069B0F5004F08 +:105F30006CD102206168A0FB015003461920A9FB27 +:105F4000007001462A463846FAF79CF96421B0FBF6 +:105F5000F1F04FEA001A02206168A0FB01510B46E4 +:105F60001920A9FB00712A463846FAF78BF98346B7 +:105F700002206168A0FB015003461920A9FB0071B3 +:105F80002A463846FAF77EF96421B0FBF1F000EBBF +:105F9000C00101EB0010ABEB8000322101EBC0002F +:105FA0006421B0FBF1F000F0F8000AEB400A022097 +:105FB0006168A0FB015003461920A9FB007001464F +:105FC0002A463846FAF75EF9834602206168A0FB4C +:105FD000015003461920A9FB00712A463846FAF7FA +:105FE00051F96421B0FBF1F000EBC00101EB0010AE +:105FF000ABEB8000322101EBC0006421B0FBF1F07B +:1060000000F007005044216888606AE0042061685D +:10601000A0FB015003461920A9FB007001462A4647 +:106020003846FAF72FF9824604206168A0FB015038 +:1060300003461920A9FB007001462A463846FAF7A4 +:1060400021F96421B0FBF1F000EBC00101EB00107D +:10605000AAEB8000322101EB00106421B0FBF1F0CB +:1060600000F0F00A04206168A0FB017003461920CB +:10607000A9FB00513A462846FAF704F96421B0FB1F +:10608000F1F00AEB001A04206168A0FB01510B46F5 +:106090001920A9FB00712A463846FAF7F3F883461F +:1060A00004206168A0FB015003461920A9FB007081 +:1060B00001462A463846FAF7E5F86421B0FBF1F0CC +:1060C00000EBC00101EB0010ABEB8000322101EBD3 +:1060D00000106421B0FBF1F000F00F005044216883 +:1060E0008860BDE8F88F00000010014000140140F6 +:1060F00010B5034699629A85DA850020186422203B +:1061000083F83E0000BF002083F83C0000BF186900 +:1061100028B11868C06840F480701C68E060186896 +:10612000406940F001001C6860611868C06840F078 +:1061300020001C68E060002010BD014691F83D0081 +:10614000212828D18868B0F5805F0BD1086948B94B +:106150000A6A1088C0F308000B685860086A801C3F +:10616000086205E00B6A581C086218780B685860D2 +:10617000C88C401E80B2C88458B90868C06820F036 +:1061800080000B68D8600868C06840F040000B6869 +:10619000D860002070470220FCE72DE9F04104465A +:1061A0000D4617469846069E34E0701C88B32EB103 +:1061B000FBF7C4F8A0EB0800B0422BD900BF00BF2A +:1061C00021680C3151E8001F21F4D07021680C3196 +:1061D00041E80002002AF3D100BF00BF00BF2168E0 +:1061E000143151E8001F21F001002168143141E809 +:1061F0000002002AF3D100BF202084F83D0084F87B +:106200003E0000BF002084F83C0000BF0320BDE832 +:10621000F081FFE7206800682840A84201D10120F2 +:1062200000E00020B842C0D00020F0E710B50248DE +:10623000FDF7F2FD10BD0000AC0600202DE9F04195 +:1062400004460D46D4F8C87204F53070D4F8D41260 +:1062500050F8210010B90320BDE8F08104F530703A +:10626000D4F8D41250F8216005F00F0000EB800143 +:1062700004F1140000EB8100406838B305F00F0012 +:1062800000EB800104F1140000EB8100416805F08F +:106290000F0000EBC00207F13C0000EB8200C06879 +:1062A000B1FBF0F200FB121080B9002105F00F00E5 +:1062B00000EB800204F1140000EB82004160002337 +:1062C0001A462946204601F02CF917E00020C6F8AE +:1062D000140204F53170D4F8D41250F8210000698A +:1062E00060B1D6F8080204F53171D4F8D42251F81F +:1062F00022102A460B6906F5047198470020ABE787 +:1063000070B504460E4604F53070D4F8D41250F837 +:106310002150D4F8D41250F8210008B9032070BDE0 +:106320003146204600F059FFC5F80C02D5F80402AA +:1063300004F53171D4F8D43251F82310CA6805F548 +:10634000037190470020EAE770B504460D463048D7 +:106350000178204600F013FE00212D48007800F05F +:106360000F0000EB800204F1140000EB82000182B8 +:1063700028480178204600F002FE002125480078D8 +:1063800000F00F0000EB800204F5AA7000EB820021 +:10639000018221480178204600F0F1FD00211E48CD +:1063A000007800F00F0000EB800204F1140000EB15 +:1063B000820001821848007800F00F0000EB800294 +:1063C00004F1140000EB8200418204F53070D4F82F +:1063D000D41250F82100C8B104F53171D4F8D42298 +:1063E00051F822104868804704F53071D4F8D4225F +:1063F00051F8220001F0BEFB002104F53070D4F802 +:10640000D42240F822100020C4F8BC02002070BD45 +:1064100023020020240200202502002070B504463B +:1064200004F53070D4F8D41250F821500DB903207F +:1064300070BD04F53170D4F8D41250F8210098B131 +:1064400095F80002FF280FD095F8012295F8000278 +:1064500004F53171D4F8D46251F826108B682946BE +:106460009847FF2085F800020020E1E701460A2056 +:1064700008800148704700009C0100202DE9F04190 +:10648000044682210D4800F0A0FC054601210B487E +:1064900000F09BFC06468121084800F096FC074668 +:1064A0000DB11020A8710EB14020B0800FB1402076 +:1064B000B880432020800148BDE8F081E001002041 +:1064C0002DE9F041044682210E4800F07EFC05468D +:1064D00001210C4800F079FC06468121094800F0B2 +:1064E00074FC07460DB11020A87116B14FF400706E +:1064F000B08017B14FF40070B8804320208001486D +:10650000BDE8F081E00100202DE9F0410446822140 +:106510000D4800F05AFC054601210B4800F055FCDF +:1065200006468121084800F050FC07460DB11020B6 +:10653000A8710EB14020B0800FB14020B880432038 +:1065400020800148BDE8F081E001002070B50446DC +:106550000E464FF4077001F00FFB054645B90021C8 +:1065600004F53070D4F8D42240F82210022070BD17 +:106570004FF407712846F9F7CFFE04F53070D4F8D0 +:10658000D41240F82150D4F8D41250F82100C4F8A5 +:10659000BC02207C98BB4FF4007302225048017863 +:1065A000204600F0BBFE01214D48007800F00F00AE +:1065B00000EB800204F1140000EB820001824B0228 +:1065C000022248480178204600F0A8FE01214548F3 +:1065D000007800F00F0000EB800204F5AA7000EBD9 +:1065E0008200018210214048007800F00F0000EB8B +:1065F000800204F1140000EB8200418232E0FFE7E8 +:106600004023022236480178204600F087FE01210F +:106610003348007800F00F0000EB800204F1140012 +:1066200000EB82000182402302222E48017820469E +:1066300000F074FE01212B48007800F00F0000EB01 +:10664000800204F5AA7000EB820001821021264826 +:10665000007800F00F0000EB800204F1140000EB62 +:1066600082004182082303221F480178204600F05F +:1066700055FE01211C48007800F00F0000EB80025D +:1066800004F1140000EB820001820020C5F804022E +:1066900004F53171D4F8D42251F8221008688047EB +:1066A0000020C5F81402C5F81802D5F8040208B98C +:1066B00002205CE7207C48B94FF400730948017858 +:1066C0002046D5F8042200F041FE07E040230548AB +:1066D00001782046D5F8042200F038FE002046E775 +:1066E00023020020240200202502002070B5044669 +:1066F00004F53070D4F8D41250F82150D4F8D412E4 +:1067000050F8210008B9032070BD207C48B94FF42F +:106710000073094801782046D5F8042200F016FEDF +:1067200007E04023044801782046D5F8042200F011 +:106730000DFE0020E8E7000024020020024609B90F +:106740000320704702F53170D2F8D43240F823109C +:106750000020F6E710B5024602F53070D2F8D442B8 +:1067600050F824300BB9032010BDC3F804120020E8 +:10677000FAE730B503460C4603F53070D3F8D4522F +:1067800050F8251009B9032030BDC1F80842C1F8FE +:1067900010220020F8E72DE9FC4105460C4605F5DE +:1067A0003070D5F8D41250F821600020019000908C +:1067B000804616B90320BDE8FC81207800F0600017 +:1067C00000283DD020287CD1E08868B3207800F0F4 +:1067D0008000B8B1E288607805F53171D5F8D4C28F +:1067E00051F82C108B6831469847E088072801D96A +:1067F000072000E0E08807463A463146284600F088 +:1068000015F91CE0607886F80002E088402801D283 +:10681000E08800E0402086F8010296F80122314627 +:10682000284600F0E2F80AE0607805F53171D5F805 +:10683000D42251F8221000228B682146984747E065 +:10684000607830B1012832D00A2813D00B282FD11C +:1068500021E095F89C02032805D1022269462846CA +:1068600000F0E4F805E02146284600F0B2F84FF0C9 +:10687000030824E095F89C02032805D1012201A910 +:10688000284600F0D3F805E02146284600F0A1F89C +:106890004FF0030813E095F89C02032805D0214629 +:1068A000284600F096F84FF0030808E009E006E0FB +:1068B0002146284600F08DF84FF0030800BF00BFC6 +:1068C00006E02146284600F084F84FF0030800BF98 +:1068D00000BF40466FE7000070B5044604F5307015 +:1068E000D4F8D41250F821500126D4F8D41250F81C +:1068F000210008B9032070BDD5F81402C8B90120E1 +:10690000C5F814020C48007800F00F0000EB80027C +:1069100004F1140000EB8200D5F810124160064823 +:1069200001782046D5F81032D5F8082200F0F9FD9C +:1069300000263046DFE700002302002070B5044641 +:106940000D460026D4F8B8022946426820469047F2 +:1069500000B10326304670BD70B504460D4694F86C +:106960009C02012804D0022803D003280CD101E0A6 +:1069700000BF00BF6888012805D10020C4F8A40228 +:10698000204600F064F804E02946204600F021F893 +:1069900000BF00BF70BD02460020704702460020C5 +:1069A000704770B506460C4615462B462246002118 +:1069B000304600F0CBFC002070BD70B506460C469A +:1069C00015462B4622460021304600F0AAFD002045 +:1069D00070BD70B504460D468021204600F075FD5F +:1069E0000021204600F071FD70BD70B504460E46D2 +:1069F00015460320C4F894024FF4AC700551001DF5 +:106A000005512B4632460021204600F09FFC002015 +:106A100070BD10B504460520C4F8940200231A4640 +:106A20001946204600F092FC002010BD70B50446C7 +:106A30000E4615460220C4F89402A561E5612B4676 +:106A400032460021204600F06CFD002070BD10B5DC +:106A500004460420C4F8940200231A46194620462E +:106A600000F05FFD002010BD70B505460C462DB945 +:106A70002246064906A000F012FA04E02246034925 +:106A800003A000F00CFA014870BD0000ACF7002034 +:106A900043444320436F6E6669670000024612203C +:106AA00008800148704700005001002070B505467D +:106AB0000C462DB92246064906A000F0F0F904E084 +:106AC0002246034903A000F0EAF9014870BD000026 +:106AD000ACF7002043444320496E746572666163DD +:106AE000650000000246042008800148704700004D +:106AF0006401002070B505460C462246024903A0F9 +:106B000000F0CDF9004870BDACF7002053544D693A +:106B100063726F656C656374726F6E696373000096 +:106B200070B505460C462DB92246064906A000F070 +:106B3000B6F904E02246034903A000F0B0F9014889 +:106B400070BD0000ACF7002053544D33322056691D +:106B5000727475616C20436F6D506F727400000029 +:106B600070B505460C461A202080FAF759F80148FE +:106B700070BD00006801002070B504460D46E8882D +:106B8000012804D029462046FFF723FF1EE094F891 +:106B90009C02012804D0022803D0032810D109E068 +:106BA00000BF0020A060012204F108012046FFF789 +:106BB0003DFF0AE00122211D2046FFF737FF04E0D8 +:106BC00029462046FFF705FF00BF00BF70BDF8B59E +:106BD00004460E4600200090002700257088001211 +:106BE000082875D2DFE800F0C7040C20C7C7A5B598 +:106BF000207CD4F8B4120A68694690470746C1E081 +:106C0000207C40B9D4F8B802816A684688470746B4 +:106C10000220787007E0D4F8B802C16A6846884755 +:106C2000074602207870ADE0B078062878D2DFE819 +:106C300000F00316293C5063D4F8B402406838B120 +:106C4000207CD4F8B4124A6869469047074605E0AC +:106C500031462046FFF7BDFE681CC5B267E0D4F898 +:106C6000B402806838B1207CD4F8B4128A686946CE +:106C70009047074605E031462046FFF7AAFE681C0C +:106C8000C5B254E0D4F8B402C06838B1207CD4F85E +:106C9000B412CA6869469047074605E03146204667 +:106CA000FFF797FE681CC5B241E0D4F8B402006952 +:106CB00038B1207CD4F8B4120A6969469047074677 +:106CC00005E031462046FFF784FE681CC5B22EE081 +:106CD00051E0D4F8B402406938B1207CD4F8B41241 +:106CE0004A6969469047074605E031462046FFF766 +:106CF00070FE681CC5B21AE0D4F8B402806940B1D5 +:106D0000207CD4F8B4128A6969469047074606E0A9 +:106D100006E031462046FFF75CFE681CC5B206E07F +:106D200031462046FFF755FE681CC5B200BF00BFC4 +:106D300028E0207C30B9D4F8B802416B6846884717 +:106D4000074605E031462046FFF743FE681CC5B202 +:106D500018E0207C40B9D4F8B802016B6846884737 +:106D600007460720787005E031462046FFF731FEE0 +:106D7000681CC5B206E031462046FFF72AFE681CB3 +:106D8000C5B200BF00BF05B1F8BDF088C0B1BDF805 +:106D9000000080B1F088BDF80010884202DDBDF827 +:106DA000000000E0F0880090BDF800203946204641 +:106DB000FFF73CFE07E031462046FFF70AFE02E0FF +:106DC0002046FFF744FE00BFDEE72DE9F841054607 +:106DD0000F462C462E464FF00008708831788842C6 +:106DE00018DD307800900FE06946204600F020F86A +:106DF00004466078052807D1A04698F80200B842FA +:106E000000D106E04FF000087088BDF800108842FD +:106E1000EADC00BF4046BDE8F881014600200A4692 +:106E200002E0431CD8B2521C1378002BF9D17047F2 +:106E300010B5024610460B88047823440B80037873 +:106E4000981810BD70B504460D4694F89C020128B0 +:106E500004D0022803D003281AD101E000BF00BFEC +:106E6000E888022804D029462046FFF7B2FD14E046 +:106E70000120E060D4F8A40218B1E06840F00200FC +:106E8000E060022204F10C012046FFF7CFFD04E090 +:106E900029462046FFF79DFD00BF00BF70BD2DE9CC +:106EA000F04107460D46904600240FB9BDE8F08139 +:106EB0003E463046FFF7B1FF022101EB4000A8F843 +:106EC000000098F800002855601CC4B20320285523 +:106ED000601CC4B208E030782855761C601CC4B22F +:106EE00000202855601CC4B230780028F3D100BFC0 +:106EF000DCE70146002031B1012906D0022906D085 +:106F0000032908D105E0002007E0032005E0012067 +:106F100003E0032001E0032000BF00BF70472DE91C +:106F2000F04104460D46164614B90320BDE8F08131 +:106F30000020C4F8B802C4F8C402C4F8D0020DB1ED +:106F4000C4F8B452012084F89C022670204600F058 +:106F50004DF907463846E9E72DE9F04104460D466C +:106F6000002600272946D4F8C802FAF7AEFB0646E9 +:106F70003046FFF7BEFF07463846BDE8F0812DE9F1 +:106F8000F04104460D46002600272946D4F8C802E1 +:106F9000FAF766FB06463046FFF7ABFF0746384672 +:106FA000BDE8F0812DE9F04704460F469146002FD9 +:106FB00056D104F11405D4F89402022846D1D5E93B +:106FC000020188420FD9D5E90201401AA86049465A +:106FD0002046AA68FFF7F1FC00231A46194620460E +:106FE00000F0B4F932E0D5E90210884217D1E9681F +:106FF0006868884213D36868D4F8981288420ED221 +:10700000002211462046FFF7D8FC0020C4F8980261 +:1070100000231A461946204600F098F916E094F825 +:107020009C0203280BD1D4F8B802C06838B1002004 +:10703000C4F8D402D4F8B802C16820468847802139 +:10704000204600F042FA2046FFF7E3FC94F8A00245 +:1070500050B3204600F0BCFA002084F8A00223E0E0 +:1070600047F080012046FFF796FC0646FF2E1BD016 +:10707000D6B994F89C02032816D104F52E7050F866 +:107080002600406980B1C4F8D46204F52E7050F82F +:10709000260039464269204690478046B8F1000FE5 +:1070A00002D04046BDE8F0870020FBE72DE9F0471D +:1070B00005460F4690464FF00009002F51D105F5C7 +:1070C000AA76D5F8940203286FD1D6E90201884246 +:1070D00010D9D6E90201401AB060D6E9020188420F +:1070E00001D2B06800E0F068024641462846FFF74A +:1070F00058FC5AE095F8AA0200F01F0020B10128C0 +:1071000004D0022812D109E0002411E040F2AE20A0 +:10711000415D2846FFF742FC044609E040F2AE20FC +:10712000415D2846FFF737FC044601E0002400BF1C +:1071300000BF94B995F89C0203280ED105F52E7076 +:1071400050F82400006940B1C5F8D44205F52E700E +:1071500050F824000169284688472846FFF777FC45 +:1071600023E007F07F012846FFF715FC0446FF2CBB +:107170001BD0D4B995F89C02032810D105F52E70C8 +:1071800050F82400806950B1C5F8D44205F52E703E +:1071900050F8240039468269284690478146B9F163 +:1071A000000F02D04846BDE8F0870020FBE701460B +:1071B0000020704770B504460025012084F89C0229 +:1071C000D4F8B80238B12179D4F8B8024268204620 +:1071D000904700B10325284670BD70B504460D46A2 +:1071E0002946D4F8C802FAF7AEFA70BD10B50446C5 +:1071F000207800282AD11648C0F80845C4F8C802EB +:107200004FF0A04012490860042048600221104855 +:10721000C16000210161022181610021C16101621F +:107220004162C1620163FAF7F4FE08B1F9F7C2FCEA +:1072300080210748FAF799F9402200210448FAF71B +:1072400099F9802201210248FAF794F9002010BD33 +:10725000AC09012010B50246D2F8C83201F0800016 +:10726000802809D101F07F0000EBC00403F13C004D +:1072700000EB8400807810BD01F07F0000EBC004BB +:1072800003F51F7000EB84008078F4E770B50446C6 +:107290000D4604F52E70D4F8D41250F8210008B928 +:1072A000032070BD94F89C02032811D104F52E70C0 +:1072B000D4F8D41250F82100006A48B104F52E70B9 +:1072C000D4F8D41250F821002946026A204690478B +:1072D0000020E6E770B504460D4604F52E70D4F89C +:1072E000D41250F8210008B9032070BD94F89C0214 +:1072F000032811D104F52E70D4F8D41250F82100CF +:10730000406A48B104F52E70D4F8D41250F8210028 +:107310002946426A204690470020E6E72DE9F047DB +:1073200004460F4615461E464FF00008C1462B4640 +:1073300032463946D4F8C802FAF710FA8046404679 +:10734000FFF7D7FD81464846BDE8F0872DE9F047B5 +:1073500004460D4616461F464FF00008C1463B4600 +:1073600032462946D4F8C802FAF73EFA804640462B +:10737000FFF7BFFD81464846BDE8F08770B504467B +:107380000025012084F89C020020C4F8940260606B +:10739000C4F8A40284F8A002D4F8B80258B1D4F812 +:1073A000B802406838B12179D4F8B8024268204662 +:1073B000904700B103254023002211462046FFF7E5 +:1073C000ADFF01214FF4B27001534021001F015164 +:1073D0004023002280212046FFF7A0FF0121A18445 +:1073E00040212162284670BD014691F89C02042884 +:1073F00003D191F89D0281F89C020020704710B5DE +:10740000044694F89C0203280BD1D4F8B80240B18A +:10741000D4F8B802C06920B1D4F8B802C1692046D6 +:107420008847002010BD02461174002070472DE9E6 +:10743000F04104460D46002600272946D4F8C8022C +:10744000FAF714FF06463046FFF753FD0746384665 +:10745000BDE8F08170B504460D46294604F2AA2025 +:1074600000F077F80120C4F894024FF42C70005B10 +:10747000C4F8980294F8AA0200F01F0020B1012875 +:1074800009D0022815D10DE004F2AA21204600F00F +:1074900083F9064616E004F2AA21204600F013FB09 +:1074A00006460FE004F2AA21204600F0CCF9064679 +:1074B00008E094F8AA0200F08001204600F005F8E8 +:1074C000064600BF00BF304670BD2DE9F0410446BE +:1074D0000D46002600272946D4F8C802FAF7B0F96D +:1074E00006463046FFF705FD07463846BDE8F08101 +:1074F00070B5044600250026D4F8C802FAF7DAFE73 +:1075000005462846FFF7F5FC0646304670BD0146A5 +:1075100091F89C0281F89D02042081F89C020020D1 +:1075200070472DE9F04704460D4616461F464FF0BA +:107530000008C1463B4632462946D4F8C802FAF74D +:10754000C4F980464046FFF7D4FC81464846BDE872 +:10755000F08770B505460E46344620782870641CC6 +:1075600020786870641C2046FEF7DCFA6880641C92 +:10757000641C2046FEF7D6FAA880641C641C2046D2 +:10758000FEF7D0FAE88070BD38B504460D460020FD +:1075900000900DB9032038BDC4F8B85204F52E7020 +:1075A000D4F8D41250F82100C06A50B104F52E70FE +:1075B000D4F8D42250F82200C16A68468847C4F83B +:1075C000D002D4F8D802401CC4F8D8020020E2E768 +:1075D00001460020704770B504460D46A88810BBD0 +:1075E000E88800BB688880281DD2A87800F07F0654 +:1075F00094F89C02032804D129462046FFF7E9F9B4 +:1076000015E084F89E6231462046FFF710FF2046C1 +:10761000FFF71DFA1EB1022084F89C0207E001204A +:1076200084F89C0203E029462046FFF7D2F970BD9A +:1076300070B504460D460026D4F8B80230B1D4F82F +:10764000B80229460268204690470646304670BD7B +:1076500070B504460E460025B0783D4908700846CE +:107660000078012805D931462046FFF7B2F90320FA +:1076700070BD94F89C02022802D0032859D11FE063 +:1076800033480078C0B132480078606030480178F3 +:107690002046FFF7CDFF05463DB131462046FFF7B6 +:1076A00098F9022084F89C0209E02046FFF7CFF900 +:1076B000032084F89C0202E02046FFF7C8F943E06B +:1076C0002348007870B9022084F89C022048007892 +:1076D00060601F4801782046FFF730F92046FFF729 +:1076E000B6F925E01A490978606888421DD02179E9 +:1076F0002046FFF723F916480078606014480178A7 +:107700002046FFF795FF05465DB131462046FFF75D +:1077100060F921792046FFF711F9022084F89C02D4 +:1077200006E02046FFF793F902E02046FFF78FF9C5 +:107730000AE031462046FFF74CF90548017820461B +:10774000FFF7FCF8032500BF00BF284690E70000C4 +:107750009801002070B505460C466088012805D1C7 +:10776000C5F8A4022846FFF772F90EE060880228E7 +:1077700007D1A088001285F8A0022846FFF767F914 +:1077800003E021462846FFF724F970BD10B50446F2 +:107790002046FFF7ADFE10BD70B504460D4600262D +:1077A000287800F0600088B1202802D0402842D11B +:1077B00000E000BF04F52E70D4F8D41250F8210078 +:1077C0002946826820469047064639E068780A28AC +:1077D0002AD2DFE800F01A24291F290A0529150FEB +:1077E00029462046FFF7F3F923E029462046FFF714 +:1077F000F2FE1EE029462046FFF72AFF064618E063 +:1078000029462046FFF7B8F913E029462046FFF73E +:1078100019FB0EE029462046FFF79CFF09E02946A8 +:107820002046FFF799F804E029462046FFF7D1F8F3 +:1078300000BF00BF04E029462046FFF7CAF800BF9A +:1078400000BF304670BD2DE9F04705460F464FF0AA +:1078500000093C79387800F06000F8B1202802D0A7 +:1078600040287DD100E000BF21462846FFF793F86D +:107870000646FF2E11D086B9C5F8D46205F52E70E4 +:1078800050F82600806840B105F52E7050F82600AB +:107890003946826828469047814610E1787800286A +:1078A0007AD001282FD003286ED195F89C020228A7 +:1078B00002D0032820D110E054B1802C08D02146FA +:1078C0002846FFF702FE80212846FFF7FEFD03E071 +:1078D00039462846FFF77DF813E0788840B93CB177 +:1078E000802C05D0F88818B921462846FFF7EDFD11 +:1078F0002846FFF7ACF804E039462846FFF769F858 +:1079000000BF00BFD4E095F89C02022802D00328F3 +:107910003BD110E054B1802C08D021462846FFF717 +:10792000D4FD80212846FFF7D0FD03E039462846E4 +:10793000FFF74FF82EE0788820BB04F07F0018B1E5 +:1079400021462846FFF708FB2846FFF780F8214626 +:107950002846FFF720F80646FF2E13D096B900E020 +:10796000A8E0C5F8D46205F52E7050F826008068AE +:1079700040B105F52E7050F8260039468268284639 +:107980009047814606E007E08DE039462846FFF73C +:1079900020F800BF00BF8BE095F89C02022802D0BF +:1079A000032879D126E034B1802C04D0394628460A +:1079B000FFF70FF875E004F08000802808D104F08C +:1079C0007F0000EB800105F1140000EB810007E06F +:1079D00004F07F0000EB800105F5AA7000EB810048 +:1079E00080460020C8F80000022241462846FFF7E2 +:1079F0001DF856E004F0800080280ED104F00F003E +:107A000000EB800105F1140000EB8100008A98B9B9 +:107A100039462846FEF7DDFF43E004F00F0000EB97 +:107A2000800105F5AA7000EB8100008A20B9394673 +:107A30002846FEF7CEFF34E004F08000802808D10D +:107A400004F07F0000EB800105F1140000EB8100E1 +:107A500007E004F07F0000EB800105F5AA7000EB61 +:107A6000810080460CB1802C03D10020C8F80000B2 +:107A70000CE021462846FFF7EDFB20B10120C8F8B5 +:107A8000000003E008E00020C8F8000002224146A0 +:107A90002846FEF7CBFF04E039462846FEF799FF5B +:107AA00000BF00BF04E039462846FEF792FF00BF42 +:107AB00000BF04E039462846FEF78BFF00BF00BF39 +:107AC0004846BDE8F0872DE9F04105460E460027FF +:107AD000307800F0600030B1202802D0402840D13A +:107AE00000E000BF00BF95F89C02012804D00228E6 +:107AF00003D003282ED101E000BF00BF3079012858 +:107B000023D831792846FEF749FF0446FF2C14D0CC +:107B10009CB905F52E7050F82400806858B1C5F85E +:107B2000D44205F52E7050F824003146826828466C +:107B30009047074602E0032700E00327F08840B99A +:107B40003FB92846FEF783FF03E031462846FEF79B +:107B500040FF04E031462846FEF73BFF00BF00BF70 +:107B600004E031462846FEF734FF00BF00BF384628 +:107B7000BDE8F081704700000146014870470000F1 +:107B8000B80E012070B504460B4622461978587885 +:107B900001282CD140F61C0080581D7805F00F06F6 +:107BA0000125B540ADB2284340F61C05A85002F5AA +:107BB000106000EB4110006800F40040F0BB9889B1 +:107BC000C0F30A001D7940EA854040EA815040F048 +:107BD000805040F4004002F5106505EB41152D681A +:107BE000284302F5106505EB411528602DE040F6AD +:107BF0001C0080581D7805F00F060125B540144E75 +:107C000006EA0545284340F61C05A85002F53060F9 +:107C100000EB4110006800F4004078B99889C0F387 +:107C20000A001D7940EA854040F0805040F4004051 +:107C300002F5306505EB41152D6800E005E02843AD +:107C400002F5306505EB41152860002070BD00008D +:107C50000000FFFF01460A464FF410608058C30A37 +:107C6000DB024FF41060835040F60400805840F46B +:107C7000807340F604008350002070470FB470B545 +:107C800004460A98012817D1A06B20F48030A06325 +:107C9000E0681A490840E060E06820F44010E060C5 +:107CA0001198012803D1E06840F48010E06020467C +:107CB00000F026F8054612E0E06840F04000E06081 +:107CC000204600F01DF805460E9820B9A06B40F440 +:107CD0008030A06303E0A06B20F48030A06308989C +:107CE000012807D1A06840F00600A060A06840F01D +:107CF0002000A060284670BC5DF814FBBFFFBDFFEC +:107D000008B501460020009000BF0098401C00907C +:107D1000104A0098904201D9032008BD086900F07C +:107D200000400028F1D000200090086940F00100D8 +:107D3000086100BF0098401C0090064A00989042DD +:107D400001D90320E9E7086900F001000028F1D11A +:107D500000BFE2E7400D030070B504460B46224623 +:107D600019785878012848D102F5106000EB4110CD +:107D7000006800F00040B0F1004F17D102F510602C +:107D800000EB4110006840F0006502F5106000EB68 +:107D90004110056002F5106000EB4110006840F0F2 +:107DA000804502F5106000EB4110056040F63C0094 +:107DB00080581D7805F00F060125B540ADB2A843E7 +:107DC00040F63C05A85040F61C0080581D7805F090 +:107DD0000F060125B540ADB2A84340F61C05A850DA +:107DE00002F5106000EB411000682B4D284002F5B1 +:107DF000106505EB411528604BE002F5306000EBA3 +:107E00004110006800F00040B0F1004F17D102F5BA +:107E1000306000EB4110006840F0006502F5306012 +:107E200000EB4110056002F5306000EB4110006886 +:107E300040F0804502F5306000EB4110056040F6EF +:107E40003C0080581D7805F00F060125B540134E03 +:107E500006EA0545A84340F63C05A85040F61C003C +:107E60008558187800F00F060120B0400B4E06EA46 +:107E70000040854340F61C00855002F5306000EB61 +:107E800041100068064D284002F5306505EB4115AC +:107E90002860002070BD0000007833EC0000FFFF78 +:107EA0000078F3EF01460A46D2F8000E20F00300F6 +:107EB000C2F8000E40F60400805820F0020340F69D +:107EC000040083500020704701460A46D2F8000E95 +:107ED00020F00300C2F8000E40F60400805840F085 +:107EE000020340F604008350002070470FB4F0B541 +:107EF000054600272E46002405E0002105F5827086 +:107F000040F82410641C0F2CF7D31098A0B940F649 +:107F10000400805940F0020140F604008151A86B32 +:107F200040F40010A863A86B20F40020A863A86B9D +:107F300020F48020A86307E0A86B20F40010A86359 +:107F4000A86B40F40020A8630020C6F8000ED6F805 +:107F50000008C6F800080B9801280BD1089820B932 +:107F60000021284600F0BCFD08E00121284600F071 +:107F7000B7FD03E00321284600F0B2FD102128469A +:107F800000F0B2FC00B10127284600F083FC00B1EC +:107F9000012700214FF401608151001D815140F6FD +:107FA0001C00815100242EE006F5106000EB441007 +:107FB000006800F00040B0F1004F10D13CB94FF024 +:107FC000006106F5106000EB441001600DE04FF019 +:107FD000904106F5106000EB4410016005E00021BF +:107FE00006F5106000EB44100160002106F51060FA +:107FF00000EB441001614FF67F3106F5106000EB95 +:1080000044108160641C0698A042CDD800242EE064 +:1080100006F5306000EB4410006800F00040B0F15D +:10802000004F10D13CB94FF0006106F5306000EB15 +:10803000441001600DE04FF0904106F5306000EB18 +:108040004410016005E0002106F5306000EB4410AB +:108050000160002106F5306000EB441001614FF62D +:108060007F3106F5306000EB44108160641C069897 +:10807000A042CDD84FF40160805920F480714FF4B4 +:10808000016081510020A8616FF08040686109980B +:1080900018B9A86940F01000A861A8690949084307 +:1080A000A8610C9818B1A86940F00800A861109860 +:1080B000012803D1A86904490843A8613846F0BCE7 +:1080C0005DF814FB00383C800400004001468868DD +:1080D00020F001008860002070470000F0B50546E0 +:1080E0000B4614462A4619785878012875D19869A4 +:1080F00020BB02F5106000EB411000696D4E30406E +:1081000002F5106606EB4116306102F5106000EBD7 +:108110004110006940F4002602F5106000EB4110A8 +:10812000066102F5106000EB41100069C60CF60410 +:1081300002F5106000EB4110066137E002F51060B7 +:1081400000EB41100069C60CF60402F5106000EB6C +:108150004110066102F5106000EB41100069554EB8 +:10816000304002F5106606EB41163061DE68986912 +:10817000B04201D9D868986102F5106000EB411057 +:10818000006940F4002602F5106000EB4110066122 +:1081900002F5106000EB411000699E69C6F31206FB +:1081A000304302F5106606EB41163061012C15D103 +:1081B000586928B102F5106000EB41105E69466114 +:1081C00002F5106000EB4110006840F0044602F533 +:1081D000106000EB411006606AE01BE002F51060E1 +:1081E00000EB4110006840F0044602F5106000EB1F +:1081F00041100660986900285AD040F63400805833 +:108200001E7806F00F070126BE40304340F63406C4 +:10821000B0504DE002F5306000EB41100069C60C33 +:10822000F60402F5306000EB4110066102F53060A3 +:1082300000EB411000691F4E304002F5306606EB3E +:1082400041163061986908B1D8689861D868D861DA +:1082500002F5306000EB4110006940F4002602F5A1 +:10826000306000EB4110066102F5306000EB411018 +:108270000069DE69C6F31206304302F5306606EB8C +:1082800041163061012C07D1186928B102F5306020 +:1082900000EB41101E69466102F5306000EB4110B1 +:1082A000006840F0044602F5306000EB41100660C3 +:1082B0000020F0BDFFFF07E070B503460C461946ED +:1082C0001D6C1848854209D94FF43060405800F0C1 +:1082D0000040B0F1004F01D1002070BD0026C1F870 +:1082E000106BD1F8100B40F40026C1F8106BD1F8D8 +:1082F000100B40F01806C1F8106BD1F8100B40F0CD +:10830000C046C1F8106B012C09D1C1F8142B4FF4F1 +:108310003060405840F080264FF4306046500020D6 +:10832000DBE700000A30544F30B504460B462246C6 +:108330001978587801281ED102F5106000EB411021 +:10834000006820F4001502F5106000EB4110056094 +:108350001879032802D0187902282AD102F5106072 +:1083600000EB4110006840F0805502F5106000EB12 +:10837000411005601DE002F5306000EB411000681F +:1083800020F4001502F5306000EB4110056018790B +:10839000032802D0187902280BD102F5306000EBD7 +:1083A0004110006840F0805502F5306000EB41104C +:1083B0000560002030BD30B504460B4622461978D2 +:1083C0005878012821D102F5106000EB41100068B7 +:1083D00000F0004060B959B102F5106000EB4110A7 +:1083E000006820F0804502F5106000EB4110056048 +:1083F00002F5106000EB4110006840F4001502F532 +:10840000106000EB4110056020E002F5306000EBE9 +:108410004110006800F0004060B959B102F53060C9 +:1084200000EB4110006820F0804502F5306000EB61 +:108430004110056002F5306000EB4110006840F427 +:10844000001502F5306000EB41100560002030BDE2 +:108450002DE9F84381460E4617464D46347870782C +:1084600001287DD1B06920BB05F5106000EB4410F8 +:108470000069C849084005F5106101EB4411086125 +:1084800005F5106000EB4410006940F4002105F58B +:10849000106000EB4410016105F5106000EB441022 +:1084A0000069C10CC90405F5106000EB44100161BE +:1084B00055E005F5106000EB44100069C10CC904DB +:1084C00005F5106000EB4410016105F5106000EB4C +:1084D00044100069AF49084005F5106101EB4411F3 +:1084E0000861F168B0690844401EB0FBF1F0A94989 +:1084F000C94301EAC04005F5106101EB4411096967 +:10850000084305F5106101EB4411086105F51060A1 +:1085100000EB44100069B169C1F31201084305F58D +:10852000106101EB441108613079012817D105F57C +:10853000106000EB4410006920F0C04105F51060A8 +:1085400000EB4410016105F5106000EB4410006978 +:1085500040F0005105F5106000EB4410016100E0AF +:108560007FE0012F36D1706928B105F5106000EB6E +:10857000441071694161307901281ED140F608002C +:10858000405900F4807060B905F5106000EB4410AC +:10859000006840F0005105F5106000EB44100160E8 +:1085A0000BE005F5106000EB4410006840F08051CE +:1085B00005F5106000EB4410016005F5106000EB5C +:1085C0004410006840F0044105F5106000EB4410D1 +:1085D0000160DCE005F5106000EB4410006840F03D +:1085E000044105F5106000EB44100160307901286A +:1085F0000FD0B0690028ECD040F6340040593178F3 +:1086000001F00F0201219140084340F63401485126 +:10861000BDE040F60800405900F4807060B905F5EF +:10862000106000EB4410006840F0005105F5106048 +:1086300000EB441001600BE005F5106000EB441006 +:10864000006840F0805105F5106000EB44100160B7 +:108650000097308B83B232784846316900F0BEFA19 +:1086600095E005F5306000EB44100069C10CC904C9 +:1086700005F5306000EB4410016105F5306000EB5A +:10868000441000694349084005F5306101EB44118D +:108690000861B069D0B905F5306000EB441000699D +:1086A000F168C1F31201084305F5306101EB441193 +:1086B000086105F5306000EB4410006940F40021CA +:1086C00005F5306000EB4410016128E0F168B06905 +:1086D0000844401EB0FBF1F01FFA80F8F06800FB80 +:1086E00008F0F06105F5306000EB4410006929499D +:1086F000C94301EAC841084305F5306101EB441163 +:10870000086105F5306000EB44100069F169C1F3C0 +:108710001201084305F5306101EB44110861012F96 +:1087200007D1306928B105F5306000EB441031699C +:108730004161307901281ED140F60800405900F40B +:10874000807060B905F5306000EB4410006840F0BF +:10875000005105F5306000EB441001600BE005F5B9 +:10876000306000EB4410006840F0805105F5306047 +:1087700000EB4410016005F5306000EB4410006828 +:1087800040F0044105F5306000EB4410016000202A +:10879000BDE8F883FFFF07E078B5034600240094A6 +:1087A00000201A464C78012C35D10C7802F5106562 +:1087B00005EB4414246804F00044B4F1004F60D188 +:1087C0000C7805EB4414246844F000660C7805EB43 +:1087D000441426600C7805EB4414246844F0804669 +:1087E0000C7805EB4414266000BF009C641C0094C8 +:1087F00042F21075009CAC4201D901200AE00C78CD +:1088000002F5106505EB4414246804F00044B4F14B +:10881000004FEAD035E00C7802F5306505EB4414E2 +:10882000246804F00044B4F1004F2AD10C7805EB21 +:108830004414246844F000660C7805EB4414266068 +:108840000C7805EB4414246844F080460C7805EB62 +:108850004414266000BF009C641C009442F2107512 +:10886000009CAC4201D901200AE00C7802F5306589 +:1088700005EB4414246804F00044B4F1004FEAD03E +:1088800000BF78BD0146886840F001008860002084 +:108890007047000008B501460020009000BF009816 +:1088A000401C00900F4A0098904201D9032008BD57 +:1088B000086900F000400028F1D00020009010204E +:1088C000086100BF0098401C0090064A0098904242 +:1088D00001D90320EBE7086900F010001028F1D05F +:1088E0000020E4E7400D030008B502460020009098 +:1088F00000BF0098401C0090104B0098984201D98E +:10890000032008BD106900F000400028F1D00020CD +:108910000090202040EA8110106100BF0098401CA8 +:108920000090064B0098984201D90320E9E71069AE +:1089300000F020002028F1D00020E2E7400D0300E5 +:1089400010B501460B4640F60804E45804F0060250 +:108950000AB9002006E0022A01D0062A01D102202D +:1089600000E00F2010BD0146486900F0010070478B +:1089700001460B4640F61800C258001DC058024080 +:1089800090B2704701460B4640F61800C258001DD1 +:10899000C0580240100C704770B5024613464FF4A1 +:1089A0000166F45840F63406F55801F00F0625FA32 +:1089B00006F606F0010644EAC61403F5106606EB57 +:1089C0004116B66806EA040070BD10B502461346AB +:1089D00003F5306404EB4114A06840F61404E45835 +:1089E000204010BD014648698A69104070472DE952 +:1089F000F04104460D46274628464FEA920C02F005 +:108A0000030300210AE04FF4805858F80780C0F8AB +:108A10000080401C401C401C401C491C6145F2D396 +:108A20009BB100214FF4805858F8076000BF4FEA0F +:108A3000C10826FA08F880F80080491C401CA3F100 +:108A400001081FFA88F3002BF1D1BDE8F08170B561 +:108A500004460E460025E06820F0C040E060012E8C +:108A600010D1E06840F00050E06000BF0120F8F74E +:108A70003FFB6D1C2046FFF776FF012815D0322DF5 +:108A8000F4D312E07EB9E06840F08040E06000BFBF +:108A90000120F8F72DFB6D1C2046FFF764FF20B185 +:108AA000322DF5D301E0012070BD322D01D101201E +:108AB000FAE70020F8E710B502460B461146D1F858 +:108AC000000820F4FE60C1F80008D1F800084FF457 +:108AD000FE6404EA03142043C1F80008002010BD1E +:108AE00002461346D3F800080843C3F800080020E4 +:108AF0007047000030B503461446022C49D12D487A +:108B0000814204D32C48814201D20F2245E02A48F9 +:108B1000814204D32948814201D20E223DE02748F8 +:108B2000814204D32648814201D20D2235E02448F7 +:108B3000814204D32348814201D20C222DE02148F6 +:108B4000814204D32048814201D20B2225E01E48F5 +:108B5000814204D31D48814201D20A221DE01B48F4 +:108B6000814204D31A48814201D2092215E01848F3 +:108B7000814204D31748814201D208220DE01548F2 +:108B8000814204D31448814201D2072205E0062223 +:108B900003E00CB9092200E00922D86820F47050E3 +:108BA000D860D8684FF4705505EA82252843D8600C +:108BB000002030BDC0ACD800C0E1E4000024F400C7 +:108BC00080730601A0491A01002D310140A44C0117 +:108BD00000366E0120ABA6010048E8012DE9F04304 +:108BE00004460D461E46DDF81CC0A0462946BCF1D1 +:108BF000000F12D1F01C870800230CE0D1F8009080 +:108C000008F5805000EB0230C0F80090491C491C68 +:108C1000491C491C5B1CBB42F0D30020BDE8F0831B +:108C200000BFFEE70FB4084B10B504A902AA0398D1 +:108C300000F046FC044602A9002001F061F920463C +:108C400010BC5DF814FB0000019F00087CB50C000F +:108C50001D461646014601D0601E00E00020CDE909 +:108C60000010064B6A462946304600F029FC002CCD +:108C700002D0009A002111707CBD0000099E0008FE +:108C800002480068C0F30220704700000CED00E0CD +:108C900010B5002804DB0A07130E054A135406E03A +:108CA0000A07140E034A00F00F031B1FD45410BD13 +:108CB00000E400E018ED00E002E008C8121F08C15F +:108CC000002AFAD170477047002001E001C1121F4D +:108CD000002AFBD170472DE9FC410446A089401EC3 +:108CE00080B200906089401E83B200221146204667 +:108CF000266FB0472068006A006800684FF6BF71B1 +:108D000008402168096A096808602068006A0068EC +:108D1000006840F400602168096A096808602068FA +:108D2000006A0068006840F040002168096A09682C +:108D3000086020680169D1E90401CDE900012068DB +:108D40000669F7683B4696E80700B847002508E043 +:108D5000608A2168096A0968C860206801F0E8F83B +:108D60006D1C6089A1894843A842F1D8206801F0B0 +:108D7000D6F820680169D1E90401CDE90001206835 +:108D80000669D6E902733A46D6E90001B847206879 +:108D9000006A006800684FF6BF7108402168096AE0 +:108DA000096808602068006A006800684FF2FF7177 +:108DB00008402168096A096808602068006A00683C +:108DC000006840F040002168096A09680860BDE851 +:108DD000FC8100002DE9FE4F0446884691461D4661 +:108DE0000026B2460027B346A5F12000C5B2206890 +:108DF0000169D1E90401CDE900012068D0F810E053 +:108E0000DEF80CC063469EE80700E04700BF33E091 +:108E1000A0690068A169098905FB0161405C0290B5 +:108E20004FF0000A22E0029800F0010028B1A08A69 +:108E30002249096821F8170004E0608A1F4909687F +:108E400021F81700029840100290781C87B20BF1AD +:108E500001001FFA80FBA0698088584502D14FF0BD +:108E6000000B06E00AF101001FFA80FABAF1080FC0 +:108E7000D9DB00BF701C86B2A0690089B042C7DC94 +:108E8000A069C0884844401E80B20090A0698088D4 +:108E90004044401E83B24A4641462046D4F870C042 +:108EA000E047A0698088A169C988484382B2034825 +:108EB0000168204601F045F8BDE8FE8F3001002032 +:108EC0002DE9FE4F0446884691461E4600250027A0 +:108ED0000020029083461BE0E06902680089691C5B +:108EE0004843105C317888420BD1E06902890168FF +:108EF000681C00FB021040787178884201D1AA46B4 +:108F000007E0A81C85B2E0694089A84200DC00E0C7 +:108F1000E2E700BF0025002733E0E0690068E1696F +:108F200009890AFB0100C05D01900020029022E047 +:108F3000019800F0010028B1A08A2349096821F8AE +:108F4000150004E0608A2049096821F81500681CB2 +:108F500085B20198401001900BF101001FFA80FBCF +:108F6000E0698088584502D14FF0000B06E0029876 +:108F7000401C80B2029002980828D9DB00BF781C00 +:108F800087B2E0690089B842C7DCE069C08848441C +:108F9000401E80B20090E06980884044401E83B249 +:108FA0004A4641462046D4F870C0E047E0698088D0 +:108FB000E169C988484382B203480168204600F04D +:108FC000C0FFBDE8FE8F0000300100202DE9F04118 +:108FD00005460E4617461C4619E020787F280BDC14 +:108FE00023783A4631462846FFF7F4FEA869808880 +:108FF000304486B2641C0AE023463A46314628468D +:10900000FFF75EFFE8698088304486B2A41C2078B0 +:109010000028E2D1BDE8F0812DE9FF5F82B0002198 +:10902000DDE90430020DDDF840B0034318D044F60A +:109030001050A2F2FF3242431514119801281FD09C +:10904000A5EB0B00401C5FEA000A4FF000064E4FF4 +:10905000DFF83891B046504615D5CAF1000413E048 +:10906000119801244AA3012801D16FEA0B0102984B +:10907000119AC0E90031C0E9024206B0BDE8F09F94 +:10908000CBF10000DFE704460021404A491842EBDB +:109090000450CDE9001012E0E00707D032463B460D +:1090A00040464946F7F70EFA8046894632463B4627 +:1090B00010461946F7F706FA06460F466410002CCC +:1090C000EAD1DDE90401DDE90023BAF1000F06DA97 +:1090D000F7F7F8F942464B46F7F7F4F905E0F7F7EA +:1090E00007FB42464B46F7F703FB04460E460022B9 +:1090F000284BF7F785FB03D84FF0FF30014607E018 +:109100000022254B20463146F7F735F9F7F75FFB8C +:10911000102409E0002C0ADB0A220023F7F7B2F83A +:10912000039B30321A55641E50EA0102F2D1641CCE +:10913000039AC4F111031444119A012A03D00122A5 +:1091400008430DD10AE0084304D000204FF0110B72 +:10915000119072E7A3EB0B056D1E0DE05B4504DD7E +:109160004FF0000205F1010504E003DA4FF00002C0 +:10917000A5F10105002AECD002981199C0E902314D +:10918000C0E9004579E70000000014400000F03F0E +:10919000300000000000F0430000E03F30B5002246 +:1091A0000023002401F478052A0A01F47C456B09A8 +:1091B000C1F3C40442EA03052543458230BD0000E3 +:1091C000014601F1100000E0001D02681AB9024AD0 +:1091D00012689042F8D370478800002070B50446AA +:1091E0000D460CB1012100E00021084640F20511B6 +:1091F000F7F740FC0DB1012100E0002108464FF4D3 +:109200008371F7F737FC002084F831002562206A6B +:109210000068006840F04000216A0968086070BD7D +:109220007CB504460A20F7F763FF4FF480552946C2 +:10923000012001F0ADFA9749086008460068A06275 +:1092400020680169D1E90401CDE9000120680569C0 +:10925000EE68334695E80700B0473621206800F0F5 +:10926000E5FE0021206800F01BFF3A21206800F095 +:10927000DDFE0521206800F013FFB221206800F018 +:10928000D5FE0C21206800F00BFF0C21206800F0B7 +:1092900007FF0021206800F003FF3321206800F061 +:1092A000FFFE3321206800F0FBFEB721206800F0AC +:1092B000BDFE3521206800F0F3FEBB21206800F0E0 +:1092C000B5FE1921206800F0EBFEC021206800F0F7 +:1092D000ADFE2C21206800F0E3FEC221206800F0E2 +:1092E000A5FE0121206800F0DBFEC321206800F00C +:1092F0009DFE1221206800F0D3FEC421206800F0FA +:1093000095FE2021206800F0CBFEC621206800F0E9 +:109310008DFE0F21206800F0C3FED021206800F0F0 +:1093200085FEA421206800F0BBFEA121206800F08A +:10933000B7FEE021206800F079FED021206800F01F +:10934000AFFE0421206800F0ABFE0D21206800F084 +:10935000A7FE1121206800F0A3FE1321206800F071 +:109360009FFE2B21206800F09BFE3F21206800F02B +:1093700097FE5421206800F093FE4C21206800F0F5 +:109380008FFE1821206800F08BFE0D21206800F070 +:1093900087FE0B21206800F083FE1F21206800F06B +:1093A0007FFE2321206800F07BFEE121206800F091 +:1093B0003DFED021206800F073FE0421206800F0FB +:1093C0006FFE0C21206800F06BFE1121206800F078 +:1093D00067FE1321206800F063FE2C21206800F056 +:1093E0005FFE3F21206800F05BFE4421206800F012 +:1093F00057FE5121206800F053FE2F21206800F015 +:109400004FFE1F21206800F04BFE1F21206800F056 +:1094100047FE2021206800F043FE2321206800F051 +:109420003FFE2121206800F001FE1121206800F09C +:10943000FDFD7820F7F75CFE2921206800F0F6FD9D +:10944000206800F06CFD20680169D1E90401CDE9D4 +:10945000000120680569D5E902633246D5E90001BB +:10946000B04702212046E26D904700212046E26E7F +:1094700090476FF07F412046226E90472046616FF3 +:109480008847842002590449204690470020A0754F +:109490007CBD0000300100200001002010B506480E +:1094A000046803E02046FFF78BFE0446034800688B +:1094B0008442F7D310BD0000840000208800002003 +:1094C0002DE9FF4F95B09A46884606460025EEE105 +:1094D000252877D100242746F94A0121039400E08A +:1094E000044316F8013F203B01FA03F01042F7D184 +:1094F00030782A2811D06FF02F033078A0F1300295 +:10950000092A16D8039A44F0020402EB820203EB04 +:1095100042021044761C0390EFE758F8042B0392A4 +:10952000002A03DA504244F40054039044F0020449 +:10953000761C30782E2816D116F8010F44F004045A +:109540002A280DD06FF02F023078A0F13003092BBC +:1095500009D807EB870302EB4303C718761CF3E730 +:1095600058F8047B761C30786C280FD006DC4C2829 +:1095700017D068280DD06A2814D104E0742810D0C0 +:109580007A280FD10DE044F400140AE044F480146A +:1095900001E044F440147278824202D104F5801450 +:1095A000761C761C307866280BD013DC582877D0D0 +:1095B00009DC002875D04528F6D04628F4D0472885 +:1095C0001AD193E118E0632835D0642879D0652852 +:1095D00012D18BE1702873D008DC6728F1D069289C +:1095E0006FD06E280DD06F2806D1ACE073282CD038 +:1095F000752874D0782853D05246179990476D1C1F +:1096000054E1C4F30250022809D003280DD0D8F841 +:10961000001004280DD00D6008F1040846E1D8F8C8 +:109620000010EA17C1E90052F6E7D8F800100D80E3 +:10963000F2E70D70F0E718F8041B8DF80010002019 +:109640008DF80100EB46012003E058F804BB4FF011 +:10965000FF3061074FF0000102D40DE009F1010174 +:109660008946B9420FDA8145F8DB1BF80910002959 +:10967000F4D108E009F1010189468142FADB1BF8C7 +:1096800009100029F6D103985346A0EB090721469B +:109690003846179A00F080FA284400EB090507E0E5 +:1096A00044E008E10DE01BF8010B52461799904782 +:1096B000B9F10109F7D2534621463846179AF2E02C +:1096C00039E00A21C4F302524FF0000B0091022A44 +:1096D00006D058F8040BC117032A09D00AE023E08A +:1096E00008F1070020F00702F2E80201904605E0C9 +:1096F00000B2C117042A01D140B2C117002906DA0D +:109700000A460021404261EB02012D2202E02205BF +:1097100004D52B228DF80420012203E0E20701D0BA +:109720002022F7E7914657E00A2100E010214FF090 +:10973000000B00910BE010214FF0000B44F00404EB +:109740000827009103E008204FF0000B0090C4F3BD +:109750000252022A05D058F8040B0021032A08D02F +:1097600008E008F1070020F00702F2E80201904645 +:1097700003E080B2042A00D1C0B24FF000092207F2 +:109780002AD53278702A07D0DDF800C08CF0100C92 +:109790005CEA0B0C05D00EE040228DF8042001227B +:1097A00008E050EA010306D030238DF804308DF82C +:1097B000052002229146009B83F0080353EA0B0325 +:1097C0000AD150EA010201D1620705D530228DF895 +:1097D00004204FF001097F1E3278582A04D039A2A4 +:1097E0000C920CAA02920BE03BA2F9E75B46009AAE +:1097F000F6F748FD0C9B9B5C029A521E0292137076 +:1098000050EA0102F2D1029804A9081A00F1200BD3 +:10981000600702D524F4803400E001275F4502DDB3 +:10982000A7EB0B0000E0002000EB0B010090039879 +:109830004944401A0390E00306D453462146179A40 +:10984000039800F0A9F90544002706E001A8524654 +:10985000C05D179990476D1C7F1C4F45F6DBE003F8 +:109860000CD553462146179A039800F095F9054404 +:1098700004E030205246179990476D1C0099481E0D +:1098800000900029F5DC08E0029802995246007821 +:10989000491C0291179990476D1CBBF10001ABF177 +:1098A000010BF1DC5BE100F065F90544761C3078D2 +:1098B00000287FF40DAE19B02846BDE8F08F0000F7 +:1098C0000928010030313233343536373839616296 +:1098D000636465660000000030313233343536375A +:1098E000383941424344454600000000600700D437 +:1098F000062708F1070020F00700F0E80223804661 +:1099000003F0004C5FEA0C0001D097A009E02005AD +:1099100001D596A005E0E00701D095A001E0AFF2E7 +:109920004C001390307823F0004365280CD006DCFF +:10993000452809D046281DD047287FD13BE066281E +:1099400018D067287AD136E00021112F01DB1120D1 +:1099500000E0781CCDE9000104A90CA8FFF75CFB2E +:10996000DDE90D010C9A4FF0000B07F1010910928F +:1099700000914EE04FF000400097CDE9011004A99E +:109980000CA8FFF749FBDDE90D020C9B0F994FF086 +:10999000000B91461093009211B9791C00EB01095C +:1099A000B7EB090003D4C0F1FF3B07F10109A9EBB4 +:1099B0000700019042E0012F00DA01270021112F5A +:1099C00001DD112000E03846CDE9000104A90CA812 +:1099D000FFF722FBDDE90D010C9A00914FF0000B1F +:1099E000B946109221070FD4009A4A4503DA9146EE +:1099F00001E0A9F10109B9F1010F05DD109AA9F102 +:109A00000101515C3029F4D0B84202DA10F1040FA0 +:109A100003DA0121CDE9011010E0002803DC8344C2 +:109A2000A9EB000102E0411C494500DD8946A0EB9D +:109A30000B00401C01904FF000400290200705D41D +:109A40000198484502DB4FF0FF30019000208DF86F +:109A50004B0002980DF14B07B0F1004F25D00220CA +:109A60000C902B200D90029800280CDA40420290B6 +:109A70002D200D9007E00A210298F6F795FD303170 +:109A8000029007F8011D0C99481E0C900029F2DC89 +:109A900002980028EFD1791E0D980870307800F0F8 +:109AA000200040F0450007F8020D11A8C01BC01DA2 +:109AB00002901398007800B1012000EB0901019891 +:109AC00001EBE071029801440398401A401E039094 +:109AD000E00306D453462146179A039800F05CF839 +:109AE00005441398007818B15246179990476D1C99 +:109AF000E00323D553462146179A039800F04CF80B +:109B000005441BE0BBF1000F07DB0098584504DD5E +:109B10001098179910F80B0001E017993020524661 +:109B2000904701980BF1010B401E05F101050190D2 +:109B300004D12E205246179990476D1CB9F10001AF +:109B4000A9F10109DEDC05E017F8010B524617996F +:109B500090476D1C0299481E02900029F4DC534680 +:109B60002146179A03989EE62D0000002B00000066 +:109B7000200000002DE9F041044600251E4617464E +:109B8000880404D405E039462020B0476D1C641ECB +:109B9000F9D52846BDE8F0812DE9F04104460025BD +:109BA0001E469046C80301D5302700E020278804D0 +:109BB00004D505E041463846B0476D1C641EF9D512 +:109BC0002846BDE8F0810FB410B5BDF80C1002981E +:109BD000F7F79CFB012802D110BC5DF814FB0020B4 +:109BE000FAE70FB410B5BDF80C1000220298F7F791 +:109BF0009FFB10BC5DF814FB0FB410B5BDF80C1042 +:109C000001220298F7F794FB10BC5DF814FB2DE9D4 +:109C1000FC4704460D4616461F46DDF8288020689E +:109C20000169D1E90401CDE900012068D0F810C034 +:109C3000DCF80C904B469CE80700C8472A212068B6 +:109C400000F0F4F9E2892A4491B2206800F017FA92 +:109C5000E2893A4491B2206800F011FA2B21206881 +:109C600000F0E4F9228A324491B2206800F007FA49 +:109C7000228A424491B2206800F001FA2C21206827 +:109C800000F0D4F9206800F04AF920680169D1E9B0 +:109C90000401CDE900012068D0F810C0DCE902938E +:109CA0004A46DCE90001C847BDE8FC87816170478E +:109CB00030B500220023002401F478052A0A01F4BB +:109CC0007C456B09C1F3C40442EA03052543858240 +:109CD00030BD2DE9FC4104460D462572206801691E +:109CE000D1E90401CDE9000120680669F7683B4627 +:109CF00096E80700B8475DB93621206800F096F96C +:109D00007021206800F0CCF90020E08120822AE058 +:109D1000022D0BD13621206800F088F9002120683F +:109D200000F0BEF90020E08120821CE0012D0CD162 +:109D30003621206800F07AF9A021206800F0B0F9FF +:109D40005020E081002020820DE0032D0BD1362130 +:109D5000206800F06BF9C021206800F0A1F9002014 +:109D6000E08150202082206800F0D9F82068016945 +:109D7000D1E90401CDE9000120680669D6E9027342 +:109D80003A46D6E90001B847BDE8FC8170B5044603 +:109D90000D46E561A888142816D004DC0C2807D0ED +:109DA000102823D10AE0182814D020281ED117E04B +:109DB000842002590F492046904718E08420025918 +:109DC0000D492046904712E0842002590B49204655 +:109DD00090470CE08420025909492046904706E04C +:109DE0008420025907492046904700E000BF00BF89 +:109DF00070BD000024010020180100200C0100208B +:109E000000010020F40000204A68002A06D00A68F9 +:109E1000531C0B6010704868401E486070472DE965 +:109E2000FC4105460E4600270DB1012100E000214E +:109E30000846DD21F6F71EFE2C460CB1012100E09C +:109E4000002108463621F6F715FEA06960B1A16928 +:109E5000D1E90401CDE90001D4F818C0DCF80C8088 +:109E600043469CE80700C04700BF284602F076FE44 +:109E70003146284602F0A3FE0746284602F052FE6D +:109E80003846BDE8FC812DE9FC4705460E461746DD +:109E90004FF000080DB1012100E000210846F0213B +:109EA000F6F7E8FD2C460CB1012100E00021084640 +:109EB0002821F6F7DFFDA06960B1A169D1E90401AD +:109EC000CDE90001D4F818C0DCE902934A46DCE988 +:109ED0000001C84700BF284602F040FE002407E00A +:109EE0003178284602F06BFE8046761C601C84B2F6 +:109EF000BC42F5DB284602F015FE4046BDE8FC8773 +:109F00000A68531C0B60107070470FB410B5BDF891 +:109F10000C100298F7F702FA10BC5DF814FB00BFB2 +:109F2000016A0968896801F080010029F8D1704749 +:109F300000BF016A0968896801F002010029F8D0B0 +:109F400070472DE9FC4104460E4617462068006A1A +:109F5000006800684FF6BF7108402168096A096807 +:109F600008602068006A0068006840F400602168AA +:109F7000096A096808602068006A0068006840F0A3 +:109F800040002168096A0968086020680169D1E910 +:109F90000401CDE900012068D0F810C0DCF80C8085 +:109FA00043469CE80700C047002509E036F8150045 +:109FB0002168096A0968C8602068FFF7B9FF6D1C4D +:109FC000BD42F3D32068FFF7AAFF20680169D1E9F9 +:109FD0000401CDE900012068D0F810C0DCE902835B +:109FE0004246DCE90001C0472068006A006800685A +:109FF0004FF6BF7108402168096A09680860206847 +:10A00000006A006800684FF2FF7108402168096A21 +:10A01000096808602068006A0068006840F0400035 +:10A020002168096A09680860BDE8FC812DE9FC41E6 +:10A0300004460D462046FFF772FFE169D1E90401AD +:10A04000CDE90001E669F7683B4696E80700B847A6 +:10A05000206A0068C5602046FFF76AFF2046FFF7C8 +:10A060005EFFE169D1E90401CDE90001E669D6E9C5 +:10A0700002733A46D6E90001B847BDE8FC8170B5E5 +:10A0800004460D462812216A0968C8602046FFF779 +:10A090004FFF206A0068C5602046FFF749FF70BD8A +:10A0A00070B504460D46206A0068C5602046FFF77B +:10A0B0003FFF70BD1CB502F089FE0A480121002354 +:10A0C0008A02CDE9001008A10B4803F0EFFE0B480F +:10A0D00001210B4B8A02CDE900100AA10C4803F0C4 +:10A0E000E5FE1CBD7C000020627573696E657373AC +:10A0F0005F7461736B00000025A1000880000020E0 +:10A10000F81001207368656C6C5F7461736B0000FC +:10A11000C1C7000810B500F0BBF801F025F801F048 +:10A12000EFF810BD00BF01F0A5F800F039F90020EC +:10A1300000F000FA4FF47A7003F008F8F3E7F0B596 +:10A1400003460024012901D0022904D101F10C00A9 +:10A15000C1B2581E83B24D1C05EB4505052695FB83 +:10A16000F6F5022606FB012635441D441846DE1787 +:10A1700003EB967605EBA605642693FBF6F6AD1B7E +:10A180004FF4C87693FBF6F63544072695FBF6F7B1 +:10A1900006FB1755ECB2601CC0B2F0BD2DE9F041D2 +:10A1A00005460E4618273946002000F0F1FA04460D +:10A1B0000CB1012100E0002108463621F6F75AFCD7 +:10A1C0002560A6800548A0600548E060054820613C +:10A1D000054860612046BDE8F0810000F99B000859 +:10A1E000E39B00080B9F0008C79B000800BFEFF32C +:10A1F000058008B1012070470020FCE70FB470B55E +:10A2000098252946002000F0C3FA04460CB101212C +:10A2100000E0002108461C21F6F72CFC204604A98A +:10A22000382203E011F8013B00F8013B131EA2F1B4 +:10A230000105AAB2F6D100BF012184F894100220D2 +:10A2400020B1012803D0022807D101E00CE00BE087 +:10A2500004F1380000F03EF906E0204600F007F86F +:10A26000002070BC5DF814FB00BF2046F9E710B574 +:10A2700004460CB1012100E0002108461421F6F744 +:10A28000F9FB00BF2146002000F058FA00BF10BDC6 +:10A2900030B5ADB04FF400613D48FFF77FFF299026 +:10A2A0004FF480513A48FFF779FF2C903822394912 +:10A2B00018A8F6F718F80020049029A80FC88DE810 +:10A2C0000F00012026A90EC902F0EAFB1890189889 +:10A2D0003149C26A9047232218A90AA8F6F703F861 +:10A2E0009DF883008DF84B00142221A913A8F5F7DF +:10A2F000FAFF28220EA96846F5F7F5FF0AA80FC84D +:10A30000FFF77CFF25490861096909B1012100E0D7 +:10A31000002108464FF48771F6F7ACFB1F4800692F +:10A320000068C169D1E90401CDE900011B48006959 +:10A330000068C469194800690068C069856894E8C4 +:10A340000F00A8471548006900680169D1E90401B8 +:10A35000CDE9000111480069006804690F480069EF +:10A3600000680069856894E80F00A84700224FF450 +:10A3700000510748F6F7DCFF084A10691269916B33 +:10A380008847012251030248F6F7D2FF2DB030BDB5 +:10A39000000C0240ACE400085406002028440020D1 +:10A3A00030B5A5B0802105A8F5F7B6FF3349086997 +:10A3B0000969D1F88820324990473049086909690C +:10A3C000CA6E002190472D49086909690A6E6FF02D +:10A3D0007F41904746242949086909690A6E29493D +:10A3E000904726490869096927A322468D6E0D21E9 +:10A3F000A8472249086909690A6E274990471F49F9 +:10A400000969C969C98821448AB21C49086909696E +:10A4100022A38D6E0D21A8471849086909690A6EA3 +:10A4200023499047154908690969D1F884202149D1 +:10A4300090471248007B1149C97A104A927A0F4B13 +:10A44000DB79CDE90032CDE902100C4883798088B0 +:10A4500000F5FA6218A105A8FEF7E4FB07490969AF +:10A46000C969C98804EB41018AB2044908690969CC +:10A4700005AB8D6E0D21A84725B030BD28440020C6 +:10A48000DC000020FF80800053544D3332205254B2 +:10A4900043B2E2CAD400000080FFFF00C6C1C4BBC3 +:10A4A000B7D6B1E6C2CA3A3234302A32343000006C +:10A4B0008080FF000C01002025642D253032642DA2 +:10A4C0002530326420253032643A253032643A2512 +:10A4D0003032640010B504460CB1012100E00021C7 +:10A4E000084640F2AF11F6F7C5FA0948206009485E +:10A4F00060620948A0620948A0630948E06409480D +:10A500002065094820630948E0630948606310BD7D +:10A5100021920008D39C0008B19C00080F9C000801 +:10A52000AD9C00088D9D0008CD8F0008D78C0008D9 +:10A530009D91000810B504462CB94FF40051034812 +:10A54000F6F7ECFE00E000BF00BF10BD00080240BF +:10A55000F6F706FFFBF710FBF9F778FFF9F730FF86 +:10A56000FAF78CF8FAF7A4F8F9F74EFFFAF7C4F8FF +:10A57000FAF7A0F8002000F04BF8012000F048F8AE +:10A58000FFF7C8FDFFF796FDF9F74CFF00F033F930 +:10A5900000BFFEE701460020842901D0CA1C1044F8 +:10A5A000704700002DE9F04104460E461548005D55 +:10A5B00038B9144818380168204688470120BDE89A +:10A5C000F081114850F82400B04219D90F4850F8D2 +:10A5D0002400B6FBF0F70B48083850F8240030F898 +:10A5E0001780002508E000210648083850F82400AC +:10A5F0007A1920F812106D1C4545F4DB0020DEE7C7 +:10A600000120DCE7A40000200CE5000804E50008B8 +:10A6100010B504460C4951F824104A000B4951F872 +:10A620002400002100F0C8F8094951F82420074906 +:10A63000083951F82400002100F0BEF80121034838 +:10A640000830015510BD0000FCE400089C0000200B +:10A650000CE500082DE9F04704460F460025A94601 +:10A660002348005D20B922481838016820468847F1 +:10A670001FB94FF0FF30BDE8F0871E4850F82400A6 +:10A68000B7FBF0F61B4850F82400B7FBF0F100FBD5 +:10A69000117000B1761C184850F82400451E22E0C5 +:10A6A0001348083850F8240030F8150010B909F1A3 +:10A6B000010901E04FF00009B14513D14FF0000846 +:10A6C00009E00B48083850F8240005EB080220F890 +:10A6D000126008F10108B045F3D3064850F8240091 +:10A6E0006843C8E76D1E002DDADA4FF0FF30C2E78D +:10A6F000A400002004E50008FCE4000810B50146B1 +:10A700000023002207E00B4850F8210030F8120027 +:10A7100000B15B1C521C084850F821009042F2D84E +:10A7200064205843044C54F82140B0FBF4F0C0B20C +:10A7300010BD00009C000020FCE400082DE9F04161 +:10A7400004460D460DB9BDE8F0810F4850F82400CD +:10A750002E1A0E4850F82400B6FBF0F10A480830D3 +:10A7600050F8240030F81100084951F8241000FB7B +:10A7700001F73A460021284600F01EF831462046EF +:10A78000FFF710FF00BFDEE79400002004E500089B +:10A7900070B504460E4631462046FFF75BFF05467E +:10A7A000681C08B9002070BD024850F824002844F5 +:10A7B000F9E700009400002030B5034601E003F8FB +:10A7C000011B141EA2F10102F9D130BD70B504467F +:10A7D00025460DB1294600E00121084602F0B6FCED +:10A7E000002070BD10B503F0F1FB012801D100205D +:10A7F00010BD0120FCE710B502F076FD002010BD71 +:10A8000010B5FFF7F3FC10B103F0F6FB10BD03F039 +:10A81000EDFBFBE7F8B504460D46A06840B1E068E3 +:10A8200030B10020009094E80F0002F0F5FEF8BD72 +:10A830000022D4E9000102F0C2FEF8E72DE9FF4151 +:10A8400007460D4614460295002001903DB9802030 +:10A8500000909DE8070087E80700BDE8FF81002021 +:10A8600003900026601C08B9761E03E014B126464A +:10A8700006B90126FFF7BAFCB0B103AA01A9284620 +:10A8800003F08CF9012802D11020009001E0002093 +:10A8900000900398B8B14FF080500E490860BFF3A4 +:10A8A0004F8FBFF36F8F0EE0324601A9284603F0A9 +:10A8B000C1F8012802D11020009004E00EB9002058 +:10A8C00000E0402000909DE8070087E8070000BFF7 +:10A8D000C3E7000004ED00E077B581B006461446FA +:10A8E00000200090254605B90125FFF77FFCA8B19F +:10A8F00000236A4602A9304603F01EF8012802D060 +:10A90000FF2004B070BD009890B14FF0805009490D +:10A910000860BFF34F8FBFF36F8F09E000232A4613 +:10A9200002A9304602F034FF012801D0FF20E8E7F9 +:10A930000020E6E704ED00E07FB504460D466069BF +:10A9400098B1A06988B1B4F90800FFF723FE064664 +:10A95000D4E90510CDE9006102902B462269D4E9C3 +:10A96000001003F0D5FA039013E0B4F90800FFF7E4 +:10A9700011FE064603A8CDE90060238A9AB22B4651 +:10A98000D4E9001003F092FA012802D0002004B0AC +:10A9900070BD0398FBE700002DE9F04105460E4627 +:10A9A0001C4807681C480068001D02F08FFA50B967 +:10A9B0001948006890F82C10012088401749096850 +:10A9C000814316480160681C38B936B112480168E5 +:10A9D000091D134802F0C4FA1AE07C190E480068F9 +:10A9E0004460BC4207D20C480168091D0D4800684C +:10A9F00002F09CFA0CE008480168091D0A4800684A +:10AA000002F094FA09480068844201D207480460C1 +:10AA1000BDE8F08128000020140000202C00002058 +:10AA2000140800201C000020180000204400002012 +:10AA300010B5044602F0A0FA23480068401C2249E1 +:10AA400008602248006840B9204804600846006851 +:10AA500001280DD100F0BEF90AE01D48006838B9A0 +:10AA60001A480068C06AE16A884201D81748046041 +:10AA700018480068401C1749086094F82C10012001 +:10AA8000884015490968084313490860E16A01EBE9 +:10AA90008101124A02EB8100211D02F061FA02F0ED +:10AAA00095FA0B48006868B108480068C06AE16A16 +:10AAB000884207D24FF0805009490860BFF34F8F9A +:10AAC000BFF36F8F10BD0000240000201400002091 +:10AAD00030000020400000202C000020380700201B +:10AAE00004ED00E010B516E002F046FA0C48C0682C +:10AAF000C468201D02F0EAF90A480068401E0949AE +:10AB0000086009480068401E0749086002F05EFAC4 +:10AB1000204600F05FF8044800680028E4D110BD2A +:10AB200000080020240000202000002070B504460A +:10AB30000D46206C70B1216CE0680144E160D4E9FD +:10AB40000210884201D32168E1602846226CE16846 +:10AB5000F5F7C9FB70BD2DE9F04104460F461546D7 +:10AB60004FF00008A66B206C48B9206800282CD153 +:10AB7000A06803F0EFFA80460020A06025E07DB9D0 +:10AB80003946226C6068F5F7AEFB216C60680844BA +:10AB90006060D4E90101884217D32068606014E046 +:10ABA0003946226CE068F5F79EFB216CE068411A9B +:10ABB000E1602168E068884203D2216CA068411AF4 +:10ABC000E160022D01D106B1761E701CA0634046E3 +:10ABD000BDE8F08110B5044694F8510030B9206BFF +:10ABE00002F012FA204602F00FFA1AE094F851002F +:10ABF000012803D1204602F007FA12E094F8510030 +:10AC0000022801D1012000E0002050B900BF5020EF +:10AC100080F31188BFF34F8FBFF36F8F00BF00BF6A +:10AC2000FEE710BD01464A6A22B10A6B1268C2F102 +:10AC3000070000E00020704730B54FF4705317480C +:10AC400000F007042CB1C01D20F00700134C041BBA +:10AC50001B1B0246124C22600024114D6C60D01860 +:10AC6000083820F007000F4C206000240D4D2D689F +:10AC70006C600C4D2D682C601146441A4C60094CD8 +:10AC800024680C60084D4C682C60084D4C682C60A2 +:10AC90004FF00044064D2C6030BD00002808002015 +:10ACA0005000002058000020600000205C000020C0 +:10ACB0006C00002000BFFFF715FF06480068012860 +:10ACC000F9D94FF0805004490860BFF34F8FBFF3AC +:10ACD0006F8FF0E73807002004ED00E010B5044660 +:10ACE00054B10020A06020600021E16000231A46DA +:10ACF0001946204602F04CFD10BD2DE9F0410646F4 +:10AD00000D4617469846069C0DB9246000E0276062 +:10AD1000E66325640121204602F0EEFCBDE8F081E7 +:10AD20002DE9FF5F81460E469246DDE90E7B109CC1 +:10AD3000AAF10100216B01EB800828F0070808F058 +:10AD4000070008B9012000E0002050B900BF5020E2 +:10AD500080F31188BFF34F8FBFF36F8F00BF00BF29 +:10AD6000FEE786B1002507E0715D04F1340041552E +:10AD7000705D00B902E06D1C102DF5D300BF0021FD +:10AD80004320015502E0002084F83400072F00D34F +:10AD90000627E76267640020A064201D02F0C3F864 +:10ADA00004F1180002F0BFF82461C7F10700A061A8 +:10ADB00064620020E06484F8500049464046039AEB +:10ADC00000F0BCF92060BBF1000F01D0CBF80040CF +:10ADD000BDE8FF9F10B5002407E004EB84010F4A93 +:10ADE00002EB810002F092F8641C072CF5D30C48AA +:10ADF00002F08CF80B4802F089F80B4802F086F854 +:10AE00000A4802F083F80A4802F080F80448094929 +:10AE1000086004480849086010BD00003807002099 +:10AE2000C4070020D8070020EC07002000080020FD +:10AE300014080020180000201C00002010B5014656 +:10AE4000164800E0006803688B42FBD30246436863 +:10AE500013448B4204D143684C6823444360014649 +:10AE60000A464B6813440468A34211D10C4C036892 +:10AE70002468A34208D04B680468646823444B608C +:10AE800003681B680B6005E0054B1B680B6001E065 +:10AE900003680B60884200D0016010BD50000020A4 +:10AEA0005800002070B5054602F066F8A86B08B996 +:10AEB000012400E0002402F089F8204670BD70B53E +:10AEC000054602F059F8A86BE96B884201D10124CC +:10AED00000E0002402F07AF8204670BD0A490968B3 +:10AEE000096809B9012100E0002121B14FF0FF31CB +:10AEF000064A116006E004490968C968C868034A3F +:10AF000041681160704700001800002044000020D4 +:10AF10000E480068401C08B9012000E0002050B92C +:10AF200000BF502080F31188BFF34F8FBFF36F8FA6 +:10AF300000BF00BFFEE700BF502080F31188BFF3C1 +:10AF40004F8FBFF36F8F00BF00BFFEE77000002080 +:10AF500070B5044602F010F894F9455010E0606AAC +:10AF600008B9012000E0002038B904F1240003F002 +:10AF7000B1F918B102F024F900E003E0681E45B20F +:10AF8000002DECDC00BFFF2084F8450002F01EF825 +:10AF900001F0F2FF94F9445010E0206908B9012053 +:10AFA00000E0002048B904F1100003F093F908B163 +:10AFB00002F006F9681E45B200E001E0002DECDC6D +:10AFC00000BFFF2084F8440002F000F870BD0000CC +:10AFD0002DE9F04104464FF0000802F0DDF9494840 +:10AFE000006808B9FFF728FE47480068204000289D +:10AFF00070D1D4B1083404F00700B0B104F00700F8 +:10B00000C0F10800044404F0070008B9012000E082 +:10B01000002050B900BF502080F31188BFF34F8F3C +:10B02000BFF36F8F00BF00BFFEE7002C52D0374840 +:10B03000006884424ED8364E3046056801E02E4600 +:10B040002D686868A04202D228680028F7D12D48F0 +:10B05000006885423ED0306800F1080828683060FA +:10B060006868001B102819D92F1907F0070008B9C4 +:10B07000012000E0002050B900BF502080F311886B +:10B08000BFF34F8FBFF36F8F00BF00BFFEE768684D +:10B09000001B78606C603846FFF7D0FE1B4968687B +:10B0A0000968081A194908600846006819490968BA +:10B0B000884203D21548006816490860124968683A +:10B0C0000968084368600020286013480068401C35 +:10B0D0001149086003F04AF908F0070008B9012097 +:10B0E00000E0002050B900BF502080F31188BFF36A +:10B0F0004F8FBFF36F8F00BF00BFFEE74046BDE834 +:10B10000F0810000580000206C0000205C0000204E +:10B110005000002060000020640000200648006805 +:10B1200030B10549096801F14800896C491C01608A +:10B13000014800687047000014000020001F4FF015 +:10B1400080730360001F21F001030360001F054BA3 +:10B15000036014380260001F6FF0020303602038A0 +:10B160007047000011AF00083EB50024002000F039 +:10B1700035F884B245F2500084422CD0401C844201 +:10B1800029D01920ADF8040001208DF806008DF8B3 +:10B1900007009DF807209DF80610BDF8043003F560 +:10B1A000FA6398B2FEF7CBFF8DF8080000208DF807 +:10B1B00000008DF801008DF802000021009800F0D9 +:10B1C00037F8DDE9010100F013F845F251010020E4 +:10B1D00000F07AF800BF01203EBD000001460022C9 +:10B1E000024800EB810210687047000050280040C0 +:10B1F00003B581B09DF806008DF801009DF80700A9 +:10B200008DF80200BDF80400C0B28DF803009DF86F +:10B2100008008DF80000002269460448F7F7E6FDB3 +:10B2200008B901200EBD0020FCE70000F00400205A +:10B2300013B586B00C469DF818008DF804009DF8F3 +:10B2400019008DF805009DF81A008DF806008DF89C +:10B250000740002004900590002201A90448F7F758 +:10B2600025FE10B9012008B010BD0020FBE700004A +:10B27000F004002000B587B0002201A91048F7F7BC +:10B2800017FD002206A90E48F7F7ECFC9DF8040014 +:10B290000C4988729DF805100A48C1729DF8061085 +:10B2A00001739DF8181001729DF8191081719DF8B5 +:10B2B0001A10C1719DF81B000249888007B000BDBB +:10B2C000F00400202844002070B504460D46F7F72E +:10B2D00031F82A4621460248F7F7BAFC70BD000053 +:10B2E000F004002010B588B069460448F7F7BCFFA9 +:10B2F00004460CB108B010BD00BFFBE73C44002081 +:10B3000010B50E480E4908600020486000210C4826 +:10B310008160C1600161416104218161F7F7C9FF6A +:10B3200008B1F5F747FC4FF400610548F7F752FE06 +:10B3300008B1F5F73FFCFFF7D5FF10BD002C014029 +:10B340003C4400200146002009E0074A52F8202032 +:10B350001AB9054A42F820107047421C10B205285D +:10B36000F3DB00BFF8E70000D810012010B5044659 +:10B370000121204600F075F810BD000010B504460C +:10B38000226891682069F4F7D9FF60B994F86000E9 +:10B3900020F00100401C84F8600008480168204645 +:10B3A00001F066FB04E00548416B204601F060FBBC +:10B3B0000020A0810021E18110BD000028020020B2 +:10B3C0000246087858B1487800F00F00082806D0E7 +:10B3D000106878B1087813681B78184050B192F85B +:10B3E000600000F0010018B94878C0F3001008B1FF +:10B3F000002070474FF0FF30FBE7000010B500F071 +:10B400001BFB044624B10348816B204601F030FB4E +:10B4100010BD00002802002070B50446A189E08913 +:10B42000081A05B205E02021204601F03BFA681E0B +:10B4300005B2002DF7DC217B204600F07FF870BDBF +:10B4400010B500F0F9FA044614B1204600F054FD9E +:10B4500010BD10B504464FF0FF31204600F001F852 +:10B4600010BD2DE9F04104460D46681C08B90120C5 +:10B4700000E000200746E08908B9012D05D0E089E9 +:10B48000A189884203D1681C08B9BDE8F081E08930 +:10B49000A189884210D1012D0ED1E089401EE081A2 +:10B4A000A089401EA0810021A28920698154012128 +:10B4B000204600F043F83FE038460AE0E1890144C5 +:10B4C0002269525CE1890144491E23695A54411C96 +:10B4D00008B2A289E189511A8142EFDCA089401E9D +:10B4E000A08137B9E089401EE0810821204601F0A3 +:10B4F000D9F90021A28920698154E08906B206E0C9 +:10B500002069815D204601F0CDF9701C06B2A0894A +:10B51000B042F5DC2021204601F0C4F9A189E08980 +:10B52000081A401C06B205E00821204601F0BAF9CD +:10B53000701E06B2002EF7DC00BFA6E770B5054608 +:10B540000C4603E004A1284601F092FA201EA4F163 +:10B550000101CCB2F6D170BD0820080010B5044638 +:10B560004FF0FF31204600F041FB10BD10B50446FE +:10B57000204600F005F80121204601F0FFF910BD3A +:10B5800070B50446A08900B970BD0021A289206968 +:10B59000815494F8600000F0010010B3204600F0E0 +:10B5A00086FB204600F0DEFD0021E181A181E08ED6 +:10B5B00000B9E9E70DA1204601F05AFA0023204620 +:10B5C000A26D616900F077FE054625B12946204647 +:10B5D00000F018FE04E006488169204601F048FAB0 +:10B5E00002E02046FFF7CAFE00BFCDE70D0A0000CB +:10B5F0002802002010B50246114600200B78302B9F +:10B6000007D14B78782B02D04B78582B01D10320EF +:10B610000EE00B78302B07D14B78622B02D04B78A1 +:10B62000422B01D1012003E00B78302B00D1022006 +:10B6300006E00B782E2B03D14B780BB1042003E0EE +:10B6400011F8014B002CF4D100BF10BD0246137855 +:10B65000272B01D1531C00E01346194600200B781C +:10B660005C2B1AD14B786E2B0ED004DC302B0FD014 +:10B67000622B0FD104E0722B04D0742B0AD105E0A9 +:10B68000082009E00D2007E00A2005E0092003E07A +:10B69000002001E0487800BF00E008787047000013 +:10B6A0002DE9F84F05464FF0000A4FF00A0B2C46E3 +:10B6B00000200090012600279FED330A10EE109A1B +:10B6C000804628782D2800D1B61E711C09B90121A9 +:10B6D00000E000214819FFF78DFF8246BAF1010F03 +:10B6E0000FD0BAF1020F07D0BAF1030F0ED14FF00D +:10B6F000100B022000900AE04FF0080B0120009090 +:10B7000005E04FF0020B0220009000E000BF00BFF8 +:10B7100000982918701C08B9012000E000200C18BE +:10B7200011E020782E2803D14FF00108641C0AE0B4 +:10B73000207800F025F907FB0B0708EB88004FEA9B +:10B740004008641C00BF20780028EAD1BAF1040F39 +:10B7500017D1B8F1000F14D000EE107AB8EE401AED +:10B7600000EE108AB8EE400AC1EE000A00EE106A40 +:10B77000B8EEC00A20EE800A10EE109A4846BDE8E6 +:10B78000F88F07FB06F0FAE7000000002DE9F04112 +:10B7900007460C4616461D4626B1207824282FD190 +:10B7A000607868B32078272808D1607830B12046C7 +:10B7B000FFF74CFF28600020BDE8F08120782D289D +:10B7C00005D02078302808DB2078392805DC204691 +:10B7D000FFF766FF28600020EEE72078242807D1D5 +:10B7E000607828B12A462146384600F031F8E3E770 +:10B7F000207828B1204600F006F828600020DBE71A +:10B800004FF0FF30D8E770B5044625460026207873 +:10B81000222802D1601C0446054613E028785C28E3 +:10B8200005D12846FFF712FFA0556D1C07E02878C8 +:10B83000222802D10020A05501E02878A0556D1CD7 +:10B84000701C86B228780028E8D1A055204670BD2B +:10B850002DE9F04104460D4616460023691C20469A +:10B86000A26D00F028FD07463FB13946204600F0A2 +:10B87000FDF830600020BDE8F0814FF0FF30FAE7BE +:10B880002DE9F0478CB080460C4615461E464FF019 +:10B89000000A202104A8F4F73FFDA07800F00F0172 +:10B8A000681E814203DDA07800F00F0000E0681EF2 +:10B8B00007464FF0000912E004A800EB890309F1E4 +:10B8C000010056F8201000224046FFF75FFF20B12C +:10B8D0004FF0FF300CB0BDE8F08709F10109681E98 +:10B8E0004845E9DC082F45D2DFE807F004080E15CB +:10B8F0001C232C37A068804782463EE0D4F808908D +:10B900000498C847824638E0D4F80890DDE904017D +:10B91000C847824631E0D4F8089004A807C8C84751 +:10B9200082462AE0D4F8089004A80FC8C847824687 +:10B9300023E0D4F808900898009004A80FC8C847DE +:10B9400082461AE0D4F80890DDE90801CDE900014B +:10B9500004A80FC8C84782460FE0D4F80890DDE974 +:10B9600008120A98CDE90012029004A80FC8C8472F +:10B97000824602E04FF0FF3A00BF00BF5046A9E701 +:10B980000146302905DB392903DCA1F13000C0B2C2 +:10B990007047612905DB662903DCA1F15700C0B2BD +:10B9A000F6E7412905DB462903DCA1F13700C0B2E7 +:10B9B000EEE70020ECE70146487800F00F00012890 +:10B9C00001DCC8687047487800F00F00072801DCE8 +:10B9D000C868F7E7487800F00F00082801DCC8685D +:10B9E000F0E7C868EEE7000010B50446002004E068 +:10B9F0003021104A1154411CC8B20928F8DB607884 +:10BA000000F00F00012801DC606810BD607800F0D4 +:10BA10000F00072801DC6068F7E7607800F00F008E +:10BA2000082801DC6068F0E70249606800F005FF63 +:10BA30000048EAE7EC100120002111E00A4850F824 +:10BA4000210058B1084850F8210090F86000C0F378 +:10BA5000400018B1044850F821007047481C01B25A +:10BA60000529EBDB0020F8E7D81001202DE9F04193 +:10BA700007460C460026607800F00F00801E06285E +:10BA80001BD2DFE800F003060A0D0E10A06806685E +:10BA900014E0A068B0F9006010E0A06806780DE03E +:10BAA00000BFA6680AE0A06845681DB1A1680868E3 +:10BAB000A84700E00020064600E000BF00BF304677 +:10BAC000BDE8F0812DE9F04704468846B8F1000F43 +:10BAD00001D1BDE8F0872046E16E884718274FF076 +:10BAE0000009208F00F47F4018B100276FF0FF0994 +:10BAF0000EE0A06B00F47F0018B10827DFF8BC90BF +:10BB000006E0A06B00F07F4010B110274FF07F4996 +:10BB1000A66D00253EE006EB0510407800F00F0012 +:10BB2000092835D106EB05112046FFF749FC70BB0B +:10BB300006EB0510406800EA0900A16B884227D196 +:10BB400006EB05104168FF20B840084008FA07F1ED +:10BB500088421DD108FA07F1A06B0843A0634FF09B +:10BB6000000847B106EB05104068A7F10801FF2265 +:10BB70008A40104058B906EB0510806820B106EBEA +:10BB800005108168204688470021A16306E0FFE791 +:10BB9000681C05B25C20005BA842BCDC00BFB8F1A9 +:10BBA000000F05D00021A1634146204600F0CCFAE9 +:10BBB0002046216F884700BF8BE700000000FFFF91 +:10BBC00070B504460D46FFF737FF064606B970BD4F +:10BBD000012C03D1304600F089F905E0012C03DD8A +:10BBE0003046696800F094FE00BFF0E770B5044687 +:10BBF0000D46002D25DDB4F954105420005B401E85 +:10BC000002B2542002535020025B5220005B824259 +:10BC100002DD5020005B01E05220005B4042814287 +:10BC20001DDC5020015B5220005B814202DD502070 +:10BC3000005B01E05220005B404201B254200153FE +:10BC40000DE0002D0ADA5420005B401C01B25420A4 +:10BC50000153002903DD0021015370BDFDE720469B +:10BC6000FFF7DAFB5420005B18B90021A181E181C4 +:10BC70001BE05220005B401DB4F95410084405211C +:10BC800090FBF1F201FB120104F13C0050F821603D +:10BC90003146206900F000FDA08100B9DDE7A189EF +:10BCA000E1812046216900F0E3FE00BFD5E710B531 +:10BCB00004460021542001535020005B002810DD71 +:10BCC0005222125B21690AB9052201E05222125B5D +:10BCD000521E04F13C0353F82200F4F72FFB00B985 +:10BCE00010BD5222135B04F13C0252F8230021697B +:10BCF00000F0D2FC28B15220005B401C81B25220DF +:10BD000001535020005B401C81B250200153052993 +:10BD100001DD052101535220005B052802DB0021D3 +:10BD20005220015300BFDBE72DE9F04104460D46E8 +:10BD300016460020A0810021E181206094F8600077 +:10BD400020F00100401C84F860002561062096FB6D +:10BD5000F0F0A0865420015350200153522001538B +:10BD6000002009E0A28E411C02FB015204F13C01BB +:10BD700041F82020411C08B20528F3DB0E48A065DD +:10BD80000E480D49401AC0F30F115C2001532046A4 +:10BD9000FFF7D8FA00230AA12046A26D00F08BFA23 +:10BDA00007463946204600F0C3FA0121204600F03C +:10BDB000E5FDBDE8F0810000205101084052010876 +:10BDC0006C6574746572000070B504460D46A189F7 +:10BDD000A08E401E81420DDB38484168204600F0AD +:10BDE00047FE0121204600F0C9FD2046216900F0F0 +:10BDF0003FFE70BDE089A189884218D1A189481C05 +:10BE0000A081206945540021A28920698154E089DC +:10BE1000401CE08194F8600000F0010008B1284661 +:10BE200000E02A200146204600F03CFD44E0E08985 +:10BE3000A189884240DAA289E189511A08B20AE050 +:10BE4000E1890144491E2269525CE1890144236968 +:10BE50005A54411E08B20028F2DCE189481CE081F6 +:10BE6000206945540021A089401C80B22269A0812C +:10BE70001154E089401E06B20EE094F8600000F014 +:10BE8000010010B12069805D00E02A2001462046B3 +:10BE900000F008FD701C06B2A089B042EDDCA1895B +:10BEA000E089081A06B205E00821204600F0FAFCF5 +:10BEB000701E06B2002EF7DC00BF9AE728020020B1 +:10BEC00010B5FFF7B9FD044614B1204600F0B8F8EC +:10BED00010BD10B50446E089002806DD0821204683 +:10BEE00000F0E0FCE089401EE08110BD10B5044682 +:10BEF000204600F001F810BD70B50546AE6D104843 +:10BF00008168284600F0B4FD002413E006EB04101D +:10BF1000407800F00F0001280ADC06EB04112846E7 +:10BF2000FFF74EFA20B906EB0411284600F00AF894 +:10BF3000601C04B25C20405BA042E7DC70BD0000E6 +:10BF4000280200202DE9F04107460C462046FFF765 +:10BF50004BFD05462946384600F08AFDC0F1160023 +:10BF600006B2002E01DD304600E00420064600BF88 +:10BF70002021384600F096FC701E00B2061EF7D154 +:10BF8000607800F00F00012805DC2A48016C384673 +:10BF900000F06EFD25E0607800F00F00072805DC5A +:10BFA0002448416C384600F063FD1AE0607800F0E8 +:10BFB0000F00082805DC1F48816C384600F058FD4A +:10BFC0000FE0607800F00F00092805DC1948C16C0B +:10BFD000384600F04DFD04E01648016D384600F08B +:10BFE00047FD15A1384600F043FD07250DE02078F8 +:10BFF0000122AA40104008B1782000E02D2001461F +:10C00000384600F04FFC681E45B2002DEFDA0AA159 +:10C01000384600F02DFD2046FFF7CDFC05462946A9 +:10C02000384600F047FC05A1384600F021FDBDE888 +:10C03000F081000028020020202000000D0A0000EE +:10C0400070B50646B56D13484169304600F010FDE5 +:10C0500000241AE005EB0410407800F00F000828D7 +:10C0600011DD05EB0410407800F00F0009280ADC10 +:10C0700005EB04113046FFF7A3F920B905EB0411D5 +:10C080003046FFF75FFF601C04B25C20805BA0427B +:10C09000E0DC70BD2802002070B50646B56D13487F +:10C0A0000169304600F0E4FC00241AE005EB0410BE +:10C0B000407800F00F00072811DD05EB04104078F0 +:10C0C00000F00F0008280ADC05EB04113046FFF7EA +:10C0D00077F920B905EB04113046FFF733FF601CF8 +:10C0E00004B25C20805BA042E0DC70BD280200202E +:10C0F00070B50646B56D1348C168304600F0B8FC0F +:10C1000000241AE005EB0410407800F00F0001282D +:10C1100011DD05EB0410407800F00F0007280ADC61 +:10C1200005EB04113046FFF74BF920B905EB04117C +:10C130003046FFF707FF601C04B25C20805BA04222 +:10C14000E0DC70BD2802002070B504460D4694F86E +:10C15000600020F0040084F8600029462046FFF7C4 +:10C1600033FE70BD18B5044608200090A189202335 +:10C1700004F11402206900F0EDF9E08618BD70B5F5 +:10C18000044600252BE004F1140050F82500007847 +:10C1900022280CD1002104F1140050F82500017070 +:10C1A00004F1140050F82510491C40F8251004F142 +:10C1B000140151F82500F4F7BAF886B204F114001E +:10C1C00050F82510701E085C222806D1002104F1C9 +:10C1D000140050F82520701E1154681C85B2E08EA2 +:10C1E000A842D0DC70BD10B50446E089A189884220 +:10C1F00007DAE289501CE0812069815C204600F06A +:10C2000051FB10BD2DE9F04104460D46002694F87F +:10C21000600020F00200801C84F86000687800F064 +:10C220000F0088B92046FFF7AAFFAF68E08E04F13F +:10C230001401B84706466878C0F3401018B9314673 +:10C24000204600F0CFFB2DE0687800F00F000128B9 +:10C2500010D1E28E04F1140329462046FFF710FBAB +:10C2600006466878C0F34010E0B93146204600F039 +:10C27000B9FB17E0687800F00F00022809DB687846 +:10C2800000F00F00072804DC2946204600F002F9E0 +:10C2900008E0687800F00F00082803D129462046FE +:10C2A00000F046F894F8600020F0020084F8600086 +:10C2B0003046BDE8F0812DE9F04706468846144631 +:10C2C0001F465C20805BB16D611AA0EB11101FFA54 +:10C2D00080F9002528E004EB0510407800F00F00FD +:10C2E000092805D004EB05113046FFF769F800B1C5 +:10C2F00018E004EB0510FFF777FB824647B951467B +:10C300004046F4F71BF860B904EB0510BDE8F08770 +:10C310003A4651464046F4F71FF810B904EB0510B1 +:10C32000F4E700BF681C85B24D45D4DB0020EDE783 +:10C3300070B504460D462560A86858B1A868F3F7A3 +:10C34000F6FF38B1E08E022806DBA169A868F3F792 +:10C35000F5FF08B9012000E0002094F8601060F3B8 +:10C36000000184F860100848816B204600F080FBD3 +:10C3700094F8600000F0010020B1034801682046F5 +:10C3800000F076FB70BD0000280200202DE9F0418E +:10C3900006460F46FFF750FB054615B90020BDE8DD +:10C3A000F081002331462846AA6DFFF784FF04463A +:10C3B00034B91148816A284600F05AFB0020EEE7A4 +:10C3C000607800F00F00022804DB607800F00F00B6 +:10C3D00007280ADD3146284600F04AFB0648416A34 +:10C3E000284600F045FB0020D9E73A46214628467A +:10C3F00000F004F8D3E70000280200202DE9F04106 +:10C4000006460C4615466078C0F3801028B12048D7 +:10C41000016A304600F02CFB34E0607800F00F0039 +:10C42000801E06282CD2DFE800F003060A0D121841 +:10C43000A068056025E029B2A068018021E0A0681D +:10C4400005701EE02946A06800F026F919E01048A2 +:10C45000C169304600F00CFB13E0A068806870B141 +:10C46000A068006830B1A0688768A168086829469C +:10C47000B84704E0A06887682846B84700BF00E0D6 +:10C4800000BF00BF2146304600F004F8BDE8F0814F +:10C4900028020020FEB505460C4626A207CA8DE8F4 +:10C4A000070021462846FFF7E1FA0746284661685B +:10C4B00000F0DEFA22A1284600F0DAFA607800F0F7 +:10C4C0000F0005280CD11FA1284600F0D1FA3946EB +:10C4D000284600F0CDFA1BA1284600F0C9FA21E059 +:10C4E0006946384600F07EF9C0F10B0069464618EF +:10C4F0003146284600F0BCFA13A1284600F0B8FAED +:10C50000002004E030210DF80010411C08B20B2877 +:10C51000F8DB6946384600F090F96946284600F095 +:10C52000A7FA00BF00BF0AA1284600F0A1FA3846CA +:10C53000FEBD000030303030303030303030300030 +:10C54000203D2000220000002C2030780000000058 +:10C550000D0A00002DE9FF4F04468C4615460D9F3D +:10C560004FF00108002000900190029003900021FC +:10C57000002600BF04E0002245F82020421C10B233 +:10C58000B842F8DB002068E011BB225C9A420DD073 +:10C59000B8F1010F0AD1BE4208DA04EB000A3246B4 +:10C5A000761C45F822A04FF0000811E0225C9A4268 +:10C5B00002D0225C202A0BD1B8F1000F08D1002252 +:10C5C0002254421CA25C202A01D04FF0010842E014 +:10C5D000002234E0002918DD14F80090DFF888A06C +:10C5E0000AEB420A9AF801A0D1450ED1A1F1010946 +:10C5F0001DF80990DFF870A01AF812A0D14504D1F7 +:10C60000A1F1010909F0FF011BE014F80090DFF827 +:10C6100058A01AF812A0D1450DD1DFF84C9019F8A6 +:10C6200012B0894601F1010A0AF0FF010DF809B0C4 +:10C6300001F00F0105E002F1010909F0FF02002AF3 +:10C64000C8D000BF225C5C2A04D1421CA25C0AB1A3 +:10C65000421C90B200BF421C90B2604594DB304651 +:10C6600004B0BDE8F08F00007C02002030B5024627 +:10C670000B460020002108E0545C5D5CAC4200D019 +:10C6800008E0441CA0B24C1CA1B2545C14B15C5C28 +:10C69000002CF1D100BF30BD0246002003E00B5C4E +:10C6A0001354431C98B20B5C002BF8D11354704701 +:10C6B0002DE9F84F0446B4F834A04FF000080025E7 +:10C6C000A08938B92046FFF711FC0121204600F06F +:10C6D00055F970E0A08900286DDD0021A28920694C +:10C6E0008154A66D002737E006EB07112046FEF7C0 +:10C6F00067FE78BB06EB0710FFF776F983465946CD +:10C700002069FFF7B3FFA189884223D1F5B1012D3C +:10C7100003D12AA1204600F0ABF906EB0811204610 +:10C72000FFF710FC06EB0710FFF75EF9834606EBF8 +:10C730000810FFF759F959460090FFF797FF814617 +:10C74000CA4501DD484600E0504682461FFA87F898 +:10C75000681C85B2781C07B25C20005BB842C3DC61 +:10C760000DB9BDE8F88F012D02D12046FEF754FE29 +:10C770004DB106EB0810FFF737F907463946206937 +:10C78000FFF78AFFA081012D0ADD06EB0811204684 +:10C79000FFF7D8FB0121204600F0F0F8A4F80CA028 +:10C7A0000021A28920698154A189E1812046216963 +:10C7B00000F05EF900BF00BFD3E700000D0A0000E3 +:10C7C00008B505462C460CE0606E50B10121684664 +:10C7D000626E9047012804D19DF800102046FFF7B3 +:10C7E00071F9F1E730B502460B241346002A00DA4E +:10C7F00053420020C8720DE00A2093FBF0F500FBC5 +:10C8000015303030C5B2601EC0B204460D540A2047 +:10C8100093FBF0F3002BEFD1002A04DA2D25601EE4 +:10C82000C0B204460D5422B93025601EC0B2044681 +:10C830000D54C4F10B0040B230BD30B502460B467A +:10C840000824002018720EE002F00F01092902DD11 +:10C8500001F1570001E001F13000C5B2601EC0B225 +:10C8600004461D541209002AEED1C4F1080040B25A +:10C8700030BD10B5044601212046FFF7B7F910BDC1 +:10C8800010B5FFF7D9F8044614B12046FFF704FCB1 +:10C8900010BD10B5FFF7D0F8044614B12046FFF7DD +:10C8A00027FC10BD13B50446012101A8A26E9047D4 +:10C8B0001CBD00002DE9F04104460F4600253E4610 +:10C8C000A06E10B90020BDE8F08102E0761C681C63 +:10C8D00085B2307828B130780D2802D030780A2817 +:10C8E000F4D1242D08DD24213846A26E904703217F +:10C8F00006A0A26E904703E029463846A26E9047F4 +:10C90000242D01DD2420DEE72720DCE72E2E2E005B +:10C910002DE9F04104460E46002331462046A26D23 +:10C92000FFF7C9FC0546EDB11248C16A204600F088 +:10C930009FF82846FFF758F807463946204600F08A +:10C9400097F80DA1204600F093F82846FFF733F83A +:10C9500007463946204600F08BF807A1204600F034 +:10C9600087F804E003488169204600F081F8BDE8BB +:10C97000F0810000280200200D0A000070B5044676 +:10C980000D4694F8600000F00100D8B11DB110A16F +:10C99000204600F06DF820684168204600F068F8F5 +:10C9A0000CA1204600F064F8A06808B1A06800E07F +:10C9B00009A00146204600F05BF808A1204600F0DF +:10C9C00057F804E00648016B204600F051F870BDAE +:10C9D0000D0A00003A0000002F0000002420000093 +:10C9E00028020020FEB505460C4618A2D2E9001028 +:10C9F0009268CDE90102009117A1284600F038F8AD +:10CA000069462046FFF7EEFEC0F10B006946461866 +:10CA10003146284600F02CF812A1284600F028F8EC +:10CA2000002004E030210DF80010411C08B20B2852 +:10CA3000F8DB69462046FFF700FF6946284600F00C +:10CA400017F80AA1284600F013F8FEBD3030303048 +:10CA5000303030303030300052657475726E3A20AC +:10CA6000000000002C203078000000000D0A0000BB +:10CA70002DE9F04104460D4600262F46A06E10B960 +:10CA80000020BDE8F08101E0701C86B217F8011BA0 +:10CA90000029F9D131462846A26E904780B2F0E7CE +:10CAA0000FB42DE9F04105460E9F022D01DA012158 +:10CAB00000E0002108464FF48771F3F7DBFF3426CE +:10CAC00031460020FDF764FE044600BF201D07A983 +:10CAD0001C2203E011F8013B00F8013B131EA2F1F8 +:10CAE0000106B2B2F6D100BF278084F830500A495F +:10CAF000E1625DB1012D04D1084860620849A1627C +:10CB000004E040F21F110020F3F7B4FF2046BDE817 +:10CB1000F0015DF814FB0000DD9100081F9E000885 +:10CB2000879E00087CB504460CB1012100E000217D +:10CB300008464421F3F79EFF206970B12169D1E9CD +:10CB40000401CDE900012569D5E902633246D5E942 +:10CB50000001B047204600F01CF87CBD7CB50446BF +:10CB60000CB1012100E0002108465321F3F782FFB8 +:10CB7000206968B12169D1E90401CDE90001256985 +:10CB8000EE68334695E80700B047204600F001F80C +:10CB90007CBD70B5044600250CB1012100E00021E8 +:10CBA00008460D21F3F766FF2588002D06DD00E01D +:10CBB00000BF281EA5F101018DB2F9D170BD2DE98C +:10CBC000F34182B00446FF270CB1012100E00021AF +:10CBD0000846A921F3F74EFF94F8310001287ED1D1 +:10CBE00000269AE025460DB1012100E0002108460B +:10CBF0008C21F3F73FFFE86860B1E968D1E90401EF +:10CC0000CDE90001D5F80CC0DCF80C8043469CE867 +:10CC10000700C04700BF2046FFF7BBFF9DF80C0090 +:10CC200000F08000C8B125460DB1012100E00021CF +:10CC300008466221F3F71EFF686860B16968D1E9B0 +:10CC40000401CDE90001D5F804C0DCE902834246C5 +:10CC5000DCE90001C04700BF19E025460DB1012104 +:10CC600000E0002108467021F3F704FF686860B116 +:10CC70006968D1E90401CDE90001D5F804C0DCF808 +:10CC80000C8043469CE80700C04700BF00BF204619 +:10CC9000FFF77FFF25460DB1012100E00021084686 +:10CCA0007E21F3F7E7FEE86860B1E968D1E90401A5 +:10CCB000CDE90001D5F80CC0DCE902834246DCE98D +:10CCC0000001C04700BF2046FFF763FF9DF80C003E +:10CCD0004006000E03907806070EA06800E023E0EF +:10CCE0000068C0B125460DB1012100E000210846D1 +:10CCF0009A21F3F7BFFEA968D1E90401CDE900014B +:10CD0000D5F808C0DCF814809CE80F00C047012863 +:10CD100001D1781CC7B2701CC6B2082EFFF662AFF4 +:10CD2000384604B0BDE8F081002001904FF4FA606D +:10CD30000090012301AA03A9206AF6F7EFFD08B1CC +:10CD4000FF20EEE79DF80400EBE700000FB4F8B514 +:10CD500007A800904FF400611348009B069AFBF768 +:10CD600075FF0546002000900326104890F89C02AD +:10CD7000032812D10D48D0F8BC72F4F7DFFA04464C +:10CD800005E0F4F7DBFA001BB04200D903E0D7F866 +:10CD900014020028F5D100BF00BFA9B20248F3F782 +:10CDA0004DFEF8BC5DF814FBAC010120D0F400206E +:10CDB00070B505460C46214601A0FFF7C7FF70BDC0 +:10CDC0006C656E203D2025640D0A000010B5012021 +:10CDD00000F0E4FB0B4908600B480C4988660C48DE +:10CDE00048660C48C8660C4808674FF400720B4947 +:10CDF0000648FEF799FF012209490A48F7F702FAA7 +:10CE000010BD000080020020B1CE0008F810012003 +:10CE100041CE000829CE000895CE00086C110120F3 +:10CE200088020020AC06002010B504464FF0FF3108 +:10CE30000248006800F018FF002010BD80020020AA +:10CE400030B502460B46002119E00F4800880F4C10 +:10CE50002488A04200D114E00D480C4C2488055DC4 +:10CE600008464C1CA1B21554084C2488601CC417F9 +:10CE700000EB5464E411A0EBC414044D2C809942DF +:10CE8000E3DB00BF08B230BD840200208602002030 +:10CE90006C13012010B5044600231A4619460348B6 +:10CEA000006800F075FC002010BD0000800200202A +:10CEB00070B505460C4640F2FF132246294602484B +:10CEC000F7F7F2F920B270BDAC06002001460A69FE +:10CED000D1E901309860D1E9010358605068884277 +:10CEE00001D188685060002008611068401E106001 +:10CEF00010687047034B0360034B0B608023136083 +:10CF0000704700009C020020F002002000F10801A0 +:10CF100041604FF0FF31816000F10801C1600161A3 +:10CF200000210160704700210161704710B5024681 +:10CF30000B685C1C0CB9106907E002F1080000E006 +:10CF40004068446824689C42FAD944684C604C6844 +:10CF5000A160886041600A611468641C146010BD9F +:10CF600042684A6093688B60936859609160086179 +:10CF700003685B1C0360704700BF502080F311887A +:10CF8000BFF34F8FBFF36F8F00BF0E480068401C88 +:10CF90000C49086008460068012812D10A48006858 +:10CFA000C0B208B9012000E0002050B900BF5020F5 +:10CFB00080F31188BFF34F8FBFF36F8F00BF00BFA7 +:10CFC000FEE770477000002004ED00E00D480068A7 +:10CFD00050B900BF502080F31188BFF34F8FBFF3CB +:10CFE0006F8F00BF00BFFEE706480068401E05497E +:10CFF00008600846006820B9002080F3118800BF4F +:10D0000000BF70477000002070B506463546002E00 +:10D0100044D0083D2C46224960680968084008B1A0 +:10D02000012000E0002050B900BF502080F311889B +:10D03000BFF34F8FBFF36F8F00BF00BFFEE72068C5 +:10D0400008B9012000E0002050B900BF502080F353 +:10D050001188BFF34F8FBFF36F8F00BF00BFFEE794 +:10D060000F49606809680840C0B12068B0B90C4930 +:10D07000606809688843606000F08EF9094960685B +:10D0800009680844074908602046FDF7D7FE0648AE +:10D090000068401C0449086001F068F970BD000098 +:10D0A0006C0000205C0000206800002000204FF091 +:10D0B000E02108618861064800684FF47A71B0FB8E +:10D0C000F1F0401E4FF0E0214861072008617047F1 +:10D0D0001000002070B5F3F7BFF80446102C16D3EB +:10D0E00004F1E02090F8F05315480078854201DB08 +:10D0F000012000E0002050B900BF502080F31188CB +:10D10000BFF34F8FBFF36F8F00BF00BFFEE70D4827 +:10D11000006800F4E0600C490968884201D80120E9 +:10D1200000E0002050B900BF502080F31188BFF309 +:10D130004F8FBFF36F8F00BF00BFFEE770BD0000D1 +:10D14000740000200CED00E07800002070B504466B +:10D150000025D4B11248006808B9012000E0002081 +:10D1600050B900BF502080F31188BFF34F8FBFF339 +:10D170006F8F00BF00BFFEE700F00EF900212046D0 +:10D18000FDF70AFC01F0F2F805463DB94FF080507A +:10D1900004490860BFF34F8FBFF36F8F70BD00006D +:10D1A0004C00002004ED00E00349096801600349D8 +:10D1B00009684160704700003C0000202800002002 +:10D1C00001200149086070473800002070B504460E +:10D1D0000D4654B900BF502080F31188BFF34F8F24 +:10D1E000BFF36F8F00BF00BFFEE70548016818312D +:10D1F0002046FFF79BFE01212846FDF7CDFB70BDC1 +:10D20000140000202DE9F04706460F4634464FF043 +:10D210000109002E60D0A06C50B900BF502080F3EF +:10D220001188BFF34F8FBFF36F8F00BF00BFFEE7C2 +:10D23000606CB84201D23D4600E0656CE06AA842ED +:10D240004AD0A06C012847D124480068844201D00C +:10D25000012000E0002050B900BF502080F3118869 +:10D26000BFF34F8FBFF36F8F00BF00BFFEE7D4F84F +:10D270002C80E562A06900F0004010B9C5F10700FC +:10D28000A06108EB8801164A02EB810160698842BF +:10D2900001D1012000E00020F0B1201DFFF716FEB3 +:10D2A00040B994F82C10012088400E490968814348 +:10D2B0000C48016094F82C10012088400949096845 +:10D2C000084308490860E16A01EB8101044A02EB66 +:10D2D0008100211DFFF744FEBDE8F0871400002007 +:10D2E000380700202C00002010B586B000200590E3 +:10D2F000049003AA04A905A8FFF7FCFD0022DDE9BC +:10D3000004101346CDE9002102901CA11D48039A88 +:10D3100000F0FEFD1C4908600846006808B10124C1 +:10D3200000E00024012C15D100BF502080F31188AB +:10D33000BFF34F8FBFF36F8F00BF4FF0FF30134924 +:10D34000086001201249086000201249086000F0BE +:10D3500071F810E0601C08B1012000E0002050B915 +:10D3600000BF502080F31188BFF34F8FBFF36F8F42 +:10D3700000BF00BFFEE706B010BD000049444C45A9 +:10D3800000000000B5AC0008480000204400002068 +:10D39000300000202800002002480068401C01499D +:10D3A000086070474C0000201D48006818B101203B +:10D3B0001C49086032E000201A4908601A480068D9 +:10D3C000B0FA80F0C0F11F0101EB8100174A52F85A +:10D3D000200008B1012000E0002050B900BF50201B +:10D3E00080F31188BFF34F8FBFF36F8F00BF00BF73 +:10D3F000FEE701EB81020D4B03EB820042685268AD +:10D40000426000F108024368934202D142685268C8 +:10D4100042604268D268064B1A6000BF7047000045 +:10D420004C000020380000202C000020380700208D +:10D43000140000201CB5524800685249884201D0AF +:10D44000012000E0002050B900BF502080F3118877 +:10D45000BFF34F8FBFF36F8F00BF00BFFEE7484899 +:10D4600000684849491E884201D0012000E00020A0 +:10D4700050B900BF502080F31188BFF34F8FBFF326 +:10D480006F8F00BF00BFFEE73F490846007801905C +:10D49000FF200A4610700846007800909DF80000B2 +:10D4A00000F0F0009DF80020904201D1012000E042 +:10D4B000002050B900BF502080F31188BFF34F8F78 +:10D4C000BFF36F8F00BF00BFFEE79DF8000000F0C4 +:10D4D00050002E4A107007202D4A106009E02C4899 +:10D4E0000068401E2A4A10609DF800004006000EA9 +:10D4F00000909DF8000000F080008028EFD02448C4 +:10D500000068C0F10700042801D1012000E00020DC +:10D5100050B900BF502080F31188BFF34F8FBFF385 +:10D520006F8F00BF00BFFEE7194800680002184A6D +:10D5300010601046008800F4E0601060124A019804 +:10D5400010700F482030006840F470000C49203102 +:10D5500008600846006840F070400860FFF7A6FDCC +:10D5600000200C490860F2F73FFE0B48006840F0CD +:10D57000404009490860F2F723FE00201CBD00006E +:10D5800000ED00E071C20F4100E400E074000020F3 +:10D59000780000207000002034EF00E02DE9F04119 +:10D5A00004460126002722460021012000F007F84A +:10D5B00005462846FDF792FB2846BDE8F0812DE997 +:10D5C000F84305460E4617460DB1012000E0002045 +:10D5D00050B900BF502080F31188BFF34F8FBFF3C5 +:10D5E0006F8F00BF00BFFEE705FB06F808F148009B +:10D5F000FDF7EEFC044664B1A14609F1480900209C +:10D6000084F846003B464A46314628460094FDF7DA +:10D6100074FB2046BDE8F8832DE9F84380460E46AA +:10D6200017461D46DDF82090B8F1000F01D001200B +:10D6300000E0002050B900BF502080F31188BFF3F4 +:10D640004F8FBFF36F8F00BF00BFFEE70DB101200A +:10D6500000E0002050B900BF502080F31188BFF3D4 +:10D660004F8FBFF36F8F00BF00BFFEE707B10EB152 +:10D67000012000E0002050B900BF502080F3118845 +:10D68000BFF34F8FBFF36F8F00BF00BFFEE707B937 +:10D690000EB9012000E0002050B900BF502080F3F7 +:10D6A0001188BFF34F8FBFF36F8F00BF00BFFEE73E +:10D6B000482000900098482801D1012000E0002077 +:10D6C00050B900BF502080F31188BFF34F8FBFF3D4 +:10D6D0006F8F00BF00BFFEE700BF2C464CB101209A +:10D6E00084F846004B463A46314640460094FDF7E2 +:10D6F00004FB2046BDE8F88370B505460E462C466F +:10D7000054B900BF502080F31188BFF34F8FBFF38F +:10D710006F8F00BF00BFFEE7FFF72EFCD4E90F12AA +:10D72000206801FB0200A0600020A0632068606008 +:10D73000E06B401E226C216800FB0211E160FF20BB +:10D7400084F8440084F845009EB9206908B9012096 +:10D7500000E00020A8B904F1100000F0BBFD80B18A +:10D760004FF0805009490860BFF34F8FBFF36F8FB0 +:10D7700007E004F11000FFF7C9FB04F12400FFF7F4 +:10D78000C5FBFFF723FC012070BD000004ED00E0A5 +:10D790002DE9FF4383B0064688461D464FF0000939 +:10D7A000344654B900BF502080F31188BFF34F8F27 +:10D7B000BFF36F8F00BF00BFFEE7B8F1000F01D1CC +:10D7C000206C08B9012000E0002050B900BF5020B3 +:10D7D00080F31188BFF34F8FBFF36F8F00BF00BF7F +:10D7E000FEE7022D02D1E06B012801D1012000E00B +:10D7F000002050B900BF502080F31188BFF34F8F35 +:10D80000BFF36F8F00BF00BFFEE700F0DFFB08B97A +:10D81000059808B9012000E0002050B900BF502051 +:10D8200080F31188BFF34F8FBFF36F8F00BF00BF2E +:10D83000FEE700BFFFF7A0FBA06BE16B884201D3BE +:10D84000022D28D12A4641462046FDF784F9074695 +:10D85000606A08B9012000E0002068B904F12400E2 +:10D8600000F038FD88B14FF0805032490860BFF3B6 +:10D870004F8FBFF36F8F08E03FB14FF080502D49BD +:10D880000860BFF34F8FBFF36F8FFFF79FFB01203F +:10D8900007B0BDE8F083059818B9FFF797FB0020A3 +:10D8A000F6E7B9F1000F04D101A8FFF77DFC4FF0B6 +:10D8B0000109FFF78BFBFFF76FFDFFF75DFB94F9A5 +:10D8C0004400401C10B9002084F8440094F945003D +:10D8D000401C10B9002084F84500FFF777FB05A92C +:10D8E00001A800F09DFAF0B92046FDF7E8FAA0B1D2 +:10D8F00004F110000599FFF769FC2046FDF728FBAD +:10D9000000F034FD002895D14FF08050094908609F +:10D91000BFF34F8FBFF36F8F8CE72046FDF718FBE7 +:10D9200000F024FD86E72046FDF712FB00F01EFD07 +:10D930000020ADE704ED00E02DE9F84F07468A46E8 +:10D9400090461E463C4654B900BF502080F31188D3 +:10D95000BFF34F8FBFF36F8F00BF00BFFEE7BAF179 +:10D96000000F01D1206C08B9012000E0002050B95F +:10D9700000BF502080F31188BFF34F8FBFF36F8F2C +:10D9800000BF00BFFEE7022E02D1E06B012801D1EB +:10D99000012000E0002050B900BF502080F3118822 +:10D9A000BFF34F8FBFF36F8F00BF00BFFEE7FFF7DE +:10D9B00091FB00BF5021EFF3118081F31188BFF379 +:10D9C0004F8FBFF36F8F00BF0546A06BE16B88429E +:10D9D00001D3022E25D194F945B0A06B00903246B8 +:10D9E00051462046FDF7B7F80BF1010088B9606A8F +:10D9F00008B9012000E0002050B904F1240000F033 +:10DA000069FC28B1B8F1000F02D00120C8F800006D +:10DA100004E00BF1010040B284F845004FF0010929 +:10DA200001E04FF0000900BF85F3118800BF4846B0 +:10DA3000BDE8F88F2DE9F74183B005460E464FF05B +:10DA400000082C4654B900BF502080F31188BFF362 +:10DA50004F8FBFF36F8F00BF00BFFEE70EB9206C82 +:10DA600008B9012000E0002050B900BF502080F329 +:10DA70001188BFF34F8FBFF36F8F00BF00BFFEE76A +:10DA800000F0A4FA08B9059808B9012000E00020C8 +:10DA900050B900BF502080F31188BFF34F8FBFF300 +:10DAA0006F8F00BF00BFFEE700BFFFF765FAA76BEF +:10DAB000F7B131462046FDF739F8781EA06320699A +:10DAC00008B9012000E0002060B904F1100000F066 +:10DAD00001FC38B14FF080502F490860BFF34F8FE1 +:10DAE000BFF36F8FFFF772FA012006B0BDE8F08137 +:10DAF000059818B9FFF76AFA0020F6E7B8F1000FA9 +:10DB000004D101A8FFF750FB4FF00108FFF75EFAC0 +:10DB1000FFF742FCFFF730FA94F94400401C10B9BB +:10DB2000002084F8440094F94500401C10B90020FE +:10DB300084F84500FFF74AFA05A901A800F070F93A +:10DB4000F0B92046FDF7AEF9A0B104F12400059923 +:10DB5000FFF73CFB2046FDF7FBF900F007FC00282F +:10DB6000A3D14FF080500C490860BFF34F8FBFF333 +:10DB70006F8F9AE72046FDF7EBF900F0F7FB94E78B +:10DB80002046FDF7E5F900F0F1FB2046FDF78AF9A4 +:10DB900000288AD00020A8E704ED00E02DE9F05F1E +:10DBA000064689461746344654B900BF502080F3D4 +:10DBB0001188BFF34F8FBFF36F8F00BF00BFFEE729 +:10DBC000B9F1000F01D1206C08B9012000E000205C +:10DBD00050B900BF502080F31188BFF34F8FBFF3BF +:10DBE0006F8F00BF00BFFEE7FFF774FA00BF502140 +:10DBF000EFF3118081F31188BFF34F8FBFF36F8F65 +:10DC000000BF0546D4F838A0BAF1000F22D094F92D +:10DC100044B049462046FCF789FFAAF10100A06301 +:10DC20000BF1010070B9206908B9012000E0002063 +:10DC300068B904F1100000F04DFB40B13FB1012084 +:10DC4000386004E00BF1010040B284F844004FF06A +:10DC5000010801E04FF0000800BF85F3118800BF04 +:10DC60004046BDE8F09F00002DE9F34182B0054633 +:10DC70004FF000082C46002654B900BF502080F316 +:10DC80001188BFF34F8FBFF36F8F00BF00BFFEE758 +:10DC9000206C08B9012000E0002050B900BF5020DE +:10DCA00080F31188BFF34F8FBFF36F8F00BF00BFAA +:10DCB000FEE700F08BF908B9039808B9012000E0ED +:10DCC000002050B900BF502080F31188BFF34F8F60 +:10DCD000BFF36F8F00BF00BFFEE700BFFFF74CF937 +:10DCE000A76BFFB1781EA063206810B9FDF716FA84 +:10DCF000A060206908B9012000E0002060B904F1AB +:10DD0000100000F0E7FA38B14FF080504349086046 +:10DD1000BFF34F8FBFF36F8FFFF758F9012004B0A7 +:10DD2000BDE8F081039898B90EB9012000E0002009 +:10DD300050B900BF502080F31188BFF34F8FBFF35D +:10DD40006F8F00BF00BFFEE7FFF740F90020E6E756 +:10DD5000B8F1000F04D16846FFF726FA4FF001082A +:10DD6000FFF734F9FFF718FBFFF706F994F94400C1 +:10DD7000401C10B9002084F8440094F94500401C70 +:10DD800010B9002084F84500FFF720F903A9684680 +:10DD900000F046F840BB2046FDF784F8F0B120685B +:10DDA00038B9FFF7E9F8A06800F038FA0646FFF73F +:10DDB0000DF904F124000399FFF708FA2046FDF756 +:10DDC000C7F800F0D3FA002888D14FF080501349EB +:10DDD0000860BFF34F8FBFF36F8F7FE72046FDF7DB +:10DDE000B7F800F0C3FA79E72046FDF7B1F800F084 +:10DDF000BDFA2046FDF756F80028EED05EB1FFF7D9 +:10DE0000BBF82046FCF70EFF07463946A068FFF72F +:10DE1000F9F9FFF7DBF8002081E7000004ED00E0EE +:10DE200070B505460C4655B900BF502080F31188E7 +:10DE3000BFF34F8FBFF36F8F00BF00BFFEE754B932 +:10DE400000BF502080F31188BFF34F8FBFF36F8F57 +:10DE500000BF00BFFEE7FFF78FF81248026868684E +:10DE6000131A2068401C08B9002617E00E492868DC +:10DE70000968884204D06868904201D801260DE004 +:10DE80002068984207D92068C01A20602846FFF70A +:10DE90008BF9002602E0002020600126FFF796F8AB +:10DEA000304670BD280000203C0000202DE9FF4FC7 +:10DEB00085B0804689461746DDE912ABB800FDF70C +:10DEC00087F8064656B15420FDF782F804460CB197 +:10DED000266304E03046FFF797F800E000248CB199 +:10DEE000002084F85100CDE900ABCDE902403A466C +:10DEF00049464046089BFCF713FF2046FCF798FD77 +:10DF0000012501E04FF0FF35284609B0BDE8F08F4C +:10DF10002DE9F04F85B00746884691469A46DDE9DF +:10DF20000EB6109C0EB1012000E0002050B900BFD9 +:10DF3000502080F31188BFF34F8FBFF36F8F00BF66 +:10DF400000BFFEE70CB1012000E0002050B900BF87 +:10DF5000502080F31188BFF34F8FBFF36F8F00BF46 +:10DF600000BFFEE7542003900398542801D10120FC +:10DF700000E0002050B900BF502080F31188BFF3AB +:10DF80004F8FBFF36F8F00BF00BFFEE700BFB4B17C +:10DF9000AEB125462C462E63022085F851000020A4 +:10DFA00004A953464A46CDE900B1CDE902504146A5 +:10DFB0003846FCF7B5FE2846FCF73AFD01E00020A4 +:10DFC0000490049805B0BDE8F08F00000549096889 +:10DFD00009B9012005E00449096809B9022000E0F7 +:10DFE00000207047300000204C00002001490868E4 +:10DFF000704700002800002070B5FFF76BF800257F +:10E0000001480468204670BD280000202DE9F04139 +:10E010004FF000084448006800287CD1434800685D +:10E02000451C4248056015BB41480068006808B9B6 +:10E03000012000E0002050B900BF502080F311887B +:10E04000BFF34F8FBFF36F8F00BF00BFFEE73848AD +:10E05000076838480068364908603648076036481F +:10E060000068401C34490860FCF738FF00BF3348A3 +:10E07000006885423CD300BF2D480068006808B99D +:10E08000012000E0002020B14FF0FF302B49086054 +:10E090002DE027480068C068C4686668B54202D2AF +:10E0A0002648066023E0201DFEF710FFA06A18B185 +:10E0B00004F11800FEF70AFF94F82C1001208840A4 +:10E0C0001F49096808431E490860E16A01EB8101A4 +:10E0D0001C4A02EB8100211DFEF742FF1A49E06A4B +:10E0E0000968C96A8842C7D34FF00108C4E700BF76 +:10E0F00015480068C06A00EB8000124951F8200002 +:10E10000012801D94FF001081048006808B14FF00C +:10E11000010805E0FFE70E480068401C0C49086054 +:10E120004046BDE8F08100004C000020280000209F +:10E13000180000201C0000203C00002044000020AB +:10E140002C00002038070020140000203800002098 +:10E150003400002070B505462C460026002D55D011 +:10E160002B480068844201D1012000E0002050B912 +:10E1700000BF502080F31188BFF34F8FBFF36F8F24 +:10E1800000BF00BFFEE7A06C50B900BF502080F375 +:10E190001188BFF34F8FBFF36F8F00BF00BFFEE743 +:10E1A000A06C401EA064616CE06A88422ED0A06C16 +:10E1B00060BB201DFEF78AFE78B9E06A00EB8000A4 +:10E1C000144951F8200040B994F82C1001208840DF +:10E1D00011490968814310480160606CE062E06A9F +:10E1E000C0F10700A06194F82C10012088400A4972 +:10E1F0000968084308490860E16A01EB8101054AA2 +:10E2000002EB8100211DFEF7ABFE0126304670BDFA +:10E2100014000020380700202C00002070B50546AF +:10E220002C460026002D4DD02749E06A0968C96AAE +:10E23000884240D2A06900F0004028B92248006816 +:10E24000C06AC0F10700A061E16A01EB81011F4AC9 +:10E2500002EB81016069884201D1012000E00020C9 +:10E2600018B3201DFEF732FE40B994F82C1001209F +:10E2700088401749096881431548016012480068C1 +:10E28000C06AE06294F82C100120884010490968A7 +:10E2900008430F490860E16A01EB81010B4A02EB78 +:10E2A0008100211DFEF75CFE03E007480068C06A9C +:10E2B000E062012606E00449606C0968C96A884288 +:10E2C00000D20126304670BD14000020380700201F +:10E2D0002C00002070B50646F068C46854B900BF31 +:10E2E000502080F31188BFF34F8FBFF36F8F00BFB3 +:10E2F00000BFFEE704F11800FEF7E8FD15480068CE +:10E30000A8B9201DFEF7E2FD94F82C1001208840EA +:10E3100011490968084310490860E16A01EB81016D +:10E320000E4A02EB8100211DFEF71AFE04E004F103 +:10E3300018010B48FEF714FE0A49E06A0968C96A29 +:10E34000884204D9012501200749086000E0002522 +:10E35000284670BD4C0000202C000020380700200B +:10E36000EC070020140000203800002070B50024C5 +:10E3700000263648006850B900BF502080F311884D +:10E38000BFF34F8FBFF36F8F00BF00BFFEE7FEF7F5 +:10E39000F3FD2E480068401E2C49086008460068BE +:10E3A00000284FD12A48006800284BD024E0294893 +:10E3B000C068C46804F11800FEF788FD201DFEF750 +:10E3C00085FD94F82C1001208840234909680843F2 +:10E3D00021490860E16A01EB8101204A02EB8100DA +:10E3E000211DFEF7BDFD1E49E06A0968C96A884221 +:10E3F00002D301201B4908601648006808B90120B3 +:10E4000000E000200028D2D00CB1FCF767FD1648D0 +:10E41000056865B100BFFFF7F9FD10B10120114992 +:10E4200008606D1E002DF6D100200F4908600D48D0 +:10E43000006838B1012630070C490860BFF34F8FE0 +:10E44000BFF36F8FFEF7C2FD304670BD4C00002059 +:10E4500024000020EC0700202C00002038070020BA +:10E4600014000020380000203400002004ED00E0FB +:10E47000404E0108375B000800000000000000006B +:10E4800080000000000000000000000000061016E0 +:10E490000006101600000000000000000102030446 +:10E4A0000607080900000000010203040000000044 +:10E4B000000000000200F000F0000000000000007A +:10E4C0000000000000000000000000000000030049 :10E4D000000000000000000000000000000000003C -:10E4E000000000000000000000000000000000002C -:10E4F000000000000000000000000000000000001C -:10E50000000000000000000000000000000000000B -:10E5100000000000000000000000000000000000FB -:10E5200000000000000000000000000000000000EB -:10E5300000000000000000000000000000000000DB -:10E5400000000000000000000000000000000000CB -:10E5500000000000000000000000000000000000BB -:10E5600000000000000000000000000000000000AB -:10E57000000000000000000000000000000000009B -:10E58000000000000000000000000000000000008B -:10E59000000000000000000000000000000000007B -:10E5A000000000000000000000000000000000006B -:10E5B000000000000000000000000000000000005B -:10E5C000000000000000000000000000000000004B -:10E5D000000000000000000000000000000000003B -:10E5E000000000000000000000000000000000002B -:10E5F000000000000000000000000000000000001B -:10E60000000000000000000000000000000000000A -:10E61000000000000000000000000000C003C00374 -:10E62000C003C003C003C0038003800180018001D8 -:10E630008001800180018001800100000000000055 -:10E640008001C003C0038001000000000000000042 -:10E6500000000000C018E01CE01C700E300618031B -:10E660008C01840000000000000000000000000099 +:10E4E000000000005F6C697374006C6973742061D4 +:10E4F0006C6C20636F6D6D616E6400000010000035 +:10E500000008000008000000080000000080000073 +:10E5100000400000F957000855590008D15800087C +:10E5200061590008655800080A0000000200000058 +:10E5300000000000000000004000FE079200FE07FF +:10E540009204FE0702008A04BA028A01AA0419078B +:10E55000C2B9200000000000000000000000000020 +:10E56000000000000000000020002000200020002B +:10E570002401240222022204210420002000380069 +:10E58000D0A12000000000000000000000000000FA +:10E5900000000000000000002000A70722012A015F +:10E5A0002A012F01AA072601220116011301C8071B +:10E5B000B0E02000000000000000000000000000AB +:10E5C00000000000000000000801270144010401D0 +:10E5D0003F0144010E011607E50104010401040195 +:10E5E000BFC6200000000000000000000000000086 +:10E5F000000000000000000084008400F4078F0089 +:10E600008400F4032C0227024401840044013606EE +:10E61000BCBC200000000000000000000000000062 +:10E6200000000000000000000000000000000000EA +:10E6300000000000000000000000000000000000DA +:10E6400000000000000000000000000000000000CA +:10E6500000000000000000000000000000000000BA +:10E6600000000000000000000000000000000000AA :10E67000000000000000000000000000000000009A :10E68000000000000000000000000000000000008A -:10E69000000000000000000000000000201020101A -:10E6A000201020102010FE7FFE7FFE7F1008100833 -:10E6B0001008100810081008FE7FFE7FFE7F180C5F -:10E6C000080408040804080400000000000000001A -:10E6D000000000000000000080008000C003B00CBB -:10E6E00090189818981C981CB800B000F000E00032 -:10E6F000C0038007800F800C801C80189C189C1819 -:10E700008C188C0C9806E0038000800080000000CC -:10E710000000000000000000000000001C08360897 -:10E720002204630463026302630263016301220142 -:10E73000B61C9C3640224063406320632063106314 -:10E74000106310220836081C0000000000000000C2 -:10E75000000000000000000000000000F000980031 -:10E760008C018C018C018C018C00CC005C00380089 -:10E770001C3E3C08320873086304E304C3048303AB -:10E78000834306678C3E781C0000000000000000F8 -:10E79000000000001C003C003C0030003000100075 -:10E7A0000C00060000000000000000000000000057 -:10E7B0000000000000000000000000000000000059 +:10E69000000000000000000000000000000000007A +:10E6A000000000000000000000000000000000006A +:10E6B000000000000000000000000000000000005A +:10E6C000000000000000000000000000000000004A +:10E6D000000000000000000000000000000000003A +:10E6E000000000000000000000000000000000002A +:10E6F000000000000000000000000000000000001A +:10E700000000000000000000000000000000000009 +:10E71000000000000000000080000001FC7F4404B5 +:10E720004404FC3F44244424FC3F14021422F41A01 +:10E7300012061222D122303CC2B920000000000093 +:10E7400000000000000000000000000000000000C9 +:10E7500000000000000000008000800080008000B9 +:10E76000800088088810882084208440824081406E +:10E7700080008000A0004000D0A120000000000028 +:10E780000000000000000000000000000000000089 +:10E790000000000000000000000100011F7D441186 +:10E7A0004411441144115F7D4411241104119C1043 +:10E7B0008710427C20001000B0E020000000000024 :10E7C0000000000000000000000000000000000049 -:10E7D000000000000040002000100018000C0004A1 -:10E7E0000006000200030003800180018001800117 -:10E7F000800180018001800180010003000300028C -:10E8000000060004000C001800100020004000006A -:10E810000000000002000400080018003000200082 -:10E8200060004000C000C0008001800180018001C4 -:10E8300080018001800180018001C000C000C00013 -:10E8400060002000300018000800040002000000F2 +:10E7D00000000000000000001008B8080F09080938 +:10E7E0000808BF0808091C092C080A78CA0F09087C +:10E7F0000808080808080808BFC620000000000034 +:10E800000000000000000000000000000000000008 +:10E810000000000000000000080408040804C87F8D +:10E820003F0408040804A83F18210C110B12080A21 +:10E830000804080A8A116460BCBC200000000000C3 +:10E8400000000000000000000000000000000000C8 :10E8500000000000000000000000000000000000B8 -:10E860000003800380030C631C713839600D800342 -:10E870008003600D38391C718C6180038003800334 +:10E8600000000000000000000000000000000000A8 +:10E870000000000000000000000000000000000098 :10E880000000000000000000000000000000000088 :10E890000000000000000000000000000000000078 -:10E8A0000000000100010001000100010001000161 -:10E8B000FC7F0001000100010001000100010001D6 +:10E8A0000000000000000000000000000000000068 +:10E8B0000000000000000000000000000000000058 :10E8C0000000000000000000000000000000000048 :10E8D0000000000000000000000000000000000038 :10E8E0000000000000000000000000000000000028 :10E8F0000000000000000000000000000000000018 -:10E900001C003C003C003000300010000C000600F1 +:10E900000000000000000000000000000000000007 :10E9100000000000000000000000000000000000F7 :10E9200000000000000000000000000000000000E7 -:10E93000FE7F00000000000000000000000000005A +:10E9300000000000000000000000000000000000D7 :10E9400000000000000000000000000000000000C7 :10E9500000000000000000000000000000000000B7 :10E9600000000000000000000000000000000000A7 :10E970000000000000000000000000000000000097 -:10E9800018003C003C0018000000000000000000DF -:10E990000000000000000040006000200030001077 -:10E9A00000180008000C000400060002000300012B -:10E9B00080018000C0004000600020003000100096 -:10E9C000180008000C00040006000200000000000F -:10E9D000000000000000000000000000C003600410 -:10E9E000300C1818181818100C300C300C300C3073 -:10E9F0000C300C300C300C300C300C301810181857 -:10EA00001818300C6004C003000000000000000073 -:10EA10000000000000000000000000000001800174 -:10EA2000F801800180018001800180018001800166 -:10EA300080018001800180018001800180018001CE -:10EA400080018001C003F81F0000000000000000EA -:10EA5000000000000000000000000000E007101CA3 -:10EA60000818043004300C300C3000300018001846 -:10EA7000000C000600038001C00040002020102090 -:10EA800008200430FC1FFC1F0000000000000000F4 -:10EA9000000000000000000000000000E003180675 -:10EAA0000C0C0C180C180C1800180018000C0006A0 -:10EAB000C003000E00180010003000300C300C3085 -:10EAC0000C100C18180CE0030000000000000000FF -:10EAD000000000000000000000000000000600062A -:10EAE0000007000780068006400620062006100664 -:10EAF000100608060C0604060206FE3F0006000685 -:10EB0000000600060006C03F0000000000000000F4 -:10EB1000000000000000000000000000F03FF03F97 -:10EB2000080008000800080008000800C807280CB2 -:10EB30001818081000300030003000300C300C3055 -:10EB400004180418180CE003000000000000000086 -:10EB500000000000000000000000000080076018B6 -:10EB6000301810181800080008000C00CC076C0CB6 -:10EB70001C181C100C300C300C300C300C301830C1 -:10EB800018103018700CC0070000000000000000D2 -:10EB9000000000000000000000000000F83FF83F07 -:10EBA00008100C080408040400040002000200021B -:10EBB000000100018000800080008000C000C000D3 -:10EBC000C000C000C000C000000000000000000045 -:10EBD000000000000000000000000000E007300C12 -:10EBE00018180C300C300C301C301C107818F00445 -:10EBF000E003180F0C1E0C1C0638063006300630D9 -:10EC000006300C18180CE0030000000000000000A3 -:10EC1000000000000000000000000000E0031804F5 -:10EC20000C080C1806100630063006300630063088 -:10EC30000E380C341836F031003000180018000877 -:10EC40000C0C0C060C03F00100000000000000009A +:10E980000000000000000000000000000000000087 +:10E990000000000000000000000000000400000C67 +:10E9A00000F8EE03081100081100F8FF010811013A +:10E9B000081101F8F701080801C81001489001C8C2 +:10E9C0007300481002481402441302C4F00302000A +:10E9D00000000000C2B9200000000000000000009C +:10E9E0000000000000000000000000000000000027 +:10E9F0000000000000000000000000000000000017 +:10EA00000000000000000000000000000000000006 +:10EA100000000000040000040000040000040000E6 +:10EA2000040040040060240020C40020840110047D +:10EA300003080403080402040402000400000400A4 +:10EA4000000400800700000200000000D0A12000A8 +:10EA500000000000000000000000000000000000B6 +:10EA600000000000000000000000000000000000A6 +:10EA70000000000000000000000000000000000096 +:10EA80000000000000000000000000000400EC0492 +:10EA90000010BC0310440010440010440010450056 +:10EAA000FC450010E503904400104400104400D0E1 +:10EAB00042003042000E410082F807400000300062 +:10EAC00000000000B0E02000000000000000000096 +:10EAD0000000000000000000000000000000000036 +:10EAE0000000000000000000000000000000000026 +:10EAF0000000000000000000000000000000000016 +:10EB0000000000008000C081003C800020880020C0 +:10EB10009000209000FC8100208000608800B09070 +:10EB20000030810728F9002487002280002080001F +:10EB3000208000208000208000000000BFC6200050 +:10EB400000000000000000000000000000000000C5 +:10EB500000000000000000000000000000000000B5 +:10EB600000000000000000000000000000000000A5 +:10EB70000000000000000000000000101000302025 +:10EB800000202000202000FCFF0320200020200087 +:10EB9000202000E0F80138040126840020880020AD +:10EBA00048002070002030002048003C860390017F +:10EBB00002000000BCBC20000000000000000000BB +:10EBC0000000000000000000000000000000000045 +:10EBD0000000000000000000000000000000000035 +:10EBE0000000000000000000000000000000000025 +:10EBF000000000000000000000000000000000FC19 +:10EC0000FF03000000000000000000000000F8FF0B +:10EC100001000000000000000000000000000000F3 +:10EC2000FEFF07000000000000000000C8FD2000FB +:10EC300000000000000000000000000000000000D4 +:10EC400000000000000000000000000000000000C4 :10EC500000000000000000000000000000000000B4 -:10EC6000000000000000000000008001C003C0039D -:10EC70008001000000000000000000000000000013 -:10EC80008001C003C00380010000000000000000FC -:10EC90000000000000000000000000000000000074 -:10ECA000000000000000000000000000C001C001E2 -:10ECB000C001000000000000000000000000000093 -:10ECC0000000C001C001C0018001C000C000000000 -:10ECD0000000000000000000000000000020001004 -:10ECE0000008000400020001800040002000100025 -:10ECF0000800080010002000400080000001000211 -:10ED000000040008001000200000000000000000C7 -:10ED100000000000000000000000000000000000F3 -:10ED200000000000000000000000FE7F0000000066 -:10ED3000000000000000FE7F000000000000000056 +:10EC600000000000000000000000000000000000A4 +:10EC700000000000000000102000FEFF0110200036 +:10EC8000F03F00102000F03F00102000FFFF0310B5 +:10EC90002100FCFF00030103FEFF01000000000053 +:10ECA00000000000BBF92000000000000000000090 +:10ECB0000000000000000000000000000000000054 +:10ECC0000000000000000000000000000000000044 +:10ECD0000000000000000000000000000000000034 +:10ECE00000000000000000000000000000000040E4 +:10ECF0000000F01F00181800040C00FFFF00048241 +:10ED000000048200FCFF00048000040000040002F4 +:10ED1000F8FF01000000000000000000C9AB200067 +:10ED200000000000000000000000000000000000E3 +:10ED300000000000000000000000000000000000D3 :10ED400000000000000000000000000000000000C3 -:10ED500000000000000000000000000004000800A7 -:10ED600010002000400080000001000200040008A4 -:10ED700000100010000800040002000180004000A4 -:10ED80002000100008000400000000000000000047 -:10ED9000000000000000000000000000C007301864 -:10EDA000183008600C601C601C601C60003000188B -:10EDB000000E00030001000100010001000000003E -:10EDC0008001C003C00380010000000000000000BB -:10EDD000000000000000000000000000C007600804 -:10EDE000301018200C2B8C4D844CC64CC644664405 -:10EDF000664466446646662666266417CC0C0C405C -:10EE0000082018303018C007000000000000000083 -:10EE1000000000000000000000000000C001C00170 -:10EE2000C001C0012003200320032003300210068C -:10EE3000100610061004F80F080C080C080C041833 -:10EE40000418041806381F7C0000000000000000B1 -:10EE5000000000000000000000000000FE07181C79 -:10EE60001818183018301830183018301818180CB6 -:10EE7000F807181818301820186018601860186003 -:10EE8000186018301818FE0F000000000000000085 -:10EE9000000000000000000000000000C007603813 -:10EEA000103018600C400C400C00060006000600F4 -:10EEB0000600060006000600060006000C400C4096 -:10EEC000082018103008C0070000000000000000F3 -:10EED000000000000000000000000000FE03180E0B -:10EEE000181818101830183018601860186018605A -:10EEF00018601860186018601860182018301830F2 -:10EF0000181818181806FE03000000000000000082 -:10EF1000000000000000000000000000FE3F18306C -:10EF20001820184018401800180018081808180C65 -:10EF3000F80F180C180818081800180018001840C6 -:10EF4000184018201830FE3F0000000000000000AC -:10EF5000000000000000000000000000FE3F183824 -:10EF60001820184018401800180018081808180C25 -:10EF7000F80F180C180818081808180018001800BE -:10EF80001800180018007E000000000000000000BB -:10EF9000000000000000000000000000C003300C72 -:10EFA000100818180C100C100400060006000600CB -:10EFB00006000600067E0618061804180C180C1821 -:10EFC000081818183004E0030000000000000000DA -:10EFD0000000000000000000000000003FFC0C30BA -:10EFE0000C300C300C300C300C300C300C300C3041 -:10EFF000FC3F0C300C300C300C300C300C300C3032 -:10F000000C300C300C303FFC000000000000000011 -:10F01000000000000000000000000000F81F800158 -:10F0200080018001800180018001800180018001D8 -:10F0300080018001800180018001800180018001C8 -:10F04000800180018001F81F000000000000000026 -:10F05000000000000000000000000000E07F00064B -:10F060000006000600060006000600060006000670 -:10F070000006000600060006000600060006000660 -:10F0800000060006000600060E060E038E01FC00B8 -:10F090000000000000000000000000007E3E180C90 -:10F0A0001804180618021801180198009800D800D2 -:10F0B000B801B8011803180318061806180C180C24 -:10F0C000180C181818187E7C0000000000000000C2 -:10F0D0000000000000000000000000007E0018009A -:10F0E0001800180018001800180018001800180060 -:10F0F0001800180018001800180018001800184010 -:10F10000184018201830FE3F0000000000000000EA -:10F110000000000000000000000000000FF01C389C -:10F120001C381C381C381C343434343434343432F5 -:10F13000343264326432643264314431C431C431B3 -:10F14000C430C43084308FFC000000000000000098 -:10F150000000000000000000000000000FF81C206C -:10F160001C203420342064206420C420C420842146 -:10F1700084210423042304260426042C042C0438AC -:10F180000438043004301F2000000000000000009C -:10F19000000000000000000000000000C003300C70 -:10F1A000181808100C300C30062006600660066047 -:10F1B0000660066006600660066004600C300C3075 -:10F1C00008101818300CC0030000000000000000F8 -:10F1D000000000000000000000000000FE0F1818F2 -:10F1E00018301860186018601860186018601830BF -:10F1F0001818F80718001800180018001800180050 -:10F200001800180018007E00000000000000000038 -:10F21000000000000000000000000000C003300CEF -:10F22000181808100C300C30066006600660066086 -:10F23000066006600660066006600660E4211C3316 -:10F240001C36181E300EC007004C003C0038000071 -:10F25000000000000000000000000000FE07181C75 -:10F260001818183018301830183018301818180CB2 -:10F27000F80718031803180618061806180C180CB7 -:10F28000180C181818187E78000000000000000004 -:10F29000000000000000000000000000F013181E35 -:10F2A0000C1806180610061006000E003C00F800A8 -:10F2B000E003800F001E00180038023002300630D4 -:10F2C00004300C181C0CE4070000000000000000D3 -:10F2D000000000000000000000000000FC3F8C2146 -:10F2E000846182418241800180018001800180012E -:10F2F0008001800180018001800180018001800106 -:10F30000800180018001E007000000000000000093 -:10F310000000000000000000000000003F7C0C1016 -:10F320000C100C100C100C100C100C100C100C10FD -:10F330000C100C100C100C100C100C100C100C10ED -:10F340000C1018083804E003000000000000000062 -:10F350000000000000000000000000003E781830AF -:10F360001810181018103008300830083008300411 -:10F370006004600460046002C002C002C002C001F8 -:10F38000800180018000800000000000000000007B -:10F39000000000000000000000000000CFF38661C4 -:10F3A0008621842104210C238C238C238C138C1321 -:10F3B0008813481258165816580E380E300E300E54 -:10F3C000300C3004100410040000000000000000A5 -:10F3D0000000000000000000000000003E7C18104B -:10F3E00018083008300460046002C002C0018001C7 -:10F3F000800180018003400340062006200E100C8F -:10F40000100C181808383E7C0000000000000000B6 -:10F410000000000000000000000000007E7C1C10C6 -:10F420001810180830083008300460046004C00266 -:10F43000C002C00180018001800180018001800143 -:10F44000800180018001E007000000000000000052 -:10F45000000000000000000000000000F87F3830CD -:10F4600018300C180418000C0006000600030003F6 -:10F4700080018001C000C0006000600030001840C2 -:10F4800018600C200C38FE3F000000000000000057 -:10F49000000000000000C03FC000C000C000C0006D -:10F4A000C000C000C000C000C000C000C000C0005C -:10F4B000C000C000C000C000C000C000C000C0004C -:10F4C000C000C000C000C000C000C03F000000007D -:10F4D00000000000000000000000180018001000EC -:10F4E00030002000600060004000C000800080010B -:10F4F000800100010003000200060006000C000C61 -:10F50000000C0018001800300030003000600000CF -:10F51000000000000000FC030003000300030003E0 -:10F5200000030003000300030003000300030003C3 -:10F5300000030003000300030003000300030003B3 -:10F5400000030003000300030003FC0300000000AD -:10F5500000000000C003C0076004100800000000A5 +:10ED500000000000000000000000000000000000B3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED90000000000000000000000000000000000073 +:10EDA0000000000000000000000000000000000063 +:10EDB0000000000000000000000000000000000053 +:10EDC0000000000000000000000000000000000043 +:10EDD0000000000000000000000000000000000033 +:10EDE0000000000000000000000000000000000023 +:10EDF0000000000000000000000000000000000013 +:10EE00000000000000000000000000000000000002 +:10EE100000000000000000000000000000000000F2 +:10EE200000000000000000000000000000000000E2 +:10EE300000000000000000000000000000000000D2 +:10EE40000000000000000000000000001000003082 +:10EE500010F0FF3F104200104200104200F0FF1F70 +:10EE6000104208104208104208F0FF0F10200890CE +:10EE7000C00090410890410E904F0398C100884116 +:10EE80001088491084473084C13F02000000000010 +:10EE9000C2B92000000000000000000000000000D7 +:10EEA0000000000000000000000000000000000062 +:10EEB0000000000000000000000000000000000052 +:10EEC0000000000000000000000000000000000042 +:10EED000000000000000000000000000000000181A +:10EEE00000001800001000001000001000001000CA +:10EEF000809000801101C0100240100460101C308E +:10EF000010181010300810300410200010000010ED +:10EF100000001000001900001E00000C000000009E +:10EF2000D0A1200000000000000000000000000050 +:10EF300000000000000000000000000000000000D1 +:10EF400000000000000000000000000000000000C1 +:10EF500000000000000000000000000000000000B1 +:10EF60000000000000000000000000001000003061 +:10EF700000FED13F201002201002201002201002BB +:10EF8000201402FC150220140220D63F2012022079 +:10EF90001202201002A009026008021C08020604E6 +:10EFA0000200020200F13FC000002000000000004B +:10EFB000B0E02000000000000000000000000000A1 +:10EFC0000000000000000000000000000000000041 +:10EFD0000000000000000000000000000000000031 +:10EFE0000000000000000000000000000000000021 +:10EFF0000000000000000000000000000004000706 +:10F000000CF80004C00004C06004C0C004C00004C8 +:10F01000FE0704C00004C02004E06004E04304F0E4 +:10F020004624D04474C8800FC87804C40404C200C5 +:10F0300004C00004C00004C00004C0000440000478 +:10F04000BFC620000000000000000000000000001B +:10F0500000000000000000000000000000000000B0 +:10F0600000000000000000000000000000000000A0 +:10F070000000000000000000000000000000000090 +:10F080000000000000000000000000208000608000 +:10F0900001608000608000608000FEFF3F608000B3 +:10F0A000608000608000608200E0FD1F7010086ECC +:10F0B000100C642004602006604002604003608001 +:10F0C0000160400364300E780C7C200310000000C7 +:10F0D000BCBC200000000000000000000000000098 +:10F0E0000000000000000000000000000000000020 +:10F0F0000000000000000000000000000000000010 +:10F1000000000000000000000000000000000000FF +:10F1100000000000000000000000000000000000EF +:10F12000000000000000C0F8FFC018C0CC18C0CC20 +:10F13000F8FFCC18C0CC180CCC180CCCD8FFCCD80D +:10F14000CCCCD8CCCCD8CCCCCCCCC0CCCCC004FC97 +:10F15000C0060C7E0000000000000000000000005F +:10F16000CBA2200000000000000000000000000012 +:10F17000000000000000000000000000000000008F +:10F18000000000000000000000000000000000007F +:10F19000000000000000000000000000000000006F +:10F1A000000000000000000000000000000000005F +:10F1B00000000000000000F8FF7F180060180060E9 +:10F1C000F8FF7F180666180C06180803D8FF7F188A +:10F1D0000C06180C06F8FFFF0C0C060C0C060406B7 +:10F1E0000606030603010600000000000000000000 +:10F1F000C6C1200000000000000000000000000068 +:10F2000000000000000000000000000000000000FE +:10F2100000000000000000000000000000000000EE +:10F2200000000000000000000000000000000000DE +:10F2300000000000000000000000000000000000CE +:10F24000000000000200C084FFCC9CC1CC88C1CC6F +:10F2500080D9CC83D9CC8ED9CC98D9CC80D9CC804C +:10F26000D9CC88D9CC98CDCC0C0CCC0C36C00C6346 +:10F27000C0C6C1C074807D00000000000000000016 +:10F28000B2E22000000000000000000000000000CA +:10F29000000000000000000000000000000000006E +:10F2A000000000000000000000000000000000005E +:10F2B000000000000000000000000000000000004E +:10F2C000000000000000000000000000000000003E +:10F2D0000000000002001B0C0073180043380003FC +:10F2E00080FFFF0000031F000318000398FF0318AE +:10F2F0001802181806981806D8188678188C38F846 +:10F300008D9C0F980800F000000000000000000035 +:10F31000CAD420000000000000000000000000002F +:10F3200000000000000000000000000000000000DD +:10F3300000000000000000000000000000000000CD +:10F3400000000000000000000000000000000000BD +:10F3500000000000000000000000000000000000AD +:10F3600000000000008301FEFFFF008301F0FF3F6B +:10F37000300030F0FF3F300030F0FF3F300C300005 +:10F380000600FEFFFFC0300CF8FF7F67309860304A +:10F390001860301F00300000000000000000000076 +:10F3A000C4BB2000000000000000000000000000BE +:10F3B000000000000000000000000000000000004D +:10F3C000000000000000000000000000000000003D +:10F3D000000000000000000000000000000000002D +:10F3E000000000000000000000000000000000001D +:10F3F0000000000000630080C100C08001600003C5 +:10F4000030000618001C0E00700200C0F8FF0F004C +:10F41000030E00030E800106800106C00006600096 +:10F420000738FC030E000000000000000000000090 +:10F43000B7D620000000000000000000000000001F +:10F4400000000000000000000000000000000000BC +:10F4500000000000000000000000000000000000AC +:10F46000000000000000000000000000000000009C +:10F47000000000000000000000000000000000008C +:10F480000018600C306018306010FEE1FF00600072 +:10F4900082EDC1C46C636C6C36FE65FF306618305B +:10F4A0006618306018FEB1FF3030183818181C1C70 +:10F4B000180E0E18020218000000000000000000E4 +:10F4C000B1E6200000000000000000000000000085 +:10F4D000000000000000000000000000000000002C +:10F4E000000000000000000000000000000000001C +:10F4F000000000000000000000000000000000000C +:10F5000000000000000000000000000000000000FB +:10F5100000000000003800007000FFFFFF0038000E +:10F52000064E608C6338D03F08001C00202604F88B +:10F53000C31CCFFFF1023041003000FFFFFF00305D +:10F54000000030000030000000000000000000005B +:10F55000C2CA2000000000000000000000000000FF :10F56000000000000000000000000000000000009B :10F57000000000000000000000000000000000008B :10F58000000000000000000000000000000000007B :10F59000000000000000000000000000000000006B -:10F5A000000000000000000000000000000000005B -:10F5B000000000000000000000000000000000004B -:10F5C0000000000000000000000000000000FFFF3D -:10F5D000000000007800C0000001000000000000F2 -:10F5E000000000000000000000000000000000001B +:10F5A0000030800030800130000330FEFFFE06C0D6 +:10F5B0003086C4304018303030301860F00FC03E14 +:10F5C000F87F3000033000033000033000033000C8 +:10F5D0000330FFFF1E0000000000000000000000DC +:10F5E000BFD8200000000000000000000000000064 :10F5F000000000000000000000000000000000000B :10F6000000000000000000000000000000000000FA :10F6100000000000000000000000000000000000EA -:10F6200000000000000000000000E007180C0C18AB -:10F630000C180C18001CE01B38180C1806180618BB -:10F64000061806980C9EF8710000000000000000EB -:10F650000000000000000000000010001E00180064 -:10F66000180018001800180018009807581C3818BF -:10F67000383018301830183018301830183018302A -:10F6800018103818380CC8070000000000000000EF +:10F6200000000000000000000000000000000000DA +:10F63000000000008001609801608C0163FC3F6362 +:10F64000860163820163FFFF63800163800163FCC5 +:10F650007F638C61638C61638C61608C61608C3DC5 +:10F660006080013F0000000000000000000000007A +:10F67000D6C62000000000000000000000000000CE +:10F68000000000000000000000000000000000007A :10F69000000000000000000000000000000000006A -:10F6A00000000000000000000000C00770083018D3 -:10F6B00018180C180C000C000C000C000C000C208E -:10F6C000182018103008C0070000000000000000DB -:10F6D000000000000000000000000010001E0018E4 -:10F6E00000180018001800180018E01B301C18182B -:10F6F00018180C180C180C180C180C180C180C18DE -:10F700000818181C307AE009000000000000000012 +:10F6A000000000000000000000000000000000005A +:10F6B000000000000000000000000000000000004A +:10F6C00000000000000000FCC77F0CC6600CC66094 +:10F6D000FCC77F0CC660003006FEFFFF006E000016 +:10F6E000C701F0010F1F00F8FCC77F0CC6600CC6F5 +:10F6F00060FCC77F0CC66000000000000000000036 +:10F70000C6F720000000000000000000000000001C :10F7100000000000000000000000000000000000E9 -:10F7200000000000000000000000C003300C1018B2 -:10F7300018100C300C300C30FC3F0C000C000C008E -:10F74000182018107018C00700000000000000000A -:10F75000000000000000000000000000003E80618A -:10F760008060C060C000C000C000FC1FC000C000BE -:10F77000C000C000C000C000C000C000C000C00089 -:10F78000C000C000C000F80F000000000000000032 -:10F790000000000000000000000000000000000069 -:10F7A00000000000000000000000C077306C10185E -:10F7B0001818181818181018300CF007180018002E -:10F7C000F803F01F18380C300C300C301818E00714 -:10F7D0000000000000000000000010001E001800E3 -:10F7E000180018001800180018009807580C38184E -:10F7F0001818181818181818181818181818181889 -:10F800001818181818187E7E00000000000000006C -:10F810000000000000000000000000008001C003A4 -:10F8200080010000000000000001F801800180015B -:10F8300080018001800180018001800180018001C0 -:10F84000800180018001F81F00000000000000001E -:10F85000000000000000000000000000001C001E6E -:10F86000000C0000000000000008C00F000C000C9D -:10F87000000C000C000C000C000C000C000C000C28 -:10F88000000C000C000C000C000C18061802F00113 -:10F890000000000000000000000010001E00180022 -:10F8A00018001800180018001800183E180C18044A -:10F8B000180218019801D801780338031806180CAB -:10F8C000180C181818387E7C00000000000000009A -:10F8D000000000000000000000000001F8018001AD -:10F8E0008001800180018001800180018001800110 -:10F8F0008001800180018001800180018001800100 -:10F90000800180018001F81F00000000000000005D -:10F9100000000000000000000000000000000000E7 -:10F9200000000000000000000400F73C8E638661C8 -:10F93000866186618661866186618661866186618F -:10F94000866186618661CFF3000000000000000040 +:10F7200000000000000000000000000000000000D9 +:10F7300000000000000000000000000000000000C9 +:10F7400000000000000000000000000000000000B9 +:10F7500000000800001800003000FEFFFF0600C097 +:10F760000600C0E0FF0F00000700800100E000007D +:10F770003000FFFFFF00300000300000300000309C +:10F7800000801F00000000000000000000000000DA +:10F79000D7D620000000000000000000000000009C +:10F7A0000000000000000000000000000000000059 +:10F7B0000000000000000000000000000000000049 +:10F7C0000000000000000000000000000000000039 +:10F7D0000000000000000000000000000000000029 +:10F7E0000020800130C000F8DFFFC8600684710C83 +:10F7F00002390801100060000C70000CB8FFFF3CDB +:10F80000000C36040C320C0C30180C30100C30008C +:10F810000C30000C30E00700000000000000000089 +:10F82000B7FB200000000000000000000000000006 +:10F8300000000000000000000000000000000000C8 +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F8700000000000C0300060E000F0FFFF386000D2 +:10F88000F6FFFF336000F0FFFF306000F0FFFF3055 +:10F890000000003000003000FEFFFF00FE0180315C +:10F8A000077030380F30C00000000000000000007A +:10F8B000BCAF2000000000000000000000000000BD +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F0000000000000000000000000000000000008 +:10F900000000000000180000180000180000180097 +:10F91000FCFF7F0C18600C18600C18600C18600C51 +:10F920001860FCFF7F0C1860001800001800001819 +:10F930000000180000180000000000000000000097 +:10F94000D6D02000000000000000000000000000F1 :10F9500000000000000000000000000000000000A7 -:10F960000000000000000000000090075E0C381846 -:10F970001818181818181818181818181818181807 -:10F980001818181818187E7E0000000000000000EB -:10F990000000000000000000000000000000000067 -:10F9A00000000000000000000000C003300C101830 -:10F9B000181808300C300C300C300C300C300C3077 -:10F9C00018181818300CC0030000000000000000D8 -:10F9D0000000000000000000000000000000000027 -:10F9E0000000000000000000000090075E0C3818C6 -:10F9F00018101830183018301830183018301830E7 -:10FA000018183818780C98071800180018007E008D +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F9900000001C00003800006000FFFFFF60000C4A +:10F9A00060000CC00006C000068001030083010057 +:10F9B000C700006C0000380000EE00C0830778002C +:10F9C0003C0600E000000000000000000000000015 +:10F9D000CEC4200000000000000000000000000075 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 :10FA100000000000000000000000000000000000E6 -:10FA200000000000000000000000C013301E181C81 -:10FA300018180C180C180C180C180C180C180C189A -:10FA40000818181C301EE019001800180018007E55 -:10FA500000000000000000000000000000000000A6 -:10FA60000000000000000000000060387E66606159 -:10FA7000E001E00060006000600060006000600085 -:10FA8000600060006000FE07000000000000000051 +:10FA200000000000000000F8FF3F18003018003010 +:10FA3000F8FF3F180030180030F8FF3F180030047E +:10FA4000C62008C63018C63830C61820C60800C6FA +:10FA500000FEFFFF000000000000000000000000AA +:10FA6000CFD42000000000000000000000000000D3 +:10FA70000000000000000000000000000000000086 +:10FA80000000000000000000000000000000000076 :10FA90000000000000000000000000000000000066 -:10FAA00000000000000000000000C0276038303077 -:10FAB000302030207000E003800F001E0038083036 -:10FAC000083018303818C80F00000000000000008F -:10FAD0000000000000000000000000000000000026 -:10FAE000800080008000C000E000FC1FC000C0005B -:10FAF000C000C000C000C000C000C000C000C00006 -:10FB0000C020C0208011000F000000000000000095 +:10FAA0000000000000000000000000000000000056 +:10FAB00000000000000000FCFF7F000000000000CC +:10FAC000000000000000FFFFFF0030002030043085 +:10FAD000300C3830181830300C30600630C002302E +:10FAE00080003000801F00000000000000000000C7 +:10FAF000CABE20000000000000000000000000005E +:10FB000000000000000000000000000000000000F5 :10FB100000000000000000000000000000000000E5 -:10FB2000000000000000000010101E1E1818181819 -:10FB30001818181818181818181818181818181845 -:10FB40001818181C307AE0090000000000000000BE -:10FB500000000000000000000000000000000000A5 -:10FB6000000000000000000000003E7C183018106B -:10FB7000181830083008200460046004C002C00275 -:10FB8000C003800180018000000000000000000030 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000FEFFFF00300000300059 +:10FB500000300030300030300030300030F07F3086 +:10FB60003000303000303000303000303000303085 +:10FB700000FFFFFF00000000000000000000000088 +:10FB8000D5FD200000000000000000000000000083 :10FB90000000000000000000000000000000000065 -:10FBA00000000000000000000000DFF386618421F7 -:10FBB0008C218C218C13881358135812580E700EF8 -:10FBC000300E300C30042004000000000000000063 -:10FBD0000000000000000000000000000000000025 -:10FBE000000000000000000000007C3E30087008AB -:10FBF0006004C002C002800180018003400620062C -:10FC0000200C101818183E7E0000000000000000B4 -:10FC100000000000000000000000000000000000E4 -:10FC2000000000000000000000003E7C18181808CA -:10FC3000100830082004600460044002C002800202 -:10FC40008001800180008000800040007C003C003A +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD00000000000000300800100C0FF0760000378 +:10FBE0003880010C6000F4FF3F300030303030309E +:10FBF000303030303030303030303030F830009805 +:10FC00000300070EE001781E00C0000000000000A5 +:10FC1000B8BA200000000000000000000000000052 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 :10FC500000000000000000000000000000000000A4 -:10FC600000000000000000000000FC1F0C1C0C0C39 -:10FC70000406040700038001C001C000600070207A -:10FC8000302018300C18FC1F00000000000000009D -:10FC9000000000000030000800040004000400041C -:10FCA0000004000400040004000400040004000335 -:10FCB00080010002000400040004000400040004A9 -:10FCC00000040004000400040004000800300000E8 -:10FCD000000100010001000100010001000100011C -:10FCE000000100010001000100010001000100010C -:10FCF00000010001000100010001000100010001FC -:10FD000000010001000100010001000100010001EB -:10FD100000000000180020004000400040004000AB -:10FD20004000400040004000400040004000800192 -:10FD300000038000400040004000400040004000C0 -:10FD4000400040004000400040002000180000003B -:10FD500000007800C400824102410027001C00001E +:10FC600000000000003000003000003000003000D4 +:10FC700060300630300C30301C1830381830300C02 +:10FC800030600E30E00630C00230800030000030BE +:10FC900000C01F0000000000000000000000000085 +:10FCA000D0A12000000000000000000000000000C3 +:10FCB0000000000000000000000000000000000044 +:10FCC0000000000000000000000000000000000034 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF00000000000C00003C60C01C48601C080FFE4 +:10FD0000FECF60E0C060F8E360CCFE31C3983130D4 +:10FD10008031FF0F1B0C0C1B06060E3C070EE00388 +:10FD20001BE0C3313C76E0071880000000000000B3 +:10FD3000CAFD2000000000000000000000000000DC +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 :10FD60000000000000000000000000000000000093 :10FD70000000000000000000000000000000000083 -:10FD80000000000000000000000000000000000073 -:10FD90000000000000000000000000000000000063 -:10FDA0000000000000000000000000000000000053 -:10FDB0000000000000000000000000000000000043 -:10FDC00000000000000000006000600060006000B3 -:10FDD0006000600060004000200020002000000063 -:10FDE00000000000600060006000000000000000F3 -:10FDF000000000006006600630039801880044009F +:10FD80000000000030000330000330FEFF300003AD +:10FD9000300003FFFD7F300C6030FC7F300C6030A2 +:10FDA000FC7F300C60B0FD7F780C6007FFFF0060C7 +:10FDB0001C001CF080030000000000000000000098 +:10FDC000CCEE200000000000000000000000000059 +:10FDD0000000000000000000000000000000000023 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 :10FE000000000000000000000000000000000000F2 -:10FE100000000000000000000000000000000000E2 -:10FE2000000000000000000010021002100210028A -:10FE3000FE07FE0708020801080108010801FE0785 -:10FE4000FE07040104010401040100000000000099 -:10FE500000000000000040004000F00158034C0387 -:10FE6000CC034C0058007000E000C001C00140030A -:10FE70004C035C034C034801F000400040000000CC -:10FE800000000000000000000E010A019100910036 -:10FE90009100510051003A00AE03A00250045004FA -:10FEA0004804480448048402840300000000000061 -:10FEB000000000000000000038006C006C006C00C6 -:10FEC0006C006C002C0098071C011A0133013301EF -:10FED0006301E300C308C6093C07000000000000FE -:10FEE000000000000C001C001000100008000400BE +:10FE100000000000000800001800003800FFFFFF8D +:10FE2000000E00808301C0000770000CFCFF3F0043 +:10FE3000C32000C30080C10080C1C0E0C0C038C082 +:10FE4000C007807F000000000000000000000000EC +:10FE5000B3E42000000000000000000000000000EB +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA00000000000003800007000FEFFFF0600C0E8 +:10FEB0000686C3C0011E3800700600C0000000F8AE +:10FEC000FF3F00180000180000180000180000187C +:10FED00000FEFFFF00000000000000000000000026 +:10FEE000BFD520000000000000000000000000005E :10FEF0000000000000000000000000000000000002 :10FF000000000000000000000000000000000000F1 -:10FF1000000000000004000200018000800040009A -:10FF200040002000200020002000200020002000B1 -:10FF3000400040008000800000010002000400003A -:10FF40000000000002000400080010001000200063 -:10FF500020004000400040004000400040004000C1 -:10FF60002000200010001000080004000200000023 -:10FF70000000000000000000000000004000C00081 -:10FF80004000460C4E0FD001F0015E0F460C4000C1 -:10FF900040004000000000000000000000000000E1 -:10FFA0000000000000000000000000000000400011 -:10FFB0004000400040004000FE0F40004000400074 -:10FFC00040004000000000000000000000000000B1 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF30000000000030600030300030F07F3078701A +:10FF4000FF5B3830CC0CF88007B8C10F3C7A7836AC +:10FF50000EC033F87F3118603018603018603018E8 +:10FF60006030F87F301860000000000000000000E2 +:10FF7000B8F12000000000000000000000000000B8 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB0000000000000000000000000000000000041 +:10FFC0000000000000000000000000000000000031 :10FFD0000000000000000000000000000000000021 :10FFE0000000000000000000000000000000000011 -:10FFF000000000000C001C001000100008000400AD +:10FFF0000000000000000000000000000000000001 :020000040801F1 :1000000000000000000000000000000000000000F0 -:100010000000000000000000FE07000000000000DB +:1000100000000000000000000000000000000000E0 :1000200000000000000000000000000000000000D0 :1000300000000000000000000000000000000000C0 :1000400000000000000000000000000000000000B0 -:10005000000000001C001C001C000000000000004C -:10006000000000000004000600020003000100017F -:100070008000800040004000600020002000100050 -:100080001000080008000C00040006000200000038 -:1000900000000000000000000000F00098010C03C8 -:1000A0000C030606060606060606060606060606ED -:1000B00006060C030C039801F0000000000000008D -:1000C0000000000000000000000040007C00600014 -:1000D0006000600060006000600060006000600020 -:1000E0006000600060006000FC0300000000000091 -:1000F00000000000000000000000F800840102037E -:1001000006030603000300018001C0006000200018 -:100110001000080204020602FE03000000000000B6 -:10012000000000000000000000007800C60086010A -:10013000860180018001C000700080010001000381 -:100140000003060306038601F8000000000000001B -:100150000000000000000000000080018001C001DC -:10016000A001A00190018801880184018201FE0F95 -:100170008001800180018001E00700000000000094 -:1001800000000000000000000000FC030400040068 -:10019000040004000400F4008C01040300030003C5 -:1001A0000603060382018401F8000000000000003D -:1001B00000000000000000000000E00118030C0334 -:1001C0000C0004000600E60116030E0606060606ED -:1001D000060604060C021803F000000000000000F0 -:1001E00000000000000000000000F8070C060402F8 -:1001F0000401000100018000800040004000400038 -:10020000600060006000600060000000000000000E -:1002100000000000000000000000F8010C030606CA -:10022000060606060C021C03F000C8010C030606B5 -:100230000606060606060C03F0010000000000009A -:1002400000000000000000000000F0000C010C03A2 -:10025000060206060606060606078C06780600064F -:10026000000300030C018C01780000000000000076 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:1000900000000000000000000080000000000300DD +:1000A000000003002000020CE0FFFF1F60300C0086 +:1000B00060300C0060300C04E0FFFF0F60300C0477 +:1000C00060300C0460300C0460300C04E0FFFF076B +:1000D000600000046000040060041C00600C0C045C +:1000E00060040C0F60C48C0320FCED0020041C0095 +:1000F00030040C0010040D0810C40C0808340C184F +:10010000081E1838040CF81F020000000000000050 +:10011000C2B9200000000000000000000000000044 +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:100190000000000000000000008000000080070058 +:1001A000008001000080010000800100008001004B +:1001B000008001000080010000820100008E21000B +:1001C0000086410000878100008381018081010356 +:1001D00080810106C080010E4080011C6080011CEE +:1001E000308001181080011808800110048001007F +:1001F000008001000080010000800100008C0100EF +:1002000000F0010000E000000040000000000000DD +:10021000D0A120000000000000000000000000004D +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E :10027000000000000000000000000000000000007E -:1002800000000000E000E000E000000000000000CE -:1002900000000000E000E000E000000000000000BE -:1002A000000000000000000000000000000000004E -:1002B000000000006000600000000000000000007E -:1002C00000000000000060006000400020002000EE -:1002D0000000000000000000000400020001800097 -:1002E000400020001000080004000800100020005A -:1002F0004000800000010002000400000000000037 -:1003000000000000000000000000000000000000ED -:1003100000000000FE07000000000000FE070000D3 +:10028000000000000000000000000000000000006E +:100290000000000000000000000001000000070056 +:1002A000000C0318FC1FFF3FC0008301C000830146 +:1002B000C0008301C0008301C0008301C00083012E +:1002C000C0248301FC2F8301C0208309C020FF1FAD +:1002D000C0308301C0188101C0008101C0008101CC +:1002E000C0908101C08C8101C0838001F0C0800179 +:1002F0003E4080010C208001003080110008FE3F4C +:100300000006000000010000C00000000000000026 +:10031000B0E020000000000000000000000000002D :1003200000000000000000000000000000000000CD -:100330000000000000000000040008001000200081 -:100340004000800000010002000400020001800063 -:100350004000200010000800040000000000000021 -:1003600000000000000000000000E0031806040C7C -:10037000040C0C0C0C0C00078001400040004000F5 -:1003800000000000E000E000E000000000000000CD -:100390000000000000000000E00018030C02CC0583 -:1003A00064056605A605B604B604B604B604B6022E -:1003B000E4010C040C021803F0000000000000002F -:1003C000000000000000000000006000600050001D -:1003D000D00090009000880088010801F801040313 -:1003E00004030402020202060F0F000000000000D6 -:1003F00000000000000000000000FE008C030C0361 -:100400000C030C030C038C01FC000C030C020C0607 -:100410000C060C060C060C03FE0100000000000098 -:1004200000000000000000000000E00318030C06BC -:100430000C04040406000600060006000600060080 -:1004400006040C040C021803F00000000000000079 -:10045000000000000000000000007F008C010C0381 -:100460000C030C060C060C060C060C060C060C06FF -:100470000C060C030C038C017F0000000000000040 -:1004800000000000000000000000FF030603060457 -:100490000604060086008600FE00860086008600B0 -:1004A0000600060406040602FF0300000000000028 -:1004B00000000000000000000000FF030603060427 -:1004C0000604060086008600FE0086008600860080 -:1004D00006000600060006001F00000000000000E5 -:1004E00000000000000000000000F00018010C02F5 -:1004F0000C0204020600060006000600C60F0603F2 -:1005000006030C030C031803F000000000000000B9 -:10051000000000000000000000000F0F06060606A5 -:100520000606060606060606FE0706060606060672 -:1005300006060606060606060F0F0000000000006D -:1005400000000000000000000000FC0360006000EC -:10055000600060006000600060006000600060009B -:100560006000600060006000FC030000000000000C -:1005700000000000000000000000F807C000C000FC -:10058000C000C000C000C000C000C000C000C0006B -:10059000C000C000C000C000C000C60066003C0033 -:1005A00000000000000000000000CF038601C6002C -:1005B00046002600160036002E006E004600C600DB -:1005C00086008601060106038F0700000000000078 -:1005D000000000000000000000001F0006000600F0 -:1005E00006000600060006000600060006000600DB -:1005F0000600060406040602FF03000000000000D7 -:1006000000000000000000000000070786038603CA -:100610008E038E034E034E034A035A035A033A03D2 -:100620003203320332031203870700000000000088 -:10063000000000000000000000008E0F0C021C02F1 -:100640001C0234023402640264024402C4028402C2 -:1006500084038403040304031F020000000000005D -:1006600000000000000000000000F00098010C03F2 -:100670000C02060606060606060606060606060618 -:1006800006060C020C039801F000000000000000B8 -:1006900000000000000000000000FF000603060646 -:1006A00006060606060606068603FE000600060087 -:1006B00006000600060006001F0000000000000003 -:1006C00000000000000000000000F00098010C0392 -:1006D0000C020606060606060606060606060606B8 -:1006E00076064C02CC039801F0008007000300005E -:1006F00000000000000000000000FF0106030606E5 -:100700000606060606060603FE004600C60086002C -:1007100086010603060306060F0E00000000000017 -:1007200000000000000000000000F8020C030602B8 -:10073000060206000E003C00F800E00380030007FC -:100740000206020606060C03F0010000000000008D -:1007500000000000000000000000FE0762046108C5 -:100760006108600060006000600060006000600080 -:100770006000600060006000F80100000000000000 -:10078000000000000000000000001E070C020C0228 -:100790000C020C020C020C020C020C020C020C02E9 -:1007A0000C020C020C021801F00000000000000016 -:1007B000000000000000000000000F070602040116 -:1007C00004010C010C01880088009800980050007A -:1007D00050007000300020002000000000000000E9 -:1007E00000000000000000000000F70E6204420458 -:1007F0004604460464026402E402E4029C029C0192 -:10080000980198018801880088000000000000001D -:10081000000000000000000000009E070C0108011D -:1008200018019000B0006000200060006000D0005F -:1008300090008801080104038E07000000000000FA -:10084000000000000000000000000F0F060404027A -:100850000C0208011801B800B000700060006000D0 -:100860006000600060006000F8010000000000000F -:1008700000000000000000000000FC070C0206035E -:100880000201800180004000400020002000100094 -:10089000180008040C040402FE030000000000001D -:1008A00000000000E00320002000200020002000C5 -:1008B0002000200020002000200020002000200038 -:1008C000200020002000200020002000E003000085 -:1008D0000000000000000000040004000800080000 -:1008E0001000100010002000200040004000C00058 -:1008F00080008000000100010002000200020004EC -:10090000000000007C00400040004000400040002B -:1009100040004000400040004000400040004000D7 -:100920004000400040004000400040007C000000CB -:1009300000006000900008010000000000000000BE +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:100390000000000000000000000000010030000725 +:1003A000003C0003E00700031C03000300030603F6 +:1003B00000030C03000318030003180300230003C9 +:1003C000FC7F000300030003000302038003060315 +:1003D000800F0C03C03B0803403300336023003F11 +:1003E0002023F00310830F030863000304030003BA +:1003F00002030003000300030003000300030003E3 +:1004000000030003000300030001000100000000DE +:10041000BFC6200000000000000000000000000037 +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:1004900000000000000000008000100080037000D9 +:1004A0008001300080013000800130008001300088 +:1004B00080193018FCFFFF3F8001300080013000C0 +:1004C00080013000800130008031300480CDFF0F8A +:1004D00080030106F0010106BC0102038C01020346 +:1004E00080018601800184018001CC0080016800C8 +:1004F00080017000800178008001EC008001C7035A +:10050000F881011FE071003E400C00000000000077 +:10051000BCBC200000000000000000000000000043 +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 :1009400000000000000000000000000000000000A7 :100950000000000000000000000000000000000097 :100960000000000000000000000000000000000087 :100970000000000000000000000000000000000077 -:100980000000000000000000000000000000FF0F59 -:1009900000000000180060000000000000000000DF +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 :1009A0000000000000000000000000000000000047 :1009B0000000000000000000000000000000000037 :1009C0000000000000000000000000000000000027 -:1009D00000000000F0010C030C030003E0031C0303 -:1009E0000E03060306038E0B7C0E000000000000C1 -:1009F000000000000000000008000E000C000C00C9 -:100A00000C000C00CC013C031C060C060C060C066A -:100A10000C060C060C021C03E401000000000000A0 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 :100A200000000000000000000000000000000000C6 -:100A300000000000F0008C018C0186010600060019 -:100A4000060006020C020C01F0000000000000008D -:100A500000000000000000000002C00300030003CB -:100A60000003000378038C030C030603060306034C -:100A70000603060304038C07780100000000000051 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 :100A80000000000000000000000000000000000066 -:100A900000000000E001180308020C060C06FC0729 -:100AA0000C000C0018041802E00100000000000017 -:100AB00000000000000000000000C00360063006D7 -:100AC00030003000FE0130003000300030003000D7 -:100AD0003000300030003000FC0100000000000059 -:100AE0000000000000000000000000000000000006 -:100AF00000000000F007D8068C018C018C019801E1 -:100B0000F8000C00FC00CC03060306038E03F8007B -:100B1000000000000000000008000E000C000C00A7 -:100B20000C000C00EC011C030C030C030C030C0365 -:100B30000C030C030C030C039E07000000000000D4 -:100B400000000000000000000000600060000000E5 -:100B5000000040007C0060006000600060006000F9 -:100B60006000600060006000FC0300000000000006 -:100B700000000000000000000000C001C0010000F3 -:100B800000000001F00180018001800180018001EE -:100B9000800180018001800180018001CC007C0007 -:100BA000000000000000000008000E000C000C0017 -:100BB0000C000C008C038C008C004C006C005C0062 -:100BC0008C008C010C010C039E070000000000004B -:100BD000000000000000000040007C006000600099 -:100BE0006000600060006000600060006000600005 -:100BF0006000600060006000FC0300000000000076 -:100C000000000000000000000000000000000000E4 -:100C1000000000003707EE066606660666066606F2 -:100C20006606660666066606FF0F00000000000006 -:100C300000000000000000000000000000000000B4 -:100C400000000000EE011C030C030C030C030C035A -:100C50000C030C030C030C039E07000000000000B3 -:100C60000000000000000000000000000000000084 -:100C700000000000F00098010C03060606060606B8 -:100C8000060606060C030C03F0000000000000003E -:100C90000000000000000000000000000000000054 -:100CA00000000000EE011C030C060C060C060C06EE -:100CB0000C060C060C031C03EC010C000C003E009F -:100CC0000000000000000000000000000000000024 -:100CD0000000000078028C030C03060306030603E1 -:100CE0000603060304038C03780300030003C00714 -:100CF00000000000000000000000000000000000F4 -:100D0000000000009F03580638061800180018005D -:100D10001800180018001800FF0000000000000074 -:100D200000000000000000000000000000000000C3 -:100D300000000000F0031C030C020C023800F0005D -:100D4000C003040304038C03FC0100000000000046 -:100D50000000000000000000000000002000200053 -:100D600030003000FE013000300030003000300034 -:100D70003000300030023002E001000000000000CE +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD000000000000000000000000000C003C00390 +:100AE000C003C003C003C0038003800180018001F4 +:100AF0008001800180018001800100000000000071 +:100B00008001C003C003800100000000000000005D +:100B100000000000C018E01CE01C700E3006180336 +:100B20008C018400000000000000000000000000B4 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000002010201035 +:100B6000201020102010FE7FFE7FFE7F100810084E +:100B70001008100810081008FE7FFE7FFE7F180C7A +:100B80000804080408040804000000000000000035 +:100B9000000000000000000080008000C003B00CD6 +:100BA00090189818981C981CB800B000F000E0004D +:100BB000C0038007800F800C801C80189C189C1834 +:100BC0008C188C0C9806E0038000800080000000E8 +:100BD0000000000000000000000000001C083608B3 +:100BE000220463046302630263026301630122015E +:100BF000B61C9C3640224063406320632063106330 +:100C0000106310220836081C0000000000000000DD +:100C1000000000000000000000000000F00098004C +:100C20008C018C018C018C018C00CC005C003800A4 +:100C30001C3E3C08320873086304E304C3048303C6 +:100C4000834306678C3E781C000000000000000013 +:100C5000000000001C003C003C0030003000100090 +:100C60000C00060000000000000000000000000072 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C9000000000000040002000100018000C0004BC +:100CA0000006000200030003800180018001800132 +:100CB00080018001800180018001000300030002A7 +:100CC00000060004000C0018001000200040000086 +:100CD000000000000200040008001800300020009E +:100CE00060004000C000C0008001800180018001E0 +:100CF00080018001800180018001C000C000C0002F +:100D0000600020003000180008000400020000000D +:100D100000000000000000000000000000000000D3 +:100D20000003800380030C631C713839600D80035D +:100D30008003600D38391C718C618003800380034F +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D6000000000010001000100010001000100017C +:100D7000FC7F0001000100010001000100010001F1 :100D80000000000000000000000000000000000063 -:100D9000000008028E030C030C030C030C030C036D -:100DA0000C030C030C039C077801000000000000FA +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 :100DB0000000000000000000000000000000000033 -:100DC000000000001E070C02080108011801900035 -:100DD000B000B000600060002000000000000000D3 +:100DC0001C003C003C003000300010000C0006000D +:100DD0000000000000000000000000000000000013 :100DE0000000000000000000000000000000000003 -:100DF00000000000F70E6204460464026402EC0284 -:100E00009C01980198019801080000000000000072 +:100DF000FE7F000000000000000000000000000076 +:100E000000000000000000000000000000000000E2 :100E100000000000000000000000000000000000D2 -:100E200000000000BC0718011001B0006000600065 -:100E3000E0009000080108039E0700000000000089 -:100E400000000000000000000000000000000000A2 -:100E5000000000009E0708010801080190009000B2 -:100E6000B0006000600060002000200024001C0032 -:100E70000000000000000000000000000000000072 -:100E800000000000FC018401C40044006000200058 -:100E90003000180208020C03FC01000000000000F2 -:100EA00000000000000380008000800080008000BF -:100EB0008000800080004000200040008000800012 -:100EC000800080008000800080008000000300001F -:100ED0004000400040004000400040004000400012 -:100EE0004000400040004000400040004000400002 -:100EF00040004000400040004000400040004000F2 -:100F0000000000000C001000100010001000100085 -:100F10001000100010002000400020001000100001 -:100F20001000100010001000100010000C00000055 -:100F300000001C002204C204800300000000000026 -:100F400000000000000000000000000000000000A1 -:100F50000000000000000000000000000000000091 -:100F60000000000000000000000000000000000081 -:100F70000000000000000000000000000000000071 -:100F80000000000000000000000000000000300031 -:100F90003000300030003000200020002000200011 -:100FA00020000000000030003000000000000000C1 -:100FB0000000D800D8006C002400120000000000DF -:100FC0000000000000000000000000000000000021 -:100FD0000000000000000000000000000000000011 -:100FE000840084008400FF0184008400C600420065 -:100FF0004200FF01420042004200000000000000E9 -:101000000000000000002000F80024012401A401D9 -:10101000280030006000A00020012C0124012401E0 -:10102000F800200020000000000000000000000088 -:10103000860049004900290029001900D60028012E -:101040002801280124012401C20000000000000042 -:1010500000000000000000000C001200120012004E -:10106000EA0046004600250029003900110032013F -:10107000CC00000000000000000006000600040094 -:10108000020001000000000000000000000000005D -:101090000000000000000000000000000000000050 -:1010A000000000018000400020002000200010000F -:1010B0001000100010001000100020002000200080 -:1010C0004000800000010000000001000200040058 -:1010D00008000800080010001000100010001000A8 -:1010E00010000800080008000400020001000000D1 -:1010F0000000000000000000000020002000260387 -:10110000AE0370007000AE03260320002000000034 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400018003C003C0018000000000000000000FA +:100E50000000000000000040006000200030001092 +:100E600000180008000C0004000600020003000146 +:100E700080018000C00040006000200030001000B1 +:100E8000180008000C00040006000200000000002A +:100E9000000000000000000000000000C00360042B +:100EA000300C1818181818100C300C300C300C308E +:100EB0000C300C300C300C300C300C301810181872 +:100EC0001818300C6004C00300000000000000008F +:100ED0000000000000000000000000000001800190 +:100EE000F801800180018001800180018001800182 +:100EF00080018001800180018001800180018001EA +:100F000080018001C003F81F000000000000000005 +:100F1000000000000000000000000000E007101CBE +:100F20000818043004300C300C3000300018001861 +:100F3000000C000600038001C000400020201020AB +:100F400008200430FC1FFC1F00000000000000000F +:100F5000000000000000000000000000E003180690 +:100F60000C0C0C180C180C1800180018000C0006BB +:100F7000C003000E00180010003000300C300C30A0 +:100F80000C100C18180CE00300000000000000001A +:100F90000000000000000000000000000006000645 +:100FA000000700078006800640062006200610067F +:100FB000100608060C0604060206FE3F00060006A0 +:100FC000000600060006C03F000000000000000010 +:100FD000000000000000000000000000F03FF03FB3 +:100FE000080008000800080008000800C807280CCE +:100FF0001818081000300030003000300C300C3071 +:1010000004180418180CE0030000000000000000A1 +:1010100000000000000000000000000080076018D1 +:10102000301810181800080008000C00CC076C0CD1 +:101030001C181C100C300C300C300C300C301830DC +:1010400018103018700CC0070000000000000000ED +:10105000000000000000000000000000F83FF83F22 +:1010600008100C0804080404000400020002000236 +:10107000000100018000800080008000C000C000EE +:10108000C000C000C000C000000000000000000060 +:10109000000000000000000000000000E007300C2D +:1010A00018180C300C300C301C301C107818F00460 +:1010B000E003180F0C1E0C1C0638063006300630F4 +:1010C00006300C18180CE0030000000000000000BF +:1010D000000000000000000000000000E003180411 +:1010E0000C080C18061006300630063006300630A4 +:1010F0000E380C341836F031003000180018000893 +:101100000C0C0C060C03F0010000000000000000B5 :1011100000000000000000000000000000000000CF -:1011200000001000100010001000FF01100010005F -:10113000100010000000000000000000000000008F -:10114000000000000000000000000000000000009F -:101150000000000000000000000000000000060089 -:101160000600040002000100000000000000000072 -:1011700000000000000000000000FE03000000006E -:10118000000000000000000000000000000000005F -:10119000000000000000000000000000000000004F -:1011A0000000000000000000000000000000060039 -:1011B0000600000000000000000000020001000125 -:1011C00080008000C000400060002000300010005F -:1011D00018000800080004000400020000000000DD -:1011E000000000000000000078008400840002017C -:1011F00002010201020102010201020184008400D5 -:101200007800000000000000000000000000000066 -:1012100010001C0010001000100010001000100042 -:1012200010001000100010007C0000000000000002 -:1012300000000000000000007C00820002010201AA -:10124000020180004000200010000800040102019B -:10125000FE0100000000000000000000000000008F -:101260003C004200820082004000700080000001CB -:1012700000010201020182007C0000000000000069 -:1012800000000000000040004000600050004800E6 -:101290004800440042004200FE014000400040007F -:1012A000F00100000000000000000000000000004D -:1012B000FC01040004000400040074008C00000120 -:1012C00000010201020182007C0000000000000019 -:1012D0000000000000000000F0000801040104000C -:1012E00002007A008600020102010201040184006A -:1012F0007800000000000000000000000000000076 -:10130000FE01820042004000200010001000080092 -:1013100008000800080008000800000000000000A5 -:1013200000000000000000007800840002010201BB -:10133000020184007800840002010201020184009D -:101340007800000000000000000000000000000025 -:101350007800840082000201020102018401780108 -:1013600000018000820042003C00000000000000FC -:10137000000000000000000000000000000030003D -:1013800030000000000000000000000000003000FD -:10139000300000000000000000000000000000001D -:1013A000000000000000000010000000000000002D -:1013B00000000000000000001000100010001000ED -:1013C0000000000000008000400020001000080025 -:1013D000040002000400080010002000400080000B -:1013E00000000000000000000000000000000000FD -:1013F000000000000000FF01000000000000FF01ED -:1014000000000000000000000000000000000000DC -:10141000000000000000020004000800100020008E -:10142000400080004000200010000800040002007E -:101430000000000000000000000000000000780034 -:101440008400020106010601000180004000200026 -:1014500020002000000030003000000000000000EC -:1014600000000000000000007800C400F2015901F3 -:101470004901450125012501A500D900020184008B -:1014800078000000000000000000000000000000E4 -:101490001000100028002800280028004400440004 -:1014A0007C00440082008200C701000000000000B0 -:1014B00000000000000000003F0042004200420027 -:1014C00022003E0042008200820082008200420030 -:1014D0003F000000000000000000000000000000CD -:1014E00078018401020102010100010001000100F4 -:1014F00001000101020186007800000000000000E8 -:1015000000000000000000003F00C2008200020155 -:1015100002010201020102010201020182004200F5 -:101520003F0000000000000000000000000000007C -:10153000FF0082000201420042007E0042004200A1 -:101540000200020002018200FF0000000000000013 -:101550000000000000000000FF00820002014200C5 -:1015600042007E004200420002000200020002002F -:101570000700000000000000000000000000000064 -:1015800070018801040102010200020002008203CE -:101590000201020104010C01F00000000000000043 -:1015A0000000000000000000C701820082008200ED -:1015B00082008200FE00820082008200820082009F -:1015C000C701000000000000000000000000000053 -:1015D000FE0010001000100010001000100010009D -:1015E0001000100010001000FE00000000000000BD -:1015F0000000000000000000FC012000200020008E -:1016000020002000200020002000200020002000DA -:10161000210011000E00000000000000000000008A -:10162000E70142002200220012001A0016002200E8 -:101630002200420042008200C701000000000000BA -:10164000000000000000000007000200020002008D -:1016500002000200020002000200020002018200F9 -:10166000FF0000000000000000000000000000007B -:10167000C701C600C600C600AA00AA00AA00AA00A8 -:10168000AA00920092009200D70100000000000022 -:101690000000000000000000C70186008A008A00E8 -:1016A0008A0092009200A200A200C200C200C20002 -:1016B00087000000000000000000000000000000A3 -:1016C0003800C60082000101010101010101010190 -:1016D000010101018200C600380000000000000086 -:1016E00000000000000000007F00820002010201F3 -:1016F000020182007E0002000200020002000200DD -:1017000007000000000000000000000000000000D2 -:101710003800C6008200010101010101010101013F -:1017200001011901A600A60078004001C0000000D8 -:1017300000000000000000003F0042008200820024 -:1017400042003E00120022002200420042008200BD -:101750008701000000000000000000000000000001 -:10176000780184010201020002000C007000800078 -:1017700000010201020186007A0000000000000062 -:101780000000000000000000FE0011011101100027 -:1017900010001000100010001000100010001000C9 -:1017A0003800000000000000000000000000000001 -:1017B000C7018200820082008200820082008200D3 -:1017C0008200820082004400380000000000000017 -:1017D0000000000000000000C701820082004400F9 -:1017E000440044004400280028002800380010006D -:1017F00010000000000000000000000000000000D9 -:10180000BB019200920092009200AA00AA00AA00D6 -:101810006A0044004400440044000000000000004E -:101820000000000000000000CE01840044004800D9 -:1018300028003000100030002800480048008400D4 -:10184000CE010000000000000000000000000000C9 -:10185000C701820044004400280028001000100046 -:101860001000100010001000380000000000000000 -:101870000000000000000000FC0184008200400025 -:10188000400020001000100008000800040184003F -:10189000FE000000000000000000F0011000100039 -:1018A00010001000100010001000100010001000B8 -:1018B00010001000100010001000F00100000000E7 -:1018C00000000000020004000400080008000800F6 -:1018D0001000100020002000200040004000800088 -:1018E000800080000001000000003E002000200079 -:1018F00020002000200020002000200020002000E8 -:10190000200020002000200020003E0000000000F9 -:101910000000380028004400000000000000000023 -:1019200000000000000000000000000000000000B7 -:1019300000000000000000000000000000000000A7 -:101940000000000000000000000000000000000097 -:101950000000000000000000000000000000FF0385 -:10196000000018002000000000000000000000003F -:101970000000000000000000000000000000000067 -:101980000000000000000000000000000000000057 -:1019900000000000000000007C0082008200F000D7 -:1019A0008C0082008200C202BC0300000000000024 -:1019B000000000000000000003000200020002001E -:1019C0003A004600820082008200820082004600C7 -:1019D0003A000000000000000000000000000000CD -:1019E0000000000000000000780084008200020077 -:1019F00002000200020184007800000000000000E4 -:101A00000000000000000000C00080008000800096 -:101A1000B800C40082008200820082008200C400FC -:101A2000B8010000000000000000000000000000FD -:101A30000000000000000000780084000201FE01A8 -:101A40000200020002018400780000000000000093 -:101A50000000000000000000E00110021000100073 -:101A6000FC0010001000100010001000100010000A -:101A7000FC0000000000000000000000000000006A -:101A80000000000000000000F801840084008400D1 -:101A90008400780004007C00840102010201FC0043 -:101AA000000000000000000003000200020002002D -:101AB0007A0086008200820082008200820082001A -:101AC000C70100000000000000000000000000004E -:101AD00018001800000000001C001000100010008A -:101AE00010001000100010007C000000000000003A -:101AF0000000000000000000600060000000000026 -:101B000070004000400040004000400040004000A5 -:101B10004000400022001E00000000000000000005 -:101B20000300020002000200E200220012000A008C -:101B30001600220042008200C701000000000000E1 -:101B400000000000000000001E0010001000100047 -:101B50001000100010001000100010001000100005 -:101B6000FE00000000000000000000000000000077 -:101B700000000000000000007F0092009200920030 -:101B80009200920092009200B70100000000000055 -:101B90000000000000000000000000000000000045 -:101BA0007B00860082008200820082008200820028 -:101BB000C70100000000000000000000000000005D -:101BC0000000000000000000780084000201020113 -:101BD0000201020102018400780000000000000000 -:101BE00000000000000000000000000000000000F5 -:101BF0003B00460082008200820082008200460094 -:101C00003A0002000200070000000000000000008F -:101C10000000000000000000B800C4008200820044 -:101C2000820082008200C400B80080008000C001F1 -:101C300000000000000000000000000000000000A4 -:101C4000CE0128011800080008000800080008005C -:101C50003E00000000000000000000000000000046 -:101C60000000000000000000BC00C200820006006E -:101C70003800C000820086007A00000000000000EA -:101C80000000000000000000000010001000100024 -:101C9000FC00100010001000100010001000900058 -:101CA00060000000000000000000000000000000D4 -:101CB0000000000000000000C300820082008200DB -:101CC000820082008200C200BC010000000000000F -:101CD0000000000000000000000000000000000004 -:101CE000C70182004400440044002800280010007E -:101CF00010000000000000000000000000000000D4 -:101D00000000000000000000BB0192009200920061 -:101D1000AA00AA00440044004400000000000000A3 -:101D200000000000000000000000000000000000B3 -:101D3000CE018400480030003000300048008400AC -:101D4000CE010000000000000000000000000000C4 -:101D50000000000000000000EE0184008800480040 -:101D600048005000300020001000100010000C004F -:101D70000000000000000000000000000000000063 -:101D8000FE004200220020001000080084008200B3 -:101D9000FE00000000000000000080014000400044 -:101DA0004000400040004000600010006000400023 -:101DB0004000400040004000400040008001000022 -:101DC0002000200020002000200020002000200013 -:101DD0002000200020002000200020002000200003 -:101DE000200020002000200000000600080008005D -:101DF000080008000800080018002000180008006B -:101E0000080008000800080008000800060000009C -:101E10001C0026022203C001000000000000000098 -:101E200000000000000000000000000000000000B2 -:101E300000000000000000000000000000000000A2 -:101E4000000000000000000000000008080808086A -:101E5000080800001818000000486C241200000058 -:101E600000000000000000000000002424247F1275 -:101E700012127F12121200000000081C2A2A0A0CFB -:101E80001828282A2A1C08080000002225151515E4 -:101E90002A585454542200000000000C1212120A56 -:101EA00076252911916E000000060604030000004B -:101EB000000000000000000000402010100808088A -:101EC0000808081010204000000204080810101034 -:101ED00010101008080402000000000008086B1C25 -:101EE0001C6B08080000000000000000080808083B -:101EF0007F08080808000000000000000000000043 -:101F000000000000060604030000000000000000BE -:101F1000FE000000000000000000000000000000C3 -:101F20000000000006060000000080404020201055 -:101F30001008080404020200000000182442424273 -:101F40004242424224180000000000080E0808081F -:101F500008080808083E00000000003C42424220F9 -:101F600020100804427E00000000003C424220187D -:101F700020404042221C0000000000203028242481 -:101F800022227E20207800000000007E0202021A39 -:101F900026404042221C0000000000382402021AA1 -:101FA00026424242241800000000007E2222101027 -:101FB00008080808080800000000003C42424224CB -:101FC00018244242423C00000000001824424242D1 -:101FD00064584040241C0000000000000000181855 -:101FE00000000000181800000000000000000008B9 -:101FF0000000000000080804000000402010080451 -:1020000002040810204000000000000000007F00D3 -:1020100000007F0000000000000000020408102003 -:1020200040201008040200000000003C42424640EC -:1020300020101000181800000000001C225A5555EE -:1020400055552D42221C00000000000808181414E9 -:10205000243C224242E700000000001F2222221EF0 -:1020600022424242221F00000000007C4242010145 -:1020700001010142221C00000000001F22424242D6 -:1020800042424242221F00000000003F4212121E44 -:1020900012120242423F00000000003F4212121E94 -:1020A00012120202020700000000003C222201017D -:1020B00001712122221C0000000000E7424242423E -:1020C0007E42424242E700000000003E0808080845 -:1020D00008080808083E00000000007C10101010DE -:1020E000101010101010110F0000007722120A0EAD -:1020F0000A121222227700000000000702020202E8 -:1021000002020202427F00000000007736363636B7 -:102110002A2A2A2A2A6B0000000000E346464A4A7F -:1021200052525262624700000000001C22414141AD -:1021300041414141221C00000000003F4242424216 -:102140003E020202020700000000001C2241414141 -:1021500041414D53321C60000000003F4242423E6C -:102160001212222242C700000000007C42420204F8 -:1021700018204042423E00000000007F4908080845 -:1021800008080808081C0000000000E7424242421C -:1021900042424242423C0000000000E74242222408 -:1021A00024141418080800000000006B494949492C -:1021B0005555362222220000000000E74224241850 -:1021C0001818242442E7000000000077222214148B -:1021D00008080808081C00000000007E21201010DC -:1021E00008040442423F0000007808080808080874 -:1021F000080808080808780000000202040408081B -:102200000810102020204040001E10101010101048 -:102210001010101010101E000038440000000000C4 +:10112000000000000000000000008001C003C003B8 +:10113000800100000000000000000000000000002E +:101140008001C003C0038001000000000000000017 +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000C001C001FD +:10117000C0010000000000000000000000000000AE +:101180000000C001C001C0018001C000C00000001B +:10119000000000000000000000000000002000101F +:1011A0000008000400020001800040002000100040 +:1011B000080008001000200040008000000100022C +:1011C00000040008001000200000000000000000E3 +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000FE7F0000000082 +:1011F000000000000000FE7F000000000000000072 +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000004000800C2 +:1012200010002000400080000001000200040008BF +:1012300000100010000800040002000180004000BF +:101240002000100008000400000000000000000062 +:10125000000000000000000000000000C00730187F +:10126000183008600C601C601C601C6000300018A6 +:10127000000E000300010001000100010000000059 +:101280008001C003C00380010000000000000000D6 +:10129000000000000000000000000000C00760081F +:1012A000301018200C2B8C4D844CC64CC644664420 +:1012B000664466446646662666266417CC0C0C4077 +:1012C000082018303018C00700000000000000009F +:1012D000000000000000000000000000C001C0018C +:1012E000C001C001200320032003200330021006A8 +:1012F000100610061004F80F080C080C080C04184F +:101300000418041806381F7C0000000000000000CC +:10131000000000000000000000000000FE07181C94 +:101320001818183018301830183018301818180CD1 +:10133000F80718181830182018601860186018601E +:10134000186018301818FE0F0000000000000000A0 +:10135000000000000000000000000000C00760382E +:10136000103018600C400C400C000600060006000F +:101370000600060006000600060006000C400C40B1 +:10138000082018103008C00700000000000000000E +:10139000000000000000000000000000FE03180E26 +:1013A0001818181018301830186018601860186075 +:1013B000186018601860186018601820183018300D +:1013C000181818181806FE0300000000000000009E +:1013D000000000000000000000000000FE3F183088 +:1013E0001820184018401800180018081808180C81 +:1013F000F80F180C180818081800180018001840E2 +:10140000184018201830FE3F0000000000000000C7 +:10141000000000000000000000000000FE3F18383F +:101420001820184018401800180018081808180C40 +:10143000F80F180C180818081808180018001800D9 +:101440001800180018007E000000000000000000D6 +:10145000000000000000000000000000C003300C8D +:10146000100818180C100C100400060006000600E6 +:1014700006000600067E0618061804180C180C183C +:10148000081818183004E0030000000000000000F5 +:101490000000000000000000000000003FFC0C30D5 +:1014A0000C300C300C300C300C300C300C300C305C +:1014B000FC3F0C300C300C300C300C300C300C304D +:1014C0000C300C300C303FFC00000000000000002D +:1014D000000000000000000000000000F81F800174 +:1014E00080018001800180018001800180018001F4 +:1014F00080018001800180018001800180018001E4 +:10150000800180018001F81F000000000000000041 +:10151000000000000000000000000000E07F000666 +:10152000000600060006000600060006000600068B +:10153000000600060006000600060006000600067B +:1015400000060006000600060E060E038E01FC00D3 +:101550000000000000000000000000007E3E180CAB +:101560001804180618021801180198009800D800ED +:10157000B801B8011803180318061806180C180C3F +:10158000180C181818187E7C0000000000000000DD +:101590000000000000000000000000007E001800B5 +:1015A000180018001800180018001800180018007B +:1015B000180018001800180018001800180018402B +:1015C000184018201830FE3F000000000000000006 +:1015D0000000000000000000000000000FF01C38B8 +:1015E0001C381C381C381C34343434343434343211 +:1015F000343264326432643264314431C431C431CF +:10160000C430C43084308FFC0000000000000000B3 +:101610000000000000000000000000000FF81C2087 +:101620001C203420342064206420C420C420842161 +:1016300084210423042304260426042C042C0438C7 +:101640000438043004301F200000000000000000B7 +:10165000000000000000000000000000C003300C8B +:10166000181808100C300C30062006600660066062 +:101670000660066006600660066004600C300C3090 +:1016800008101818300CC003000000000000000013 +:10169000000000000000000000000000FE0F18180D +:1016A00018301860186018601860186018601830DA +:1016B0001818F8071800180018001800180018006B +:1016C0001800180018007E00000000000000000054 +:1016D000000000000000000000000000C003300C0B +:1016E000181808100C300C300660066006600660A2 +:1016F000066006600660066006600660E4211C3332 +:101700001C36181E300EC007004C003C003800008C +:10171000000000000000000000000000FE07181C90 +:101720001818183018301830183018301818180CCD +:10173000F80718031803180618061806180C180CD2 +:10174000180C181818187E7800000000000000001F +:10175000000000000000000000000000F013181E50 +:101760000C1806180610061006000E003C00F800C3 +:10177000E003800F001E00180038023002300630EF +:1017800004300C181C0CE4070000000000000000EE +:10179000000000000000000000000000FC3F8C2161 +:1017A0008461824182418001800180018001800149 +:1017B0008001800180018001800180018001800121 +:1017C000800180018001E0070000000000000000AF +:1017D0000000000000000000000000003F7C0C1032 +:1017E0000C100C100C100C100C100C100C100C1019 +:1017F0000C100C100C100C100C100C100C100C1009 +:101800000C1018083804E00300000000000000007D +:101810000000000000000000000000003E781830CA +:10182000181018101810300830083008300830042C +:101830006004600460046002C002C002C002C00113 +:101840008001800180008000000000000000000096 +:10185000000000000000000000000000CFF38661DF +:101860008621842104210C238C238C238C138C133C +:101870008813481258165816580E380E300E300E6F +:10188000300C3004100410040000000000000000C0 +:101890000000000000000000000000003E7C181066 +:1018A00018083008300460046002C002C0018001E2 +:1018B000800180018003400340062006200E100CAA +:1018C000100C181808383E7C0000000000000000D2 +:1018D0000000000000000000000000007E7C1C10E2 +:1018E0001810180830083008300460046004C00282 +:1018F000C002C0018001800180018001800180015F +:10190000800180018001E00700000000000000006D +:10191000000000000000000000000000F87F3830E8 +:1019200018300C180418000C000600060003000311 +:1019300080018001C000C0006000600030001840DD +:1019400018600C200C38FE3F000000000000000072 +:10195000000000000000C03FC000C000C000C00088 +:10196000C000C000C000C000C000C000C000C00077 +:10197000C000C000C000C000C000C000C000C00067 +:10198000C000C000C000C000C000C03F0000000098 +:101990000000000000000000000018001800100007 +:1019A00030002000600060004000C0008000800126 +:1019B000800100010003000200060006000C000C7C +:1019C000000C0018001800300030003000600000EB +:1019D000000000000000FC030003000300030003FC +:1019E00000030003000300030003000300030003DF +:1019F00000030003000300030003000300030003CF +:101A000000030003000300030003FC0300000000C8 +:101A100000000000C003C0076004100800000000C0 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000FFFF58 +:101A9000000000007800C00000010000000000000D +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000E007180C0C18C7 +:101AF0000C180C18001CE01B38180C1806180618D7 +:101B0000061806980C9EF871000000000000000006 +:101B10000000000000000000000010001E0018007F +:101B2000180018001800180018009807581C3818DA +:101B30003830183018301830183018301830183045 +:101B400018103818380CC80700000000000000000A +:101B50000000000000000000000000000000000085 +:101B600000000000000000000000C00770083018EE +:101B700018180C180C000C000C000C000C000C20A9 +:101B8000182018103008C0070000000000000000F6 +:101B9000000000000000000000000010001E0018FF +:101BA00000180018001800180018E01B301C181846 +:101BB00018180C180C180C180C180C180C180C18F9 +:101BC0000818181C307AE00900000000000000002E +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000C003300C1018CE +:101BF00018100C300C300C30FC3F0C000C000C00AA +:101C0000182018107018C007000000000000000025 +:101C1000000000000000000000000000003E8061A5 +:101C20008060C060C000C000C000FC1FC000C000D9 +:101C3000C000C000C000C000C000C000C000C000A4 +:101C4000C000C000C000F80F00000000000000004D +:101C50000000000000000000000000000000000084 +:101C600000000000000000000000C077306C101879 +:101C70001818181818181018300CF0071800180049 +:101C8000F803F01F18380C300C300C301818E0072F +:101C90000000000000000000000010001E001800FE +:101CA000180018001800180018009807580C381869 +:101CB00018181818181818181818181818181818A4 +:101CC0001818181818187E7E000000000000000088 +:101CD0000000000000000000000000008001C003C0 +:101CE00080010000000000000001F8018001800177 +:101CF00080018001800180018001800180018001DC +:101D0000800180018001F81F000000000000000039 +:101D1000000000000000000000000000001C001E89 +:101D2000000C0000000000000008C00F000C000CB8 +:101D3000000C000C000C000C000C000C000C000C43 +:101D4000000C000C000C000C000C18061802F0012E +:101D50000000000000000000000010001E0018003D +:101D600018001800180018001800183E180C180465 +:101D7000180218019801D801780338031806180CC6 +:101D8000180C181818387E7C0000000000000000B5 +:101D9000000000000000000000000001F8018001C8 +:101DA000800180018001800180018001800180012B +:101DB000800180018001800180018001800180011B +:101DC000800180018001F81F000000000000000079 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000400F73C8E638661E4 +:101DF00086618661866186618661866186618661AB +:101E0000866186618661CFF300000000000000005B +:101E100000000000000000000000000000000000C2 +:101E20000000000000000000000090075E0C381861 +:101E30001818181818181818181818181818181822 +:101E40001818181818187E7E000000000000000006 +:101E50000000000000000000000000000000000082 +:101E600000000000000000000000C003300C10184B +:101E7000181808300C300C300C300C300C300C3092 +:101E800018181818300CC0030000000000000000F3 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000090075E0C3818E1 +:101EB0001810183018301830183018301830183002 +:101EC00018183818780C98071800180018007E00A9 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000C013301E181C9D +:101EF00018180C180C180C180C180C180C180C18B6 +:101F00000818181C301EE019001800180018007E70 +:101F100000000000000000000000000000000000C1 +:101F20000000000000000000000060387E66606174 +:101F3000E001E000600060006000600060006000A0 +:101F4000600060006000FE0700000000000000006C +:101F50000000000000000000000000000000000081 +:101F600000000000000000000000C0276038303092 +:101F7000302030207000E003800F001E0038083051 +:101F8000083018303818C80F0000000000000000AA +:101F90000000000000000000000000000000000041 +:101FA000800080008000C000E000FC1FC000C00076 +:101FB000C000C000C000C000C000C000C000C00021 +:101FC000C020C0208011000F0000000000000000B1 +:101FD0000000000000000000000000000000000001 +:101FE000000000000000000010101E1E1818181835 +:101FF0001818181818181818181818181818181861 +:102000001818181C307AE0090000000000000000D9 +:1020100000000000000000000000000000000000C0 +:10202000000000000000000000003E7C1830181086 +:10203000181830083008200460046004C002C00290 +:10204000C00380018001800000000000000000004B +:102050000000000000000000000000000000000080 +:1020600000000000000000000000DFF38661842112 +:102070008C218C218C13881358135812580E700E13 +:10208000300E300C3004200400000000000000007E +:102090000000000000000000000000000000000040 +:1020A000000000000000000000007C3E30087008C6 +:1020B0006004C002C0028001800180034006200647 +:1020C000200C101818183E7E0000000000000000D0 +:1020D0000000000000000000000000000000000000 +:1020E000000000000000000000003E7C18181808E6 +:1020F000100830082004600460044002C00280021E +:102100008001800180008000800040007C003C0055 +:1021100000000000000000000000000000000000BF +:1021200000000000000000000000FC1F0C1C0C0C54 +:102130000406040700038001C001C0006000702095 +:10214000302018300C18FC1F0000000000000000B8 +:102150000000000000300008000400040004000437 +:102160000004000400040004000400040004000350 +:1021700080010002000400040004000400040004C4 +:102180000004000400040004000400080030000003 +:102190000001000100010001000100010001000137 +:1021A0000001000100010001000100010001000127 +:1021B0000001000100010001000100010001000117 +:1021C0000001000100010001000100010001000107 +:1021D00000000000180020004000400040004000C7 +:1021E00040004000400040004000400040008001AE +:1021F00000038000400040004000400040004000DC +:102200004000400040004000400020001800000056 +:1022100000007800C400824102410027001C000039 :1022200000000000000000000000000000000000AE -:1022300000000000000000FF000608000000000091 -:102240000000000000000000000000000000003C52 -:102250004278444242FC0000000000030202021ADD -:1022600026424242261A000000000000000000380A -:102270004402020244380000000000604040407800 -:102280004442424264D80000000000000000003CCC -:10229000427E0202423C0000000000F08808087EF6 -:1022A00008080808083E0000000000000000007C4C -:1022B00022221C023C42423C000000030202023A7D -:1022C0004642424242E700000000000C0C00000EB3 -:1022D00008080808083E0000000000303000003800 -:1022E000202020202020221E000000030202027273 -:1022F000120A1612227700000000000E08080808D3 -:1023000008080808083E0000000000000000007FE8 -:102310009292929292B70000000000000000003BF1 -:102320004642424242E70000000000000000003C3C -:1023300042424242423C0000000000000000001BFC -:1023400026424242221E02070000000000000078E0 -:1023500044424242447840E0000000000000007720 -:102360004C040404041F0000000000000000007C76 -:1023700042023C40423E0000000000000008083ECF -:102380000808080808300000000000000000006392 -:102390004242424262DC000000000000000000E710 -:1023A000422424140808000000000000000000EB94 -:1023B0004949555522220000000000000000007627 -:1023C00024181818246E000000000000000000E728 -:1023D0004224241418080807000000000000007EB2 -:1023E00022100808447E000000C020202020201079 -:1023F000202020202020C0001010101010101010DD -:10240000101010101010101000060808080808100E -:1024100008080808080806000C32C2000000000086 -:1024200000000000000000000000000000000000AC -:102430000000000000000404040404040004000080 -:1024400000140A0A0000000000000000000014143C -:102450003F140A3F0A0A000000041E1505060C146A -:10246000150F0400000012150D0A142C2A1200008A -:102470000000040A0A1E15150936000000020201B8 -:1024800000000000000000000020100808080808F4 -:1024900008102000000204080808080808040200C8 -:1024A00000000004150E0E150400000000000404D6 -:1024B000041F0404040000000000000000000000ED -:1024C0000002020100000000001F000000000000E8 -:1024D00000000000000000000002000000100808DA -:1024E000080404020202010000000E111111111172 -:1024F000110E00000000040604040404040E000091 -:1025000000000E1111080402011F000000000E114E -:10251000100C1010110E00000000080C0A0A091E11 -:102520000818000000001F01010F1010110E00001C -:1025300000000E09010F1111110E000000001F090B -:10254000080404040404000000000E11110E11110F -:10255000110E000000000E1111111E10120E0000CD -:102560000000000004000000000400000000000063 -:102570000004000000040400002010080402040805 -:1025800010200000000000001F00001F00000000DD -:1025900000020408102010080402000000000E11C0 -:1025A000110804040004000000000E111915151D87 -:1025B000011E0000000004040C0A0A1E1233000071 -:1025C00000000F12120E1212120F000000001E1156 -:1025D00001010101110E000000000F12121212126F -:1025E000120F000000001F120A0E0A02121F000044 -:1025F00000001F120A0E0A020207000000001C124F -:1026000001013911120C000000003312121E1212C7 -:102610001233000000001F0404040404041F00001F -:1026200000003E08080808080809070000003712E3 -:102630000A060A0A1237000000000702020202021C -:10264000223F000000001B1B1B1B15151515000069 -:1026500000003B1216161A1A1217000000000E1185 -:1026600011111111110E000000000F12120E0202C2 -:102670000207000000000E1111111117190E1800A9 -:1026800000000F12120E0A121237000000001E1175 -:1026900001060810110F000000001F1504040404B7 -:1026A000040E00000000331212121212120C00006D -:1026B00000003312120A0A0C040400000000151571 -:1026C000150E0A0A0A0A000000001B0A0A04040A7E -:1026D0000A1B000000001B0A0A040404040E000088 -:1026E00000001F0908040402121F0000001C04045B -:1026F0000404040404041C00000202020404080888 -:1027000008100000000E08080808080808080E0055 -:1027100000040A00000000000000000000000000AB -:10272000000000000000003F000400000000000066 -:102730000000000000000000000C121C123C000011 -:1027400000000302020E1212120E00000000000030 -:10275000001C1202021C000000001810101C1212B3 -:10276000123C000000000000000C121E021C0000C1 -:1027700000003804041E0404041E000000000000D1 -:10278000003C120C021E221C00000302020E121258 -:10279000123700000000040000060404040E0000CC -:1027A00000000800000C08080808080700000302E1 -:1027B000023A0A0E12370000000007040404040461 -:1027C000041F000000000000000F15151515000083 -:1027D00000000000000F121212370000000000007D -:1027E000000C1212120C000000000000000F121268 -:1027F000120E020700000000001C1212121C1038FA -:1028000000000000001B060202070000000000009C -:10281000001E020C101E000000000004040E040440 -:102820000418000000000000001B1212123C0000FF -:10283000000000000037120A0C0400000000000035 -:102840000015150E0A0A000000000000001B0A0413 -:102850000A1B0000000000000037120A0C040403E9 -:1028600000000000001E0804041E000000180808F4 -:1028700008040808080818000808080808080808D4 -:1028800008080808000604040408040404040600F8 -:102890000225180000000000000000006465666169 -:1028A000756C745461736B00D82801080000002017 -:1028B000340200000C080008202A0108340200201D -:1028C0004412010058840008202A010800C0012099 -:1028D00000400000588400088132104201035D244A -:1028E000F41AAA01011413719D14085D9E14086066 -:1028F00044122016C0012060C41C2060E40C6998BA -:10290000B11378C013080C120C121812141358C209 -:102910001B0810BE1A200C13D8C41B0814081A3C3C -:10292000041388C91B0818221248124113D0DB1B5C -:102930000820221A80182BD0E530122032402B902C -:10294000FD48121832301E600F01080A2032281E7E -:10295000381E0108085432101E28240108066C7223 -:102960000C132D621B0875041A85041AB1041AF1A0 -:102970000413F9611B083D08131201140202021628 -:1029800040830440571D02010203B9071A040309DA -:10299000041A0313A1091B089D041A59041AC5043B -:1029A0001AE90441130A0632022A40FC13DD5C14C2 -:1029B00008D95A4C08275F1C13AD5B1408CD591B6E -:1029C000089114C11A51281A0D041A99041AFD24E9 -:1029D0001C090243871125C03209041B01020B1395 -:1029E0000524161001052401100901042402020522 -:1029F00024061E0107058203ED1B0904BD320A2EC1 -:102A00000705010240072A8107248101821324C09F -:102A10001B082A0417C6E533B42D8C0200080000F9 +:10223000000000000000000000000000000000009E +:10224000000000000000000000000000000000008E +:10225000000000000000000000000000000000007E +:10226000000000000000000000000000000000006E +:10227000000000000000000000000000000000005E +:1022800000000000000000006000600060006000CE +:10229000600060006000400020002000200000007E +:1022A000000000006000600060000000000000000E +:1022B00000000000600660063003980188004400BA +:1022C000000000000000000000000000000000000E +:1022D00000000000000000000000000000000000FE +:1022E00000000000000000001002100210021002A6 +:1022F000FE07FE0708020801080108010801FE07A1 +:10230000FE070401040104010401000000000000B4 +:1023100000000000000040004000F00158034C03A2 +:10232000CC034C0058007000E000C001C001400325 +:102330004C035C034C034801F000400040000000E7 +:1023400000000000000000000E010A019100910051 +:102350009100510051003A00AE03A0025004500415 +:10236000480448044804840284030000000000007C +:10237000000000000000000038006C006C006C00E1 +:102380006C006C002C0098071C011A01330133010A +:102390006301E300C308C6093C0700000000000019 +:1023A000000000000C001C001000100008000400D9 +:1023B000000000000000000000000000000000001D +:1023C000000000000000000000000000000000000D +:1023D00000000000000400020001800080004000B6 +:1023E00040002000200020002000200020002000CD +:1023F0004000400080008000000100020004000056 +:10240000000000000200040008001000100020007E +:1024100020004000400040004000400040004000DC +:10242000200020001000100008000400020000003E +:102430000000000000000000000000004000C0009C +:102440004000460C4E0FD001F0015E0F460C4000DC +:1024500040004000000000000000000000000000FC +:10246000000000000000000000000000000040002C +:102470004000400040004000FE0F4000400040008F +:1024800040004000000000000000000000000000CC +:10249000000000000000000000000000000000003C +:1024A000000000000000000000000000000000002C +:1024B000000000000C001C001000100008000400C8 +:1024C000000000000000000000000000000000000C +:1024D0000000000000000000FE07000000000000F7 +:1024E00000000000000000000000000000000000EC +:1024F00000000000000000000000000000000000DC +:1025000000000000000000000000000000000000CB +:10251000000000001C001C001C0000000000000067 +:10252000000000000004000600020003000100019A +:10253000800080004000400060002000200010006B +:102540001000080008000C00040006000200000053 +:1025500000000000000000000000F00098010C03E3 +:102560000C03060606060606060606060606060608 +:1025700006060C030C039801F000000000000000A8 +:102580000000000000000000000040007C0060002F +:10259000600060006000600060006000600060003B +:1025A0006000600060006000FC03000000000000AC +:1025B00000000000000000000000F8008401020399 +:1025C00006030603000300018001C0006000200034 +:1025D0001000080204020602FE03000000000000D2 +:1025E000000000000000000000007800C600860126 +:1025F000860180018001C00070008001000100039D +:102600000003060306038601F80000000000000036 +:102610000000000000000000000080018001C001F7 +:10262000A001A00190018801880184018201FE0FB0 +:102630008001800180018001E007000000000000AF +:1026400000000000000000000000FC030400040083 +:10265000040004000400F4008C01040300030003E0 +:102660000603060382018401F80000000000000058 +:1026700000000000000000000000E00118030C034F +:102680000C0004000600E60116030E060606060608 +:10269000060604060C021803F0000000000000000B +:1026A00000000000000000000000F8070C06040213 +:1026B0000401000100018000800040004000400053 +:1026C000600060006000600060000000000000002A +:1026D00000000000000000000000F8010C030606E6 +:1026E000060606060C021C03F000C8010C030606D1 +:1026F0000606060606060C03F001000000000000B6 +:1027000000000000000000000000F0000C010C03BD +:10271000060206060606060606078C06780600066A +:10272000000300030C018C01780000000000000091 +:102730000000000000000000000000000000000099 +:1027400000000000E000E000E000000000000000E9 +:1027500000000000E000E000E000000000000000D9 +:102760000000000000000000000000000000000069 +:102770000000000060006000000000000000000099 +:102780000000000000006000600040002000200009 +:1027900000000000000000000004000200018000B2 +:1027A0004000200010000800040008001000200075 +:1027B0004000800000010002000400000000000052 +:1027C0000000000000000000000000000000000009 +:1027D00000000000FE07000000000000FE070000EF +:1027E00000000000000000000000000000000000E9 +:1027F000000000000000000004000800100020009D +:10280000400080000001000200040002000180007E +:10281000400020001000080004000000000000003C +:1028200000000000000000000000E0031806040C97 +:10283000040C0C0C0C0C0007800140004000400010 +:1028400000000000E000E000E000000000000000E8 +:102850000000000000000000E00018030C02CC059E +:1028600064056605A605B604B604B604B604B60249 +:10287000E4010C040C021803F0000000000000004A +:102880000000000000000000000060006000500038 +:10289000D00090009000880088010801F80104032E +:1028A00004030402020202060F0F000000000000F1 +:1028B00000000000000000000000FE008C030C037C +:1028C0000C030C030C038C01FC000C030C020C0623 +:1028D0000C060C060C060C03FE01000000000000B4 +:1028E00000000000000000000000E00318030C06D8 +:1028F0000C0404040600060006000600060006009C +:1029000006040C040C021803F00000000000000094 +:10291000000000000000000000007F008C010C039C +:102920000C030C060C060C060C060C060C060C061A +:102930000C060C030C038C017F000000000000005B +:1029400000000000000000000000FF030603060472 +:102950000604060086008600FE00860086008600CB +:102960000600060406040602FF0300000000000043 +:1029700000000000000000000000FF030603060442 +:102980000604060086008600FE008600860086009B +:1029900006000600060006001F0000000000000000 +:1029A00000000000000000000000F00018010C0210 +:1029B0000C0204020600060006000600C60F06030D +:1029C00006030C030C031803F000000000000000D5 +:1029D000000000000000000000000F0F06060606C1 +:1029E0000606060606060606FE070606060606068E +:1029F00006060606060606060F0F00000000000089 +:102A000000000000000000000000FC036000600007 +:102A100060006000600060006000600060006000B6 +:102A20006000600060006000FC0300000000000027 +:102A300000000000000000000000F807C000C00017 +:102A4000C000C000C000C000C000C000C000C00086 +:102A5000C000C000C000C000C000C60066003C004E +:102A600000000000000000000000CF038601C60047 +:102A700046002600160036002E006E004600C600F6 +:102A800086008601060106038F0700000000000093 +:102A9000000000000000000000001F00060006000B +:102AA00006000600060006000600060006000600F6 +:102AB0000600060406040602FF03000000000000F2 +:102AC00000000000000000000000070786038603E6 +:102AD0008E038E034E034E034A035A035A033A03EE +:102AE00032033203320312038707000000000000A4 +:102AF000000000000000000000008E0F0C021C020D +:102B00001C0234023402640264024402C4028402DD +:102B100084038403040304031F0200000000000078 +:102B200000000000000000000000F00098010C030D +:102B30000C02060606060606060606060606060633 +:102B400006060C020C039801F000000000000000D3 +:102B500000000000000000000000FF000603060661 +:102B600006060606060606068603FE0006000600A2 +:102B700006000600060006001F000000000000001E +:102B800000000000000000000000F00098010C03AD +:102B90000C020606060606060606060606060606D3 +:102BA00076064C02CC039801F00080070003000079 +:102BB00000000000000000000000FF010603060600 +:102BC0000606060606060603FE004600C600860048 +:102BD00086010603060306060F0E00000000000033 +:102BE00000000000000000000000F8020C030602D4 +:102BF000060206000E003C00F800E0038003000718 +:102C00000206020606060C03F001000000000000A8 +:102C100000000000000000000000FE0762046108E0 +:102C2000610860006000600060006000600060009B +:102C30006000600060006000F8010000000000001B +:102C4000000000000000000000001E070C020C0243 +:102C50000C020C020C020C020C020C020C020C0204 +:102C60000C020C020C021801F00000000000000031 +:102C7000000000000000000000000F070602040131 +:102C800004010C010C018800880098009800500095 +:102C90005000700030002000200000000000000004 +:102CA00000000000000000000000F70E6204420473 +:102CB0004604460464026402E402E4029C029C01AD +:102CC0009801980188018800880000000000000039 +:102CD000000000000000000000009E070C01080139 +:102CE00018019000B0006000200060006000D0007B +:102CF00090008801080104038E0700000000000016 +:102D0000000000000000000000000F0F0604040295 +:102D10000C0208011801B800B000700060006000EB +:102D20006000600060006000F8010000000000002A +:102D300000000000000000000000FC070C02060379 +:102D400002018001800040004000200020001000AF +:102D5000180008040C040402FE0300000000000038 +:102D600000000000E00320002000200020002000E0 +:102D70002000200020002000200020002000200053 +:102D8000200020002000200020002000E0030000A0 +:102D9000000000000000000004000400080008001B +:102DA0001000100010002000200040004000C00073 +:102DB0008000800000010001000200020002000407 +:102DC000000000007C004000400040004000400047 +:102DD00040004000400040004000400040004000F3 +:102DE0004000400040004000400040007C000000E7 +:102DF00000006000900008010000000000000000DA +:102E000000000000000000000000000000000000C2 +:102E100000000000000000000000000000000000B2 +:102E200000000000000000000000000000000000A2 +:102E30000000000000000000000000000000000092 +:102E40000000000000000000000000000000FF0F74 +:102E500000000000180060000000000000000000FA +:102E60000000000000000000000000000000000062 +:102E70000000000000000000000000000000000052 +:102E80000000000000000000000000000000000042 +:102E900000000000F0010C030C030003E0031C031E +:102EA0000E03060306038E0B7C0E000000000000DC +:102EB000000000000000000008000E000C000C00E4 +:102EC0000C000C00CC013C031C060C060C060C0686 +:102ED0000C060C060C021C03E401000000000000BC +:102EE00000000000000000000000000000000000E2 +:102EF00000000000F0008C018C0186010600060035 +:102F0000060006020C020C01F000000000000000A8 +:102F100000000000000000000002C00300030003E6 +:102F20000003000378038C030C0306030603060367 +:102F30000603060304038C0778010000000000006C +:102F40000000000000000000000000000000000081 +:102F500000000000E001180308020C060C06FC0744 +:102F60000C000C0018041802E00100000000000032 +:102F700000000000000000000000C00360063006F2 +:102F800030003000FE0130003000300030003000F2 +:102F90003000300030003000FC0100000000000074 +:102FA0000000000000000000000000000000000021 +:102FB00000000000F007D8068C018C018C019801FC +:102FC000F8000C00FC00CC03060306038E03F80097 +:102FD000000000000000000008000E000C000C00C3 +:102FE0000C000C00EC011C030C030C030C030C0381 +:102FF0000C030C030C030C039E07000000000000F0 +:103000000000000000000000000060006000000000 +:10301000000040007C006000600060006000600014 +:103020006000600060006000FC0300000000000021 +:1030300000000000000000000000C001C00100000E +:1030400000000001F0018001800180018001800109 +:10305000800180018001800180018001CC007C0022 +:10306000000000000000000008000E000C000C0032 +:103070000C000C008C038C008C004C006C005C007D +:103080008C008C010C010C039E0700000000000066 +:10309000000000000000000040007C0060006000B4 +:1030A0006000600060006000600060006000600020 +:1030B0006000600060006000FC0300000000000091 +:1030C0000000000000000000000000000000000000 +:1030D000000000003707EE0666066606660666060E +:1030E0006606660666066606FF0F00000000000022 +:1030F00000000000000000000000000000000000D0 +:1031000000000000EE011C030C030C030C030C0375 +:103110000C030C030C030C039E07000000000000CE +:10312000000000000000000000000000000000009F +:1031300000000000F00098010C03060606060606D3 +:10314000060606060C030C03F00000000000000059 +:10315000000000000000000000000000000000006F +:1031600000000000EE011C030C060C060C060C0609 +:103170000C060C060C031C03EC010C000C003E00BA +:10318000000000000000000000000000000000003F +:103190000000000078028C030C03060306030603FC +:1031A0000603060304038C03780300030003C0072F +:1031B000000000000000000000000000000000000F +:1031C000000000009F035806380618001800180079 +:1031D0001800180018001800FF0000000000000090 +:1031E00000000000000000000000000000000000DF +:1031F00000000000F0031C030C020C023800F00079 +:10320000C003040304038C03FC0100000000000061 +:10321000000000000000000000000000200020006E +:1032200030003000FE01300030003000300030004F +:103230003000300030023002E001000000000000E9 +:10324000000000000000000000000000000000007E +:10325000000008028E030C030C030C030C030C0388 +:103260000C030C030C039C07780100000000000015 +:10327000000000000000000000000000000000004E +:10328000000000001E070C02080108011801900050 +:10329000B000B000600060002000000000000000EE +:1032A000000000000000000000000000000000001E +:1032B00000000000F70E6204460464026402EC029F +:1032C0009C0198019801980108000000000000008E +:1032D00000000000000000000000000000000000EE +:1032E00000000000BC0718011001B0006000600081 +:1032F000E0009000080108039E07000000000000A5 +:1033000000000000000000000000000000000000BD +:10331000000000009E0708010801080190009000CD +:10332000B0006000600060002000200024001C004D +:10333000000000000000000000000000000000008D +:1033400000000000FC018401C40044006000200073 +:103350003000180208020C03FC010000000000000D +:1033600000000000000380008000800080008000DA +:10337000800080008000400020004000800080002D +:10338000800080008000800080008000000300003A +:10339000400040004000400040004000400040002D +:1033A000400040004000400040004000400040001D +:1033B000400040004000400040004000400040000D +:1033C000000000000C0010001000100010001000A1 +:1033D000100010001000200040002000100010001D +:1033E0001000100010001000100010000C00000071 +:1033F00000001C002204C204800300000000000042 +:1034000000000000000000000000000000000000BC +:1034100000000000000000000000000000000000AC +:10342000000000000000000000000000000000009C +:10343000000000000000000000000000000000008C +:10344000000000000000000000000000000030004C +:10345000300030003000300020002000200020002C +:1034600020000000000030003000000000000000DC +:103470000000D800D8006C002400120000000000FA +:10348000000000000000000000000000000000003C +:10349000000000000000000000000000000000002C +:1034A000840084008400FF0184008400C600420080 +:1034B0004200FF0142004200420000000000000004 +:1034C0000000000000002000F80024012401A401F5 +:1034D000280030006000A00020012C0124012401FC +:1034E000F8002000200000000000000000000000A4 +:1034F000860049004900290029001900D60028014A +:103500002801280124012401C2000000000000005D +:1035100000000000000000000C0012001200120069 +:10352000EA0046004600250029003900110032015A +:10353000CC000000000000000000060006000400AF +:103540000200010000000000000000000000000078 +:10355000000000000000000000000000000000006B +:10356000000000018000400020002000200010002A +:10357000100010001000100010002000200020009B +:103580004000800000010000000001000200040073 +:1035900008000800080010001000100010001000C3 +:1035A00010000800080008000400020001000000EC +:1035B00000000000000000000000200020002603A2 +:1035C000AE0370007000AE03260320002000000050 +:1035D00000000000000000000000000000000000EB +:1035E00000001000100010001000FF01100010007B +:1035F00010001000000000000000000000000000AB +:1036000000000000000000000000000000000000BA +:1036100000000000000000000000000000000600A4 +:10362000060004000200010000000000000000008D +:1036300000000000000000000000FE030000000089 +:10364000000000000000000000000000000000007A +:10365000000000000000000000000000000000006A +:103660000000000000000000000000000000060054 +:103670000600000000000000000000020001000140 +:1036800080008000C000400060002000300010007A +:1036900018000800080004000400020000000000F8 +:1036A0000000000000000000780084008400020197 +:1036B00002010201020102010201020184008400F0 +:1036C0007800000000000000000000000000000082 +:1036D00010001C001000100010001000100010005E +:1036E00010001000100010007C000000000000001E +:1036F00000000000000000007C00820002010201C6 +:1037000002018000400020001000080004010201B6 +:10371000FE010000000000000000000000000000AA +:103720003C004200820082004000700080000001E6 +:1037300000010201020182007C0000000000000084 +:103740000000000000004000400060005000480001 +:103750004800440042004200FE014000400040009A +:10376000F001000000000000000000000000000068 +:10377000FC01040004000400040074008C0000013B +:1037800000010201020182007C0000000000000034 +:103790000000000000000000F00008010401040027 +:1037A00002007A0086000201020102010401840085 +:1037B0007800000000000000000000000000000091 +:1037C000FE018200420040002000100010000800AE +:1037D00008000800080008000800000000000000C1 +:1037E00000000000000000007800840002010201D7 +:1037F00002018400780084000201020102018400B9 +:103800007800000000000000000000000000000040 +:103810007800840082000201020102018401780123 +:1038200000018000820042003C0000000000000017 +:103830000000000000000000000000000000300058 +:103840003000000000000000000000000000300018 +:103850003000000000000000000000000000000038 +:103860000000000000000000100000000000000048 +:103870000000000000000000100010001000100008 +:103880000000000000008000400020001000080040 +:103890000400020004000800100020004000800026 +:1038A0000000000000000000000000000000000018 +:1038B000000000000000FF01000000000000FF0108 +:1038C00000000000000000000000000000000000F8 +:1038D00000000000000002000400080010002000AA +:1038E000400080004000200010000800040002009A +:1038F0000000000000000000000000000000780050 +:103900008400020106010601000180004000200041 +:103910002000200000003000300000000000000007 +:1039200000000000000000007800C400F20159010E +:103930004901450125012501A500D90002018400A6 +:1039400078000000000000000000000000000000FF +:10395000100010002800280028002800440044001F +:103960007C00440082008200C701000000000000CB +:1039700000000000000000003F0042004200420042 +:1039800022003E004200820082008200820042004B +:103990003F000000000000000000000000000000E8 +:1039A000780184010201020101000100010001000F +:1039B0000100010102018600780000000000000003 +:1039C00000000000000000003F00C2008200020171 +:1039D0000201020102010201020102018200420011 +:1039E0003F00000000000000000000000000000098 +:1039F000FF0082000201420042007E0042004200BD +:103A00000200020002018200FF000000000000002E +:103A10000000000000000000FF00820002014200E0 +:103A200042007E004200420002000200020002004A +:103A3000070000000000000000000000000000007F +:103A400070018801040102010200020002008203E9 +:103A50000201020104010C01F0000000000000005E +:103A60000000000000000000C70182008200820008 +:103A700082008200FE0082008200820082008200BA +:103A8000C70100000000000000000000000000006E +:103A9000FE001000100010001000100010001000B8 +:103AA0001000100010001000FE00000000000000D8 +:103AB0000000000000000000FC01200020002000A9 +:103AC00020002000200020002000200020002000F6 +:103AD000210011000E0000000000000000000000A6 +:103AE000E70142002200220012001A001600220004 +:103AF0002200420042008200C701000000000000D6 +:103B000000000000000000000700020002000200A8 +:103B10000200020002000200020002000201820014 +:103B2000FF00000000000000000000000000000096 +:103B3000C701C600C600C600AA00AA00AA00AA00C3 +:103B4000AA00920092009200D7010000000000003D +:103B50000000000000000000C70186008A008A0003 +:103B60008A0092009200A200A200C200C200C2001D +:103B700087000000000000000000000000000000BE +:103B80003800C600820001010101010101010101AB +:103B9000010101018200C6003800000000000000A1 +:103BA00000000000000000007F008200020102010E +:103BB000020182007E0002000200020002000200F8 +:103BC00007000000000000000000000000000000EE +:103BD0003800C6008200010101010101010101015B +:103BE00001011901A600A60078004001C0000000F4 +:103BF00000000000000000003F0042008200820040 +:103C000042003E00120022002200420042008200D8 +:103C1000870100000000000000000000000000001C +:103C2000780184010201020002000C007000800093 +:103C300000010201020186007A000000000000007D +:103C40000000000000000000FE0011011101100042 +:103C500010001000100010001000100010001000E4 +:103C6000380000000000000000000000000000001C +:103C7000C7018200820082008200820082008200EE +:103C80008200820082004400380000000000000032 +:103C90000000000000000000C70182008200440014 +:103CA0004400440044002800280028003800100088 +:103CB00010000000000000000000000000000000F4 +:103CC000BB019200920092009200AA00AA00AA00F2 +:103CD0006A0044004400440044000000000000006A +:103CE0000000000000000000CE01840044004800F5 +:103CF00028003000100030002800480048008400F0 +:103D0000CE010000000000000000000000000000E4 +:103D1000C701820044004400280028001000100061 +:103D2000100010001000100038000000000000001B +:103D30000000000000000000FC0184008200400040 +:103D4000400020001000100008000800040184005A +:103D5000FE000000000000000000F0011000100054 +:103D600010001000100010001000100010001000D3 +:103D700010001000100010001000F0010000000002 +:103D80000000000002000400040008000800080011 +:103D900010001000200020002000400040008000A3 +:103DA000800080000001000000003E002000200094 +:103DB0002000200020002000200020002000200003 +:103DC000200020002000200020003E000000000015 +:103DD000000038002800440000000000000000003F +:103DE00000000000000000000000000000000000D3 +:103DF00000000000000000000000000000000000C3 +:103E000000000000000000000000000000000000B2 +:103E10000000000000000000000000000000FF03A0 +:103E2000000018002000000000000000000000005A +:103E30000000000000000000000000000000000082 +:103E40000000000000000000000000000000000072 +:103E500000000000000000007C0082008200F000F2 +:103E60008C0082008200C202BC030000000000003F +:103E70000000000000000000030002000200020039 +:103E80003A004600820082008200820082004600E2 +:103E90003A000000000000000000000000000000E8 +:103EA0000000000000000000780084008200020092 +:103EB00002000200020184007800000000000000FF +:103EC0000000000000000000C000800080008000B2 +:103ED000B800C40082008200820082008200C40018 +:103EE000B801000000000000000000000000000019 +:103EF0000000000000000000780084000201FE01C4 +:103F000002000200020184007800000000000000AE +:103F10000000000000000000E0011002100010008E +:103F2000FC00100010001000100010001000100025 +:103F3000FC00000000000000000000000000000085 +:103F40000000000000000000F801840084008400EC +:103F50008400780004007C00840102010201FC005E +:103F60000000000000000000030002000200020048 +:103F70007A00860082008200820082008200820035 +:103F8000C701000000000000000000000000000069 +:103F900018001800000000001C00100010001000A5 +:103FA00010001000100010007C0000000000000055 +:103FB0000000000000000000600060000000000041 +:103FC00070004000400040004000400040004000C1 +:103FD0004000400022001E00000000000000000021 +:103FE0000300020002000200E200220012000A00A8 +:103FF0001600220042008200C701000000000000FD +:1040000000000000000000001E0010001000100062 +:104010001000100010001000100010001000100020 +:10402000FE00000000000000000000000000000092 +:1040300000000000000000007F009200920092004B +:104040009200920092009200B70100000000000070 +:104050000000000000000000000000000000000060 +:104060007B00860082008200820082008200820043 +:10407000C701000000000000000000000000000078 +:10408000000000000000000078008400020102012E +:10409000020102010201840078000000000000001B +:1040A0000000000000000000000000000000000010 +:1040B0003B004600820082008200820082004600AF +:1040C0003A000200020007000000000000000000AB +:1040D0000000000000000000B800C4008200820060 +:1040E000820082008200C400B80080008000C0010D +:1040F00000000000000000000000000000000000C0 +:10410000CE01280118000800080008000800080077 +:104110003E00000000000000000000000000000061 +:104120000000000000000000BC00C2008200060089 +:104130003800C000820086007A0000000000000005 +:10414000000000000000000000001000100010003F +:10415000FC00100010001000100010001000900073 +:1041600060000000000000000000000000000000EF +:104170000000000000000000C300820082008200F6 +:10418000820082008200C200BC010000000000002A +:10419000000000000000000000000000000000001F +:1041A000C701820044004400440028002800100099 +:1041B00010000000000000000000000000000000EF +:1041C0000000000000000000BB019200920092007D +:1041D000AA00AA00440044004400000000000000BF +:1041E00000000000000000000000000000000000CF +:1041F000CE018400480030003000300048008400C8 +:10420000CE010000000000000000000000000000DF +:104210000000000000000000EE018400880048005B +:1042200048005000300020001000100010000C006A +:10423000000000000000000000000000000000007E +:10424000FE004200220020001000080084008200CE +:10425000FE0000000000000000008001400040005F +:10426000400040004000400060001000600040003E +:10427000400040004000400040004000800100003D +:10428000200020002000200020002000200020002E +:10429000200020002000200020002000200020001E +:1042A0002000200020002000000006000800080078 +:1042B0000800080008000800180020001800080086 +:1042C00008000800080008000800080006000000B8 +:1042D0001C0026022203C0010000000000000000B4 +:1042E00000000000000000000000000000000000CE +:1042F00000000000000000000000000000000000BE +:104300000000000000000000000000080808080885 +:10431000080800001818000000486C241200000073 +:1043200000000000000000000000002424247F1290 +:1043300012127F12121200000000081C2A2A0A0C16 +:104340001828282A2A1C08080000002225151515FF +:104350002A585454542200000000000C1212120A71 +:1043600076252911916E0000000606040300000066 +:1043700000000000000000000040201010080808A5 +:10438000080808101020400000020408081010104F +:1043900010101008080402000000000008086B1C40 +:1043A0001C6B080800000000000000000808080856 +:1043B0007F0808080800000000000000000000005E +:1043C00000000000060604030000000000000000DA +:1043D000FE000000000000000000000000000000DF +:1043E0000000000006060000000080404020201071 +:1043F000100808040402020000000018244242428F +:104400004242424224180000000000080E0808083A +:1044100008080808083E00000000003C4242422014 +:1044200020100804427E00000000003C4242201898 +:1044300020404042221C000000000020302824249C +:1044400022227E20207800000000007E0202021A54 +:1044500026404042221C0000000000382402021ABC +:1044600026424242241800000000007E2222101042 +:1044700008080808080800000000003C42424224E6 +:1044800018244242423C00000000001824424242EC +:1044900064584040241C0000000000000000181870 +:1044A00000000000181800000000000000000008D4 +:1044B000000000000008080400000040201008046C +:1044C00002040810204000000000000000007F00EF +:1044D00000007F000000000000000002040810201F +:1044E00040201008040200000000003C4242464008 +:1044F00020101000181800000000001C225A55550A +:1045000055552D42221C0000000000080818141404 +:10451000243C224242E700000000001F2222221E0B +:1045200022424242221F00000000007C4242010160 +:1045300001010142221C00000000001F22424242F1 +:1045400042424242221F00000000003F4212121E5F +:1045500012120242423F00000000003F4212121EAF +:1045600012120202020700000000003C2222010198 +:1045700001712122221C0000000000E74242424259 +:104580007E42424242E700000000003E0808080860 +:1045900008080808083E00000000007C10101010F9 +:1045A000101010101010110F0000007722120A0EC8 +:1045B0000A12122222770000000000070202020203 +:1045C00002020202427F00000000007736363636D3 +:1045D0002A2A2A2A2A6B0000000000E346464A4A9B +:1045E00052525262624700000000001C22414141C9 +:1045F00041414141221C00000000003F4242424232 +:104600003E020202020700000000001C224141415C +:1046100041414D53321C60000000003F4242423E87 +:104620001212222242C700000000007C4242020413 +:1046300018204042423E00000000007F4908080860 +:1046400008080808081C0000000000E74242424237 +:1046500042424242423C0000000000E74242222423 +:1046600024141418080800000000006B4949494947 +:104670005555362222220000000000E7422424186B +:104680001818242442E700000000007722221414A6 +:1046900008080808081C00000000007E21201010F7 +:1046A00008040442423F000000780808080808088F +:1046B0000808080808087800000002020404080836 +:1046C0000810102020204040001E10101010101064 +:1046D0001010101010101E000038440000000000E0 +:1046E00000000000000000000000000000000000CA +:1046F00000000000000000FF0006080000000000AD +:104700000000000000000000000000000000003C6D +:104710004278444242FC0000000000030202021AF8 +:1047200026424242261A0000000000000000003825 +:10473000440202024438000000000060404040781B +:104740004442424264D80000000000000000003CE7 +:10475000427E0202423C0000000000F08808087E11 +:1047600008080808083E0000000000000000007C67 +:1047700022221C023C42423C000000030202023A98 +:104780004642424242E700000000000C0C00000ECE +:1047900008080808083E000000000030300000381B +:1047A000202020202020221E00000003020202728E +:1047B000120A1612227700000000000E08080808EE +:1047C00008080808083E0000000000000000007F04 +:1047D0009292929292B70000000000000000003B0D +:1047E0004642424242E70000000000000000003C58 +:1047F00042424242423C0000000000000000001B18 +:1048000026424242221E02070000000000000078FB +:1048100044424242447840E000000000000000773B +:104820004C040404041F0000000000000000007C91 +:1048300042023C40423E0000000000000008083EEA +:1048400008080808083000000000000000000063AD +:104850004242424262DC000000000000000000E72B +:10486000422424140808000000000000000000EBAF +:104870004949555522220000000000000000007642 +:1048800024181818246E000000000000000000E743 +:104890004224241418080807000000000000007ECD +:1048A00022100808447E000000C020202020201094 +:1048B000202020202020C0001010101010101010F8 +:1048C000101010101010101000060808080808102A +:1048D00008080808080806000C32C20000000000A2 +:1048E00000000000000000000000000000000000C8 +:1048F000000000000000040404040404000400009C +:1049000000140A0A00000000000000000000141457 +:104910003F140A3F0A0A000000041E1505060C1485 +:10492000150F0400000012150D0A142C2A120000A5 +:104930000000040A0A1E15150936000000020201D3 +:10494000000000000000000000201008080808080F +:1049500008102000000204080808080808040200E3 +:1049600000000004150E0E150400000000000404F1 +:10497000041F040404000000000000000000000008 +:104980000002020100000000001F00000000000003 +:1049900000000000000000000002000000100808F5 +:1049A000080404020202010000000E11111111118D +:1049B000110E00000000040604040404040E0000AC +:1049C00000000E1111080402011F000000000E116A +:1049D000100C1010110E00000000080C0A0A091E2D +:1049E0000818000000001F01010F1010110E000038 +:1049F00000000E09010F1111110E000000001F0927 +:104A0000080404040404000000000E11110E11112A +:104A1000110E000000000E1111111E10120E0000E8 +:104A2000000000000400000000040000000000007E +:104A30000004000000040400002010080402040820 +:104A400010200000000000001F00001F00000000F8 +:104A500000020408102010080402000000000E11DB +:104A6000110804040004000000000E111915151DA2 +:104A7000011E0000000004040C0A0A1E123300008C +:104A800000000F12120E1212120F000000001E1171 +:104A900001010101110E000000000F12121212128A +:104AA000120F000000001F120A0E0A02121F00005F +:104AB00000001F120A0E0A020207000000001C126A +:104AC00001013911120C000000003312121E1212E3 +:104AD0001233000000001F0404040404041F00003B +:104AE00000003E08080808080809070000003712FF +:104AF0000A060A0A12370000000007020202020238 +:104B0000223F000000001B1B1B1B15151515000084 +:104B100000003B1216161A1A1217000000000E11A0 +:104B200011111111110E000000000F12120E0202DD +:104B30000207000000000E1111111117190E1800C4 +:104B400000000F12120E0A121237000000001E1190 +:104B500001060810110F000000001F1504040404D2 +:104B6000040E00000000331212121212120C000088 +:104B700000003312120A0A0C04040000000015158C +:104B8000150E0A0A0A0A000000001B0A0A04040A99 +:104B90000A1B000000001B0A0A040404040E0000A3 +:104BA00000001F0908040402121F0000001C040476 +:104BB0000404040404041C000002020204040808A3 +:104BC00008100000000E08080808080808080E0071 +:104BD00000040A00000000000000000000000000C7 +:104BE000000000000000003F000400000000000082 +:104BF0000000000000000000000C121C123C00002D +:104C000000000302020E1212120E0000000000004B +:104C1000001C1202021C000000001810101C1212CE +:104C2000123C000000000000000C121E021C0000DC +:104C300000003804041E0404041E000000000000EC +:104C4000003C120C021E221C00000302020E121273 +:104C5000123700000000040000060404040E0000E7 +:104C600000000800000C08080808080700000302FC +:104C7000023A0A0E1237000000000704040404047C +:104C8000041F000000000000000F1515151500009E +:104C900000000000000F1212123700000000000098 +:104CA000000C1212120C000000000000000F121283 +:104CB000120E020700000000001C1212121C103815 +:104CC00000000000001B06020207000000000000B8 +:104CD000001E020C101E000000000004040E04045C +:104CE0000418000000000000001B1212123C00001B +:104CF000000000000037120A0C0400000000000051 +:104D00000015150E0A0A000000000000001B0A042E +:104D10000A1B0000000000000037120A0C04040304 +:104D200000000000001E0804041E0000001808080F +:104D300008040808080818000808080808080808EF +:104D40000808080800060404040804040404060013 +:104D50000225180000000000000000006C6574745B +:104D60006572000064656661756C742075736572A8 +:104D70000073657456617200736574207661720009 +:104D8000757000646F776E007269676874006C6597 +:104D9000667400746162006261636B737061636565 +:104DA000006261636B73706163650064656C657458 +:104DB0006500656E74657200656E74657200686585 +:104DC0006C700073686F7720636F6D6D616E642027 +:104DD000696E666F0D0A68656C70205B636D645D5B +:104DE000007573657273006C69737420616C6C205C +:104DF0007573657200636D6473006C697374206110 +:104E00006C6C20636D640076617273006C697374FE +:104E100020616C6C20766172006B657973006C693F +:104E2000737420616C6C206B657900636C656172D2 +:104E300000636C65617220636F6E736F6C65000058 +:104E400064656661756C745461736B000D0A436F21 +:104E50006D6D616E64204C6973743A0D0A00000038 +:104E60000D0A566172204C6973743A0D0A000000F5 +:104E70000D0A55736572204C6973743A0D0A00006F +:104E80000D0A4B6579204C6973743A0D0A000000D5 +:104E9000436F6D6D616E64206E6F7420466F756E2A +:104EA000640D0A000D0A5761726E696E673A2043FD +:104EB0006F6D6D616E6420697320746F6F206C6F0D +:104EC0006E670D0A00000000206973206E6F742069 +:104ED00061207661720D0A0063616E27742073652C +:104EE000742072656164206F6E6C79207661720D3A +:104EF0000A00000063616E27742073657420706F70 +:104F0000696E7465720D0A000D0A205F2020202052 +:104F100020202020205F2020205F20202020202013 +:104F20002020202020202020202020205F20202042 +:104F3000202020202020205F205F200D0A7C207C64 +:104F4000202020205F5F5F7C207C5F7C207C5F20B6 +:104F50005F5F5F205F205F5F2020205F5F5F7C20BE +:104F60007C5F5F2020205F5F5F7C207C207C0D0ABF +:104F70007C207C2020202F205F205C205F5F7C2015 +:104F80005F5F2F205F205C20275F5F7C202F205FEA +:104F90005F7C20275F205C202F205F205C207C200E +:104FA0007C0D0A7C207C5F5F7C20205F5F2F207C53 +:104FB0005F7C207C7C20205F5F2F207C20202020B5 +:104FC0005C5F5F205C207C207C207C20205F5F2F4A +:104FD000207C207C0D0A7C5F5F5F5F5F5C5F5F5FB2 +:104FE0007C5C5F5F7C5C5F5F5C5F5F5F7C5F7C20A5 +:104FF0002020207C5F5F5F2F5F7C207C5F7C5C5F7C +:105000005F5F7C5F7C5F7C0D0A0D0A4275696C6492 +:105010003A20202020202020536570202039203283 +:105020003032352032333A33383A32300D0A566551 +:105030007273696F6E3A2020202020332E322E3476 +:105040000D0A436F707972696768743A20202028CE +:1050500063292032303230204C65747465720D0A39 +:10506000000000000D0A70617373776F7264206531 +:1050700072726F720D0A0000566172206E6F74209A +:10508000466F756E740D0A001B5B324B0D000000FD +:10509000434D442000000000564152200000000013 +:1050A0004B45592000000000636F6D6D616E6420F8 +:1050B00068656C70206F662000000000506C6561B0 +:1050C000736520696E7075742070617373776F7289 +:1050D000643A00004E4F4E45000000001B5B324A10 +:1050E0001B5B314800000000555345520000000092 +:1050F00040520108000000209C02000054080008F3 +:10510000CC5301089C02002054150100C88C0008F3 +:10511000CC53010800C0012000400000C88C0008EA +:10512000000800005C4D0108634D0108644D010852 +:1051300000210000714D01088DC30008784D010861 +:105140000009000000415B1B73C80008804D010886 +:105150000009000000425B1B5DB50008834D01089B +:105160000019000000435B1BE7C10008884D0108DF +:105170000019000000445B1BD3BE00088E4D0108DF +:105180000009000000000009B1C60008934D0108A5 +:1051900000190000000000086DB30008974D0108D9 +:1051A000001900000000007F6DB30008A14D010848 +:1051B000001900007E335B1B53B40008AB4D01089F +:1051C000001900000000000A6DB50008B24D01088A +:1051D000001900000000000D6DB50008B84D010871 +:1051E00000200000BE4D0108C1BB0008C34D0108EE +:1051F00000210000E14D010881C80008E74D0108C9 +:1052000000210000F54D010841B40008FA4D0108E5 +:1052100000210000074E010893C800080C4E010849 +:1052200000210000194E0108C1BE00081E4E0108F1 +:10523000002100002B4E0108FDB30008314E01088B +:105240008132104201035D24F41AAA0101181311DE +:10525000A61B08FD0413C044122016C00120C0C4C0 +:105260001C20C0E40C699CB11338E513080C120C27 +:10527000121812141318E71B0810C21A200C1398E6 +:10528000E91B0814081A3C041348EE1B08182212E4 +:1052900048124112901C010820221A80181C900A02 +:1052A0000130122032401C50220148121832301EA8 +:1052B000203401080A2032281EF84201080854321E +:1052C000101EE8480108066C720C139D6A1B08E565 +:1052D000041AF50413216B1B0861041A690C1AAD3A +:1052E00004131201140202021640830440571D02E7 +:1052F000010203B9071A040309041A031BE9095040 +:1053000019041AA104130D0A1B08310441130A06DB +:1053100032022A40FC134D65140849634C08976714 +:105320001C131D6414083D621B080114C11AC11826 +:105330001A7D041A09302A6D081B0243871125C003 +:105340003209041B01020B13052416100105240168 +:10535000100901042402020524061E010705820328 +:10536000ED1B0904BD320A2E0705010240072A8100 +:105370000724810182180A084F0108A44E01084C35 +:10538000041A60041A70041A80041A90041AF404AF +:105390001AD8041AC8041E78500108A8041ABC04BC +:1053A0001A64041ADC041A88041A90041A98041A5D +:1053B000E8041AA0041AD404E3222213E4E41B082C +:0C53C000EA0417C6E533B49D940200080F :040000050800018965 :00000001FF diff --git a/USB_DEVICE/App/usbd_cdc_if.c b/USB_DEVICE/App/usbd_cdc_if.c index 30f789d..2918f0b 100644 --- a/USB_DEVICE/App/usbd_cdc_if.c +++ b/USB_DEVICE/App/usbd_cdc_if.c @@ -35,56 +35,56 @@ /* USER CODE END PV */ /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @brief Usb device library. - * @{ - */ + * @brief Usb device library. + * @{ + */ /** @addtogroup USBD_CDC_IF - * @{ - */ + * @{ + */ /** @defgroup USBD_CDC_IF_Private_TypesDefinitions USBD_CDC_IF_Private_TypesDefinitions - * @brief Private types. - * @{ - */ + * @brief Private types. + * @{ + */ /* USER CODE BEGIN PRIVATE_TYPES */ /* USER CODE END PRIVATE_TYPES */ /** - * @} - */ + * @} + */ /** @defgroup USBD_CDC_IF_Private_Defines USBD_CDC_IF_Private_Defines - * @brief Private defines. - * @{ - */ + * @brief Private defines. + * @{ + */ /* USER CODE BEGIN PRIVATE_DEFINES */ /* USER CODE END PRIVATE_DEFINES */ /** - * @} - */ + * @} + */ /** @defgroup USBD_CDC_IF_Private_Macros USBD_CDC_IF_Private_Macros - * @brief Private macros. - * @{ - */ + * @brief Private macros. + * @{ + */ /* USER CODE BEGIN PRIVATE_MACRO */ /* USER CODE END PRIVATE_MACRO */ /** - * @} - */ + * @} + */ /** @defgroup USBD_CDC_IF_Private_Variables USBD_CDC_IF_Private_Variables - * @brief Private variables. - * @{ - */ + * @brief Private variables. + * @{ + */ /* Create buffer for reception and transmission */ /* It's up to user to redefine and/or remove those define */ /** Received data over USB are stored in this buffer */ @@ -98,13 +98,13 @@ uint8_t UserTxBufferFS[APP_TX_DATA_SIZE]; /* USER CODE END PRIVATE_VARIABLES */ /** - * @} - */ + * @} + */ /** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables - * @brief Public variables. - * @{ - */ + * @brief Public variables. + * @{ + */ extern USBD_HandleTypeDef hUsbDeviceFS; @@ -113,18 +113,18 @@ extern USBD_HandleTypeDef hUsbDeviceFS; /* USER CODE END EXPORTED_VARIABLES */ /** - * @} - */ + * @} + */ /** @defgroup USBD_CDC_IF_Private_FunctionPrototypes USBD_CDC_IF_Private_FunctionPrototypes - * @brief Private functions declaration. - * @{ - */ + * @brief Private functions declaration. + * @{ + */ static int8_t CDC_Init_FS(void); static int8_t CDC_DeInit_FS(void); -static int8_t CDC_Control_FS(uint8_t cmd, uint8_t *pbuf, uint16_t length); -static int8_t CDC_Receive_FS(uint8_t *pbuf, uint32_t *Len); +static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length); +static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len); static int8_t CDC_TransmitCplt_FS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum); /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ @@ -132,22 +132,23 @@ static int8_t CDC_TransmitCplt_FS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum); /* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */ /** - * @} - */ + * @} + */ USBD_CDC_ItfTypeDef USBD_Interface_fops_FS = - { - CDC_Init_FS, - CDC_DeInit_FS, - CDC_Control_FS, - CDC_Receive_FS, - CDC_TransmitCplt_FS}; +{ + CDC_Init_FS, + CDC_DeInit_FS, + CDC_Control_FS, + CDC_Receive_FS, + CDC_TransmitCplt_FS +}; /* Private functions ---------------------------------------------------------*/ /** - * @brief Initializes the CDC media low layer over the FS USB IP - * @retval USBD_OK if all operations are OK else USBD_FAIL - */ + * @brief Initializes the CDC media low layer over the FS USB IP + * @retval USBD_OK if all operations are OK else USBD_FAIL + */ static int8_t CDC_Init_FS(void) { /* USER CODE BEGIN 3 */ @@ -159,9 +160,9 @@ static int8_t CDC_Init_FS(void) } /** - * @brief DeInitializes the CDC media low layer - * @retval USBD_OK if all operations are OK else USBD_FAIL - */ + * @brief DeInitializes the CDC media low layer + * @retval USBD_OK if all operations are OK else USBD_FAIL + */ static int8_t CDC_DeInit_FS(void) { /* USER CODE BEGIN 4 */ @@ -170,13 +171,13 @@ static int8_t CDC_DeInit_FS(void) } /** - * @brief Manage the CDC class requests - * @param cmd: Command code - * @param pbuf: Buffer containing command data (request parameters) - * @param length: Number of data to be sent (in bytes) - * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL - */ -static int8_t CDC_Control_FS(uint8_t cmd, uint8_t *pbuf, uint16_t length) + * @brief Manage the CDC class requests + * @param cmd: Command code + * @param pbuf: Buffer containing command data (request parameters) + * @param length: Number of data to be sent (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) { /* USER CODE BEGIN 5 */ switch (cmd) @@ -243,21 +244,21 @@ static int8_t CDC_Control_FS(uint8_t cmd, uint8_t *pbuf, uint16_t length) } /** - * @brief Data received over USB OUT endpoint are sent over CDC interface - * through this function. - * - * @note - * This function will issue a NAK packet on any OUT packet received on - * USB endpoint until exiting this function. If you exit this function - * before transfer is complete on CDC interface (ie. using DMA controller) - * it will result in receiving more data while previous ones are still - * not sent. - * - * @param Buf: Buffer of data to be received - * @param Len: Number of data received (in bytes) - * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL - */ -static int8_t CDC_Receive_FS(uint8_t *Buf, uint32_t *Len) + * @brief Data received over USB OUT endpoint are sent over CDC interface + * through this function. + * + * @note + * This function will issue a NAK packet on any OUT packet received on + * USB endpoint until exiting this function. If you exit this function + * before transfer is complete on CDC interface (ie. using DMA controller) + * it will result in receiving more data while previous ones are still + * not sent. + * + * @param Buf: Buffer of data to be received + * @param Len: Number of data received (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ usb_receive(Buf, *Len); @@ -268,17 +269,17 @@ static int8_t CDC_Receive_FS(uint8_t *Buf, uint32_t *Len) } /** - * @brief CDC_Transmit_FS - * Data to send over USB IN endpoint are sent over CDC interface - * through this function. - * @note - * - * - * @param Buf: Buffer of data to be sent - * @param Len: Number of data to be sent (in bytes) - * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY - */ -uint8_t CDC_Transmit_FS(uint8_t *Buf, uint16_t Len) + * @brief CDC_Transmit_FS + * Data to send over USB IN endpoint are sent over CDC interface + * through this function. + * @note + * + * + * @param Buf: Buffer of data to be sent + * @param Len: Number of data to be sent (in bytes) + * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY + */ +uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) { uint8_t result = USBD_OK; /* USER CODE BEGIN 7 */ @@ -294,17 +295,17 @@ uint8_t CDC_Transmit_FS(uint8_t *Buf, uint16_t Len) } /** - * @brief CDC_TransmitCplt_FS - * Data transmitted callback - * - * @note - * This function is IN transfer complete callback used to inform user that - * the submitted Data is successfully sent over USB. - * - * @param Buf: Buffer of data to be received - * @param Len: Number of data received (in bytes) - * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL - */ + * @brief CDC_TransmitCplt_FS + * Data transmitted callback + * + * @note + * This function is IN transfer complete callback used to inform user that + * the submitted Data is successfully sent over USB. + * + * @param Buf: Buffer of data to be received + * @param Len: Number of data received (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum) { uint8_t result = USBD_OK; @@ -320,8 +321,8 @@ static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum) #include void usb_printf(const char *format, ...) { - va_list args; // va_list型变量,指向参数的指针 - uint32_t length; // 数据的长度 + va_list args; // va_list型变?,指向参数的指? + uint32_t length; // 数据的长? uint16_t USB_TimeOut; // 超时判断时间 uint32_t Tickstart; // 计时起始时间 @@ -330,16 +331,16 @@ void usb_printf(const char *format, ...) // 向字符串打印指定格式的数据,并获取最终的数据长度 length = vsnprintf((char *)UserTxBufferFS, APP_TX_DATA_SIZE, (char *)format, args); - va_end(args); // 结束可变参数的读取 + va_end(args); // 结束可变参数的读? - USB_TimeOut = 3; // 超时等待时间,这里取3ms,实测单次发送2K的数据将近2ms,用户可以根据实际需求进行调整 + USB_TimeOut = 3; // 超时等待时间,这里取3ms,实测单次发?2K的数据将?2ms,用户可以根据实际需求进行调? - if (hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED) // 判断USB是否处于连接状态 + if (hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED) // 判断USB是否处于连接状?? { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)hUsbDeviceFS.pClassData; // 获取相应的CDC状态 + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)hUsbDeviceFS.pClassData; // 获取相应的CDC状?? Tickstart = HAL_GetTick(); // 获取当前时间 - while (hcdc->TxState != 0) // 等待发送完成 + while (hcdc->TxState != 0) // 等待发?完? { if ((HAL_GetTick() - Tickstart) > USB_TimeOut) // 达到超时时间 { @@ -348,7 +349,7 @@ void usb_printf(const char *format, ...) } } - CDC_Transmit_FS(UserTxBufferFS, length); // 调用 USB CDC函数发送数据 + CDC_Transmit_FS(UserTxBufferFS, length); // 调用 USB CDC函数发?数? } void usb_receive(uint8_t *pbuf, uint32_t len) @@ -358,9 +359,9 @@ void usb_receive(uint8_t *pbuf, uint32_t len) /* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ diff --git a/User/application/app.c b/User/application/app.c index 94c55fc..3df2449 100644 --- a/User/application/app.c +++ b/User/application/app.c @@ -1,7 +1,10 @@ #include "app.h" #include "board.h" #include "os.h" +#include "shell_port.h" + static TaskHandle_t business_task_handle = NULL; +static TaskHandle_t shell_task_handle = NULL; void business_task(void *pvParameters) { @@ -18,6 +21,7 @@ void business_task(void *pvParameters) void app_init(void) { + userShellInit(); // 初始化shell // 创建任务 xTaskCreate((TaskFunction_t)business_task, // 任务入口函数 (const char *)"business_task", // 任务名字 @@ -25,4 +29,12 @@ void app_init(void) (void *)NULL, // 任务入口函数参数 (UBaseType_t)1, // 任务优先级 (TaskHandle_t *)&business_task_handle); // 任务句柄 + + extern Shell shell; + xTaskCreate((TaskFunction_t)shellTask, // 任务入口函数 + (const char *)"shell_task", // 任务名字 + (uint16_t)1024, // 任务栈大小 + (void *)&shell, // 任务入口函数参数(传递 shell 对象指针) + (UBaseType_t)1, // 任务优先级 + (TaskHandle_t *)&shell_task_handle); // 任务句柄 } diff --git a/User/system/letter_shell/shell.c b/User/system/letter_shell/shell.c new file mode 100644 index 0000000..f956266 --- /dev/null +++ b/User/system/letter_shell/shell.c @@ -0,0 +1,2059 @@ +/** + * @file shell.c + * @author Letter (NevermindZZT@gmail.com) + * @version 3.0.0 + * @date 2019-12-30 + * + * @copyright (c) 2020 Letter + * + */ + +#include "shell.h" +#include "shell_cfg.h" +#include "string.h" +#include "stdio.h" +#include "stdarg.h" +#include "shell_ext.h" + + +#if SHELL_USING_CMD_EXPORT == 1 +/** + * @brief 默认用户 + */ +const char shellCmdDefaultUser[] = SHELL_DEFAULT_USER; +const char shellPasswordDefaultUser[] = SHELL_DEFAULT_USER_PASSWORD; +const char shellDesDefaultUser[] = "default user"; +SHELL_USED const ShellCommand shellUserDefault SHELL_SECTION("shellCommand") = +{ + .attr.value = SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_USER), + .data.user.name = shellCmdDefaultUser, + .data.user.password = shellPasswordDefaultUser, + .data.user.desc = shellDesDefaultUser +}; +#endif + +#if SHELL_USING_CMD_EXPORT == 1 + #if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 6000000) + extern const unsigned int shellCommand$$Base; + extern const unsigned int shellCommand$$Limit; + #elif defined(__ICCARM__) || defined(__ICCRX__) + #pragma section="shellCommand" + #elif defined(__GNUC__) + extern const unsigned int _shell_command_start; + extern const unsigned int _shell_command_end; + #endif +#else + extern const ShellCommand shellCommandList[]; + extern const unsigned short shellCommandCount; +#endif + + +/** + * @brief shell 常量文本索引 + */ +enum +{ +#if SHELL_SHOW_INFO == 1 + SHELL_TEXT_INFO, /**< shell信息 */ +#endif + SHELL_TEXT_CMD_TOO_LONG, /**< 命令过长 */ + SHELL_TEXT_CMD_LIST, /**< 可执行命令列表标题 */ + SHELL_TEXT_VAR_LIST, /**< 变量列表标题 */ + SHELL_TEXT_USER_LIST, /**< 用户列表标题 */ + SHELL_TEXT_KEY_LIST, /**< 按键列表标题 */ + SHELL_TEXT_CMD_NOT_FOUND, /**< 命令未找到 */ + SHELL_TEXT_POINT_CANNOT_MODIFY, /**< 指针变量不允许修改 */ + SHELL_TEXT_VAR_READ_ONLY_CANNOT_MODIFY, /**< 只读变量不允许修改 */ + SHELL_TEXT_NOT_VAR, /**< 命令不是变量 */ + SHELL_TEXT_VAR_NOT_FOUND, /**< 变量未找到 */ + SHELL_TEXT_HELP_HEADER, /**< help头 */ + SHELL_TEXT_PASSWORD_HINT, /**< 密码输入提示 */ + SHELL_TEXT_PASSWORD_ERROR, /**< 密码错误 */ + SHELL_TEXT_CLEAR_CONSOLE, /**< 清空控制台 */ + SHELL_TEXT_CLEAR_LINE, /**< 清空当前行 */ + SHELL_TEXT_TYPE_CMD, /**< 命令类型 */ + SHELL_TEXT_TYPE_VAR, /**< 变量类型 */ + SHELL_TEXT_TYPE_USER, /**< 用户类型 */ + SHELL_TEXT_TYPE_KEY, /**< 按键类型 */ + SHELL_TEXT_TYPE_NONE, /**< 非法类型 */ +#if SHELL_EXEC_UNDEF_FUNC == 1 + SHELL_TEXT_PARAM_ERROR, /**< 参数错误 */ +#endif +}; + + +static const char *shellText[] = +{ +#if SHELL_SHOW_INFO == 1 + [SHELL_TEXT_INFO] = + "\r\n" + " _ _ _ _ _ _ \r\n" + "| | ___| |_| |_ ___ _ __ ___| |__ ___| | |\r\n" + "| | / _ \\ __| __/ _ \\ '__| / __| '_ \\ / _ \\ | |\r\n" + "| |__| __/ |_| || __/ | \\__ \\ | | | __/ | |\r\n" + "|_____\\___|\\__|\\__\\___|_| |___/_| |_|\\___|_|_|\r\n" + "\r\n" + "Build: "__DATE__" "__TIME__"\r\n" + "Version: "SHELL_VERSION"\r\n" + "Copyright: (c) 2020 Letter\r\n", +#endif + [SHELL_TEXT_CMD_TOO_LONG] = + "\r\nWarning: Command is too long\r\n", + [SHELL_TEXT_CMD_LIST] = + "\r\nCommand List:\r\n", + [SHELL_TEXT_VAR_LIST] = + "\r\nVar List:\r\n", + [SHELL_TEXT_USER_LIST] = + "\r\nUser List:\r\n", + [SHELL_TEXT_KEY_LIST] = + "\r\nKey List:\r\n", + [SHELL_TEXT_CMD_NOT_FOUND] = + "Command not Found\r\n", + [SHELL_TEXT_POINT_CANNOT_MODIFY] = + "can't set pointer\r\n", + [SHELL_TEXT_VAR_READ_ONLY_CANNOT_MODIFY] = + "can't set read only var\r\n", + [SHELL_TEXT_NOT_VAR] = + " is not a var\r\n", + [SHELL_TEXT_VAR_NOT_FOUND] = + "Var not Fount\r\n", + [SHELL_TEXT_HELP_HEADER] = + "command help of ", + [SHELL_TEXT_PASSWORD_HINT] = + "Please input password:", + [SHELL_TEXT_PASSWORD_ERROR] = + "\r\npassword error\r\n", + [SHELL_TEXT_CLEAR_CONSOLE] = + "\033[2J\033[1H", + [SHELL_TEXT_CLEAR_LINE] = + "\033[2K\r", + [SHELL_TEXT_TYPE_CMD] = + "CMD ", + [SHELL_TEXT_TYPE_VAR] = + "VAR ", + [SHELL_TEXT_TYPE_USER] = + "USER", + [SHELL_TEXT_TYPE_KEY] = + "KEY ", + [SHELL_TEXT_TYPE_NONE] = + "NONE", +#if SHELL_EXEC_UNDEF_FUNC == 1 + [SHELL_TEXT_PARAM_ERROR] = + "Parameter error\r\n", +#endif +}; + + +unsigned char pairedChars[][2] = { + {'\"', '\"'}, +#if SHELL_SUPPORT_ARRAY_PARAM == 1 + {'[', ']'}, +#endif /** SHELL_SUPPORT_ARRAY_PARAM == 1 */ + // {'(', ')'}, + // {'{', '}'}, + // {'<', '>'}, + // {'\'', '\''}, + // {'`', '`'}, +}; + + +/** + * @brief shell对象表 + */ +static Shell *shellList[SHELL_MAX_NUMBER] = {NULL}; + + +static void shellAdd(Shell *shell); +static void shellWritePrompt(Shell *shell, unsigned char newline); +static void shellWriteReturnValue(Shell *shell, int value); +static int shellShowVar(Shell *shell, ShellCommand *command); +void shellSetUser(Shell *shell, const ShellCommand *user); +ShellCommand* shellSeekCommand(Shell *shell, + const char *cmd, + ShellCommand *base, + unsigned short compareLength); +static void shellWriteCommandHelp(Shell *shell, char *cmd); + +/** + * @brief shell 初始化 + * + * @param shell shell对象 + */ +void shellInit(Shell *shell, char *buffer, unsigned short size) +{ + shell->parser.length = 0; + shell->parser.cursor = 0; + shell->info.user = NULL; + shell->status.isChecked = 1; + + shell->parser.buffer = buffer; + shell->parser.bufferSize = size / (SHELL_HISTORY_MAX_NUMBER + 1); + +#if SHELL_HISTORY_MAX_NUMBER > 0 + shell->history.offset = 0; + shell->history.number = 0; + shell->history.record = 0; + for (short i = 0; i < SHELL_HISTORY_MAX_NUMBER; i++) + { + shell->history.item[i] = buffer + shell->parser.bufferSize * (i + 1); + } +#endif /** SHELL_HISTORY_MAX_NUMBER > 0 */ + +#if SHELL_USING_CMD_EXPORT == 1 + #if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 6000000) + shell->commandList.base = (ShellCommand *)(&shellCommand$$Base); + shell->commandList.count = ((size_t)(&shellCommand$$Limit) + - (size_t)(&shellCommand$$Base)) + / sizeof(ShellCommand); + + #elif defined(__ICCARM__) || defined(__ICCRX__) + shell->commandList.base = (ShellCommand *)(__section_begin("shellCommand")); + shell->commandList.count = ((size_t)(__section_end("shellCommand")) + - (size_t)(__section_begin("shellCommand"))) + / sizeof(ShellCommand); + #elif defined(__GNUC__) + shell->commandList.base = (ShellCommand *)(&_shell_command_start); + shell->commandList.count = ((size_t)(&_shell_command_end) + - (size_t)(&_shell_command_start)) + / sizeof(ShellCommand); + #else + #error not supported compiler, please use command table mode + #endif +#else + shell->commandList.base = (ShellCommand *)shellCommandList; + shell->commandList.count = shellCommandCount; +#endif + + shellAdd(shell); + + shellSetUser(shell, shellSeekCommand(shell, + SHELL_DEFAULT_USER, + shell->commandList.base, + 0)); + shellWritePrompt(shell, 1); +} + + +/** + * @brief 添加shell + * + * @param shell shell对象 + */ +static void shellAdd(Shell *shell) +{ + for (short i = 0; i < SHELL_MAX_NUMBER; i++) + { + if (shellList[i] == NULL) + { + shellList[i] = shell; + return; + } + } +} + +/** + * @brief 移除shell + * + * @param shell shell对象 + * + */ +void shellRemove(Shell *shell) +{ + for (short i = 0; i < SHELL_MAX_NUMBER; i++) + { + if (shellList[i] == shell) + { + shellList[i] = NULL; + return; + } + } +} + +/** + * @brief 获取当前活动shell + * + * @return Shell* 当前活动shell对象 + */ +Shell* shellGetCurrent(void) +{ + for (short i = 0; i < SHELL_MAX_NUMBER; i++) + { + if (shellList[i] && shellList[i]->status.isActive) + { + return shellList[i]; + } + } + return NULL; +} + + +/** + * @brief shell写字符 + * + * @param shell shell对象 + * @param data 字符数据 + */ +static void shellWriteByte(Shell *shell, char data) +{ + shell->write(&data, 1); +} + + +/** + * @brief shell 写字符串 + * + * @param shell shell对象 + * @param string 字符串数据 + * + * @return unsigned short 写入字符的数量 + */ +unsigned short shellWriteString(Shell *shell, const char *string) +{ + unsigned short count = 0; + const char *p = string; + SHELL_ASSERT(shell->write, return 0); + while(*p++) + { + count ++; + } + return shell->write((char *)string, count); +} + + +/** + * @brief shell 写命令描述字符串 + * + * @param shell shell对象 + * @param string 字符串数据 + * + * @return unsigned short 写入字符的数量 + */ +static unsigned short shellWriteCommandDesc(Shell *shell, const char *string) +{ + unsigned short count = 0; + const char *p = string; + SHELL_ASSERT(shell->write, return 0); + while (*p && *p != '\r' && *p != '\n') + { + p++; + count++; + } + + if (count > 36) + { + shell->write((char *)string, 36); + shell->write("...", 3); + } + else + { + shell->write((char *)string, count); + } + return count > 36 ? 36 : 39; +} + + +/** + * @brief shell写命令提示符 + * + * @param shell shell对象 + * @param newline 新行 + * + */ +static void shellWritePrompt(Shell *shell, unsigned char newline) +{ + if (shell->status.isChecked) + { + if (newline) + { + shellWriteString(shell, "\r\n"); + } + shellWriteString(shell, shell->info.user->data.user.name); + shellWriteString(shell, ":"); + shellWriteString(shell, shell->info.path ? shell->info.path : "/"); + shellWriteString(shell, "$ "); + } + else + { + shellWriteString(shell, shellText[SHELL_TEXT_PASSWORD_HINT]); + } +} + + +#if SHELL_PRINT_BUFFER > 0 +/** + * @brief shell格式化输出 + * + * @param shell shell对象 + * @param fmt 格式化字符串 + * @param ... 参数 + */ +void shellPrint(Shell *shell, const char *fmt, ...) +{ + char buffer[SHELL_PRINT_BUFFER]; + va_list vargs; + int len; + + SHELL_ASSERT(shell, return); + + va_start(vargs, fmt); + len = vsnprintf(buffer, SHELL_PRINT_BUFFER, fmt, vargs); + va_end(vargs); + if (len > SHELL_PRINT_BUFFER) + { + len = SHELL_PRINT_BUFFER; + } + shell->write(buffer, len); +} +#endif + + +#if SHELL_SCAN_BUFFER > 0 +/** + * @brief shell格式化输入 + * + * @param shell shell对象 + * @param fmt 格式化字符串 + * @param ... 参数 + */ +void shellScan(Shell *shell, char *fmt, ...) +{ + char buffer[SHELL_SCAN_BUFFER]; + va_list vargs; + short index = 0; + + SHELL_ASSERT(shell, return); + + if (shell->read) + { + do { + if (shell->read(&buffer[index], 1) == 1) + { + shell->write(&buffer[index], 1); + index++; + } + } while (buffer[index -1] != '\r' && buffer[index -1] != '\n' && index < SHELL_SCAN_BUFFER); + shellWriteString(shell, "\r\n"); + buffer[index] = '\0'; + } + + va_start(vargs, fmt); + vsscanf(buffer, fmt, vargs); + va_end(vargs); +} +#endif + + +/** + * @brief shell 检查命令权限 + * + * @param shell shell对象 + * @param command ShellCommand + * + * @return signed char 0 当前用户具有该命令权限 + * @return signec char -1 当前用户不具有该命令权限 + */ +signed char shellCheckPermission(Shell *shell, ShellCommand *command) +{ + return ((!command->attr.attrs.permission + || command->attr.attrs.type == SHELL_TYPE_USER + || (shell->info.user + && (command->attr.attrs.permission + & shell->info.user->attr.attrs.permission))) + && (shell->status.isChecked + || command->attr.attrs.enableUnchecked)) + ? 0 : -1; +} + + +/** + * @brief int转16进制字符串 + * + * @param value 数值 + * @param buffer 缓冲 + * + * @return signed char 转换后有效数据长度 + */ +signed char shellToHex(unsigned int value, char *buffer) +{ + char byte; + unsigned char i = 8; + buffer[8] = 0; + while (value) + { + byte = value & 0x0000000F; + buffer[--i] = (byte > 9) ? (byte + 87) : (byte + 48); + value >>= 4; + } + return 8 - i; +} + + +/** +* @brief int转10进制字符串 + * + * @param value 数值 + * @param buffer 缓冲 + * + * @return signed char 转换后有效数据长度 + */ +signed char shellToDec(int value, char *buffer) +{ + unsigned char i = 11; + int v = value; + if (value < 0) + { + v = -value; + } + buffer[11] = 0; + while (v) + { + buffer[--i] = v % 10 + 48; + v /= 10; + } + if (value < 0) + { + buffer[--i] = '-'; + } + if (value == 0) { + buffer[--i] = '0'; + } + return 11 - i; +} + + +/** + * @brief shell字符串复制 + * + * @param dest 目标字符串 + * @param src 源字符串 + * @return unsigned short 字符串长度 + */ +static unsigned short shellStringCopy(char *dest, char* src) +{ + unsigned short count = 0; + while (*(src + count)) + { + *(dest + count) = *(src + count); + count++; + } + *(dest + count) = 0; + return count; +} + + +/** + * @brief shell字符串比较 + * + * @param dest 目标字符串 + * @param src 源字符串 + * @return unsigned short 匹配长度 + */ +static unsigned short shellStringCompare(char* dest, char *src) +{ + unsigned short match = 0; + unsigned short i = 0; + + while (*(dest +i) && *(src + i)) + { + if (*(dest + i) != *(src +i)) + { + break; + } + match ++; + i++; + } + return match; +} + + +/** + * @brief shell获取命令名 + * + * @param command 命令 + * @return const char* 命令名 + */ +static const char* shellGetCommandName(ShellCommand *command) +{ + static char buffer[9]; + for (unsigned char i = 0; i < 9; i++) + { + buffer[i] = '0'; + } + if (command->attr.attrs.type <= SHELL_TYPE_CMD_FUNC) + { + return command->data.cmd.name; + } + else if (command->attr.attrs.type <= SHELL_TYPE_VAR_NODE) + { + return command->data.var.name; + } + else if (command->attr.attrs.type <= SHELL_TYPE_USER) + { + return command->data.user.name; + } +#if SHELL_USING_FUNC_SIGNATURE == 1 + else if (command->attr.attrs.type == SHELL_TYPE_PARAM_PARSER) + { + return command->data.paramParser.type; + } +#endif + else + { + shellToHex(command->data.key.value, buffer); + return buffer; + } +} + + +/** + * @brief shell获取命令描述 + * + * @param command 命令 + * @return const char* 命令描述 + */ +static const char* shellGetCommandDesc(ShellCommand *command) +{ + if (command->attr.attrs.type <= SHELL_TYPE_CMD_FUNC) + { + return command->data.cmd.desc; + } + else if (command->attr.attrs.type <= SHELL_TYPE_VAR_NODE) + { + return command->data.var.desc; + } + else if (command->attr.attrs.type <= SHELL_TYPE_USER) + { + return command->data.user.desc; + } + else + { + return command->data.key.desc; + } +} + +/** + * @brief shell 列出命令条目 + * + * @param shell shell对象 + * @param item 命令条目 + */ +void shellListItem(Shell *shell, ShellCommand *item) +{ + short spaceLength; + + spaceLength = 22 - shellWriteString(shell, shellGetCommandName(item)); + spaceLength = (spaceLength > 0) ? spaceLength : 4; + do { + shellWriteByte(shell, ' '); + } while (--spaceLength); + if (item->attr.attrs.type <= SHELL_TYPE_CMD_FUNC) + { + shellWriteString(shell, shellText[SHELL_TEXT_TYPE_CMD]); + } + else if (item->attr.attrs.type <= SHELL_TYPE_VAR_NODE) + { + shellWriteString(shell, shellText[SHELL_TEXT_TYPE_VAR]); + } + else if (item->attr.attrs.type <= SHELL_TYPE_USER) + { + shellWriteString(shell, shellText[SHELL_TEXT_TYPE_USER]); + } + else if (item->attr.attrs.type <= SHELL_TYPE_KEY) + { + shellWriteString(shell, shellText[SHELL_TEXT_TYPE_KEY]); + } + else + { + shellWriteString(shell, shellText[SHELL_TEXT_TYPE_NONE]); + } +#if SHELL_HELP_SHOW_PERMISSION == 1 + shellWriteString(shell, " "); + for (signed char i = 7; i >= 0; i--) + { + shellWriteByte(shell, item->attr.attrs.permission & (1 << i) ? 'x' : '-'); + } +#endif + shellWriteString(shell, " "); + shellWriteCommandDesc(shell, shellGetCommandDesc(item)); + shellWriteString(shell, "\r\n"); +} + + +/** + * @brief shell列出可执行命令 + * + * @param shell shell对象 + */ +void shellListCommand(Shell *shell) +{ + ShellCommand *base = (ShellCommand *)shell->commandList.base; + shellWriteString(shell, shellText[SHELL_TEXT_CMD_LIST]); + for (short i = 0; i < shell->commandList.count; i++) + { + if (base[i].attr.attrs.type <= SHELL_TYPE_CMD_FUNC + && shellCheckPermission(shell, &base[i]) == 0) + { + shellListItem(shell, &base[i]); + } + } +} + + +/** + * @brief shell列出变量 + * + * @param shell shell对象 + */ +void shellListVar(Shell *shell) +{ + ShellCommand *base = (ShellCommand *)shell->commandList.base; + shellWriteString(shell, shellText[SHELL_TEXT_VAR_LIST]); + for (short i = 0; i < shell->commandList.count; i++) + { + if (base[i].attr.attrs.type > SHELL_TYPE_CMD_FUNC + && base[i].attr.attrs.type <= SHELL_TYPE_VAR_NODE + && shellCheckPermission(shell, &base[i]) == 0) + { + shellListItem(shell, &base[i]); + } + } +} + + +/** + * @brief shell列出用户 + * + * @param shell shell对象 + */ +void shellListUser(Shell *shell) +{ + ShellCommand *base = (ShellCommand *)shell->commandList.base; + shellWriteString(shell, shellText[SHELL_TEXT_USER_LIST]); + for (short i = 0; i < shell->commandList.count; i++) + { + if (base[i].attr.attrs.type > SHELL_TYPE_VAR_NODE + && base[i].attr.attrs.type <= SHELL_TYPE_USER + && shellCheckPermission(shell, &base[i]) == 0) + { + shellListItem(shell, &base[i]); + } + } +} + + +/** + * @brief shell列出按键 + * + * @param shell shell对象 + */ +void shellListKey(Shell *shell) +{ + ShellCommand *base = (ShellCommand *)shell->commandList.base; + shellWriteString(shell, shellText[SHELL_TEXT_KEY_LIST]); + for (short i = 0; i < shell->commandList.count; i++) + { + if (base[i].attr.attrs.type > SHELL_TYPE_USER + && base[i].attr.attrs.type <= SHELL_TYPE_KEY + && shellCheckPermission(shell, &base[i]) == 0) + { + shellListItem(shell, &base[i]); + } + } +} + + +/** + * @brief shell列出所有命令 + * + * @param shell shell对象 + */ +void shellListAll(Shell *shell) +{ +#if SHELL_HELP_LIST_USER == 1 + shellListUser(shell); +#endif + shellListCommand(shell); +#if SHELL_HELP_LIST_VAR == 1 + shellListVar(shell); +#endif +#if SHELL_HELP_LIST_KEY == 1 + shellListKey(shell); +#endif +} + + +/** + * @brief shell删除命令行数据 + * + * @param shell shell对象 + * @param length 删除长度 + */ +void shellDeleteCommandLine(Shell *shell, unsigned char length) +{ + while (length--) + { + shellWriteString(shell, "\b \b"); + } +} + + +/** + * @brief shell 清空命令行输入 + * + * @param shell shell对象 + */ +void shellClearCommandLine(Shell *shell) +{ + for (short i = shell->parser.length - shell->parser.cursor; i > 0; i--) + { + shellWriteByte(shell, ' '); + } + shellDeleteCommandLine(shell, shell->parser.length); +} + + +/** + * @brief shell插入一个字符到光标位置 + * + * @param shell shell对象 + * @param data 字符数据 + */ +void shellInsertByte(Shell *shell, char data) +{ + /* 判断输入数据是否过长 */ + if (shell->parser.length >= shell->parser.bufferSize - 1) + { + shellWriteString(shell, shellText[SHELL_TEXT_CMD_TOO_LONG]); + shellWritePrompt(shell, 1); + shellWriteString(shell, shell->parser.buffer); + return; + } + + /* 插入数据 */ + if (shell->parser.cursor == shell->parser.length) + { + shell->parser.buffer[shell->parser.length++] = data; + shell->parser.buffer[shell->parser.length] = 0; + shell->parser.cursor++; + shellWriteByte(shell, shell->status.isChecked ? data : '*'); + } + else if (shell->parser.cursor < shell->parser.length) + { + for (short i = shell->parser.length - shell->parser.cursor; i > 0; i--) + { + shell->parser.buffer[shell->parser.cursor + i] = + shell->parser.buffer[shell->parser.cursor + i - 1]; + } + shell->parser.buffer[shell->parser.cursor++] = data; + shell->parser.buffer[++shell->parser.length] = 0; + for (short i = shell->parser.cursor - 1; i < shell->parser.length; i++) + { + shellWriteByte(shell, + shell->status.isChecked ? shell->parser.buffer[i] : '*'); + } + for (short i = shell->parser.length - shell->parser.cursor; i > 0; i--) + { + shellWriteByte(shell, '\b'); + } + } +} + + +/** + * @brief shell 删除字节 + * + * @param shell shell对象 + * @param direction 删除方向 {@code 1}删除光标前字符 {@code -1}删除光标处字符 + */ +void shellDeleteByte(Shell *shell, signed char direction) +{ + char offset = (direction == -1) ? 1 : 0; + + if ((shell->parser.cursor == 0 && direction == 1) + || (shell->parser.cursor == shell->parser.length && direction == -1)) + { + return; + } + if (shell->parser.cursor == shell->parser.length && direction == 1) + { + shell->parser.cursor--; + shell->parser.length--; + shell->parser.buffer[shell->parser.length] = 0; + shellDeleteCommandLine(shell, 1); + } + else + { + for (short i = offset; i < shell->parser.length - shell->parser.cursor; i++) + { + shell->parser.buffer[shell->parser.cursor + i - 1] = + shell->parser.buffer[shell->parser.cursor + i]; + } + shell->parser.length--; + if (!offset) + { + shell->parser.cursor--; + shellWriteByte(shell, '\b'); + } + shell->parser.buffer[shell->parser.length] = 0; + for (short i = shell->parser.cursor; i < shell->parser.length; i++) + { + shellWriteByte(shell, shell->parser.buffer[i]); + } + shellWriteByte(shell, ' '); + for (short i = shell->parser.length - shell->parser.cursor + 1; i > 0; i--) + { + shellWriteByte(shell, '\b'); + } + } +} + + +/** + * @brief shell 字符串分割 + * + * @param string 字符串 + * @param array 分割后保存的字符串数组 + * @param splitKey 分隔符 + * @param maxNum 最大分割数量 + * + * @return int 分割得到的字串数量 + */ +int shellSplit(char *string, unsigned short strLen, char *array[], char splitKey, short maxNum) +{ + unsigned char record = 1; + unsigned char pairedLeft[16] = {0}; + unsigned char pariedCount = 0; + int count = 0; + + for (short i = 0; i < maxNum; i++) + { + array[i] = NULL; + } + + for (unsigned short i = 0; i < strLen; i++) + { + if (pariedCount == 0) + { + if (string[i] != splitKey && record == 1 && count < maxNum) + { + array[count++] = &(string[i]); + record = 0; + } + else if ((string[i] == splitKey || string[i] == ' ') && record == 0) + { + string[i] = 0; + if (string[i + 1] != ' ') + { + record = 1; + } + continue; + } + } + + for (unsigned char j = 0; j < sizeof(pairedChars) / 2; j++) + { + if (pariedCount > 0 + && string[i] == pairedChars[j][1] + && pairedLeft[pariedCount - 1] == pairedChars[j][0]) + { + --pariedCount; + break; + } + else if (string[i] == pairedChars[j][0]) + { + pairedLeft[pariedCount++] = pairedChars[j][0]; + pariedCount &= 0x0F; + break; + } + } + + if (string[i] == '\\' && string[i + 1] != 0) + { + i++; + } + } + return count; +} + + +/** + * @brief shell 解析参数 + * + * @param shell shell对象 + */ +static void shellParserParam(Shell *shell) +{ + shell->parser.paramCount = + shellSplit(shell->parser.buffer, shell->parser.length, + shell->parser.param, ' ', SHELL_PARAMETER_MAX_NUMBER); +} + + +/** + * @brief shell去除字符串参数头尾的双引号 + * + * @param shell shell对象 + */ +static void shellRemoveParamQuotes(Shell *shell) +{ + unsigned short paramLength; + for (unsigned short i = 0; i < shell->parser.paramCount; i++) + { + if (shell->parser.param[i][0] == '\"') + { + shell->parser.param[i][0] = 0; + shell->parser.param[i] = &shell->parser.param[i][1]; + } + paramLength = strlen(shell->parser.param[i]); + if (shell->parser.param[i][paramLength - 1] == '\"') + { + shell->parser.param[i][paramLength - 1] = 0; + } + } +} + + +/** + * @brief shell匹配命令 + * + * @param shell shell对象 + * @param cmd 命令 + * @param base 匹配命令表基址 + * @param compareLength 匹配字符串长度 + * @return ShellCommand* 匹配到的命令 + */ +ShellCommand* shellSeekCommand(Shell *shell, + const char *cmd, + ShellCommand *base, + unsigned short compareLength) +{ + const char *name; + unsigned short count = shell->commandList.count - + ((size_t)base - (size_t)shell->commandList.base) / sizeof(ShellCommand); + for (unsigned short i = 0; i < count; i++) + { + if (base[i].attr.attrs.type == SHELL_TYPE_KEY + || shellCheckPermission(shell, &base[i]) != 0) + { + continue; + } + name = shellGetCommandName(&base[i]); + if (!compareLength) + { + if (strcmp(cmd, name) == 0) + { + return &base[i]; + } + } + else + { + if (strncmp(cmd, name, compareLength) == 0) + { + return &base[i]; + } + } + } + return NULL; +} + + +/** + * @brief shell 获取变量值 + * + * @param shell shell对象 + * @param command 命令 + * @return int 变量值 + */ +int shellGetVarValue(Shell *shell, ShellCommand *command) +{ + int value = 0; + switch (command->attr.attrs.type) + { + case SHELL_TYPE_VAR_INT: + value = *((int *)(command->data.var.value)); + break; + case SHELL_TYPE_VAR_SHORT: + value = *((short *)(command->data.var.value)); + break; + case SHELL_TYPE_VAR_CHAR: + value = *((char *)(command->data.var.value)); + break; + case SHELL_TYPE_VAR_STRING: + case SHELL_TYPE_VAR_POINT: + value = (size_t)(command->data.var.value); + break; + case SHELL_TYPE_VAR_NODE: { + int (*func)(void *) = ((ShellNodeVarAttr *)command->data.var.value)->get; + value = func ? func(((ShellNodeVarAttr *)command->data.var.value)->var) : 0; + break; + } + default: + break; + } + return value; +} + + +/** + * @brief shell设置变量值 + * + * @param shell shell对象 + * @param command 命令 + * @param value 值 + * @return int 返回变量值 + */ +int shellSetVarValue(Shell *shell, ShellCommand *command, int value) +{ + if (command->attr.attrs.readOnly) + { + shellWriteString(shell, shellText[SHELL_TEXT_VAR_READ_ONLY_CANNOT_MODIFY]); + } + else + { + switch (command->attr.attrs.type) + { + case SHELL_TYPE_VAR_INT: + *((int *)(command->data.var.value)) = value; + break; + case SHELL_TYPE_VAR_SHORT: + *((short *)(command->data.var.value)) = value; + break; + case SHELL_TYPE_VAR_CHAR: + *((char *)(command->data.var.value)) = value; + break; + case SHELL_TYPE_VAR_STRING: + shellStringCopy(((char *)(command->data.var.value)), (char *) (size_t) value); + break; + case SHELL_TYPE_VAR_POINT: + shellWriteString(shell, shellText[SHELL_TEXT_POINT_CANNOT_MODIFY]); + break; + case SHELL_TYPE_VAR_NODE: + if (((ShellNodeVarAttr *)command->data.var.value)->set) + { + if (((ShellNodeVarAttr *)command->data.var.value)->var) + { + int (*func)(void *, int) = ((ShellNodeVarAttr *)command->data.var.value)->set; + func(((ShellNodeVarAttr *)command->data.var.value)->var, value); + } + else + { + int (*func)(int) = ((ShellNodeVarAttr *)command->data.var.value)->set; + func(value); + } + } + break; + default: + break; + } + } + return shellShowVar(shell, command); +} + + +/** + * @brief shell变量输出 + * + * @param shell shell对象 + * @param command 命令 + * @return int 返回变量值 + */ +static int shellShowVar(Shell *shell, ShellCommand *command) +{ + char buffer[12] = "00000000000"; + int value = shellGetVarValue(shell, command); + + shellWriteString(shell, command->data.var.name); + shellWriteString(shell, " = "); + + switch (command->attr.attrs.type) + { + case SHELL_TYPE_VAR_STRING: + shellWriteString(shell, "\""); + shellWriteString(shell, (char *) (size_t) value); + shellWriteString(shell, "\""); + break; + // case SHELL_TYPE_VAR_INT: + // case SHELL_TYPE_VAR_SHORT: + // case SHELL_TYPE_VAR_CHAR: + // case SHELL_TYPE_VAR_POINT: + default: + shellWriteString(shell, &buffer[11 - shellToDec(value, buffer)]); + shellWriteString(shell, ", 0x"); + for (short i = 0; i < 11; i++) + { + buffer[i] = '0'; + } + shellToHex(value, buffer); + shellWriteString(shell, buffer); + break; + } + + shellWriteString(shell, "\r\n"); + return value; +} + + +/** + * @brief shell设置变量 + * + * @param name 变量名 + * @param value 变量值 + * @return int 返回变量值 + */ +int shellSetVar(char *name, int value) +{ + Shell *shell = shellGetCurrent(); + if (shell == NULL) + { + return 0; + } + ShellCommand *command = shellSeekCommand(shell, + name, + shell->commandList.base, + 0); + if (!command) + { + shellWriteString(shell, shellText[SHELL_TEXT_VAR_NOT_FOUND]); + return 0; + } + if (command->attr.attrs.type < SHELL_TYPE_VAR_INT + || command->attr.attrs.type > SHELL_TYPE_VAR_NODE) + { + shellWriteString(shell, name); + shellWriteString(shell, shellText[SHELL_TEXT_NOT_VAR]); + return 0; + } + return shellSetVarValue(shell, command, value); +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +setVar, shellSetVar, set var); + + +/** + * @brief shell运行命令 + * + * @param shell shell对象 + * @param command 命令 + * + * @return unsigned int 命令返回值 + */ +unsigned int shellRunCommand(Shell *shell, ShellCommand *command) +{ + int returnValue = 0; + shell->status.isActive = 1; + if (command->attr.attrs.type == SHELL_TYPE_CMD_MAIN) + { + shellRemoveParamQuotes(shell); + int (*func)(int, char **) = command->data.cmd.function; + returnValue = func(shell->parser.paramCount, shell->parser.param); + if (!command->attr.attrs.disableReturn) + { + shellWriteReturnValue(shell, returnValue); + } + } + else if (command->attr.attrs.type == SHELL_TYPE_CMD_FUNC) + { + returnValue = shellExtRun(shell, + command, + shell->parser.paramCount, + shell->parser.param); + if (!command->attr.attrs.disableReturn) + { + shellWriteReturnValue(shell, returnValue); + } + } + else if (command->attr.attrs.type >= SHELL_TYPE_VAR_INT + && command->attr.attrs.type <= SHELL_TYPE_VAR_NODE) + { + shellShowVar(shell, command); + } + else if (command->attr.attrs.type == SHELL_TYPE_USER) + { + shellSetUser(shell, command); + } + shell->status.isActive = 0; + + return returnValue; +} + + +/** + * @brief shell校验密码 + * + * @param shell shell对象 + */ +static void shellCheckPassword(Shell *shell) +{ + if (strcmp(shell->parser.buffer, shell->info.user->data.user.password) == 0) + { + shell->status.isChecked = 1; + #if SHELL_SHOW_INFO == 1 + shellWriteString(shell, shellText[SHELL_TEXT_INFO]); + #endif + } + else + { + shellWriteString(shell, shellText[SHELL_TEXT_PASSWORD_ERROR]); + } + shell->parser.length = 0; + shell->parser.cursor = 0; +} + + +/** + * @brief shell设置用户 + * + * @param shell shell对象 + * @param user 用户 + */ +void shellSetUser(Shell *shell, const ShellCommand *user) +{ + shell->info.user = user; + shell->status.isChecked = + ((user->data.user.password && strlen(user->data.user.password) != 0) + && (shell->parser.paramCount < 2 + || strcmp(user->data.user.password, shell->parser.param[1]) != 0)) + ? 0 : 1; + +#if SHELL_CLS_WHEN_LOGIN == 1 + shellWriteString(shell, shellText[SHELL_TEXT_CLEAR_CONSOLE]); +#endif +#if SHELL_SHOW_INFO == 1 + if (shell->status.isChecked) + { + shellWriteString(shell, shellText[SHELL_TEXT_INFO]); + } +#endif +} + + +/** + * @brief shell写返回值 + * + * @param shell shell对象 + * @param value 返回值 + */ +static void shellWriteReturnValue(Shell *shell, int value) +{ + char buffer[12] = "00000000000"; + shellWriteString(shell, "Return: "); + shellWriteString(shell, &buffer[11 - shellToDec(value, buffer)]); + shellWriteString(shell, ", 0x"); + for (short i = 0; i < 11; i++) + { + buffer[i] = '0'; + } + shellToHex(value, buffer); + shellWriteString(shell, buffer); + shellWriteString(shell, "\r\n"); +#if SHELL_KEEP_RETURN_VALUE == 1 + shell->info.retVal = value; +#endif +} + + +#if SHELL_HISTORY_MAX_NUMBER > 0 +/** + * @brief shell历史记录添加 + * + * @param shell shell对象 + */ +static void shellHistoryAdd(Shell *shell) +{ + shell->history.offset = 0; + if (shell->history.number > 0 + && strcmp(shell->history.item[(shell->history.record == 0 ? + SHELL_HISTORY_MAX_NUMBER : shell->history.record) - 1], + shell->parser.buffer) == 0) + { + return; + } + if (shellStringCopy(shell->history.item[shell->history.record], + shell->parser.buffer) != 0) + { + shell->history.record++; + } + if (++shell->history.number > SHELL_HISTORY_MAX_NUMBER) + { + shell->history.number = SHELL_HISTORY_MAX_NUMBER; + } + if (shell->history.record >= SHELL_HISTORY_MAX_NUMBER) + { + shell->history.record = 0; + } +} + + +/** + * @brief shell历史记录查找 + * + * @param shell shell对象 + * @param dir 方向 {@code <0}往上查找 {@code >0}往下查找 + */ +static void shellHistory(Shell *shell, signed char dir) +{ + if (dir > 0) + { + if (shell->history.offset-- <= + -((shell->history.number > shell->history.record) ? + shell->history.number : shell->history.record)) + { + shell->history.offset = -((shell->history.number > shell->history.record) + ? shell->history.number : shell->history.record); + } + } + else if (dir < 0) + { + if (++shell->history.offset > 0) + { + shell->history.offset = 0; + return; + } + } + else + { + return; + } + shellClearCommandLine(shell); + if (shell->history.offset == 0) + { + shell->parser.cursor = shell->parser.length = 0; + } + else + { + if ((shell->parser.length = shellStringCopy(shell->parser.buffer, + shell->history.item[(shell->history.record + SHELL_HISTORY_MAX_NUMBER + + shell->history.offset) % SHELL_HISTORY_MAX_NUMBER])) == 0) + { + return; + } + shell->parser.cursor = shell->parser.length; + shellWriteString(shell, shell->parser.buffer); + } + +} +#endif /** SHELL_HISTORY_MAX_NUMBER > 0 */ + + +/** + * @brief shell 常规输入 + * + * @param shell shell 对象 + * @param data 输入字符 + */ +void shellNormalInput(Shell *shell, char data) +{ + shell->status.tabFlag = 0; + shellInsertByte(shell, data); +} + + +/** + * @brief shell运行命令 + * + * @param shell shell对象 + */ +void shellExec(Shell *shell) +{ + + if (shell->parser.length == 0) + { + return; + } + + shell->parser.buffer[shell->parser.length] = 0; + + if (shell->status.isChecked) + { + #if SHELL_HISTORY_MAX_NUMBER > 0 + shellHistoryAdd(shell); + #endif /** SHELL_HISTORY_MAX_NUMBER > 0 */ + shellParserParam(shell); + shell->parser.length = shell->parser.cursor = 0; + if (shell->parser.paramCount == 0) + { + return; + } + shellWriteString(shell, "\r\n"); + + ShellCommand *command = shellSeekCommand(shell, + shell->parser.param[0], + shell->commandList.base, + 0); + if (command != NULL) + { + shellRunCommand(shell, command); + } + else + { + shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]); + } + } + else + { + shellCheckPassword(shell); + } +} + + +#if SHELL_HISTORY_MAX_NUMBER > 0 +/** + * @brief shell上方向键输入 + * + * @param shell shell对象 + */ +void shellUp(Shell *shell) +{ + shellHistory(shell, 1); +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x1B5B4100, shellUp, up); + + +/** + * @brief shell下方向键输入 + * + * @param shell shell对象 + */ +void shellDown(Shell *shell) +{ + shellHistory(shell, -1); +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x1B5B4200, shellDown, down); +#endif /** SHELL_HISTORY_MAX_NUMBER > 0 */ + + +/** + * @brief shell右方向键输入 + * + * @param shell shell对象 + */ +void shellRight(Shell *shell) +{ + if (shell->parser.cursor < shell->parser.length) + { + shellWriteByte(shell, shell->parser.buffer[shell->parser.cursor++]); + } +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x1B5B4300, shellRight, right); + + +/** + * @brief shell左方向键输入 + * + * @param shell shell对象 + */ +void shellLeft(Shell *shell) +{ + if (shell->parser.cursor > 0) + { + shellWriteByte(shell, '\b'); + shell->parser.cursor--; + } +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x1B5B4400, shellLeft, left); + + +/** + * @brief shell Tab按键处理 + * + * @param shell shell对象 + */ +void shellTab(Shell *shell) +{ + unsigned short maxMatch = shell->parser.bufferSize; + unsigned short lastMatchIndex = 0; + unsigned short matchNum = 0; + unsigned short length; + + if (shell->parser.length == 0) + { + shellListAll(shell); + shellWritePrompt(shell, 1); + } + else if (shell->parser.length > 0) + { + shell->parser.buffer[shell->parser.length] = 0; + ShellCommand *base = (ShellCommand *)shell->commandList.base; + for (short i = 0; i < shell->commandList.count; i++) + { + if (shellCheckPermission(shell, &base[i]) == 0 + && shellStringCompare(shell->parser.buffer, + (char *)shellGetCommandName(&base[i])) + == shell->parser.length) + { + if (matchNum != 0) + { + if (matchNum == 1) + { + shellWriteString(shell, "\r\n"); + } + shellListItem(shell, &base[lastMatchIndex]); + length = + shellStringCompare((char *)shellGetCommandName(&base[lastMatchIndex]), + (char *)shellGetCommandName(&base[i])); + maxMatch = (maxMatch > length) ? length : maxMatch; + } + lastMatchIndex = i; + matchNum++; + } + } + if (matchNum == 0) + { + return; + } + if (matchNum == 1) + { + shellClearCommandLine(shell); + } + if (matchNum != 0) + { + shell->parser.length = + shellStringCopy(shell->parser.buffer, + (char *)shellGetCommandName(&base[lastMatchIndex])); + } + if (matchNum > 1) + { + shellListItem(shell, &base[lastMatchIndex]); + shellWritePrompt(shell, 1); + shell->parser.length = maxMatch; + } + shell->parser.buffer[shell->parser.length] = 0; + shell->parser.cursor = shell->parser.length; + shellWriteString(shell, shell->parser.buffer); + } + + if (SHELL_GET_TICK()) + { + if (matchNum == 1 + && shell->status.tabFlag + && SHELL_GET_TICK() - shell->info.activeTime < SHELL_DOUBLE_CLICK_TIME) + { + #if SHELL_QUICK_HELP == 1 + shellWriteString(shell, "\r\n"); + shellWriteCommandHelp(shell, shell->parser.buffer); + shellWritePrompt(shell, 1); + shellWriteString(shell, shell->parser.buffer); + #else + shellClearCommandLine(shell); + for (short i = shell->parser.length; i >= 0; i--) + { + shell->parser.buffer[i + 5] = shell->parser.buffer[i]; + } + shellStringCopy(shell->parser.buffer, "help"); + shell->parser.buffer[4] = ' '; + shell->parser.length += 5; + shell->parser.cursor = shell->parser.length; + shellWriteString(shell, shell->parser.buffer); + #endif + } + else + { + shell->status.tabFlag = 1; + } + } +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x09000000, shellTab, tab); + + +/** + * @brief shell 退格 + * + * @param shell shell对象 + */ +void shellBackspace(Shell *shell) +{ + shellDeleteByte(shell, 1); +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x08000000, shellBackspace, backspace); +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x7F000000, shellBackspace, backspace); + + +/** + * @brief shell 删除 + * + * @param shell shell对象 + */ +void shellDelete(Shell *shell) +{ + shellDeleteByte(shell, -1); +} +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x1B5B337E, shellDelete, delete); + + +/** + * @brief shell 回车处理 + * + * @param shell shell对象 + */ +void shellEnter(Shell *shell) +{ + shellExec(shell); + shellWritePrompt(shell, 1); +} +#if SHELL_ENTER_LF == 1 +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x0A000000, shellEnter, enter); +#endif +#if SHELL_ENTER_CR == 1 +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x0D000000, shellEnter, enter); +#endif +#if SHELL_ENTER_CRLF == 1 +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, +0x0D0A0000, shellEnter, enter); +#endif + +/** + * @brief shell 写命令帮助信息 + * + * @param shell shell对象 + * @param cmd 命令字符串 + */ +static void shellWriteCommandHelp(Shell *shell, char *cmd) +{ + ShellCommand *command = shellSeekCommand(shell, + cmd, + shell->commandList.base, + 0); + if (command) + { + shellWriteString(shell, shellText[SHELL_TEXT_HELP_HEADER]); + shellWriteString(shell, shellGetCommandName(command)); + shellWriteString(shell, "\r\n"); + shellWriteString(shell, shellGetCommandDesc(command)); + shellWriteString(shell, "\r\n"); + } + else + { + shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]); + } +} + +/** + * @brief shell help + * + * @param argc 参数个数 + * @param argv 参数 + */ +void shellHelp(int argc, char *argv[]) +{ + Shell *shell = shellGetCurrent(); + SHELL_ASSERT(shell, return); + if (argc == 1) + { + shellListAll(shell); + } + else if (argc > 1) + { + shellWriteCommandHelp(shell, argv[1]); + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN, +help, shellHelp, show command info\r\nhelp [cmd]); + +/** + * @brief shell 输入处理 + * + * @param shell shell对象 + * @param data 输入数据 + */ +void shellHandler(Shell *shell, char data) +{ + SHELL_ASSERT(data, return); + SHELL_LOCK(shell); + +#if SHELL_LOCK_TIMEOUT > 0 + if (shell->info.user->data.user.password + && strlen(shell->info.user->data.user.password) != 0 + && SHELL_GET_TICK()) + { + if (SHELL_GET_TICK() - shell->info.activeTime > SHELL_LOCK_TIMEOUT) + { + shell->status.isChecked = 0; + } + } +#endif + + /* 根据记录的按键键值计算当前字节在按键键值中的偏移 */ + char keyByteOffset = 24; + int keyFilter = 0x00000000; + if ((shell->parser.keyValue & 0x0000FF00) != 0x00000000) + { + keyByteOffset = 0; + keyFilter = 0xFFFFFF00; + } + else if ((shell->parser.keyValue & 0x00FF0000) != 0x00000000) + { + keyByteOffset = 8; + keyFilter = 0xFFFF0000; + } + else if ((shell->parser.keyValue & 0xFF000000) != 0x00000000) + { + keyByteOffset = 16; + keyFilter = 0xFF000000; + } + + /* 遍历ShellCommand列表,尝试进行按键键值匹配 */ + ShellCommand *base = (ShellCommand *)shell->commandList.base; + for (short i = 0; i < shell->commandList.count; i++) + { + /* 判断是否是按键定义并验证权限 */ + if (base[i].attr.attrs.type == SHELL_TYPE_KEY + && shellCheckPermission(shell, &(base[i])) == 0) + { + /* 对输入的字节同按键键值进行匹配 */ + if ((base[i].data.key.value & keyFilter) == shell->parser.keyValue + && (base[i].data.key.value & (0xFF << keyByteOffset)) + == (data << keyByteOffset)) + { + shell->parser.keyValue |= data << keyByteOffset; + data = 0x00; + if (keyByteOffset == 0 + || (base[i].data.key.value & (0xFF << (keyByteOffset - 8))) + == 0x00000000) + { + if (base[i].data.key.function) + { + base[i].data.key.function(shell); + } + shell->parser.keyValue = 0x00000000; + break; + } + } + } + } + + if (data != 0x00) + { + shell->parser.keyValue = 0x00000000; + shellNormalInput(shell, data); + } + + if (SHELL_GET_TICK()) + { + shell->info.activeTime = SHELL_GET_TICK(); + } + SHELL_UNLOCK(shell); +} + + +#if SHELL_SUPPORT_END_LINE == 1 +void shellWriteEndLine(Shell *shell, char *buffer, int len) +{ + SHELL_LOCK(shell); + if (!shell->status.isActive) + { + shellWriteString(shell, shellText[SHELL_TEXT_CLEAR_LINE]); + } + shell->write(buffer, len); + + if (!shell->status.isActive) + { + shellWritePrompt(shell, 0); + if (shell->parser.length > 0) + { + shellWriteString(shell, shell->parser.buffer); + for (short i = 0; i < shell->parser.length - shell->parser.cursor; i++) + { + shellWriteByte(shell, '\b'); + } + } + } + SHELL_UNLOCK(shell); +} +#endif /** SHELL_SUPPORT_END_LINE == 1 */ + + +/** + * @brief shell 任务 + * + * @param param 参数(shell对象) + * + */ +void shellTask(void *param) +{ + Shell *shell = (Shell *)param; + char data; +#if SHELL_TASK_WHILE == 1 + while(1) + { +#endif + if (shell->read && shell->read(&data, 1) == 1) + { + shellHandler(shell, data); + } +#if SHELL_TASK_WHILE == 1 + } +#endif +} + + +/** + * @brief shell 输出用户列表(shell调用) + */ +void shellUsers(void) +{ + Shell *shell = shellGetCurrent(); + if (shell) + { + shellListUser(shell); + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +users, shellUsers, list all user); + + +/** + * @brief shell 输出命令列表(shell调用) + */ +void shellCmds(void) +{ + Shell *shell = shellGetCurrent(); + if (shell) + { + shellListCommand(shell); + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +cmds, shellCmds, list all cmd); + + +/** + * @brief shell 输出变量列表(shell调用) + */ +void shellVars(void) +{ + Shell *shell = shellGetCurrent(); + if (shell) + { + shellListVar(shell); + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +vars, shellVars, list all var); + + +/** + * @brief shell 输出按键列表(shell调用) + */ +void shellKeys(void) +{ + Shell *shell = shellGetCurrent(); + if (shell) + { + shellListKey(shell); + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +keys, shellKeys, list all key); + + +/** + * @brief shell 清空控制台(shell调用) + */ +void shellClear(void) +{ + Shell *shell = shellGetCurrent(); + if (shell) + { + shellWriteString(shell, shellText[SHELL_TEXT_CLEAR_CONSOLE]); + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +clear, shellClear, clear console); + + +/** + * @brief shell执行命令 + * + * @param shell shell对象 + * @param cmd 命令字符串 + * @return int 返回值 + */ +int shellRun(Shell *shell, const char *cmd) +{ + SHELL_ASSERT(shell && cmd, return -1); + char active = shell->status.isActive; + if (strlen(cmd) > shell->parser.bufferSize - 1) + { + shellWriteString(shell, shellText[SHELL_TEXT_CMD_TOO_LONG]); + return -1; + } + else + { + shell->parser.length = shellStringCopy(shell->parser.buffer, (char *)cmd); + shellExec(shell); + shell->status.isActive = active; + return 0; + } +} + + +#if SHELL_EXEC_UNDEF_FUNC == 1 +/** + * @brief shell执行未定义函数 + * + * @param argc 参数个数 + * @param argv 参数 + * @return int 返回值 + */ +int shellExecute(int argc, char *argv[]) +{ + Shell *shell = shellGetCurrent(); + if (shell && argc >= 2) + { + size_t result; + if (shellExtParsePara(shell, argv[1], NULL, &result) != 0) + { + shellWriteString(shell, shellText[SHELL_TEXT_PARAM_ERROR]); + return -1; + } + int (*func)() = (int (*)())result; + ShellCommand command = { + .attr.value = SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) + |SHELL_CMD_DISABLE_RETURN, + .data.cmd.function = func, + }; + return shellExtRun(shell, &command, argc - 1, &argv[1]); + } + else + { + shellWriteString(shell, shellText[SHELL_TEXT_PARAM_ERROR]); + return -1; + } +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN, +exec, shellExecute, execute function undefined); +#endif + +#if SHELL_KEEP_RETURN_VALUE == 1 +/** + * @brief shell返回值获取 + * 获取上一次执行的命令的返回值 + * + * @return int 返回值 + */ +static int shellRetValGet() +{ + Shell *shell = shellGetCurrent(); + return shell ? shell->info.retVal : 0; +} +static ShellNodeVarAttr shellRetVal = { + .get = shellRetValGet +}; +SHELL_EXPORT_VAR(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_VAR_NODE)|SHELL_CMD_READ_ONLY, +RETVAL, &shellRetVal, return value of last command); +#endif /** SHELL_KEEP_RETURN_VALUE == 1 */ diff --git a/User/system/letter_shell/shell.h b/User/system/letter_shell/shell.h new file mode 100644 index 0000000..3932750 --- /dev/null +++ b/User/system/letter_shell/shell.h @@ -0,0 +1,557 @@ +/** + * @file shell.h + * @author Letter (NevermindZZT@gmail.com) + * @brief letter shell + * @version 3.0.0 + * @date 2019-12-30 + * + * @copyright (c) 2020 Letter + * + */ + +#ifndef __SHELL_H__ +#define __SHELL_H__ + +#include "shell_cfg.h" + +#define SHELL_VERSION "3.2.4" /**< 版本号 */ + + +/** + * @brief shell 断言 + * + * @param expr 表达式 + * @param action 断言失败操作 + */ +#define SHELL_ASSERT(expr, action) \ + if (!(expr)) { \ + action; \ + } + +#if SHELL_USING_LOCK == 1 +#define SHELL_LOCK(shell) shell->lock(shell) +#define SHELL_UNLOCK(shell) shell->unlock(shell) +#else +#define SHELL_LOCK(shell) +#define SHELL_UNLOCK(shell) +#endif /** SHELL_USING_LOCK == 1 */ +/** + * @brief shell 命令权限 + * + * @param permission 权限级别 + */ +#define SHELL_CMD_PERMISSION(permission) \ + (permission & 0x000000FF) + +/** + * @brief shell 命令类型 + * + * @param type 类型 + */ +#define SHELL_CMD_TYPE(type) \ + ((type & 0x0000000F) << 8) + +/** + * @brief 使能命令在未校验密码的情况下使用 + */ +#define SHELL_CMD_ENABLE_UNCHECKED \ + (1 << 12) + +/** + * @brief 禁用返回值打印 + */ +#define SHELL_CMD_DISABLE_RETURN \ + (1 << 13) + +/** + * @brief 只读属性(仅对变量生效) + */ +#define SHELL_CMD_READ_ONLY \ + (1 << 14) + +/** + * @brief 命令参数数量 + */ +#define SHELL_CMD_PARAM_NUM(num) \ + ((num & 0x0000000F)) << 16 + +#ifndef SHELL_SECTION + #if defined(__CC_ARM) || defined(__CLANG_ARM) + #define SHELL_SECTION(x) __attribute__((section(x), aligned(1))) + #elif defined (__IAR_SYSTEMS_ICC__) + #define SHELL_SECTION(x) @ x + #elif defined(__GNUC__) + #define SHELL_SECTION(x) __attribute__((section(x), aligned(1))) + #else + #define SHELL_SECTION(x) + #endif +#endif + +#ifndef SHELL_USED + #if defined(__CC_ARM) || defined(__CLANG_ARM) + #define SHELL_USED __attribute__((used)) + #elif defined (__IAR_SYSTEMS_ICC__) + #define SHELL_USED __root + #elif defined(__GNUC__) + #define SHELL_USED __attribute__((used)) + #else + #define SHELL_USED + #endif +#endif + +/** + * @brief shell float型参数转换 + */ +#define SHELL_PARAM_FLOAT(x) (*(float *)(&x)) + +/** + * @brief shell 代理函数名 + */ +#define SHELL_AGENCY_FUNC_NAME(_func) agency##_func + +/** + * @brief shell代理函数定义 + * + * @param _func 被代理的函数 + * @param ... 代理参数 + */ +#define SHELL_AGENCY_FUNC(_func, ...) \ + void SHELL_AGENCY_FUNC_NAME(_func)(int p1, int p2, int p3, int p4, int p5, int p6, int p7) \ + { _func(__VA_ARGS__); } + +#if SHELL_USING_CMD_EXPORT == 1 + + /** + * @brief shell 命令定义 + * + * @param _attr 命令属性 + * @param _name 命令名 + * @param _func 命令函数 + * @param _desc 命令描述 + * @param ... 其他参数 + */ + #define SHELL_EXPORT_CMD(_attr, _name, _func, _desc, ...) \ + const char shellCmd##_name[] = #_name; \ + const char shellDesc##_name[] = #_desc; \ + SHELL_USED const ShellCommand \ + shellCommand##_name SHELL_SECTION("shellCommand") = \ + { \ + .attr.value = _attr, \ + .data.cmd.name = shellCmd##_name, \ + .data.cmd.function = (int (*)())_func, \ + .data.cmd.desc = shellDesc##_name, \ + ##__VA_ARGS__ \ + } + +#if SHELL_USING_FUNC_SIGNATURE == 1 + /** + * @brief shell 命令定义 + * + * @param _attr 命令属性 + * @param _name 命令名 + * @param _func 命令函数 + * @param _desc 命令描述 + * @param _sign 命令签名 + */ + #define SHELL_EXPORT_CMD_SIGN(_attr, _name, _func, _desc, _sign) \ + const char shellCmd##_name[] = #_name; \ + const char shellDesc##_name[] = #_desc; \ + const char shellSign##_name[] = #_sign; \ + SHELL_USED const ShellCommand \ + shellCommand##_name SHELL_SECTION("shellCommand") = \ + { \ + .attr.value = _attr, \ + .data.cmd.name = shellCmd##_name, \ + .data.cmd.function = (int (*)())_func, \ + .data.cmd.desc = shellDesc##_name, \ + .data.cmd.signature = shellSign##_name \ + } +#endif /** SHELL_USING_FUNC_SIGNATURE == 1 */ + + /** + * @brief shell 代理命令定义 + * + * @param _attr 命令属性 + * @param _name 命令名 + * @param _func 命令函数 + * @param _desc 命令描述 + * @param ... 代理参数 + */ + #define SHELL_EXPORT_CMD_AGENCY(_attr, _name, _func, _desc, ...) \ + SHELL_AGENCY_FUNC(_func, ##__VA_ARGS__) \ + SHELL_EXPORT_CMD(_attr, _name, SHELL_AGENCY_FUNC_NAME(_func), _desc) + + /** + * @brief shell 变量定义 + * + * @param _attr 变量属性 + * @param _name 变量名 + * @param _value 变量值 + * @param _desc 变量描述 + */ + #define SHELL_EXPORT_VAR(_attr, _name, _value, _desc) \ + const char shellCmd##_name[] = #_name; \ + const char shellDesc##_name[] = #_desc; \ + SHELL_USED const ShellCommand \ + shellVar##_name SHELL_SECTION("shellCommand") = \ + { \ + .attr.value = _attr, \ + .data.var.name = shellCmd##_name, \ + .data.var.value = (void *)_value, \ + .data.var.desc = shellDesc##_name \ + } + + /** + * @brief shell 用户定义 + * + * @param _attr 用户属性 + * @param _name 用户名 + * @param _password 用户密码 + * @param _desc 用户描述 + */ + #define SHELL_EXPORT_USER(_attr, _name, _password, _desc) \ + const char shellCmd##_name[] = #_name; \ + const char shellPassword##_name[] = #_password; \ + const char shellDesc##_name[] = #_desc; \ + SHELL_USED const ShellCommand \ + shellUser##_name SHELL_SECTION("shellCommand") = \ + { \ + .attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_USER), \ + .data.user.name = shellCmd##_name, \ + .data.user.password = shellPassword##_name, \ + .data.user.desc = shellDesc##_name \ + } + + /** + * @brief shell 按键定义 + * + * @param _attr 按键属性 + * @param _value 按键键值 + * @param _func 按键函数 + * @param _desc 按键描述 + */ + #define SHELL_EXPORT_KEY(_attr, _value, _func, _desc) \ + const char shellDesc##_value[] = #_desc; \ + SHELL_USED const ShellCommand \ + shellKey##_value SHELL_SECTION("shellCommand") = \ + { \ + .attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \ + .data.key.value = _value, \ + .data.key.function = (void (*)(Shell *))_func, \ + .data.key.desc = shellDesc##_value \ + } + + /** + * @brief shell 代理按键定义 + * + * @param _attr 按键属性 + * @param _value 按键键值 + * @param _func 按键函数 + * @param _desc 按键描述 + * @param ... 代理参数 + */ + #define SHELL_EXPORT_KEY_AGENCY(_attr, _value, _func, _desc, ...) \ + SHELL_AGENCY_FUNC(_func, ##__VA_ARGS__) \ + SHELL_EXPORT_KEY(_attr, _value, SHELL_AGENCY_FUNC_NAME(_func), _desc) + +#if SHELL_USING_FUNC_SIGNATURE == 1 + /** + * @brief shell 参数解析器定义 + * + * @param _attr 参数解析器属性 + * @param _type 参数解析器类型 + * @param _parser 参数解析器函数 + * @param _cleaner 参数清理器 + */ + #define SHELL_EXPORT_PARAM_PARSER(_attr, _type, _parser, _cleaner) \ + const char shellDesc##_parser[] = #_type; \ + SHELL_USED const ShellCommand \ + shellCommand##_parser SHELL_SECTION("shellCommand") = \ + { \ + .attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_PARAM_PARSER), \ + .data.paramParser.type = shellDesc##_parser, \ + .data.paramParser.parser = (int (*)(char *, void **))_parser, \ + .data.paramParser.cleaner = (int (*)(void *))_cleaner \ + } +#endif + +#else + /** + * @brief shell 命令item定义 + * + * @param _attr 命令属性 + * @param _name 命令名 + * @param _func 命令函数 + * @param _desc 命令描述 + */ + #define SHELL_CMD_ITEM(_attr, _name, _func, _desc) \ + { \ + .attr.value = _attr, \ + .data.cmd.name = #_name, \ + .data.cmd.function = (int (*)())_func, \ + .data.cmd.desc = #_desc \ + } + + /** + * @brief shell 变量item定义 + * + * @param _attr 变量属性 + * @param _name 变量名 + * @param _value 变量值 + * @param _desc 变量描述 + */ + #define SHELL_VAR_ITEM(_attr, _name, _value, _desc) \ + { \ + .attr.value = _attr, \ + .data.var.name = #_name, \ + .data.var.value = (void *)_value, \ + .data.var.desc = #_desc \ + } + + /** + * @brief shell 用户item定义 + * + * @param _attr 用户属性 + * @param _name 用户名 + * @param _password 用户密码 + * @param _desc 用户描述 + */ + #define SHELL_USER_ITEM(_attr, _name, _password, _desc) \ + { \ + .attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_USER), \ + .data.user.name = #_name, \ + .data.user.password = #_password, \ + .data.user.desc = #_desc \ + } + + /** + * @brief shell 按键item定义 + * + * @param _attr 按键属性 + * @param _value 按键键值 + * @param _func 按键函数 + * @param _desc 按键描述 + */ + #define SHELL_KEY_ITEM(_attr, _value, _func, _desc) \ + { \ + .attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \ + .data.key.value = _value, \ + .data.key.function = (void (*)(Shell *))_func, \ + .data.key.desc = #_desc \ + } + +#if SHELL_USING_FUNC_SIGNATURE == 1 + /** + * @brief shell 参数解析器item定义 + * + * @param _attr 参数解析器属性 + * @param _type 参数解析器类型 + * @param _parser 参数解析器函数 + * @param _cleaner 参数清理器 + */ + #define SHELL_PARAM_PARSER_ITEM(_attr, _type, _parser, _cleaner) \ + { \ + .attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_PARAM_PARSER), \ + .data.paramParser.type = #_type, \ + .data.paramParser.parser = (int (*)(char *, void **))_parser, \ + .data.paramParser.cleaner = (int (*)(void *))_cleaner \ + } +#endif /** SHELL_USING_FUNC_SIGNATURE == 1 */ + + #define SHELL_EXPORT_CMD(_attr, _name, _func, _desc) +#if SHELL_USING_FUNC_SIGNATURE == 1 + #define SHELL_EXPORT_CMD_SIGN(_attr, _name, _func, _desc, _sign) +#endif /** SHELL_USING_FUNC_SIGNATURE == 1 */ + #define SHELL_EXPORT_CMD_AGENCY(_attr, _name, _func, _desc, ...) + #define SHELL_EXPORT_VAR(_attr, _name, _value, _desc) + #define SHELL_EXPORT_USER(_attr, _name, _password, _desc) + #define SHELL_EXPORT_KEY(_attr, _value, _func, _desc) + #define SHELL_EXPORT_KEY_AGENCY(_attr, _name, _func, _desc, ...) +#if SHELL_USING_FUNC_SIGNATURE == 1 + #define SHELL_EXPORT_PARAM_PARSER(_attr, _type, _parser, _cleaner) +#endif /** SHELL_USING_FUNC_SIGNATURE == 1 */ +#endif /** SHELL_USING_CMD_EXPORT == 1 */ + +/** + * @brief shell command类型 + */ +typedef enum +{ + SHELL_TYPE_CMD_MAIN = 0, /**< main形式命令 */ + SHELL_TYPE_CMD_FUNC, /**< C函数形式命令 */ + SHELL_TYPE_VAR_INT, /**< int型变量 */ + SHELL_TYPE_VAR_SHORT, /**< short型变量 */ + SHELL_TYPE_VAR_CHAR, /**< char型变量 */ + SHELL_TYPE_VAR_STRING, /**< string型变量 */ + SHELL_TYPE_VAR_POINT, /**< 指针型变量 */ + SHELL_TYPE_VAR_NODE, /**< 节点变量 */ + SHELL_TYPE_USER, /**< 用户 */ + SHELL_TYPE_KEY, /**< 按键 */ +#if SHELL_USING_FUNC_SIGNATURE == 1 + SHELL_TYPE_PARAM_PARSER, /**< 参数解析器 */ +#endif +} ShellCommandType; + + +/** + * @brief Shell定义 + */ +typedef struct shell_def +{ + struct + { + const struct shell_command *user; /**< 当前用户 */ + int activeTime; /**< shell激活时间 */ + char *path; /**< 当前shell路径 */ + #if SHELL_USING_COMPANION == 1 + struct shell_companion_object *companions; /**< 伴生对象 */ + #endif + #if SHELL_KEEP_RETURN_VALUE == 1 + int retVal; /**< 返回值 */ + #endif + } info; + struct + { + unsigned short length; /**< 输入数据长度 */ + unsigned short cursor; /**< 当前光标位置 */ + char *buffer; /**< 输入缓冲 */ + char *param[SHELL_PARAMETER_MAX_NUMBER]; /**< 参数 */ + unsigned short bufferSize; /**< 输入缓冲大小 */ + unsigned short paramCount; /**< 参数数量 */ + int keyValue; /**< 输入按键键值 */ + } parser; +#if SHELL_HISTORY_MAX_NUMBER > 0 + struct + { + char *item[SHELL_HISTORY_MAX_NUMBER]; /**< 历史记录 */ + unsigned short number; /**< 历史记录数 */ + unsigned short record; /**< 当前记录位置 */ + signed short offset; /**< 当前历史记录偏移 */ + } history; +#endif /** SHELL_HISTORY_MAX_NUMBER > 0 */ + struct + { + void *base; /**< 命令表基址 */ + unsigned short count; /**< 命令数量 */ + } commandList; + struct + { + unsigned char isChecked : 1; /**< 密码校验通过 */ + unsigned char isActive : 1; /**< 当前活动Shell */ + unsigned char tabFlag : 1; /**< tab标志 */ + } status; + signed short (*read)(char *, unsigned short); /**< shell读函数 */ + signed short (*write)(char *, unsigned short); /**< shell写函数 */ +#if SHELL_USING_LOCK == 1 + int (*lock)(struct shell_def *); /**< shell 加锁 */ + int (*unlock)(struct shell_def *); /**< shell 解锁 */ +#endif +} Shell; + + +/** + * @brief shell command定义 + */ +typedef struct shell_command +{ + union + { + struct + { + unsigned char permission : 8; /**< command权限 */ + ShellCommandType type : 4; /**< command类型 */ + unsigned char enableUnchecked : 1; /**< 在未校验密码的情况下可用 */ + unsigned char disableReturn : 1; /**< 禁用返回值输出 */ + unsigned char readOnly : 1; /**< 只读 */ + unsigned char reserve : 1; /**< 保留 */ + unsigned char paramNum : 4; /**< 参数数量 */ + } attrs; + int value; + } attr; /**< 属性 */ + union + { + struct + { + const char *name; /**< 命令名 */ + int (*function)(); /**< 命令执行函数 */ + const char *desc; /**< 命令描述 */ + #if SHELL_USING_FUNC_SIGNATURE == 1 + const char *signature; /**< 函数签名 */ + #endif + } cmd; /**< 命令定义 */ + struct + { + const char *name; /**< 变量名 */ + void *value; /**< 变量值 */ + const char *desc; /**< 变量描述 */ + } var; /**< 变量定义 */ + struct + { + const char *name; /**< 用户名 */ + const char *password; /**< 用户密码 */ + const char *desc; /**< 用户描述 */ + } user; /**< 用户定义 */ + struct + { + int value; /**< 按键键值 */ + void (*function)(Shell *); /**< 按键执行函数 */ + const char *desc; /**< 按键描述 */ + } key; /**< 按键定义 */ +#if SHELL_USING_FUNC_SIGNATURE == 1 + struct + { + const char *type; /**< 参数类型 */ + int (*parser)(char *, void **); /**< 解析函数 */ + int (*cleaner)(void *); /**< 清理器 */ + } paramParser; /**< 参数解析器 */ +#endif + } data; +} ShellCommand; + +/** + * @brief shell节点变量属性 + */ +typedef struct +{ + void *var; /**< 变量引用 */ + int (*get)(); /**< 变量get方法 */ + int (*set)(); /**< 变量set方法 */ +} ShellNodeVarAttr; + + +#define shellSetPath(_shell, _path) (_shell)->info.path = _path +#define shellGetPath(_shell) ((_shell)->info.path) + +#define shellDeInit(shell) shellRemove(shell) + +void shellInit(Shell *shell, char *buffer, unsigned short size); +void shellRemove(Shell *shell); +unsigned short shellWriteString(Shell *shell, const char *string); +void shellPrint(Shell *shell, const char *fmt, ...); +void shellScan(Shell *shell, char *fmt, ...); +Shell* shellGetCurrent(void); +void shellHandler(Shell *shell, char data); +void shellWriteEndLine(Shell *shell, char *buffer, int len); +void shellTask(void *param); +int shellRun(Shell *shell, const char *cmd); + + + +#if SHELL_USING_COMPANION == 1 +/** + * @brief shell伴生对象定义 + */ +typedef struct shell_companion_object +{ + int id; /**< 伴生对象ID */ + void *obj; /**< 伴生对象 */ + struct shell_companion_object *next; /**< 下一个伴生对象 */ +} ShellCompanionObj; + + +signed char shellCompanionAdd(Shell *shell, int id, void *object); +signed char shellCompanionDel(Shell *shell, int id); +void *shellCompanionGet(Shell *shell, int id); +#endif + +#endif diff --git a/User/system/letter_shell/shell_cfg.h b/User/system/letter_shell/shell_cfg.h new file mode 100644 index 0000000..096f87c --- /dev/null +++ b/User/system/letter_shell/shell_cfg.h @@ -0,0 +1,267 @@ +/** + * @file shell_cfg.h + * @author Letter (nevermindzzt@gmail.com) + * @brief shell config + * @version 3.0.0 + * @date 2019-12-31 + * + * @copyright (c) 2019 Letter + * + */ + +#ifndef __SHELL_CFG_H__ +#define __SHELL_CFG_H__ + +#ifdef SHELL_CFG_USER +#include SHELL_CFG_USER +#endif + +#ifndef SHELL_TASK_WHILE +/** + * @brief 是否使用默认shell任务while循环 + * 使能此宏,则`shellTask()`函数会一直循环读取输入,一般使用操作系统建立shell + * 任务时使能此宏,关闭此宏的情况下,一般适用于无操作系统,在主循环中调用`shellTask()` + */ +#define SHELL_TASK_WHILE 1 +#endif /** SHELL_TASK_WHILE */ + +#ifndef SHELL_USING_CMD_EXPORT +/** + * @brief 是否使用命令导出方式 + * 使能此宏后,可以使用`SHELL_EXPORT_CMD()`等导出命令 + * 定义shell命令,关闭此宏的情况下,需要使用命令表的方式 + */ +#define SHELL_USING_CMD_EXPORT 1 +#endif /** SHELL_USING_CMD_EXPORT */ + +#ifndef SHELL_USING_COMPANION +/** + * @brief 是否使用shell伴生对象 + * 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象 + */ +#define SHELL_USING_COMPANION 0 +#endif /** SHELL_USING_COMPANION */ + +#ifndef SHELL_SUPPORT_END_LINE +/** + * @brief 支持shell尾行模式 + */ +#define SHELL_SUPPORT_END_LINE 0 +#endif /** SHELL_SUPPORT_END_LINE */ + +#ifndef SHELL_HELP_LIST_USER +/** + * @brief 是否在输出命令列表中列出用户 + */ +#define SHELL_HELP_LIST_USER 0 +#endif /** SHELL_HELP_LIST_USER */ + +#ifndef SHELL_HELP_LIST_VAR +/** + * @brief 是否在输出命令列表中列出变量 + */ +#define SHELL_HELP_LIST_VAR 0 +#endif /** SHELL_HELP_LIST_VAR */ + +#ifndef SHELL_HELP_LIST_KEY +/** + * @brief 是否在输出命令列表中列出按键 + */ +#define SHELL_HELP_LIST_KEY 0 +#endif /** SHELL_HELP_LIST_KEY */ + +#ifndef SHELL_HELP_SHOW_PERMISSION +/** + * @brief 是否在输出命令列表中展示命令权限 + */ +#define SHELL_HELP_SHOW_PERMISSION 1 +#endif /** SHELL_HELP_SHOW_PERMISSION */ + +#ifndef SHELL_ENTER_LF +/** + * @brief 使用LF作为命令行回车触发 + * 可以和SHELL_ENTER_CR同时开启 + */ +#define SHELL_ENTER_LF 1 +#endif /** SHELL_ENTER_LF */ + +#ifndef SHELL_ENTER_CR +/** + * @brief 使用CR作为命令行回车触发 + * 可以和SHELL_ENTER_LF同时开启 + */ +#define SHELL_ENTER_CR 1 +#endif /** SHELL_ENTER_CR */ + +#ifndef SHELL_ENTER_CRLF +/** + * @brief 使用CRLF作为命令行回车触发 + * 不可以和SHELL_ENTER_LF或SHELL_ENTER_CR同时开启 + */ +#define SHELL_ENTER_CRLF 0 +#endif /** SHELL_ENTER_CRLF */ + +#ifndef SHELL_EXEC_UNDEF_FUNC +/** + * @brief 使用执行未导出函数的功能 + * 启用后,可以通过`exec [addr] [args]`直接执行对应地址的函数 + * @attention 如果地址错误,可能会直接引起程序崩溃 + */ +#define SHELL_EXEC_UNDEF_FUNC 0 +#endif /** SHELL_EXEC_UNDEF_FUNC */ + +#ifndef SHELL_PARAMETER_MAX_NUMBER +/** + * @brief shell命令参数最大数量 + * 包含命令名在内,超过16个参数并且使用了参数自动转换的情况下,需要修改源码 + */ +#define SHELL_PARAMETER_MAX_NUMBER 8 +#endif /** SHELL_PARAMETER_MAX_NUMBER */ + +#ifndef SHELL_HISTORY_MAX_NUMBER +/** + * @brief 历史命令记录数量 + */ +#define SHELL_HISTORY_MAX_NUMBER 5 +#endif /** SHELL_HISTORY_MAX_NUMBER */ + +#ifndef SHELL_DOUBLE_CLICK_TIME +/** + * @brief 双击间隔(ms) + * 使能宏`SHELL_LONG_HELP`后此宏生效,定义双击tab补全help的时间间隔 + */ +#define SHELL_DOUBLE_CLICK_TIME 200 +#endif /** SHELL_DOUBLE_CLICK_TIME */ + +#ifndef SHELL_QUICK_HELP +/** + * @brief 快速帮助 + * 作用于双击tab的场景,当使能此宏时,双击tab不会对命令进行help补全,而是直接显示对应命令的帮助信息 + */ +#define SHELL_QUICK_HELP 1 +#endif /** SHELL_QUICK_HELP */ + +#ifndef SHELL_KEEP_RETURN_VALUE +/** + * @brief 保存命令返回值 + * 开启后会默认定义一个`RETVAL`变量,会保存上一次命令执行的返回值,可以在随后的命令中进行调用 + * 如果命令的`SHELL_CMD_DISABLE_RETURN`标志被设置,则该命令不会更新`RETVAL` + */ +#define SHELL_KEEP_RETURN_VALUE 0 +#endif /** SHELL_KEEP_RETURN_VALUE */ + +#ifndef SHELL_MAX_NUMBER +/** + * @brief 管理的最大shell数量 + */ +#define SHELL_MAX_NUMBER 5 +#endif /** SHELL_MAX_NUMBER */ + +#ifndef SHELL_PRINT_BUFFER +/** + * @brief shell格式化输出的缓冲大小 + * 为0时不使用shell格式化输出 + */ +#define SHELL_PRINT_BUFFER 128 +#endif /** SHELL_PRINT_BUFFER */ + +#ifndef SHELL_SCAN_BUFFER +/** + * @brief shell格式化输入的缓冲大小 + * 为0时不使用shell格式化输入 + * @note shell格式化输入会阻塞shellTask, 仅适用于在有操作系统的情况下使用 + */ +#define SHELL_SCAN_BUFFER 0 +#endif /** SHELL_SCAN_BUFFER */ + +#ifndef SHELL_GET_TICK +/** + * @brief 获取系统时间(ms) + * 定义此宏为获取系统Tick,如`HAL_GetTick()` + * @note 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定 + */ +#define SHELL_GET_TICK() 0 +#endif /** SHELL_GET_TICK */ + +#ifndef SHELL_USING_LOCK +/** + * @brief 使用锁 + * @note 使用shell锁时,需要对加锁和解锁进行实现 + */ +#define SHELL_USING_LOCK 1 +#endif /** SHELL_USING_LOCK */ + +#ifndef SHELL_MALLOC +/** + * @brief shell内存分配 + * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 + */ +#define SHELL_MALLOC(size) 0 +#endif /** SHELL_MALLOC */ + +#ifndef SHELL_FREE +/** + * @brief shell内存释放 + * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 + */ +#define SHELL_FREE(obj) 0 +#endif /** SHELL_FREE */ + +#ifndef SHELL_SHOW_INFO +/** + * @brief 是否显示shell信息 + */ +#define SHELL_SHOW_INFO 1 +#endif /** SHELL_SHOW_INFO */ + +#ifndef SHELL_CLS_WHEN_LOGIN +/** + * @brief 是否在登录后清除命令行 + */ +#define SHELL_CLS_WHEN_LOGIN 1 +#endif /** SHELL_CLS_WHEN_LOGIN */ + +#ifndef SHELL_DEFAULT_USER +/** + * @brief shell默认用户 + */ +#define SHELL_DEFAULT_USER "letter" +#endif /** SHELL_DEFAULT_USER */ + +#ifndef SHELL_DEFAULT_USER_PASSWORD +/** + * @brief shell默认用户密码 + * 若默认用户不需要密码,设为"" + */ +#define SHELL_DEFAULT_USER_PASSWORD "" +#endif /** SHELL_DEFAULT_USER_PASSWORD */ + +#ifndef SHELL_LOCK_TIMEOUT +/** + * @brief shell自动锁定超时 + * shell当前用户密码有效的时候生效,超时后会自动重新锁定shell + * 设置为0时关闭自动锁定功能,时间单位为`SHELL_GET_TICK()`单位 + * @note 使用超时锁定必须保证`SHELL_GET_TICK()`有效 + */ +#define SHELL_LOCK_TIMEOUT 0 * 60 * 1000 +#endif /** SHELL_LOCK_TIMEOUT */ + +#ifndef SHELL_USING_FUNC_SIGNATURE +/** + * @brief 使用函数签名 + * 使能后,可以在声明命令时,指定函数的签名,shell 会根据函数签名进行参数转换, + * 而不是自动判断参数的类型,如果参数和函数签名不匹配,会停止执行命令 + */ +#define SHELL_USING_FUNC_SIGNATURE 0 +#endif /** SHELL_USING_FUNC_SIGNATURE */ + +#ifndef SHELL_SUPPORT_ARRAY_PARAM +/** + * @brief 支持数组参数 + * 使能后,可以在命令中使用数组参数,如`cmd [1,2,3]` + * 需要使能 `SHELL_USING_FUNC_SIGNATURE` 宏,并且配置 `SHELL_MALLOC`, `SHELL_FREE` + */ +#define SHELL_SUPPORT_ARRAY_PARAM 0 +#endif /** SHELL_SUPPORT_ARRAY_PARAM */ + +#endif diff --git a/User/system/letter_shell/shell_cfg_user.h b/User/system/letter_shell/shell_cfg_user.h new file mode 100644 index 0000000..bf3437c --- /dev/null +++ b/User/system/letter_shell/shell_cfg_user.h @@ -0,0 +1,82 @@ +/** + * @file shell_cfg_user.h + * @author Letter (nevermindzzt@gmail.com) + * @brief shell config + * @version 3.0.0 + * @date 2019-12-31 + * + * @copyright (c) 2019 Letter + * + */ + +#ifndef __SHELL_CFG_USER_H__ +#define __SHELL_CFG_USER_H__ + +#include "stm32f4xx_hal.h" +#include "FreeRTOS.h" +#include "portable.h" + +/** + * @brief 是否使用shell伴生对象 + * 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象 + */ +#define SHELL_USING_COMPANION 1 + + +/** + * @brief 支持shell尾行模式 + */ +#define SHELL_SUPPORT_END_LINE 1 + + +/** + * @brief 使用LF作为命令行回车触发 + * 可以和SHELL_ENTER_CR同时开启 + */ +#define SHELL_ENTER_LF 1 + +/** + * @brief 使用CR作为命令行回车触发 + * 可以和SHELL_ENTER_LF同时开启 + */ +#define SHELL_ENTER_CR 0 + +/** + * @brief 使用CRLF作为命令行回车触发 + * 不可以和SHELL_ENTER_LF或SHELL_ENTER_CR同时开启 + */ +#define SHELL_ENTER_CRLF 1 + +/** + * @brief shell格式化输入的缓冲大小 + * 为0时不使用shell格式化输入 + * @note shell格式化输入会阻塞shellTask, 仅适用于在有操作系统的情况下使用 + */ +#define SHELL_SCAN_BUFFER 128 + +/** + * @brief 获取系统时间(ms) + * 定义此宏为获取系统Tick,如`HAL_GetTick()` + * @note 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定 + */ +#define SHELL_GET_TICK() HAL_GetTick() + +/** + * @brief 使用锁 + * @note 使用shell锁时,需要对加锁和解锁进行实现 + */ +#define SHELL_USING_LOCK 1 + +/** + * @brief shell内存分配 + * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 + */ +#define SHELL_MALLOC(size) pvPortMalloc(size) + +/** + * @brief shell内存释放 + * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 + */ +#define SHELL_FREE(obj) vPortFree(obj) + +#endif diff --git a/User/system/letter_shell/shell_cmd_list.c b/User/system/letter_shell/shell_cmd_list.c new file mode 100644 index 0000000..139a531 --- /dev/null +++ b/User/system/letter_shell/shell_cmd_list.c @@ -0,0 +1,103 @@ +/** + * @file shell_cmd_list.c + * @author Letter (NevermindZZT@gmail.com) + * @brief shell cmd list + * @version 3.0.0 + * @date 2020-01-17 + * + * @copyright (c) 2020 Letter + * + */ + +#include "shell.h" + +#if SHELL_USING_CMD_EXPORT != 1 + +extern int shellSetVar(char *name, int value); +extern void shellUp(Shell *shell); +extern void shellDown(Shell *shell); +extern void shellRight(Shell *shell); +extern void shellLeft(Shell *shell); +extern void shellTab(Shell *shell); +extern void shellBackspace(Shell *shell); +extern void shellDelete(Shell *shell); +extern void shellEnter(Shell *shell); +extern void shellHelp(int argc, char *argv[]); +extern void shellUsers(void); +extern void shellCmds(void); +extern void shellVars(void); +extern void shellKeys(void); +extern void shellClear(void); +#if SHELL_EXEC_UNDEF_FUNC == 1 +extern int shellExecute(int argc, char *argv[]); +#endif + +SHELL_AGENCY_FUNC(shellRun, shellGetCurrent(), (const char *)p1); + + +/** + * @brief shell命令表 + * + */ +const ShellCommand shellCommandList[] = +{ + {.attr.value=SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_USER), + .data.user.name = SHELL_DEFAULT_USER, + .data.user.password = SHELL_DEFAULT_USER_PASSWORD, + .data.user.desc = "default user"}, + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), + setVar, shellSetVar, set var), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0), 0x1B5B4100, shellUp, up), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0), 0x1B5B4200, shellDown, down), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x1B5B4300, shellRight, right), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x1B5B4400, shellLeft, left), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0), 0x09000000, shellTab, tab), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x08000000, shellBackspace, backspace), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x7F000000, shellDelete, delete), + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x1B5B337E, shellDelete, delete), +#if SHELL_ENTER_LF == 1 + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x0A000000, shellEnter, enter), +#endif +#if SHELL_ENTER_CR == 1 + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x0D000000, shellEnter, enter), +#endif +#if SHELL_ENTER_CRLF == 1 + SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED, + 0x0D0A0000, shellEnter, enter), +#endif + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN, + help, shellHelp, show command info\r\nhelp [cmd]), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, + users, shellUsers, list all user), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, + cmds, shellCmds, list all cmd), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, + vars, shellVars, list all var), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, + keys, shellKeys, list all key), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, + clear, shellClear, clear console), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, + sh, SHELL_AGENCY_FUNC_NAME(shellRun), run command directly), +#if SHELL_EXEC_UNDEF_FUNC == 1 + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN, + exec, shellExecute, execute function undefined), +#endif +}; + + +/** + * @brief shell命令表大小 + * + */ +const unsigned short shellCommandCount + = sizeof(shellCommandList) / sizeof(ShellCommand); + +#endif diff --git a/User/system/letter_shell/shell_companion.c b/User/system/letter_shell/shell_companion.c new file mode 100644 index 0000000..eb494c7 --- /dev/null +++ b/User/system/letter_shell/shell_companion.c @@ -0,0 +1,87 @@ +/** + * @file shell_companion.c + * @author Letter (nevermindzzt@gmail.com) + * @brief shell companion object support + * @version 3.0.3 + * @date 2020-07-22 + * + * @copyright (c) 2020 Letter + * + */ + #include "shell.h" + +#if SHELL_USING_COMPANION == 1 +/** + * @brief shell添加伴生对象 + * + * @param shell shell对象 + * @param id 伴生对象ID + * @param object 伴生对象 + * @return signed char 0 添加成功 -1 添加失败 + */ +signed char shellCompanionAdd(Shell *shell, int id, void *object) +{ + ShellCompanionObj *companions = shell->info.companions; + ShellCompanionObj *node = SHELL_MALLOC(sizeof(ShellCompanionObj)); + SHELL_ASSERT(node, return -1); + node->id = id; + node->obj = object; + node->next = companions; + shell->info.companions = node; + return 0; +} + +/** + * @brief shell删除伴生对象 + * + * @param shell shell对象 + * @param id 伴生对象ID + * @return signed char 0 删除成功 -1 无匹配对象 + */ +signed char shellCompanionDel(Shell *shell, int id) +{ + ShellCompanionObj *companions = shell->info.companions; + ShellCompanionObj *front = companions; + while (companions) + { + if (companions->id == id) + { + if (companions == shell->info.companions && !(companions->next)) + { + shell->info.companions = (void *)0; + } + else + { + front->next = companions->next; + } + SHELL_FREE(companions); + return 0; + } + front = companions; + companions = companions->next; + } + return -1; +} + +/** + * @brief shell获取伴生对象 + * + * @param shell shell对象 + * @param id 伴生对象ID + * @return void* 伴生对象,无匹配对象时返回NULL + */ +void *shellCompanionGet(Shell *shell, int id) +{ + SHELL_ASSERT(shell, return (void *)0); + ShellCompanionObj *companions = shell->info.companions; + while (companions) + { + if (companions->id == id) + { + return companions->obj; + } + companions = companions->next; + } + return (void *)0; +} +#endif /** SHELL_USING_COMPANION == 1 */ diff --git a/User/system/letter_shell/shell_ext.c b/User/system/letter_shell/shell_ext.c new file mode 100644 index 0000000..40ae537 --- /dev/null +++ b/User/system/letter_shell/shell_ext.c @@ -0,0 +1,848 @@ +/** + * @file shell_ext.c + * @author Letter (NevermindZZT@gmail.com) + * @brief shell extensions + * @version 3.0.0 + * @date 2019-12-31 + * + * @copyright (c) 2019 Letter + * + */ + +#include "shell_cfg.h" +#include "shell.h" +#include "shell_ext.h" +#include "string.h" + +extern ShellCommand* shellSeekCommand(Shell *shell, + const char *cmd, + ShellCommand *base, + unsigned short compareLength); +extern int shellGetVarValue(Shell *shell, ShellCommand *command); + +#if SHELL_SUPPORT_ARRAY_PARAM == 1 +extern int shellSplit(char *string, unsigned short strLen, char *array[], char splitKey, short maxNum); + +static int shellExtParseArray(Shell *shell, char *string, char *type, size_t *result); +static int shellExtCleanerArray(Shell *shell, char *type, void *param); +#endif /** SHELL_SUPPORT_ARRAY_PARAM == 1 */ + +#if SHELL_USING_FUNC_SIGNATURE == 1 +/** + * @brief 获取下一个参数类型 + * + * @param signature 函数签名 + * @param index 参数遍历在签名中的起始索引 + * @param type 获取到的参数类型 + * + * @return int 下一个参数在签名中的索引 + */ +static int shellGetNextParamType(const char *signature, int index, char *type) +{ + const char *p = signature + index; +#if SHELL_SUPPORT_ARRAY_PARAM == 1 + if (*p == '[') + { + *type++ = *p++; + index++; + } +#endif /** SHELL_SUPPORT_ARRAY_PARAM == 1 */ + if (*p == 'L') + { + while (*p != ';' && *p != 0) + { + *type++ = *p++; + index++; + } + *type++ = *p++; + index++; + } + else if (*p != 0) + { + *type++ = *p; + index++; + } + *type = '\0'; + return index; +} + +/** + * @brief 获取期待的参数个数 + * + * @param signature 函数签名 + * + * @return int 参数个数 + */ +static int shellGetParamNumExcept(const char *signature) +{ + int num = 0; + const char *p = signature; + + while (*p) + { + #if SHELL_SUPPORT_ARRAY_PARAM == 1 + if (*p == '[') + { + p++; + } + #endif /** SHELL_SUPPORT_ARRAY_PARAM == 1 */ + if (*p == 'L') + { + while (*p != ';' && *p != 0) + { + p++; + } + p++; + } + else + { + p++; + } + num++; + } + return num; +} +#endif + +/** + * @brief 判断数字进制 + * + * @param string 参数字符串 + * @return ShellNumType 进制 + */ +static ShellNumType shellExtNumType(char *string) +{ + char *p = string; + ShellNumType type = NUM_TYPE_DEC; + + if ((*p == '0') && ((*(p + 1) == 'x') || (*(p + 1) == 'X'))) + { + type = NUM_TYPE_HEX; + } + else if ((*p == '0') && ((*(p + 1) == 'b') || (*(p + 1) == 'B'))) + { + type = NUM_TYPE_BIN; + } + else if (*p == '0') + { + type = NUM_TYPE_OCT; + } + + while (*p++) + { + if (*p == '.' && *(p + 1) != 0) + { + type = NUM_TYPE_FLOAT; + break; + } + } + + return type; +} + + +/** + * @brief 字符转数字 + * + * @param code 字符 + * @return char 数字 + */ +static char shellExtToNum(char code) +{ + if ((code >= '0') && (code <= '9')) + { + return code -'0'; + } + else if ((code >= 'a') && (code <= 'f')) + { + return code - 'a' + 10; + } + else if ((code >= 'A') && (code <= 'F')) + { + return code - 'A' + 10; + } + else + { + return 0; + } +} + + +/** + * @brief 解析字符参数 + * + * @param string 字符串参数 + * @return char 解析出的字符 + */ +static char shellExtParseChar(char *string) +{ + char *p = (*string == '\'') ? (string + 1) : string; + char value = 0; + + if (*p == '\\') + { + switch (*(p + 1)) + { + case 'b': + value = '\b'; + break; + case 'r': + value = '\r'; + break; + case 'n': + value = '\n'; + break; + case 't': + value = '\t'; + break; + case '0': + value = 0; + break; + default: + value = *(p + 1); + break; + } + } + else + { + value = *p; + } + return value; +} + + +/** + * @brief 解析字符串参数 + * + * @param string 字符串参数 + * @return char* 解析出的字符串 + */ +static char* shellExtParseString(char *string) +{ + char *p = string; + unsigned short index = 0; + + if (*string == '\"') + { + p = ++string; + } + + while (*p) + { + if (*p == '\\') + { + *(string + index) = shellExtParseChar(p); + p++; + } + else if (*p == '\"') + { + *(string + index) = 0; + } + else + { + *(string + index) = *p; + } + p++; + index ++; + } + *(string + index) = 0; + return string; +} + + +/** + * @brief 解析数字参数 + * + * @param string 字符串参数 + * @return size_t 解析出的数字 + */ +static size_t shellExtParseNumber(char *string) +{ + ShellNumType type = NUM_TYPE_DEC; + char radix = 10; + char *p = string; + char offset = 0; + signed char sign = 1; + size_t valueInt = 0; + float valueFloat = 0.0; + size_t devide = 0; + + if (*string == '-') + { + sign = -1; + } + + type = shellExtNumType(string + ((sign == -1) ? 1 : 0)); + + switch ((char)type) + { + case NUM_TYPE_HEX: + radix = 16; + offset = 2; + break; + + case NUM_TYPE_OCT: + radix = 8; + offset = 1; + break; + + case NUM_TYPE_BIN: + radix = 2; + offset = 2; + break; + + default: + break; + } + + p = string + offset + ((sign == -1) ? 1 : 0); + + while (*p) + { + if (*p == '.') + { + devide = 1; + p++; + continue; + } + valueInt = valueInt * radix + shellExtToNum(*p); + devide *= 10; + p++; + } + if (type == NUM_TYPE_FLOAT && devide != 0) + { + valueFloat = (float)valueInt / devide * sign; + return *(size_t *)(&valueFloat); + } + else + { + return valueInt * sign; + } +} + + +/** + * @brief 解析变量参数 + * + * @param shell shell对象 + * @param var 变量 + * @param result 解析结果 + * + * @return int 0 解析成功 --1 解析失败 + */ +static int shellExtParseVar(Shell *shell, char *var, size_t *result) +{ + ShellCommand *command = shellSeekCommand(shell, + var + 1, + shell->commandList.base, + 0); + if (command) + { + *result = shellGetVarValue(shell, command); + return 0; + } + else + { + return -1; + } +} + + +/** + * @brief 解析参数 + * + * @param shell shell对象 + * @param string 参数 + * @param type 参数类型 + * @param result 解析结果 + * + * @return int 0 解析成功 --1 解析失败 + */ +int shellExtParsePara(Shell *shell, char *string, char *type, size_t *result) +{ + if (type == NULL || (*string == '$' && *(string + 1))) + { + if (*string == '\'' && *(string + 1)) + { + *result = (size_t)shellExtParseChar(string); + return 0; + } + else if (*string == '-' || (*string >= '0' && *string <= '9')) + { + *result = shellExtParseNumber(string); + return 0; + } + else if (*string == '$' && *(string + 1)) + { + return shellExtParseVar(shell, string, result); + } + else if (*string) + { + *result = (size_t)shellExtParseString(string); + return 0; + } + } +#if SHELL_USING_FUNC_SIGNATURE == 1 + else + { + if (*string == '$' && *(string + 1)) + { + return shellExtParseVar(shell, string, result); + } + #if SHELL_SUPPORT_ARRAY_PARAM == 1 + else if (type[0] == '[') + { + return shellExtParseArray(shell, string, type, result); + } + #endif /** SHELL_SUPPORT_ARRAY_PARAM == 1 */ + else if (strcmp("c", type) == 0) + { + *result = (size_t)shellExtParseChar(string); + return 0; + } + else if (strcmp("q", type) == 0 + || strcmp("h", type) == 0 + || strcmp("i", type) == 0 + || strcmp("f", type) == 0 + || strcmp("p", type) == 0) + { + *result = shellExtParseNumber(string); + return 0; + } + else if (strcmp("s", type) == 0) + { + *result = (size_t)shellExtParseString(string); + return 0; + } + else + { + ShellCommand *command = shellSeekCommand(shell, + type, + shell->commandList.base, + 0); + if (command != NULL) + { + void *param; + if (command->data.paramParser.parser(shellExtParseString(string), ¶m) == 0) + { + *result = (size_t)param; + return 0; + } + else + { + shellWriteString(shell, "Parse param for type: "); + shellWriteString(shell, type); + shellWriteString(shell, " failed\r\n"); + return -1; + } + } + else + { + shellWriteString(shell, "Can't find the param parser for type: "); + shellWriteString(shell, type); + shellWriteString(shell, "\r\n"); + return -1; + } + } + } +#endif /** SHELL_USING_FUNC_SIGNATURE == 1 */ + return -1; +} + + +#if SHELL_USING_FUNC_SIGNATURE == 1 +/** + * @brief 清理参数 + * + * @param shell shell + * @param type 参数类型 + * @param param 参数 + * + * @return int 0 清理成功 -1 清理失败 + */ +int shellExtCleanerPara(Shell *shell, char *type, size_t param) +{ + if (type == NULL) + { + return 0; + } + else + { + #if SHELL_SUPPORT_ARRAY_PARAM == 1 + if (type[0] == '[') { + return shellExtCleanerArray(shell, type, (void *) param); + } + else + #endif /** SHELL_SUPPORT_ARRAY_PARAM == 1 */ + if (strcmp("c", type) == 0 + || strcmp("q", type) == 0 + || strcmp("h", type) == 0 + || strcmp("i", type) == 0 + || strcmp("f", type) == 0 + || strcmp("p", type) == 0 + || strcmp("s", type) == 0) + { + return 0; + } + else + { + ShellCommand *command = shellSeekCommand(shell, + type, + shell->commandList.base, + 0); + if (command != NULL && command->data.paramParser.cleaner != NULL) + { + return command->data.paramParser.cleaner((void *)param); + } + } + } + return -1; +} +#endif /** SHELL_USING_FUNC_SIGNATURE == 1 */ + +#if SHELL_SUPPORT_ARRAY_PARAM == 1 +/** + * @brief 估算数组长度 + * + * @param string 数组参数 + * + * @return int 估算的数组长度 + */ +static int shellEstimateArrayLength(char *string) +{ + int length = 0; + char *p = string; + while (*p) + { + if (*p == ',') + { + length++; + } + p++; + } + return length + 1; +} + +/** + * @brief 分割数组参数 + * + * @param string 数组参数 + * @param array 分割后的字符串数组 + * + * @return int 数组长度 + */ +static int shellSplitArray(char *string, char ***array) +{ + int strLen = strlen(string); + if (string[strLen - 1] == ']') + { + string[--strLen] = 0; + } + if (string[0] == '[') + { + --strLen; + string++; + } + int size = shellEstimateArrayLength(string); + *array = SHELL_MALLOC(size * sizeof(char *)); + return shellSplit(string, strLen, *array, ',', size); +} + +/** + * @brief 解析数组参数 + * + * @param shell shell 对象 + * @param string 数组参数 + * @param type 参数类型 + * @param result 解析结果 + * + * @return int 0 解析成功 -1 解析失败 + */ +static int shellExtParseArray(Shell *shell, char *string, char *type, size_t *result) +{ + char **params; + int size = shellSplitArray(string, ¶ms); + int elementBytes = sizeof(void *); + + if (strcmp(type + 1, "q") == 0) + { + elementBytes = sizeof(char); + } + else if (strcmp(type + 1, "h") == 0) + { + elementBytes = sizeof(short); + } + else if (strcmp(type + 1, "i") == 0) + { + elementBytes = sizeof(int); + } + + ShellArrayHeader *header = SHELL_MALLOC(elementBytes * size + sizeof(ShellArrayHeader)); + *result = (size_t) ((size_t) header + sizeof(ShellArrayHeader)); + header->size = size; + header->elementBytes = elementBytes; + for (short i = 0; i < size; i++) + { + size_t value; + if (shellExtParsePara(shell, params[i], type + 1, &value) != 0) + { + SHELL_FREE(header); + SHELL_FREE(params); + return -1; + } + memcpy((void *) ((size_t) *result + elementBytes * i), &value, elementBytes); + } + + SHELL_FREE(params); + return 0; +} + +/** + * @brief 清理数组参数 + * + * @param shell shell 对象 + * @param type 参数类型 + * @param param 参数 + * + * @return int 0 清理成功 -1 清理失败 + */ +static int shellExtCleanerArray(Shell *shell, char *type, void *param) +{ + ShellArrayHeader *header = (ShellArrayHeader *) ((size_t) param - sizeof(ShellArrayHeader)); + for (short i = 0; i < header->size; i++) + { + if (shellExtCleanerPara(shell, type + 1, *(size_t *) ((size_t) param + header->elementBytes * i)) != 0) + { + return -1; + } + } + SHELL_FREE(header); + return 0; +} + +/** + * @brief 获取数组大小 + * + * @param param 数组 + * + * @return int 数组大小 + */ +int shellGetArrayParamSize(void *param) +{ + ShellArrayHeader *header = (ShellArrayHeader *) ((size_t) param - sizeof(ShellArrayHeader)); + return header->size; +} +#endif /** SHELL_SUPPORT_ARRAY_PARAM == 1 */ + + +/** + * @brief 执行命令 + * + * @param shell shell对象 + * @param command 命令 + * @param argc 参数个数 + * @param argv 参数 + * @return int 返回值 + */ +int shellExtRun(Shell *shell, ShellCommand *command, int argc, char *argv[]) +{ + int ret = 0; + size_t params[SHELL_PARAMETER_MAX_NUMBER] = {0}; + int paramNum = command->attr.attrs.paramNum > (argc - 1) ? + command->attr.attrs.paramNum : (argc - 1); +#if SHELL_USING_FUNC_SIGNATURE == 1 + char type[16]; + int index = 0; + + if (command->data.cmd.signature != NULL) + { + int except = shellGetParamNumExcept(command->data.cmd.signature); + if (except != argc - 1) + { + shellWriteString(shell, "Parameters number incorrect\r\n"); + return -1; + } + } +#endif + for (int i = 0; i < argc - 1; i++) + { + #if SHELL_USING_FUNC_SIGNATURE == 1 + if (command->data.cmd.signature != NULL) { + index = shellGetNextParamType(command->data.cmd.signature, index, type); + if (shellExtParsePara(shell, argv[i + 1], type, ¶ms[i]) != 0) + { + return -1; + } + } + else + #endif /** SHELL_USING_FUNC_SIGNATURE == 1 */ + { + if (shellExtParsePara(shell, argv[i + 1], NULL, ¶ms[i]) != 0) + { + return -1; + } + } + } + switch (paramNum) + { +#if SHELL_PARAMETER_MAX_NUMBER >= 1 + case 0: + ret = command->data.cmd.function(); + break; +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 1 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 2 + case 1: + { + int (*func)(size_t) = command->data.cmd.function; + ret = func(params[0]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 2 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 3 + case 2: + { + int (*func)(size_t, size_t) = command->data.cmd.function; + ret = func(params[0], params[1]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 3 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 4 + case 3: + { + int (*func)(size_t, size_t, size_t) = command->data.cmd.function; + ret = func(params[0], params[1], params[2]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 4 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 5 + case 4: + { + int (*func)(size_t, size_t, size_t, size_t) = command->data.cmd.function; + ret = func(params[0], params[1], params[2], params[3]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 5 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 6 + case 5: + { + int (*func)(size_t, size_t, size_t, size_t, size_t) = command->data.cmd.function; + ret = func(params[0], params[1], params[2], params[3], params[4]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 6 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 7 + case 6: + { + int (*func)(size_t, size_t, size_t, size_t, size_t, size_t) = command->data.cmd.function; + ret = func(params[0], params[1], params[2], params[3], params[4], params[5]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 7 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 8 + case 7: + { + int (*func)(size_t, size_t, size_t, size_t, size_t, size_t, size_t) = command->data.cmd.function; + ret = func(params[0], params[1], params[2], params[3], params[4], params[5], params[6]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 8 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 9 + case 8: + { + int (*func)(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t) + = command->data.cmd.function; + ret = func(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 9 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 10 + case 9: + { + int (*func)(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, + size_t) = command->data.cmd.function; + ret = func(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7], + params[8]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 10 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 11 + case 10: + { + int (*func)(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, + size_t, size_t) = command->data.cmd.function; + ret = func(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7], + params[8], params[9]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 11 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 12 + case 11: + { + int (*func)(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, + size_t, size_t, size_t) = command->data.cmd.function; + ret = func(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7], + params[8], params[9], params[10]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 12 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 13 + case 12: + { + int (*func)(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, + size_t, size_t, size_t, size_t) = command->data.cmd.function; + ret = func(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7], + params[8], params[9], params[10], params[11]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 13 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 14 + case 13: + { + int (*func)(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, + size_t, size_t, size_t, size_t, size_t) = command->data.cmd.function; + ret = func(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7], + params[8], params[9], params[10], params[11], params[12]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 14 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 15 + case 14: + { + int (*func)(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, + size_t, size_t, size_t, size_t, size_t, size_t) + = command->data.cmd.function; + ret = func(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7], + params[8], params[9], params[10], params[11], params[12], params[13]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 15 */ +#if SHELL_PARAMETER_MAX_NUMBER >= 16 + case 15: + { + int (*func)(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, + size_t, size_t, size_t, size_t, size_t, size_t, size_t) + = command->data.cmd.function; + ret = func(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7], + params[8], params[9], params[10], params[11], params[12], params[13], params[14]); + break; + } +#endif /** SHELL_PARAMETER_MAX_NUMBER >= 16 */ + default: + ret = -1; + break; + } + +#if SHELL_USING_FUNC_SIGNATURE == 1 + if (command->data.cmd.signature != NULL) { + index = 0; + for (int i = 0; i < argc - 1; i++) + { + index = shellGetNextParamType(command->data.cmd.signature, index, type); + shellExtCleanerPara(shell, type, params[i]); + } + } +#endif /** SHELL_USING_FUNC_SIGNATURE == 1 */ + + return ret; +} + diff --git a/User/system/letter_shell/shell_ext.h b/User/system/letter_shell/shell_ext.h new file mode 100644 index 0000000..d87b4c3 --- /dev/null +++ b/User/system/letter_shell/shell_ext.h @@ -0,0 +1,47 @@ +/** + * @file shell_ext.h + * @author Letter (NevermindZZT@gmail.com) + * @brief shell extensions + * @version 3.0.0 + * @date 2019-12-31 + * + * @copyright (c) 2019 Letter + * + */ + +#ifndef __SHELL_EXT_H__ +#define __SHELL_EXT_H__ +#include +#include "shell.h" + +/** + * @brief 数字类型 + * + */ +typedef enum +{ + NUM_TYPE_DEC, /**< 十进制整型 */ + NUM_TYPE_BIN, /**< 二进制整型 */ + NUM_TYPE_OCT, /**< 八进制整型 */ + NUM_TYPE_HEX, /**< 十六进制整型 */ + NUM_TYPE_FLOAT /**< 浮点型 */ +} ShellNumType; + +#if SHELL_SUPPORT_ARRAY_PARAM == 1 +typedef struct +{ + unsigned short size; + unsigned char elementBytes; +} ShellArrayHeader; +#endif /** SHELL_SUPPORT_ARRAY_PARAM == 1 */ + +int shellExtParsePara(Shell *shell, char *string, char *type, size_t *result); +#if SHELL_USING_FUNC_SIGNATURE == 1 +int shellExtCleanerPara(Shell *shell, char *type, size_t param); +#endif /** SHELL_USING_FUNC_SIGNATURE == 1 */ +#if SHELL_SUPPORT_ARRAY_PARAM == 1 +int shellGetArrayParamSize(void *param); +#endif /** SHELL_SUPPORT_ARRAY_PARAM == 1 */ +int shellExtRun(Shell *shell, ShellCommand *command, int argc, char *argv[]); + +#endif diff --git a/User/system/letter_shell/shell_port.c b/User/system/letter_shell/shell_port.c new file mode 100644 index 0000000..fa4e72f --- /dev/null +++ b/User/system/letter_shell/shell_port.c @@ -0,0 +1,132 @@ +/** + * @file shell_port.c + */ + +#include "FreeRTOS.h" +#include "task.h" +#include "shell.h" + +#include "stm32f4xx_hal.h" +#include "usart.h" + +#include "shell_port.h" +#include "semphr.h" + +Shell shell; +char shellBuffer[512]; + +static SemaphoreHandle_t shellMutex; + +// 串口接收缓冲区(环形队列) +#define SHELL_UART_RX_BUF_SIZE 128 +static uint8_t shell_uart_rx_buf[SHELL_UART_RX_BUF_SIZE]; +static volatile uint16_t shell_uart_rx_head = 0; +static volatile uint16_t shell_uart_rx_tail = 0; +static uint8_t shell_uart_rx_temp; + +/** + * @brief 用户shell写 + * + * @param data 数据 + * @param len 数据长度 + * + * @return short 实际写入的数据长度 + */ +short userShellWrite(char *data, unsigned short len) +{ + HAL_UART_Transmit(&huart1, (uint8_t *)data, len, 0x1FF); + return len; +} + +/** + * @brief 用户shell读 + * + * @param data 数据 + * @param len 数据长度 + * + * @return short 实际读取到 + */ + +// 从环形缓冲区读取数据 +short userShellRead(char *data, unsigned short len) +{ + unsigned short count = 0; + while (count < len) + { + if (shell_uart_rx_head == shell_uart_rx_tail) + { + // 缓冲区无数据 + break; + } + data[count++] = shell_uart_rx_buf[shell_uart_rx_tail]; + shell_uart_rx_tail = (shell_uart_rx_tail + 1) % SHELL_UART_RX_BUF_SIZE; + } + return count; +} + +/** + * @brief 用户shell上锁 + * + * @param shell shell + * + * @return int 0 + */ +int userShellLock(Shell *shell) +{ + // xSemaphoreTakeRecursive(shellMutex, portMAX_DELAY); + xSemaphoreTake(shellMutex, portMAX_DELAY); + return 0; +} + +/** + * @brief 用户shell解锁 + * + * @param shell shell + * + * @return int 0 + */ +int userShellUnlock(Shell *shell) +{ + // xSemaphoreGiveRecursive(shellMutex); + xSemaphoreGive(shellMutex); + return 0; +} + +/** + * @brief 用户shell初始化 + * + */ +void userShellInit(void) +{ + shellMutex = xSemaphoreCreateMutex(); + + shell.write = userShellWrite; + shell.read = userShellRead; + shell.lock = userShellLock; + shell.unlock = userShellUnlock; + shellInit(&shell, shellBuffer, 512); + + // 启动串口中断接收 + HAL_UART_Receive_IT(&huart1, &shell_uart_rx_temp, 1); + // if (xTaskCreate(shellTask, "shell", 256, &shell, 5, NULL) != pdPASS) + // { + //// logError("shell task creat failed"); + // } +} + +// 串口接收完成回调(在 usart.c 里实现也可) +void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) +{ + if (huart->Instance == USART1) + { + uint16_t next = (shell_uart_rx_head + 1) % SHELL_UART_RX_BUF_SIZE; + if (next != shell_uart_rx_tail) + { + shell_uart_rx_buf[shell_uart_rx_head] = shell_uart_rx_temp; + shell_uart_rx_head = next; + } + // 继续接收下一个字节 + HAL_UART_Receive_IT(&huart1, &shell_uart_rx_temp, 1); + } +} +// CEVENT_EXPORT(EVENT_INIT_STAGE2, userShellInit); diff --git a/User/system/letter_shell/shell_port.h b/User/system/letter_shell/shell_port.h new file mode 100644 index 0000000..267ac8d --- /dev/null +++ b/User/system/letter_shell/shell_port.h @@ -0,0 +1,14 @@ +/** + * @file shell_port.h + */ + +#ifndef __SHELL_PORT_H__ +#define __SHELL_PORT_H__ + +#include "semphr.h" +#include "shell.h" + +extern Shell shell; + +void userShellInit(void); +#endif diff --git a/User/system/lua/Makefile b/User/system/lua/Makefile new file mode 100644 index 0000000..72ca8ff --- /dev/null +++ b/User/system/lua/Makefile @@ -0,0 +1,106 @@ +# Makefile for installing Lua +# See doc/readme.html for installation and customization instructions. + +# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= + +# Your platform. See PLATS for possible values. +PLAT= guess + +# Where to install. The installation starts in the src and doc directories, +# so take care if INSTALL_TOP is not an absolute path. See the local target. +# You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with +# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h. +INSTALL_TOP= /usr/local +INSTALL_BIN= $(INSTALL_TOP)/bin +INSTALL_INC= $(INSTALL_TOP)/include +INSTALL_LIB= $(INSTALL_TOP)/lib +INSTALL_MAN= $(INSTALL_TOP)/man/man1 +INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V +INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V + +# How to install. If your install program does not support "-p", then +# you may have to run ranlib on the installed liblua.a. +INSTALL= install -p +INSTALL_EXEC= $(INSTALL) -m 0755 +INSTALL_DATA= $(INSTALL) -m 0644 +# +# If you don't have "install" you can use "cp" instead. +# INSTALL= cp -p +# INSTALL_EXEC= $(INSTALL) +# INSTALL_DATA= $(INSTALL) + +# Other utilities. +MKDIR= mkdir -p +RM= rm -f + +# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= + +# Convenience platforms targets. +PLATS= guess aix bsd c89 freebsd generic ios linux linux-readline macosx mingw posix solaris + +# What to install. +TO_BIN= lua luac +TO_INC= lua.h luaconf.h lualib.h lauxlib.h lua.hpp +TO_LIB= liblua.a +TO_MAN= lua.1 luac.1 + +# Lua version and release. +V= 5.4 +R= $V.7 + +# Targets start here. +all: $(PLAT) + +$(PLATS) help test clean: + @cd src && $(MAKE) $@ + +install: dummy + cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD) + cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN) + cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC) + cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB) + cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN) + +uninstall: + cd src && cd $(INSTALL_BIN) && $(RM) $(TO_BIN) + cd src && cd $(INSTALL_INC) && $(RM) $(TO_INC) + cd src && cd $(INSTALL_LIB) && $(RM) $(TO_LIB) + cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN) + +local: + $(MAKE) install INSTALL_TOP=../install + +# make may get confused with install/ if it does not support .PHONY. +dummy: + +# Echo config parameters. +echo: + @cd src && $(MAKE) -s echo + @echo "PLAT= $(PLAT)" + @echo "V= $V" + @echo "R= $R" + @echo "TO_BIN= $(TO_BIN)" + @echo "TO_INC= $(TO_INC)" + @echo "TO_LIB= $(TO_LIB)" + @echo "TO_MAN= $(TO_MAN)" + @echo "INSTALL_TOP= $(INSTALL_TOP)" + @echo "INSTALL_BIN= $(INSTALL_BIN)" + @echo "INSTALL_INC= $(INSTALL_INC)" + @echo "INSTALL_LIB= $(INSTALL_LIB)" + @echo "INSTALL_MAN= $(INSTALL_MAN)" + @echo "INSTALL_LMOD= $(INSTALL_LMOD)" + @echo "INSTALL_CMOD= $(INSTALL_CMOD)" + @echo "INSTALL_EXEC= $(INSTALL_EXEC)" + @echo "INSTALL_DATA= $(INSTALL_DATA)" + +# Echo pkg-config data. +pc: + @echo "version=$R" + @echo "prefix=$(INSTALL_TOP)" + @echo "libdir=$(INSTALL_LIB)" + @echo "includedir=$(INSTALL_INC)" + +# Targets that do not create files (not all makes understand .PHONY). +.PHONY: all $(PLATS) help test clean install uninstall local dummy echo pc + +# (end of Makefile) diff --git a/User/system/lua/README b/User/system/lua/README new file mode 100644 index 0000000..fe99b87 --- /dev/null +++ b/User/system/lua/README @@ -0,0 +1,6 @@ + +This is Lua 5.4.7, released on 13 Jun 2024. + +For installation instructions, license details, and +further information about Lua, see doc/readme.html. + diff --git a/User/system/lua/doc/OSIApproved_100X125.png b/User/system/lua/doc/OSIApproved_100X125.png new file mode 100644 index 0000000..795f7a0 Binary files /dev/null and b/User/system/lua/doc/OSIApproved_100X125.png differ diff --git a/User/system/lua/doc/index.css b/User/system/lua/doc/index.css new file mode 100644 index 0000000..c961835 --- /dev/null +++ b/User/system/lua/doc/index.css @@ -0,0 +1,21 @@ +ul { + list-style-type: none ; +} + +ul.contents { + padding: 0 ; +} + +table { + border: none ; + border-spacing: 0 ; + border-collapse: collapse ; +} + +td { + vertical-align: top ; + padding: 0 ; + text-align: left ; + line-height: 1.25 ; + width: 15% ; +} diff --git a/User/system/lua/doc/logo.gif b/User/system/lua/doc/logo.gif new file mode 100644 index 0000000..5c77eac Binary files /dev/null and b/User/system/lua/doc/logo.gif differ diff --git a/User/system/lua/doc/lua.1 b/User/system/lua/doc/lua.1 new file mode 100644 index 0000000..3c9e000 --- /dev/null +++ b/User/system/lua/doc/lua.1 @@ -0,0 +1,155 @@ +.\" $Id: lua.man,v 1.14 2024/05/08 18:48:27 lhf Exp $ +.TH LUA 1 "$Date: 2024/05/08 18:48:27 $" +.SH NAME +lua \- Lua interpreter +.SH SYNOPSIS +.B lua +[ +.I options +] +[ +.I script +[ +.I args +] +] +.SH DESCRIPTION +.B lua +is the standalone Lua interpreter. +It loads and executes Lua programs, +either in textual source form or +in precompiled binary form. +(Precompiled binaries are output by +.BR luac , +the Lua compiler.) +.B lua +can be used as a batch interpreter and also interactively. +.LP +After handling the +.IR options , +the Lua program in file +.I script +is loaded and executed. +The +.I args +are available to +.I script +as strings in a global table named +.B arg +and also as arguments to its main function. +When called without arguments, +.B lua +behaves as +.B "lua \-v \-i" +if the standard input is a terminal, +and as +.B "lua \-" +otherwise. +.LP +In interactive mode, +.B lua +prompts the user, +reads lines from the standard input, +and executes them as they are read. +If the line contains an expression, +then the line is evaluated and the result is printed. +If a line does not contain a complete statement, +then a secondary prompt is displayed and +lines are read until a complete statement is formed or +a syntax error is found. +.LP +Before handling command line options and scripts, +.B lua +checks the contents of the environment variables +.B LUA_INIT_5_4 +and +.BR LUA_INIT , +in that order. +If the contents are of the form +.RI '@ filename ', +then +.I filename +is executed. +Otherwise, the contents are assumed to be a Lua statement and is executed. +When +.B LUA_INIT_5_4 +is defined, +.B LUA_INIT +is ignored. +.SH OPTIONS +.TP +.BI \-e " stat" +execute statement +.IR stat . +.TP +.B \-i +enter interactive mode after executing +.IR script . +.TP +.BI \-l " mod" +require library +.I mod +into global +.IR mod . +.TP +.BI \-l " g=mod" +require library +.I mod +into global +.IR g . +.TP +.B \-v +show version information. +.TP +.B \-E +ignore environment variables. +.TP +.B \-W +turn warnings on. +.TP +.B \-\- +stop handling options. +.TP +.B \- +stop handling options and execute the standard input as a file. +.SH ENVIRONMENT VARIABLES +The following environment variables affect the execution of +.BR lua . +When defined, +the version-specific variants take priority +and the version-neutral variants are ignored. +.TP +.B LUA_INIT, LUA_INIT_5_4 +Code to be executed before command line options and scripts. +.TP +.B LUA_PATH, LUA_PATH_5_4 +Initial value of package.path, +the path used by require to search for Lua loaders. +.TP +.B LUA_CPATH, LUA_CPATH_5_4 +Initial value of package.cpath, +the path used by require to search for C loaders. +.SH EXIT STATUS +If a script calls os.exit, +then +.B lua +exits with the given exit status. +Otherwise, +.B lua +exits +with EXIT_SUCCESS (0 on POSIX systems) if there were no errors +and +with EXIT_FAILURE (1 on POSIX systems) if there were errors. +Errors raised in interactive mode do not cause exits. +.SH DIAGNOSTICS +Error messages should be self explanatory. +.SH "SEE ALSO" +.BR luac (1) +.br +The documentation at lua.org, +especially section 7 of the reference manual. +.SH AUTHORS +R. Ierusalimschy, +L. H. de Figueiredo, +W. Celes +.\" EOF diff --git a/User/system/lua/doc/lua.css b/User/system/lua/doc/lua.css new file mode 100644 index 0000000..9013b44 --- /dev/null +++ b/User/system/lua/doc/lua.css @@ -0,0 +1,162 @@ +html { + background-color: #F8F8F8 ; +} + +body { + background-color: #FFFFFF ; + color: #000000 ; + font-family: Helvetica, Arial, sans-serif ; + text-align: justify ; + line-height: 1.25 ; + margin: 16px auto ; + padding: 32px ; + border: solid #ccc 1px ; + border-radius: 20px ; + max-width: 70em ; + width: 90% ; +} + +h1, h2, h3, h4 { + color: #000080 ; + font-family: Verdana, Geneva, sans-serif ; + font-weight: normal ; + font-style: normal ; + text-align: left ; +} + +h1 { + font-size: 28pt ; +} + +h1 img { + vertical-align: text-bottom ; +} + +h2:before { + content: "\2756" ; + padding-right: 0.5em ; +} + +a { + text-decoration: none ; +} + +a:link { + color: #000080 ; +} + +a:link:hover, a:visited:hover { + background-color: #D0D0FF ; + color: #000080 ; + border-radius: 4px ; +} + +a:link:active, a:visited:active { + color: #FF0000 ; +} + +div.menubar { + padding-bottom: 0.5em ; +} + +p.menubar { + margin-left: 2.5em ; +} + +.menubar a:hover { + margin: -3px -3px -3px -3px ; + padding: 3px 3px 3px 3px ; + border-radius: 4px ; +} + +:target { + background-color: #F0F0F0 ; + margin: -8px ; + padding: 8px ; + border-radius: 8px ; + outline: none ; +} + +hr { + display: none ; +} + +table hr { + background-color: #a0a0a0 ; + color: #a0a0a0 ; + border: 0 ; + height: 1px ; + display: block ; +} + +.footer { + color: gray ; + font-size: x-small ; + text-transform: lowercase ; +} + +input[type=text] { + border: solid #a0a0a0 2px ; + border-radius: 2em ; + background-image: url('images/search.png') ; + background-repeat: no-repeat ; + background-position: 4px center ; + padding-left: 20px ; + height: 2em ; +} + +pre.session { + background-color: #F8F8F8 ; + padding: 1em ; + border-radius: 8px ; +} + +table { + border: none ; + border-spacing: 0 ; + border-collapse: collapse ; +} + +td { + padding: 0 ; + margin: 0 ; +} + +td.gutter { + width: 4% ; +} + +table.columns td { + vertical-align: top ; + padding-bottom: 1em ; + text-align: justify ; + line-height: 1.25 ; +} + +table.book td { + vertical-align: top ; +} + +table.book td.cover { + padding-right: 1em ; +} + +table.book img { + border: solid #000080 1px ; + border-radius: 2px ; +} + +table.book span { + font-size: small ; + text-align: left ; + display: block ; + margin-top: 0.25em ; +} + +p.logos a:link:hover, p.logos a:visited:hover { + background-color: inherit ; +} + +img { + background-color: white ; +} diff --git a/User/system/lua/doc/luac.1 b/User/system/lua/doc/luac.1 new file mode 100644 index 0000000..33a4ed0 --- /dev/null +++ b/User/system/lua/doc/luac.1 @@ -0,0 +1,118 @@ +.\" $Id: luac.man,v 1.29 2011/11/16 13:53:40 lhf Exp $ +.TH LUAC 1 "$Date: 2011/11/16 13:53:40 $" +.SH NAME +luac \- Lua compiler +.SH SYNOPSIS +.B luac +[ +.I options +] [ +.I filenames +] +.SH DESCRIPTION +.B luac +is the Lua compiler. +It translates programs written in the Lua programming language +into binary files containing precompiled chunks +that can be later loaded and executed. +.LP +The main advantages of precompiling chunks are: +faster loading, +protecting source code from accidental user changes, +and +off-line syntax checking. +Precompiling does not imply faster execution +because in Lua chunks are always compiled into bytecodes before being executed. +.B luac +simply allows those bytecodes to be saved in a file for later execution. +Precompiled chunks are not necessarily smaller than the corresponding source. +The main goal in precompiling is faster loading. +.LP +In the command line, +you can mix +text files containing Lua source and +binary files containing precompiled chunks. +.B luac +produces a single output file containing the combined bytecodes +for all files given. +Executing the combined file is equivalent to executing the given files. +By default, +the output file is named +.BR luac.out , +but you can change this with the +.B \-o +option. +.LP +Precompiled chunks are +.I not +portable across different architectures. +Moreover, +the internal format of precompiled chunks +is likely to change when a new version of Lua is released. +Make sure you save the source files of all Lua programs that you precompile. +.LP +.SH OPTIONS +.TP +.B \-l +produce a listing of the compiled bytecode for Lua's virtual machine. +Listing bytecodes is useful to learn about Lua's virtual machine. +If no files are given, then +.B luac +loads +.B luac.out +and lists its contents. +Use +.B \-l \-l +for a full listing. +.TP +.BI \-o " file" +output to +.IR file , +instead of the default +.BR luac.out . +(You can use +.B "'\-'" +for standard output, +but not on platforms that open standard output in text mode.) +The output file may be one of the given files because +all files are loaded before the output file is written. +Be careful not to overwrite precious files. +.TP +.B \-p +load files but do not generate any output file. +Used mainly for syntax checking and for testing precompiled chunks: +corrupted files will probably generate errors when loaded. +If no files are given, then +.B luac +loads +.B luac.out +and tests its contents. +No messages are displayed if the file loads without errors. +.TP +.B \-s +strip debug information before writing the output file. +This saves some space in very large chunks, +but if errors occur when running a stripped chunk, +then the error messages may not contain the full information they usually do. +In particular, +line numbers and names of local variables are lost. +.TP +.B \-v +show version information. +.TP +.B \-\- +stop handling options. +.TP +.B \- +stop handling options and process standard input. +.SH "SEE ALSO" +.BR lua (1) +.br +The documentation at lua.org. +.SH DIAGNOSTICS +Error messages should be self explanatory. +.SH AUTHORS +R. Ierusalimschy, +L. H. de Figueiredo, +W. Celes +.\" EOF diff --git a/User/system/lua/doc/manual.css b/User/system/lua/doc/manual.css new file mode 100644 index 0000000..aa0e677 --- /dev/null +++ b/User/system/lua/doc/manual.css @@ -0,0 +1,21 @@ +h3 code { + font-family: inherit ; + font-size: inherit ; +} + +pre, code { + font-size: 12pt ; +} + +span.apii { + color: gray ; + float: right ; + font-family: inherit ; + font-style: normal ; + font-size: small ; +} + +h2:before { + content: "" ; + padding-right: 0em ; +} diff --git a/User/system/lua/src/Makefile b/User/system/lua/src/Makefile new file mode 100644 index 0000000..b771196 --- /dev/null +++ b/User/system/lua/src/Makefile @@ -0,0 +1,225 @@ +# Makefile for building Lua +# See ../doc/readme.html for installation and customization instructions. + +# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= + +# Your platform. See PLATS for possible values. +PLAT= guess + +CC= gcc -std=gnu99 +CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_3 $(SYSCFLAGS) $(MYCFLAGS) +LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) +LIBS= -lm $(SYSLIBS) $(MYLIBS) + +AR= ar rcu +RANLIB= ranlib +RM= rm -f +UNAME= uname + +SYSCFLAGS= +SYSLDFLAGS= +SYSLIBS= + +MYCFLAGS= +MYLDFLAGS= +MYLIBS= +MYOBJS= + +# Special flags for compiler modules; -Os reduces code size. +CMCFLAGS= + +# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= + +PLATS= guess aix bsd c89 freebsd generic ios linux linux-readline macosx mingw posix solaris + +LUA_A= liblua.a +CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o +LIB_O= lauxlib.o lbaselib.o lcorolib.o ldblib.o liolib.o lmathlib.o loadlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o linit.o +BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) + +LUA_T= lua +LUA_O= lua.o + +LUAC_T= luac +LUAC_O= luac.o + +ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O) +ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) +ALL_A= $(LUA_A) + +# Targets start here. +default: $(PLAT) + +all: $(ALL_T) + +o: $(ALL_O) + +a: $(ALL_A) + +$(LUA_A): $(BASE_O) + $(AR) $@ $(BASE_O) + $(RANLIB) $@ + +$(LUA_T): $(LUA_O) $(LUA_A) + $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) + +$(LUAC_T): $(LUAC_O) $(LUA_A) + $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) + +test: + ./$(LUA_T) -v + +clean: + $(RM) $(ALL_T) $(ALL_O) + +depend: + @$(CC) $(CFLAGS) -MM l*.c + +echo: + @echo "PLAT= $(PLAT)" + @echo "CC= $(CC)" + @echo "CFLAGS= $(CFLAGS)" + @echo "LDFLAGS= $(LDFLAGS)" + @echo "LIBS= $(LIBS)" + @echo "AR= $(AR)" + @echo "RANLIB= $(RANLIB)" + @echo "RM= $(RM)" + @echo "UNAME= $(UNAME)" + +# Convenience targets for popular platforms. +ALL= all + +help: + @echo "Do 'make PLATFORM' where PLATFORM is one of these:" + @echo " $(PLATS)" + @echo "See doc/readme.html for complete instructions." + +guess: + @echo Guessing `$(UNAME)` + @$(MAKE) `$(UNAME)` + +AIX aix: + $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" + +bsd: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" + +c89: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_C89" CC="gcc -std=c89" + @echo '' + @echo '*** C89 does not guarantee 64-bit integers for Lua.' + @echo '*** Make sure to compile all external Lua libraries' + @echo '*** with LUA_USE_C89 to ensure consistency' + @echo '' + +FreeBSD NetBSD OpenBSD freebsd: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX -DLUA_USE_READLINE -I/usr/include/edit" SYSLIBS="-Wl,-E -ledit" CC="cc" + +generic: $(ALL) + +ios: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_IOS" + +Linux linux: linux-noreadline + +linux-noreadline: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl" + +linux-readline: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX -DLUA_USE_READLINE" SYSLIBS="-Wl,-E -ldl -lreadline" + +Darwin macos macosx: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX -DLUA_USE_READLINE" SYSLIBS="-lreadline" + +mingw: + $(MAKE) "LUA_A=lua54.dll" "LUA_T=lua.exe" \ + "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ + "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe + $(MAKE) "LUAC_T=luac.exe" luac.exe + +posix: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" + +SunOS solaris: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN -D_REENTRANT" SYSLIBS="-ldl" + +# Targets that do not create files (not all makes understand .PHONY). +.PHONY: all $(PLATS) help test clean default o a depend echo + +# Compiler modules may use special flags. +llex.o: + $(CC) $(CFLAGS) $(CMCFLAGS) -c llex.c + +lparser.o: + $(CC) $(CFLAGS) $(CMCFLAGS) -c lparser.c + +lcode.o: + $(CC) $(CFLAGS) $(CMCFLAGS) -c lcode.c + +# DO NOT DELETE + +lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ + lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \ + ltable.h lundump.h lvm.h +lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h +lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ + llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ + ldo.h lgc.h lstring.h ltable.h lvm.h +lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h +ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ + lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \ + ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h +ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ + lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \ + lparser.h lstring.h ltable.h lundump.h lvm.h +ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \ + ltm.h lzio.h lmem.h lundump.h +lfunc.o: lfunc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h +lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h +linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h +liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \ + lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \ + lstring.h ltable.h +lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h +loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \ + ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \ + lvm.h +lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h +loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ + llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ + ldo.h lfunc.h lstring.h lgc.h ltable.h +lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ + lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \ + lstring.h ltable.h +lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ + lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h +lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h +ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h +lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h ldebug.h lstate.h \ + lobject.h llimits.h ltm.h lzio.h lmem.h lopcodes.h lopnames.h lundump.h +lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ + lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \ + lundump.h +lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h +lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \ + ltable.h lvm.h ljumptab.h +lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \ + lobject.h ltm.h lzio.h + +# (end of Makefile) diff --git a/User/system/lua/src/lapi.c b/User/system/lua/src/lapi.c new file mode 100644 index 0000000..332e97d --- /dev/null +++ b/User/system/lua/src/lapi.c @@ -0,0 +1,1463 @@ +/* +** $Id: lapi.c $ +** Lua API +** See Copyright Notice in lua.h +*/ + +#define lapi_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" + + + +const char lua_ident[] = + "$LuaVersion: " LUA_COPYRIGHT " $" + "$LuaAuthors: " LUA_AUTHORS " $"; + + + +/* +** Test for a valid index (one that is not the 'nilvalue'). +** '!ttisnil(o)' implies 'o != &G(L)->nilvalue', so it is not needed. +** However, it covers the most common cases in a faster way. +*/ +#define isvalid(L, o) (!ttisnil(o) || o != &G(L)->nilvalue) + + +/* test for pseudo index */ +#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) + +/* test for upvalue */ +#define isupvalue(i) ((i) < LUA_REGISTRYINDEX) + + +/* +** Convert an acceptable index to a pointer to its respective value. +** Non-valid indices return the special nil value 'G(L)->nilvalue'. +*/ +static TValue *index2value (lua_State *L, int idx) { + CallInfo *ci = L->ci; + if (idx > 0) { + StkId o = ci->func.p + idx; + api_check(L, idx <= ci->top.p - (ci->func.p + 1), "unacceptable index"); + if (o >= L->top.p) return &G(L)->nilvalue; + else return s2v(o); + } + else if (!ispseudo(idx)) { /* negative index */ + api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1), + "invalid index"); + return s2v(L->top.p + idx); + } + else if (idx == LUA_REGISTRYINDEX) + return &G(L)->l_registry; + else { /* upvalues */ + idx = LUA_REGISTRYINDEX - idx; + api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); + if (ttisCclosure(s2v(ci->func.p))) { /* C closure? */ + CClosure *func = clCvalue(s2v(ci->func.p)); + return (idx <= func->nupvalues) ? &func->upvalue[idx-1] + : &G(L)->nilvalue; + } + else { /* light C function or Lua function (through a hook)?) */ + api_check(L, ttislcf(s2v(ci->func.p)), "caller not a C function"); + return &G(L)->nilvalue; /* no upvalues */ + } + } +} + + + +/* +** Convert a valid actual index (not a pseudo-index) to its address. +*/ +l_sinline StkId index2stack (lua_State *L, int idx) { + CallInfo *ci = L->ci; + if (idx > 0) { + StkId o = ci->func.p + idx; + api_check(L, o < L->top.p, "invalid index"); + return o; + } + else { /* non-positive index */ + api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1), + "invalid index"); + api_check(L, !ispseudo(idx), "invalid index"); + return L->top.p + idx; + } +} + + +LUA_API int lua_checkstack (lua_State *L, int n) { + int res; + CallInfo *ci; + lua_lock(L); + ci = L->ci; + api_check(L, n >= 0, "negative 'n'"); + if (L->stack_last.p - L->top.p > n) /* stack large enough? */ + res = 1; /* yes; check is OK */ + else /* need to grow stack */ + res = luaD_growstack(L, n, 0); + if (res && ci->top.p < L->top.p + n) + ci->top.p = L->top.p + n; /* adjust frame top */ + lua_unlock(L); + return res; +} + + +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { + int i; + if (from == to) return; + lua_lock(to); + api_checknelems(from, n); + api_check(from, G(from) == G(to), "moving among independent states"); + api_check(from, to->ci->top.p - to->top.p >= n, "stack overflow"); + from->top.p -= n; + for (i = 0; i < n; i++) { + setobjs2s(to, to->top.p, from->top.p + i); + to->top.p++; /* stack already checked by previous 'api_check' */ + } + lua_unlock(to); +} + + +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; +} + + +LUA_API lua_Number lua_version (lua_State *L) { + UNUSED(L); + return LUA_VERSION_NUM; +} + + + +/* +** basic stack manipulation +*/ + + +/* +** convert an acceptable stack index into an absolute index +*/ +LUA_API int lua_absindex (lua_State *L, int idx) { + return (idx > 0 || ispseudo(idx)) + ? idx + : cast_int(L->top.p - L->ci->func.p) + idx; +} + + +LUA_API int lua_gettop (lua_State *L) { + return cast_int(L->top.p - (L->ci->func.p + 1)); +} + + +LUA_API void lua_settop (lua_State *L, int idx) { + CallInfo *ci; + StkId func, newtop; + ptrdiff_t diff; /* difference for new top */ + lua_lock(L); + ci = L->ci; + func = ci->func.p; + if (idx >= 0) { + api_check(L, idx <= ci->top.p - (func + 1), "new top too large"); + diff = ((func + 1) + idx) - L->top.p; + for (; diff > 0; diff--) + setnilvalue(s2v(L->top.p++)); /* clear new slots */ + } + else { + api_check(L, -(idx+1) <= (L->top.p - (func + 1)), "invalid new top"); + diff = idx + 1; /* will "subtract" index (as it is negative) */ + } + api_check(L, L->tbclist.p < L->top.p, "previous pop of an unclosed slot"); + newtop = L->top.p + diff; + if (diff < 0 && L->tbclist.p >= newtop) { + lua_assert(hastocloseCfunc(ci->nresults)); + newtop = luaF_close(L, newtop, CLOSEKTOP, 0); + } + L->top.p = newtop; /* correct top only after closing any upvalue */ + lua_unlock(L); +} + + +LUA_API void lua_closeslot (lua_State *L, int idx) { + StkId level; + lua_lock(L); + level = index2stack(L, idx); + api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist.p == level, + "no variable to close at given level"); + level = luaF_close(L, level, CLOSEKTOP, 0); + setnilvalue(s2v(level)); + lua_unlock(L); +} + + +/* +** Reverse the stack segment from 'from' to 'to' +** (auxiliary to 'lua_rotate') +** Note that we move(copy) only the value inside the stack. +** (We do not move additional fields that may exist.) +*/ +l_sinline void reverse (lua_State *L, StkId from, StkId to) { + for (; from < to; from++, to--) { + TValue temp; + setobj(L, &temp, s2v(from)); + setobjs2s(L, from, to); + setobj2s(L, to, &temp); + } +} + + +/* +** Let x = AB, where A is a prefix of length 'n'. Then, +** rotate x n == BA. But BA == (A^r . B^r)^r. +*/ +LUA_API void lua_rotate (lua_State *L, int idx, int n) { + StkId p, t, m; + lua_lock(L); + t = L->top.p - 1; /* end of stack segment being rotated */ + p = index2stack(L, idx); /* start of segment */ + api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'"); + m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */ + reverse(L, p, m); /* reverse the prefix with length 'n' */ + reverse(L, m + 1, t); /* reverse the suffix */ + reverse(L, p, t); /* reverse the entire segment */ + lua_unlock(L); +} + + +LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { + TValue *fr, *to; + lua_lock(L); + fr = index2value(L, fromidx); + to = index2value(L, toidx); + api_check(L, isvalid(L, to), "invalid index"); + setobj(L, to, fr); + if (isupvalue(toidx)) /* function upvalue? */ + luaC_barrier(L, clCvalue(s2v(L->ci->func.p)), fr); + /* LUA_REGISTRYINDEX does not need gc barrier + (collector revisits it before finishing collection) */ + lua_unlock(L); +} + + +LUA_API void lua_pushvalue (lua_State *L, int idx) { + lua_lock(L); + setobj2s(L, L->top.p, index2value(L, idx)); + api_incr_top(L); + lua_unlock(L); +} + + + +/* +** access functions (stack -> C) +*/ + + +LUA_API int lua_type (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return (isvalid(L, o) ? ttype(o) : LUA_TNONE); +} + + +LUA_API const char *lua_typename (lua_State *L, int t) { + UNUSED(L); + api_check(L, LUA_TNONE <= t && t < LUA_NUMTYPES, "invalid type"); + return ttypename(t); +} + + +LUA_API int lua_iscfunction (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return (ttislcf(o) || (ttisCclosure(o))); +} + + +LUA_API int lua_isinteger (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return ttisinteger(o); +} + + +LUA_API int lua_isnumber (lua_State *L, int idx) { + lua_Number n; + const TValue *o = index2value(L, idx); + return tonumber(o, &n); +} + + +LUA_API int lua_isstring (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return (ttisstring(o) || cvt2str(o)); +} + + +LUA_API int lua_isuserdata (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return (ttisfulluserdata(o) || ttislightuserdata(o)); +} + + +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { + const TValue *o1 = index2value(L, index1); + const TValue *o2 = index2value(L, index2); + return (isvalid(L, o1) && isvalid(L, o2)) ? luaV_rawequalobj(o1, o2) : 0; +} + + +LUA_API void lua_arith (lua_State *L, int op) { + lua_lock(L); + if (op != LUA_OPUNM && op != LUA_OPBNOT) + api_checknelems(L, 2); /* all other operations expect two operands */ + else { /* for unary operations, add fake 2nd operand */ + api_checknelems(L, 1); + setobjs2s(L, L->top.p, L->top.p - 1); + api_incr_top(L); + } + /* first operand at top - 2, second at top - 1; result go to top - 2 */ + luaO_arith(L, op, s2v(L->top.p - 2), s2v(L->top.p - 1), L->top.p - 2); + L->top.p--; /* remove second operand */ + lua_unlock(L); +} + + +LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { + const TValue *o1; + const TValue *o2; + int i = 0; + lua_lock(L); /* may call tag method */ + o1 = index2value(L, index1); + o2 = index2value(L, index2); + if (isvalid(L, o1) && isvalid(L, o2)) { + switch (op) { + case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break; + case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break; + case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break; + default: api_check(L, 0, "invalid option"); + } + } + lua_unlock(L); + return i; +} + + +LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) { + size_t sz = luaO_str2num(s, s2v(L->top.p)); + if (sz != 0) + api_incr_top(L); + return sz; +} + + +LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) { + lua_Number n = 0; + const TValue *o = index2value(L, idx); + int isnum = tonumber(o, &n); + if (pisnum) + *pisnum = isnum; + return n; +} + + +LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) { + lua_Integer res = 0; + const TValue *o = index2value(L, idx); + int isnum = tointeger(o, &res); + if (pisnum) + *pisnum = isnum; + return res; +} + + +LUA_API int lua_toboolean (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return !l_isfalse(o); +} + + +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { + TValue *o; + lua_lock(L); + o = index2value(L, idx); + if (!ttisstring(o)) { + if (!cvt2str(o)) { /* not convertible? */ + if (len != NULL) *len = 0; + lua_unlock(L); + return NULL; + } + luaO_tostring(L, o); + luaC_checkGC(L); + o = index2value(L, idx); /* previous call may reallocate the stack */ + } + if (len != NULL) + *len = tsslen(tsvalue(o)); + lua_unlock(L); + return getstr(tsvalue(o)); +} + + +LUA_API lua_Unsigned lua_rawlen (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + switch (ttypetag(o)) { + case LUA_VSHRSTR: return tsvalue(o)->shrlen; + case LUA_VLNGSTR: return tsvalue(o)->u.lnglen; + case LUA_VUSERDATA: return uvalue(o)->len; + case LUA_VTABLE: return luaH_getn(hvalue(o)); + default: return 0; + } +} + + +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + if (ttislcf(o)) return fvalue(o); + else if (ttisCclosure(o)) + return clCvalue(o)->f; + else return NULL; /* not a C function */ +} + + +l_sinline void *touserdata (const TValue *o) { + switch (ttype(o)) { + case LUA_TUSERDATA: return getudatamem(uvalue(o)); + case LUA_TLIGHTUSERDATA: return pvalue(o); + default: return NULL; + } +} + + +LUA_API void *lua_touserdata (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return touserdata(o); +} + + +LUA_API lua_State *lua_tothread (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); +} + + +/* +** Returns a pointer to the internal representation of an object. +** Note that ANSI C does not allow the conversion of a pointer to +** function to a 'void*', so the conversion here goes through +** a 'size_t'. (As the returned pointer is only informative, this +** conversion should not be a problem.) +*/ +LUA_API const void *lua_topointer (lua_State *L, int idx) { + const TValue *o = index2value(L, idx); + switch (ttypetag(o)) { + case LUA_VLCF: return cast_voidp(cast_sizet(fvalue(o))); + case LUA_VUSERDATA: case LUA_VLIGHTUSERDATA: + return touserdata(o); + default: { + if (iscollectable(o)) + return gcvalue(o); + else + return NULL; + } + } +} + + + +/* +** push functions (C -> stack) +*/ + + +LUA_API void lua_pushnil (lua_State *L) { + lua_lock(L); + setnilvalue(s2v(L->top.p)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { + lua_lock(L); + setfltvalue(s2v(L->top.p), n); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { + lua_lock(L); + setivalue(s2v(L->top.p), n); + api_incr_top(L); + lua_unlock(L); +} + + +/* +** Pushes on the stack a string with given length. Avoid using 's' when +** 'len' == 0 (as 's' can be NULL in that case), due to later use of +** 'memcmp' and 'memcpy'. +*/ +LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { + TString *ts; + lua_lock(L); + ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len); + setsvalue2s(L, L->top.p, ts); + api_incr_top(L); + luaC_checkGC(L); + lua_unlock(L); + return getstr(ts); +} + + +LUA_API const char *lua_pushstring (lua_State *L, const char *s) { + lua_lock(L); + if (s == NULL) + setnilvalue(s2v(L->top.p)); + else { + TString *ts; + ts = luaS_new(L, s); + setsvalue2s(L, L->top.p, ts); + s = getstr(ts); /* internal copy's address */ + } + api_incr_top(L); + luaC_checkGC(L); + lua_unlock(L); + return s; +} + + +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, + va_list argp) { + const char *ret; + lua_lock(L); + ret = luaO_pushvfstring(L, fmt, argp); + luaC_checkGC(L); + lua_unlock(L); + return ret; +} + + +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { + const char *ret; + va_list argp; + lua_lock(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + luaC_checkGC(L); + lua_unlock(L); + return ret; +} + + +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { + lua_lock(L); + if (n == 0) { + setfvalue(s2v(L->top.p), fn); + api_incr_top(L); + } + else { + CClosure *cl; + api_checknelems(L, n); + api_check(L, n <= MAXUPVAL, "upvalue index too large"); + cl = luaF_newCclosure(L, n); + cl->f = fn; + L->top.p -= n; + while (n--) { + setobj2n(L, &cl->upvalue[n], s2v(L->top.p + n)); + /* does not need barrier because closure is white */ + lua_assert(iswhite(cl)); + } + setclCvalue(L, s2v(L->top.p), cl); + api_incr_top(L); + luaC_checkGC(L); + } + lua_unlock(L); +} + + +LUA_API void lua_pushboolean (lua_State *L, int b) { + lua_lock(L); + if (b) + setbtvalue(s2v(L->top.p)); + else + setbfvalue(s2v(L->top.p)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { + lua_lock(L); + setpvalue(s2v(L->top.p), p); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_pushthread (lua_State *L) { + lua_lock(L); + setthvalue(L, s2v(L->top.p), L); + api_incr_top(L); + lua_unlock(L); + return (G(L)->mainthread == L); +} + + + +/* +** get functions (Lua -> stack) +*/ + + +l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) { + const TValue *slot; + TString *str = luaS_new(L, k); + if (luaV_fastget(L, t, str, slot, luaH_getstr)) { + setobj2s(L, L->top.p, slot); + api_incr_top(L); + } + else { + setsvalue2s(L, L->top.p, str); + api_incr_top(L); + luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, slot); + } + lua_unlock(L); + return ttype(s2v(L->top.p - 1)); +} + + +/* +** Get the global table in the registry. Since all predefined +** indices in the registry were inserted right when the registry +** was created and never removed, they must always be in the array +** part of the registry. +*/ +#define getGtable(L) \ + (&hvalue(&G(L)->l_registry)->array[LUA_RIDX_GLOBALS - 1]) + + +LUA_API int lua_getglobal (lua_State *L, const char *name) { + const TValue *G; + lua_lock(L); + G = getGtable(L); + return auxgetstr(L, G, name); +} + + +LUA_API int lua_gettable (lua_State *L, int idx) { + const TValue *slot; + TValue *t; + lua_lock(L); + t = index2value(L, idx); + if (luaV_fastget(L, t, s2v(L->top.p - 1), slot, luaH_get)) { + setobj2s(L, L->top.p - 1, slot); + } + else + luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, slot); + lua_unlock(L); + return ttype(s2v(L->top.p - 1)); +} + + +LUA_API int lua_getfield (lua_State *L, int idx, const char *k) { + lua_lock(L); + return auxgetstr(L, index2value(L, idx), k); +} + + +LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { + TValue *t; + const TValue *slot; + lua_lock(L); + t = index2value(L, idx); + if (luaV_fastgeti(L, t, n, slot)) { + setobj2s(L, L->top.p, slot); + } + else { + TValue aux; + setivalue(&aux, n); + luaV_finishget(L, t, &aux, L->top.p, slot); + } + api_incr_top(L); + lua_unlock(L); + return ttype(s2v(L->top.p - 1)); +} + + +l_sinline int finishrawget (lua_State *L, const TValue *val) { + if (isempty(val)) /* avoid copying empty items to the stack */ + setnilvalue(s2v(L->top.p)); + else + setobj2s(L, L->top.p, val); + api_incr_top(L); + lua_unlock(L); + return ttype(s2v(L->top.p - 1)); +} + + +static Table *gettable (lua_State *L, int idx) { + TValue *t = index2value(L, idx); + api_check(L, ttistable(t), "table expected"); + return hvalue(t); +} + + +LUA_API int lua_rawget (lua_State *L, int idx) { + Table *t; + const TValue *val; + lua_lock(L); + api_checknelems(L, 1); + t = gettable(L, idx); + val = luaH_get(t, s2v(L->top.p - 1)); + L->top.p--; /* remove key */ + return finishrawget(L, val); +} + + +LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) { + Table *t; + lua_lock(L); + t = gettable(L, idx); + return finishrawget(L, luaH_getint(t, n)); +} + + +LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) { + Table *t; + TValue k; + lua_lock(L); + t = gettable(L, idx); + setpvalue(&k, cast_voidp(p)); + return finishrawget(L, luaH_get(t, &k)); +} + + +LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { + Table *t; + lua_lock(L); + t = luaH_new(L); + sethvalue2s(L, L->top.p, t); + api_incr_top(L); + if (narray > 0 || nrec > 0) + luaH_resize(L, t, narray, nrec); + luaC_checkGC(L); + lua_unlock(L); +} + + +LUA_API int lua_getmetatable (lua_State *L, int objindex) { + const TValue *obj; + Table *mt; + int res = 0; + lua_lock(L); + obj = index2value(L, objindex); + switch (ttype(obj)) { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + default: + mt = G(L)->mt[ttype(obj)]; + break; + } + if (mt != NULL) { + sethvalue2s(L, L->top.p, mt); + api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) { + TValue *o; + int t; + lua_lock(L); + o = index2value(L, idx); + api_check(L, ttisfulluserdata(o), "full userdata expected"); + if (n <= 0 || n > uvalue(o)->nuvalue) { + setnilvalue(s2v(L->top.p)); + t = LUA_TNONE; + } + else { + setobj2s(L, L->top.p, &uvalue(o)->uv[n - 1].uv); + t = ttype(s2v(L->top.p)); + } + api_incr_top(L); + lua_unlock(L); + return t; +} + + +/* +** set functions (stack -> Lua) +*/ + +/* +** t[k] = value at the top of the stack (where 'k' is a string) +*/ +static void auxsetstr (lua_State *L, const TValue *t, const char *k) { + const TValue *slot; + TString *str = luaS_new(L, k); + api_checknelems(L, 1); + if (luaV_fastget(L, t, str, slot, luaH_getstr)) { + luaV_finishfastset(L, t, slot, s2v(L->top.p - 1)); + L->top.p--; /* pop value */ + } + else { + setsvalue2s(L, L->top.p, str); /* push 'str' (to make it a TValue) */ + api_incr_top(L); + luaV_finishset(L, t, s2v(L->top.p - 1), s2v(L->top.p - 2), slot); + L->top.p -= 2; /* pop value and key */ + } + lua_unlock(L); /* lock done by caller */ +} + + +LUA_API void lua_setglobal (lua_State *L, const char *name) { + const TValue *G; + lua_lock(L); /* unlock done in 'auxsetstr' */ + G = getGtable(L); + auxsetstr(L, G, name); +} + + +LUA_API void lua_settable (lua_State *L, int idx) { + TValue *t; + const TValue *slot; + lua_lock(L); + api_checknelems(L, 2); + t = index2value(L, idx); + if (luaV_fastget(L, t, s2v(L->top.p - 2), slot, luaH_get)) { + luaV_finishfastset(L, t, slot, s2v(L->top.p - 1)); + } + else + luaV_finishset(L, t, s2v(L->top.p - 2), s2v(L->top.p - 1), slot); + L->top.p -= 2; /* pop index and value */ + lua_unlock(L); +} + + +LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { + lua_lock(L); /* unlock done in 'auxsetstr' */ + auxsetstr(L, index2value(L, idx), k); +} + + +LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { + TValue *t; + const TValue *slot; + lua_lock(L); + api_checknelems(L, 1); + t = index2value(L, idx); + if (luaV_fastgeti(L, t, n, slot)) { + luaV_finishfastset(L, t, slot, s2v(L->top.p - 1)); + } + else { + TValue aux; + setivalue(&aux, n); + luaV_finishset(L, t, &aux, s2v(L->top.p - 1), slot); + } + L->top.p--; /* pop value */ + lua_unlock(L); +} + + +static void aux_rawset (lua_State *L, int idx, TValue *key, int n) { + Table *t; + lua_lock(L); + api_checknelems(L, n); + t = gettable(L, idx); + luaH_set(L, t, key, s2v(L->top.p - 1)); + invalidateTMcache(t); + luaC_barrierback(L, obj2gco(t), s2v(L->top.p - 1)); + L->top.p -= n; + lua_unlock(L); +} + + +LUA_API void lua_rawset (lua_State *L, int idx) { + aux_rawset(L, idx, s2v(L->top.p - 2), 2); +} + + +LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { + TValue k; + setpvalue(&k, cast_voidp(p)); + aux_rawset(L, idx, &k, 1); +} + + +LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) { + Table *t; + lua_lock(L); + api_checknelems(L, 1); + t = gettable(L, idx); + luaH_setint(L, t, n, s2v(L->top.p - 1)); + luaC_barrierback(L, obj2gco(t), s2v(L->top.p - 1)); + L->top.p--; + lua_unlock(L); +} + + +LUA_API int lua_setmetatable (lua_State *L, int objindex) { + TValue *obj; + Table *mt; + lua_lock(L); + api_checknelems(L, 1); + obj = index2value(L, objindex); + if (ttisnil(s2v(L->top.p - 1))) + mt = NULL; + else { + api_check(L, ttistable(s2v(L->top.p - 1)), "table expected"); + mt = hvalue(s2v(L->top.p - 1)); + } + switch (ttype(obj)) { + case LUA_TTABLE: { + hvalue(obj)->metatable = mt; + if (mt) { + luaC_objbarrier(L, gcvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } + break; + } + case LUA_TUSERDATA: { + uvalue(obj)->metatable = mt; + if (mt) { + luaC_objbarrier(L, uvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } + break; + } + default: { + G(L)->mt[ttype(obj)] = mt; + break; + } + } + L->top.p--; + lua_unlock(L); + return 1; +} + + +LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) { + TValue *o; + int res; + lua_lock(L); + api_checknelems(L, 1); + o = index2value(L, idx); + api_check(L, ttisfulluserdata(o), "full userdata expected"); + if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue))) + res = 0; /* 'n' not in [1, uvalue(o)->nuvalue] */ + else { + setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top.p - 1)); + luaC_barrierback(L, gcvalue(o), s2v(L->top.p - 1)); + res = 1; + } + L->top.p--; + lua_unlock(L); + return res; +} + + +/* +** 'load' and 'call' functions (run Lua code) +*/ + + +#define checkresults(L,na,nr) \ + api_check(L, (nr) == LUA_MULTRET \ + || (L->ci->top.p - L->top.p >= (nr) - (na)), \ + "results from function overflow current stack size") + + +LUA_API void lua_callk (lua_State *L, int nargs, int nresults, + lua_KContext ctx, lua_KFunction k) { + StkId func; + lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); + api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); + func = L->top.p - (nargs+1); + if (k != NULL && yieldable(L)) { /* need to prepare continuation? */ + L->ci->u.c.k = k; /* save continuation */ + L->ci->u.c.ctx = ctx; /* save context */ + luaD_call(L, func, nresults); /* do the call */ + } + else /* no continuation or no yieldable */ + luaD_callnoyield(L, func, nresults); /* just do the call */ + adjustresults(L, nresults); + lua_unlock(L); +} + + + +/* +** Execute a protected call. +*/ +struct CallS { /* data to 'f_call' */ + StkId func; + int nresults; +}; + + +static void f_call (lua_State *L, void *ud) { + struct CallS *c = cast(struct CallS *, ud); + luaD_callnoyield(L, c->func, c->nresults); +} + + + +LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, + lua_KContext ctx, lua_KFunction k) { + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); + api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); + if (errfunc == 0) + func = 0; + else { + StkId o = index2stack(L, errfunc); + api_check(L, ttisfunction(s2v(o)), "error handler must be a function"); + func = savestack(L, o); + } + c.func = L->top.p - (nargs+1); /* function to be called */ + if (k == NULL || !yieldable(L)) { /* no continuation or no yieldable? */ + c.nresults = nresults; /* do a 'conventional' protected call */ + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + } + else { /* prepare continuation (call is already protected by 'resume') */ + CallInfo *ci = L->ci; + ci->u.c.k = k; /* save continuation */ + ci->u.c.ctx = ctx; /* save context */ + /* save information for error recovery */ + ci->u2.funcidx = cast_int(savestack(L, c.func)); + ci->u.c.old_errfunc = L->errfunc; + L->errfunc = func; + setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */ + ci->callstatus |= CIST_YPCALL; /* function can do error recovery */ + luaD_call(L, c.func, nresults); /* do the call */ + ci->callstatus &= ~CIST_YPCALL; + L->errfunc = ci->u.c.old_errfunc; + status = LUA_OK; /* if it is here, there were no errors */ + } + adjustresults(L, nresults); + lua_unlock(L); + return status; +} + + +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, + const char *chunkname, const char *mode) { + ZIO z; + int status; + lua_lock(L); + if (!chunkname) chunkname = "?"; + luaZ_init(L, &z, reader, data); + status = luaD_protectedparser(L, &z, chunkname, mode); + if (status == LUA_OK) { /* no errors? */ + LClosure *f = clLvalue(s2v(L->top.p - 1)); /* get new function */ + if (f->nupvalues >= 1) { /* does it have an upvalue? */ + /* get global table from registry */ + const TValue *gt = getGtable(L); + /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ + setobj(L, f->upvals[0]->v.p, gt); + luaC_barrier(L, f->upvals[0], gt); + } + } + lua_unlock(L); + return status; +} + + +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { + int status; + TValue *o; + lua_lock(L); + api_checknelems(L, 1); + o = s2v(L->top.p - 1); + if (isLfunction(o)) + status = luaU_dump(L, getproto(o), writer, data, strip); + else + status = 1; + lua_unlock(L); + return status; +} + + +LUA_API int lua_status (lua_State *L) { + return L->status; +} + + +/* +** Garbage-collection function +*/ +LUA_API int lua_gc (lua_State *L, int what, ...) { + va_list argp; + int res = 0; + global_State *g = G(L); + if (g->gcstp & GCSTPGC) /* internal stop? */ + return -1; /* all options are invalid when stopped */ + lua_lock(L); + va_start(argp, what); + switch (what) { + case LUA_GCSTOP: { + g->gcstp = GCSTPUSR; /* stopped by the user */ + break; + } + case LUA_GCRESTART: { + luaE_setdebt(g, 0); + g->gcstp = 0; /* (GCSTPGC must be already zero here) */ + break; + } + case LUA_GCCOLLECT: { + luaC_fullgc(L, 0); + break; + } + case LUA_GCCOUNT: { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + res = cast_int(gettotalbytes(g) >> 10); + break; + } + case LUA_GCCOUNTB: { + res = cast_int(gettotalbytes(g) & 0x3ff); + break; + } + case LUA_GCSTEP: { + int data = va_arg(argp, int); + l_mem debt = 1; /* =1 to signal that it did an actual step */ + lu_byte oldstp = g->gcstp; + g->gcstp = 0; /* allow GC to run (GCSTPGC must be zero here) */ + if (data == 0) { + luaE_setdebt(g, 0); /* do a basic step */ + luaC_step(L); + } + else { /* add 'data' to total debt */ + debt = cast(l_mem, data) * 1024 + g->GCdebt; + luaE_setdebt(g, debt); + luaC_checkGC(L); + } + g->gcstp = oldstp; /* restore previous state */ + if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */ + res = 1; /* signal it */ + break; + } + case LUA_GCSETPAUSE: { + int data = va_arg(argp, int); + res = getgcparam(g->gcpause); + setgcparam(g->gcpause, data); + break; + } + case LUA_GCSETSTEPMUL: { + int data = va_arg(argp, int); + res = getgcparam(g->gcstepmul); + setgcparam(g->gcstepmul, data); + break; + } + case LUA_GCISRUNNING: { + res = gcrunning(g); + break; + } + case LUA_GCGEN: { + int minormul = va_arg(argp, int); + int majormul = va_arg(argp, int); + res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC; + if (minormul != 0) + g->genminormul = minormul; + if (majormul != 0) + setgcparam(g->genmajormul, majormul); + luaC_changemode(L, KGC_GEN); + break; + } + case LUA_GCINC: { + int pause = va_arg(argp, int); + int stepmul = va_arg(argp, int); + int stepsize = va_arg(argp, int); + res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC; + if (pause != 0) + setgcparam(g->gcpause, pause); + if (stepmul != 0) + setgcparam(g->gcstepmul, stepmul); + if (stepsize != 0) + g->gcstepsize = stepsize; + luaC_changemode(L, KGC_INC); + break; + } + default: res = -1; /* invalid option */ + } + va_end(argp); + lua_unlock(L); + return res; +} + + + +/* +** miscellaneous functions +*/ + + +LUA_API int lua_error (lua_State *L) { + TValue *errobj; + lua_lock(L); + errobj = s2v(L->top.p - 1); + api_checknelems(L, 1); + /* error object is the memory error message? */ + if (ttisshrstring(errobj) && eqshrstr(tsvalue(errobj), G(L)->memerrmsg)) + luaM_error(L); /* raise a memory error */ + else + luaG_errormsg(L); /* raise a regular error */ + /* code unreachable; will unlock when control actually leaves the kernel */ + return 0; /* to avoid warnings */ +} + + +LUA_API int lua_next (lua_State *L, int idx) { + Table *t; + int more; + lua_lock(L); + api_checknelems(L, 1); + t = gettable(L, idx); + more = luaH_next(L, t, L->top.p - 1); + if (more) { + api_incr_top(L); + } + else /* no more elements */ + L->top.p -= 1; /* remove key */ + lua_unlock(L); + return more; +} + + +LUA_API void lua_toclose (lua_State *L, int idx) { + int nresults; + StkId o; + lua_lock(L); + o = index2stack(L, idx); + nresults = L->ci->nresults; + api_check(L, L->tbclist.p < o, "given index below or equal a marked one"); + luaF_newtbcupval(L, o); /* create new to-be-closed upvalue */ + if (!hastocloseCfunc(nresults)) /* function not marked yet? */ + L->ci->nresults = codeNresults(nresults); /* mark it */ + lua_assert(hastocloseCfunc(L->ci->nresults)); + lua_unlock(L); +} + + +LUA_API void lua_concat (lua_State *L, int n) { + lua_lock(L); + api_checknelems(L, n); + if (n > 0) + luaV_concat(L, n); + else { /* nothing to concatenate */ + setsvalue2s(L, L->top.p, luaS_newlstr(L, "", 0)); /* push empty string */ + api_incr_top(L); + } + luaC_checkGC(L); + lua_unlock(L); +} + + +LUA_API void lua_len (lua_State *L, int idx) { + TValue *t; + lua_lock(L); + t = index2value(L, idx); + luaV_objlen(L, L->top.p, t); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { + lua_Alloc f; + lua_lock(L); + if (ud) *ud = G(L)->ud; + f = G(L)->frealloc; + lua_unlock(L); + return f; +} + + +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { + lua_lock(L); + G(L)->ud = ud; + G(L)->frealloc = f; + lua_unlock(L); +} + + +void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud) { + lua_lock(L); + G(L)->ud_warn = ud; + G(L)->warnf = f; + lua_unlock(L); +} + + +void lua_warning (lua_State *L, const char *msg, int tocont) { + lua_lock(L); + luaE_warning(L, msg, tocont); + lua_unlock(L); +} + + + +LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) { + Udata *u; + lua_lock(L); + api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value"); + u = luaS_newudata(L, size, nuvalue); + setuvalue(L, s2v(L->top.p), u); + api_incr_top(L); + luaC_checkGC(L); + lua_unlock(L); + return getudatamem(u); +} + + + +static const char *aux_upvalue (TValue *fi, int n, TValue **val, + GCObject **owner) { + switch (ttypetag(fi)) { + case LUA_VCCL: { /* C closure */ + CClosure *f = clCvalue(fi); + if (!(cast_uint(n) - 1u < cast_uint(f->nupvalues))) + return NULL; /* 'n' not in [1, f->nupvalues] */ + *val = &f->upvalue[n-1]; + if (owner) *owner = obj2gco(f); + return ""; + } + case LUA_VLCL: { /* Lua closure */ + LClosure *f = clLvalue(fi); + TString *name; + Proto *p = f->p; + if (!(cast_uint(n) - 1u < cast_uint(p->sizeupvalues))) + return NULL; /* 'n' not in [1, p->sizeupvalues] */ + *val = f->upvals[n-1]->v.p; + if (owner) *owner = obj2gco(f->upvals[n - 1]); + name = p->upvalues[n-1].name; + return (name == NULL) ? "(no name)" : getstr(name); + } + default: return NULL; /* not a closure */ + } +} + + +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val = NULL; /* to avoid warnings */ + lua_lock(L); + name = aux_upvalue(index2value(L, funcindex), n, &val, NULL); + if (name) { + setobj2s(L, L->top.p, val); + api_incr_top(L); + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val = NULL; /* to avoid warnings */ + GCObject *owner = NULL; /* to avoid warnings */ + TValue *fi; + lua_lock(L); + fi = index2value(L, funcindex); + api_checknelems(L, 1); + name = aux_upvalue(fi, n, &val, &owner); + if (name) { + L->top.p--; + setobj(L, val, s2v(L->top.p)); + luaC_barrier(L, owner, val); + } + lua_unlock(L); + return name; +} + + +static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { + static const UpVal *const nullup = NULL; + LClosure *f; + TValue *fi = index2value(L, fidx); + api_check(L, ttisLclosure(fi), "Lua function expected"); + f = clLvalue(fi); + if (pf) *pf = f; + if (1 <= n && n <= f->p->sizeupvalues) + return &f->upvals[n - 1]; /* get its upvalue pointer */ + else + return (UpVal**)&nullup; +} + + +LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { + TValue *fi = index2value(L, fidx); + switch (ttypetag(fi)) { + case LUA_VLCL: { /* lua closure */ + return *getupvalref(L, fidx, n, NULL); + } + case LUA_VCCL: { /* C closure */ + CClosure *f = clCvalue(fi); + if (1 <= n && n <= f->nupvalues) + return &f->upvalue[n - 1]; + /* else */ + } /* FALLTHROUGH */ + case LUA_VLCF: + return NULL; /* light C functions have no upvalues */ + default: { + api_check(L, 0, "function expected"); + return NULL; + } + } +} + + +LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, + int fidx2, int n2) { + LClosure *f1; + UpVal **up1 = getupvalref(L, fidx1, n1, &f1); + UpVal **up2 = getupvalref(L, fidx2, n2, NULL); + api_check(L, *up1 != NULL && *up2 != NULL, "invalid upvalue index"); + *up1 = *up2; + luaC_objbarrier(L, f1, *up1); +} + + diff --git a/User/system/lua/src/lapi.h b/User/system/lua/src/lapi.h new file mode 100644 index 0000000..a742427 --- /dev/null +++ b/User/system/lua/src/lapi.h @@ -0,0 +1,52 @@ +/* +** $Id: lapi.h $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "llimits.h" +#include "lstate.h" + + +/* Increments 'L->top.p', checking for stack overflows */ +#define api_incr_top(L) {L->top.p++; \ + api_check(L, L->top.p <= L->ci->top.p, \ + "stack overflow");} + + +/* +** If a call returns too many multiple returns, the callee may not have +** stack space to accommodate all results. In this case, this macro +** increases its stack space ('L->ci->top.p'). +*/ +#define adjustresults(L,nres) \ + { if ((nres) <= LUA_MULTRET && L->ci->top.p < L->top.p) \ + L->ci->top.p = L->top.p; } + + +/* Ensure the stack has at least 'n' elements */ +#define api_checknelems(L,n) \ + api_check(L, (n) < (L->top.p - L->ci->func.p), \ + "not enough elements in the stack") + + +/* +** To reduce the overhead of returning from C functions, the presence of +** to-be-closed variables in these functions is coded in the CallInfo's +** field 'nresults', in a way that functions with no to-be-closed variables +** with zero, one, or "all" wanted results have no overhead. Functions +** with other number of wanted results, as well as functions with +** variables to be closed, have an extra check. +*/ + +#define hastocloseCfunc(n) ((n) < LUA_MULTRET) + +/* Map [-1, inf) (range of 'nresults') into (-inf, -2] */ +#define codeNresults(n) (-(n) - 3) +#define decodeNresults(n) (-(n) - 3) + +#endif diff --git a/User/system/lua/src/lauxlib.c b/User/system/lua/src/lauxlib.c new file mode 100644 index 0000000..923105e --- /dev/null +++ b/User/system/lua/src/lauxlib.c @@ -0,0 +1,1126 @@ +/* +** $Id: lauxlib.c $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + +#define lauxlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include +#include + + +/* +** This file uses only the official API of Lua. +** Any function declared here could be written as an application function. +*/ + +#include "lua.h" + +#include "lauxlib.h" + + +#if !defined(MAX_SIZET) +/* maximum value for size_t */ +#define MAX_SIZET ((size_t)(~(size_t)0)) +#endif + + +/* +** {====================================================== +** Traceback +** ======================================================= +*/ + + +#define LEVELS1 10 /* size of the first part of the stack */ +#define LEVELS2 11 /* size of the second part of the stack */ + + + +/* +** Search for 'objidx' in table at index -1. ('objidx' must be an +** absolute index.) Return 1 + string at top if it found a good name. +*/ +static int findfield (lua_State *L, int objidx, int level) { + if (level == 0 || !lua_istable(L, -1)) + return 0; /* not found */ + lua_pushnil(L); /* start 'next' loop */ + while (lua_next(L, -2)) { /* for each pair in table */ + if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */ + if (lua_rawequal(L, objidx, -1)) { /* found object? */ + lua_pop(L, 1); /* remove value (but keep name) */ + return 1; + } + else if (findfield(L, objidx, level - 1)) { /* try recursively */ + /* stack: lib_name, lib_table, field_name (top) */ + lua_pushliteral(L, "."); /* place '.' between the two names */ + lua_replace(L, -3); /* (in the slot occupied by table) */ + lua_concat(L, 3); /* lib_name.field_name */ + return 1; + } + } + lua_pop(L, 1); /* remove value */ + } + return 0; /* not found */ +} + + +/* +** Search for a name for a function in all loaded modules +*/ +static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { + int top = lua_gettop(L); + lua_getinfo(L, "f", ar); /* push function */ + lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + luaL_checkstack(L, 6, "not enough stack"); /* slots for 'findfield' */ + if (findfield(L, top + 1, 2)) { + const char *name = lua_tostring(L, -1); + if (strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */ + lua_pushstring(L, name + 3); /* push name without prefix */ + lua_remove(L, -2); /* remove original name */ + } + lua_copy(L, -1, top + 1); /* copy name to proper place */ + lua_settop(L, top + 1); /* remove table "loaded" and name copy */ + return 1; + } + else { + lua_settop(L, top); /* remove function and global table */ + return 0; + } +} + + +static void pushfuncname (lua_State *L, lua_Debug *ar) { + if (pushglobalfuncname(L, ar)) { /* try first a global name */ + lua_pushfstring(L, "function '%s'", lua_tostring(L, -1)); + lua_remove(L, -2); /* remove name */ + } + else if (*ar->namewhat != '\0') /* is there a name from code? */ + lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name); /* use it */ + else if (*ar->what == 'm') /* main? */ + lua_pushliteral(L, "main chunk"); + else if (*ar->what != 'C') /* for Lua functions, use */ + lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); + else /* nothing left... */ + lua_pushliteral(L, "?"); +} + + +static int lastlevel (lua_State *L) { + lua_Debug ar; + int li = 1, le = 1; + /* find an upper bound */ + while (lua_getstack(L, le, &ar)) { li = le; le *= 2; } + /* do a binary search */ + while (li < le) { + int m = (li + le)/2; + if (lua_getstack(L, m, &ar)) li = m + 1; + else le = m; + } + return le - 1; +} + + +LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, + const char *msg, int level) { + luaL_Buffer b; + lua_Debug ar; + int last = lastlevel(L1); + int limit2show = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1; + luaL_buffinit(L, &b); + if (msg) { + luaL_addstring(&b, msg); + luaL_addchar(&b, '\n'); + } + luaL_addstring(&b, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (limit2show-- == 0) { /* too many levels? */ + int n = last - level - LEVELS2 + 1; /* number of levels to skip */ + lua_pushfstring(L, "\n\t...\t(skipping %d levels)", n); + luaL_addvalue(&b); /* add warning about skip */ + level += n; /* and skip to last levels */ + } + else { + lua_getinfo(L1, "Slnt", &ar); + if (ar.currentline <= 0) + lua_pushfstring(L, "\n\t%s: in ", ar.short_src); + else + lua_pushfstring(L, "\n\t%s:%d: in ", ar.short_src, ar.currentline); + luaL_addvalue(&b); + pushfuncname(L, &ar); + luaL_addvalue(&b); + if (ar.istailcall) + luaL_addstring(&b, "\n\t(...tail calls...)"); + } + } + luaL_pushresult(&b); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Error-report functions +** ======================================================= +*/ + +LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) { + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ + return luaL_error(L, "bad argument #%d (%s)", arg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) { + arg--; /* do not count 'self' */ + if (arg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling '%s' on bad self (%s)", + ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; + return luaL_error(L, "bad argument #%d to '%s' (%s)", + arg, ar.name, extramsg); +} + + +LUALIB_API int luaL_typeerror (lua_State *L, int arg, const char *tname) { + const char *msg; + const char *typearg; /* name for the type of the actual argument */ + if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING) + typearg = lua_tostring(L, -1); /* use the given type name */ + else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA) + typearg = "light userdata"; /* special name for messages */ + else + typearg = luaL_typename(L, arg); /* standard name */ + msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg); + return luaL_argerror(L, arg, msg); +} + + +static void tag_error (lua_State *L, int arg, int tag) { + luaL_typeerror(L, arg, lua_typename(L, tag)); +} + + +/* +** The use of 'lua_pushfstring' ensures this function does not +** need reserved stack space when called. +*/ +LUALIB_API void luaL_where (lua_State *L, int level) { + lua_Debug ar; + if (lua_getstack(L, level, &ar)) { /* check function at level */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ + if (ar.currentline > 0) { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + } + lua_pushfstring(L, ""); /* else, no information available... */ +} + + +/* +** Again, the use of 'lua_pushvfstring' ensures this function does +** not need reserved stack space when called. (At worst, it generates +** an error with "stack overflow" instead of the given message.) +*/ +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} + + +LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { + int en = errno; /* calls to Lua API may change this value */ + if (stat) { + lua_pushboolean(L, 1); + return 1; + } + else { + const char *msg; + luaL_pushfail(L); + msg = (en != 0) ? strerror(en) : "(no extra info)"; + if (fname) + lua_pushfstring(L, "%s: %s", fname, msg); + else + lua_pushstring(L, msg); + lua_pushinteger(L, en); + return 3; + } +} + + +#if !defined(l_inspectstat) /* { */ + +#if defined(LUA_USE_POSIX) + +#include + +/* +** use appropriate macros to interpret 'pclose' return status +*/ +#define l_inspectstat(stat,what) \ + if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ + else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } + +#else + +#define l_inspectstat(stat,what) /* no op */ + +#endif + +#endif /* } */ + + +LUALIB_API int luaL_execresult (lua_State *L, int stat) { + if (stat != 0 && errno != 0) /* error with an 'errno'? */ + return luaL_fileresult(L, 0, NULL); + else { + const char *what = "exit"; /* type of termination */ + l_inspectstat(stat, what); /* interpret result */ + if (*what == 'e' && stat == 0) /* successful termination? */ + lua_pushboolean(L, 1); + else + luaL_pushfail(L); + lua_pushstring(L, what); + lua_pushinteger(L, stat); + return 3; /* return true/fail,what,code */ + } +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Userdata's metatable manipulation +** ======================================================= +*/ + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { + if (luaL_getmetatable(L, tname) != LUA_TNIL) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_createtable(L, 0, 2); /* create metatable */ + lua_pushstring(L, tname); + lua_setfield(L, -2, "__name"); /* metatable.__name = tname */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; +} + + +LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) { + luaL_getmetatable(L, tname); + lua_setmetatable(L, -2); +} + + +LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) { + void *p = lua_touserdata(L, ud); + if (p != NULL) { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ + luaL_getmetatable(L, tname); /* get correct metatable */ + if (!lua_rawequal(L, -1, -2)) /* not the same? */ + p = NULL; /* value is a userdata with wrong metatable */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + return NULL; /* value is not a userdata with a metatable */ +} + + +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + void *p = luaL_testudata(L, ud, tname); + luaL_argexpected(L, p != NULL, ud, tname); + return p; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Argument check functions +** ======================================================= +*/ + +LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def, + const char *const lst[]) { + const char *name = (def) ? luaL_optstring(L, arg, def) : + luaL_checkstring(L, arg); + int i; + for (i=0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + return luaL_argerror(L, arg, + lua_pushfstring(L, "invalid option '%s'", name)); +} + + +/* +** Ensures the stack has at least 'space' extra slots, raising an error +** if it cannot fulfill the request. (The error handling needs a few +** extra slots to format the error message. In case of an error without +** this extra space, Lua will generate the same 'stack overflow' error, +** but without 'msg'.) +*/ +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { + if (l_unlikely(!lua_checkstack(L, space))) { + if (msg) + luaL_error(L, "stack overflow (%s)", msg); + else + luaL_error(L, "stack overflow"); + } +} + + +LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) { + if (l_unlikely(lua_type(L, arg) != t)) + tag_error(L, arg, t); +} + + +LUALIB_API void luaL_checkany (lua_State *L, int arg) { + if (l_unlikely(lua_type(L, arg) == LUA_TNONE)) + luaL_argerror(L, arg, "value expected"); +} + + +LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) { + const char *s = lua_tolstring(L, arg, len); + if (l_unlikely(!s)) tag_error(L, arg, LUA_TSTRING); + return s; +} + + +LUALIB_API const char *luaL_optlstring (lua_State *L, int arg, + const char *def, size_t *len) { + if (lua_isnoneornil(L, arg)) { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else return luaL_checklstring(L, arg, len); +} + + +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) { + int isnum; + lua_Number d = lua_tonumberx(L, arg, &isnum); + if (l_unlikely(!isnum)) + tag_error(L, arg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) { + return luaL_opt(L, luaL_checknumber, arg, def); +} + + +static void interror (lua_State *L, int arg) { + if (lua_isnumber(L, arg)) + luaL_argerror(L, arg, "number has no integer representation"); + else + tag_error(L, arg, LUA_TNUMBER); +} + + +LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) { + int isnum; + lua_Integer d = lua_tointegerx(L, arg, &isnum); + if (l_unlikely(!isnum)) { + interror(L, arg); + } + return d; +} + + +LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg, + lua_Integer def) { + return luaL_opt(L, luaL_checkinteger, arg, def); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +/* userdata to box arbitrary data */ +typedef struct UBox { + void *box; + size_t bsize; +} UBox; + + +static void *resizebox (lua_State *L, int idx, size_t newsize) { + void *ud; + lua_Alloc allocf = lua_getallocf(L, &ud); + UBox *box = (UBox *)lua_touserdata(L, idx); + void *temp = allocf(ud, box->box, box->bsize, newsize); + if (l_unlikely(temp == NULL && newsize > 0)) { /* allocation error? */ + lua_pushliteral(L, "not enough memory"); + lua_error(L); /* raise a memory error */ + } + box->box = temp; + box->bsize = newsize; + return temp; +} + + +static int boxgc (lua_State *L) { + resizebox(L, 1, 0); + return 0; +} + + +static const luaL_Reg boxmt[] = { /* box metamethods */ + {"__gc", boxgc}, + {"__close", boxgc}, + {NULL, NULL} +}; + + +static void newbox (lua_State *L) { + UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0); + box->box = NULL; + box->bsize = 0; + if (luaL_newmetatable(L, "_UBOX*")) /* creating metatable? */ + luaL_setfuncs(L, boxmt, 0); /* set its metamethods */ + lua_setmetatable(L, -2); +} + + +/* +** check whether buffer is using a userdata on the stack as a temporary +** buffer +*/ +#define buffonstack(B) ((B)->b != (B)->init.b) + + +/* +** Whenever buffer is accessed, slot 'idx' must either be a box (which +** cannot be NULL) or it is a placeholder for the buffer. +*/ +#define checkbufferlevel(B,idx) \ + lua_assert(buffonstack(B) ? lua_touserdata(B->L, idx) != NULL \ + : lua_touserdata(B->L, idx) == (void*)B) + + +/* +** Compute new size for buffer 'B', enough to accommodate extra 'sz' +** bytes. (The test for "not big enough" also gets the case when the +** computation of 'newsize' overflows.) +*/ +static size_t newbuffsize (luaL_Buffer *B, size_t sz) { + size_t newsize = (B->size / 2) * 3; /* buffer size * 1.5 */ + if (l_unlikely(MAX_SIZET - sz < B->n)) /* overflow in (B->n + sz)? */ + return luaL_error(B->L, "buffer too large"); + if (newsize < B->n + sz) /* not big enough? */ + newsize = B->n + sz; + return newsize; +} + + +/* +** Returns a pointer to a free area with at least 'sz' bytes in buffer +** 'B'. 'boxidx' is the relative position in the stack where is the +** buffer's box or its placeholder. +*/ +static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) { + checkbufferlevel(B, boxidx); + if (B->size - B->n >= sz) /* enough space? */ + return B->b + B->n; + else { + lua_State *L = B->L; + char *newbuff; + size_t newsize = newbuffsize(B, sz); + /* create larger buffer */ + if (buffonstack(B)) /* buffer already has a box? */ + newbuff = (char *)resizebox(L, boxidx, newsize); /* resize it */ + else { /* no box yet */ + lua_remove(L, boxidx); /* remove placeholder */ + newbox(L); /* create a new box */ + lua_insert(L, boxidx); /* move box to its intended position */ + lua_toclose(L, boxidx); + newbuff = (char *)resizebox(L, boxidx, newsize); + memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */ + } + B->b = newbuff; + B->size = newsize; + return newbuff + B->n; + } +} + +/* +** returns a pointer to a free area with at least 'sz' bytes +*/ +LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { + return prepbuffsize(B, sz, -1); +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + if (l > 0) { /* avoid 'memcpy' when 's' can be NULL */ + char *b = prepbuffsize(B, l, -1); + memcpy(b, s, l * sizeof(char)); + luaL_addsize(B, l); + } +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + lua_State *L = B->L; + checkbufferlevel(B, -1); + lua_pushlstring(L, B->b, B->n); + if (buffonstack(B)) + lua_closeslot(L, -2); /* close the box */ + lua_remove(L, -2); /* remove box or placeholder from the stack */ +} + + +LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) { + luaL_addsize(B, sz); + luaL_pushresult(B); +} + + +/* +** 'luaL_addvalue' is the only function in the Buffer system where the +** box (if existent) is not on the top of the stack. So, instead of +** calling 'luaL_addlstring', it replicates the code using -2 as the +** last argument to 'prepbuffsize', signaling that the box is (or will +** be) below the string being added to the buffer. (Box creation can +** trigger an emergency GC, so we should not remove the string from the +** stack before we have the space guaranteed.) +*/ +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t len; + const char *s = lua_tolstring(L, -1, &len); + char *b = prepbuffsize(B, len, -2); + memcpy(b, s, len * sizeof(char)); + luaL_addsize(B, len); + lua_pop(L, 1); /* pop string */ +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->b = B->init.b; + B->n = 0; + B->size = LUAL_BUFFERSIZE; + lua_pushlightuserdata(L, (void*)B); /* push placeholder */ +} + + +LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { + luaL_buffinit(L, B); + return prepbuffsize(B, sz, -1); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Reference system +** ======================================================= +*/ + +/* index of free-list header (after the predefined values) */ +#define freelist (LUA_RIDX_LAST + 1) + +/* +** The previously freed references form a linked list: +** t[freelist] is the index of a first free index, or zero if list is +** empty; t[t[freelist]] is the index of the second element; etc. +*/ +LUALIB_API int luaL_ref (lua_State *L, int t) { + int ref; + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* 'nil' has a unique fixed reference */ + } + t = lua_absindex(L, t); + if (lua_rawgeti(L, t, freelist) == LUA_TNIL) { /* first access? */ + ref = 0; /* list is empty */ + lua_pushinteger(L, 0); /* initialize as an empty list */ + lua_rawseti(L, t, freelist); /* ref = t[freelist] = 0 */ + } + else { /* already initialized */ + lua_assert(lua_isinteger(L, -1)); + ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ + } + lua_pop(L, 1); /* remove element from stack */ + if (ref != 0) { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ + } + else /* no free elements */ + ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ + lua_rawseti(L, t, ref); + return ref; +} + + +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { + if (ref >= 0) { + t = lua_absindex(L, t); + lua_rawgeti(L, t, freelist); + lua_assert(lua_isinteger(L, -1)); + lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, freelist); /* t[freelist] = ref */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Load functions +** ======================================================= +*/ + +typedef struct LoadF { + int n; /* number of pre-read characters */ + FILE *f; /* file being read */ + char buff[BUFSIZ]; /* area for reading file */ +} LoadF; + + +static const char *getF (lua_State *L, void *ud, size_t *size) { + LoadF *lf = (LoadF *)ud; + (void)L; /* not used */ + if (lf->n > 0) { /* are there pre-read characters to be read? */ + *size = lf->n; /* return them (chars already in buffer) */ + lf->n = 0; /* no more pre-read characters */ + } + else { /* read a block from file */ + /* 'fread' can return > 0 *and* set the EOF flag. If next call to + 'getF' called 'fread', it might still wait for user input. + The next check avoids this problem. */ + if (feof(lf->f)) return NULL; + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */ + } + return lf->buff; +} + + +static int errfile (lua_State *L, const char *what, int fnameindex) { + int err = errno; + const char *filename = lua_tostring(L, fnameindex) + 1; + if (err != 0) + lua_pushfstring(L, "cannot %s %s: %s", what, filename, strerror(err)); + else + lua_pushfstring(L, "cannot %s %s", what, filename); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + + +/* +** Skip an optional BOM at the start of a stream. If there is an +** incomplete BOM (the first character is correct but the rest is +** not), returns the first character anyway to force an error +** (as no chunk can start with 0xEF). +*/ +static int skipBOM (FILE *f) { + int c = getc(f); /* read first character */ + if (c == 0xEF && getc(f) == 0xBB && getc(f) == 0xBF) /* correct BOM? */ + return getc(f); /* ignore BOM and return next char */ + else /* no (valid) BOM */ + return c; /* return first character */ +} + + +/* +** reads the first character of file 'f' and skips an optional BOM mark +** in its beginning plus its first line if it starts with '#'. Returns +** true if it skipped the first line. In any case, '*cp' has the +** first "valid" character of the file (after the optional BOM and +** a first-line comment). +*/ +static int skipcomment (FILE *f, int *cp) { + int c = *cp = skipBOM(f); + if (c == '#') { /* first line is a comment (Unix exec. file)? */ + do { /* skip first line */ + c = getc(f); + } while (c != EOF && c != '\n'); + *cp = getc(f); /* next character after comment, if present */ + return 1; /* there was a comment */ + } + else return 0; /* no comment */ +} + + +LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, + const char *mode) { + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + if (filename == NULL) { + lua_pushliteral(L, "=stdin"); + lf.f = stdin; + } + else { + lua_pushfstring(L, "@%s", filename); + errno = 0; + lf.f = fopen(filename, "r"); + if (lf.f == NULL) return errfile(L, "open", fnameindex); + } + lf.n = 0; + if (skipcomment(lf.f, &c)) /* read initial portion */ + lf.buff[lf.n++] = '\n'; /* add newline to correct line numbers */ + if (c == LUA_SIGNATURE[0]) { /* binary file? */ + lf.n = 0; /* remove possible newline */ + if (filename) { /* "real" file? */ + errno = 0; + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ + if (lf.f == NULL) return errfile(L, "reopen", fnameindex); + skipcomment(lf.f, &c); /* re-read initial portion */ + } + } + if (c != EOF) + lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ + errno = 0; + status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); + readstatus = ferror(lf.f); + if (filename) fclose(lf.f); /* close file (even in case of errors) */ + if (readstatus) { + lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ + return errfile(L, "read", fnameindex); + } + lua_remove(L, fnameindex); + return status; +} + + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + + +static const char *getS (lua_State *L, void *ud, size_t *size) { + LoadS *ls = (LoadS *)ud; + (void)L; /* not used */ + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; +} + + +LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size, + const char *name, const char *mode) { + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name, mode); +} + + +LUALIB_API int luaL_loadstring (lua_State *L, const char *s) { + return luaL_loadbuffer(L, s, strlen(s), s); +} + +/* }====================================================== */ + + + +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return LUA_TNIL; + else { + int tt; + lua_pushstring(L, event); + tt = lua_rawget(L, -2); + if (tt == LUA_TNIL) /* is metafield nil? */ + lua_pop(L, 2); /* remove metatable and metafield */ + else + lua_remove(L, -2); /* remove only metatable */ + return tt; /* return metafield type */ + } +} + + +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { + obj = lua_absindex(L, obj); + if (luaL_getmetafield(L, obj, event) == LUA_TNIL) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; +} + + +LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) { + lua_Integer l; + int isnum; + lua_len(L, idx); + l = lua_tointegerx(L, -1, &isnum); + if (l_unlikely(!isnum)) + luaL_error(L, "object length is not an integer"); + lua_pop(L, 1); /* remove object */ + return l; +} + + +LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { + idx = lua_absindex(L,idx); + if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */ + if (!lua_isstring(L, -1)) + luaL_error(L, "'__tostring' must return a string"); + } + else { + switch (lua_type(L, idx)) { + case LUA_TNUMBER: { + if (lua_isinteger(L, idx)) + lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx)); + else + lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx)); + break; + } + case LUA_TSTRING: + lua_pushvalue(L, idx); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: { + int tt = luaL_getmetafield(L, idx, "__name"); /* try name */ + const char *kind = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : + luaL_typename(L, idx); + lua_pushfstring(L, "%s: %p", kind, lua_topointer(L, idx)); + if (tt != LUA_TNIL) + lua_remove(L, -2); /* remove '__name' */ + break; + } + } + } + return lua_tolstring(L, -1, len); +} + + +/* +** set functions from list 'l' into table at top - 'nup'; each +** function gets the 'nup' elements at the top as upvalues. +** Returns with only the table at the stack. +*/ +LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { + luaL_checkstack(L, nup, "too many upvalues"); + for (; l->name != NULL; l++) { /* fill the table with given functions */ + if (l->func == NULL) /* placeholder? */ + lua_pushboolean(L, 0); + else { + int i; + for (i = 0; i < nup; i++) /* copy upvalues to the top */ + lua_pushvalue(L, -nup); + lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ + } + lua_setfield(L, -(nup + 2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ +} + + +/* +** ensure that stack[idx][fname] has a table and push that table +** into the stack +*/ +LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { + if (lua_getfield(L, idx, fname) == LUA_TTABLE) + return 1; /* table already there */ + else { + lua_pop(L, 1); /* remove previous result */ + idx = lua_absindex(L, idx); + lua_newtable(L); + lua_pushvalue(L, -1); /* copy to be left at top */ + lua_setfield(L, idx, fname); /* assign new table to field */ + return 0; /* false, because did not find table there */ + } +} + + +/* +** Stripped-down 'require': After checking "loaded" table, calls 'openf' +** to open a module, registers the result in 'package.loaded' table and, +** if 'glb' is true, also registers the result in the global table. +** Leaves resulting module on the top. +*/ +LUALIB_API void luaL_requiref (lua_State *L, const char *modname, + lua_CFunction openf, int glb) { + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_getfield(L, -1, modname); /* LOADED[modname] */ + if (!lua_toboolean(L, -1)) { /* package not already loaded? */ + lua_pop(L, 1); /* remove field */ + lua_pushcfunction(L, openf); + lua_pushstring(L, modname); /* argument to open function */ + lua_call(L, 1, 1); /* call 'openf' to open module */ + lua_pushvalue(L, -1); /* make copy of module (call result) */ + lua_setfield(L, -3, modname); /* LOADED[modname] = module */ + } + lua_remove(L, -2); /* remove LOADED table */ + if (glb) { + lua_pushvalue(L, -1); /* copy of module */ + lua_setglobal(L, modname); /* _G[modname] = module */ + } +} + + +LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s, + const char *p, const char *r) { + const char *wild; + size_t l = strlen(p); + while ((wild = strstr(s, p)) != NULL) { + luaL_addlstring(b, s, wild - s); /* push prefix */ + luaL_addstring(b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after 'p' */ + } + luaL_addstring(b, s); /* push last suffix */ +} + + +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, + const char *p, const char *r) { + luaL_Buffer b; + luaL_buffinit(L, &b); + luaL_addgsub(&b, s, p, r); + luaL_pushresult(&b); + return lua_tostring(L, -1); +} + + +static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { + (void)ud; (void)osize; /* not used */ + if (nsize == 0) { + free(ptr); + return NULL; + } + else + return realloc(ptr, nsize); +} + + +/* +** Standard panic funcion just prints an error message. The test +** with 'lua_type' avoids possible memory errors in 'lua_tostring'. +*/ +static int panic (lua_State *L) { + const char *msg = (lua_type(L, -1) == LUA_TSTRING) + ? lua_tostring(L, -1) + : "error object is not a string"; + lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", + msg); + return 0; /* return to Lua to abort */ +} + + +/* +** Warning functions: +** warnfoff: warning system is off +** warnfon: ready to start a new message +** warnfcont: previous message is to be continued +*/ +static void warnfoff (void *ud, const char *message, int tocont); +static void warnfon (void *ud, const char *message, int tocont); +static void warnfcont (void *ud, const char *message, int tocont); + + +/* +** Check whether message is a control message. If so, execute the +** control or ignore it if unknown. +*/ +static int checkcontrol (lua_State *L, const char *message, int tocont) { + if (tocont || *(message++) != '@') /* not a control message? */ + return 0; + else { + if (strcmp(message, "off") == 0) + lua_setwarnf(L, warnfoff, L); /* turn warnings off */ + else if (strcmp(message, "on") == 0) + lua_setwarnf(L, warnfon, L); /* turn warnings on */ + return 1; /* it was a control message */ + } +} + + +static void warnfoff (void *ud, const char *message, int tocont) { + checkcontrol((lua_State *)ud, message, tocont); +} + + +/* +** Writes the message and handle 'tocont', finishing the message +** if needed and setting the next warn function. +*/ +static void warnfcont (void *ud, const char *message, int tocont) { + lua_State *L = (lua_State *)ud; + lua_writestringerror("%s", message); /* write message */ + if (tocont) /* not the last part? */ + lua_setwarnf(L, warnfcont, L); /* to be continued */ + else { /* last part */ + lua_writestringerror("%s", "\n"); /* finish message with end-of-line */ + lua_setwarnf(L, warnfon, L); /* next call is a new message */ + } +} + + +static void warnfon (void *ud, const char *message, int tocont) { + if (checkcontrol((lua_State *)ud, message, tocont)) /* control message? */ + return; /* nothing else to be done */ + lua_writestringerror("%s", "Lua warning: "); /* start a new warning */ + warnfcont(ud, message, tocont); /* finish processing */ +} + + +LUALIB_API lua_State *luaL_newstate (void) { + lua_State *L = lua_newstate(l_alloc, NULL); + if (l_likely(L)) { + lua_atpanic(L, &panic); + lua_setwarnf(L, warnfoff, L); /* default is warnings off */ + } + return L; +} + + +LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) { + lua_Number v = lua_version(L); + if (sz != LUAL_NUMSIZES) /* check numeric types */ + luaL_error(L, "core and library have incompatible numeric types"); + else if (v != ver) + luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", + (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)v); +} + diff --git a/User/system/lua/src/lauxlib.h b/User/system/lua/src/lauxlib.h new file mode 100644 index 0000000..5b977e2 --- /dev/null +++ b/User/system/lua/src/lauxlib.h @@ -0,0 +1,301 @@ +/* +** $Id: lauxlib.h $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "luaconf.h" +#include "lua.h" + + +/* global table */ +#define LUA_GNAME "_G" + + +typedef struct luaL_Buffer luaL_Buffer; + + +/* extra error code for 'luaL_loadfilex' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +/* key, in the registry, for table of loaded modules */ +#define LUA_LOADED_TABLE "_LOADED" + + +/* key, in the registry, for table of preloaded loaders */ +#define LUA_PRELOAD_TABLE "_PRELOAD" + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + +#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number)) + +LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz); +#define luaL_checkversion(L) \ + luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES) + +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); +LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); +LUALIB_API int (luaL_typeerror) (lua_State *L, int arg, const char *tname); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int arg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); +LUALIB_API int (luaL_execresult) (lua_State *L, int stat); + + +/* predefined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, + const char *mode); + +#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) + +LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, + const char *name, const char *mode); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + +LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); + +LUALIB_API void (luaL_addgsub) (luaL_Buffer *b, const char *s, + const char *p, const char *r); +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, + const char *p, const char *r); + +LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); + +LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); + +LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, + const char *msg, int level); + +LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, + lua_CFunction openf, int glb); + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + + +#define luaL_newlibtable(L,l) \ + lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) + +#define luaL_newlib(L,l) \ + (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) + +#define luaL_argcheck(L, cond,arg,extramsg) \ + ((void)(luai_likely(cond) || luaL_argerror(L, (arg), (extramsg)))) + +#define luaL_argexpected(L,cond,arg,tname) \ + ((void)(luai_likely(cond) || luaL_typeerror(L, (arg), (tname)))) + +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) + + +/* +** Perform arithmetic operations on lua_Integer values with wrap-around +** semantics, as the Lua core does. +*/ +#define luaL_intop(op,v1,v2) \ + ((lua_Integer)((lua_Unsigned)(v1) op (lua_Unsigned)(v2))) + + +/* push the value used to represent failure/error */ +#define luaL_pushfail(L) lua_pushnil(L) + + +/* +** Internal assertions for in-house debugging +*/ +#if !defined(lua_assert) + +#if defined LUAI_ASSERT + #include + #define lua_assert(c) assert(c) +#else + #define lua_assert(c) ((void)0) +#endif + +#endif + + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +struct luaL_Buffer { + char *b; /* buffer address */ + size_t size; /* buffer size */ + size_t n; /* number of characters in buffer */ + lua_State *L; + union { + LUAI_MAXALIGN; /* ensure maximum alignment for buffer */ + char b[LUAL_BUFFERSIZE]; /* initial buffer */ + } init; +}; + + +#define luaL_bufflen(bf) ((bf)->n) +#define luaL_buffaddr(bf) ((bf)->b) + + +#define luaL_addchar(B,c) \ + ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ + ((B)->b[(B)->n++] = (c))) + +#define luaL_addsize(B,s) ((B)->n += (s)) + +#define luaL_buffsub(B,s) ((B)->n -= (s)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); +LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); + +#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) + +/* }====================================================== */ + + + +/* +** {====================================================== +** File handles for IO library +** ======================================================= +*/ + +/* +** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and +** initial structure 'luaL_Stream' (it may contain other fields +** after that initial structure). +*/ + +#define LUA_FILEHANDLE "FILE*" + + +typedef struct luaL_Stream { + FILE *f; /* stream (NULL for incompletely created streams) */ + lua_CFunction closef; /* to close stream (NULL for closed streams) */ +} luaL_Stream; + +/* }====================================================== */ + +/* +** {================================================================== +** "Abstraction Layer" for basic report of messages and errors +** =================================================================== +*/ + +/* print a string */ +#if !defined(lua_writestring) +#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) +#endif + +/* print a newline and flush the output */ +#if !defined(lua_writeline) +#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) +#endif + +/* print an error message */ +#if !defined(lua_writestringerror) +#define lua_writestringerror(s,p) \ + (fprintf(stderr, (s), (p)), fflush(stderr)) +#endif + +/* }================================================================== */ + + +/* +** {============================================================ +** Compatibility with deprecated conversions +** ============================================================= +*/ +#if defined(LUA_COMPAT_APIINTCASTS) + +#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) +#define luaL_optunsigned(L,a,d) \ + ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d))) + +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) + +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#endif +/* }============================================================ */ + + + +#endif + + diff --git a/User/system/lua/src/lbaselib.c b/User/system/lua/src/lbaselib.c new file mode 100644 index 0000000..1d60c9d --- /dev/null +++ b/User/system/lua/src/lbaselib.c @@ -0,0 +1,549 @@ +/* +** $Id: lbaselib.c $ +** Basic library +** See Copyright Notice in lua.h +*/ + +#define lbaselib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + for (i = 1; i <= n; i++) { /* for each argument */ + size_t l; + const char *s = luaL_tolstring(L, i, &l); /* convert it to string */ + if (i > 1) /* not the first element? */ + lua_writestring("\t", 1); /* add a tab before it */ + lua_writestring(s, l); /* print it */ + lua_pop(L, 1); /* pop result */ + } + lua_writeline(); + return 0; +} + + +/* +** Creates a warning with all given arguments. +** Check first for errors; otherwise an error may interrupt +** the composition of a warning, leaving it unfinished. +*/ +static int luaB_warn (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + luaL_checkstring(L, 1); /* at least one argument */ + for (i = 2; i <= n; i++) + luaL_checkstring(L, i); /* make sure all arguments are strings */ + for (i = 1; i < n; i++) /* compose warning */ + lua_warning(L, lua_tostring(L, i), 1); + lua_warning(L, lua_tostring(L, n), 0); /* close warning */ + return 0; +} + + +#define SPACECHARS " \f\n\r\t\v" + +static const char *b_str2int (const char *s, int base, lua_Integer *pn) { + lua_Unsigned n = 0; + int neg = 0; + s += strspn(s, SPACECHARS); /* skip initial spaces */ + if (*s == '-') { s++; neg = 1; } /* handle sign */ + else if (*s == '+') s++; + if (!isalnum((unsigned char)*s)) /* no digit? */ + return NULL; + do { + int digit = (isdigit((unsigned char)*s)) ? *s - '0' + : (toupper((unsigned char)*s) - 'A') + 10; + if (digit >= base) return NULL; /* invalid numeral */ + n = n * base + digit; + s++; + } while (isalnum((unsigned char)*s)); + s += strspn(s, SPACECHARS); /* skip trailing spaces */ + *pn = (lua_Integer)((neg) ? (0u - n) : n); + return s; +} + + +static int luaB_tonumber (lua_State *L) { + if (lua_isnoneornil(L, 2)) { /* standard conversion? */ + if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */ + lua_settop(L, 1); /* yes; return it */ + return 1; + } + else { + size_t l; + const char *s = lua_tolstring(L, 1, &l); + if (s != NULL && lua_stringtonumber(L, s) == l + 1) + return 1; /* successful conversion to number */ + /* else not a number */ + luaL_checkany(L, 1); /* (but there must be some parameter) */ + } + } + else { + size_t l; + const char *s; + lua_Integer n = 0; /* to avoid warnings */ + lua_Integer base = luaL_checkinteger(L, 2); + luaL_checktype(L, 1, LUA_TSTRING); /* no numbers as strings */ + s = lua_tolstring(L, 1, &l); + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + if (b_str2int(s, (int)base, &n) == s + l) { + lua_pushinteger(L, n); + return 1; + } /* else not a number */ + } /* else not a number */ + luaL_pushfail(L); /* not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + int level = (int)luaL_optinteger(L, 2, 1); + lua_settop(L, 1); + if (lua_type(L, 1) == LUA_TSTRING && level > 0) { + luaL_where(L, level); /* add extra information */ + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); +} + + +static int luaB_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ +} + + +static int luaB_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table"); + if (l_unlikely(luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)) + return luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; +} + + +static int luaB_rawequal (lua_State *L) { + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; +} + + +static int luaB_rawlen (lua_State *L) { + int t = lua_type(L, 1); + luaL_argexpected(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, + "table or string"); + lua_pushinteger(L, lua_rawlen(L, 1)); + return 1; +} + + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; +} + + +static int pushmode (lua_State *L, int oldmode) { + if (oldmode == -1) + luaL_pushfail(L); /* invalid call to 'lua_gc' */ + else + lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" + : "generational"); + return 1; +} + + +/* +** check whether call to 'lua_gc' was valid (not inside a finalizer) +*/ +#define checkvalres(res) { if (res == -1) break; } + +static int luaB_collectgarbage (lua_State *L) { + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setpause", "setstepmul", + "isrunning", "generational", "incremental", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, + LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; + int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; + switch (o) { + case LUA_GCCOUNT: { + int k = lua_gc(L, o); + int b = lua_gc(L, LUA_GCCOUNTB); + checkvalres(k); + lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024)); + return 1; + } + case LUA_GCSTEP: { + int step = (int)luaL_optinteger(L, 2, 0); + int res = lua_gc(L, o, step); + checkvalres(res); + lua_pushboolean(L, res); + return 1; + } + case LUA_GCSETPAUSE: + case LUA_GCSETSTEPMUL: { + int p = (int)luaL_optinteger(L, 2, 0); + int previous = lua_gc(L, o, p); + checkvalres(previous); + lua_pushinteger(L, previous); + return 1; + } + case LUA_GCISRUNNING: { + int res = lua_gc(L, o); + checkvalres(res); + lua_pushboolean(L, res); + return 1; + } + case LUA_GCGEN: { + int minormul = (int)luaL_optinteger(L, 2, 0); + int majormul = (int)luaL_optinteger(L, 3, 0); + return pushmode(L, lua_gc(L, o, minormul, majormul)); + } + case LUA_GCINC: { + int pause = (int)luaL_optinteger(L, 2, 0); + int stepmul = (int)luaL_optinteger(L, 3, 0); + int stepsize = (int)luaL_optinteger(L, 4, 0); + return pushmode(L, lua_gc(L, o, pause, stepmul, stepsize)); + } + default: { + int res = lua_gc(L, o); + checkvalres(res); + lua_pushinteger(L, res); + return 1; + } + } + luaL_pushfail(L); /* invalid call (inside a finalizer) */ + return 1; +} + + +static int luaB_type (lua_State *L) { + int t = lua_type(L, 1); + luaL_argcheck(L, t != LUA_TNONE, 1, "value expected"); + lua_pushstring(L, lua_typename(L, t)); + return 1; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int pairscont (lua_State *L, int status, lua_KContext k) { + (void)L; (void)status; (void)k; /* unused */ + return 3; +} + +static int luaB_pairs (lua_State *L) { + luaL_checkany(L, 1); + if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */ + lua_pushcfunction(L, luaB_next); /* will return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushnil(L); /* and initial value */ + } + else { + lua_pushvalue(L, 1); /* argument 'self' to metamethod */ + lua_callk(L, 1, 3, 0, pairscont); /* get 3 values from metamethod */ + } + return 3; +} + + +/* +** Traversal function for 'ipairs' +*/ +static int ipairsaux (lua_State *L) { + lua_Integer i = luaL_checkinteger(L, 2); + i = luaL_intop(+, i, 1); + lua_pushinteger(L, i); + return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2; +} + + +/* +** 'ipairs' function. Returns 'ipairsaux', given "table", 0. +** (The given "table" may not be a table.) +*/ +static int luaB_ipairs (lua_State *L) { + luaL_checkany(L, 1); + lua_pushcfunction(L, ipairsaux); /* iteration function */ + lua_pushvalue(L, 1); /* state */ + lua_pushinteger(L, 0); /* initial value */ + return 3; +} + + +static int load_aux (lua_State *L, int status, int envidx) { + if (l_likely(status == LUA_OK)) { + if (envidx != 0) { /* 'env' parameter? */ + lua_pushvalue(L, envidx); /* environment for loaded function */ + if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */ + lua_pop(L, 1); /* remove 'env' if not used by previous call */ + } + return 1; + } + else { /* error (message is on top of the stack) */ + luaL_pushfail(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return fail plus error message */ + } +} + + +static int luaB_loadfile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + const char *mode = luaL_optstring(L, 2, NULL); + int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */ + int status = luaL_loadfilex(L, fname, mode); + return load_aux(L, status, env); +} + + +/* +** {====================================================== +** Generic Read function +** ======================================================= +*/ + + +/* +** reserved slot, above all arguments, to hold a copy of the returned +** string to avoid it being collected while parsed. 'load' has four +** optional arguments (chunk, source name, mode, and environment). +*/ +#define RESERVEDSLOT 5 + + +/* +** Reader for generic 'load' function: 'lua_load' uses the +** stack for internal stuff, so the reader cannot change the +** stack top. Instead, it keeps its resulting string in a +** reserved slot inside the stack. +*/ +static const char *generic_reader (lua_State *L, void *ud, size_t *size) { + (void)(ud); /* not used */ + luaL_checkstack(L, 2, "too many nested functions"); + lua_pushvalue(L, 1); /* get function */ + lua_call(L, 0, 1); /* call it */ + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* pop result */ + *size = 0; + return NULL; + } + else if (l_unlikely(!lua_isstring(L, -1))) + luaL_error(L, "reader function must return a string"); + lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ + return lua_tolstring(L, RESERVEDSLOT, size); +} + + +static int luaB_load (lua_State *L) { + int status; + size_t l; + const char *s = lua_tolstring(L, 1, &l); + const char *mode = luaL_optstring(L, 3, "bt"); + int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */ + if (s != NULL) { /* loading a string? */ + const char *chunkname = luaL_optstring(L, 2, s); + status = luaL_loadbufferx(L, s, l, chunkname, mode); + } + else { /* loading from a reader function */ + const char *chunkname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, RESERVEDSLOT); /* create reserved slot */ + status = lua_load(L, generic_reader, NULL, chunkname, mode); + } + return load_aux(L, status, env); +} + +/* }====================================================== */ + + +static int dofilecont (lua_State *L, int d1, lua_KContext d2) { + (void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */ + return lua_gettop(L) - 1; +} + + +static int luaB_dofile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + lua_settop(L, 1); + if (l_unlikely(luaL_loadfile(L, fname) != LUA_OK)) + return lua_error(L); + lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); + return dofilecont(L, 0, 0); +} + + +static int luaB_assert (lua_State *L) { + if (l_likely(lua_toboolean(L, 1))) /* condition is true? */ + return lua_gettop(L); /* return all arguments */ + else { /* error */ + luaL_checkany(L, 1); /* there must be a condition */ + lua_remove(L, 1); /* remove it */ + lua_pushliteral(L, "assertion failed!"); /* default message */ + lua_settop(L, 1); /* leave only message (default if no other one) */ + return luaB_error(L); /* call 'error' */ + } +} + + +static int luaB_select (lua_State *L) { + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { + lua_pushinteger(L, n-1); + return 1; + } + else { + lua_Integer i = luaL_checkinteger(L, 1); + if (i < 0) i = n + i; + else if (i > n) i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - (int)i; + } +} + + +/* +** Continuation function for 'pcall' and 'xpcall'. Both functions +** already pushed a 'true' before doing the call, so in case of success +** 'finishpcall' only has to return everything in the stack minus +** 'extra' values (where 'extra' is exactly the number of items to be +** ignored). +*/ +static int finishpcall (lua_State *L, int status, lua_KContext extra) { + if (l_unlikely(status != LUA_OK && status != LUA_YIELD)) { /* error? */ + lua_pushboolean(L, 0); /* first result (false) */ + lua_pushvalue(L, -2); /* error message */ + return 2; /* return false, msg */ + } + else + return lua_gettop(L) - (int)extra; /* return all results */ +} + + +static int luaB_pcall (lua_State *L) { + int status; + luaL_checkany(L, 1); + lua_pushboolean(L, 1); /* first result if no errors */ + lua_insert(L, 1); /* put it in place */ + status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall); + return finishpcall(L, status, 0); +} + + +/* +** Do a protected call with error handling. After 'lua_rotate', the +** stack will have ; so, the function passes +** 2 to 'finishpcall' to skip the 2 first values when returning results. +*/ +static int luaB_xpcall (lua_State *L) { + int status; + int n = lua_gettop(L); + luaL_checktype(L, 2, LUA_TFUNCTION); /* check error function */ + lua_pushboolean(L, 1); /* first result */ + lua_pushvalue(L, 1); /* function */ + lua_rotate(L, 3, 2); /* move them below function's arguments */ + status = lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall); + return finishpcall(L, status, 2); +} + + +static int luaB_tostring (lua_State *L) { + luaL_checkany(L, 1); + luaL_tolstring(L, 1, NULL); + return 1; +} + + +static const luaL_Reg base_funcs[] = { + {"assert", luaB_assert}, + {"collectgarbage", luaB_collectgarbage}, + {"dofile", luaB_dofile}, + {"error", luaB_error}, + {"getmetatable", luaB_getmetatable}, + {"ipairs", luaB_ipairs}, + {"loadfile", luaB_loadfile}, + {"load", luaB_load}, + {"next", luaB_next}, + {"pairs", luaB_pairs}, + {"pcall", luaB_pcall}, + {"print", luaB_print}, + {"warn", luaB_warn}, + {"rawequal", luaB_rawequal}, + {"rawlen", luaB_rawlen}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"select", luaB_select}, + {"setmetatable", luaB_setmetatable}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {"xpcall", luaB_xpcall}, + /* placeholders */ + {LUA_GNAME, NULL}, + {"_VERSION", NULL}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_base (lua_State *L) { + /* open lib into global table */ + lua_pushglobaltable(L); + luaL_setfuncs(L, base_funcs, 0); + /* set global _G */ + lua_pushvalue(L, -1); + lua_setfield(L, -2, LUA_GNAME); + /* set global _VERSION */ + lua_pushliteral(L, LUA_VERSION); + lua_setfield(L, -2, "_VERSION"); + return 1; +} + diff --git a/User/system/lua/src/lcode.c b/User/system/lua/src/lcode.c new file mode 100644 index 0000000..8761614 --- /dev/null +++ b/User/system/lua/src/lcode.c @@ -0,0 +1,1874 @@ +/* +** $Id: lcode.c $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#define lcode_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include +#include + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstring.h" +#include "ltable.h" +#include "lvm.h" + + +/* Maximum number of registers in a Lua function (must fit in 8 bits) */ +#define MAXREGS 255 + + +#define hasjumps(e) ((e)->t != (e)->f) + + +static int codesJ (FuncState *fs, OpCode o, int sj, int k); + + + +/* semantic error */ +l_noret luaK_semerror (LexState *ls, const char *msg) { + ls->t.token = 0; /* remove "near " from final message */ + luaX_syntaxerror(ls, msg); +} + + +/* +** If expression is a numeric constant, fills 'v' with its value +** and returns 1. Otherwise, returns 0. +*/ +static int tonumeral (const expdesc *e, TValue *v) { + if (hasjumps(e)) + return 0; /* not a numeral */ + switch (e->k) { + case VKINT: + if (v) setivalue(v, e->u.ival); + return 1; + case VKFLT: + if (v) setfltvalue(v, e->u.nval); + return 1; + default: return 0; + } +} + + +/* +** Get the constant value from a constant expression +*/ +static TValue *const2val (FuncState *fs, const expdesc *e) { + lua_assert(e->k == VCONST); + return &fs->ls->dyd->actvar.arr[e->u.info].k; +} + + +/* +** If expression is a constant, fills 'v' with its value +** and returns 1. Otherwise, returns 0. +*/ +int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) { + if (hasjumps(e)) + return 0; /* not a constant */ + switch (e->k) { + case VFALSE: + setbfvalue(v); + return 1; + case VTRUE: + setbtvalue(v); + return 1; + case VNIL: + setnilvalue(v); + return 1; + case VKSTR: { + setsvalue(fs->ls->L, v, e->u.strval); + return 1; + } + case VCONST: { + setobj(fs->ls->L, v, const2val(fs, e)); + return 1; + } + default: return tonumeral(e, v); + } +} + + +/* +** Return the previous instruction of the current code. If there +** may be a jump target between the current instruction and the +** previous one, return an invalid instruction (to avoid wrong +** optimizations). +*/ +static Instruction *previousinstruction (FuncState *fs) { + static const Instruction invalidinstruction = ~(Instruction)0; + if (fs->pc > fs->lasttarget) + return &fs->f->code[fs->pc - 1]; /* previous instruction */ + else + return cast(Instruction*, &invalidinstruction); +} + + +/* +** Create a OP_LOADNIL instruction, but try to optimize: if the previous +** instruction is also OP_LOADNIL and ranges are compatible, adjust +** range of previous instruction instead of emitting a new one. (For +** instance, 'local a; local b' will generate a single opcode.) +*/ +void luaK_nil (FuncState *fs, int from, int n) { + int l = from + n - 1; /* last register to set nil */ + Instruction *previous = previousinstruction(fs); + if (GET_OPCODE(*previous) == OP_LOADNIL) { /* previous is LOADNIL? */ + int pfrom = GETARG_A(*previous); /* get previous range */ + int pl = pfrom + GETARG_B(*previous); + if ((pfrom <= from && from <= pl + 1) || + (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ + if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ + if (pl > l) l = pl; /* l = max(l, pl) */ + SETARG_A(*previous, from); + SETARG_B(*previous, l - from); + return; + } /* else go through */ + } + luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ +} + + +/* +** Gets the destination address of a jump instruction. Used to traverse +** a list of jumps. +*/ +static int getjump (FuncState *fs, int pc) { + int offset = GETARG_sJ(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +/* +** Fix jump instruction at position 'pc' to jump to 'dest'. +** (Jump addresses are relative in Lua) +*/ +static void fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest - (pc + 1); + lua_assert(dest != NO_JUMP); + if (!(-OFFSET_sJ <= offset && offset <= MAXARG_sJ - OFFSET_sJ)) + luaX_syntaxerror(fs->ls, "control structure too long"); + lua_assert(GET_OPCODE(*jmp) == OP_JMP); + SETARG_sJ(*jmp, offset); +} + + +/* +** Concatenate jump-list 'l2' into jump-list 'l1' +*/ +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (l2 == NO_JUMP) return; /* nothing to concatenate? */ + else if (*l1 == NO_JUMP) /* no original list? */ + *l1 = l2; /* 'l1' points to 'l2' */ + else { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); /* last element links to 'l2' */ + } +} + + +/* +** Create a jump instruction and return its position, so its destination +** can be fixed later (with 'fixjump'). +*/ +int luaK_jump (FuncState *fs) { + return codesJ(fs, OP_JMP, NO_JUMP, 0); +} + + +/* +** Code a 'return' instruction +*/ +void luaK_ret (FuncState *fs, int first, int nret) { + OpCode op; + switch (nret) { + case 0: op = OP_RETURN0; break; + case 1: op = OP_RETURN1; break; + default: op = OP_RETURN; break; + } + luaK_codeABC(fs, op, first, nret + 1, 0); +} + + +/* +** Code a "conditional jump", that is, a test or comparison opcode +** followed by a jump. Return jump position. +*/ +static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) { + luaK_codeABCk(fs, op, A, B, C, k); + return luaK_jump(fs); +} + + +/* +** returns current 'pc' and marks it as a jump target (to avoid wrong +** optimizations with consecutive instructions not in the same basic block). +*/ +int luaK_getlabel (FuncState *fs) { + fs->lasttarget = fs->pc; + return fs->pc; +} + + +/* +** Returns the position of the instruction "controlling" a given +** jump (that is, its condition), or the jump itself if it is +** unconditional. +*/ +static Instruction *getjumpcontrol (FuncState *fs, int pc) { + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) + return pi-1; + else + return pi; +} + + +/* +** Patch destination register for a TESTSET instruction. +** If instruction in position 'node' is not a TESTSET, return 0 ("fails"). +** Otherwise, if 'reg' is not 'NO_REG', set it as the destination +** register. Otherwise, change instruction to a simple 'TEST' (produces +** no register value) +*/ +static int patchtestreg (FuncState *fs, int node, int reg) { + Instruction *i = getjumpcontrol(fs, node); + if (GET_OPCODE(*i) != OP_TESTSET) + return 0; /* cannot patch other instructions */ + if (reg != NO_REG && reg != GETARG_B(*i)) + SETARG_A(*i, reg); + else { + /* no register to put value or register already has the value; + change instruction to simple test */ + *i = CREATE_ABCk(OP_TEST, GETARG_B(*i), 0, 0, GETARG_k(*i)); + } + return 1; +} + + +/* +** Traverse a list of tests ensuring no one produces a value +*/ +static void removevalues (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) + patchtestreg(fs, list, NO_REG); +} + + +/* +** Traverse a list of tests, patching their destination address and +** registers: tests producing values jump to 'vtarget' (and put their +** values in 'reg'), other tests jump to 'dtarget'. +*/ +static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, + int dtarget) { + while (list != NO_JUMP) { + int next = getjump(fs, list); + if (patchtestreg(fs, list, reg)) + fixjump(fs, list, vtarget); + else + fixjump(fs, list, dtarget); /* jump to default target */ + list = next; + } +} + + +/* +** Path all jumps in 'list' to jump to 'target'. +** (The assert means that we cannot fix a jump to a forward address +** because we only know addresses once code is generated.) +*/ +void luaK_patchlist (FuncState *fs, int list, int target) { + lua_assert(target <= fs->pc); + patchlistaux(fs, list, target, NO_REG, target); +} + + +void luaK_patchtohere (FuncState *fs, int list) { + int hr = luaK_getlabel(fs); /* mark "here" as a jump target */ + luaK_patchlist(fs, list, hr); +} + + +/* limit for difference between lines in relative line info. */ +#define LIMLINEDIFF 0x80 + + +/* +** Save line info for a new instruction. If difference from last line +** does not fit in a byte, of after that many instructions, save a new +** absolute line info; (in that case, the special value 'ABSLINEINFO' +** in 'lineinfo' signals the existence of this absolute information.) +** Otherwise, store the difference from last line in 'lineinfo'. +*/ +static void savelineinfo (FuncState *fs, Proto *f, int line) { + int linedif = line - fs->previousline; + int pc = fs->pc - 1; /* last instruction coded */ + if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ >= MAXIWTHABS) { + luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo, + f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines"); + f->abslineinfo[fs->nabslineinfo].pc = pc; + f->abslineinfo[fs->nabslineinfo++].line = line; + linedif = ABSLINEINFO; /* signal that there is absolute information */ + fs->iwthabs = 1; /* restart counter */ + } + luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte, + MAX_INT, "opcodes"); + f->lineinfo[pc] = linedif; + fs->previousline = line; /* last line saved */ +} + + +/* +** Remove line information from the last instruction. +** If line information for that instruction is absolute, set 'iwthabs' +** above its max to force the new (replacing) instruction to have +** absolute line info, too. +*/ +static void removelastlineinfo (FuncState *fs) { + Proto *f = fs->f; + int pc = fs->pc - 1; /* last instruction coded */ + if (f->lineinfo[pc] != ABSLINEINFO) { /* relative line info? */ + fs->previousline -= f->lineinfo[pc]; /* correct last line saved */ + fs->iwthabs--; /* undo previous increment */ + } + else { /* absolute line information */ + lua_assert(f->abslineinfo[fs->nabslineinfo - 1].pc == pc); + fs->nabslineinfo--; /* remove it */ + fs->iwthabs = MAXIWTHABS + 1; /* force next line info to be absolute */ + } +} + + +/* +** Remove the last instruction created, correcting line information +** accordingly. +*/ +static void removelastinstruction (FuncState *fs) { + removelastlineinfo(fs); + fs->pc--; +} + + +/* +** Emit instruction 'i', checking for array sizes and saving also its +** line information. Return 'i' position. +*/ +int luaK_code (FuncState *fs, Instruction i) { + Proto *f = fs->f; + /* put new instruction in code array */ + luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "opcodes"); + f->code[fs->pc++] = i; + savelineinfo(fs, f, fs->ls->lastline); + return fs->pc - 1; /* index of new instruction */ +} + + +/* +** Format and emit an 'iABC' instruction. (Assertions check consistency +** of parameters versus opcode.) +*/ +int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) { + lua_assert(getOpMode(o) == iABC); + lua_assert(a <= MAXARG_A && b <= MAXARG_B && + c <= MAXARG_C && (k & ~1) == 0); + return luaK_code(fs, CREATE_ABCk(o, a, b, c, k)); +} + + +/* +** Format and emit an 'iABx' instruction. +*/ +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { + lua_assert(getOpMode(o) == iABx); + lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); + return luaK_code(fs, CREATE_ABx(o, a, bc)); +} + + +/* +** Format and emit an 'iAsBx' instruction. +*/ +static int codeAsBx (FuncState *fs, OpCode o, int a, int bc) { + unsigned int b = bc + OFFSET_sBx; + lua_assert(getOpMode(o) == iAsBx); + lua_assert(a <= MAXARG_A && b <= MAXARG_Bx); + return luaK_code(fs, CREATE_ABx(o, a, b)); +} + + +/* +** Format and emit an 'isJ' instruction. +*/ +static int codesJ (FuncState *fs, OpCode o, int sj, int k) { + unsigned int j = sj + OFFSET_sJ; + lua_assert(getOpMode(o) == isJ); + lua_assert(j <= MAXARG_sJ && (k & ~1) == 0); + return luaK_code(fs, CREATE_sJ(o, j, k)); +} + + +/* +** Emit an "extra argument" instruction (format 'iAx') +*/ +static int codeextraarg (FuncState *fs, int a) { + lua_assert(a <= MAXARG_Ax); + return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); +} + + +/* +** Emit a "load constant" instruction, using either 'OP_LOADK' +** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX' +** instruction with "extra argument". +*/ +static int luaK_codek (FuncState *fs, int reg, int k) { + if (k <= MAXARG_Bx) + return luaK_codeABx(fs, OP_LOADK, reg, k); + else { + int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); + codeextraarg(fs, k); + return p; + } +} + + +/* +** Check register-stack level, keeping track of its maximum size +** in field 'maxstacksize' +*/ +void luaK_checkstack (FuncState *fs, int n) { + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) { + if (newstack >= MAXREGS) + luaX_syntaxerror(fs->ls, + "function or expression needs too many registers"); + fs->f->maxstacksize = cast_byte(newstack); + } +} + + +/* +** Reserve 'n' registers in register stack +*/ +void luaK_reserveregs (FuncState *fs, int n) { + luaK_checkstack(fs, n); + fs->freereg += n; +} + + +/* +** Free register 'reg', if it is neither a constant index nor +** a local variable. +) +*/ +static void freereg (FuncState *fs, int reg) { + if (reg >= luaY_nvarstack(fs)) { + fs->freereg--; + lua_assert(reg == fs->freereg); + } +} + + +/* +** Free two registers in proper order +*/ +static void freeregs (FuncState *fs, int r1, int r2) { + if (r1 > r2) { + freereg(fs, r1); + freereg(fs, r2); + } + else { + freereg(fs, r2); + freereg(fs, r1); + } +} + + +/* +** Free register used by expression 'e' (if any) +*/ +static void freeexp (FuncState *fs, expdesc *e) { + if (e->k == VNONRELOC) + freereg(fs, e->u.info); +} + + +/* +** Free registers used by expressions 'e1' and 'e2' (if any) in proper +** order. +*/ +static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) { + int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1; + int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1; + freeregs(fs, r1, r2); +} + + +/* +** Add constant 'v' to prototype's list of constants (field 'k'). +** Use scanner's table to cache position of constants in constant list +** and try to reuse constants. Because some values should not be used +** as keys (nil cannot be a key, integer keys can collapse with float +** keys), the caller must provide a useful 'key' for indexing the cache. +** Note that all functions share the same table, so entering or exiting +** a function can make some indices wrong. +*/ +static int addk (FuncState *fs, TValue *key, TValue *v) { + TValue val; + lua_State *L = fs->ls->L; + Proto *f = fs->f; + const TValue *idx = luaH_get(fs->ls->h, key); /* query scanner table */ + int k, oldsize; + if (ttisinteger(idx)) { /* is there an index there? */ + k = cast_int(ivalue(idx)); + /* correct value? (warning: must distinguish floats from integers!) */ + if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) && + luaV_rawequalobj(&f->k[k], v)) + return k; /* reuse index */ + } + /* constant not found; create a new entry */ + oldsize = f->sizek; + k = fs->nk; + /* numerical value does not need GC barrier; + table has no metatable, so it does not need to invalidate cache */ + setivalue(&val, k); + luaH_finishset(L, fs->ls->h, key, idx, &val); + luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[k], v); + fs->nk++; + luaC_barrier(L, f, v); + return k; +} + + +/* +** Add a string to list of constants and return its index. +*/ +static int stringK (FuncState *fs, TString *s) { + TValue o; + setsvalue(fs->ls->L, &o, s); + return addk(fs, &o, &o); /* use string itself as key */ +} + + +/* +** Add an integer to list of constants and return its index. +*/ +static int luaK_intK (FuncState *fs, lua_Integer n) { + TValue o; + setivalue(&o, n); + return addk(fs, &o, &o); /* use integer itself as key */ +} + +/* +** Add a float to list of constants and return its index. Floats +** with integral values need a different key, to avoid collision +** with actual integers. To that, we add to the number its smaller +** power-of-two fraction that is still significant in its scale. +** For doubles, that would be 1/2^52. +** (This method is not bulletproof: there may be another float +** with that value, and for floats larger than 2^53 the result is +** still an integer. At worst, this only wastes an entry with +** a duplicate.) +*/ +static int luaK_numberK (FuncState *fs, lua_Number r) { + TValue o; + lua_Integer ik; + setfltvalue(&o, r); + if (!luaV_flttointeger(r, &ik, F2Ieq)) /* not an integral value? */ + return addk(fs, &o, &o); /* use number itself as key */ + else { /* must build an alternative key */ + const int nbm = l_floatatt(MANT_DIG); + const lua_Number q = l_mathop(ldexp)(l_mathop(1.0), -nbm + 1); + const lua_Number k = (ik == 0) ? q : r + r*q; /* new key */ + TValue kv; + setfltvalue(&kv, k); + /* result is not an integral value, unless value is too large */ + lua_assert(!luaV_flttointeger(k, &ik, F2Ieq) || + l_mathop(fabs)(r) >= l_mathop(1e6)); + return addk(fs, &kv, &o); + } +} + + +/* +** Add a false to list of constants and return its index. +*/ +static int boolF (FuncState *fs) { + TValue o; + setbfvalue(&o); + return addk(fs, &o, &o); /* use boolean itself as key */ +} + + +/* +** Add a true to list of constants and return its index. +*/ +static int boolT (FuncState *fs) { + TValue o; + setbtvalue(&o); + return addk(fs, &o, &o); /* use boolean itself as key */ +} + + +/* +** Add nil to list of constants and return its index. +*/ +static int nilK (FuncState *fs) { + TValue k, v; + setnilvalue(&v); + /* cannot use nil as key; instead use table itself to represent nil */ + sethvalue(fs->ls->L, &k, fs->ls->h); + return addk(fs, &k, &v); +} + + +/* +** Check whether 'i' can be stored in an 'sC' operand. Equivalent to +** (0 <= int2sC(i) && int2sC(i) <= MAXARG_C) but without risk of +** overflows in the hidden addition inside 'int2sC'. +*/ +static int fitsC (lua_Integer i) { + return (l_castS2U(i) + OFFSET_sC <= cast_uint(MAXARG_C)); +} + + +/* +** Check whether 'i' can be stored in an 'sBx' operand. +*/ +static int fitsBx (lua_Integer i) { + return (-OFFSET_sBx <= i && i <= MAXARG_Bx - OFFSET_sBx); +} + + +void luaK_int (FuncState *fs, int reg, lua_Integer i) { + if (fitsBx(i)) + codeAsBx(fs, OP_LOADI, reg, cast_int(i)); + else + luaK_codek(fs, reg, luaK_intK(fs, i)); +} + + +static void luaK_float (FuncState *fs, int reg, lua_Number f) { + lua_Integer fi; + if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi)) + codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); + else + luaK_codek(fs, reg, luaK_numberK(fs, f)); +} + + +/* +** Convert a constant in 'v' into an expression description 'e' +*/ +static void const2exp (TValue *v, expdesc *e) { + switch (ttypetag(v)) { + case LUA_VNUMINT: + e->k = VKINT; e->u.ival = ivalue(v); + break; + case LUA_VNUMFLT: + e->k = VKFLT; e->u.nval = fltvalue(v); + break; + case LUA_VFALSE: + e->k = VFALSE; + break; + case LUA_VTRUE: + e->k = VTRUE; + break; + case LUA_VNIL: + e->k = VNIL; + break; + case LUA_VSHRSTR: case LUA_VLNGSTR: + e->k = VKSTR; e->u.strval = tsvalue(v); + break; + default: lua_assert(0); + } +} + + +/* +** Fix an expression to return the number of results 'nresults'. +** 'e' must be a multi-ret expression (function call or vararg). +*/ +void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { + Instruction *pc = &getinstruction(fs, e); + if (e->k == VCALL) /* expression is an open function call? */ + SETARG_C(*pc, nresults + 1); + else { + lua_assert(e->k == VVARARG); + SETARG_C(*pc, nresults + 1); + SETARG_A(*pc, fs->freereg); + luaK_reserveregs(fs, 1); + } +} + + +/* +** Convert a VKSTR to a VK +*/ +static void str2K (FuncState *fs, expdesc *e) { + lua_assert(e->k == VKSTR); + e->u.info = stringK(fs, e->u.strval); + e->k = VK; +} + + +/* +** Fix an expression to return one result. +** If expression is not a multi-ret expression (function call or +** vararg), it already returns one result, so nothing needs to be done. +** Function calls become VNONRELOC expressions (as its result comes +** fixed in the base register of the call), while vararg expressions +** become VRELOC (as OP_VARARG puts its results where it wants). +** (Calls are created returning one result, so that does not need +** to be fixed.) +*/ +void luaK_setoneret (FuncState *fs, expdesc *e) { + if (e->k == VCALL) { /* expression is an open function call? */ + /* already returns 1 value */ + lua_assert(GETARG_C(getinstruction(fs, e)) == 2); + e->k = VNONRELOC; /* result has fixed position */ + e->u.info = GETARG_A(getinstruction(fs, e)); + } + else if (e->k == VVARARG) { + SETARG_C(getinstruction(fs, e), 2); + e->k = VRELOC; /* can relocate its simple result */ + } +} + + +/* +** Ensure that expression 'e' is not a variable (nor a ). +** (Expression still may have jump lists.) +*/ +void luaK_dischargevars (FuncState *fs, expdesc *e) { + switch (e->k) { + case VCONST: { + const2exp(const2val(fs, e), e); + break; + } + case VLOCAL: { /* already in a register */ + int temp = e->u.var.ridx; + e->u.info = temp; /* (can't do a direct assignment; values overlap) */ + e->k = VNONRELOC; /* becomes a non-relocatable value */ + break; + } + case VUPVAL: { /* move value to some (pending) register */ + e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); + e->k = VRELOC; + break; + } + case VINDEXUP: { + e->u.info = luaK_codeABC(fs, OP_GETTABUP, 0, e->u.ind.t, e->u.ind.idx); + e->k = VRELOC; + break; + } + case VINDEXI: { + freereg(fs, e->u.ind.t); + e->u.info = luaK_codeABC(fs, OP_GETI, 0, e->u.ind.t, e->u.ind.idx); + e->k = VRELOC; + break; + } + case VINDEXSTR: { + freereg(fs, e->u.ind.t); + e->u.info = luaK_codeABC(fs, OP_GETFIELD, 0, e->u.ind.t, e->u.ind.idx); + e->k = VRELOC; + break; + } + case VINDEXED: { + freeregs(fs, e->u.ind.t, e->u.ind.idx); + e->u.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.ind.t, e->u.ind.idx); + e->k = VRELOC; + break; + } + case VVARARG: case VCALL: { + luaK_setoneret(fs, e); + break; + } + default: break; /* there is one value available (somewhere) */ + } +} + + +/* +** Ensure expression value is in register 'reg', making 'e' a +** non-relocatable expression. +** (Expression still may have jump lists.) +*/ +static void discharge2reg (FuncState *fs, expdesc *e, int reg) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: { + luaK_codeABC(fs, OP_LOADFALSE, reg, 0, 0); + break; + } + case VTRUE: { + luaK_codeABC(fs, OP_LOADTRUE, reg, 0, 0); + break; + } + case VKSTR: { + str2K(fs, e); + } /* FALLTHROUGH */ + case VK: { + luaK_codek(fs, reg, e->u.info); + break; + } + case VKFLT: { + luaK_float(fs, reg, e->u.nval); + break; + } + case VKINT: { + luaK_int(fs, reg, e->u.ival); + break; + } + case VRELOC: { + Instruction *pc = &getinstruction(fs, e); + SETARG_A(*pc, reg); /* instruction will put result in 'reg' */ + break; + } + case VNONRELOC: { + if (reg != e->u.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); + break; + } + default: { + lua_assert(e->k == VJMP); + return; /* nothing to do... */ + } + } + e->u.info = reg; + e->k = VNONRELOC; +} + + +/* +** Ensure expression value is in a register, making 'e' a +** non-relocatable expression. +** (Expression still may have jump lists.) +*/ +static void discharge2anyreg (FuncState *fs, expdesc *e) { + if (e->k != VNONRELOC) { /* no fixed register yet? */ + luaK_reserveregs(fs, 1); /* get a register */ + discharge2reg(fs, e, fs->freereg-1); /* put value there */ + } +} + + +static int code_loadbool (FuncState *fs, int A, OpCode op) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, op, A, 0, 0); +} + + +/* +** check whether list has any jump that do not produce a value +** or produce an inverted value +*/ +static int need_value (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) return 1; + } + return 0; /* not found */ +} + + +/* +** Ensures final expression result (which includes results from its +** jump lists) is in register 'reg'. +** If expression has jumps, need to patch these jumps either to +** its final position or to "load" instructions (for those tests +** that do not produce values). +*/ +static void exp2reg (FuncState *fs, expdesc *e, int reg) { + discharge2reg(fs, e, reg); + if (e->k == VJMP) /* expression itself is a test? */ + luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */ + if (hasjumps(e)) { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t) || need_value(fs, e->f)) { + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); + p_f = code_loadbool(fs, reg, OP_LFALSESKIP); /* skip next inst. */ + p_t = code_loadbool(fs, reg, OP_LOADTRUE); + /* jump around these booleans if 'e' is not a test */ + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + patchlistaux(fs, e->f, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t); + } + e->f = e->t = NO_JUMP; + e->u.info = reg; + e->k = VNONRELOC; +} + + +/* +** Ensures final expression result is in next available register. +*/ +void luaK_exp2nextreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + freeexp(fs, e); + luaK_reserveregs(fs, 1); + exp2reg(fs, e, fs->freereg - 1); +} + + +/* +** Ensures final expression result is in some (any) register +** and return that register. +*/ +int luaK_exp2anyreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) { /* expression already has a register? */ + if (!hasjumps(e)) /* no jumps? */ + return e->u.info; /* result is already in a register */ + if (e->u.info >= luaY_nvarstack(fs)) { /* reg. is not a local? */ + exp2reg(fs, e, e->u.info); /* put final result in it */ + return e->u.info; + } + /* else expression has jumps and cannot change its register + to hold the jump values, because it is a local variable. + Go through to the default case. */ + } + luaK_exp2nextreg(fs, e); /* default: use next available register */ + return e->u.info; +} + + +/* +** Ensures final expression result is either in a register +** or in an upvalue. +*/ +void luaK_exp2anyregup (FuncState *fs, expdesc *e) { + if (e->k != VUPVAL || hasjumps(e)) + luaK_exp2anyreg(fs, e); +} + + +/* +** Ensures final expression result is either in a register +** or it is a constant. +*/ +void luaK_exp2val (FuncState *fs, expdesc *e) { + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); +} + + +/* +** Try to make 'e' a K expression with an index in the range of R/K +** indices. Return true iff succeeded. +*/ +static int luaK_exp2K (FuncState *fs, expdesc *e) { + if (!hasjumps(e)) { + int info; + switch (e->k) { /* move constants to 'k' */ + case VTRUE: info = boolT(fs); break; + case VFALSE: info = boolF(fs); break; + case VNIL: info = nilK(fs); break; + case VKINT: info = luaK_intK(fs, e->u.ival); break; + case VKFLT: info = luaK_numberK(fs, e->u.nval); break; + case VKSTR: info = stringK(fs, e->u.strval); break; + case VK: info = e->u.info; break; + default: return 0; /* not a constant */ + } + if (info <= MAXINDEXRK) { /* does constant fit in 'argC'? */ + e->k = VK; /* make expression a 'K' expression */ + e->u.info = info; + return 1; + } + } + /* else, expression doesn't fit; leave it unchanged */ + return 0; +} + + +/* +** Ensures final expression result is in a valid R/K index +** (that is, it is either in a register or in 'k' with an index +** in the range of R/K indices). +** Returns 1 iff expression is K. +*/ +static int exp2RK (FuncState *fs, expdesc *e) { + if (luaK_exp2K(fs, e)) + return 1; + else { /* not a constant in the right range: put it in a register */ + luaK_exp2anyreg(fs, e); + return 0; + } +} + + +static void codeABRK (FuncState *fs, OpCode o, int a, int b, + expdesc *ec) { + int k = exp2RK(fs, ec); + luaK_codeABCk(fs, o, a, b, ec->u.info, k); +} + + +/* +** Generate code to store result of expression 'ex' into variable 'var'. +*/ +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { + switch (var->k) { + case VLOCAL: { + freeexp(fs, ex); + exp2reg(fs, ex, var->u.var.ridx); /* compute 'ex' into proper place */ + return; + } + case VUPVAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); + break; + } + case VINDEXUP: { + codeABRK(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, ex); + break; + } + case VINDEXI: { + codeABRK(fs, OP_SETI, var->u.ind.t, var->u.ind.idx, ex); + break; + } + case VINDEXSTR: { + codeABRK(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, ex); + break; + } + case VINDEXED: { + codeABRK(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, ex); + break; + } + default: lua_assert(0); /* invalid var kind to store */ + } + freeexp(fs, ex); +} + + +/* +** Emit SELF instruction (convert expression 'e' into 'e:key(e,'). +*/ +void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { + int ereg; + luaK_exp2anyreg(fs, e); + ereg = e->u.info; /* register where 'e' was placed */ + freeexp(fs, e); + e->u.info = fs->freereg; /* base register for op_self */ + e->k = VNONRELOC; /* self expression has a fixed register */ + luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ + codeABRK(fs, OP_SELF, e->u.info, ereg, key); + freeexp(fs, key); +} + + +/* +** Negate condition 'e' (where 'e' is a comparison). +*/ +static void negatecondition (FuncState *fs, expdesc *e) { + Instruction *pc = getjumpcontrol(fs, e->u.info); + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && + GET_OPCODE(*pc) != OP_TEST); + SETARG_k(*pc, (GETARG_k(*pc) ^ 1)); +} + + +/* +** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond' +** is true, code will jump if 'e' is true.) Return jump position. +** Optimize when 'e' is 'not' something, inverting the condition +** and removing the 'not'. +*/ +static int jumponcond (FuncState *fs, expdesc *e, int cond) { + if (e->k == VRELOC) { + Instruction ie = getinstruction(fs, e); + if (GET_OPCODE(ie) == OP_NOT) { + removelastinstruction(fs); /* remove previous OP_NOT */ + return condjump(fs, OP_TEST, GETARG_B(ie), 0, 0, !cond); + } + /* else go through */ + } + discharge2anyreg(fs, e); + freeexp(fs, e); + return condjump(fs, OP_TESTSET, NO_REG, e->u.info, 0, cond); +} + + +/* +** Emit code to go through if 'e' is true, jump otherwise. +*/ +void luaK_goiftrue (FuncState *fs, expdesc *e) { + int pc; /* pc of new jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VJMP: { /* condition? */ + negatecondition(fs, e); /* jump when it is false */ + pc = e->u.info; /* save jump position */ + break; + } + case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + default: { + pc = jumponcond(fs, e, 0); /* jump when false */ + break; + } + } + luaK_concat(fs, &e->f, pc); /* insert new jump in false list */ + luaK_patchtohere(fs, e->t); /* true list jumps to here (to go through) */ + e->t = NO_JUMP; +} + + +/* +** Emit code to go through if 'e' is false, jump otherwise. +*/ +void luaK_goiffalse (FuncState *fs, expdesc *e) { + int pc; /* pc of new jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VJMP: { + pc = e->u.info; /* already jump if true */ + break; + } + case VNIL: case VFALSE: { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + default: { + pc = jumponcond(fs, e, 1); /* jump if true */ + break; + } + } + luaK_concat(fs, &e->t, pc); /* insert new jump in 't' list */ + luaK_patchtohere(fs, e->f); /* false list jumps to here (to go through) */ + e->f = NO_JUMP; +} + + +/* +** Code 'not e', doing constant folding. +*/ +static void codenot (FuncState *fs, expdesc *e) { + switch (e->k) { + case VNIL: case VFALSE: { + e->k = VTRUE; /* true == not nil == not false */ + break; + } + case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: { + e->k = VFALSE; /* false == not "x" == not 0.5 == not 1 == not true */ + break; + } + case VJMP: { + negatecondition(fs, e); + break; + } + case VRELOC: + case VNONRELOC: { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); + e->k = VRELOC; + break; + } + default: lua_assert(0); /* cannot happen */ + } + /* interchange true and false lists */ + { int temp = e->f; e->f = e->t; e->t = temp; } + removevalues(fs, e->f); /* values are useless when negated */ + removevalues(fs, e->t); +} + + +/* +** Check whether expression 'e' is a short literal string +*/ +static int isKstr (FuncState *fs, expdesc *e) { + return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B && + ttisshrstring(&fs->f->k[e->u.info])); +} + +/* +** Check whether expression 'e' is a literal integer. +*/ +static int isKint (expdesc *e) { + return (e->k == VKINT && !hasjumps(e)); +} + + +/* +** Check whether expression 'e' is a literal integer in +** proper range to fit in register C +*/ +static int isCint (expdesc *e) { + return isKint(e) && (l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C)); +} + + +/* +** Check whether expression 'e' is a literal integer in +** proper range to fit in register sC +*/ +static int isSCint (expdesc *e) { + return isKint(e) && fitsC(e->u.ival); +} + + +/* +** Check whether expression 'e' is a literal integer or float in +** proper range to fit in a register (sB or sC). +*/ +static int isSCnumber (expdesc *e, int *pi, int *isfloat) { + lua_Integer i; + if (e->k == VKINT) + i = e->u.ival; + else if (e->k == VKFLT && luaV_flttointeger(e->u.nval, &i, F2Ieq)) + *isfloat = 1; + else + return 0; /* not a number */ + if (!hasjumps(e) && fitsC(i)) { + *pi = int2sC(cast_int(i)); + return 1; + } + else + return 0; +} + + +/* +** Create expression 't[k]'. 't' must have its final result already in a +** register or upvalue. Upvalues can only be indexed by literal strings. +** Keys can be literal strings in the constant table or arbitrary +** values in registers. +*/ +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { + if (k->k == VKSTR) + str2K(fs, k); + lua_assert(!hasjumps(t) && + (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL)); + if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */ + luaK_exp2anyreg(fs, t); /* put it in a register */ + if (t->k == VUPVAL) { + int temp = t->u.info; /* upvalue index */ + lua_assert(isKstr(fs, k)); + t->u.ind.t = temp; /* (can't do a direct assignment; values overlap) */ + t->u.ind.idx = k->u.info; /* literal short string */ + t->k = VINDEXUP; + } + else { + /* register index of the table */ + t->u.ind.t = (t->k == VLOCAL) ? t->u.var.ridx: t->u.info; + if (isKstr(fs, k)) { + t->u.ind.idx = k->u.info; /* literal short string */ + t->k = VINDEXSTR; + } + else if (isCint(k)) { + t->u.ind.idx = cast_int(k->u.ival); /* int. constant in proper range */ + t->k = VINDEXI; + } + else { + t->u.ind.idx = luaK_exp2anyreg(fs, k); /* register */ + t->k = VINDEXED; + } + } +} + + +/* +** Return false if folding can raise an error. +** Bitwise operations need operands convertible to integers; division +** operations cannot have 0 as divisor. +*/ +static int validop (int op, TValue *v1, TValue *v2) { + switch (op) { + case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: + case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */ + lua_Integer i; + return (luaV_tointegerns(v1, &i, LUA_FLOORN2I) && + luaV_tointegerns(v2, &i, LUA_FLOORN2I)); + } + case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */ + return (nvalue(v2) != 0); + default: return 1; /* everything else is valid */ + } +} + + +/* +** Try to "constant-fold" an operation; return 1 iff successful. +** (In this case, 'e1' has the final result.) +*/ +static int constfolding (FuncState *fs, int op, expdesc *e1, + const expdesc *e2) { + TValue v1, v2, res; + if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) + return 0; /* non-numeric operands or not safe to fold */ + luaO_rawarith(fs->ls->L, op, &v1, &v2, &res); /* does operation */ + if (ttisinteger(&res)) { + e1->k = VKINT; + e1->u.ival = ivalue(&res); + } + else { /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */ + lua_Number n = fltvalue(&res); + if (luai_numisnan(n) || n == 0) + return 0; + e1->k = VKFLT; + e1->u.nval = n; + } + return 1; +} + + +/* +** Convert a BinOpr to an OpCode (ORDER OPR - ORDER OP) +*/ +l_sinline OpCode binopr2op (BinOpr opr, BinOpr baser, OpCode base) { + lua_assert(baser <= opr && + ((baser == OPR_ADD && opr <= OPR_SHR) || + (baser == OPR_LT && opr <= OPR_LE))); + return cast(OpCode, (cast_int(opr) - cast_int(baser)) + cast_int(base)); +} + + +/* +** Convert a UnOpr to an OpCode (ORDER OPR - ORDER OP) +*/ +l_sinline OpCode unopr2op (UnOpr opr) { + return cast(OpCode, (cast_int(opr) - cast_int(OPR_MINUS)) + + cast_int(OP_UNM)); +} + + +/* +** Convert a BinOpr to a tag method (ORDER OPR - ORDER TM) +*/ +l_sinline TMS binopr2TM (BinOpr opr) { + lua_assert(OPR_ADD <= opr && opr <= OPR_SHR); + return cast(TMS, (cast_int(opr) - cast_int(OPR_ADD)) + cast_int(TM_ADD)); +} + + +/* +** Emit code for unary expressions that "produce values" +** (everything but 'not'). +** Expression to produce final result will be encoded in 'e'. +*/ +static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { + int r = luaK_exp2anyreg(fs, e); /* opcodes operate only on registers */ + freeexp(fs, e); + e->u.info = luaK_codeABC(fs, op, 0, r, 0); /* generate opcode */ + e->k = VRELOC; /* all those operations are relocatable */ + luaK_fixline(fs, line); +} + + +/* +** Emit code for binary expressions that "produce values" +** (everything but logical operators 'and'/'or' and comparison +** operators). +** Expression to produce final result will be encoded in 'e1'. +*/ +static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, + OpCode op, int v2, int flip, int line, + OpCode mmop, TMS event) { + int v1 = luaK_exp2anyreg(fs, e1); + int pc = luaK_codeABCk(fs, op, 0, v1, v2, 0); + freeexps(fs, e1, e2); + e1->u.info = pc; + e1->k = VRELOC; /* all those operations are relocatable */ + luaK_fixline(fs, line); + luaK_codeABCk(fs, mmop, v1, v2, event, flip); /* to call metamethod */ + luaK_fixline(fs, line); +} + + +/* +** Emit code for binary expressions that "produce values" over +** two registers. +*/ +static void codebinexpval (FuncState *fs, BinOpr opr, + expdesc *e1, expdesc *e2, int line) { + OpCode op = binopr2op(opr, OPR_ADD, OP_ADD); + int v2 = luaK_exp2anyreg(fs, e2); /* make sure 'e2' is in a register */ + /* 'e1' must be already in a register or it is a constant */ + lua_assert((VNIL <= e1->k && e1->k <= VKSTR) || + e1->k == VNONRELOC || e1->k == VRELOC); + lua_assert(OP_ADD <= op && op <= OP_SHR); + finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, binopr2TM(opr)); +} + + +/* +** Code binary operators with immediate operands. +*/ +static void codebini (FuncState *fs, OpCode op, + expdesc *e1, expdesc *e2, int flip, int line, + TMS event) { + int v2 = int2sC(cast_int(e2->u.ival)); /* immediate operand */ + lua_assert(e2->k == VKINT); + finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINI, event); +} + + +/* +** Code binary operators with K operand. +*/ +static void codebinK (FuncState *fs, BinOpr opr, + expdesc *e1, expdesc *e2, int flip, int line) { + TMS event = binopr2TM(opr); + int v2 = e2->u.info; /* K index */ + OpCode op = binopr2op(opr, OPR_ADD, OP_ADDK); + finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event); +} + + +/* Try to code a binary operator negating its second operand. +** For the metamethod, 2nd operand must keep its original value. +*/ +static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2, + OpCode op, int line, TMS event) { + if (!isKint(e2)) + return 0; /* not an integer constant */ + else { + lua_Integer i2 = e2->u.ival; + if (!(fitsC(i2) && fitsC(-i2))) + return 0; /* not in the proper range */ + else { /* operating a small integer constant */ + int v2 = cast_int(i2); + finishbinexpval(fs, e1, e2, op, int2sC(-v2), 0, line, OP_MMBINI, event); + /* correct metamethod argument */ + SETARG_B(fs->f->code[fs->pc - 1], int2sC(v2)); + return 1; /* successfully coded */ + } + } +} + + +static void swapexps (expdesc *e1, expdesc *e2) { + expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */ +} + + +/* +** Code binary operators with no constant operand. +*/ +static void codebinNoK (FuncState *fs, BinOpr opr, + expdesc *e1, expdesc *e2, int flip, int line) { + if (flip) + swapexps(e1, e2); /* back to original order */ + codebinexpval(fs, opr, e1, e2, line); /* use standard operators */ +} + + +/* +** Code arithmetic operators ('+', '-', ...). If second operand is a +** constant in the proper range, use variant opcodes with K operands. +*/ +static void codearith (FuncState *fs, BinOpr opr, + expdesc *e1, expdesc *e2, int flip, int line) { + if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) /* K operand? */ + codebinK(fs, opr, e1, e2, flip, line); + else /* 'e2' is neither an immediate nor a K operand */ + codebinNoK(fs, opr, e1, e2, flip, line); +} + + +/* +** Code commutative operators ('+', '*'). If first operand is a +** numeric constant, change order of operands to try to use an +** immediate or K operator. +*/ +static void codecommutative (FuncState *fs, BinOpr op, + expdesc *e1, expdesc *e2, int line) { + int flip = 0; + if (tonumeral(e1, NULL)) { /* is first operand a numeric constant? */ + swapexps(e1, e2); /* change order */ + flip = 1; + } + if (op == OPR_ADD && isSCint(e2)) /* immediate operand? */ + codebini(fs, OP_ADDI, e1, e2, flip, line, TM_ADD); + else + codearith(fs, op, e1, e2, flip, line); +} + + +/* +** Code bitwise operations; they are all commutative, so the function +** tries to put an integer constant as the 2nd operand (a K operand). +*/ +static void codebitwise (FuncState *fs, BinOpr opr, + expdesc *e1, expdesc *e2, int line) { + int flip = 0; + if (e1->k == VKINT) { + swapexps(e1, e2); /* 'e2' will be the constant operand */ + flip = 1; + } + if (e2->k == VKINT && luaK_exp2K(fs, e2)) /* K operand? */ + codebinK(fs, opr, e1, e2, flip, line); + else /* no constants */ + codebinNoK(fs, opr, e1, e2, flip, line); +} + + +/* +** Emit code for order comparisons. When using an immediate operand, +** 'isfloat' tells whether the original value was a float. +*/ +static void codeorder (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { + int r1, r2; + int im; + int isfloat = 0; + OpCode op; + if (isSCnumber(e2, &im, &isfloat)) { + /* use immediate operand */ + r1 = luaK_exp2anyreg(fs, e1); + r2 = im; + op = binopr2op(opr, OPR_LT, OP_LTI); + } + else if (isSCnumber(e1, &im, &isfloat)) { + /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */ + r1 = luaK_exp2anyreg(fs, e2); + r2 = im; + op = binopr2op(opr, OPR_LT, OP_GTI); + } + else { /* regular case, compare two registers */ + r1 = luaK_exp2anyreg(fs, e1); + r2 = luaK_exp2anyreg(fs, e2); + op = binopr2op(opr, OPR_LT, OP_LT); + } + freeexps(fs, e1, e2); + e1->u.info = condjump(fs, op, r1, r2, isfloat, 1); + e1->k = VJMP; +} + + +/* +** Emit code for equality comparisons ('==', '~='). +** 'e1' was already put as RK by 'luaK_infix'. +*/ +static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { + int r1, r2; + int im; + int isfloat = 0; /* not needed here, but kept for symmetry */ + OpCode op; + if (e1->k != VNONRELOC) { + lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT); + swapexps(e1, e2); + } + r1 = luaK_exp2anyreg(fs, e1); /* 1st expression must be in register */ + if (isSCnumber(e2, &im, &isfloat)) { + op = OP_EQI; + r2 = im; /* immediate operand */ + } + else if (exp2RK(fs, e2)) { /* 2nd expression is constant? */ + op = OP_EQK; + r2 = e2->u.info; /* constant index */ + } + else { + op = OP_EQ; /* will compare two registers */ + r2 = luaK_exp2anyreg(fs, e2); + } + freeexps(fs, e1, e2); + e1->u.info = condjump(fs, op, r1, r2, isfloat, (opr == OPR_EQ)); + e1->k = VJMP; +} + + +/* +** Apply prefix operation 'op' to expression 'e'. +*/ +void luaK_prefix (FuncState *fs, UnOpr opr, expdesc *e, int line) { + static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; + luaK_dischargevars(fs, e); + switch (opr) { + case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */ + if (constfolding(fs, opr + LUA_OPUNM, e, &ef)) + break; + /* else */ /* FALLTHROUGH */ + case OPR_LEN: + codeunexpval(fs, unopr2op(opr), e, line); + break; + case OPR_NOT: codenot(fs, e); break; + default: lua_assert(0); + } +} + + +/* +** Process 1st operand 'v' of binary operation 'op' before reading +** 2nd operand. +*/ +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { + luaK_dischargevars(fs, v); + switch (op) { + case OPR_AND: { + luaK_goiftrue(fs, v); /* go ahead only if 'v' is true */ + break; + } + case OPR_OR: { + luaK_goiffalse(fs, v); /* go ahead only if 'v' is false */ + break; + } + case OPR_CONCAT: { + luaK_exp2nextreg(fs, v); /* operand must be on the stack */ + break; + } + case OPR_ADD: case OPR_SUB: + case OPR_MUL: case OPR_DIV: case OPR_IDIV: + case OPR_MOD: case OPR_POW: + case OPR_BAND: case OPR_BOR: case OPR_BXOR: + case OPR_SHL: case OPR_SHR: { + if (!tonumeral(v, NULL)) + luaK_exp2anyreg(fs, v); + /* else keep numeral, which may be folded or used as an immediate + operand */ + break; + } + case OPR_EQ: case OPR_NE: { + if (!tonumeral(v, NULL)) + exp2RK(fs, v); + /* else keep numeral, which may be an immediate operand */ + break; + } + case OPR_LT: case OPR_LE: + case OPR_GT: case OPR_GE: { + int dummy, dummy2; + if (!isSCnumber(v, &dummy, &dummy2)) + luaK_exp2anyreg(fs, v); + /* else keep numeral, which may be an immediate operand */ + break; + } + default: lua_assert(0); + } +} + +/* +** Create code for '(e1 .. e2)'. +** For '(e1 .. e2.1 .. e2.2)' (which is '(e1 .. (e2.1 .. e2.2))', +** because concatenation is right associative), merge both CONCATs. +*/ +static void codeconcat (FuncState *fs, expdesc *e1, expdesc *e2, int line) { + Instruction *ie2 = previousinstruction(fs); + if (GET_OPCODE(*ie2) == OP_CONCAT) { /* is 'e2' a concatenation? */ + int n = GETARG_B(*ie2); /* # of elements concatenated in 'e2' */ + lua_assert(e1->u.info + 1 == GETARG_A(*ie2)); + freeexp(fs, e2); + SETARG_A(*ie2, e1->u.info); /* correct first element ('e1') */ + SETARG_B(*ie2, n + 1); /* will concatenate one more element */ + } + else { /* 'e2' is not a concatenation */ + luaK_codeABC(fs, OP_CONCAT, e1->u.info, 2, 0); /* new concat opcode */ + freeexp(fs, e2); + luaK_fixline(fs, line); + } +} + + +/* +** Finalize code for binary operation, after reading 2nd operand. +*/ +void luaK_posfix (FuncState *fs, BinOpr opr, + expdesc *e1, expdesc *e2, int line) { + luaK_dischargevars(fs, e2); + if (foldbinop(opr) && constfolding(fs, opr + LUA_OPADD, e1, e2)) + return; /* done by folding */ + switch (opr) { + case OPR_AND: { + lua_assert(e1->t == NO_JUMP); /* list closed by 'luaK_infix' */ + luaK_concat(fs, &e2->f, e1->f); + *e1 = *e2; + break; + } + case OPR_OR: { + lua_assert(e1->f == NO_JUMP); /* list closed by 'luaK_infix' */ + luaK_concat(fs, &e2->t, e1->t); + *e1 = *e2; + break; + } + case OPR_CONCAT: { /* e1 .. e2 */ + luaK_exp2nextreg(fs, e2); + codeconcat(fs, e1, e2, line); + break; + } + case OPR_ADD: case OPR_MUL: { + codecommutative(fs, opr, e1, e2, line); + break; + } + case OPR_SUB: { + if (finishbinexpneg(fs, e1, e2, OP_ADDI, line, TM_SUB)) + break; /* coded as (r1 + -I) */ + /* ELSE */ + } /* FALLTHROUGH */ + case OPR_DIV: case OPR_IDIV: case OPR_MOD: case OPR_POW: { + codearith(fs, opr, e1, e2, 0, line); + break; + } + case OPR_BAND: case OPR_BOR: case OPR_BXOR: { + codebitwise(fs, opr, e1, e2, line); + break; + } + case OPR_SHL: { + if (isSCint(e1)) { + swapexps(e1, e2); + codebini(fs, OP_SHLI, e1, e2, 1, line, TM_SHL); /* I << r2 */ + } + else if (finishbinexpneg(fs, e1, e2, OP_SHRI, line, TM_SHL)) { + /* coded as (r1 >> -I) */; + } + else /* regular case (two registers) */ + codebinexpval(fs, opr, e1, e2, line); + break; + } + case OPR_SHR: { + if (isSCint(e2)) + codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR); /* r1 >> I */ + else /* regular case (two registers) */ + codebinexpval(fs, opr, e1, e2, line); + break; + } + case OPR_EQ: case OPR_NE: { + codeeq(fs, opr, e1, e2); + break; + } + case OPR_GT: case OPR_GE: { + /* '(a > b)' <=> '(b < a)'; '(a >= b)' <=> '(b <= a)' */ + swapexps(e1, e2); + opr = cast(BinOpr, (opr - OPR_GT) + OPR_LT); + } /* FALLTHROUGH */ + case OPR_LT: case OPR_LE: { + codeorder(fs, opr, e1, e2); + break; + } + default: lua_assert(0); + } +} + + +/* +** Change line information associated with current position, by removing +** previous info and adding it again with new line. +*/ +void luaK_fixline (FuncState *fs, int line) { + removelastlineinfo(fs); + savelineinfo(fs, fs->f, line); +} + + +void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hsize) { + Instruction *inst = &fs->f->code[pc]; + int rb = (hsize != 0) ? luaO_ceillog2(hsize) + 1 : 0; /* hash size */ + int extra = asize / (MAXARG_C + 1); /* higher bits of array size */ + int rc = asize % (MAXARG_C + 1); /* lower bits of array size */ + int k = (extra > 0); /* true iff needs extra argument */ + *inst = CREATE_ABCk(OP_NEWTABLE, ra, rb, rc, k); + *(inst + 1) = CREATE_Ax(OP_EXTRAARG, extra); +} + + +/* +** Emit a SETLIST instruction. +** 'base' is register that keeps table; +** 'nelems' is #table plus those to be stored now; +** 'tostore' is number of values (in registers 'base + 1',...) to add to +** table (or LUA_MULTRET to add up to stack top). +*/ +void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { + lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH); + if (tostore == LUA_MULTRET) + tostore = 0; + if (nelems <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, tostore, nelems); + else { + int extra = nelems / (MAXARG_C + 1); + nelems %= (MAXARG_C + 1); + luaK_codeABCk(fs, OP_SETLIST, base, tostore, nelems, 1); + codeextraarg(fs, extra); + } + fs->freereg = base + 1; /* free registers with list values */ +} + + +/* +** return the final target of a jump (skipping jumps to jumps) +*/ +static int finaltarget (Instruction *code, int i) { + int count; + for (count = 0; count < 100; count++) { /* avoid infinite loops */ + Instruction pc = code[i]; + if (GET_OPCODE(pc) != OP_JMP) + break; + else + i += GETARG_sJ(pc) + 1; + } + return i; +} + + +/* +** Do a final pass over the code of a function, doing small peephole +** optimizations and adjustments. +*/ +void luaK_finish (FuncState *fs) { + int i; + Proto *p = fs->f; + for (i = 0; i < fs->pc; i++) { + Instruction *pc = &p->code[i]; + lua_assert(i == 0 || isOT(*(pc - 1)) == isIT(*pc)); + switch (GET_OPCODE(*pc)) { + case OP_RETURN0: case OP_RETURN1: { + if (!(fs->needclose || p->is_vararg)) + break; /* no extra work */ + /* else use OP_RETURN to do the extra work */ + SET_OPCODE(*pc, OP_RETURN); + } /* FALLTHROUGH */ + case OP_RETURN: case OP_TAILCALL: { + if (fs->needclose) + SETARG_k(*pc, 1); /* signal that it needs to close */ + if (p->is_vararg) + SETARG_C(*pc, p->numparams + 1); /* signal that it is vararg */ + break; + } + case OP_JMP: { + int target = finaltarget(p->code, i); + fixjump(fs, i, target); + break; + } + default: break; + } + } +} diff --git a/User/system/lua/src/lcode.h b/User/system/lua/src/lcode.h new file mode 100644 index 0000000..0b971fc --- /dev/null +++ b/User/system/lua/src/lcode.h @@ -0,0 +1,101 @@ +/* +** $Id: lcode.h $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums (ORDER OP) +*/ +typedef enum BinOpr { + /* arithmetic operators */ + OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, + OPR_DIV, OPR_IDIV, + /* bitwise operators */ + OPR_BAND, OPR_BOR, OPR_BXOR, + OPR_SHL, OPR_SHR, + /* string operator */ + OPR_CONCAT, + /* comparison operators */ + OPR_EQ, OPR_LT, OPR_LE, + OPR_NE, OPR_GT, OPR_GE, + /* logical operators */ + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + + +/* true if operation is foldable (that is, it is arithmetic or bitwise) */ +#define foldbinop(op) ((op) <= OPR_SHR) + + +#define luaK_codeABC(fs,o,a,b,c) luaK_codeABCk(fs,o,a,b,c,0) + + +typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; + + +/* get (pointer to) instruction of given 'expdesc' */ +#define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) + + +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) + +#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) + +LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, + int B, int C, int k); +LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); +LUAI_FUNC void luaK_fixline (FuncState *fs, int line); +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); +LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n); +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump (FuncState *fs); +LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); +LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); +LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); +LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); +LUAI_FUNC int luaK_getlabel (FuncState *fs); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, + expdesc *v2, int line); +LUAI_FUNC void luaK_settablesize (FuncState *fs, int pc, + int ra, int asize, int hsize); +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); +LUAI_FUNC void luaK_finish (FuncState *fs); +LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *msg); + + +#endif diff --git a/User/system/lua/src/lcorolib.c b/User/system/lua/src/lcorolib.c new file mode 100644 index 0000000..c64adf0 --- /dev/null +++ b/User/system/lua/src/lcorolib.c @@ -0,0 +1,210 @@ +/* +** $Id: lcorolib.c $ +** Coroutine Library +** See Copyright Notice in lua.h +*/ + +#define lcorolib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static lua_State *getco (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argexpected(L, co, 1, "thread"); + return co; +} + + +/* +** Resumes a coroutine. Returns the number of results for non-error +** cases or -1 for errors. +*/ +static int auxresume (lua_State *L, lua_State *co, int narg) { + int status, nres; + if (l_unlikely(!lua_checkstack(co, narg))) { + lua_pushliteral(L, "too many arguments to resume"); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + status = lua_resume(co, L, narg, &nres); + if (l_likely(status == LUA_OK || status == LUA_YIELD)) { + if (l_unlikely(!lua_checkstack(L, nres + 1))) { + lua_pop(co, nres); /* remove results anyway */ + lua_pushliteral(L, "too many results to resume"); + return -1; /* error flag */ + } + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } +} + + +static int luaB_coresume (lua_State *L) { + lua_State *co = getco(L); + int r; + r = auxresume(L, co, lua_gettop(L) - 1); + if (l_unlikely(r < 0)) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + 'resume' returns */ + } +} + + +static int luaB_auxwrap (lua_State *L) { + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (l_unlikely(r < 0)) { /* error? */ + int stat = lua_status(co); + if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */ + stat = lua_closethread(co, L); /* close its tbc variables */ + lua_assert(stat != LUA_OK); + lua_xmove(co, L, 1); /* move error message to the caller */ + } + if (stat != LUA_ERRMEM && /* not a memory error and ... */ + lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */ + luaL_where(L, 1); /* add extra info, if available */ + lua_insert(L, -2); + lua_concat(L, 2); + } + return lua_error(L); /* propagate error */ + } + return r; +} + + +static int luaB_cocreate (lua_State *L) { + lua_State *NL; + luaL_checktype(L, 1, LUA_TFUNCTION); + NL = lua_newthread(L); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} + + +static int luaB_cowrap (lua_State *L) { + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; +} + + +static int luaB_yield (lua_State *L) { + return lua_yield(L, lua_gettop(L)); +} + + +#define COS_RUN 0 +#define COS_DEAD 1 +#define COS_YIELD 2 +#define COS_NORM 3 + + +static const char *const statname[] = + {"running", "dead", "suspended", "normal"}; + + +static int auxstatus (lua_State *L, lua_State *co) { + if (L == co) return COS_RUN; + else { + switch (lua_status(co)) { + case LUA_YIELD: + return COS_YIELD; + case LUA_OK: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar)) /* does it have frames? */ + return COS_NORM; /* it is running */ + else if (lua_gettop(co) == 0) + return COS_DEAD; + else + return COS_YIELD; /* initial state */ + } + default: /* some error occurred */ + return COS_DEAD; + } + } +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = getco(L); + lua_pushstring(L, statname[auxstatus(L, co)]); + return 1; +} + + +static int luaB_yieldable (lua_State *L) { + lua_State *co = lua_isnone(L, 1) ? L : getco(L); + lua_pushboolean(L, lua_isyieldable(co)); + return 1; +} + + +static int luaB_corunning (lua_State *L) { + int ismain = lua_pushthread(L); + lua_pushboolean(L, ismain); + return 2; +} + + +static int luaB_close (lua_State *L) { + lua_State *co = getco(L); + int status = auxstatus(L, co); + switch (status) { + case COS_DEAD: case COS_YIELD: { + status = lua_closethread(co, L); + if (status == LUA_OK) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushboolean(L, 0); + lua_xmove(co, L, 1); /* move error message */ + return 2; + } + } + default: /* normal or running coroutine */ + return luaL_error(L, "cannot close a %s coroutine", statname[status]); + } +} + + +static const luaL_Reg co_funcs[] = { + {"create", luaB_cocreate}, + {"resume", luaB_coresume}, + {"running", luaB_corunning}, + {"status", luaB_costatus}, + {"wrap", luaB_cowrap}, + {"yield", luaB_yield}, + {"isyieldable", luaB_yieldable}, + {"close", luaB_close}, + {NULL, NULL} +}; + + + +LUAMOD_API int luaopen_coroutine (lua_State *L) { + luaL_newlib(L, co_funcs); + return 1; +} + diff --git a/User/system/lua/src/lctype.c b/User/system/lua/src/lctype.c new file mode 100644 index 0000000..9542280 --- /dev/null +++ b/User/system/lua/src/lctype.c @@ -0,0 +1,64 @@ +/* +** $Id: lctype.c $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#define lctype_c +#define LUA_CORE + +#include "lprefix.h" + + +#include "lctype.h" + +#if !LUA_USE_CTYPE /* { */ + +#include + + +#if defined (LUA_UCID) /* accept UniCode IDentifiers? */ +/* consider all non-ascii codepoints to be alphabetic */ +#define NONA 0x01 +#else +#define NONA 0x00 /* default */ +#endif + + +LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { + 0x00, /* EOZ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ + 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, + 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 8. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 9. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* a. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* b. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + 0x00, 0x00, NONA, NONA, NONA, NONA, NONA, NONA, /* c. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* d. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* e. */ + NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, + NONA, NONA, NONA, NONA, NONA, 0x00, 0x00, 0x00, /* f. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#endif /* } */ diff --git a/User/system/lua/src/lctype.h b/User/system/lua/src/lctype.h new file mode 100644 index 0000000..864e190 --- /dev/null +++ b/User/system/lua/src/lctype.h @@ -0,0 +1,101 @@ +/* +** $Id: lctype.h $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lctype_h +#define lctype_h + +#include "lua.h" + + +/* +** WARNING: the functions defined here do not necessarily correspond +** to the similar functions in the standard C ctype.h. They are +** optimized for the specific needs of Lua. +*/ + +#if !defined(LUA_USE_CTYPE) + +#if 'A' == 65 && '0' == 48 +/* ASCII case: can use its own tables; faster and fixed */ +#define LUA_USE_CTYPE 0 +#else +/* must use standard C ctype */ +#define LUA_USE_CTYPE 1 +#endif + +#endif + + +#if !LUA_USE_CTYPE /* { */ + +#include + +#include "llimits.h" + + +#define ALPHABIT 0 +#define DIGITBIT 1 +#define PRINTBIT 2 +#define SPACEBIT 3 +#define XDIGITBIT 4 + + +#define MASK(B) (1 << (B)) + + +/* +** add 1 to char to allow index -1 (EOZ) +*/ +#define testprop(c,p) (luai_ctype_[(c)+1] & (p)) + +/* +** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' +*/ +#define lislalpha(c) testprop(c, MASK(ALPHABIT)) +#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) +#define lisdigit(c) testprop(c, MASK(DIGITBIT)) +#define lisspace(c) testprop(c, MASK(SPACEBIT)) +#define lisprint(c) testprop(c, MASK(PRINTBIT)) +#define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) + + +/* +** In ASCII, this 'ltolower' is correct for alphabetic characters and +** for '.'. That is enough for Lua needs. ('check_exp' ensures that +** the character either is an upper-case letter or is unchanged by +** the transformation, which holds for lower-case letters and '.'.) +*/ +#define ltolower(c) \ + check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \ + (c) | ('A' ^ 'a')) + + +/* one entry for each character and for -1 (EOZ) */ +LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];) + + +#else /* }{ */ + +/* +** use standard C ctypes +*/ + +#include + + +#define lislalpha(c) (isalpha(c) || (c) == '_') +#define lislalnum(c) (isalnum(c) || (c) == '_') +#define lisdigit(c) (isdigit(c)) +#define lisspace(c) (isspace(c)) +#define lisprint(c) (isprint(c)) +#define lisxdigit(c) (isxdigit(c)) + +#define ltolower(c) (tolower(c)) + +#endif /* } */ + +#endif + diff --git a/User/system/lua/src/ldblib.c b/User/system/lua/src/ldblib.c new file mode 100644 index 0000000..6dcbaa9 --- /dev/null +++ b/User/system/lua/src/ldblib.c @@ -0,0 +1,483 @@ +/* +** $Id: ldblib.c $ +** Interface from Lua to its debug API +** See Copyright Notice in lua.h +*/ + +#define ldblib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** The hook table at registry[HOOKKEY] maps threads to their current +** hook function. +*/ +static const char *const HOOKKEY = "_HOOKKEY"; + + +/* +** If L1 != L, L1 can be in any state, and therefore there are no +** guarantees about its stack space; any push in L1 must be +** checked. +*/ +static void checkstack (lua_State *L, lua_State *L1, int n) { + if (l_unlikely(L != L1 && !lua_checkstack(L1, n))) + luaL_error(L, "stack overflow"); +} + + +static int db_getregistry (lua_State *L) { + lua_pushvalue(L, LUA_REGISTRYINDEX); + return 1; +} + + +static int db_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); /* no metatable */ + } + return 1; +} + + +static int db_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; /* return 1st argument */ +} + + +static int db_getuservalue (lua_State *L) { + int n = (int)luaL_optinteger(L, 2, 1); + if (lua_type(L, 1) != LUA_TUSERDATA) + luaL_pushfail(L); + else if (lua_getiuservalue(L, 1, n) != LUA_TNONE) { + lua_pushboolean(L, 1); + return 2; + } + return 1; +} + + +static int db_setuservalue (lua_State *L) { + int n = (int)luaL_optinteger(L, 3, 1); + luaL_checktype(L, 1, LUA_TUSERDATA); + luaL_checkany(L, 2); + lua_settop(L, 2); + if (!lua_setiuservalue(L, 1, n)) + luaL_pushfail(L); + return 1; +} + + +/* +** Auxiliary function used by several library functions: check for +** an optional thread as function's first argument and set 'arg' with +** 1 if this argument is present (so that functions can skip it to +** access their other arguments) +*/ +static lua_State *getthread (lua_State *L, int *arg) { + if (lua_isthread(L, 1)) { + *arg = 1; + return lua_tothread(L, 1); + } + else { + *arg = 0; + return L; /* function will operate over current thread */ + } +} + + +/* +** Variations of 'lua_settable', used by 'db_getinfo' to put results +** from 'lua_getinfo' into result table. Key is always a string; +** value can be a string, an int, or a boolean. +*/ +static void settabss (lua_State *L, const char *k, const char *v) { + lua_pushstring(L, v); + lua_setfield(L, -2, k); +} + +static void settabsi (lua_State *L, const char *k, int v) { + lua_pushinteger(L, v); + lua_setfield(L, -2, k); +} + +static void settabsb (lua_State *L, const char *k, int v) { + lua_pushboolean(L, v); + lua_setfield(L, -2, k); +} + + +/* +** In function 'db_getinfo', the call to 'lua_getinfo' may push +** results on the stack; later it creates the result table to put +** these objects. Function 'treatstackoption' puts the result from +** 'lua_getinfo' on top of the result table so that it can call +** 'lua_setfield'. +*/ +static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { + if (L == L1) + lua_rotate(L, -2, 1); /* exchange object and table */ + else + lua_xmove(L1, L, 1); /* move object to the "main" stack */ + lua_setfield(L, -2, fname); /* put object into table */ +} + + +/* +** Calls 'lua_getinfo' and collects all results in a new table. +** L1 needs stack space for an optional input (function) plus +** two optional outputs (function and line table) from function +** 'lua_getinfo'. +*/ +static int db_getinfo (lua_State *L) { + lua_Debug ar; + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg+2, "flnSrtu"); + checkstack(L, L1, 3); + luaL_argcheck(L, options[0] != '>', arg + 2, "invalid option '>'"); + if (lua_isfunction(L, arg + 1)) { /* info about a function? */ + options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */ + lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */ + lua_xmove(L, L1, 1); + } + else { /* stack level */ + if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) { + luaL_pushfail(L); /* level out of range */ + return 1; + } + } + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg+2, "invalid option"); + lua_newtable(L); /* table to collect results */ + if (strchr(options, 'S')) { + lua_pushlstring(L, ar.source, ar.srclen); + lua_setfield(L, -2, "source"); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) { + settabsi(L, "nups", ar.nups); + settabsi(L, "nparams", ar.nparams); + settabsb(L, "isvararg", ar.isvararg); + } + if (strchr(options, 'n')) { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 'r')) { + settabsi(L, "ftransfer", ar.ftransfer); + settabsi(L, "ntransfer", ar.ntransfer); + } + if (strchr(options, 't')) + settabsb(L, "istailcall", ar.istailcall); + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); + return 1; /* return table */ +} + + +static int db_getlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */ + if (lua_isfunction(L, arg + 1)) { /* function argument? */ + lua_pushvalue(L, arg + 1); /* push function */ + lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */ + return 1; /* return only name (there is no value) */ + } + else { /* stack-level argument */ + lua_Debug ar; + const char *name; + int level = (int)luaL_checkinteger(L, arg + 1); + if (l_unlikely(!lua_getstack(L1, level, &ar))) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + checkstack(L, L1, 1); + name = lua_getlocal(L1, &ar, nvar); + if (name) { + lua_xmove(L1, L, 1); /* move local value */ + lua_pushstring(L, name); /* push name */ + lua_rotate(L, -2, 1); /* re-order */ + return 2; + } + else { + luaL_pushfail(L); /* no name (nor value) */ + return 1; + } + } +} + + +static int db_setlocal (lua_State *L) { + int arg; + const char *name; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + int level = (int)luaL_checkinteger(L, arg + 1); + int nvar = (int)luaL_checkinteger(L, arg + 2); + if (l_unlikely(!lua_getstack(L1, level, &ar))) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + luaL_checkany(L, arg+3); + lua_settop(L, arg+3); + checkstack(L, L1, 1); + lua_xmove(L, L1, 1); + name = lua_setlocal(L1, &ar, nvar); + if (name == NULL) + lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */ + lua_pushstring(L, name); + return 1; +} + + +/* +** get (if 'get' is true) or set an upvalue from a closure +*/ +static int auxupvalue (lua_State *L, int get) { + const char *name; + int n = (int)luaL_checkinteger(L, 2); /* upvalue index */ + luaL_checktype(L, 1, LUA_TFUNCTION); /* closure */ + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + lua_insert(L, -(get+1)); /* no-op if get is false */ + return get + 1; +} + + +static int db_getupvalue (lua_State *L) { + return auxupvalue(L, 1); +} + + +static int db_setupvalue (lua_State *L) { + luaL_checkany(L, 3); + return auxupvalue(L, 0); +} + + +/* +** Check whether a given upvalue from a given closure exists and +** returns its index +*/ +static void *checkupval (lua_State *L, int argf, int argnup, int *pnup) { + void *id; + int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */ + luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */ + id = lua_upvalueid(L, argf, nup); + if (pnup) { + luaL_argcheck(L, id != NULL, argnup, "invalid upvalue index"); + *pnup = nup; + } + return id; +} + + +static int db_upvalueid (lua_State *L) { + void *id = checkupval(L, 1, 2, NULL); + if (id != NULL) + lua_pushlightuserdata(L, id); + else + luaL_pushfail(L); + return 1; +} + + +static int db_upvaluejoin (lua_State *L) { + int n1, n2; + checkupval(L, 1, 2, &n1); + checkupval(L, 3, 4, &n2); + luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected"); + luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected"); + lua_upvaluejoin(L, 1, n1, 3, n2); + return 0; +} + + +/* +** Call hook function registered at hook table for the current +** thread (if there is one) +*/ +static void hookf (lua_State *L, lua_Debug *ar) { + static const char *const hooknames[] = + {"call", "return", "line", "count", "tail call"}; + lua_getfield(L, LUA_REGISTRYINDEX, HOOKKEY); + lua_pushthread(L); + if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */ + lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */ + if (ar->currentline >= 0) + lua_pushinteger(L, ar->currentline); /* push current line */ + else lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); /* call hook function */ + } +} + + +/* +** Convert a string mask (for 'sethook') into a bit mask +*/ +static int makemask (const char *smask, int count) { + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + return mask; +} + + +/* +** Convert a bit mask (for 'gethook') into a string mask +*/ +static char *unmakemask (int mask, char *smask) { + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; +} + + +static int db_sethook (lua_State *L) { + int arg, mask, count; + lua_Hook func; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg+1)) { /* no hook? */ + lua_settop(L, arg+1); + func = NULL; mask = 0; count = 0; /* turn off hooks */ + } + else { + const char *smask = luaL_checkstring(L, arg+2); + luaL_checktype(L, arg+1, LUA_TFUNCTION); + count = (int)luaL_optinteger(L, arg + 3, 0); + func = hookf; mask = makemask(smask, count); + } + if (!luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)) { + /* table just created; initialize it */ + lua_pushliteral(L, "k"); + lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ + lua_pushvalue(L, -1); + lua_setmetatable(L, -2); /* metatable(hooktable) = hooktable */ + } + checkstack(L, L1, 1); + lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */ + lua_pushvalue(L, arg + 1); /* value (hook function) */ + lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */ + lua_sethook(L1, func, mask, count); + return 0; +} + + +static int db_gethook (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + char buff[5]; + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); + if (hook == NULL) { /* no hook? */ + luaL_pushfail(L); + return 1; + } + else if (hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else { /* hook table must exist */ + lua_getfield(L, LUA_REGISTRYINDEX, HOOKKEY); + checkstack(L, L1, 1); + lua_pushthread(L1); lua_xmove(L1, L, 1); + lua_rawget(L, -2); /* 1st result = hooktable[L1] */ + lua_remove(L, -2); /* remove hook table */ + } + lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */ + lua_pushinteger(L, lua_gethookcount(L1)); /* 3rd result = count */ + return 3; +} + + +static int db_debug (lua_State *L) { + for (;;) { + char buffer[250]; + lua_writestringerror("%s", "lua_debug> "); + if (fgets(buffer, sizeof(buffer), stdin) == NULL || + strcmp(buffer, "cont\n") == 0) + return 0; + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || + lua_pcall(L, 0, 0, 0)) + lua_writestringerror("%s\n", luaL_tolstring(L, -1, NULL)); + lua_settop(L, 0); /* remove eventual returns */ + } +} + + +static int db_traceback (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + const char *msg = lua_tostring(L, arg + 1); + if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */ + lua_pushvalue(L, arg + 1); /* return it untouched */ + else { + int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0); + luaL_traceback(L, L1, msg, level); + } + return 1; +} + + +static int db_setcstacklimit (lua_State *L) { + int limit = (int)luaL_checkinteger(L, 1); + int res = lua_setcstacklimit(L, limit); + lua_pushinteger(L, res); + return 1; +} + + +static const luaL_Reg dblib[] = { + {"debug", db_debug}, + {"getuservalue", db_getuservalue}, + {"gethook", db_gethook}, + {"getinfo", db_getinfo}, + {"getlocal", db_getlocal}, + {"getregistry", db_getregistry}, + {"getmetatable", db_getmetatable}, + {"getupvalue", db_getupvalue}, + {"upvaluejoin", db_upvaluejoin}, + {"upvalueid", db_upvalueid}, + {"setuservalue", db_setuservalue}, + {"sethook", db_sethook}, + {"setlocal", db_setlocal}, + {"setmetatable", db_setmetatable}, + {"setupvalue", db_setupvalue}, + {"traceback", db_traceback}, + {"setcstacklimit", db_setcstacklimit}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_debug (lua_State *L) { + luaL_newlib(L, dblib); + return 1; +} + diff --git a/User/system/lua/src/ldebug.c b/User/system/lua/src/ldebug.c new file mode 100644 index 0000000..591b352 --- /dev/null +++ b/User/system/lua/src/ldebug.c @@ -0,0 +1,962 @@ +/* +** $Id: ldebug.c $ +** Debug Interface +** See Copyright Notice in lua.h +*/ + +#define ldebug_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +#define LuaClosure(f) ((f) != NULL && (f)->c.tt == LUA_VLCL) + + +static const char *funcnamefromcall (lua_State *L, CallInfo *ci, + const char **name); + + +static int currentpc (CallInfo *ci) { + lua_assert(isLua(ci)); + return pcRel(ci->u.l.savedpc, ci_func(ci)->p); +} + + +/* +** Get a "base line" to find the line corresponding to an instruction. +** Base lines are regularly placed at MAXIWTHABS intervals, so usually +** an integer division gets the right place. When the source file has +** large sequences of empty/comment lines, it may need extra entries, +** so the original estimate needs a correction. +** If the original estimate is -1, the initial 'if' ensures that the +** 'while' will run at least once. +** The assertion that the estimate is a lower bound for the correct base +** is valid as long as the debug info has been generated with the same +** value for MAXIWTHABS or smaller. (Previous releases use a little +** smaller value.) +*/ +static int getbaseline (const Proto *f, int pc, int *basepc) { + if (f->sizeabslineinfo == 0 || pc < f->abslineinfo[0].pc) { + *basepc = -1; /* start from the beginning */ + return f->linedefined; + } + else { + int i = cast_uint(pc) / MAXIWTHABS - 1; /* get an estimate */ + /* estimate must be a lower bound of the correct base */ + lua_assert(i < 0 || + (i < f->sizeabslineinfo && f->abslineinfo[i].pc <= pc)); + while (i + 1 < f->sizeabslineinfo && pc >= f->abslineinfo[i + 1].pc) + i++; /* low estimate; adjust it */ + *basepc = f->abslineinfo[i].pc; + return f->abslineinfo[i].line; + } +} + + +/* +** Get the line corresponding to instruction 'pc' in function 'f'; +** first gets a base line and from there does the increments until +** the desired instruction. +*/ +int luaG_getfuncline (const Proto *f, int pc) { + if (f->lineinfo == NULL) /* no debug information? */ + return -1; + else { + int basepc; + int baseline = getbaseline(f, pc, &basepc); + while (basepc++ < pc) { /* walk until given instruction */ + lua_assert(f->lineinfo[basepc] != ABSLINEINFO); + baseline += f->lineinfo[basepc]; /* correct line */ + } + return baseline; + } +} + + +static int getcurrentline (CallInfo *ci) { + return luaG_getfuncline(ci_func(ci)->p, currentpc(ci)); +} + + +/* +** Set 'trap' for all active Lua frames. +** This function can be called during a signal, under "reasonable" +** assumptions. A new 'ci' is completely linked in the list before it +** becomes part of the "active" list, and we assume that pointers are +** atomic; see comment in next function. +** (A compiler doing interprocedural optimizations could, theoretically, +** reorder memory writes in such a way that the list could be +** temporarily broken while inserting a new element. We simply assume it +** has no good reasons to do that.) +*/ +static void settraps (CallInfo *ci) { + for (; ci != NULL; ci = ci->previous) + if (isLua(ci)) + ci->u.l.trap = 1; +} + + +/* +** This function can be called during a signal, under "reasonable" +** assumptions. +** Fields 'basehookcount' and 'hookcount' (set by 'resethookcount') +** are for debug only, and it is no problem if they get arbitrary +** values (causes at most one wrong hook call). 'hookmask' is an atomic +** value. We assume that pointers are atomic too (e.g., gcc ensures that +** for all platforms where it runs). Moreover, 'hook' is always checked +** before being called (see 'luaD_hook'). +*/ +LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { + if (func == NULL || mask == 0) { /* turn off hooks? */ + mask = 0; + func = NULL; + } + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast_byte(mask); + if (mask) + settraps(L->ci); /* to trace inside 'luaV_execute' */ +} + + +LUA_API lua_Hook lua_gethook (lua_State *L) { + return L->hook; +} + + +LUA_API int lua_gethookmask (lua_State *L) { + return L->hookmask; +} + + +LUA_API int lua_gethookcount (lua_State *L) { + return L->basehookcount; +} + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { + int status; + CallInfo *ci; + if (level < 0) return 0; /* invalid (negative) level */ + lua_lock(L); + for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) + level--; + if (level == 0 && ci != &L->base_ci) { /* level found? */ + status = 1; + ar->i_ci = ci; + } + else status = 0; /* no such level */ + lua_unlock(L); + return status; +} + + +static const char *upvalname (const Proto *p, int uv) { + TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); + if (s == NULL) return "?"; + else return getstr(s); +} + + +static const char *findvararg (CallInfo *ci, int n, StkId *pos) { + if (clLvalue(s2v(ci->func.p))->p->is_vararg) { + int nextra = ci->u.l.nextraargs; + if (n >= -nextra) { /* 'n' is negative */ + *pos = ci->func.p - nextra - (n + 1); + return "(vararg)"; /* generic name for any vararg */ + } + } + return NULL; /* no such vararg */ +} + + +const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, StkId *pos) { + StkId base = ci->func.p + 1; + const char *name = NULL; + if (isLua(ci)) { + if (n < 0) /* access to vararg values? */ + return findvararg(ci, n, pos); + else + name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); + } + if (name == NULL) { /* no 'standard' name? */ + StkId limit = (ci == L->ci) ? L->top.p : ci->next->func.p; + if (limit - base >= n && n > 0) { /* is 'n' inside 'ci' stack? */ + /* generic name for any valid slot */ + name = isLua(ci) ? "(temporary)" : "(C temporary)"; + } + else + return NULL; /* no name */ + } + if (pos) + *pos = base + (n - 1); + return name; +} + + +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { + const char *name; + lua_lock(L); + if (ar == NULL) { /* information about non-active function? */ + if (!isLfunction(s2v(L->top.p - 1))) /* not a Lua function? */ + name = NULL; + else /* consider live variables at function start (parameters) */ + name = luaF_getlocalname(clLvalue(s2v(L->top.p - 1))->p, n, 0); + } + else { /* active function; get information through 'ar' */ + StkId pos = NULL; /* to avoid warnings */ + name = luaG_findlocal(L, ar->i_ci, n, &pos); + if (name) { + setobjs2s(L, L->top.p, pos); + api_incr_top(L); + } + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { + StkId pos = NULL; /* to avoid warnings */ + const char *name; + lua_lock(L); + name = luaG_findlocal(L, ar->i_ci, n, &pos); + if (name) { + setobjs2s(L, pos, L->top.p - 1); + L->top.p--; /* pop value */ + } + lua_unlock(L); + return name; +} + + +static void funcinfo (lua_Debug *ar, Closure *cl) { + if (!LuaClosure(cl)) { + ar->source = "=[C]"; + ar->srclen = LL("=[C]"); + ar->linedefined = -1; + ar->lastlinedefined = -1; + ar->what = "C"; + } + else { + const Proto *p = cl->l.p; + if (p->source) { + ar->source = getstr(p->source); + ar->srclen = tsslen(p->source); + } + else { + ar->source = "=?"; + ar->srclen = LL("=?"); + } + ar->linedefined = p->linedefined; + ar->lastlinedefined = p->lastlinedefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, ar->srclen); +} + + +static int nextline (const Proto *p, int currentline, int pc) { + if (p->lineinfo[pc] != ABSLINEINFO) + return currentline + p->lineinfo[pc]; + else + return luaG_getfuncline(p, pc); +} + + +static void collectvalidlines (lua_State *L, Closure *f) { + if (!LuaClosure(f)) { + setnilvalue(s2v(L->top.p)); + api_incr_top(L); + } + else { + const Proto *p = f->l.p; + int currentline = p->linedefined; + Table *t = luaH_new(L); /* new table to store active lines */ + sethvalue2s(L, L->top.p, t); /* push it on stack */ + api_incr_top(L); + if (p->lineinfo != NULL) { /* proto with debug information? */ + int i; + TValue v; + setbtvalue(&v); /* boolean 'true' to be the value of all indices */ + if (!p->is_vararg) /* regular function? */ + i = 0; /* consider all instructions */ + else { /* vararg function */ + lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP); + currentline = nextline(p, currentline, 0); + i = 1; /* skip first instruction (OP_VARARGPREP) */ + } + for (; i < p->sizelineinfo; i++) { /* for each instruction */ + currentline = nextline(p, currentline, i); /* get its line */ + luaH_setint(L, t, currentline, &v); /* table[line] = true */ + } + } + } +} + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { + /* calling function is a known function? */ + if (ci != NULL && !(ci->callstatus & CIST_TAIL)) + return funcnamefromcall(L, ci->previous, name); + else return NULL; /* no way to find a name */ +} + + +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, + Closure *f, CallInfo *ci) { + int status = 1; + for (; *what; what++) { + switch (*what) { + case 'S': { + funcinfo(ar, f); + break; + } + case 'l': { + ar->currentline = (ci && isLua(ci)) ? getcurrentline(ci) : -1; + break; + } + case 'u': { + ar->nups = (f == NULL) ? 0 : f->c.nupvalues; + if (!LuaClosure(f)) { + ar->isvararg = 1; + ar->nparams = 0; + } + else { + ar->isvararg = f->l.p->is_vararg; + ar->nparams = f->l.p->numparams; + } + break; + } + case 't': { + ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; + break; + } + case 'n': { + ar->namewhat = getfuncname(L, ci, &ar->name); + if (ar->namewhat == NULL) { + ar->namewhat = ""; /* not found */ + ar->name = NULL; + } + break; + } + case 'r': { + if (ci == NULL || !(ci->callstatus & CIST_TRAN)) + ar->ftransfer = ar->ntransfer = 0; + else { + ar->ftransfer = ci->u2.transferinfo.ftransfer; + ar->ntransfer = ci->u2.transferinfo.ntransfer; + } + break; + } + case 'L': + case 'f': /* handled by lua_getinfo */ + break; + default: status = 0; /* invalid option */ + } + } + return status; +} + + +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + int status; + Closure *cl; + CallInfo *ci; + TValue *func; + lua_lock(L); + if (*what == '>') { + ci = NULL; + func = s2v(L->top.p - 1); + api_check(L, ttisfunction(func), "function expected"); + what++; /* skip the '>' */ + L->top.p--; /* pop function */ + } + else { + ci = ar->i_ci; + func = s2v(ci->func.p); + lua_assert(ttisfunction(func)); + } + cl = ttisclosure(func) ? clvalue(func) : NULL; + status = auxgetinfo(L, what, ar, cl, ci); + if (strchr(what, 'f')) { + setobj2s(L, L->top.p, func); + api_incr_top(L); + } + if (strchr(what, 'L')) + collectvalidlines(L, cl); + lua_unlock(L); + return status; +} + + +/* +** {====================================================== +** Symbolic Execution +** ======================================================= +*/ + + +static int filterpc (int pc, int jmptarget) { + if (pc < jmptarget) /* is code conditional (inside a jump)? */ + return -1; /* cannot know who sets that register */ + else return pc; /* current position sets that register */ +} + + +/* +** Try to find last instruction before 'lastpc' that modified register 'reg'. +*/ +static int findsetreg (const Proto *p, int lastpc, int reg) { + int pc; + int setreg = -1; /* keep last instruction that changed 'reg' */ + int jmptarget = 0; /* any code before this address is conditional */ + if (testMMMode(GET_OPCODE(p->code[lastpc]))) + lastpc--; /* previous instruction was not actually executed */ + for (pc = 0; pc < lastpc; pc++) { + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + int change; /* true if current instruction changed 'reg' */ + switch (op) { + case OP_LOADNIL: { /* set registers from 'a' to 'a+b' */ + int b = GETARG_B(i); + change = (a <= reg && reg <= a + b); + break; + } + case OP_TFORCALL: { /* affect all regs above its base */ + change = (reg >= a + 2); + break; + } + case OP_CALL: + case OP_TAILCALL: { /* affect all registers above base */ + change = (reg >= a); + break; + } + case OP_JMP: { /* doesn't change registers, but changes 'jmptarget' */ + int b = GETARG_sJ(i); + int dest = pc + 1 + b; + /* jump does not skip 'lastpc' and is larger than current one? */ + if (dest <= lastpc && dest > jmptarget) + jmptarget = dest; /* update 'jmptarget' */ + change = 0; + break; + } + default: /* any instruction that sets A */ + change = (testAMode(op) && reg == a); + break; + } + if (change) + setreg = filterpc(pc, jmptarget); + } + return setreg; +} + + +/* +** Find a "name" for the constant 'c'. +*/ +static const char *kname (const Proto *p, int index, const char **name) { + TValue *kvalue = &p->k[index]; + if (ttisstring(kvalue)) { + *name = getstr(tsvalue(kvalue)); + return "constant"; + } + else { + *name = "?"; + return NULL; + } +} + + +static const char *basicgetobjname (const Proto *p, int *ppc, int reg, + const char **name) { + int pc = *ppc; + *name = luaF_getlocalname(p, reg + 1, pc); + if (*name) /* is a local? */ + return "local"; + /* else try symbolic execution */ + *ppc = pc = findsetreg(p, pc, reg); + if (pc != -1) { /* could find instruction? */ + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + switch (op) { + case OP_MOVE: { + int b = GETARG_B(i); /* move from 'b' to 'a' */ + if (b < GETARG_A(i)) + return basicgetobjname(p, ppc, b, name); /* get name for 'b' */ + break; + } + case OP_GETUPVAL: { + *name = upvalname(p, GETARG_B(i)); + return "upvalue"; + } + case OP_LOADK: return kname(p, GETARG_Bx(i), name); + case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name); + default: break; + } + } + return NULL; /* could not find reasonable name */ +} + + +/* +** Find a "name" for the register 'c'. +*/ +static void rname (const Proto *p, int pc, int c, const char **name) { + const char *what = basicgetobjname(p, &pc, c, name); /* search for 'c' */ + if (!(what && *what == 'c')) /* did not find a constant name? */ + *name = "?"; +} + + +/* +** Find a "name" for a 'C' value in an RK instruction. +*/ +static void rkname (const Proto *p, int pc, Instruction i, const char **name) { + int c = GETARG_C(i); /* key index */ + if (GETARG_k(i)) /* is 'c' a constant? */ + kname(p, c, name); + else /* 'c' is a register */ + rname(p, pc, c, name); +} + + +/* +** Check whether table being indexed by instruction 'i' is the +** environment '_ENV' +*/ +static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) { + int t = GETARG_B(i); /* table index */ + const char *name; /* name of indexed variable */ + if (isup) /* is 't' an upvalue? */ + name = upvalname(p, t); + else /* 't' is a register */ + basicgetobjname(p, &pc, t, &name); + return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; +} + + +/* +** Extend 'basicgetobjname' to handle table accesses +*/ +static const char *getobjname (const Proto *p, int lastpc, int reg, + const char **name) { + const char *kind = basicgetobjname(p, &lastpc, reg, name); + if (kind != NULL) + return kind; + else if (lastpc != -1) { /* could find instruction? */ + Instruction i = p->code[lastpc]; + OpCode op = GET_OPCODE(i); + switch (op) { + case OP_GETTABUP: { + int k = GETARG_C(i); /* key index */ + kname(p, k, name); + return isEnv(p, lastpc, i, 1); + } + case OP_GETTABLE: { + int k = GETARG_C(i); /* key index */ + rname(p, lastpc, k, name); + return isEnv(p, lastpc, i, 0); + } + case OP_GETI: { + *name = "integer index"; + return "field"; + } + case OP_GETFIELD: { + int k = GETARG_C(i); /* key index */ + kname(p, k, name); + return isEnv(p, lastpc, i, 0); + } + case OP_SELF: { + rkname(p, lastpc, i, name); + return "method"; + } + default: break; /* go through to return NULL */ + } + } + return NULL; /* could not find reasonable name */ +} + + +/* +** Try to find a name for a function based on the code that called it. +** (Only works when function was called by a Lua function.) +** Returns what the name is (e.g., "for iterator", "method", +** "metamethod") and sets '*name' to point to the name. +*/ +static const char *funcnamefromcode (lua_State *L, const Proto *p, + int pc, const char **name) { + TMS tm = (TMS)0; /* (initial value avoids warnings) */ + Instruction i = p->code[pc]; /* calling instruction */ + switch (GET_OPCODE(i)) { + case OP_CALL: + case OP_TAILCALL: + return getobjname(p, pc, GETARG_A(i), name); /* get function name */ + case OP_TFORCALL: { /* for iterator */ + *name = "for iterator"; + return "for iterator"; + } + /* other instructions can do calls through metamethods */ + case OP_SELF: case OP_GETTABUP: case OP_GETTABLE: + case OP_GETI: case OP_GETFIELD: + tm = TM_INDEX; + break; + case OP_SETTABUP: case OP_SETTABLE: case OP_SETI: case OP_SETFIELD: + tm = TM_NEWINDEX; + break; + case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { + tm = cast(TMS, GETARG_C(i)); + break; + } + case OP_UNM: tm = TM_UNM; break; + case OP_BNOT: tm = TM_BNOT; break; + case OP_LEN: tm = TM_LEN; break; + case OP_CONCAT: tm = TM_CONCAT; break; + case OP_EQ: tm = TM_EQ; break; + /* no cases for OP_EQI and OP_EQK, as they don't call metamethods */ + case OP_LT: case OP_LTI: case OP_GTI: tm = TM_LT; break; + case OP_LE: case OP_LEI: case OP_GEI: tm = TM_LE; break; + case OP_CLOSE: case OP_RETURN: tm = TM_CLOSE; break; + default: + return NULL; /* cannot find a reasonable name */ + } + *name = getshrstr(G(L)->tmname[tm]) + 2; + return "metamethod"; +} + + +/* +** Try to find a name for a function based on how it was called. +*/ +static const char *funcnamefromcall (lua_State *L, CallInfo *ci, + const char **name) { + if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ + *name = "?"; + return "hook"; + } + else if (ci->callstatus & CIST_FIN) { /* was it called as a finalizer? */ + *name = "__gc"; + return "metamethod"; /* report it as such */ + } + else if (isLua(ci)) + return funcnamefromcode(L, ci_func(ci)->p, currentpc(ci), name); + else + return NULL; +} + +/* }====================================================== */ + + + +/* +** Check whether pointer 'o' points to some value in the stack frame of +** the current function and, if so, returns its index. Because 'o' may +** not point to a value in this stack, we cannot compare it with the +** region boundaries (undefined behavior in ISO C). +*/ +static int instack (CallInfo *ci, const TValue *o) { + int pos; + StkId base = ci->func.p + 1; + for (pos = 0; base + pos < ci->top.p; pos++) { + if (o == s2v(base + pos)) + return pos; + } + return -1; /* not found */ +} + + +/* +** Checks whether value 'o' came from an upvalue. (That can only happen +** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on +** upvalues.) +*/ +static const char *getupvalname (CallInfo *ci, const TValue *o, + const char **name) { + LClosure *c = ci_func(ci); + int i; + for (i = 0; i < c->nupvalues; i++) { + if (c->upvals[i]->v.p == o) { + *name = upvalname(c->p, i); + return "upvalue"; + } + } + return NULL; +} + + +static const char *formatvarinfo (lua_State *L, const char *kind, + const char *name) { + if (kind == NULL) + return ""; /* no information */ + else + return luaO_pushfstring(L, " (%s '%s')", kind, name); +} + +/* +** Build a string with a "description" for the value 'o', such as +** "variable 'x'" or "upvalue 'y'". +*/ +static const char *varinfo (lua_State *L, const TValue *o) { + CallInfo *ci = L->ci; + const char *name = NULL; /* to avoid warnings */ + const char *kind = NULL; + if (isLua(ci)) { + kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ + if (!kind) { /* not an upvalue? */ + int reg = instack(ci, o); /* try a register */ + if (reg >= 0) /* is 'o' a register? */ + kind = getobjname(ci_func(ci)->p, currentpc(ci), reg, &name); + } + } + return formatvarinfo(L, kind, name); +} + + +/* +** Raise a type error +*/ +static l_noret typeerror (lua_State *L, const TValue *o, const char *op, + const char *extra) { + const char *t = luaT_objtypename(L, o); + luaG_runerror(L, "attempt to %s a %s value%s", op, t, extra); +} + + +/* +** Raise a type error with "standard" information about the faulty +** object 'o' (using 'varinfo'). +*/ +l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { + typeerror(L, o, op, varinfo(L, o)); +} + + +/* +** Raise an error for calling a non-callable object. Try to find a name +** for the object based on how it was called ('funcnamefromcall'); if it +** cannot get a name there, try 'varinfo'. +*/ +l_noret luaG_callerror (lua_State *L, const TValue *o) { + CallInfo *ci = L->ci; + const char *name = NULL; /* to avoid warnings */ + const char *kind = funcnamefromcall(L, ci, &name); + const char *extra = kind ? formatvarinfo(L, kind, name) : varinfo(L, o); + typeerror(L, o, "call", extra); +} + + +l_noret luaG_forerror (lua_State *L, const TValue *o, const char *what) { + luaG_runerror(L, "bad 'for' %s (number expected, got %s)", + what, luaT_objtypename(L, o)); +} + + +l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) { + if (ttisstring(p1) || cvt2str(p1)) p1 = p2; + luaG_typeerror(L, p1, "concatenate"); +} + + +l_noret luaG_opinterror (lua_State *L, const TValue *p1, + const TValue *p2, const char *msg) { + if (!ttisnumber(p1)) /* first operand is wrong? */ + p2 = p1; /* now second is wrong */ + luaG_typeerror(L, p2, msg); +} + + +/* +** Error when both values are convertible to numbers, but not to integers +*/ +l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { + lua_Integer temp; + if (!luaV_tointegerns(p1, &temp, LUA_FLOORN2I)) + p2 = p1; + luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2)); +} + + +l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { + const char *t1 = luaT_objtypename(L, p1); + const char *t2 = luaT_objtypename(L, p2); + if (strcmp(t1, t2) == 0) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); +} + + +/* add src:line information to 'msg' */ +const char *luaG_addinfo (lua_State *L, const char *msg, TString *src, + int line) { + char buff[LUA_IDSIZE]; + if (src) + luaO_chunkid(buff, getstr(src), tsslen(src)); + else { /* no source available; use "?" instead */ + buff[0] = '?'; buff[1] = '\0'; + } + return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); +} + + +l_noret luaG_errormsg (lua_State *L) { + if (L->errfunc != 0) { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + lua_assert(ttisfunction(s2v(errfunc))); + setobjs2s(L, L->top.p, L->top.p - 1); /* move argument */ + setobjs2s(L, L->top.p - 1, errfunc); /* push function */ + L->top.p++; /* assume EXTRA_STACK */ + luaD_callnoyield(L, L->top.p - 2, 1); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); +} + + +l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { + CallInfo *ci = L->ci; + const char *msg; + va_list argp; + luaC_checkGC(L); /* error message uses memory */ + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); /* format message */ + va_end(argp); + if (isLua(ci)) { /* if Lua function, add source:line information */ + luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci)); + setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */ + L->top.p--; + } + luaG_errormsg(L); +} + + +/* +** Check whether new instruction 'newpc' is in a different line from +** previous instruction 'oldpc'. More often than not, 'newpc' is only +** one or a few instructions after 'oldpc' (it must be after, see +** caller), so try to avoid calling 'luaG_getfuncline'. If they are +** too far apart, there is a good chance of a ABSLINEINFO in the way, +** so it goes directly to 'luaG_getfuncline'. +*/ +static int changedline (const Proto *p, int oldpc, int newpc) { + if (p->lineinfo == NULL) /* no debug information? */ + return 0; + if (newpc - oldpc < MAXIWTHABS / 2) { /* not too far apart? */ + int delta = 0; /* line difference */ + int pc = oldpc; + for (;;) { + int lineinfo = p->lineinfo[++pc]; + if (lineinfo == ABSLINEINFO) + break; /* cannot compute delta; fall through */ + delta += lineinfo; + if (pc == newpc) + return (delta != 0); /* delta computed successfully */ + } + } + /* either instructions are too far apart or there is an absolute line + info in the way; compute line difference explicitly */ + return (luaG_getfuncline(p, oldpc) != luaG_getfuncline(p, newpc)); +} + + +/* +** Traces Lua calls. If code is running the first instruction of a function, +** and function is not vararg, and it is not coming from an yield, +** calls 'luaD_hookcall'. (Vararg functions will call 'luaD_hookcall' +** after adjusting its variable arguments; otherwise, they could call +** a line/count hook before the call hook. Functions coming from +** an yield already called 'luaD_hookcall' before yielding.) +*/ +int luaG_tracecall (lua_State *L) { + CallInfo *ci = L->ci; + Proto *p = ci_func(ci)->p; + ci->u.l.trap = 1; /* ensure hooks will be checked */ + if (ci->u.l.savedpc == p->code) { /* first instruction (not resuming)? */ + if (p->is_vararg) + return 0; /* hooks will start at VARARGPREP instruction */ + else if (!(ci->callstatus & CIST_HOOKYIELD)) /* not yieded? */ + luaD_hookcall(L, ci); /* check 'call' hook */ + } + return 1; /* keep 'trap' on */ +} + + +/* +** Traces the execution of a Lua function. Called before the execution +** of each opcode, when debug is on. 'L->oldpc' stores the last +** instruction traced, to detect line changes. When entering a new +** function, 'npci' will be zero and will test as a new line whatever +** the value of 'oldpc'. Some exceptional conditions may return to +** a function without setting 'oldpc'. In that case, 'oldpc' may be +** invalid; if so, use zero as a valid value. (A wrong but valid 'oldpc' +** at most causes an extra call to a line hook.) +** This function is not "Protected" when called, so it should correct +** 'L->top.p' before calling anything that can run the GC. +*/ +int luaG_traceexec (lua_State *L, const Instruction *pc) { + CallInfo *ci = L->ci; + lu_byte mask = L->hookmask; + const Proto *p = ci_func(ci)->p; + int counthook; + if (!(mask & (LUA_MASKLINE | LUA_MASKCOUNT))) { /* no hooks? */ + ci->u.l.trap = 0; /* don't need to stop again */ + return 0; /* turn off 'trap' */ + } + pc++; /* reference is always next instruction */ + ci->u.l.savedpc = pc; /* save 'pc' */ + counthook = (mask & LUA_MASKCOUNT) && (--L->hookcount == 0); + if (counthook) + resethookcount(L); /* reset count */ + else if (!(mask & LUA_MASKLINE)) + return 1; /* no line hook and count != 0; nothing to be done now */ + if (ci->callstatus & CIST_HOOKYIELD) { /* hook yielded last time? */ + ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ + return 1; /* do not call hook again (VM yielded, so it did not move) */ + } + if (!isIT(*(ci->u.l.savedpc - 1))) /* top not being used? */ + L->top.p = ci->top.p; /* correct top */ + if (counthook) + luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0); /* call count hook */ + if (mask & LUA_MASKLINE) { + /* 'L->oldpc' may be invalid; use zero in this case */ + int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0; + int npci = pcRel(pc, p); + if (npci <= oldpc || /* call hook when jump back (loop), */ + changedline(p, oldpc, npci)) { /* or when enter new line */ + int newline = luaG_getfuncline(p, npci); + luaD_hook(L, LUA_HOOKLINE, newline, 0, 0); /* call line hook */ + } + L->oldpc = npci; /* 'pc' of last call to line hook */ + } + if (L->status == LUA_YIELD) { /* did hook yield? */ + if (counthook) + L->hookcount = 1; /* undo decrement to zero */ + ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ + luaD_throw(L, LUA_YIELD); + } + return 1; /* keep 'trap' on */ +} + diff --git a/User/system/lua/src/ldebug.h b/User/system/lua/src/ldebug.h new file mode 100644 index 0000000..2bfce3c --- /dev/null +++ b/User/system/lua/src/ldebug.h @@ -0,0 +1,64 @@ +/* +** $Id: ldebug.h $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" + + +#define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1) + + +/* Active Lua function (given call info) */ +#define ci_func(ci) (clLvalue(s2v((ci)->func.p))) + + +#define resethookcount(L) (L->hookcount = L->basehookcount) + +/* +** mark for entries in 'lineinfo' array that has absolute information in +** 'abslineinfo' array +*/ +#define ABSLINEINFO (-0x80) + + +/* +** MAXimum number of successive Instructions WiTHout ABSolute line +** information. (A power of two allows fast divisions.) +*/ +#if !defined(MAXIWTHABS) +#define MAXIWTHABS 128 +#endif + + +LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); +LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, + StkId *pos); +LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC l_noret luaG_callerror (lua_State *L, const TValue *o); +LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, + const char *what); +LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, + const TValue *p2, + const char *msg); +LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, + TString *src, int line); +LUAI_FUNC l_noret luaG_errormsg (lua_State *L); +LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); +LUAI_FUNC int luaG_tracecall (lua_State *L); + + +#endif diff --git a/User/system/lua/src/ldo.c b/User/system/lua/src/ldo.c new file mode 100644 index 0000000..ea05295 --- /dev/null +++ b/User/system/lua/src/ldo.c @@ -0,0 +1,1028 @@ +/* +** $Id: ldo.c $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#define ldo_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" +#include "lzio.h" + + + +#define errorstatus(s) ((s) > LUA_YIELD) + + +/* +** {====================================================== +** Error-recovery functions +** ======================================================= +*/ + +/* +** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By +** default, Lua handles errors with exceptions when compiling as +** C++ code, with _longjmp/_setjmp when asked to use them, and with +** longjmp/setjmp otherwise. +*/ +#if !defined(LUAI_THROW) /* { */ + +#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* { */ + +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) \ + try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_POSIX) /* }{ */ + +/* in POSIX, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else /* }{ */ + +/* ISO C handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif /* } */ + +#endif /* } */ + + + +/* chain list of long jump buffers */ +struct lua_longjmp { + struct lua_longjmp *previous; + luai_jmpbuf b; + volatile int status; /* error code */ +}; + + +void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { + switch (errcode) { + case LUA_ERRMEM: { /* memory error? */ + setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ + break; + } + case LUA_ERRERR: { + setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); + break; + } + case LUA_OK: { /* special case only for closing upvalues */ + setnilvalue(s2v(oldtop)); /* no error message */ + break; + } + default: { + lua_assert(errorstatus(errcode)); /* real error */ + setobjs2s(L, oldtop, L->top.p - 1); /* error message on current top */ + break; + } + } + L->top.p = oldtop + 1; +} + + +l_noret luaD_throw (lua_State *L, int errcode) { + if (L->errorJmp) { /* thread has an error handler? */ + L->errorJmp->status = errcode; /* set status */ + LUAI_THROW(L, L->errorJmp); /* jump to it */ + } + else { /* thread has no error handler */ + global_State *g = G(L); + errcode = luaE_resetthread(L, errcode); /* close all upvalues */ + if (g->mainthread->errorJmp) { /* main thread has a handler? */ + setobjs2s(L, g->mainthread->top.p++, L->top.p - 1); /* copy error obj. */ + luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ + } + else { /* no handler at all; abort */ + if (g->panic) { /* panic function? */ + lua_unlock(L); + g->panic(L); /* call panic function (last chance to jump out) */ + } + abort(); + } + } +} + + +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + l_uint32 oldnCcalls = L->nCcalls; + struct lua_longjmp lj; + lj.status = LUA_OK; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + LUAI_TRY(L, &lj, + (*f)(L, ud); + ); + L->errorJmp = lj.previous; /* restore old error handler */ + L->nCcalls = oldnCcalls; + return lj.status; +} + +/* }====================================================== */ + + +/* +** {================================================================== +** Stack reallocation +** =================================================================== +*/ + + +/* +** Change all pointers to the stack into offsets. +*/ +static void relstack (lua_State *L) { + CallInfo *ci; + UpVal *up; + L->top.offset = savestack(L, L->top.p); + L->tbclist.offset = savestack(L, L->tbclist.p); + for (up = L->openupval; up != NULL; up = up->u.open.next) + up->v.offset = savestack(L, uplevel(up)); + for (ci = L->ci; ci != NULL; ci = ci->previous) { + ci->top.offset = savestack(L, ci->top.p); + ci->func.offset = savestack(L, ci->func.p); + } +} + + +/* +** Change back all offsets into pointers. +*/ +static void correctstack (lua_State *L) { + CallInfo *ci; + UpVal *up; + L->top.p = restorestack(L, L->top.offset); + L->tbclist.p = restorestack(L, L->tbclist.offset); + for (up = L->openupval; up != NULL; up = up->u.open.next) + up->v.p = s2v(restorestack(L, up->v.offset)); + for (ci = L->ci; ci != NULL; ci = ci->previous) { + ci->top.p = restorestack(L, ci->top.offset); + ci->func.p = restorestack(L, ci->func.offset); + if (isLua(ci)) + ci->u.l.trap = 1; /* signal to update 'trap' in 'luaV_execute' */ + } +} + + +/* some space for error handling */ +#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) + +/* +** Reallocate the stack to a new size, correcting all pointers into it. +** In ISO C, any pointer use after the pointer has been deallocated is +** undefined behavior. So, before the reallocation, all pointers are +** changed to offsets, and after the reallocation they are changed back +** to pointers. As during the reallocation the pointers are invalid, the +** reallocation cannot run emergency collections. +** +** In case of allocation error, raise an error or return false according +** to 'raiseerror'. +*/ +int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { + int oldsize = stacksize(L); + int i; + StkId newstack; + int oldgcstop = G(L)->gcstopem; + lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); + relstack(L); /* change pointers to offsets */ + G(L)->gcstopem = 1; /* stop emergency collection */ + newstack = luaM_reallocvector(L, L->stack.p, oldsize + EXTRA_STACK, + newsize + EXTRA_STACK, StackValue); + G(L)->gcstopem = oldgcstop; /* restore emergency collection */ + if (l_unlikely(newstack == NULL)) { /* reallocation failed? */ + correctstack(L); /* change offsets back to pointers */ + if (raiseerror) + luaM_error(L); + else return 0; /* do not raise an error */ + } + L->stack.p = newstack; + correctstack(L); /* change offsets back to pointers */ + L->stack_last.p = L->stack.p + newsize; + for (i = oldsize + EXTRA_STACK; i < newsize + EXTRA_STACK; i++) + setnilvalue(s2v(newstack + i)); /* erase new segment */ + return 1; +} + + +/* +** Try to grow the stack by at least 'n' elements. When 'raiseerror' +** is true, raises any error; otherwise, return 0 in case of errors. +*/ +int luaD_growstack (lua_State *L, int n, int raiseerror) { + int size = stacksize(L); + if (l_unlikely(size > LUAI_MAXSTACK)) { + /* if stack is larger than maximum, thread is already using the + extra space reserved for errors, that is, thread is handling + a stack error; cannot grow further than that. */ + lua_assert(stacksize(L) == ERRORSTACKSIZE); + if (raiseerror) + luaD_throw(L, LUA_ERRERR); /* error inside message handler */ + return 0; /* if not 'raiseerror', just signal it */ + } + else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */ + int newsize = 2 * size; /* tentative new size */ + int needed = cast_int(L->top.p - L->stack.p) + n; + if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ + newsize = LUAI_MAXSTACK; + if (newsize < needed) /* but must respect what was asked for */ + newsize = needed; + if (l_likely(newsize <= LUAI_MAXSTACK)) + return luaD_reallocstack(L, newsize, raiseerror); + } + /* else stack overflow */ + /* add extra size to be able to handle the error message */ + luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror); + if (raiseerror) + luaG_runerror(L, "stack overflow"); + return 0; +} + + +/* +** Compute how much of the stack is being used, by computing the +** maximum top of all call frames in the stack and the current top. +*/ +static int stackinuse (lua_State *L) { + CallInfo *ci; + int res; + StkId lim = L->top.p; + for (ci = L->ci; ci != NULL; ci = ci->previous) { + if (lim < ci->top.p) lim = ci->top.p; + } + lua_assert(lim <= L->stack_last.p + EXTRA_STACK); + res = cast_int(lim - L->stack.p) + 1; /* part of stack in use */ + if (res < LUA_MINSTACK) + res = LUA_MINSTACK; /* ensure a minimum size */ + return res; +} + + +/* +** If stack size is more than 3 times the current use, reduce that size +** to twice the current use. (So, the final stack size is at most 2/3 the +** previous size, and half of its entries are empty.) +** As a particular case, if stack was handling a stack overflow and now +** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than +** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack +** will be reduced to a "regular" size. +*/ +void luaD_shrinkstack (lua_State *L) { + int inuse = stackinuse(L); + int max = (inuse > LUAI_MAXSTACK / 3) ? LUAI_MAXSTACK : inuse * 3; + /* if thread is currently not handling a stack overflow and its + size is larger than maximum "reasonable" size, shrink it */ + if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) { + int nsize = (inuse > LUAI_MAXSTACK / 2) ? LUAI_MAXSTACK : inuse * 2; + luaD_reallocstack(L, nsize, 0); /* ok if that fails */ + } + else /* don't change stack */ + condmovestack(L,{},{}); /* (change only for debugging) */ + luaE_shrinkCI(L); /* shrink CI list */ +} + + +void luaD_inctop (lua_State *L) { + luaD_checkstack(L, 1); + L->top.p++; +} + +/* }================================================================== */ + + +/* +** Call a hook for the given event. Make sure there is a hook to be +** called. (Both 'L->hook' and 'L->hookmask', which trigger this +** function, can be changed asynchronously by signals.) +*/ +void luaD_hook (lua_State *L, int event, int line, + int ftransfer, int ntransfer) { + lua_Hook hook = L->hook; + if (hook && L->allowhook) { /* make sure there is a hook */ + int mask = CIST_HOOKED; + CallInfo *ci = L->ci; + ptrdiff_t top = savestack(L, L->top.p); /* preserve original 'top' */ + ptrdiff_t ci_top = savestack(L, ci->top.p); /* idem for 'ci->top' */ + lua_Debug ar; + ar.event = event; + ar.currentline = line; + ar.i_ci = ci; + if (ntransfer != 0) { + mask |= CIST_TRAN; /* 'ci' has transfer information */ + ci->u2.transferinfo.ftransfer = ftransfer; + ci->u2.transferinfo.ntransfer = ntransfer; + } + if (isLua(ci) && L->top.p < ci->top.p) + L->top.p = ci->top.p; /* protect entire activation register */ + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + if (ci->top.p < L->top.p + LUA_MINSTACK) + ci->top.p = L->top.p + LUA_MINSTACK; + L->allowhook = 0; /* cannot call hooks inside a hook */ + ci->callstatus |= mask; + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + ci->top.p = restorestack(L, ci_top); + L->top.p = restorestack(L, top); + ci->callstatus &= ~mask; + } +} + + +/* +** Executes a call hook for Lua functions. This function is called +** whenever 'hookmask' is not zero, so it checks whether call hooks are +** active. +*/ +void luaD_hookcall (lua_State *L, CallInfo *ci) { + L->oldpc = 0; /* set 'oldpc' for new function */ + if (L->hookmask & LUA_MASKCALL) { /* is call hook on? */ + int event = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL + : LUA_HOOKCALL; + Proto *p = ci_func(ci)->p; + ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ + luaD_hook(L, event, -1, 1, p->numparams); + ci->u.l.savedpc--; /* correct 'pc' */ + } +} + + +/* +** Executes a return hook for Lua and C functions and sets/corrects +** 'oldpc'. (Note that this correction is needed by the line hook, so it +** is done even when return hooks are off.) +*/ +static void rethook (lua_State *L, CallInfo *ci, int nres) { + if (L->hookmask & LUA_MASKRET) { /* is return hook on? */ + StkId firstres = L->top.p - nres; /* index of first result */ + int delta = 0; /* correction for vararg functions */ + int ftransfer; + if (isLua(ci)) { + Proto *p = ci_func(ci)->p; + if (p->is_vararg) + delta = ci->u.l.nextraargs + p->numparams + 1; + } + ci->func.p += delta; /* if vararg, back to virtual 'func' */ + ftransfer = cast(unsigned short, firstres - ci->func.p); + luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */ + ci->func.p -= delta; + } + if (isLua(ci = ci->previous)) + L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* set 'oldpc' */ +} + + +/* +** Check whether 'func' has a '__call' metafield. If so, put it in the +** stack, below original 'func', so that 'luaD_precall' can call it. Raise +** an error if there is no '__call' metafield. +*/ +static StkId tryfuncTM (lua_State *L, StkId func) { + const TValue *tm; + StkId p; + checkstackGCp(L, 1, func); /* space for metamethod */ + tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); /* (after previous GC) */ + if (l_unlikely(ttisnil(tm))) + luaG_callerror(L, s2v(func)); /* nothing to call */ + for (p = L->top.p; p > func; p--) /* open space for metamethod */ + setobjs2s(L, p, p-1); + L->top.p++; /* stack space pre-allocated by the caller */ + setobj2s(L, func, tm); /* metamethod is the new function to be called */ + return func; +} + + +/* +** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'. +** Handle most typical cases (zero results for commands, one result for +** expressions, multiple results for tail calls/single parameters) +** separated. +*/ +l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) { + StkId firstresult; + int i; + switch (wanted) { /* handle typical cases separately */ + case 0: /* no values needed */ + L->top.p = res; + return; + case 1: /* one value needed */ + if (nres == 0) /* no results? */ + setnilvalue(s2v(res)); /* adjust with nil */ + else /* at least one result */ + setobjs2s(L, res, L->top.p - nres); /* move it to proper place */ + L->top.p = res + 1; + return; + case LUA_MULTRET: + wanted = nres; /* we want all results */ + break; + default: /* two/more results and/or to-be-closed variables */ + if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */ + L->ci->callstatus |= CIST_CLSRET; /* in case of yields */ + L->ci->u2.nres = nres; + res = luaF_close(L, res, CLOSEKTOP, 1); + L->ci->callstatus &= ~CIST_CLSRET; + if (L->hookmask) { /* if needed, call hook after '__close's */ + ptrdiff_t savedres = savestack(L, res); + rethook(L, L->ci, nres); + res = restorestack(L, savedres); /* hook can move stack */ + } + wanted = decodeNresults(wanted); + if (wanted == LUA_MULTRET) + wanted = nres; /* we want all results */ + } + break; + } + /* generic case */ + firstresult = L->top.p - nres; /* index of first result */ + if (nres > wanted) /* extra results? */ + nres = wanted; /* don't need them */ + for (i = 0; i < nres; i++) /* move all results to correct place */ + setobjs2s(L, res + i, firstresult + i); + for (; i < wanted; i++) /* complete wanted number of results */ + setnilvalue(s2v(res + i)); + L->top.p = res + wanted; /* top points after the last result */ +} + + +/* +** Finishes a function call: calls hook if necessary, moves current +** number of results to proper place, and returns to previous call +** info. If function has to close variables, hook must be called after +** that. +*/ +void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { + int wanted = ci->nresults; + if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted))) + rethook(L, ci, nres); + /* move results to proper place */ + moveresults(L, ci->func.p, nres, wanted); + /* function cannot be in any of these cases when returning */ + lua_assert(!(ci->callstatus & + (CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET))); + L->ci = ci->previous; /* back to caller (after closing variables) */ +} + + + +#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) + + +l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret, + int mask, StkId top) { + CallInfo *ci = L->ci = next_ci(L); /* new frame */ + ci->func.p = func; + ci->nresults = nret; + ci->callstatus = mask; + ci->top.p = top; + return ci; +} + + +/* +** precall for C functions +*/ +l_sinline int precallC (lua_State *L, StkId func, int nresults, + lua_CFunction f) { + int n; /* number of returns */ + CallInfo *ci; + checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ + L->ci = ci = prepCallInfo(L, func, nresults, CIST_C, + L->top.p + LUA_MINSTACK); + lua_assert(ci->top.p <= L->stack_last.p); + if (l_unlikely(L->hookmask & LUA_MASKCALL)) { + int narg = cast_int(L->top.p - func) - 1; + luaD_hook(L, LUA_HOOKCALL, -1, 1, narg); + } + lua_unlock(L); + n = (*f)(L); /* do the actual call */ + lua_lock(L); + api_checknelems(L, n); + luaD_poscall(L, ci, n); + return n; +} + + +/* +** Prepare a function for a tail call, building its call info on top +** of the current call info. 'narg1' is the number of arguments plus 1 +** (so that it includes the function itself). Return the number of +** results, if it was a C function, or -1 for a Lua function. +*/ +int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, + int narg1, int delta) { + retry: + switch (ttypetag(s2v(func))) { + case LUA_VCCL: /* C closure */ + return precallC(L, func, LUA_MULTRET, clCvalue(s2v(func))->f); + case LUA_VLCF: /* light C function */ + return precallC(L, func, LUA_MULTRET, fvalue(s2v(func))); + case LUA_VLCL: { /* Lua function */ + Proto *p = clLvalue(s2v(func))->p; + int fsize = p->maxstacksize; /* frame size */ + int nfixparams = p->numparams; + int i; + checkstackGCp(L, fsize - delta, func); + ci->func.p -= delta; /* restore 'func' (if vararg) */ + for (i = 0; i < narg1; i++) /* move down function and arguments */ + setobjs2s(L, ci->func.p + i, func + i); + func = ci->func.p; /* moved-down function */ + for (; narg1 <= nfixparams; narg1++) + setnilvalue(s2v(func + narg1)); /* complete missing arguments */ + ci->top.p = func + 1 + fsize; /* top for new function */ + lua_assert(ci->top.p <= L->stack_last.p); + ci->u.l.savedpc = p->code; /* starting point */ + ci->callstatus |= CIST_TAIL; + L->top.p = func + narg1; /* set top */ + return -1; + } + default: { /* not a function */ + func = tryfuncTM(L, func); /* try to get '__call' metamethod */ + /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */ + narg1++; + goto retry; /* try again */ + } + } +} + + +/* +** Prepares the call to a function (C or Lua). For C functions, also do +** the call. The function to be called is at '*func'. The arguments +** are on the stack, right after the function. Returns the CallInfo +** to be executed, if it was a Lua function. Otherwise (a C function) +** returns NULL, with all the results on the stack, starting at the +** original function position. +*/ +CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { + retry: + switch (ttypetag(s2v(func))) { + case LUA_VCCL: /* C closure */ + precallC(L, func, nresults, clCvalue(s2v(func))->f); + return NULL; + case LUA_VLCF: /* light C function */ + precallC(L, func, nresults, fvalue(s2v(func))); + return NULL; + case LUA_VLCL: { /* Lua function */ + CallInfo *ci; + Proto *p = clLvalue(s2v(func))->p; + int narg = cast_int(L->top.p - func) - 1; /* number of real arguments */ + int nfixparams = p->numparams; + int fsize = p->maxstacksize; /* frame size */ + checkstackGCp(L, fsize, func); + L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize); + ci->u.l.savedpc = p->code; /* starting point */ + for (; narg < nfixparams; narg++) + setnilvalue(s2v(L->top.p++)); /* complete missing arguments */ + lua_assert(ci->top.p <= L->stack_last.p); + return ci; + } + default: { /* not a function */ + func = tryfuncTM(L, func); /* try to get '__call' metamethod */ + /* return luaD_precall(L, func, nresults); */ + goto retry; /* try again with metamethod */ + } + } +} + + +/* +** Call a function (C or Lua) through C. 'inc' can be 1 (increment +** number of recursive invocations in the C stack) or nyci (the same +** plus increment number of non-yieldable calls). +** This function can be called with some use of EXTRA_STACK, so it should +** check the stack before doing anything else. 'luaD_precall' already +** does that. +*/ +l_sinline void ccall (lua_State *L, StkId func, int nResults, l_uint32 inc) { + CallInfo *ci; + L->nCcalls += inc; + if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) { + checkstackp(L, 0, func); /* free any use of EXTRA_STACK */ + luaE_checkcstack(L); + } + if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */ + ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */ + luaV_execute(L, ci); /* call it */ + } + L->nCcalls -= inc; +} + + +/* +** External interface for 'ccall' +*/ +void luaD_call (lua_State *L, StkId func, int nResults) { + ccall(L, func, nResults, 1); +} + + +/* +** Similar to 'luaD_call', but does not allow yields during the call. +*/ +void luaD_callnoyield (lua_State *L, StkId func, int nResults) { + ccall(L, func, nResults, nyci); +} + + +/* +** Finish the job of 'lua_pcallk' after it was interrupted by an yield. +** (The caller, 'finishCcall', does the final call to 'adjustresults'.) +** The main job is to complete the 'luaD_pcall' called by 'lua_pcallk'. +** If a '__close' method yields here, eventually control will be back +** to 'finishCcall' (when that '__close' method finally returns) and +** 'finishpcallk' will run again and close any still pending '__close' +** methods. Similarly, if a '__close' method errs, 'precover' calls +** 'unroll' which calls ''finishCcall' and we are back here again, to +** close any pending '__close' methods. +** Note that, up to the call to 'luaF_close', the corresponding +** 'CallInfo' is not modified, so that this repeated run works like the +** first one (except that it has at least one less '__close' to do). In +** particular, field CIST_RECST preserves the error status across these +** multiple runs, changing only if there is a new error. +*/ +static int finishpcallk (lua_State *L, CallInfo *ci) { + int status = getcistrecst(ci); /* get original status */ + if (l_likely(status == LUA_OK)) /* no error? */ + status = LUA_YIELD; /* was interrupted by an yield */ + else { /* error */ + StkId func = restorestack(L, ci->u2.funcidx); + L->allowhook = getoah(ci->callstatus); /* restore 'allowhook' */ + func = luaF_close(L, func, status, 1); /* can yield or raise an error */ + luaD_seterrorobj(L, status, func); + luaD_shrinkstack(L); /* restore stack size in case of overflow */ + setcistrecst(ci, LUA_OK); /* clear original status */ + } + ci->callstatus &= ~CIST_YPCALL; + L->errfunc = ci->u.c.old_errfunc; + /* if it is here, there were errors or yields; unlike 'lua_pcallk', + do not change status */ + return status; +} + + +/* +** Completes the execution of a C function interrupted by an yield. +** The interruption must have happened while the function was either +** closing its tbc variables in 'moveresults' or executing +** 'lua_callk'/'lua_pcallk'. In the first case, it just redoes +** 'luaD_poscall'. In the second case, the call to 'finishpcallk' +** finishes the interrupted execution of 'lua_pcallk'. After that, it +** calls the continuation of the interrupted function and finally it +** completes the job of the 'luaD_call' that called the function. In +** the call to 'adjustresults', we do not know the number of results +** of the function called by 'lua_callk'/'lua_pcallk', so we are +** conservative and use LUA_MULTRET (always adjust). +*/ +static void finishCcall (lua_State *L, CallInfo *ci) { + int n; /* actual number of results from C function */ + if (ci->callstatus & CIST_CLSRET) { /* was returning? */ + lua_assert(hastocloseCfunc(ci->nresults)); + n = ci->u2.nres; /* just redo 'luaD_poscall' */ + /* don't need to reset CIST_CLSRET, as it will be set again anyway */ + } + else { + int status = LUA_YIELD; /* default if there were no errors */ + /* must have a continuation and must be able to call it */ + lua_assert(ci->u.c.k != NULL && yieldable(L)); + if (ci->callstatus & CIST_YPCALL) /* was inside a 'lua_pcallk'? */ + status = finishpcallk(L, ci); /* finish it */ + adjustresults(L, LUA_MULTRET); /* finish 'lua_callk' */ + lua_unlock(L); + n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation */ + lua_lock(L); + api_checknelems(L, n); + } + luaD_poscall(L, ci, n); /* finish 'luaD_call' */ +} + + +/* +** Executes "full continuation" (everything in the stack) of a +** previously interrupted coroutine until the stack is empty (or another +** interruption long-jumps out of the loop). +*/ +static void unroll (lua_State *L, void *ud) { + CallInfo *ci; + UNUSED(ud); + while ((ci = L->ci) != &L->base_ci) { /* something in the stack */ + if (!isLua(ci)) /* C function? */ + finishCcall(L, ci); /* complete its execution */ + else { /* Lua function */ + luaV_finishOp(L); /* finish interrupted instruction */ + luaV_execute(L, ci); /* execute down to higher C 'boundary' */ + } + } +} + + +/* +** Try to find a suspended protected call (a "recover point") for the +** given thread. +*/ +static CallInfo *findpcall (lua_State *L) { + CallInfo *ci; + for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ + if (ci->callstatus & CIST_YPCALL) + return ci; + } + return NULL; /* no pending pcall */ +} + + +/* +** Signal an error in the call to 'lua_resume', not in the execution +** of the coroutine itself. (Such errors should not be handled by any +** coroutine error handler and should not kill the coroutine.) +*/ +static int resume_error (lua_State *L, const char *msg, int narg) { + L->top.p -= narg; /* remove args from the stack */ + setsvalue2s(L, L->top.p, luaS_new(L, msg)); /* push error message */ + api_incr_top(L); + lua_unlock(L); + return LUA_ERRRUN; +} + + +/* +** Do the work for 'lua_resume' in protected mode. Most of the work +** depends on the status of the coroutine: initial state, suspended +** inside a hook, or regularly suspended (optionally with a continuation +** function), plus erroneous cases: non-suspended coroutine or dead +** coroutine. +*/ +static void resume (lua_State *L, void *ud) { + int n = *(cast(int*, ud)); /* number of arguments */ + StkId firstArg = L->top.p - n; /* first argument */ + CallInfo *ci = L->ci; + if (L->status == LUA_OK) /* starting a coroutine? */ + ccall(L, firstArg - 1, LUA_MULTRET, 0); /* just call its body */ + else { /* resuming from previous yield */ + lua_assert(L->status == LUA_YIELD); + L->status = LUA_OK; /* mark that it is running (again) */ + if (isLua(ci)) { /* yielded inside a hook? */ + /* undo increment made by 'luaG_traceexec': instruction was not + executed yet */ + lua_assert(ci->callstatus & CIST_HOOKYIELD); + ci->u.l.savedpc--; + L->top.p = firstArg; /* discard arguments */ + luaV_execute(L, ci); /* just continue running Lua code */ + } + else { /* 'common' yield */ + if (ci->u.c.k != NULL) { /* does it have a continuation function? */ + lua_unlock(L); + n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ + lua_lock(L); + api_checknelems(L, n); + } + luaD_poscall(L, ci, n); /* finish 'luaD_call' */ + } + unroll(L, NULL); /* run continuation */ + } +} + + +/* +** Unrolls a coroutine in protected mode while there are recoverable +** errors, that is, errors inside a protected call. (Any error +** interrupts 'unroll', and this loop protects it again so it can +** continue.) Stops with a normal end (status == LUA_OK), an yield +** (status == LUA_YIELD), or an unprotected error ('findpcall' doesn't +** find a recover point). +*/ +static int precover (lua_State *L, int status) { + CallInfo *ci; + while (errorstatus(status) && (ci = findpcall(L)) != NULL) { + L->ci = ci; /* go down to recovery functions */ + setcistrecst(ci, status); /* status to finish 'pcall' */ + status = luaD_rawrunprotected(L, unroll, NULL); + } + return status; +} + + +LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, + int *nresults) { + int status; + lua_lock(L); + if (L->status == LUA_OK) { /* may be starting a coroutine */ + if (L->ci != &L->base_ci) /* not in base level? */ + return resume_error(L, "cannot resume non-suspended coroutine", nargs); + else if (L->top.p - (L->ci->func.p + 1) == nargs) /* no function? */ + return resume_error(L, "cannot resume dead coroutine", nargs); + } + else if (L->status != LUA_YIELD) /* ended with errors? */ + return resume_error(L, "cannot resume dead coroutine", nargs); + L->nCcalls = (from) ? getCcalls(from) : 0; + if (getCcalls(L) >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow", nargs); + L->nCcalls++; + luai_userstateresume(L, nargs); + api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); + status = luaD_rawrunprotected(L, resume, &nargs); + /* continue running after recoverable errors */ + status = precover(L, status); + if (l_likely(!errorstatus(status))) + lua_assert(status == L->status); /* normal end or yield */ + else { /* unrecoverable error */ + L->status = cast_byte(status); /* mark thread as 'dead' */ + luaD_seterrorobj(L, status, L->top.p); /* push error message */ + L->ci->top.p = L->top.p; + } + *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield + : cast_int(L->top.p - (L->ci->func.p + 1)); + lua_unlock(L); + return status; +} + + +LUA_API int lua_isyieldable (lua_State *L) { + return yieldable(L); +} + + +LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, + lua_KFunction k) { + CallInfo *ci; + luai_userstateyield(L, nresults); + lua_lock(L); + ci = L->ci; + api_checknelems(L, nresults); + if (l_unlikely(!yieldable(L))) { + if (L != G(L)->mainthread) + luaG_runerror(L, "attempt to yield across a C-call boundary"); + else + luaG_runerror(L, "attempt to yield from outside a coroutine"); + } + L->status = LUA_YIELD; + ci->u2.nyield = nresults; /* save number of results */ + if (isLua(ci)) { /* inside a hook? */ + lua_assert(!isLuacode(ci)); + api_check(L, nresults == 0, "hooks cannot yield values"); + api_check(L, k == NULL, "hooks cannot continue after yielding"); + } + else { + if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ + ci->u.c.ctx = ctx; /* save context */ + luaD_throw(L, LUA_YIELD); + } + lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ + lua_unlock(L); + return 0; /* return to 'luaD_hook' */ +} + + +/* +** Auxiliary structure to call 'luaF_close' in protected mode. +*/ +struct CloseP { + StkId level; + int status; +}; + + +/* +** Auxiliary function to call 'luaF_close' in protected mode. +*/ +static void closepaux (lua_State *L, void *ud) { + struct CloseP *pcl = cast(struct CloseP *, ud); + luaF_close(L, pcl->level, pcl->status, 0); +} + + +/* +** Calls 'luaF_close' in protected mode. Return the original status +** or, in case of errors, the new status. +*/ +int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status) { + CallInfo *old_ci = L->ci; + lu_byte old_allowhooks = L->allowhook; + for (;;) { /* keep closing upvalues until no more errors */ + struct CloseP pcl; + pcl.level = restorestack(L, level); pcl.status = status; + status = luaD_rawrunprotected(L, &closepaux, &pcl); + if (l_likely(status == LUA_OK)) /* no more errors? */ + return pcl.status; + else { /* an error occurred; restore saved state and repeat */ + L->ci = old_ci; + L->allowhook = old_allowhooks; + } + } +} + + +/* +** Call the C function 'func' in protected mode, restoring basic +** thread information ('allowhook', etc.) and in particular +** its stack level in case of errors. +*/ +int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t old_top, ptrdiff_t ef) { + int status; + CallInfo *old_ci = L->ci; + lu_byte old_allowhooks = L->allowhook; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (l_unlikely(status != LUA_OK)) { /* an error occurred? */ + L->ci = old_ci; + L->allowhook = old_allowhooks; + status = luaD_closeprotected(L, old_top, status); + luaD_seterrorobj(L, status, restorestack(L, old_top)); + luaD_shrinkstack(L); /* restore stack size in case of overflow */ + } + L->errfunc = old_errfunc; + return status; +} + + + +/* +** Execute a protected parser. +*/ +struct SParser { /* data to 'f_parser' */ + ZIO *z; + Mbuffer buff; /* dynamic structure used by the scanner */ + Dyndata dyd; /* dynamic structures used by the parser */ + const char *mode; + const char *name; +}; + + +static void checkmode (lua_State *L, const char *mode, const char *x) { + if (mode && strchr(mode, x[0]) == NULL) { + luaO_pushfstring(L, + "attempt to load a %s chunk (mode is '%s')", x, mode); + luaD_throw(L, LUA_ERRSYNTAX); + } +} + + +static void f_parser (lua_State *L, void *ud) { + LClosure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = zgetc(p->z); /* read first character */ + if (c == LUA_SIGNATURE[0]) { + checkmode(L, p->mode, "binary"); + cl = luaU_undump(L, p->z, p->name); + } + else { + checkmode(L, p->mode, "text"); + cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); + } + lua_assert(cl->nupvalues == cl->p->sizeupvalues); + luaF_initupvals(L, cl); +} + + +int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode) { + struct SParser p; + int status; + incnny(L); /* cannot yield during parsing */ + p.z = z; p.name = name; p.mode = mode; + p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; + p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; + p.dyd.label.arr = NULL; p.dyd.label.size = 0; + luaZ_initbuffer(L, &p.buff); + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top.p), L->errfunc); + luaZ_freebuffer(L, &p.buff); + luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); + luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); + luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); + decnny(L); + return status; +} + + diff --git a/User/system/lua/src/ldo.h b/User/system/lua/src/ldo.h new file mode 100644 index 0000000..56008ab --- /dev/null +++ b/User/system/lua/src/ldo.h @@ -0,0 +1,87 @@ +/* +** $Id: ldo.h $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "llimits.h" +#include "lobject.h" +#include "lstate.h" +#include "lzio.h" + + +/* +** Macro to check stack size and grow stack if needed. Parameters +** 'pre'/'pos' allow the macro to preserve a pointer into the +** stack across reallocations, doing the work only when needed. +** It also allows the running of one GC step when the stack is +** reallocated. +** 'condmovestack' is used in heavy tests to force a stack reallocation +** at every check. +*/ +#define luaD_checkstackaux(L,n,pre,pos) \ + if (l_unlikely(L->stack_last.p - L->top.p <= (n))) \ + { pre; luaD_growstack(L, n, 1); pos; } \ + else { condmovestack(L,pre,pos); } + +/* In general, 'pre'/'pos' are empty (nothing to save) */ +#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) + + + +#define savestack(L,pt) (cast_charp(pt) - cast_charp(L->stack.p)) +#define restorestack(L,n) cast(StkId, cast_charp(L->stack.p) + (n)) + + +/* macro to check stack size, preserving 'p' */ +#define checkstackp(L,n,p) \ + luaD_checkstackaux(L, n, \ + ptrdiff_t t__ = savestack(L, p), /* save 'p' */ \ + p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ + + +/* macro to check stack size and GC, preserving 'p' */ +#define checkstackGCp(L,n,p) \ + luaD_checkstackaux(L, n, \ + ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ + luaC_checkGC(L), /* stack grow uses memory */ \ + p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ + + +/* macro to check stack size and GC */ +#define checkstackGC(L,fsize) \ + luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0) + + +/* type of protected functions, to be ran by 'runprotected' */ +typedef void (*Pfunc) (lua_State *L, void *ud); + +LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode); +LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, + int fTransfer, int nTransfer); +LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); +LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, + int narg1, int delta); +LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); +LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); +LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); +LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, int nres); +LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); +LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); +LUAI_FUNC void luaD_shrinkstack (lua_State *L); +LUAI_FUNC void luaD_inctop (lua_State *L); + +LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); + +#endif + diff --git a/User/system/lua/src/ldump.c b/User/system/lua/src/ldump.c new file mode 100644 index 0000000..f231691 --- /dev/null +++ b/User/system/lua/src/ldump.c @@ -0,0 +1,230 @@ +/* +** $Id: ldump.c $ +** save precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#define ldump_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lundump.h" + + +typedef struct { + lua_State *L; + lua_Writer writer; + void *data; + int strip; + int status; +} DumpState; + + +/* +** All high-level dumps go through dumpVector; you can change it to +** change the endianness of the result +*/ +#define dumpVector(D,v,n) dumpBlock(D,v,(n)*sizeof((v)[0])) + +#define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char)) + + +static void dumpBlock (DumpState *D, const void *b, size_t size) { + if (D->status == 0 && size > 0) { + lua_unlock(D->L); + D->status = (*D->writer)(D->L, b, size, D->data); + lua_lock(D->L); + } +} + + +#define dumpVar(D,x) dumpVector(D,&x,1) + + +static void dumpByte (DumpState *D, int y) { + lu_byte x = (lu_byte)y; + dumpVar(D, x); +} + + +/* +** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6" +** rounds up the division.) +*/ +#define DIBS ((sizeof(size_t) * CHAR_BIT + 6) / 7) + +static void dumpSize (DumpState *D, size_t x) { + lu_byte buff[DIBS]; + int n = 0; + do { + buff[DIBS - (++n)] = x & 0x7f; /* fill buffer in reverse order */ + x >>= 7; + } while (x != 0); + buff[DIBS - 1] |= 0x80; /* mark last byte */ + dumpVector(D, buff + DIBS - n, n); +} + + +static void dumpInt (DumpState *D, int x) { + dumpSize(D, x); +} + + +static void dumpNumber (DumpState *D, lua_Number x) { + dumpVar(D, x); +} + + +static void dumpInteger (DumpState *D, lua_Integer x) { + dumpVar(D, x); +} + + +static void dumpString (DumpState *D, const TString *s) { + if (s == NULL) + dumpSize(D, 0); + else { + size_t size = tsslen(s); + const char *str = getstr(s); + dumpSize(D, size + 1); + dumpVector(D, str, size); + } +} + + +static void dumpCode (DumpState *D, const Proto *f) { + dumpInt(D, f->sizecode); + dumpVector(D, f->code, f->sizecode); +} + + +static void dumpFunction(DumpState *D, const Proto *f, TString *psource); + +static void dumpConstants (DumpState *D, const Proto *f) { + int i; + int n = f->sizek; + dumpInt(D, n); + for (i = 0; i < n; i++) { + const TValue *o = &f->k[i]; + int tt = ttypetag(o); + dumpByte(D, tt); + switch (tt) { + case LUA_VNUMFLT: + dumpNumber(D, fltvalue(o)); + break; + case LUA_VNUMINT: + dumpInteger(D, ivalue(o)); + break; + case LUA_VSHRSTR: + case LUA_VLNGSTR: + dumpString(D, tsvalue(o)); + break; + default: + lua_assert(tt == LUA_VNIL || tt == LUA_VFALSE || tt == LUA_VTRUE); + } + } +} + + +static void dumpProtos (DumpState *D, const Proto *f) { + int i; + int n = f->sizep; + dumpInt(D, n); + for (i = 0; i < n; i++) + dumpFunction(D, f->p[i], f->source); +} + + +static void dumpUpvalues (DumpState *D, const Proto *f) { + int i, n = f->sizeupvalues; + dumpInt(D, n); + for (i = 0; i < n; i++) { + dumpByte(D, f->upvalues[i].instack); + dumpByte(D, f->upvalues[i].idx); + dumpByte(D, f->upvalues[i].kind); + } +} + + +static void dumpDebug (DumpState *D, const Proto *f) { + int i, n; + n = (D->strip) ? 0 : f->sizelineinfo; + dumpInt(D, n); + dumpVector(D, f->lineinfo, n); + n = (D->strip) ? 0 : f->sizeabslineinfo; + dumpInt(D, n); + for (i = 0; i < n; i++) { + dumpInt(D, f->abslineinfo[i].pc); + dumpInt(D, f->abslineinfo[i].line); + } + n = (D->strip) ? 0 : f->sizelocvars; + dumpInt(D, n); + for (i = 0; i < n; i++) { + dumpString(D, f->locvars[i].varname); + dumpInt(D, f->locvars[i].startpc); + dumpInt(D, f->locvars[i].endpc); + } + n = (D->strip) ? 0 : f->sizeupvalues; + dumpInt(D, n); + for (i = 0; i < n; i++) + dumpString(D, f->upvalues[i].name); +} + + +static void dumpFunction (DumpState *D, const Proto *f, TString *psource) { + if (D->strip || f->source == psource) + dumpString(D, NULL); /* no debug info or same source as its parent */ + else + dumpString(D, f->source); + dumpInt(D, f->linedefined); + dumpInt(D, f->lastlinedefined); + dumpByte(D, f->numparams); + dumpByte(D, f->is_vararg); + dumpByte(D, f->maxstacksize); + dumpCode(D, f); + dumpConstants(D, f); + dumpUpvalues(D, f); + dumpProtos(D, f); + dumpDebug(D, f); +} + + +static void dumpHeader (DumpState *D) { + dumpLiteral(D, LUA_SIGNATURE); + dumpByte(D, LUAC_VERSION); + dumpByte(D, LUAC_FORMAT); + dumpLiteral(D, LUAC_DATA); + dumpByte(D, sizeof(Instruction)); + dumpByte(D, sizeof(lua_Integer)); + dumpByte(D, sizeof(lua_Number)); + dumpInteger(D, LUAC_INT); + dumpNumber(D, LUAC_NUM); +} + + +/* +** dump Lua function as precompiled chunk +*/ +int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, + int strip) { + DumpState D; + D.L = L; + D.writer = w; + D.data = data; + D.strip = strip; + D.status = 0; + dumpHeader(&D); + dumpByte(&D, f->sizeupvalues); + dumpFunction(&D, f, NULL); + return D.status; +} + diff --git a/User/system/lua/src/lfunc.c b/User/system/lua/src/lfunc.c new file mode 100644 index 0000000..0945f24 --- /dev/null +++ b/User/system/lua/src/lfunc.c @@ -0,0 +1,294 @@ +/* +** $Id: lfunc.c $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#define lfunc_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +CClosure *luaF_newCclosure (lua_State *L, int nupvals) { + GCObject *o = luaC_newobj(L, LUA_VCCL, sizeCclosure(nupvals)); + CClosure *c = gco2ccl(o); + c->nupvalues = cast_byte(nupvals); + return c; +} + + +LClosure *luaF_newLclosure (lua_State *L, int nupvals) { + GCObject *o = luaC_newobj(L, LUA_VLCL, sizeLclosure(nupvals)); + LClosure *c = gco2lcl(o); + c->p = NULL; + c->nupvalues = cast_byte(nupvals); + while (nupvals--) c->upvals[nupvals] = NULL; + return c; +} + + +/* +** fill a closure with new closed upvalues +*/ +void luaF_initupvals (lua_State *L, LClosure *cl) { + int i; + for (i = 0; i < cl->nupvalues; i++) { + GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal)); + UpVal *uv = gco2upv(o); + uv->v.p = &uv->u.value; /* make it closed */ + setnilvalue(uv->v.p); + cl->upvals[i] = uv; + luaC_objbarrier(L, cl, uv); + } +} + + +/* +** Create a new upvalue at the given level, and link it to the list of +** open upvalues of 'L' after entry 'prev'. +**/ +static UpVal *newupval (lua_State *L, StkId level, UpVal **prev) { + GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal)); + UpVal *uv = gco2upv(o); + UpVal *next = *prev; + uv->v.p = s2v(level); /* current value lives in the stack */ + uv->u.open.next = next; /* link it to list of open upvalues */ + uv->u.open.previous = prev; + if (next) + next->u.open.previous = &uv->u.open.next; + *prev = uv; + if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ + L->twups = G(L)->twups; /* link it to the list */ + G(L)->twups = L; + } + return uv; +} + + +/* +** Find and reuse, or create if it does not exist, an upvalue +** at the given level. +*/ +UpVal *luaF_findupval (lua_State *L, StkId level) { + UpVal **pp = &L->openupval; + UpVal *p; + lua_assert(isintwups(L) || L->openupval == NULL); + while ((p = *pp) != NULL && uplevel(p) >= level) { /* search for it */ + lua_assert(!isdead(G(L), p)); + if (uplevel(p) == level) /* corresponding upvalue? */ + return p; /* return it */ + pp = &p->u.open.next; + } + /* not found: create a new upvalue after 'pp' */ + return newupval(L, level, pp); +} + + +/* +** Call closing method for object 'obj' with error message 'err'. The +** boolean 'yy' controls whether the call is yieldable. +** (This function assumes EXTRA_STACK.) +*/ +static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) { + StkId top = L->top.p; + const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE); + setobj2s(L, top, tm); /* will call metamethod... */ + setobj2s(L, top + 1, obj); /* with 'self' as the 1st argument */ + setobj2s(L, top + 2, err); /* and error msg. as 2nd argument */ + L->top.p = top + 3; /* add function and arguments */ + if (yy) + luaD_call(L, top, 0); + else + luaD_callnoyield(L, top, 0); +} + + +/* +** Check whether object at given level has a close metamethod and raise +** an error if not. +*/ +static void checkclosemth (lua_State *L, StkId level) { + const TValue *tm = luaT_gettmbyobj(L, s2v(level), TM_CLOSE); + if (ttisnil(tm)) { /* no metamethod? */ + int idx = cast_int(level - L->ci->func.p); /* variable index */ + const char *vname = luaG_findlocal(L, L->ci, idx, NULL); + if (vname == NULL) vname = "?"; + luaG_runerror(L, "variable '%s' got a non-closable value", vname); + } +} + + +/* +** Prepare and call a closing method. +** If status is CLOSEKTOP, the call to the closing method will be pushed +** at the top of the stack. Otherwise, values can be pushed right after +** the 'level' of the upvalue being closed, as everything after that +** won't be used again. +*/ +static void prepcallclosemth (lua_State *L, StkId level, int status, int yy) { + TValue *uv = s2v(level); /* value being closed */ + TValue *errobj; + if (status == CLOSEKTOP) + errobj = &G(L)->nilvalue; /* error object is nil */ + else { /* 'luaD_seterrorobj' will set top to level + 2 */ + errobj = s2v(level + 1); /* error object goes after 'uv' */ + luaD_seterrorobj(L, status, level + 1); /* set error object */ + } + callclosemethod(L, uv, errobj, yy); +} + + +/* +** Maximum value for deltas in 'tbclist', dependent on the type +** of delta. (This macro assumes that an 'L' is in scope where it +** is used.) +*/ +#define MAXDELTA \ + ((256ul << ((sizeof(L->stack.p->tbclist.delta) - 1) * 8)) - 1) + + +/* +** Insert a variable in the list of to-be-closed variables. +*/ +void luaF_newtbcupval (lua_State *L, StkId level) { + lua_assert(level > L->tbclist.p); + if (l_isfalse(s2v(level))) + return; /* false doesn't need to be closed */ + checkclosemth(L, level); /* value must have a close method */ + while (cast_uint(level - L->tbclist.p) > MAXDELTA) { + L->tbclist.p += MAXDELTA; /* create a dummy node at maximum delta */ + L->tbclist.p->tbclist.delta = 0; + } + level->tbclist.delta = cast(unsigned short, level - L->tbclist.p); + L->tbclist.p = level; +} + + +void luaF_unlinkupval (UpVal *uv) { + lua_assert(upisopen(uv)); + *uv->u.open.previous = uv->u.open.next; + if (uv->u.open.next) + uv->u.open.next->u.open.previous = uv->u.open.previous; +} + + +/* +** Close all upvalues up to the given stack level. +*/ +void luaF_closeupval (lua_State *L, StkId level) { + UpVal *uv; + StkId upl; /* stack index pointed by 'uv' */ + while ((uv = L->openupval) != NULL && (upl = uplevel(uv)) >= level) { + TValue *slot = &uv->u.value; /* new position for value */ + lua_assert(uplevel(uv) < L->top.p); + luaF_unlinkupval(uv); /* remove upvalue from 'openupval' list */ + setobj(L, slot, uv->v.p); /* move value to upvalue slot */ + uv->v.p = slot; /* now current value lives here */ + if (!iswhite(uv)) { /* neither white nor dead? */ + nw2black(uv); /* closed upvalues cannot be gray */ + luaC_barrier(L, uv, slot); + } + } +} + + +/* +** Remove first element from the tbclist plus its dummy nodes. +*/ +static void poptbclist (lua_State *L) { + StkId tbc = L->tbclist.p; + lua_assert(tbc->tbclist.delta > 0); /* first element cannot be dummy */ + tbc -= tbc->tbclist.delta; + while (tbc > L->stack.p && tbc->tbclist.delta == 0) + tbc -= MAXDELTA; /* remove dummy nodes */ + L->tbclist.p = tbc; +} + + +/* +** Close all upvalues and to-be-closed variables up to the given stack +** level. Return restored 'level'. +*/ +StkId luaF_close (lua_State *L, StkId level, int status, int yy) { + ptrdiff_t levelrel = savestack(L, level); + luaF_closeupval(L, level); /* first, close the upvalues */ + while (L->tbclist.p >= level) { /* traverse tbc's down to that level */ + StkId tbc = L->tbclist.p; /* get variable index */ + poptbclist(L); /* remove it from list */ + prepcallclosemth(L, tbc, status, yy); /* close variable */ + level = restorestack(L, levelrel); + } + return level; +} + + +Proto *luaF_newproto (lua_State *L) { + GCObject *o = luaC_newobj(L, LUA_VPROTO, sizeof(Proto)); + Proto *f = gco2p(o); + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->sizecode = 0; + f->lineinfo = NULL; + f->sizelineinfo = 0; + f->abslineinfo = NULL; + f->sizeabslineinfo = 0; + f->upvalues = NULL; + f->sizeupvalues = 0; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->locvars = NULL; + f->sizelocvars = 0; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; + return f; +} + + +void luaF_freeproto (lua_State *L, Proto *f) { + luaM_freearray(L, f->code, f->sizecode); + luaM_freearray(L, f->p, f->sizep); + luaM_freearray(L, f->k, f->sizek); + luaM_freearray(L, f->lineinfo, f->sizelineinfo); + luaM_freearray(L, f->abslineinfo, f->sizeabslineinfo); + luaM_freearray(L, f->locvars, f->sizelocvars); + luaM_freearray(L, f->upvalues, f->sizeupvalues); + luaM_free(L, f); +} + + +/* +** Look for n-th local variable at line 'line' in function 'func'. +** Returns NULL if not found. +*/ +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } + } + return NULL; /* not found */ +} + diff --git a/User/system/lua/src/lfunc.h b/User/system/lua/src/lfunc.h new file mode 100644 index 0000000..3be265e --- /dev/null +++ b/User/system/lua/src/lfunc.h @@ -0,0 +1,64 @@ +/* +** $Id: lfunc.h $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + +#define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \ + cast_int(sizeof(TValue)) * (n)) + +#define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \ + cast_int(sizeof(TValue *)) * (n)) + + +/* test whether thread is in 'twups' list */ +#define isintwups(L) (L->twups != L) + + +/* +** maximum number of upvalues in a closure (both C and Lua). (Value +** must fit in a VM register.) +*/ +#define MAXUPVAL 255 + + +#define upisopen(up) ((up)->v.p != &(up)->u.value) + + +#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v.p)) + + +/* +** maximum number of misses before giving up the cache of closures +** in prototypes +*/ +#define MAXMISS 10 + + + +/* special status to close upvalues preserving the top of the stack */ +#define CLOSEKTOP (-1) + + +LUAI_FUNC Proto *luaF_newproto (lua_State *L); +LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nupvals); +LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nupvals); +LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); +LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, int status, int yy); +LUAI_FUNC void luaF_unlinkupval (UpVal *uv); +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, + int pc); + + +#endif diff --git a/User/system/lua/src/lgc.c b/User/system/lua/src/lgc.c new file mode 100644 index 0000000..5817f9e --- /dev/null +++ b/User/system/lua/src/lgc.c @@ -0,0 +1,1743 @@ +/* +** $Id: lgc.c $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#define lgc_c +#define LUA_CORE + +#include "lprefix.h" + +#include +#include + + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +/* +** Maximum number of elements to sweep in each single step. +** (Large enough to dissipate fixed overheads but small enough +** to allow small steps for the collector.) +*/ +#define GCSWEEPMAX 100 + +/* +** Maximum number of finalizers to call in each single step. +*/ +#define GCFINMAX 10 + + +/* +** Cost of calling one finalizer. +*/ +#define GCFINALIZECOST 50 + + +/* +** The equivalent, in bytes, of one unit of "work" (visiting a slot, +** sweeping an object, etc.) +*/ +#define WORK2MEM sizeof(TValue) + + +/* +** macro to adjust 'pause': 'pause' is actually used like +** 'pause / PAUSEADJ' (value chosen by tests) +*/ +#define PAUSEADJ 100 + + +/* mask with all color bits */ +#define maskcolors (bitmask(BLACKBIT) | WHITEBITS) + +/* mask with all GC bits */ +#define maskgcbits (maskcolors | AGEBITS) + + +/* macro to erase all color bits then set only the current white bit */ +#define makewhite(g,x) \ + (x->marked = cast_byte((x->marked & ~maskcolors) | luaC_white(g))) + +/* make an object gray (neither white nor black) */ +#define set2gray(x) resetbits(x->marked, maskcolors) + + +/* make an object black (coming from any color) */ +#define set2black(x) \ + (x->marked = cast_byte((x->marked & ~WHITEBITS) | bitmask(BLACKBIT))) + + +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) + +#define keyiswhite(n) (keyiscollectable(n) && iswhite(gckey(n))) + + +/* +** Protected access to objects in values +*/ +#define gcvalueN(o) (iscollectable(o) ? gcvalue(o) : NULL) + + +#define markvalue(g,o) { checkliveness(g->mainthread,o); \ + if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } + +#define markkey(g, n) { if keyiswhite(n) reallymarkobject(g,gckey(n)); } + +#define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); } + +/* +** mark an object that can be NULL (either because it is really optional, +** or it was stripped as debug info, or inside an uncompleted structure) +*/ +#define markobjectN(g,t) { if (t) markobject(g,t); } + +static void reallymarkobject (global_State *g, GCObject *o); +static lu_mem atomic (lua_State *L); +static void entersweep (lua_State *L); + + +/* +** {====================================================== +** Generic functions +** ======================================================= +*/ + + +/* +** one after last element in a hash array +*/ +#define gnodelast(h) gnode(h, cast_sizet(sizenode(h))) + + +static GCObject **getgclist (GCObject *o) { + switch (o->tt) { + case LUA_VTABLE: return &gco2t(o)->gclist; + case LUA_VLCL: return &gco2lcl(o)->gclist; + case LUA_VCCL: return &gco2ccl(o)->gclist; + case LUA_VTHREAD: return &gco2th(o)->gclist; + case LUA_VPROTO: return &gco2p(o)->gclist; + case LUA_VUSERDATA: { + Udata *u = gco2u(o); + lua_assert(u->nuvalue > 0); + return &u->gclist; + } + default: lua_assert(0); return 0; + } +} + + +/* +** Link a collectable object 'o' with a known type into the list 'p'. +** (Must be a macro to access the 'gclist' field in different types.) +*/ +#define linkgclist(o,p) linkgclist_(obj2gco(o), &(o)->gclist, &(p)) + +static void linkgclist_ (GCObject *o, GCObject **pnext, GCObject **list) { + lua_assert(!isgray(o)); /* cannot be in a gray list */ + *pnext = *list; + *list = o; + set2gray(o); /* now it is */ +} + + +/* +** Link a generic collectable object 'o' into the list 'p'. +*/ +#define linkobjgclist(o,p) linkgclist_(obj2gco(o), getgclist(o), &(p)) + + + +/* +** Clear keys for empty entries in tables. If entry is empty, mark its +** entry as dead. This allows the collection of the key, but keeps its +** entry in the table: its removal could break a chain and could break +** a table traversal. Other places never manipulate dead keys, because +** its associated empty value is enough to signal that the entry is +** logically empty. +*/ +static void clearkey (Node *n) { + lua_assert(isempty(gval(n))); + if (keyiscollectable(n)) + setdeadkey(n); /* unused key; remove it */ +} + + +/* +** tells whether a key or value can be cleared from a weak +** table. Non-collectable objects are never removed from weak +** tables. Strings behave as 'values', so are never removed too. for +** other objects: if really collected, cannot keep them; for objects +** being finalized, keep them in keys, but not in values +*/ +static int iscleared (global_State *g, const GCObject *o) { + if (o == NULL) return 0; /* non-collectable value */ + else if (novariant(o->tt) == LUA_TSTRING) { + markobject(g, o); /* strings are 'values', so are never weak */ + return 0; + } + else return iswhite(o); +} + + +/* +** Barrier that moves collector forward, that is, marks the white object +** 'v' being pointed by the black object 'o'. In the generational +** mode, 'v' must also become old, if 'o' is old; however, it cannot +** be changed directly to OLD, because it may still point to non-old +** objects. So, it is marked as OLD0. In the next cycle it will become +** OLD1, and in the next it will finally become OLD (regular old). By +** then, any object it points to will also be old. If called in the +** incremental sweep phase, it clears the black object to white (sweep +** it) to avoid other barrier calls for this same object. (That cannot +** be done is generational mode, as its sweep does not distinguish +** whites from deads.) +*/ +void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + if (keepinvariant(g)) { /* must keep invariant? */ + reallymarkobject(g, v); /* restore invariant */ + if (isold(o)) { + lua_assert(!isold(v)); /* white object could not be old */ + setage(v, G_OLD0); /* restore generational invariant */ + } + } + else { /* sweep phase */ + lua_assert(issweepphase(g)); + if (g->gckind == KGC_INC) /* incremental mode? */ + makewhite(g, o); /* mark 'o' as white to avoid other barriers */ + } +} + + +/* +** barrier that moves collector backward, that is, mark the black object +** pointing to a white object as gray again. +*/ +void luaC_barrierback_ (lua_State *L, GCObject *o) { + global_State *g = G(L); + lua_assert(isblack(o) && !isdead(g, o)); + lua_assert((g->gckind == KGC_GEN) == (isold(o) && getage(o) != G_TOUCHED1)); + if (getage(o) == G_TOUCHED2) /* already in gray list? */ + set2gray(o); /* make it gray to become touched1 */ + else /* link it in 'grayagain' and paint it gray */ + linkobjgclist(o, g->grayagain); + if (isold(o)) /* generational mode? */ + setage(o, G_TOUCHED1); /* touched in current cycle */ +} + + +void luaC_fix (lua_State *L, GCObject *o) { + global_State *g = G(L); + lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */ + set2gray(o); /* they will be gray forever */ + setage(o, G_OLD); /* and old forever */ + g->allgc = o->next; /* remove object from 'allgc' list */ + o->next = g->fixedgc; /* link it to 'fixedgc' list */ + g->fixedgc = o; +} + + +/* +** create a new collectable object (with given type, size, and offset) +** and link it to 'allgc' list. +*/ +GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz, size_t offset) { + global_State *g = G(L); + char *p = cast_charp(luaM_newobject(L, novariant(tt), sz)); + GCObject *o = cast(GCObject *, p + offset); + o->marked = luaC_white(g); + o->tt = tt; + o->next = g->allgc; + g->allgc = o; + return o; +} + + +GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { + return luaC_newobjdt(L, tt, sz, 0); +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Mark functions +** ======================================================= +*/ + + +/* +** Mark an object. Userdata with no user values, strings, and closed +** upvalues are visited and turned black here. Open upvalues are +** already indirectly linked through their respective threads in the +** 'twups' list, so they don't go to the gray list; nevertheless, they +** are kept gray to avoid barriers, as their values will be revisited +** by the thread or by 'remarkupvals'. Other objects are added to the +** gray list to be visited (and turned black) later. Both userdata and +** upvalues can call this function recursively, but this recursion goes +** for at most two levels: An upvalue cannot refer to another upvalue +** (only closures can), and a userdata's metatable must be a table. +*/ +static void reallymarkobject (global_State *g, GCObject *o) { + switch (o->tt) { + case LUA_VSHRSTR: + case LUA_VLNGSTR: { + set2black(o); /* nothing to visit */ + break; + } + case LUA_VUPVAL: { + UpVal *uv = gco2upv(o); + if (upisopen(uv)) + set2gray(uv); /* open upvalues are kept gray */ + else + set2black(uv); /* closed upvalues are visited here */ + markvalue(g, uv->v.p); /* mark its content */ + break; + } + case LUA_VUSERDATA: { + Udata *u = gco2u(o); + if (u->nuvalue == 0) { /* no user values? */ + markobjectN(g, u->metatable); /* mark its metatable */ + set2black(u); /* nothing else to mark */ + break; + } + /* else... */ + } /* FALLTHROUGH */ + case LUA_VLCL: case LUA_VCCL: case LUA_VTABLE: + case LUA_VTHREAD: case LUA_VPROTO: { + linkobjgclist(o, g->gray); /* to be visited later */ + break; + } + default: lua_assert(0); break; + } +} + + +/* +** mark metamethods for basic types +*/ +static void markmt (global_State *g) { + int i; + for (i=0; i < LUA_NUMTAGS; i++) + markobjectN(g, g->mt[i]); +} + + +/* +** mark all objects in list of being-finalized +*/ +static lu_mem markbeingfnz (global_State *g) { + GCObject *o; + lu_mem count = 0; + for (o = g->tobefnz; o != NULL; o = o->next) { + count++; + markobject(g, o); + } + return count; +} + + +/* +** For each non-marked thread, simulates a barrier between each open +** upvalue and its value. (If the thread is collected, the value will be +** assigned to the upvalue, but then it can be too late for the barrier +** to act. The "barrier" does not need to check colors: A non-marked +** thread must be young; upvalues cannot be older than their threads; so +** any visited upvalue must be young too.) Also removes the thread from +** the list, as it was already visited. Removes also threads with no +** upvalues, as they have nothing to be checked. (If the thread gets an +** upvalue later, it will be linked in the list again.) +*/ +static int remarkupvals (global_State *g) { + lua_State *thread; + lua_State **p = &g->twups; + int work = 0; /* estimate of how much work was done here */ + while ((thread = *p) != NULL) { + work++; + if (!iswhite(thread) && thread->openupval != NULL) + p = &thread->twups; /* keep marked thread with upvalues in the list */ + else { /* thread is not marked or without upvalues */ + UpVal *uv; + lua_assert(!isold(thread) || thread->openupval == NULL); + *p = thread->twups; /* remove thread from the list */ + thread->twups = thread; /* mark that it is out of list */ + for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { + lua_assert(getage(uv) <= getage(thread)); + work++; + if (!iswhite(uv)) { /* upvalue already visited? */ + lua_assert(upisopen(uv) && isgray(uv)); + markvalue(g, uv->v.p); /* mark its value */ + } + } + } + } + return work; +} + + +static void cleargraylists (global_State *g) { + g->gray = g->grayagain = NULL; + g->weak = g->allweak = g->ephemeron = NULL; +} + + +/* +** mark root set and reset all gray lists, to start a new collection +*/ +static void restartcollection (global_State *g) { + cleargraylists(g); + markobject(g, g->mainthread); + markvalue(g, &g->l_registry); + markmt(g); + markbeingfnz(g); /* mark any finalizing object left from previous cycle */ +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Traverse functions +** ======================================================= +*/ + + +/* +** Check whether object 'o' should be kept in the 'grayagain' list for +** post-processing by 'correctgraylist'. (It could put all old objects +** in the list and leave all the work to 'correctgraylist', but it is +** more efficient to avoid adding elements that will be removed.) Only +** TOUCHED1 objects need to be in the list. TOUCHED2 doesn't need to go +** back to a gray list, but then it must become OLD. (That is what +** 'correctgraylist' does when it finds a TOUCHED2 object.) +*/ +static void genlink (global_State *g, GCObject *o) { + lua_assert(isblack(o)); + if (getage(o) == G_TOUCHED1) { /* touched in this cycle? */ + linkobjgclist(o, g->grayagain); /* link it back in 'grayagain' */ + } /* everything else do not need to be linked back */ + else if (getage(o) == G_TOUCHED2) + changeage(o, G_TOUCHED2, G_OLD); /* advance age */ +} + + +/* +** Traverse a table with weak values and link it to proper list. During +** propagate phase, keep it in 'grayagain' list, to be revisited in the +** atomic phase. In the atomic phase, if table has any white value, +** put it in 'weak' list, to be cleared. +*/ +static void traverseweakvalue (global_State *g, Table *h) { + Node *n, *limit = gnodelast(h); + /* if there is array part, assume it may have white values (it is not + worth traversing it now just to check) */ + int hasclears = (h->alimit > 0); + for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ + if (isempty(gval(n))) /* entry is empty? */ + clearkey(n); /* clear its key */ + else { + lua_assert(!keyisnil(n)); + markkey(g, n); + if (!hasclears && iscleared(g, gcvalueN(gval(n)))) /* a white value? */ + hasclears = 1; /* table will have to be cleared */ + } + } + if (g->gcstate == GCSatomic && hasclears) + linkgclist(h, g->weak); /* has to be cleared later */ + else + linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ +} + + +/* +** Traverse an ephemeron table and link it to proper list. Returns true +** iff any object was marked during this traversal (which implies that +** convergence has to continue). During propagation phase, keep table +** in 'grayagain' list, to be visited again in the atomic phase. In +** the atomic phase, if table has any white->white entry, it has to +** be revisited during ephemeron convergence (as that key may turn +** black). Otherwise, if it has any white key, table has to be cleared +** (in the atomic phase). In generational mode, some tables +** must be kept in some gray list for post-processing; this is done +** by 'genlink'. +*/ +static int traverseephemeron (global_State *g, Table *h, int inv) { + int marked = 0; /* true if an object is marked in this traversal */ + int hasclears = 0; /* true if table has white keys */ + int hasww = 0; /* true if table has entry "white-key -> white-value" */ + unsigned int i; + unsigned int asize = luaH_realasize(h); + unsigned int nsize = sizenode(h); + /* traverse array part */ + for (i = 0; i < asize; i++) { + if (valiswhite(&h->array[i])) { + marked = 1; + reallymarkobject(g, gcvalue(&h->array[i])); + } + } + /* traverse hash part; if 'inv', traverse descending + (see 'convergeephemerons') */ + for (i = 0; i < nsize; i++) { + Node *n = inv ? gnode(h, nsize - 1 - i) : gnode(h, i); + if (isempty(gval(n))) /* entry is empty? */ + clearkey(n); /* clear its key */ + else if (iscleared(g, gckeyN(n))) { /* key is not marked (yet)? */ + hasclears = 1; /* table must be cleared */ + if (valiswhite(gval(n))) /* value not marked yet? */ + hasww = 1; /* white-white entry */ + } + else if (valiswhite(gval(n))) { /* value not marked yet? */ + marked = 1; + reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ + } + } + /* link table into proper list */ + if (g->gcstate == GCSpropagate) + linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ + else if (hasww) /* table has white->white entries? */ + linkgclist(h, g->ephemeron); /* have to propagate again */ + else if (hasclears) /* table has white keys? */ + linkgclist(h, g->allweak); /* may have to clean white keys */ + else + genlink(g, obj2gco(h)); /* check whether collector still needs to see it */ + return marked; +} + + +static void traversestrongtable (global_State *g, Table *h) { + Node *n, *limit = gnodelast(h); + unsigned int i; + unsigned int asize = luaH_realasize(h); + for (i = 0; i < asize; i++) /* traverse array part */ + markvalue(g, &h->array[i]); + for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ + if (isempty(gval(n))) /* entry is empty? */ + clearkey(n); /* clear its key */ + else { + lua_assert(!keyisnil(n)); + markkey(g, n); + markvalue(g, gval(n)); + } + } + genlink(g, obj2gco(h)); +} + + +static lu_mem traversetable (global_State *g, Table *h) { + const char *weakkey, *weakvalue; + const TValue *mode = gfasttm(g, h->metatable, TM_MODE); + TString *smode; + markobjectN(g, h->metatable); + if (mode && ttisshrstring(mode) && /* is there a weak mode? */ + (cast_void(smode = tsvalue(mode)), + cast_void(weakkey = strchr(getshrstr(smode), 'k')), + cast_void(weakvalue = strchr(getshrstr(smode), 'v')), + (weakkey || weakvalue))) { /* is really weak? */ + if (!weakkey) /* strong keys? */ + traverseweakvalue(g, h); + else if (!weakvalue) /* strong values? */ + traverseephemeron(g, h, 0); + else /* all weak */ + linkgclist(h, g->allweak); /* nothing to traverse now */ + } + else /* not weak */ + traversestrongtable(g, h); + return 1 + h->alimit + 2 * allocsizenode(h); +} + + +static int traverseudata (global_State *g, Udata *u) { + int i; + markobjectN(g, u->metatable); /* mark its metatable */ + for (i = 0; i < u->nuvalue; i++) + markvalue(g, &u->uv[i].uv); + genlink(g, obj2gco(u)); + return 1 + u->nuvalue; +} + + +/* +** Traverse a prototype. (While a prototype is being build, its +** arrays can be larger than needed; the extra slots are filled with +** NULL, so the use of 'markobjectN') +*/ +static int traverseproto (global_State *g, Proto *f) { + int i; + markobjectN(g, f->source); + for (i = 0; i < f->sizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ + markobjectN(g, f->upvalues[i].name); + for (i = 0; i < f->sizep; i++) /* mark nested protos */ + markobjectN(g, f->p[i]); + for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ + markobjectN(g, f->locvars[i].varname); + return 1 + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars; +} + + +static int traverseCclosure (global_State *g, CClosure *cl) { + int i; + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->upvalue[i]); + return 1 + cl->nupvalues; +} + +/* +** Traverse a Lua closure, marking its prototype and its upvalues. +** (Both can be NULL while closure is being created.) +*/ +static int traverseLclosure (global_State *g, LClosure *cl) { + int i; + markobjectN(g, cl->p); /* mark its prototype */ + for (i = 0; i < cl->nupvalues; i++) { /* visit its upvalues */ + UpVal *uv = cl->upvals[i]; + markobjectN(g, uv); /* mark upvalue */ + } + return 1 + cl->nupvalues; +} + + +/* +** Traverse a thread, marking the elements in the stack up to its top +** and cleaning the rest of the stack in the final traversal. That +** ensures that the entire stack have valid (non-dead) objects. +** Threads have no barriers. In gen. mode, old threads must be visited +** at every cycle, because they might point to young objects. In inc. +** mode, the thread can still be modified before the end of the cycle, +** and therefore it must be visited again in the atomic phase. To ensure +** these visits, threads must return to a gray list if they are not new +** (which can only happen in generational mode) or if the traverse is in +** the propagate phase (which can only happen in incremental mode). +*/ +static int traversethread (global_State *g, lua_State *th) { + UpVal *uv; + StkId o = th->stack.p; + if (isold(th) || g->gcstate == GCSpropagate) + linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ + if (o == NULL) + return 1; /* stack not completely built yet */ + lua_assert(g->gcstate == GCSatomic || + th->openupval == NULL || isintwups(th)); + for (; o < th->top.p; o++) /* mark live elements in the stack */ + markvalue(g, s2v(o)); + for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) + markobject(g, uv); /* open upvalues cannot be collected */ + if (g->gcstate == GCSatomic) { /* final traversal? */ + if (!g->gcemergency) + luaD_shrinkstack(th); /* do not change stack in emergency cycle */ + for (o = th->top.p; o < th->stack_last.p + EXTRA_STACK; o++) + setnilvalue(s2v(o)); /* clear dead stack slice */ + /* 'remarkupvals' may have removed thread from 'twups' list */ + if (!isintwups(th) && th->openupval != NULL) { + th->twups = g->twups; /* link it back to the list */ + g->twups = th; + } + } + return 1 + stacksize(th); +} + + +/* +** traverse one gray object, turning it to black. +*/ +static lu_mem propagatemark (global_State *g) { + GCObject *o = g->gray; + nw2black(o); + g->gray = *getgclist(o); /* remove from 'gray' list */ + switch (o->tt) { + case LUA_VTABLE: return traversetable(g, gco2t(o)); + case LUA_VUSERDATA: return traverseudata(g, gco2u(o)); + case LUA_VLCL: return traverseLclosure(g, gco2lcl(o)); + case LUA_VCCL: return traverseCclosure(g, gco2ccl(o)); + case LUA_VPROTO: return traverseproto(g, gco2p(o)); + case LUA_VTHREAD: return traversethread(g, gco2th(o)); + default: lua_assert(0); return 0; + } +} + + +static lu_mem propagateall (global_State *g) { + lu_mem tot = 0; + while (g->gray) + tot += propagatemark(g); + return tot; +} + + +/* +** Traverse all ephemeron tables propagating marks from keys to values. +** Repeat until it converges, that is, nothing new is marked. 'dir' +** inverts the direction of the traversals, trying to speed up +** convergence on chains in the same table. +** +*/ +static void convergeephemerons (global_State *g) { + int changed; + int dir = 0; + do { + GCObject *w; + GCObject *next = g->ephemeron; /* get ephemeron list */ + g->ephemeron = NULL; /* tables may return to this list when traversed */ + changed = 0; + while ((w = next) != NULL) { /* for each ephemeron table */ + Table *h = gco2t(w); + next = h->gclist; /* list is rebuilt during loop */ + nw2black(h); /* out of the list (for now) */ + if (traverseephemeron(g, h, dir)) { /* marked some value? */ + propagateall(g); /* propagate changes */ + changed = 1; /* will have to revisit all ephemeron tables */ + } + } + dir = !dir; /* invert direction next time */ + } while (changed); /* repeat until no more changes */ +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Sweep Functions +** ======================================================= +*/ + + +/* +** clear entries with unmarked keys from all weaktables in list 'l' +*/ +static void clearbykeys (global_State *g, GCObject *l) { + for (; l; l = gco2t(l)->gclist) { + Table *h = gco2t(l); + Node *limit = gnodelast(h); + Node *n; + for (n = gnode(h, 0); n < limit; n++) { + if (iscleared(g, gckeyN(n))) /* unmarked key? */ + setempty(gval(n)); /* remove entry */ + if (isempty(gval(n))) /* is entry empty? */ + clearkey(n); /* clear its key */ + } + } +} + + +/* +** clear entries with unmarked values from all weaktables in list 'l' up +** to element 'f' +*/ +static void clearbyvalues (global_State *g, GCObject *l, GCObject *f) { + for (; l != f; l = gco2t(l)->gclist) { + Table *h = gco2t(l); + Node *n, *limit = gnodelast(h); + unsigned int i; + unsigned int asize = luaH_realasize(h); + for (i = 0; i < asize; i++) { + TValue *o = &h->array[i]; + if (iscleared(g, gcvalueN(o))) /* value was collected? */ + setempty(o); /* remove entry */ + } + for (n = gnode(h, 0); n < limit; n++) { + if (iscleared(g, gcvalueN(gval(n)))) /* unmarked value? */ + setempty(gval(n)); /* remove entry */ + if (isempty(gval(n))) /* is entry empty? */ + clearkey(n); /* clear its key */ + } + } +} + + +static void freeupval (lua_State *L, UpVal *uv) { + if (upisopen(uv)) + luaF_unlinkupval(uv); + luaM_free(L, uv); +} + + +static void freeobj (lua_State *L, GCObject *o) { + switch (o->tt) { + case LUA_VPROTO: + luaF_freeproto(L, gco2p(o)); + break; + case LUA_VUPVAL: + freeupval(L, gco2upv(o)); + break; + case LUA_VLCL: { + LClosure *cl = gco2lcl(o); + luaM_freemem(L, cl, sizeLclosure(cl->nupvalues)); + break; + } + case LUA_VCCL: { + CClosure *cl = gco2ccl(o); + luaM_freemem(L, cl, sizeCclosure(cl->nupvalues)); + break; + } + case LUA_VTABLE: + luaH_free(L, gco2t(o)); + break; + case LUA_VTHREAD: + luaE_freethread(L, gco2th(o)); + break; + case LUA_VUSERDATA: { + Udata *u = gco2u(o); + luaM_freemem(L, o, sizeudata(u->nuvalue, u->len)); + break; + } + case LUA_VSHRSTR: { + TString *ts = gco2ts(o); + luaS_remove(L, ts); /* remove it from hash table */ + luaM_freemem(L, ts, sizelstring(ts->shrlen)); + break; + } + case LUA_VLNGSTR: { + TString *ts = gco2ts(o); + luaM_freemem(L, ts, sizelstring(ts->u.lnglen)); + break; + } + default: lua_assert(0); + } +} + + +/* +** sweep at most 'countin' elements from a list of GCObjects erasing dead +** objects, where a dead object is one marked with the old (non current) +** white; change all non-dead objects back to white, preparing for next +** collection cycle. Return where to continue the traversal or NULL if +** list is finished. ('*countout' gets the number of elements traversed.) +*/ +static GCObject **sweeplist (lua_State *L, GCObject **p, int countin, + int *countout) { + global_State *g = G(L); + int ow = otherwhite(g); + int i; + int white = luaC_white(g); /* current white */ + for (i = 0; *p != NULL && i < countin; i++) { + GCObject *curr = *p; + int marked = curr->marked; + if (isdeadm(ow, marked)) { /* is 'curr' dead? */ + *p = curr->next; /* remove 'curr' from list */ + freeobj(L, curr); /* erase 'curr' */ + } + else { /* change mark to 'white' */ + curr->marked = cast_byte((marked & ~maskgcbits) | white); + p = &curr->next; /* go to next element */ + } + } + if (countout) + *countout = i; /* number of elements traversed */ + return (*p == NULL) ? NULL : p; +} + + +/* +** sweep a list until a live object (or end of list) +*/ +static GCObject **sweeptolive (lua_State *L, GCObject **p) { + GCObject **old = p; + do { + p = sweeplist(L, p, 1, NULL); + } while (p == old); + return p; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Finalization +** ======================================================= +*/ + +/* +** If possible, shrink string table. +*/ +static void checkSizes (lua_State *L, global_State *g) { + if (!g->gcemergency) { + if (g->strt.nuse < g->strt.size / 4) { /* string table too big? */ + l_mem olddebt = g->GCdebt; + luaS_resize(L, g->strt.size / 2); + g->GCestimate += g->GCdebt - olddebt; /* correct estimate */ + } + } +} + + +/* +** Get the next udata to be finalized from the 'tobefnz' list, and +** link it back into the 'allgc' list. +*/ +static GCObject *udata2finalize (global_State *g) { + GCObject *o = g->tobefnz; /* get first element */ + lua_assert(tofinalize(o)); + g->tobefnz = o->next; /* remove it from 'tobefnz' list */ + o->next = g->allgc; /* return it to 'allgc' list */ + g->allgc = o; + resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */ + if (issweepphase(g)) + makewhite(g, o); /* "sweep" object */ + else if (getage(o) == G_OLD1) + g->firstold1 = o; /* it is the first OLD1 object in the list */ + return o; +} + + +static void dothecall (lua_State *L, void *ud) { + UNUSED(ud); + luaD_callnoyield(L, L->top.p - 2, 0); +} + + +static void GCTM (lua_State *L) { + global_State *g = G(L); + const TValue *tm; + TValue v; + lua_assert(!g->gcemergency); + setgcovalue(L, &v, udata2finalize(g)); + tm = luaT_gettmbyobj(L, &v, TM_GC); + if (!notm(tm)) { /* is there a finalizer? */ + int status; + lu_byte oldah = L->allowhook; + int oldgcstp = g->gcstp; + g->gcstp |= GCSTPGC; /* avoid GC steps */ + L->allowhook = 0; /* stop debug hooks during GC metamethod */ + setobj2s(L, L->top.p++, tm); /* push finalizer... */ + setobj2s(L, L->top.p++, &v); /* ... and its argument */ + L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ + status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top.p - 2), 0); + L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ + L->allowhook = oldah; /* restore hooks */ + g->gcstp = oldgcstp; /* restore state */ + if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */ + luaE_warnerror(L, "__gc"); + L->top.p--; /* pops error object */ + } + } +} + + +/* +** Call a few finalizers +*/ +static int runafewfinalizers (lua_State *L, int n) { + global_State *g = G(L); + int i; + for (i = 0; i < n && g->tobefnz; i++) + GCTM(L); /* call one finalizer */ + return i; +} + + +/* +** call all pending finalizers +*/ +static void callallpendingfinalizers (lua_State *L) { + global_State *g = G(L); + while (g->tobefnz) + GCTM(L); +} + + +/* +** find last 'next' field in list 'p' list (to add elements in its end) +*/ +static GCObject **findlast (GCObject **p) { + while (*p != NULL) + p = &(*p)->next; + return p; +} + + +/* +** Move all unreachable objects (or 'all' objects) that need +** finalization from list 'finobj' to list 'tobefnz' (to be finalized). +** (Note that objects after 'finobjold1' cannot be white, so they +** don't need to be traversed. In incremental mode, 'finobjold1' is NULL, +** so the whole list is traversed.) +*/ +static void separatetobefnz (global_State *g, int all) { + GCObject *curr; + GCObject **p = &g->finobj; + GCObject **lastnext = findlast(&g->tobefnz); + while ((curr = *p) != g->finobjold1) { /* traverse all finalizable objects */ + lua_assert(tofinalize(curr)); + if (!(iswhite(curr) || all)) /* not being collected? */ + p = &curr->next; /* don't bother with it */ + else { + if (curr == g->finobjsur) /* removing 'finobjsur'? */ + g->finobjsur = curr->next; /* correct it */ + *p = curr->next; /* remove 'curr' from 'finobj' list */ + curr->next = *lastnext; /* link at the end of 'tobefnz' list */ + *lastnext = curr; + lastnext = &curr->next; + } + } +} + + +/* +** If pointer 'p' points to 'o', move it to the next element. +*/ +static void checkpointer (GCObject **p, GCObject *o) { + if (o == *p) + *p = o->next; +} + + +/* +** Correct pointers to objects inside 'allgc' list when +** object 'o' is being removed from the list. +*/ +static void correctpointers (global_State *g, GCObject *o) { + checkpointer(&g->survival, o); + checkpointer(&g->old1, o); + checkpointer(&g->reallyold, o); + checkpointer(&g->firstold1, o); +} + + +/* +** if object 'o' has a finalizer, remove it from 'allgc' list (must +** search the list to find it) and link it in 'finobj' list. +*/ +void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { + global_State *g = G(L); + if (tofinalize(o) || /* obj. is already marked... */ + gfasttm(g, mt, TM_GC) == NULL || /* or has no finalizer... */ + (g->gcstp & GCSTPCLS)) /* or closing state? */ + return; /* nothing to be done */ + else { /* move 'o' to 'finobj' list */ + GCObject **p; + if (issweepphase(g)) { + makewhite(g, o); /* "sweep" object 'o' */ + if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ + g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */ + } + else + correctpointers(g, o); + /* search for pointer pointing to 'o' */ + for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } + *p = o->next; /* remove 'o' from 'allgc' list */ + o->next = g->finobj; /* link it in 'finobj' list */ + g->finobj = o; + l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Generational Collector +** ======================================================= +*/ + + +/* +** Set the "time" to wait before starting a new GC cycle; cycle will +** start when memory use hits the threshold of ('estimate' * pause / +** PAUSEADJ). (Division by 'estimate' should be OK: it cannot be zero, +** because Lua cannot even start with less than PAUSEADJ bytes). +*/ +static void setpause (global_State *g) { + l_mem threshold, debt; + int pause = getgcparam(g->gcpause); + l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */ + lua_assert(estimate > 0); + threshold = (pause < MAX_LMEM / estimate) /* overflow? */ + ? estimate * pause /* no overflow */ + : MAX_LMEM; /* overflow; truncate to maximum */ + debt = gettotalbytes(g) - threshold; + if (debt > 0) debt = 0; + luaE_setdebt(g, debt); +} + + +/* +** Sweep a list of objects to enter generational mode. Deletes dead +** objects and turns the non dead to old. All non-dead threads---which +** are now old---must be in a gray list. Everything else is not in a +** gray list. Open upvalues are also kept gray. +*/ +static void sweep2old (lua_State *L, GCObject **p) { + GCObject *curr; + global_State *g = G(L); + while ((curr = *p) != NULL) { + if (iswhite(curr)) { /* is 'curr' dead? */ + lua_assert(isdead(g, curr)); + *p = curr->next; /* remove 'curr' from list */ + freeobj(L, curr); /* erase 'curr' */ + } + else { /* all surviving objects become old */ + setage(curr, G_OLD); + if (curr->tt == LUA_VTHREAD) { /* threads must be watched */ + lua_State *th = gco2th(curr); + linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ + } + else if (curr->tt == LUA_VUPVAL && upisopen(gco2upv(curr))) + set2gray(curr); /* open upvalues are always gray */ + else /* everything else is black */ + nw2black(curr); + p = &curr->next; /* go to next element */ + } + } +} + + +/* +** Sweep for generational mode. Delete dead objects. (Because the +** collection is not incremental, there are no "new white" objects +** during the sweep. So, any white object must be dead.) For +** non-dead objects, advance their ages and clear the color of +** new objects. (Old objects keep their colors.) +** The ages of G_TOUCHED1 and G_TOUCHED2 objects cannot be advanced +** here, because these old-generation objects are usually not swept +** here. They will all be advanced in 'correctgraylist'. That function +** will also remove objects turned white here from any gray list. +*/ +static GCObject **sweepgen (lua_State *L, global_State *g, GCObject **p, + GCObject *limit, GCObject **pfirstold1) { + static const lu_byte nextage[] = { + G_SURVIVAL, /* from G_NEW */ + G_OLD1, /* from G_SURVIVAL */ + G_OLD1, /* from G_OLD0 */ + G_OLD, /* from G_OLD1 */ + G_OLD, /* from G_OLD (do not change) */ + G_TOUCHED1, /* from G_TOUCHED1 (do not change) */ + G_TOUCHED2 /* from G_TOUCHED2 (do not change) */ + }; + int white = luaC_white(g); + GCObject *curr; + while ((curr = *p) != limit) { + if (iswhite(curr)) { /* is 'curr' dead? */ + lua_assert(!isold(curr) && isdead(g, curr)); + *p = curr->next; /* remove 'curr' from list */ + freeobj(L, curr); /* erase 'curr' */ + } + else { /* correct mark and age */ + if (getage(curr) == G_NEW) { /* new objects go back to white */ + int marked = curr->marked & ~maskgcbits; /* erase GC bits */ + curr->marked = cast_byte(marked | G_SURVIVAL | white); + } + else { /* all other objects will be old, and so keep their color */ + setage(curr, nextage[getage(curr)]); + if (getage(curr) == G_OLD1 && *pfirstold1 == NULL) + *pfirstold1 = curr; /* first OLD1 object in the list */ + } + p = &curr->next; /* go to next element */ + } + } + return p; +} + + +/* +** Traverse a list making all its elements white and clearing their +** age. In incremental mode, all objects are 'new' all the time, +** except for fixed strings (which are always old). +*/ +static void whitelist (global_State *g, GCObject *p) { + int white = luaC_white(g); + for (; p != NULL; p = p->next) + p->marked = cast_byte((p->marked & ~maskgcbits) | white); +} + + +/* +** Correct a list of gray objects. Return pointer to where rest of the +** list should be linked. +** Because this correction is done after sweeping, young objects might +** be turned white and still be in the list. They are only removed. +** 'TOUCHED1' objects are advanced to 'TOUCHED2' and remain on the list; +** Non-white threads also remain on the list; 'TOUCHED2' objects become +** regular old; they and anything else are removed from the list. +*/ +static GCObject **correctgraylist (GCObject **p) { + GCObject *curr; + while ((curr = *p) != NULL) { + GCObject **next = getgclist(curr); + if (iswhite(curr)) + goto remove; /* remove all white objects */ + else if (getage(curr) == G_TOUCHED1) { /* touched in this cycle? */ + lua_assert(isgray(curr)); + nw2black(curr); /* make it black, for next barrier */ + changeage(curr, G_TOUCHED1, G_TOUCHED2); + goto remain; /* keep it in the list and go to next element */ + } + else if (curr->tt == LUA_VTHREAD) { + lua_assert(isgray(curr)); + goto remain; /* keep non-white threads on the list */ + } + else { /* everything else is removed */ + lua_assert(isold(curr)); /* young objects should be white here */ + if (getage(curr) == G_TOUCHED2) /* advance from TOUCHED2... */ + changeage(curr, G_TOUCHED2, G_OLD); /* ... to OLD */ + nw2black(curr); /* make object black (to be removed) */ + goto remove; + } + remove: *p = *next; continue; + remain: p = next; continue; + } + return p; +} + + +/* +** Correct all gray lists, coalescing them into 'grayagain'. +*/ +static void correctgraylists (global_State *g) { + GCObject **list = correctgraylist(&g->grayagain); + *list = g->weak; g->weak = NULL; + list = correctgraylist(list); + *list = g->allweak; g->allweak = NULL; + list = correctgraylist(list); + *list = g->ephemeron; g->ephemeron = NULL; + correctgraylist(list); +} + + +/* +** Mark black 'OLD1' objects when starting a new young collection. +** Gray objects are already in some gray list, and so will be visited +** in the atomic step. +*/ +static void markold (global_State *g, GCObject *from, GCObject *to) { + GCObject *p; + for (p = from; p != to; p = p->next) { + if (getage(p) == G_OLD1) { + lua_assert(!iswhite(p)); + changeage(p, G_OLD1, G_OLD); /* now they are old */ + if (isblack(p)) + reallymarkobject(g, p); + } + } +} + + +/* +** Finish a young-generation collection. +*/ +static void finishgencycle (lua_State *L, global_State *g) { + correctgraylists(g); + checkSizes(L, g); + g->gcstate = GCSpropagate; /* skip restart */ + if (!g->gcemergency) + callallpendingfinalizers(L); +} + + +/* +** Does a young collection. First, mark 'OLD1' objects. Then does the +** atomic step. Then, sweep all lists and advance pointers. Finally, +** finish the collection. +*/ +static void youngcollection (lua_State *L, global_State *g) { + GCObject **psurvival; /* to point to first non-dead survival object */ + GCObject *dummy; /* dummy out parameter to 'sweepgen' */ + lua_assert(g->gcstate == GCSpropagate); + if (g->firstold1) { /* are there regular OLD1 objects? */ + markold(g, g->firstold1, g->reallyold); /* mark them */ + g->firstold1 = NULL; /* no more OLD1 objects (for now) */ + } + markold(g, g->finobj, g->finobjrold); + markold(g, g->tobefnz, NULL); + atomic(L); + + /* sweep nursery and get a pointer to its last live element */ + g->gcstate = GCSswpallgc; + psurvival = sweepgen(L, g, &g->allgc, g->survival, &g->firstold1); + /* sweep 'survival' */ + sweepgen(L, g, psurvival, g->old1, &g->firstold1); + g->reallyold = g->old1; + g->old1 = *psurvival; /* 'survival' survivals are old now */ + g->survival = g->allgc; /* all news are survivals */ + + /* repeat for 'finobj' lists */ + dummy = NULL; /* no 'firstold1' optimization for 'finobj' lists */ + psurvival = sweepgen(L, g, &g->finobj, g->finobjsur, &dummy); + /* sweep 'survival' */ + sweepgen(L, g, psurvival, g->finobjold1, &dummy); + g->finobjrold = g->finobjold1; + g->finobjold1 = *psurvival; /* 'survival' survivals are old now */ + g->finobjsur = g->finobj; /* all news are survivals */ + + sweepgen(L, g, &g->tobefnz, NULL, &dummy); + finishgencycle(L, g); +} + + +/* +** Clears all gray lists, sweeps objects, and prepare sublists to enter +** generational mode. The sweeps remove dead objects and turn all +** surviving objects to old. Threads go back to 'grayagain'; everything +** else is turned black (not in any gray list). +*/ +static void atomic2gen (lua_State *L, global_State *g) { + cleargraylists(g); + /* sweep all elements making them old */ + g->gcstate = GCSswpallgc; + sweep2old(L, &g->allgc); + /* everything alive now is old */ + g->reallyold = g->old1 = g->survival = g->allgc; + g->firstold1 = NULL; /* there are no OLD1 objects anywhere */ + + /* repeat for 'finobj' lists */ + sweep2old(L, &g->finobj); + g->finobjrold = g->finobjold1 = g->finobjsur = g->finobj; + + sweep2old(L, &g->tobefnz); + + g->gckind = KGC_GEN; + g->lastatomic = 0; + g->GCestimate = gettotalbytes(g); /* base for memory control */ + finishgencycle(L, g); +} + + +/* +** Set debt for the next minor collection, which will happen when +** memory grows 'genminormul'%. +*/ +static void setminordebt (global_State *g) { + luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul)); +} + + +/* +** Enter generational mode. Must go until the end of an atomic cycle +** to ensure that all objects are correctly marked and weak tables +** are cleared. Then, turn all objects into old and finishes the +** collection. +*/ +static lu_mem entergen (lua_State *L, global_State *g) { + lu_mem numobjs; + luaC_runtilstate(L, bitmask(GCSpause)); /* prepare to start a new cycle */ + luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ + numobjs = atomic(L); /* propagates all and then do the atomic stuff */ + atomic2gen(L, g); + setminordebt(g); /* set debt assuming next cycle will be minor */ + return numobjs; +} + + +/* +** Enter incremental mode. Turn all objects white, make all +** intermediate lists point to NULL (to avoid invalid pointers), +** and go to the pause state. +*/ +static void enterinc (global_State *g) { + whitelist(g, g->allgc); + g->reallyold = g->old1 = g->survival = NULL; + whitelist(g, g->finobj); + whitelist(g, g->tobefnz); + g->finobjrold = g->finobjold1 = g->finobjsur = NULL; + g->gcstate = GCSpause; + g->gckind = KGC_INC; + g->lastatomic = 0; +} + + +/* +** Change collector mode to 'newmode'. +*/ +void luaC_changemode (lua_State *L, int newmode) { + global_State *g = G(L); + if (newmode != g->gckind) { + if (newmode == KGC_GEN) /* entering generational mode? */ + entergen(L, g); + else + enterinc(g); /* entering incremental mode */ + } + g->lastatomic = 0; +} + + +/* +** Does a full collection in generational mode. +*/ +static lu_mem fullgen (lua_State *L, global_State *g) { + enterinc(g); + return entergen(L, g); +} + + +/* +** Does a major collection after last collection was a "bad collection". +** +** When the program is building a big structure, it allocates lots of +** memory but generates very little garbage. In those scenarios, +** the generational mode just wastes time doing small collections, and +** major collections are frequently what we call a "bad collection", a +** collection that frees too few objects. To avoid the cost of switching +** between generational mode and the incremental mode needed for full +** (major) collections, the collector tries to stay in incremental mode +** after a bad collection, and to switch back to generational mode only +** after a "good" collection (one that traverses less than 9/8 objects +** of the previous one). +** The collector must choose whether to stay in incremental mode or to +** switch back to generational mode before sweeping. At this point, it +** does not know the real memory in use, so it cannot use memory to +** decide whether to return to generational mode. Instead, it uses the +** number of objects traversed (returned by 'atomic') as a proxy. The +** field 'g->lastatomic' keeps this count from the last collection. +** ('g->lastatomic != 0' also means that the last collection was bad.) +*/ +static void stepgenfull (lua_State *L, global_State *g) { + lu_mem newatomic; /* count of traversed objects */ + lu_mem lastatomic = g->lastatomic; /* count from last collection */ + if (g->gckind == KGC_GEN) /* still in generational mode? */ + enterinc(g); /* enter incremental mode */ + luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ + newatomic = atomic(L); /* mark everybody */ + if (newatomic < lastatomic + (lastatomic >> 3)) { /* good collection? */ + atomic2gen(L, g); /* return to generational mode */ + setminordebt(g); + } + else { /* another bad collection; stay in incremental mode */ + g->GCestimate = gettotalbytes(g); /* first estimate */ + entersweep(L); + luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ + setpause(g); + g->lastatomic = newatomic; + } +} + + +/* +** Does a generational "step". +** Usually, this means doing a minor collection and setting the debt to +** make another collection when memory grows 'genminormul'% larger. +** +** However, there are exceptions. If memory grows 'genmajormul'% +** larger than it was at the end of the last major collection (kept +** in 'g->GCestimate'), the function does a major collection. At the +** end, it checks whether the major collection was able to free a +** decent amount of memory (at least half the growth in memory since +** previous major collection). If so, the collector keeps its state, +** and the next collection will probably be minor again. Otherwise, +** we have what we call a "bad collection". In that case, set the field +** 'g->lastatomic' to signal that fact, so that the next collection will +** go to 'stepgenfull'. +** +** 'GCdebt <= 0' means an explicit call to GC step with "size" zero; +** in that case, do a minor collection. +*/ +static void genstep (lua_State *L, global_State *g) { + if (g->lastatomic != 0) /* last collection was a bad one? */ + stepgenfull(L, g); /* do a full step */ + else { + lu_mem majorbase = g->GCestimate; /* memory after last major collection */ + lu_mem majorinc = (majorbase / 100) * getgcparam(g->genmajormul); + if (g->GCdebt > 0 && gettotalbytes(g) > majorbase + majorinc) { + lu_mem numobjs = fullgen(L, g); /* do a major collection */ + if (gettotalbytes(g) < majorbase + (majorinc / 2)) { + /* collected at least half of memory growth since last major + collection; keep doing minor collections. */ + lua_assert(g->lastatomic == 0); + } + else { /* bad collection */ + g->lastatomic = numobjs; /* signal that last collection was bad */ + setpause(g); /* do a long wait for next (major) collection */ + } + } + else { /* regular case; do a minor collection */ + youngcollection(L, g); + setminordebt(g); + g->GCestimate = majorbase; /* preserve base value */ + } + } + lua_assert(isdecGCmodegen(g)); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** GC control +** ======================================================= +*/ + + +/* +** Enter first sweep phase. +** The call to 'sweeptolive' makes the pointer point to an object +** inside the list (instead of to the header), so that the real sweep do +** not need to skip objects created between "now" and the start of the +** real sweep. +*/ +static void entersweep (lua_State *L) { + global_State *g = G(L); + g->gcstate = GCSswpallgc; + lua_assert(g->sweepgc == NULL); + g->sweepgc = sweeptolive(L, &g->allgc); +} + + +/* +** Delete all objects in list 'p' until (but not including) object +** 'limit'. +*/ +static void deletelist (lua_State *L, GCObject *p, GCObject *limit) { + while (p != limit) { + GCObject *next = p->next; + freeobj(L, p); + p = next; + } +} + + +/* +** Call all finalizers of the objects in the given Lua state, and +** then free all objects, except for the main thread. +*/ +void luaC_freeallobjects (lua_State *L) { + global_State *g = G(L); + g->gcstp = GCSTPCLS; /* no extra finalizers after here */ + luaC_changemode(L, KGC_INC); + separatetobefnz(g, 1); /* separate all objects with finalizers */ + lua_assert(g->finobj == NULL); + callallpendingfinalizers(L); + deletelist(L, g->allgc, obj2gco(g->mainthread)); + lua_assert(g->finobj == NULL); /* no new finalizers */ + deletelist(L, g->fixedgc, NULL); /* collect fixed objects */ + lua_assert(g->strt.nuse == 0); +} + + +static lu_mem atomic (lua_State *L) { + global_State *g = G(L); + lu_mem work = 0; + GCObject *origweak, *origall; + GCObject *grayagain = g->grayagain; /* save original list */ + g->grayagain = NULL; + lua_assert(g->ephemeron == NULL && g->weak == NULL); + lua_assert(!iswhite(g->mainthread)); + g->gcstate = GCSatomic; + markobject(g, L); /* mark running thread */ + /* registry and global metatables may be changed by API */ + markvalue(g, &g->l_registry); + markmt(g); /* mark global metatables */ + work += propagateall(g); /* empties 'gray' list */ + /* remark occasional upvalues of (maybe) dead threads */ + work += remarkupvals(g); + work += propagateall(g); /* propagate changes */ + g->gray = grayagain; + work += propagateall(g); /* traverse 'grayagain' list */ + convergeephemerons(g); + /* at this point, all strongly accessible objects are marked. */ + /* Clear values from weak tables, before checking finalizers */ + clearbyvalues(g, g->weak, NULL); + clearbyvalues(g, g->allweak, NULL); + origweak = g->weak; origall = g->allweak; + separatetobefnz(g, 0); /* separate objects to be finalized */ + work += markbeingfnz(g); /* mark objects that will be finalized */ + work += propagateall(g); /* remark, to propagate 'resurrection' */ + convergeephemerons(g); + /* at this point, all resurrected objects are marked. */ + /* remove dead objects from weak tables */ + clearbykeys(g, g->ephemeron); /* clear keys from all ephemeron tables */ + clearbykeys(g, g->allweak); /* clear keys from all 'allweak' tables */ + /* clear values from resurrected weak tables */ + clearbyvalues(g, g->weak, origweak); + clearbyvalues(g, g->allweak, origall); + luaS_clearcache(g); + g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ + lua_assert(g->gray == NULL); + return work; /* estimate of slots marked by 'atomic' */ +} + + +static int sweepstep (lua_State *L, global_State *g, + int nextstate, GCObject **nextlist) { + if (g->sweepgc) { + l_mem olddebt = g->GCdebt; + int count; + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX, &count); + g->GCestimate += g->GCdebt - olddebt; /* update estimate */ + return count; + } + else { /* enter next state */ + g->gcstate = nextstate; + g->sweepgc = nextlist; + return 0; /* no work done */ + } +} + + +static lu_mem singlestep (lua_State *L) { + global_State *g = G(L); + lu_mem work; + lua_assert(!g->gcstopem); /* collector is not reentrant */ + g->gcstopem = 1; /* no emergency collections while collecting */ + switch (g->gcstate) { + case GCSpause: { + restartcollection(g); + g->gcstate = GCSpropagate; + work = 1; + break; + } + case GCSpropagate: { + if (g->gray == NULL) { /* no more gray objects? */ + g->gcstate = GCSenteratomic; /* finish propagate phase */ + work = 0; + } + else + work = propagatemark(g); /* traverse one gray object */ + break; + } + case GCSenteratomic: { + work = atomic(L); /* work is what was traversed by 'atomic' */ + entersweep(L); + g->GCestimate = gettotalbytes(g); /* first estimate */ + break; + } + case GCSswpallgc: { /* sweep "regular" objects */ + work = sweepstep(L, g, GCSswpfinobj, &g->finobj); + break; + } + case GCSswpfinobj: { /* sweep objects with finalizers */ + work = sweepstep(L, g, GCSswptobefnz, &g->tobefnz); + break; + } + case GCSswptobefnz: { /* sweep objects to be finalized */ + work = sweepstep(L, g, GCSswpend, NULL); + break; + } + case GCSswpend: { /* finish sweeps */ + checkSizes(L, g); + g->gcstate = GCScallfin; + work = 0; + break; + } + case GCScallfin: { /* call remaining finalizers */ + if (g->tobefnz && !g->gcemergency) { + g->gcstopem = 0; /* ok collections during finalizers */ + work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST; + } + else { /* emergency mode or no more finalizers */ + g->gcstate = GCSpause; /* finish collection */ + work = 0; + } + break; + } + default: lua_assert(0); return 0; + } + g->gcstopem = 0; + return work; +} + + +/* +** advances the garbage collector until it reaches a state allowed +** by 'statemask' +*/ +void luaC_runtilstate (lua_State *L, int statesmask) { + global_State *g = G(L); + while (!testbit(statesmask, g->gcstate)) + singlestep(L); +} + + + +/* +** Performs a basic incremental step. The debt and step size are +** converted from bytes to "units of work"; then the function loops +** running single steps until adding that many units of work or +** finishing a cycle (pause state). Finally, it sets the debt that +** controls when next step will be performed. +*/ +static void incstep (lua_State *L, global_State *g) { + int stepmul = (getgcparam(g->gcstepmul) | 1); /* avoid division by 0 */ + l_mem debt = (g->GCdebt / WORK2MEM) * stepmul; + l_mem stepsize = (g->gcstepsize <= log2maxs(l_mem)) + ? ((cast(l_mem, 1) << g->gcstepsize) / WORK2MEM) * stepmul + : MAX_LMEM; /* overflow; keep maximum value */ + do { /* repeat until pause or enough "credit" (negative debt) */ + lu_mem work = singlestep(L); /* perform one single step */ + debt -= work; + } while (debt > -stepsize && g->gcstate != GCSpause); + if (g->gcstate == GCSpause) + setpause(g); /* pause until next cycle */ + else { + debt = (debt / stepmul) * WORK2MEM; /* convert 'work units' to bytes */ + luaE_setdebt(g, debt); + } +} + +/* +** Performs a basic GC step if collector is running. (If collector is +** not running, set a reasonable debt to avoid it being called at +** every single check.) +*/ +void luaC_step (lua_State *L) { + global_State *g = G(L); + if (!gcrunning(g)) /* not running? */ + luaE_setdebt(g, -2000); + else { + if(isdecGCmodegen(g)) + genstep(L, g); + else + incstep(L, g); + } +} + + +/* +** Perform a full collection in incremental mode. +** Before running the collection, check 'keepinvariant'; if it is true, +** there may be some objects marked as black, so the collector has +** to sweep all objects to turn them back to white (as white has not +** changed, nothing will be collected). +*/ +static void fullinc (lua_State *L, global_State *g) { + if (keepinvariant(g)) /* black objects? */ + entersweep(L); /* sweep everything to turn them back to white */ + /* finish any pending sweep phase to start a new cycle */ + luaC_runtilstate(L, bitmask(GCSpause)); + luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ + g->gcstate = GCSenteratomic; /* go straight to atomic phase */ + luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ + /* estimate must be correct after a full GC cycle */ + lua_assert(g->GCestimate == gettotalbytes(g)); + luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ + setpause(g); +} + + +/* +** Performs a full GC cycle; if 'isemergency', set a flag to avoid +** some operations which could change the interpreter state in some +** unexpected ways (running finalizers and shrinking some structures). +*/ +void luaC_fullgc (lua_State *L, int isemergency) { + global_State *g = G(L); + lua_assert(!g->gcemergency); + g->gcemergency = isemergency; /* set flag */ + if (g->gckind == KGC_INC) + fullinc(L, g); + else + fullgen(L, g); + g->gcemergency = 0; +} + +/* }====================================================== */ + + diff --git a/User/system/lua/src/lgc.h b/User/system/lua/src/lgc.h new file mode 100644 index 0000000..538f6ed --- /dev/null +++ b/User/system/lua/src/lgc.h @@ -0,0 +1,202 @@ +/* +** $Id: lgc.h $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" +#include "lstate.h" + +/* +** Collectable objects may have one of three colors: white, which means +** the object is not marked; gray, which means the object is marked, but +** its references may be not marked; and black, which means that the +** object and all its references are marked. The main invariant of the +** garbage collector, while marking objects, is that a black object can +** never point to a white one. Moreover, any gray object must be in a +** "gray list" (gray, grayagain, weak, allweak, ephemeron) so that it +** can be visited again before finishing the collection cycle. (Open +** upvalues are an exception to this rule.) These lists have no meaning +** when the invariant is not being enforced (e.g., sweep phase). +*/ + + +/* +** Possible states of the Garbage Collector +*/ +#define GCSpropagate 0 +#define GCSenteratomic 1 +#define GCSatomic 2 +#define GCSswpallgc 3 +#define GCSswpfinobj 4 +#define GCSswptobefnz 5 +#define GCSswpend 6 +#define GCScallfin 7 +#define GCSpause 8 + + +#define issweepphase(g) \ + (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) + + +/* +** macro to tell when main invariant (white objects cannot point to black +** ones) must be kept. During a collection, the sweep +** phase may break the invariant, as objects turned white may point to +** still-black objects. The invariant is restored when sweep ends and +** all objects are white again. +*/ + +#define keepinvariant(g) ((g)->gcstate <= GCSatomic) + + +/* +** some useful bit tricks +*/ +#define resetbits(x,m) ((x) &= cast_byte(~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) + + +/* +** Layout for bit use in 'marked' field. First three bits are +** used for object "age" in generational mode. Last bit is used +** by tests. +*/ +#define WHITE0BIT 3 /* object is white (type 0) */ +#define WHITE1BIT 4 /* object is white (type 1) */ +#define BLACKBIT 5 /* object is black */ +#define FINALIZEDBIT 6 /* object has been marked for finalization */ + +#define TESTBIT 7 + + + +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) + + +#define iswhite(x) testbits((x)->marked, WHITEBITS) +#define isblack(x) testbit((x)->marked, BLACKBIT) +#define isgray(x) /* neither white nor black */ \ + (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) + +#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) + +#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) +#define isdeadm(ow,m) ((m) & (ow)) +#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) + +#define changewhite(x) ((x)->marked ^= WHITEBITS) +#define nw2black(x) \ + check_exp(!iswhite(x), l_setbit((x)->marked, BLACKBIT)) + +#define luaC_white(g) cast_byte((g)->currentwhite & WHITEBITS) + + +/* object age in generational mode */ +#define G_NEW 0 /* created in current cycle */ +#define G_SURVIVAL 1 /* created in previous cycle */ +#define G_OLD0 2 /* marked old by frw. barrier in this cycle */ +#define G_OLD1 3 /* first full cycle as old */ +#define G_OLD 4 /* really old object (not to be visited) */ +#define G_TOUCHED1 5 /* old object touched this cycle */ +#define G_TOUCHED2 6 /* old object touched in previous cycle */ + +#define AGEBITS 7 /* all age bits (111) */ + +#define getage(o) ((o)->marked & AGEBITS) +#define setage(o,a) ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a)) +#define isold(o) (getage(o) > G_SURVIVAL) + +#define changeage(o,f,t) \ + check_exp(getage(o) == (f), (o)->marked ^= ((f)^(t))) + + +/* Default Values for GC parameters */ +#define LUAI_GENMAJORMUL 100 +#define LUAI_GENMINORMUL 20 + +/* wait memory to double before starting new cycle */ +#define LUAI_GCPAUSE 200 + +/* +** some gc parameters are stored divided by 4 to allow a maximum value +** up to 1023 in a 'lu_byte'. +*/ +#define getgcparam(p) ((p) * 4) +#define setgcparam(p,v) ((p) = (v) / 4) + +#define LUAI_GCMUL 100 + +/* how much to allocate before next GC step (log2) */ +#define LUAI_GCSTEPSIZE 13 /* 8 KB */ + + +/* +** Check whether the declared GC mode is generational. While in +** generational mode, the collector can go temporarily to incremental +** mode to improve performance. This is signaled by 'g->lastatomic != 0'. +*/ +#define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0) + + +/* +** Control when GC is running: +*/ +#define GCSTPUSR 1 /* bit true when GC stopped by user */ +#define GCSTPGC 2 /* bit true when GC stopped by itself */ +#define GCSTPCLS 4 /* bit true when closing Lua state */ +#define gcrunning(g) ((g)->gcstp == 0) + + +/* +** Does one step of collection when debt becomes positive. 'pre'/'pos' +** allows some adjustments to be done only when needed. macro +** 'condchangemem' is used only for heavy tests (forcing a full +** GC cycle on every opportunity) +*/ +#define luaC_condGC(L,pre,pos) \ + { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ + condchangemem(L,pre,pos); } + +/* more often than not, 'pre'/'pos' are empty */ +#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0) + + +#define luaC_objbarrier(L,p,o) ( \ + (isblack(p) && iswhite(o)) ? \ + luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) + +#define luaC_barrier(L,p,v) ( \ + iscollectable(v) ? luaC_objbarrier(L,p,gcvalue(v)) : cast_void(0)) + +#define luaC_objbarrierback(L,p,o) ( \ + (isblack(p) && iswhite(o)) ? luaC_barrierback_(L,p) : cast_void(0)) + +#define luaC_barrierback(L,p,v) ( \ + iscollectable(v) ? luaC_objbarrierback(L, p, gcvalue(v)) : cast_void(0)) + +LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); +LUAI_FUNC void luaC_freeallobjects (lua_State *L); +LUAI_FUNC void luaC_step (lua_State *L); +LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); +LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); +LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); +LUAI_FUNC GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz, + size_t offset); +LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); +LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); +LUAI_FUNC void luaC_changemode (lua_State *L, int newmode); + + +#endif diff --git a/User/system/lua/src/linit.c b/User/system/lua/src/linit.c new file mode 100644 index 0000000..69808f8 --- /dev/null +++ b/User/system/lua/src/linit.c @@ -0,0 +1,65 @@ +/* +** $Id: linit.c $ +** Initialization of libraries for lua.c and other clients +** See Copyright Notice in lua.h +*/ + + +#define linit_c +#define LUA_LIB + +/* +** If you embed Lua in your program and need to open the standard +** libraries, call luaL_openlibs in your program. If you need a +** different set of libraries, copy this file to your project and edit +** it to suit your needs. +** +** You can also *preload* libraries, so that a later 'require' can +** open the library, which is already linked to the application. +** For that, do the following code: +** +** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); +** lua_pushcfunction(L, luaopen_modname); +** lua_setfield(L, -2, modname); +** lua_pop(L, 1); // remove PRELOAD table +*/ + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "lualib.h" +#include "lauxlib.h" + + +/* +** these libs are loaded by lua.c and are readily available to any Lua +** program +*/ +static const luaL_Reg loadedlibs[] = { + {LUA_GNAME, luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_COLIBNAME, luaopen_coroutine}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_UTF8LIBNAME, luaopen_utf8}, + {LUA_DBLIBNAME, luaopen_debug}, + {NULL, NULL} +}; + + +LUALIB_API void luaL_openlibs (lua_State *L) { + const luaL_Reg *lib; + /* "require" functions from 'loadedlibs' and set results to global table */ + for (lib = loadedlibs; lib->func; lib++) { + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); /* remove lib */ + } +} + diff --git a/User/system/lua/src/liolib.c b/User/system/lua/src/liolib.c new file mode 100644 index 0000000..c5075f3 --- /dev/null +++ b/User/system/lua/src/liolib.c @@ -0,0 +1,841 @@ +/* +** $Id: liolib.c $ +** Standard I/O (and system) library +** See Copyright Notice in lua.h +*/ + +#define liolib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + + +/* +** Change this macro to accept other modes for 'fopen' besides +** the standard ones. +*/ +#if !defined(l_checkmode) + +/* accepted extensions to 'mode' in 'fopen' */ +#if !defined(L_MODEEXT) +#define L_MODEEXT "b" +#endif + +/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */ +static int l_checkmode (const char *mode) { + return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && + (*mode != '+' || ((void)(++mode), 1)) && /* skip if char is '+' */ + (strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */ +} + +#endif + +/* +** {====================================================== +** l_popen spawns a new process connected to the current +** one through the file streams. +** ======================================================= +*/ + +#if !defined(l_popen) /* { */ + +#if defined(LUA_USE_POSIX) /* { */ + +#define l_popen(L,c,m) (fflush(NULL), popen(c,m)) +#define l_pclose(L,file) (pclose(file)) + +#elif defined(LUA_USE_WINDOWS) /* }{ */ + +#define l_popen(L,c,m) (_popen(c,m)) +#define l_pclose(L,file) (_pclose(file)) + +#if !defined(l_checkmodep) +/* Windows accepts "[rw][bt]?" as valid modes */ +#define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && \ + (m[1] == '\0' || ((m[1] == 'b' || m[1] == 't') && m[2] == '\0'))) +#endif + +#else /* }{ */ + +/* ISO C definitions */ +#define l_popen(L,c,m) \ + ((void)c, (void)m, \ + luaL_error(L, "'popen' not supported"), \ + (FILE*)0) +#define l_pclose(L,file) ((void)L, (void)file, -1) + +#endif /* } */ + +#endif /* } */ + + +#if !defined(l_checkmodep) +/* By default, Lua accepts only "r" or "w" as valid modes */ +#define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && m[1] == '\0') +#endif + +/* }====================================================== */ + + +#if !defined(l_getc) /* { */ + +#if defined(LUA_USE_POSIX) +#define l_getc(f) getc_unlocked(f) +#define l_lockfile(f) flockfile(f) +#define l_unlockfile(f) funlockfile(f) +#else +#define l_getc(f) getc(f) +#define l_lockfile(f) ((void)0) +#define l_unlockfile(f) ((void)0) +#endif + +#endif /* } */ + + +/* +** {====================================================== +** l_fseek: configuration for longer offsets +** ======================================================= +*/ + +#if !defined(l_fseek) /* { */ + +#if defined(LUA_USE_POSIX) /* { */ + +#include + +#define l_fseek(f,o,w) fseeko(f,o,w) +#define l_ftell(f) ftello(f) +#define l_seeknum off_t + +#elif defined(LUA_USE_WINDOWS) && !defined(_CRTIMP_TYPEINFO) \ + && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */ + +/* Windows (but not DDK) and Visual C++ 2005 or higher */ +#define l_fseek(f,o,w) _fseeki64(f,o,w) +#define l_ftell(f) _ftelli64(f) +#define l_seeknum __int64 + +#else /* }{ */ + +/* ISO C definitions */ +#define l_fseek(f,o,w) fseek(f,o,w) +#define l_ftell(f) ftell(f) +#define l_seeknum long + +#endif /* } */ + +#endif /* } */ + +/* }====================================================== */ + + + +#define IO_PREFIX "_IO_" +#define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1) +#define IO_INPUT (IO_PREFIX "input") +#define IO_OUTPUT (IO_PREFIX "output") + + +typedef luaL_Stream LStream; + + +#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) + +#define isclosed(p) ((p)->closef == NULL) + + +static int io_type (lua_State *L) { + LStream *p; + luaL_checkany(L, 1); + p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE); + if (p == NULL) + luaL_pushfail(L); /* not a file */ + else if (isclosed(p)) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; +} + + +static int f_tostring (lua_State *L) { + LStream *p = tolstream(L); + if (isclosed(p)) + lua_pushliteral(L, "file (closed)"); + else + lua_pushfstring(L, "file (%p)", p->f); + return 1; +} + + +static FILE *tofile (lua_State *L) { + LStream *p = tolstream(L); + if (l_unlikely(isclosed(p))) + luaL_error(L, "attempt to use a closed file"); + lua_assert(p->f); + return p->f; +} + + +/* +** When creating file handles, always creates a 'closed' file handle +** before opening the actual file; so, if there is a memory error, the +** handle is in a consistent state. +*/ +static LStream *newprefile (lua_State *L) { + LStream *p = (LStream *)lua_newuserdatauv(L, sizeof(LStream), 0); + p->closef = NULL; /* mark file handle as 'closed' */ + luaL_setmetatable(L, LUA_FILEHANDLE); + return p; +} + + +/* +** Calls the 'close' function from a file handle. The 'volatile' avoids +** a bug in some versions of the Clang compiler (e.g., clang 3.0 for +** 32 bits). +*/ +static int aux_close (lua_State *L) { + LStream *p = tolstream(L); + volatile lua_CFunction cf = p->closef; + p->closef = NULL; /* mark stream as closed */ + return (*cf)(L); /* close it */ +} + + +static int f_close (lua_State *L) { + tofile(L); /* make sure argument is an open stream */ + return aux_close(L); +} + + +static int io_close (lua_State *L) { + if (lua_isnone(L, 1)) /* no argument? */ + lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use default output */ + return f_close(L); +} + + +static int f_gc (lua_State *L) { + LStream *p = tolstream(L); + if (!isclosed(p) && p->f != NULL) + aux_close(L); /* ignore closed and incompletely open files */ + return 0; +} + + +/* +** function to close regular files +*/ +static int io_fclose (lua_State *L) { + LStream *p = tolstream(L); + errno = 0; + return luaL_fileresult(L, (fclose(p->f) == 0), NULL); +} + + +static LStream *newfile (lua_State *L) { + LStream *p = newprefile(L); + p->f = NULL; + p->closef = &io_fclose; + return p; +} + + +static void opencheck (lua_State *L, const char *fname, const char *mode) { + LStream *p = newfile(L); + p->f = fopen(fname, mode); + if (l_unlikely(p->f == NULL)) + luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno)); +} + + +static int io_open (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + LStream *p = newfile(L); + const char *md = mode; /* to traverse/check mode */ + luaL_argcheck(L, l_checkmode(md), 2, "invalid mode"); + errno = 0; + p->f = fopen(filename, mode); + return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; +} + + +/* +** function to close 'popen' files +*/ +static int io_pclose (lua_State *L) { + LStream *p = tolstream(L); + errno = 0; + return luaL_execresult(L, l_pclose(L, p->f)); +} + + +static int io_popen (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + LStream *p = newprefile(L); + luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode"); + errno = 0; + p->f = l_popen(L, filename, mode); + p->closef = &io_pclose; + return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; +} + + +static int io_tmpfile (lua_State *L) { + LStream *p = newfile(L); + errno = 0; + p->f = tmpfile(); + return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1; +} + + +static FILE *getiofile (lua_State *L, const char *findex) { + LStream *p; + lua_getfield(L, LUA_REGISTRYINDEX, findex); + p = (LStream *)lua_touserdata(L, -1); + if (l_unlikely(isclosed(p))) + luaL_error(L, "default %s file is closed", findex + IOPREF_LEN); + return p->f; +} + + +static int g_iofile (lua_State *L, const char *f, const char *mode) { + if (!lua_isnoneornil(L, 1)) { + const char *filename = lua_tostring(L, 1); + if (filename) + opencheck(L, filename, mode); + else { + tofile(L); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + lua_setfield(L, LUA_REGISTRYINDEX, f); + } + /* return current value */ + lua_getfield(L, LUA_REGISTRYINDEX, f); + return 1; +} + + +static int io_input (lua_State *L) { + return g_iofile(L, IO_INPUT, "r"); +} + + +static int io_output (lua_State *L) { + return g_iofile(L, IO_OUTPUT, "w"); +} + + +static int io_readline (lua_State *L); + + +/* +** maximum number of arguments to 'f:lines'/'io.lines' (it + 3 must fit +** in the limit for upvalues of a closure) +*/ +#define MAXARGLINE 250 + +/* +** Auxiliary function to create the iteration function for 'lines'. +** The iteration function is a closure over 'io_readline', with +** the following upvalues: +** 1) The file being read (first value in the stack) +** 2) the number of arguments to read +** 3) a boolean, true iff file has to be closed when finished ('toclose') +** *) a variable number of format arguments (rest of the stack) +*/ +static void aux_lines (lua_State *L, int toclose) { + int n = lua_gettop(L) - 1; /* number of arguments to read */ + luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments"); + lua_pushvalue(L, 1); /* file */ + lua_pushinteger(L, n); /* number of arguments to read */ + lua_pushboolean(L, toclose); /* close/not close file when finished */ + lua_rotate(L, 2, 3); /* move the three values to their positions */ + lua_pushcclosure(L, io_readline, 3 + n); +} + + +static int f_lines (lua_State *L) { + tofile(L); /* check that it's a valid file handle */ + aux_lines(L, 0); + return 1; +} + + +/* +** Return an iteration function for 'io.lines'. If file has to be +** closed, also returns the file itself as a second result (to be +** closed as the state at the exit of a generic for). +*/ +static int io_lines (lua_State *L) { + int toclose; + if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ + if (lua_isnil(L, 1)) { /* no file name? */ + lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */ + lua_replace(L, 1); /* put it at index 1 */ + tofile(L); /* check that it's a valid file handle */ + toclose = 0; /* do not close it after iteration */ + } + else { /* open a new file */ + const char *filename = luaL_checkstring(L, 1); + opencheck(L, filename, "r"); + lua_replace(L, 1); /* put file at index 1 */ + toclose = 1; /* close it after iteration */ + } + aux_lines(L, toclose); /* push iteration function */ + if (toclose) { + lua_pushnil(L); /* state */ + lua_pushnil(L); /* control */ + lua_pushvalue(L, 1); /* file is the to-be-closed variable (4th result) */ + return 4; + } + else + return 1; +} + + +/* +** {====================================================== +** READ +** ======================================================= +*/ + + +/* maximum length of a numeral */ +#if !defined (L_MAXLENNUM) +#define L_MAXLENNUM 200 +#endif + + +/* auxiliary structure used by 'read_number' */ +typedef struct { + FILE *f; /* file being read */ + int c; /* current character (look ahead) */ + int n; /* number of elements in buffer 'buff' */ + char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */ +} RN; + + +/* +** Add current char to buffer (if not out of space) and read next one +*/ +static int nextc (RN *rn) { + if (l_unlikely(rn->n >= L_MAXLENNUM)) { /* buffer overflow? */ + rn->buff[0] = '\0'; /* invalidate result */ + return 0; /* fail */ + } + else { + rn->buff[rn->n++] = rn->c; /* save current char */ + rn->c = l_getc(rn->f); /* read next one */ + return 1; + } +} + + +/* +** Accept current char if it is in 'set' (of size 2) +*/ +static int test2 (RN *rn, const char *set) { + if (rn->c == set[0] || rn->c == set[1]) + return nextc(rn); + else return 0; +} + + +/* +** Read a sequence of (hex)digits +*/ +static int readdigits (RN *rn, int hex) { + int count = 0; + while ((hex ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn)) + count++; + return count; +} + + +/* +** Read a number: first reads a valid prefix of a numeral into a buffer. +** Then it calls 'lua_stringtonumber' to check whether the format is +** correct and to convert it to a Lua number. +*/ +static int read_number (lua_State *L, FILE *f) { + RN rn; + int count = 0; + int hex = 0; + char decp[2]; + rn.f = f; rn.n = 0; + decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */ + decp[1] = '.'; /* always accept a dot */ + l_lockfile(rn.f); + do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */ + test2(&rn, "-+"); /* optional sign */ + if (test2(&rn, "00")) { + if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */ + else count = 1; /* count initial '0' as a valid digit */ + } + count += readdigits(&rn, hex); /* integral part */ + if (test2(&rn, decp)) /* decimal point? */ + count += readdigits(&rn, hex); /* fractional part */ + if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */ + test2(&rn, "-+"); /* exponent sign */ + readdigits(&rn, 0); /* exponent digits */ + } + ungetc(rn.c, rn.f); /* unread look-ahead char */ + l_unlockfile(rn.f); + rn.buff[rn.n] = '\0'; /* finish string */ + if (l_likely(lua_stringtonumber(L, rn.buff))) + return 1; /* ok, it is a valid number */ + else { /* invalid format */ + lua_pushnil(L); /* "result" to be removed */ + return 0; /* read fails */ + } +} + + +static int test_eof (lua_State *L, FILE *f) { + int c = getc(f); + ungetc(c, f); /* no-op when c == EOF */ + lua_pushliteral(L, ""); + return (c != EOF); +} + + +static int read_line (lua_State *L, FILE *f, int chop) { + luaL_Buffer b; + int c; + luaL_buffinit(L, &b); + do { /* may need to read several chunks to get whole line */ + char *buff = luaL_prepbuffer(&b); /* preallocate buffer space */ + int i = 0; + l_lockfile(f); /* no memory errors can happen inside the lock */ + while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n') + buff[i++] = c; /* read up to end of line or buffer limit */ + l_unlockfile(f); + luaL_addsize(&b, i); + } while (c != EOF && c != '\n'); /* repeat until end of line */ + if (!chop && c == '\n') /* want a newline and have one? */ + luaL_addchar(&b, c); /* add ending newline to result */ + luaL_pushresult(&b); /* close buffer */ + /* return ok if read something (either a newline or something else) */ + return (c == '\n' || lua_rawlen(L, -1) > 0); +} + + +static void read_all (lua_State *L, FILE *f) { + size_t nr; + luaL_Buffer b; + luaL_buffinit(L, &b); + do { /* read file in chunks of LUAL_BUFFERSIZE bytes */ + char *p = luaL_prepbuffer(&b); + nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f); + luaL_addsize(&b, nr); + } while (nr == LUAL_BUFFERSIZE); + luaL_pushresult(&b); /* close buffer */ +} + + +static int read_chars (lua_State *L, FILE *f, size_t n) { + size_t nr; /* number of chars actually read */ + char *p; + luaL_Buffer b; + luaL_buffinit(L, &b); + p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */ + nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */ + luaL_addsize(&b, nr); + luaL_pushresult(&b); /* close buffer */ + return (nr > 0); /* true iff read something */ +} + + +static int g_read (lua_State *L, FILE *f, int first) { + int nargs = lua_gettop(L) - 1; + int n, success; + clearerr(f); + errno = 0; + if (nargs == 0) { /* no arguments? */ + success = read_line(L, f, 1); + n = first + 1; /* to return 1 result */ + } + else { + /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) { + if (lua_type(L, n) == LUA_TNUMBER) { + size_t l = (size_t)luaL_checkinteger(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } + else { + const char *p = luaL_checkstring(L, n); + if (*p == '*') p++; /* skip optional '*' (for compatibility) */ + switch (*p) { + case 'n': /* number */ + success = read_number(L, f); + break; + case 'l': /* line */ + success = read_line(L, f, 1); + break; + case 'L': /* line with end-of-line */ + success = read_line(L, f, 0); + break; + case 'a': /* file */ + read_all(L, f); /* read entire file */ + success = 1; /* always success */ + break; + default: + return luaL_argerror(L, n, "invalid format"); + } + } + } + } + if (ferror(f)) + return luaL_fileresult(L, 0, NULL); + if (!success) { + lua_pop(L, 1); /* remove last result */ + luaL_pushfail(L); /* push nil instead */ + } + return n - first; +} + + +static int io_read (lua_State *L) { + return g_read(L, getiofile(L, IO_INPUT), 1); +} + + +static int f_read (lua_State *L) { + return g_read(L, tofile(L), 2); +} + + +/* +** Iteration function for 'lines'. +*/ +static int io_readline (lua_State *L) { + LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); + int i; + int n = (int)lua_tointeger(L, lua_upvalueindex(2)); + if (isclosed(p)) /* file is already closed? */ + return luaL_error(L, "file is already closed"); + lua_settop(L , 1); + luaL_checkstack(L, n, "too many arguments"); + for (i = 1; i <= n; i++) /* push arguments to 'g_read' */ + lua_pushvalue(L, lua_upvalueindex(3 + i)); + n = g_read(L, p->f, 2); /* 'n' is number of results */ + lua_assert(n > 0); /* should return at least a nil */ + if (lua_toboolean(L, -n)) /* read at least one value? */ + return n; /* return them */ + else { /* first result is false: EOF or error */ + if (n > 1) { /* is there error information? */ + /* 2nd result is error message */ + return luaL_error(L, "%s", lua_tostring(L, -n + 1)); + } + if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ + lua_settop(L, 0); /* clear stack */ + lua_pushvalue(L, lua_upvalueindex(1)); /* push file at index 1 */ + aux_close(L); /* close it */ + } + return 0; + } +} + +/* }====================================================== */ + + +static int g_write (lua_State *L, FILE *f, int arg) { + int nargs = lua_gettop(L) - arg; + int status = 1; + errno = 0; + for (; nargs--; arg++) { + if (lua_type(L, arg) == LUA_TNUMBER) { + /* optimization: could be done exactly as for strings */ + int len = lua_isinteger(L, arg) + ? fprintf(f, LUA_INTEGER_FMT, + (LUAI_UACINT)lua_tointeger(L, arg)) + : fprintf(f, LUA_NUMBER_FMT, + (LUAI_UACNUMBER)lua_tonumber(L, arg)); + status = status && (len > 0); + } + else { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + status = status && (fwrite(s, sizeof(char), l, f) == l); + } + } + if (l_likely(status)) + return 1; /* file handle already on stack top */ + else + return luaL_fileresult(L, status, NULL); +} + + +static int io_write (lua_State *L) { + return g_write(L, getiofile(L, IO_OUTPUT), 1); +} + + +static int f_write (lua_State *L) { + FILE *f = tofile(L); + lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ + return g_write(L, f, 2); +} + + +static int f_seek (lua_State *L) { + static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, "cur", modenames); + lua_Integer p3 = luaL_optinteger(L, 3, 0); + l_seeknum offset = (l_seeknum)p3; + luaL_argcheck(L, (lua_Integer)offset == p3, 3, + "not an integer in proper range"); + errno = 0; + op = l_fseek(f, offset, mode[op]); + if (l_unlikely(op)) + return luaL_fileresult(L, 0, NULL); /* error */ + else { + lua_pushinteger(L, (lua_Integer)l_ftell(f)); + return 1; + } +} + + +static int f_setvbuf (lua_State *L) { + static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; + static const char *const modenames[] = {"no", "full", "line", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, NULL, modenames); + lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); + int res; + errno = 0; + res = setvbuf(f, NULL, mode[op], (size_t)sz); + return luaL_fileresult(L, res == 0, NULL); +} + + + +static int io_flush (lua_State *L) { + FILE *f = getiofile(L, IO_OUTPUT); + errno = 0; + return luaL_fileresult(L, fflush(f) == 0, NULL); +} + + +static int f_flush (lua_State *L) { + FILE *f = tofile(L); + errno = 0; + return luaL_fileresult(L, fflush(f) == 0, NULL); +} + + +/* +** functions for 'io' library +*/ +static const luaL_Reg iolib[] = { + {"close", io_close}, + {"flush", io_flush}, + {"input", io_input}, + {"lines", io_lines}, + {"open", io_open}, + {"output", io_output}, + {"popen", io_popen}, + {"read", io_read}, + {"tmpfile", io_tmpfile}, + {"type", io_type}, + {"write", io_write}, + {NULL, NULL} +}; + + +/* +** methods for file handles +*/ +static const luaL_Reg meth[] = { + {"read", f_read}, + {"write", f_write}, + {"lines", f_lines}, + {"flush", f_flush}, + {"seek", f_seek}, + {"close", f_close}, + {"setvbuf", f_setvbuf}, + {NULL, NULL} +}; + + +/* +** metamethods for file handles +*/ +static const luaL_Reg metameth[] = { + {"__index", NULL}, /* placeholder */ + {"__gc", f_gc}, + {"__close", f_gc}, + {"__tostring", f_tostring}, + {NULL, NULL} +}; + + +static void createmeta (lua_State *L) { + luaL_newmetatable(L, LUA_FILEHANDLE); /* metatable for file handles */ + luaL_setfuncs(L, metameth, 0); /* add metamethods to new metatable */ + luaL_newlibtable(L, meth); /* create method table */ + luaL_setfuncs(L, meth, 0); /* add file methods to method table */ + lua_setfield(L, -2, "__index"); /* metatable.__index = method table */ + lua_pop(L, 1); /* pop metatable */ +} + + +/* +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + LStream *p = tolstream(L); + p->closef = &io_noclose; /* keep file opened */ + luaL_pushfail(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +static void createstdfile (lua_State *L, FILE *f, const char *k, + const char *fname) { + LStream *p = newprefile(L); + p->f = f; + p->closef = &io_noclose; + if (k != NULL) { + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */ + } + lua_setfield(L, -2, fname); /* add file to module */ +} + + +LUAMOD_API int luaopen_io (lua_State *L) { + luaL_newlib(L, iolib); /* new module */ + createmeta(L); + /* create (and set) default files */ + createstdfile(L, stdin, IO_INPUT, "stdin"); + createstdfile(L, stdout, IO_OUTPUT, "stdout"); + createstdfile(L, stderr, NULL, "stderr"); + return 1; +} + diff --git a/User/system/lua/src/ljumptab.h b/User/system/lua/src/ljumptab.h new file mode 100644 index 0000000..8306f25 --- /dev/null +++ b/User/system/lua/src/ljumptab.h @@ -0,0 +1,112 @@ +/* +** $Id: ljumptab.h $ +** Jump Table for the Lua interpreter +** See Copyright Notice in lua.h +*/ + + +#undef vmdispatch +#undef vmcase +#undef vmbreak + +#define vmdispatch(x) goto *disptab[x]; + +#define vmcase(l) L_##l: + +#define vmbreak vmfetch(); vmdispatch(GET_OPCODE(i)); + + +static const void *const disptab[NUM_OPCODES] = { + +#if 0 +** you can update the following list with this command: +** +** sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h +** +#endif + +&&L_OP_MOVE, +&&L_OP_LOADI, +&&L_OP_LOADF, +&&L_OP_LOADK, +&&L_OP_LOADKX, +&&L_OP_LOADFALSE, +&&L_OP_LFALSESKIP, +&&L_OP_LOADTRUE, +&&L_OP_LOADNIL, +&&L_OP_GETUPVAL, +&&L_OP_SETUPVAL, +&&L_OP_GETTABUP, +&&L_OP_GETTABLE, +&&L_OP_GETI, +&&L_OP_GETFIELD, +&&L_OP_SETTABUP, +&&L_OP_SETTABLE, +&&L_OP_SETI, +&&L_OP_SETFIELD, +&&L_OP_NEWTABLE, +&&L_OP_SELF, +&&L_OP_ADDI, +&&L_OP_ADDK, +&&L_OP_SUBK, +&&L_OP_MULK, +&&L_OP_MODK, +&&L_OP_POWK, +&&L_OP_DIVK, +&&L_OP_IDIVK, +&&L_OP_BANDK, +&&L_OP_BORK, +&&L_OP_BXORK, +&&L_OP_SHRI, +&&L_OP_SHLI, +&&L_OP_ADD, +&&L_OP_SUB, +&&L_OP_MUL, +&&L_OP_MOD, +&&L_OP_POW, +&&L_OP_DIV, +&&L_OP_IDIV, +&&L_OP_BAND, +&&L_OP_BOR, +&&L_OP_BXOR, +&&L_OP_SHL, +&&L_OP_SHR, +&&L_OP_MMBIN, +&&L_OP_MMBINI, +&&L_OP_MMBINK, +&&L_OP_UNM, +&&L_OP_BNOT, +&&L_OP_NOT, +&&L_OP_LEN, +&&L_OP_CONCAT, +&&L_OP_CLOSE, +&&L_OP_TBC, +&&L_OP_JMP, +&&L_OP_EQ, +&&L_OP_LT, +&&L_OP_LE, +&&L_OP_EQK, +&&L_OP_EQI, +&&L_OP_LTI, +&&L_OP_LEI, +&&L_OP_GTI, +&&L_OP_GEI, +&&L_OP_TEST, +&&L_OP_TESTSET, +&&L_OP_CALL, +&&L_OP_TAILCALL, +&&L_OP_RETURN, +&&L_OP_RETURN0, +&&L_OP_RETURN1, +&&L_OP_FORLOOP, +&&L_OP_FORPREP, +&&L_OP_TFORPREP, +&&L_OP_TFORCALL, +&&L_OP_TFORLOOP, +&&L_OP_SETLIST, +&&L_OP_CLOSURE, +&&L_OP_VARARG, +&&L_OP_VARARGPREP, +&&L_OP_EXTRAARG + +}; diff --git a/User/system/lua/src/llex.c b/User/system/lua/src/llex.c new file mode 100644 index 0000000..5fc39a5 --- /dev/null +++ b/User/system/lua/src/llex.c @@ -0,0 +1,581 @@ +/* +** $Id: llex.c $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#define llex_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lctype.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lzio.h" + + + +#define next(ls) (ls->current = zgetc(ls->z)) + + + +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') + + +/* ORDER RESERVED */ +static const char *const luaX_tokens [] = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "goto", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "//", "..", "...", "==", ">=", "<=", "~=", + "<<", ">>", "::", "", + "", "", "", "" +}; + + +#define save_and_next(ls) (save(ls, ls->current), next(ls)) + + +static l_noret lexerror (LexState *ls, const char *msg, int token); + + +static void save (LexState *ls, int c) { + Mbuffer *b = ls->buff; + if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) { + size_t newsize; + if (luaZ_sizebuffer(b) >= MAX_SIZE/2) + lexerror(ls, "lexical element too long", 0); + newsize = luaZ_sizebuffer(b) * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[luaZ_bufflen(b)++] = cast_char(c); +} + + +void luaX_init (lua_State *L) { + int i; + TString *e = luaS_newliteral(L, LUA_ENV); /* create env name */ + luaC_fix(L, obj2gco(e)); /* never collect this name */ + for (i=0; iextra = cast_byte(i+1); /* reserved word */ + } +} + + +const char *luaX_token2str (LexState *ls, int token) { + if (token < FIRST_RESERVED) { /* single-byte symbols? */ + if (lisprint(token)) + return luaO_pushfstring(ls->L, "'%c'", token); + else /* control character */ + return luaO_pushfstring(ls->L, "'<\\%d>'", token); + } + else { + const char *s = luaX_tokens[token - FIRST_RESERVED]; + if (token < TK_EOS) /* fixed format (symbols and reserved words)? */ + return luaO_pushfstring(ls->L, "'%s'", s); + else /* names, strings, and numerals */ + return s; + } +} + + +static const char *txtToken (LexState *ls, int token) { + switch (token) { + case TK_NAME: case TK_STRING: + case TK_FLT: case TK_INT: + save(ls, '\0'); + return luaO_pushfstring(ls->L, "'%s'", luaZ_buffer(ls->buff)); + default: + return luaX_token2str(ls, token); + } +} + + +static l_noret lexerror (LexState *ls, const char *msg, int token) { + msg = luaG_addinfo(ls->L, msg, ls->source, ls->linenumber); + if (token) + luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token)); + luaD_throw(ls->L, LUA_ERRSYNTAX); +} + + +l_noret luaX_syntaxerror (LexState *ls, const char *msg) { + lexerror(ls, msg, ls->t.token); +} + + +/* +** Creates a new string and anchors it in scanner's table so that it +** will not be collected until the end of the compilation; by that time +** it should be anchored somewhere. It also internalizes long strings, +** ensuring there is only one copy of each unique string. The table +** here is used as a set: the string enters as the key, while its value +** is irrelevant. We use the string itself as the value only because it +** is a TValue readily available. Later, the code generation can change +** this value. +*/ +TString *luaX_newstring (LexState *ls, const char *str, size_t l) { + lua_State *L = ls->L; + TString *ts = luaS_newlstr(L, str, l); /* create new string */ + const TValue *o = luaH_getstr(ls->h, ts); + if (!ttisnil(o)) /* string already present? */ + ts = keystrval(nodefromval(o)); /* get saved copy */ + else { /* not in use yet */ + TValue *stv = s2v(L->top.p++); /* reserve stack space for string */ + setsvalue(L, stv, ts); /* temporarily anchor the string */ + luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */ + /* table is not a metatable, so it does not need to invalidate cache */ + luaC_checkGC(L); + L->top.p--; /* remove string from stack */ + } + return ts; +} + + +/* +** increment line number and skips newline sequence (any of +** \n, \r, \n\r, or \r\n) +*/ +static void inclinenumber (LexState *ls) { + int old = ls->current; + lua_assert(currIsNewline(ls)); + next(ls); /* skip '\n' or '\r' */ + if (currIsNewline(ls) && ls->current != old) + next(ls); /* skip '\n\r' or '\r\n' */ + if (++ls->linenumber >= MAX_INT) + lexerror(ls, "chunk has too many lines", 0); +} + + +void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, + int firstchar) { + ls->t.token = 0; + ls->L = L; + ls->current = firstchar; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ + ls->z = z; + ls->fs = NULL; + ls->linenumber = 1; + ls->lastline = 1; + ls->source = source; + ls->envn = luaS_newliteral(L, LUA_ENV); /* get env name */ + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ +} + + + +/* +** ======================================================= +** LEXICAL ANALYZER +** ======================================================= +*/ + + +static int check_next1 (LexState *ls, int c) { + if (ls->current == c) { + next(ls); + return 1; + } + else return 0; +} + + +/* +** Check whether current char is in set 'set' (with two chars) and +** saves it +*/ +static int check_next2 (LexState *ls, const char *set) { + lua_assert(set[2] == '\0'); + if (ls->current == set[0] || ls->current == set[1]) { + save_and_next(ls); + return 1; + } + else return 0; +} + + +/* LUA_NUMBER */ +/* +** This function is quite liberal in what it accepts, as 'luaO_str2num' +** will reject ill-formed numerals. Roughly, it accepts the following +** pattern: +** +** %d(%x|%.|([Ee][+-]?))* | 0[Xx](%x|%.|([Pp][+-]?))* +** +** The only tricky part is to accept [+-] only after a valid exponent +** mark, to avoid reading '3-4' or '0xe+1' as a single number. +** +** The caller might have already read an initial dot. +*/ +static int read_numeral (LexState *ls, SemInfo *seminfo) { + TValue obj; + const char *expo = "Ee"; + int first = ls->current; + lua_assert(lisdigit(ls->current)); + save_and_next(ls); + if (first == '0' && check_next2(ls, "xX")) /* hexadecimal? */ + expo = "Pp"; + for (;;) { + if (check_next2(ls, expo)) /* exponent mark? */ + check_next2(ls, "-+"); /* optional exponent sign */ + else if (lisxdigit(ls->current) || ls->current == '.') /* '%x|%.' */ + save_and_next(ls); + else break; + } + if (lislalpha(ls->current)) /* is numeral touching a letter? */ + save_and_next(ls); /* force an error */ + save(ls, '\0'); + if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */ + lexerror(ls, "malformed number", TK_FLT); + if (ttisinteger(&obj)) { + seminfo->i = ivalue(&obj); + return TK_INT; + } + else { + lua_assert(ttisfloat(&obj)); + seminfo->r = fltvalue(&obj); + return TK_FLT; + } +} + + +/* +** read a sequence '[=*[' or ']=*]', leaving the last bracket. If +** sequence is well formed, return its number of '='s + 2; otherwise, +** return 1 if it is a single bracket (no '='s and no 2nd bracket); +** otherwise (an unfinished '[==...') return 0. +*/ +static size_t skip_sep (LexState *ls) { + size_t count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); + save_and_next(ls); + while (ls->current == '=') { + save_and_next(ls); + count++; + } + return (ls->current == s) ? count + 2 + : (count == 0) ? 1 + : 0; +} + + +static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) { + int line = ls->linenumber; /* initial line (for error message) */ + save_and_next(ls); /* skip 2nd '[' */ + if (currIsNewline(ls)) /* string starts with a newline? */ + inclinenumber(ls); /* skip it */ + for (;;) { + switch (ls->current) { + case EOZ: { /* error */ + const char *what = (seminfo ? "string" : "comment"); + const char *msg = luaO_pushfstring(ls->L, + "unfinished long %s (starting at line %d)", what, line); + lexerror(ls, msg, TK_EOS); + break; /* to avoid warnings */ + } + case ']': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd ']' */ + goto endloop; + } + break; + } + case '\n': case '\r': { + save(ls, '\n'); + inclinenumber(ls); + if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ + break; + } + default: { + if (seminfo) save_and_next(ls); + else next(ls); + } + } + } endloop: + if (seminfo) + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep, + luaZ_bufflen(ls->buff) - 2 * sep); +} + + +static void esccheck (LexState *ls, int c, const char *msg) { + if (!c) { + if (ls->current != EOZ) + save_and_next(ls); /* add current to buffer for error message */ + lexerror(ls, msg, TK_STRING); + } +} + + +static int gethexa (LexState *ls) { + save_and_next(ls); + esccheck (ls, lisxdigit(ls->current), "hexadecimal digit expected"); + return luaO_hexavalue(ls->current); +} + + +static int readhexaesc (LexState *ls) { + int r = gethexa(ls); + r = (r << 4) + gethexa(ls); + luaZ_buffremove(ls->buff, 2); /* remove saved chars from buffer */ + return r; +} + + +static unsigned long readutf8esc (LexState *ls) { + unsigned long r; + int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */ + save_and_next(ls); /* skip 'u' */ + esccheck(ls, ls->current == '{', "missing '{'"); + r = gethexa(ls); /* must have at least one digit */ + while (cast_void(save_and_next(ls)), lisxdigit(ls->current)) { + i++; + esccheck(ls, r <= (0x7FFFFFFFu >> 4), "UTF-8 value too large"); + r = (r << 4) + luaO_hexavalue(ls->current); + } + esccheck(ls, ls->current == '}', "missing '}'"); + next(ls); /* skip '}' */ + luaZ_buffremove(ls->buff, i); /* remove saved chars from buffer */ + return r; +} + + +static void utf8esc (LexState *ls) { + char buff[UTF8BUFFSZ]; + int n = luaO_utf8esc(buff, readutf8esc(ls)); + for (; n > 0; n--) /* add 'buff' to string */ + save(ls, buff[UTF8BUFFSZ - n]); +} + + +static int readdecesc (LexState *ls) { + int i; + int r = 0; /* result accumulator */ + for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */ + r = 10*r + ls->current - '0'; + save_and_next(ls); + } + esccheck(ls, r <= UCHAR_MAX, "decimal escape too large"); + luaZ_buffremove(ls->buff, i); /* remove read digits from buffer */ + return r; +} + + +static void read_string (LexState *ls, int del, SemInfo *seminfo) { + save_and_next(ls); /* keep delimiter (for error messages) */ + while (ls->current != del) { + switch (ls->current) { + case EOZ: + lexerror(ls, "unfinished string", TK_EOS); + break; /* to avoid warnings */ + case '\n': + case '\r': + lexerror(ls, "unfinished string", TK_STRING); + break; /* to avoid warnings */ + case '\\': { /* escape sequences */ + int c; /* final character to be saved */ + save_and_next(ls); /* keep '\\' for error messages */ + switch (ls->current) { + case 'a': c = '\a'; goto read_save; + case 'b': c = '\b'; goto read_save; + case 'f': c = '\f'; goto read_save; + case 'n': c = '\n'; goto read_save; + case 'r': c = '\r'; goto read_save; + case 't': c = '\t'; goto read_save; + case 'v': c = '\v'; goto read_save; + case 'x': c = readhexaesc(ls); goto read_save; + case 'u': utf8esc(ls); goto no_save; + case '\n': case '\r': + inclinenumber(ls); c = '\n'; goto only_save; + case '\\': case '\"': case '\'': + c = ls->current; goto read_save; + case EOZ: goto no_save; /* will raise an error next loop */ + case 'z': { /* zap following span of spaces */ + luaZ_buffremove(ls->buff, 1); /* remove '\\' */ + next(ls); /* skip the 'z' */ + while (lisspace(ls->current)) { + if (currIsNewline(ls)) inclinenumber(ls); + else next(ls); + } + goto no_save; + } + default: { + esccheck(ls, lisdigit(ls->current), "invalid escape sequence"); + c = readdecesc(ls); /* digital escape '\ddd' */ + goto only_save; + } + } + read_save: + next(ls); + /* go through */ + only_save: + luaZ_buffremove(ls->buff, 1); /* remove '\\' */ + save(ls, c); + /* go through */ + no_save: break; + } + default: + save_and_next(ls); + } + } + save_and_next(ls); /* skip delimiter */ + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, + luaZ_bufflen(ls->buff) - 2); +} + + +static int llex (LexState *ls, SemInfo *seminfo) { + luaZ_resetbuffer(ls->buff); + for (;;) { + switch (ls->current) { + case '\n': case '\r': { /* line breaks */ + inclinenumber(ls); + break; + } + case ' ': case '\f': case '\t': case '\v': { /* spaces */ + next(ls); + break; + } + case '-': { /* '-' or '--' (comment) */ + next(ls); + if (ls->current != '-') return '-'; + /* else is a comment */ + next(ls); + if (ls->current == '[') { /* long comment? */ + size_t sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */ + if (sep >= 2) { + read_long_string(ls, NULL, sep); /* skip long comment */ + luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ + break; + } + } + /* else short comment */ + while (!currIsNewline(ls) && ls->current != EOZ) + next(ls); /* skip until end of line (or end of file) */ + break; + } + case '[': { /* long string or simply '[' */ + size_t sep = skip_sep(ls); + if (sep >= 2) { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } + else if (sep == 0) /* '[=...' missing second bracket? */ + lexerror(ls, "invalid long string delimiter", TK_STRING); + return '['; + } + case '=': { + next(ls); + if (check_next1(ls, '=')) return TK_EQ; /* '==' */ + else return '='; + } + case '<': { + next(ls); + if (check_next1(ls, '=')) return TK_LE; /* '<=' */ + else if (check_next1(ls, '<')) return TK_SHL; /* '<<' */ + else return '<'; + } + case '>': { + next(ls); + if (check_next1(ls, '=')) return TK_GE; /* '>=' */ + else if (check_next1(ls, '>')) return TK_SHR; /* '>>' */ + else return '>'; + } + case '/': { + next(ls); + if (check_next1(ls, '/')) return TK_IDIV; /* '//' */ + else return '/'; + } + case '~': { + next(ls); + if (check_next1(ls, '=')) return TK_NE; /* '~=' */ + else return '~'; + } + case ':': { + next(ls); + if (check_next1(ls, ':')) return TK_DBCOLON; /* '::' */ + else return ':'; + } + case '"': case '\'': { /* short literal strings */ + read_string(ls, ls->current, seminfo); + return TK_STRING; + } + case '.': { /* '.', '..', '...', or number */ + save_and_next(ls); + if (check_next1(ls, '.')) { + if (check_next1(ls, '.')) + return TK_DOTS; /* '...' */ + else return TK_CONCAT; /* '..' */ + } + else if (!lisdigit(ls->current)) return '.'; + else return read_numeral(ls, seminfo); + } + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + return read_numeral(ls, seminfo); + } + case EOZ: { + return TK_EOS; + } + default: { + if (lislalpha(ls->current)) { /* identifier or reserved word? */ + TString *ts; + do { + save_and_next(ls); + } while (lislalnum(ls->current)); + ts = luaX_newstring(ls, luaZ_buffer(ls->buff), + luaZ_bufflen(ls->buff)); + seminfo->ts = ts; + if (isreserved(ts)) /* reserved word? */ + return ts->extra - 1 + FIRST_RESERVED; + else { + return TK_NAME; + } + } + else { /* single-char tokens ('+', '*', '%', '{', '}', ...) */ + int c = ls->current; + next(ls); + return c; + } + } + } + } +} + + +void luaX_next (LexState *ls) { + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ +} + + +int luaX_lookahead (LexState *ls) { + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); + return ls->lookahead.token; +} + diff --git a/User/system/lua/src/llex.h b/User/system/lua/src/llex.h new file mode 100644 index 0000000..389d2f8 --- /dev/null +++ b/User/system/lua/src/llex.h @@ -0,0 +1,91 @@ +/* +** $Id: llex.h $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include + +#include "lobject.h" +#include "lzio.h" + + +/* +** Single-char tokens (terminal symbols) are represented by their own +** numeric code. Other tokens start at the following value. +*/ +#define FIRST_RESERVED (UCHAR_MAX + 1) + + +#if !defined(LUA_ENV) +#define LUA_ENV "_ENV" +#endif + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, + TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, + TK_SHL, TK_SHR, + TK_DBCOLON, TK_EOS, + TK_FLT, TK_INT, TK_NAME, TK_STRING +}; + +/* number of reserved words */ +#define NUM_RESERVED (cast_int(TK_WHILE-FIRST_RESERVED + 1)) + + +typedef union { + lua_Number r; + lua_Integer i; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +/* state of the lexer plus state of the parser when shared by all + functions */ +typedef struct LexState { + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token 'consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* current function (parser) */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + Table *h; /* to avoid collection/reuse strings */ + struct Dyndata *dyd; /* dynamic structures used by the parser */ + TString *source; /* current source name */ + TString *envn; /* environment variable name */ +} LexState; + + +LUAI_FUNC void luaX_init (lua_State *L); +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, + TString *source, int firstchar); +LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); +LUAI_FUNC void luaX_next (LexState *ls); +LUAI_FUNC int luaX_lookahead (LexState *ls); +LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); + + +#endif diff --git a/User/system/lua/src/llimits.h b/User/system/lua/src/llimits.h new file mode 100644 index 0000000..1c826f7 --- /dev/null +++ b/User/system/lua/src/llimits.h @@ -0,0 +1,380 @@ +/* +** $Id: llimits.h $ +** Limits, basic types, and some other 'installation-dependent' definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#include +#include + + +#include "lua.h" + + +/* +** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count +** the total memory used by Lua (in bytes). Usually, 'size_t' and +** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines. +*/ +#if defined(LUAI_MEM) /* { external definitions? */ +typedef LUAI_UMEM lu_mem; +typedef LUAI_MEM l_mem; +#elif LUAI_IS32INT /* }{ */ +typedef size_t lu_mem; +typedef ptrdiff_t l_mem; +#else /* 16-bit ints */ /* }{ */ +typedef unsigned long lu_mem; +typedef long l_mem; +#endif /* } */ + + +/* chars used as small naturals (so that 'char' is reserved for characters) */ +typedef unsigned char lu_byte; +typedef signed char ls_byte; + + +/* maximum value for size_t */ +#define MAX_SIZET ((size_t)(~(size_t)0)) + +/* maximum size visible for Lua (must be representable in a lua_Integer) */ +#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ + : (size_t)(LUA_MAXINTEGER)) + + +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)) + +#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1)) + + +#define MAX_INT INT_MAX /* maximum value of an int */ + + +/* +** floor of the log2 of the maximum signed value for integral type 't'. +** (That is, maximum 'n' such that '2^n' fits in the given signed type.) +*/ +#define log2maxs(t) (sizeof(t) * 8 - 2) + + +/* +** test whether an unsigned value is a power of 2 (or zero) +*/ +#define ispow2(x) (((x) & ((x) - 1)) == 0) + + +/* number of chars of a literal string without the ending \0 */ +#define LL(x) (sizeof(x)/sizeof(char) - 1) + + +/* +** conversion of pointer to unsigned integer: this is for hashing only; +** there is no problem if the integer cannot hold the whole pointer +** value. (In strict ISO C this may cause undefined behavior, but no +** actual machine seems to bother.) +*/ +#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \ + __STDC_VERSION__ >= 199901L +#include +#if defined(UINTPTR_MAX) /* even in C99 this type is optional */ +#define L_P2I uintptr_t +#else /* no 'intptr'? */ +#define L_P2I uintmax_t /* use the largest available integer */ +#endif +#else /* C89 option */ +#define L_P2I size_t +#endif + +#define point2uint(p) ((unsigned int)((L_P2I)(p) & UINT_MAX)) + + + +/* types of 'usual argument conversions' for lua_Number and lua_Integer */ +typedef LUAI_UACNUMBER l_uacNumber; +typedef LUAI_UACINT l_uacInt; + + +/* +** Internal assertions for in-house debugging +*/ +#if defined LUAI_ASSERT +#undef NDEBUG +#include +#define lua_assert(c) assert(c) +#endif + +#if defined(lua_assert) +#define check_exp(c,e) (lua_assert(c), (e)) +/* to avoid problems with conditions too long */ +#define lua_longassert(c) ((c) ? (void)0 : lua_assert(0)) +#else +#define lua_assert(c) ((void)0) +#define check_exp(c,e) (e) +#define lua_longassert(c) ((void)0) +#endif + +/* +** assertion for checking API calls +*/ +#if !defined(luai_apicheck) +#define luai_apicheck(l,e) ((void)l, lua_assert(e)) +#endif + +#define api_check(l,e,msg) luai_apicheck(l,(e) && msg) + + +/* macro to avoid warnings about unused variables */ +#if !defined(UNUSED) +#define UNUSED(x) ((void)(x)) +#endif + + +/* type casts (a macro highlights casts in the code) */ +#define cast(t, exp) ((t)(exp)) + +#define cast_void(i) cast(void, (i)) +#define cast_voidp(i) cast(void *, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) +#define cast_uint(i) cast(unsigned int, (i)) +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_uchar(i) cast(unsigned char, (i)) +#define cast_char(i) cast(char, (i)) +#define cast_charp(i) cast(char *, (i)) +#define cast_sizet(i) cast(size_t, (i)) + + +/* cast a signed lua_Integer to lua_Unsigned */ +#if !defined(l_castS2U) +#define l_castS2U(i) ((lua_Unsigned)(i)) +#endif + +/* +** cast a lua_Unsigned to a signed lua_Integer; this cast is +** not strict ISO C, but two-complement architectures should +** work fine. +*/ +#if !defined(l_castU2S) +#define l_castU2S(i) ((lua_Integer)(i)) +#endif + + +/* +** non-return type +*/ +#if !defined(l_noret) + +#if defined(__GNUC__) +#define l_noret void __attribute__((noreturn)) +#elif defined(_MSC_VER) && _MSC_VER >= 1200 +#define l_noret void __declspec(noreturn) +#else +#define l_noret void +#endif + +#endif + + +/* +** Inline functions +*/ +#if !defined(LUA_USE_C89) +#define l_inline inline +#elif defined(__GNUC__) +#define l_inline __inline__ +#else +#define l_inline /* empty */ +#endif + +#define l_sinline static l_inline + + +/* +** type for virtual-machine instructions; +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +#if LUAI_IS32INT +typedef unsigned int l_uint32; +#else +typedef unsigned long l_uint32; +#endif + +typedef l_uint32 Instruction; + + + +/* +** Maximum length for short strings, that is, strings that are +** internalized. (Cannot be smaller than reserved words or tags for +** metamethods, as these strings must be internalized; +** #("function") = 8, #("__newindex") = 10.) +*/ +#if !defined(LUAI_MAXSHORTLEN) +#define LUAI_MAXSHORTLEN 40 +#endif + + +/* +** Initial size for the string table (must be power of 2). +** The Lua core alone registers ~50 strings (reserved words + +** metaevent keys + a few others). Libraries would typically add +** a few dozens more. +*/ +#if !defined(MINSTRTABSIZE) +#define MINSTRTABSIZE 128 +#endif + + +/* +** Size of cache for strings in the API. 'N' is the number of +** sets (better be a prime) and "M" is the size of each set (M == 1 +** makes a direct cache.) +*/ +#if !defined(STRCACHE_N) +#define STRCACHE_N 53 +#define STRCACHE_M 2 +#endif + + +/* minimum size for string buffer */ +#if !defined(LUA_MINBUFFER) +#define LUA_MINBUFFER 32 +#endif + + +/* +** Maximum depth for nested C calls, syntactical nested non-terminals, +** and other features implemented through recursion in C. (Value must +** fit in a 16-bit unsigned integer. It must also be compatible with +** the size of the C stack.) +*/ +#if !defined(LUAI_MAXCCALLS) +#define LUAI_MAXCCALLS 200 +#endif + + +/* +** macros that are executed whenever program enters the Lua core +** ('lua_lock') and leaves the core ('lua_unlock') +*/ +#if !defined(lua_lock) +#define lua_lock(L) ((void) 0) +#define lua_unlock(L) ((void) 0) +#endif + +/* +** macro executed during Lua functions at points where the +** function can yield. +*/ +#if !defined(luai_threadyield) +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} +#endif + + +/* +** these macros allow user-specific actions when a thread is +** created/deleted/resumed/yielded. +*/ +#if !defined(luai_userstateopen) +#define luai_userstateopen(L) ((void)L) +#endif + +#if !defined(luai_userstateclose) +#define luai_userstateclose(L) ((void)L) +#endif + +#if !defined(luai_userstatethread) +#define luai_userstatethread(L,L1) ((void)L) +#endif + +#if !defined(luai_userstatefree) +#define luai_userstatefree(L,L1) ((void)L) +#endif + +#if !defined(luai_userstateresume) +#define luai_userstateresume(L,n) ((void)L) +#endif + +#if !defined(luai_userstateyield) +#define luai_userstateyield(L,n) ((void)L) +#endif + + + +/* +** The luai_num* macros define the primitive operations over numbers. +*/ + +/* floor division (defined as 'floor(a/b)') */ +#if !defined(luai_numidiv) +#define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b))) +#endif + +/* float division */ +#if !defined(luai_numdiv) +#define luai_numdiv(L,a,b) ((a)/(b)) +#endif + +/* +** modulo: defined as 'a - floor(a/b)*b'; the direct computation +** using this definition has several problems with rounding errors, +** so it is better to use 'fmod'. 'fmod' gives the result of +** 'a - trunc(a/b)*b', and therefore must be corrected when +** 'trunc(a/b) ~= floor(a/b)'. That happens when the division has a +** non-integer negative result: non-integer result is equivalent to +** a non-zero remainder 'm'; negative result is equivalent to 'a' and +** 'b' with different signs, or 'm' and 'b' with different signs +** (as the result 'm' of 'fmod' has the same sign of 'a'). +*/ +#if !defined(luai_nummod) +#define luai_nummod(L,a,b,m) \ + { (void)L; (m) = l_mathop(fmod)(a,b); \ + if (((m) > 0) ? (b) < 0 : ((m) < 0 && (b) > 0)) (m) += (b); } +#endif + +/* exponentiation */ +#if !defined(luai_numpow) +#define luai_numpow(L,a,b) \ + ((void)L, (b == 2) ? (a)*(a) : l_mathop(pow)(a,b)) +#endif + +/* the others are quite standard operations */ +#if !defined(luai_numadd) +#define luai_numadd(L,a,b) ((a)+(b)) +#define luai_numsub(L,a,b) ((a)-(b)) +#define luai_nummul(L,a,b) ((a)*(b)) +#define luai_numunm(L,a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numgt(a,b) ((a)>(b)) +#define luai_numge(a,b) ((a)>=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + + + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#if !defined(HARDSTACKTESTS) +#define condmovestack(L,pre,pos) ((void)0) +#else +/* realloc stack keeping its size */ +#define condmovestack(L,pre,pos) \ + { int sz_ = stacksize(L); pre; luaD_reallocstack((L), sz_, 0); pos; } +#endif + +#if !defined(HARDMEMTESTS) +#define condchangemem(L,pre,pos) ((void)0) +#else +#define condchangemem(L,pre,pos) \ + { if (gcrunning(G(L))) { pre; luaC_fullgc(L, 0); pos; } } +#endif + +#endif diff --git a/User/system/lua/src/lmathlib.c b/User/system/lua/src/lmathlib.c new file mode 100644 index 0000000..4381063 --- /dev/null +++ b/User/system/lua/src/lmathlib.c @@ -0,0 +1,781 @@ +/* +** $Id: lmathlib.c $ +** Standard mathematical library +** See Copyright Notice in lua.h +*/ + +#define lmathlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#undef PI +#define PI (l_mathop(3.141592653589793238462643383279502884)) + + +static int math_abs (lua_State *L) { + if (lua_isinteger(L, 1)) { + lua_Integer n = lua_tointeger(L, 1); + if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n); + lua_pushinteger(L, n); + } + else + lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sin (lua_State *L) { + lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cos (lua_State *L) { + lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tan (lua_State *L) { + lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_asin (lua_State *L) { + lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_acos (lua_State *L) { + lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan (lua_State *L) { + lua_Number y = luaL_checknumber(L, 1); + lua_Number x = luaL_optnumber(L, 2, 1); + lua_pushnumber(L, l_mathop(atan2)(y, x)); + return 1; +} + + +static int math_toint (lua_State *L) { + int valid; + lua_Integer n = lua_tointegerx(L, 1, &valid); + if (l_likely(valid)) + lua_pushinteger(L, n); + else { + luaL_checkany(L, 1); + luaL_pushfail(L); /* value is not convertible to integer */ + } + return 1; +} + + +static void pushnumint (lua_State *L, lua_Number d) { + lua_Integer n; + if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */ + lua_pushinteger(L, n); /* result is integer */ + else + lua_pushnumber(L, d); /* result is float */ +} + + +static int math_floor (lua_State *L) { + if (lua_isinteger(L, 1)) + lua_settop(L, 1); /* integer is its own floor */ + else { + lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1)); + pushnumint(L, d); + } + return 1; +} + + +static int math_ceil (lua_State *L) { + if (lua_isinteger(L, 1)) + lua_settop(L, 1); /* integer is its own ceil */ + else { + lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1)); + pushnumint(L, d); + } + return 1; +} + + +static int math_fmod (lua_State *L) { + if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { + lua_Integer d = lua_tointeger(L, 2); + if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */ + luaL_argcheck(L, d != 0, 2, "zero"); + lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */ + } + else + lua_pushinteger(L, lua_tointeger(L, 1) % d); + } + else + lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), + luaL_checknumber(L, 2))); + return 1; +} + + +/* +** next function does not use 'modf', avoiding problems with 'double*' +** (which is not compatible with 'float*') when lua_Number is not +** 'double'. +*/ +static int math_modf (lua_State *L) { + if (lua_isinteger(L ,1)) { + lua_settop(L, 1); /* number is its own integer part */ + lua_pushnumber(L, 0); /* no fractional part */ + } + else { + lua_Number n = luaL_checknumber(L, 1); + /* integer part (rounds toward zero) */ + lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n); + pushnumint(L, ip); + /* fractional part (test needed for inf/-inf) */ + lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); + } + return 2; +} + + +static int math_sqrt (lua_State *L) { + lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); + return 1; +} + + +static int math_ult (lua_State *L) { + lua_Integer a = luaL_checkinteger(L, 1); + lua_Integer b = luaL_checkinteger(L, 2); + lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b); + return 1; +} + +static int math_log (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + lua_Number res; + if (lua_isnoneornil(L, 2)) + res = l_mathop(log)(x); + else { + lua_Number base = luaL_checknumber(L, 2); +#if !defined(LUA_USE_C89) + if (base == l_mathop(2.0)) + res = l_mathop(log2)(x); + else +#endif + if (base == l_mathop(10.0)) + res = l_mathop(log10)(x); + else + res = l_mathop(log)(x)/l_mathop(log)(base); + } + lua_pushnumber(L, res); + return 1; +} + +static int math_exp (lua_State *L) { + lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_deg (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI)); + return 1; +} + +static int math_rad (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0))); + return 1; +} + + +static int math_min (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int imin = 1; /* index of current minimum value */ + int i; + luaL_argcheck(L, n >= 1, 1, "value expected"); + for (i = 2; i <= n; i++) { + if (lua_compare(L, i, imin, LUA_OPLT)) + imin = i; + } + lua_pushvalue(L, imin); + return 1; +} + + +static int math_max (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int imax = 1; /* index of current maximum value */ + int i; + luaL_argcheck(L, n >= 1, 1, "value expected"); + for (i = 2; i <= n; i++) { + if (lua_compare(L, imax, i, LUA_OPLT)) + imax = i; + } + lua_pushvalue(L, imax); + return 1; +} + + +static int math_type (lua_State *L) { + if (lua_type(L, 1) == LUA_TNUMBER) + lua_pushstring(L, (lua_isinteger(L, 1)) ? "integer" : "float"); + else { + luaL_checkany(L, 1); + luaL_pushfail(L); + } + return 1; +} + + + +/* +** {================================================================== +** Pseudo-Random Number Generator based on 'xoshiro256**'. +** =================================================================== +*/ + +/* +** This code uses lots of shifts. ANSI C does not allow shifts greater +** than or equal to the width of the type being shifted, so some shifts +** are written in convoluted ways to match that restriction. For +** preprocessor tests, it assumes a width of 32 bits, so the maximum +** shift there is 31 bits. +*/ + + +/* number of binary digits in the mantissa of a float */ +#define FIGS l_floatatt(MANT_DIG) + +#if FIGS > 64 +/* there are only 64 random bits; use them all */ +#undef FIGS +#define FIGS 64 +#endif + + +/* +** LUA_RAND32 forces the use of 32-bit integers in the implementation +** of the PRN generator (mainly for testing). +*/ +#if !defined(LUA_RAND32) && !defined(Rand64) + +/* try to find an integer type with at least 64 bits */ + +#if ((ULONG_MAX >> 31) >> 31) >= 3 + +/* 'long' has at least 64 bits */ +#define Rand64 unsigned long +#define SRand64 long + +#elif !defined(LUA_USE_C89) && defined(LLONG_MAX) + +/* there is a 'long long' type (which must have at least 64 bits) */ +#define Rand64 unsigned long long +#define SRand64 long long + +#elif ((LUA_MAXUNSIGNED >> 31) >> 31) >= 3 + +/* 'lua_Unsigned' has at least 64 bits */ +#define Rand64 lua_Unsigned +#define SRand64 lua_Integer + +#endif + +#endif + + +#if defined(Rand64) /* { */ + +/* +** Standard implementation, using 64-bit integers. +** If 'Rand64' has more than 64 bits, the extra bits do not interfere +** with the 64 initial bits, except in a right shift. Moreover, the +** final result has to discard the extra bits. +*/ + +/* avoid using extra bits when needed */ +#define trim64(x) ((x) & 0xffffffffffffffffu) + + +/* rotate left 'x' by 'n' bits */ +static Rand64 rotl (Rand64 x, int n) { + return (x << n) | (trim64(x) >> (64 - n)); +} + +static Rand64 nextrand (Rand64 *state) { + Rand64 state0 = state[0]; + Rand64 state1 = state[1]; + Rand64 state2 = state[2] ^ state0; + Rand64 state3 = state[3] ^ state1; + Rand64 res = rotl(state1 * 5, 7) * 9; + state[0] = state0 ^ state3; + state[1] = state1 ^ state2; + state[2] = state2 ^ (state1 << 17); + state[3] = rotl(state3, 45); + return res; +} + + +/* +** Convert bits from a random integer into a float in the +** interval [0,1), getting the higher FIG bits from the +** random unsigned integer and converting that to a float. +** Some old Microsoft compilers cannot cast an unsigned long +** to a floating-point number, so we use a signed long as an +** intermediary. When lua_Number is float or double, the shift ensures +** that 'sx' is non negative; in that case, a good compiler will remove +** the correction. +*/ + +/* must throw out the extra (64 - FIGS) bits */ +#define shift64_FIG (64 - FIGS) + +/* 2^(-FIGS) == 2^-1 / 2^(FIGS-1) */ +#define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1))) + +static lua_Number I2d (Rand64 x) { + SRand64 sx = (SRand64)(trim64(x) >> shift64_FIG); + lua_Number res = (lua_Number)(sx) * scaleFIG; + if (sx < 0) + res += l_mathop(1.0); /* correct the two's complement if negative */ + lua_assert(0 <= res && res < 1); + return res; +} + +/* convert a 'Rand64' to a 'lua_Unsigned' */ +#define I2UInt(x) ((lua_Unsigned)trim64(x)) + +/* convert a 'lua_Unsigned' to a 'Rand64' */ +#define Int2I(x) ((Rand64)(x)) + + +#else /* no 'Rand64' }{ */ + +/* get an integer with at least 32 bits */ +#if LUAI_IS32INT +typedef unsigned int lu_int32; +#else +typedef unsigned long lu_int32; +#endif + + +/* +** Use two 32-bit integers to represent a 64-bit quantity. +*/ +typedef struct Rand64 { + lu_int32 h; /* higher half */ + lu_int32 l; /* lower half */ +} Rand64; + + +/* +** If 'lu_int32' has more than 32 bits, the extra bits do not interfere +** with the 32 initial bits, except in a right shift and comparisons. +** Moreover, the final result has to discard the extra bits. +*/ + +/* avoid using extra bits when needed */ +#define trim32(x) ((x) & 0xffffffffu) + + +/* +** basic operations on 'Rand64' values +*/ + +/* build a new Rand64 value */ +static Rand64 packI (lu_int32 h, lu_int32 l) { + Rand64 result; + result.h = h; + result.l = l; + return result; +} + +/* return i << n */ +static Rand64 Ishl (Rand64 i, int n) { + lua_assert(n > 0 && n < 32); + return packI((i.h << n) | (trim32(i.l) >> (32 - n)), i.l << n); +} + +/* i1 ^= i2 */ +static void Ixor (Rand64 *i1, Rand64 i2) { + i1->h ^= i2.h; + i1->l ^= i2.l; +} + +/* return i1 + i2 */ +static Rand64 Iadd (Rand64 i1, Rand64 i2) { + Rand64 result = packI(i1.h + i2.h, i1.l + i2.l); + if (trim32(result.l) < trim32(i1.l)) /* carry? */ + result.h++; + return result; +} + +/* return i * 5 */ +static Rand64 times5 (Rand64 i) { + return Iadd(Ishl(i, 2), i); /* i * 5 == (i << 2) + i */ +} + +/* return i * 9 */ +static Rand64 times9 (Rand64 i) { + return Iadd(Ishl(i, 3), i); /* i * 9 == (i << 3) + i */ +} + +/* return 'i' rotated left 'n' bits */ +static Rand64 rotl (Rand64 i, int n) { + lua_assert(n > 0 && n < 32); + return packI((i.h << n) | (trim32(i.l) >> (32 - n)), + (trim32(i.h) >> (32 - n)) | (i.l << n)); +} + +/* for offsets larger than 32, rotate right by 64 - offset */ +static Rand64 rotl1 (Rand64 i, int n) { + lua_assert(n > 32 && n < 64); + n = 64 - n; + return packI((trim32(i.h) >> n) | (i.l << (32 - n)), + (i.h << (32 - n)) | (trim32(i.l) >> n)); +} + +/* +** implementation of 'xoshiro256**' algorithm on 'Rand64' values +*/ +static Rand64 nextrand (Rand64 *state) { + Rand64 res = times9(rotl(times5(state[1]), 7)); + Rand64 t = Ishl(state[1], 17); + Ixor(&state[2], state[0]); + Ixor(&state[3], state[1]); + Ixor(&state[1], state[2]); + Ixor(&state[0], state[3]); + Ixor(&state[2], t); + state[3] = rotl1(state[3], 45); + return res; +} + + +/* +** Converts a 'Rand64' into a float. +*/ + +/* an unsigned 1 with proper type */ +#define UONE ((lu_int32)1) + + +#if FIGS <= 32 + +/* 2^(-FIGS) */ +#define scaleFIG (l_mathop(0.5) / (UONE << (FIGS - 1))) + +/* +** get up to 32 bits from higher half, shifting right to +** throw out the extra bits. +*/ +static lua_Number I2d (Rand64 x) { + lua_Number h = (lua_Number)(trim32(x.h) >> (32 - FIGS)); + return h * scaleFIG; +} + +#else /* 32 < FIGS <= 64 */ + +/* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */ +#define scaleFIG \ + (l_mathop(1.0) / (UONE << 30) / l_mathop(8.0) / (UONE << (FIGS - 33))) + +/* +** use FIGS - 32 bits from lower half, throwing out the other +** (32 - (FIGS - 32)) = (64 - FIGS) bits +*/ +#define shiftLOW (64 - FIGS) + +/* +** higher 32 bits go after those (FIGS - 32) bits: shiftHI = 2^(FIGS - 32) +*/ +#define shiftHI ((lua_Number)(UONE << (FIGS - 33)) * l_mathop(2.0)) + + +static lua_Number I2d (Rand64 x) { + lua_Number h = (lua_Number)trim32(x.h) * shiftHI; + lua_Number l = (lua_Number)(trim32(x.l) >> shiftLOW); + return (h + l) * scaleFIG; +} + +#endif + + +/* convert a 'Rand64' to a 'lua_Unsigned' */ +static lua_Unsigned I2UInt (Rand64 x) { + return (((lua_Unsigned)trim32(x.h) << 31) << 1) | (lua_Unsigned)trim32(x.l); +} + +/* convert a 'lua_Unsigned' to a 'Rand64' */ +static Rand64 Int2I (lua_Unsigned n) { + return packI((lu_int32)((n >> 31) >> 1), (lu_int32)n); +} + +#endif /* } */ + + +/* +** A state uses four 'Rand64' values. +*/ +typedef struct { + Rand64 s[4]; +} RanState; + + +/* +** Project the random integer 'ran' into the interval [0, n]. +** Because 'ran' has 2^B possible values, the projection can only be +** uniform when the size of the interval is a power of 2 (exact +** division). Otherwise, to get a uniform projection into [0, n], we +** first compute 'lim', the smallest Mersenne number not smaller than +** 'n'. We then project 'ran' into the interval [0, lim]. If the result +** is inside [0, n], we are done. Otherwise, we try with another 'ran', +** until we have a result inside the interval. +*/ +static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, + RanState *state) { + if ((n & (n + 1)) == 0) /* is 'n + 1' a power of 2? */ + return ran & n; /* no bias */ + else { + lua_Unsigned lim = n; + /* compute the smallest (2^b - 1) not smaller than 'n' */ + lim |= (lim >> 1); + lim |= (lim >> 2); + lim |= (lim >> 4); + lim |= (lim >> 8); + lim |= (lim >> 16); +#if (LUA_MAXUNSIGNED >> 31) >= 3 + lim |= (lim >> 32); /* integer type has more than 32 bits */ +#endif + lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */ + && lim >= n /* not smaller than 'n', */ + && (lim >> 1) < n); /* and it is the smallest one */ + while ((ran &= lim) > n) /* project 'ran' into [0..lim] */ + ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */ + return ran; + } +} + + +static int math_random (lua_State *L) { + lua_Integer low, up; + lua_Unsigned p; + RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); + Rand64 rv = nextrand(state->s); /* next pseudo-random value */ + switch (lua_gettop(L)) { /* check number of arguments */ + case 0: { /* no arguments */ + lua_pushnumber(L, I2d(rv)); /* float between 0 and 1 */ + return 1; + } + case 1: { /* only upper limit */ + low = 1; + up = luaL_checkinteger(L, 1); + if (up == 0) { /* single 0 as argument? */ + lua_pushinteger(L, I2UInt(rv)); /* full random integer */ + return 1; + } + break; + } + case 2: { /* lower and upper limits */ + low = luaL_checkinteger(L, 1); + up = luaL_checkinteger(L, 2); + break; + } + default: return luaL_error(L, "wrong number of arguments"); + } + /* random integer in the interval [low, up] */ + luaL_argcheck(L, low <= up, 1, "interval is empty"); + /* project random integer into the interval [0, up - low] */ + p = project(I2UInt(rv), (lua_Unsigned)up - (lua_Unsigned)low, state); + lua_pushinteger(L, p + (lua_Unsigned)low); + return 1; +} + + +static void setseed (lua_State *L, Rand64 *state, + lua_Unsigned n1, lua_Unsigned n2) { + int i; + state[0] = Int2I(n1); + state[1] = Int2I(0xff); /* avoid a zero state */ + state[2] = Int2I(n2); + state[3] = Int2I(0); + for (i = 0; i < 16; i++) + nextrand(state); /* discard initial values to "spread" seed */ + lua_pushinteger(L, n1); + lua_pushinteger(L, n2); +} + + +/* +** Set a "random" seed. To get some randomness, use the current time +** and the address of 'L' (in case the machine does address space layout +** randomization). +*/ +static void randseed (lua_State *L, RanState *state) { + lua_Unsigned seed1 = (lua_Unsigned)time(NULL); + lua_Unsigned seed2 = (lua_Unsigned)(size_t)L; + setseed(L, state->s, seed1, seed2); +} + + +static int math_randomseed (lua_State *L) { + RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); + if (lua_isnone(L, 1)) { + randseed(L, state); + } + else { + lua_Integer n1 = luaL_checkinteger(L, 1); + lua_Integer n2 = luaL_optinteger(L, 2, 0); + setseed(L, state->s, n1, n2); + } + return 2; /* return seeds */ +} + + +static const luaL_Reg randfuncs[] = { + {"random", math_random}, + {"randomseed", math_randomseed}, + {NULL, NULL} +}; + + +/* +** Register the random functions and initialize their state. +*/ +static void setrandfunc (lua_State *L) { + RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0); + randseed(L, state); /* initialize with a "random" seed */ + lua_pop(L, 2); /* remove pushed seeds */ + luaL_setfuncs(L, randfuncs, 1); +} + +/* }================================================================== */ + + +/* +** {================================================================== +** Deprecated functions (for compatibility only) +** =================================================================== +*/ +#if defined(LUA_COMPAT_MATHLIB) + +static int math_cosh (lua_State *L) { + lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sinh (lua_State *L) { + lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tanh (lua_State *L) { + lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_pow (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + lua_Number y = luaL_checknumber(L, 2); + lua_pushnumber(L, l_mathop(pow)(x, y)); + return 1; +} + +static int math_frexp (lua_State *L) { + int e; + lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); + lua_pushinteger(L, e); + return 2; +} + +static int math_ldexp (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + int ep = (int)luaL_checkinteger(L, 2); + lua_pushnumber(L, l_mathop(ldexp)(x, ep)); + return 1; +} + +static int math_log10 (lua_State *L) { + lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); + return 1; +} + +#endif +/* }================================================================== */ + + + +static const luaL_Reg mathlib[] = { + {"abs", math_abs}, + {"acos", math_acos}, + {"asin", math_asin}, + {"atan", math_atan}, + {"ceil", math_ceil}, + {"cos", math_cos}, + {"deg", math_deg}, + {"exp", math_exp}, + {"tointeger", math_toint}, + {"floor", math_floor}, + {"fmod", math_fmod}, + {"ult", math_ult}, + {"log", math_log}, + {"max", math_max}, + {"min", math_min}, + {"modf", math_modf}, + {"rad", math_rad}, + {"sin", math_sin}, + {"sqrt", math_sqrt}, + {"tan", math_tan}, + {"type", math_type}, +#if defined(LUA_COMPAT_MATHLIB) + {"atan2", math_atan}, + {"cosh", math_cosh}, + {"sinh", math_sinh}, + {"tanh", math_tanh}, + {"pow", math_pow}, + {"frexp", math_frexp}, + {"ldexp", math_ldexp}, + {"log10", math_log10}, +#endif + /* placeholders */ + {"random", NULL}, + {"randomseed", NULL}, + {"pi", NULL}, + {"huge", NULL}, + {"maxinteger", NULL}, + {"mininteger", NULL}, + {NULL, NULL} +}; + + +/* +** Open math library +*/ +LUAMOD_API int luaopen_math (lua_State *L) { + luaL_newlib(L, mathlib); + lua_pushnumber(L, PI); + lua_setfield(L, -2, "pi"); + lua_pushnumber(L, (lua_Number)HUGE_VAL); + lua_setfield(L, -2, "huge"); + lua_pushinteger(L, LUA_MAXINTEGER); + lua_setfield(L, -2, "maxinteger"); + lua_pushinteger(L, LUA_MININTEGER); + lua_setfield(L, -2, "mininteger"); + setrandfunc(L); + return 1; +} + diff --git a/User/system/lua/src/lmem.c b/User/system/lua/src/lmem.c new file mode 100644 index 0000000..9800a86 --- /dev/null +++ b/User/system/lua/src/lmem.c @@ -0,0 +1,215 @@ +/* +** $Id: lmem.c $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#define lmem_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +/* +** About the realloc function: +** void *frealloc (void *ud, void *ptr, size_t osize, size_t nsize); +** ('osize' is the old size, 'nsize' is the new size) +** +** - frealloc(ud, p, x, 0) frees the block 'p' and returns NULL. +** Particularly, frealloc(ud, NULL, 0, 0) does nothing, +** which is equivalent to free(NULL) in ISO C. +** +** - frealloc(ud, NULL, x, s) creates a new block of size 's' +** (no matter 'x'). Returns NULL if it cannot create the new block. +** +** - otherwise, frealloc(ud, b, x, y) reallocates the block 'b' from +** size 'x' to size 'y'. Returns NULL if it cannot reallocate the +** block to the new size. +*/ + + +/* +** Macro to call the allocation function. +*/ +#define callfrealloc(g,block,os,ns) ((*g->frealloc)(g->ud, block, os, ns)) + + +/* +** When an allocation fails, it will try again after an emergency +** collection, except when it cannot run a collection. The GC should +** not be called while the state is not fully built, as the collector +** is not yet fully initialized. Also, it should not be called when +** 'gcstopem' is true, because then the interpreter is in the middle of +** a collection step. +*/ +#define cantryagain(g) (completestate(g) && !g->gcstopem) + + + + +#if defined(EMERGENCYGCTESTS) +/* +** First allocation will fail except when freeing a block (frees never +** fail) and when it cannot try again; this fail will trigger 'tryagain' +** and a full GC cycle at every allocation. +*/ +static void *firsttry (global_State *g, void *block, size_t os, size_t ns) { + if (ns > 0 && cantryagain(g)) + return NULL; /* fail */ + else /* normal allocation */ + return callfrealloc(g, block, os, ns); +} +#else +#define firsttry(g,block,os,ns) callfrealloc(g, block, os, ns) +#endif + + + + + +/* +** {================================================================== +** Functions to allocate/deallocate arrays for the Parser +** =================================================================== +*/ + +/* +** Minimum size for arrays during parsing, to avoid overhead of +** reallocating to size 1, then 2, and then 4. All these arrays +** will be reallocated to exact sizes or erased when parsing ends. +*/ +#define MINSIZEARRAY 4 + + +void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize, + int size_elems, int limit, const char *what) { + void *newblock; + int size = *psize; + if (nelems + 1 <= size) /* does one extra element still fit? */ + return block; /* nothing to be done */ + if (size >= limit / 2) { /* cannot double it? */ + if (l_unlikely(size >= limit)) /* cannot grow even a little? */ + luaG_runerror(L, "too many %s (limit is %d)", what, limit); + size = limit; /* still have at least one free place */ + } + else { + size *= 2; + if (size < MINSIZEARRAY) + size = MINSIZEARRAY; /* minimum size */ + } + lua_assert(nelems + 1 <= size && size <= limit); + /* 'limit' ensures that multiplication will not overflow */ + newblock = luaM_saferealloc_(L, block, cast_sizet(*psize) * size_elems, + cast_sizet(size) * size_elems); + *psize = size; /* update only when everything else is OK */ + return newblock; +} + + +/* +** In prototypes, the size of the array is also its number of +** elements (to save memory). So, if it cannot shrink an array +** to its number of elements, the only option is to raise an +** error. +*/ +void *luaM_shrinkvector_ (lua_State *L, void *block, int *size, + int final_n, int size_elem) { + void *newblock; + size_t oldsize = cast_sizet((*size) * size_elem); + size_t newsize = cast_sizet(final_n * size_elem); + lua_assert(newsize <= oldsize); + newblock = luaM_saferealloc_(L, block, oldsize, newsize); + *size = final_n; + return newblock; +} + +/* }================================================================== */ + + +l_noret luaM_toobig (lua_State *L) { + luaG_runerror(L, "memory allocation error: block too big"); +} + + +/* +** Free memory +*/ +void luaM_free_ (lua_State *L, void *block, size_t osize) { + global_State *g = G(L); + lua_assert((osize == 0) == (block == NULL)); + callfrealloc(g, block, osize, 0); + g->GCdebt -= osize; +} + + +/* +** In case of allocation fail, this function will do an emergency +** collection to free some memory and then try the allocation again. +*/ +static void *tryagain (lua_State *L, void *block, + size_t osize, size_t nsize) { + global_State *g = G(L); + if (cantryagain(g)) { + luaC_fullgc(L, 1); /* try to free some memory... */ + return callfrealloc(g, block, osize, nsize); /* try again */ + } + else return NULL; /* cannot run an emergency collection */ +} + + +/* +** Generic allocation routine. +*/ +void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { + void *newblock; + global_State *g = G(L); + lua_assert((osize == 0) == (block == NULL)); + newblock = firsttry(g, block, osize, nsize); + if (l_unlikely(newblock == NULL && nsize > 0)) { + newblock = tryagain(L, block, osize, nsize); + if (newblock == NULL) /* still no memory? */ + return NULL; /* do not update 'GCdebt' */ + } + lua_assert((nsize == 0) == (newblock == NULL)); + g->GCdebt = (g->GCdebt + nsize) - osize; + return newblock; +} + + +void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, + size_t nsize) { + void *newblock = luaM_realloc_(L, block, osize, nsize); + if (l_unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ + luaM_error(L); + return newblock; +} + + +void *luaM_malloc_ (lua_State *L, size_t size, int tag) { + if (size == 0) + return NULL; /* that's all */ + else { + global_State *g = G(L); + void *newblock = firsttry(g, NULL, tag, size); + if (l_unlikely(newblock == NULL)) { + newblock = tryagain(L, NULL, tag, size); + if (newblock == NULL) + luaM_error(L); + } + g->GCdebt += size; + return newblock; + } +} diff --git a/User/system/lua/src/lmem.h b/User/system/lua/src/lmem.h new file mode 100644 index 0000000..8c75a44 --- /dev/null +++ b/User/system/lua/src/lmem.h @@ -0,0 +1,93 @@ +/* +** $Id: lmem.h $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#include + +#include "llimits.h" +#include "lua.h" + + +#define luaM_error(L) luaD_throw(L, LUA_ERRMEM) + + +/* +** This macro tests whether it is safe to multiply 'n' by the size of +** type 't' without overflows. Because 'e' is always constant, it avoids +** the runtime division MAX_SIZET/(e). +** (The macro is somewhat complex to avoid warnings: The 'sizeof' +** comparison avoids a runtime comparison when overflow cannot occur. +** The compiler should be able to optimize the real test by itself, but +** when it does it, it may give a warning about "comparison is always +** false due to limited range of data type"; the +1 tricks the compiler, +** avoiding this warning but also this optimization.) +*/ +#define luaM_testsize(n,e) \ + (sizeof(n) >= sizeof(size_t) && cast_sizet((n)) + 1 > MAX_SIZET/(e)) + +#define luaM_checksize(L,n,e) \ + (luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0)) + + +/* +** Computes the minimum between 'n' and 'MAX_SIZET/sizeof(t)', so that +** the result is not larger than 'n' and cannot overflow a 'size_t' +** when multiplied by the size of type 't'. (Assumes that 'n' is an +** 'int' or 'unsigned int' and that 'int' is not larger than 'size_t'.) +*/ +#define luaM_limitN(n,t) \ + ((cast_sizet(n) <= MAX_SIZET/sizeof(t)) ? (n) : \ + cast_uint((MAX_SIZET/sizeof(t)))) + + +/* +** Arrays of chars do not need any test +*/ +#define luaM_reallocvchar(L,b,on,n) \ + cast_charp(luaM_saferealloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) + +#define luaM_freemem(L, b, s) luaM_free_(L, (b), (s)) +#define luaM_free(L, b) luaM_free_(L, (b), sizeof(*(b))) +#define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b))) + +#define luaM_new(L,t) cast(t*, luaM_malloc_(L, sizeof(t), 0)) +#define luaM_newvector(L,n,t) cast(t*, luaM_malloc_(L, (n)*sizeof(t), 0)) +#define luaM_newvectorchecked(L,n,t) \ + (luaM_checksize(L,n,sizeof(t)), luaM_newvector(L,n,t)) + +#define luaM_newobject(L,tag,s) luaM_malloc_(L, (s), tag) + +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \ + luaM_limitN(limit,t),e))) + +#define luaM_reallocvector(L, v,oldn,n,t) \ + (cast(t *, luaM_realloc_(L, v, cast_sizet(oldn) * sizeof(t), \ + cast_sizet(n) * sizeof(t)))) + +#define luaM_shrinkvector(L,v,size,fs,t) \ + ((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t)))) + +LUAI_FUNC l_noret luaM_toobig (lua_State *L); + +/* not to be called directly */ +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize); +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems, + int *size, int size_elem, int limit, + const char *what); +LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem, + int final_n, int size_elem); +LUAI_FUNC void *luaM_malloc_ (lua_State *L, size_t size, int tag); + +#endif + diff --git a/User/system/lua/src/loadlib.c b/User/system/lua/src/loadlib.c new file mode 100644 index 0000000..6d289fc --- /dev/null +++ b/User/system/lua/src/loadlib.c @@ -0,0 +1,758 @@ +/* +** $Id: loadlib.c $ +** Dynamic library loader for Lua +** See Copyright Notice in lua.h +** +** This module contains an implementation of loadlib for Unix systems +** that have dlfcn, an implementation for Windows, and a stub for other +** systems. +*/ + +#define loadlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** LUA_CSUBSEP is the character that replaces dots in submodule names +** when searching for a C loader. +** LUA_LSUBSEP is the character that replaces dots in submodule names +** when searching for a Lua loader. +*/ +#if !defined(LUA_CSUBSEP) +#define LUA_CSUBSEP LUA_DIRSEP +#endif + +#if !defined(LUA_LSUBSEP) +#define LUA_LSUBSEP LUA_DIRSEP +#endif + + +/* prefix for open functions in C libraries */ +#define LUA_POF "luaopen_" + +/* separator for open functions in C libraries */ +#define LUA_OFSEP "_" + + +/* +** key for table in the registry that keeps handles +** for all loaded C libraries +*/ +static const char *const CLIBS = "_CLIBS"; + +#define LIB_FAIL "open" + + +#define setprogdir(L) ((void)0) + + +/* +** Special type equivalent to '(void*)' for functions in gcc +** (to suppress warnings when converting function pointers) +*/ +typedef void (*voidf)(void); + + +/* +** system-dependent functions +*/ + +/* +** unload library 'lib' +*/ +static void lsys_unloadlib (void *lib); + +/* +** load C library in file 'path'. If 'seeglb', load with all names in +** the library global. +** Returns the library; in case of error, returns NULL plus an +** error string in the stack. +*/ +static void *lsys_load (lua_State *L, const char *path, int seeglb); + +/* +** Try to find a function named 'sym' in library 'lib'. +** Returns the function; in case of error, returns NULL plus an +** error string in the stack. +*/ +static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym); + + + + +#if defined(LUA_USE_DLOPEN) /* { */ +/* +** {======================================================================== +** This is an implementation of loadlib based on the dlfcn interface. +** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, +** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least +** as an emulation layer on top of native functions. +** ========================================================================= +*/ + +#include + +/* +** Macro to convert pointer-to-void* to pointer-to-function. This cast +** is undefined according to ISO C, but POSIX assumes that it works. +** (The '__extension__' in gnu compilers is only to avoid warnings.) +*/ +#if defined(__GNUC__) +#define cast_func(p) (__extension__ (lua_CFunction)(p)) +#else +#define cast_func(p) ((lua_CFunction)(p)) +#endif + + +static void lsys_unloadlib (void *lib) { + dlclose(lib); +} + + +static void *lsys_load (lua_State *L, const char *path, int seeglb) { + void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); + if (l_unlikely(lib == NULL)) + lua_pushstring(L, dlerror()); + return lib; +} + + +static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = cast_func(dlsym(lib, sym)); + if (l_unlikely(f == NULL)) + lua_pushstring(L, dlerror()); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DLL) /* }{ */ +/* +** {====================================================================== +** This is an implementation of loadlib for Windows using native functions. +** ======================================================================= +*/ + +#include + + +/* +** optional flags for LoadLibraryEx +*/ +#if !defined(LUA_LLE_FLAGS) +#define LUA_LLE_FLAGS 0 +#endif + + +#undef setprogdir + + +/* +** Replace in the path (on the top of the stack) any occurrence +** of LUA_EXEC_DIR with the executable's path. +*/ +static void setprogdir (lua_State *L) { + char buff[MAX_PATH + 1]; + char *lb; + DWORD nsize = sizeof(buff)/sizeof(char); + DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */ + if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) + luaL_error(L, "unable to get ModuleFileName"); + else { + *lb = '\0'; /* cut name on the last '\\' to get the path */ + luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); + lua_remove(L, -2); /* remove original string */ + } +} + + + + +static void pusherror (lua_State *L) { + int error = GetLastError(); + char buffer[128]; + if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) + lua_pushstring(L, buffer); + else + lua_pushfstring(L, "system error %d\n", error); +} + +static void lsys_unloadlib (void *lib) { + FreeLibrary((HMODULE)lib); +} + + +static void *lsys_load (lua_State *L, const char *path, int seeglb) { + HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); + (void)(seeglb); /* not used: symbols are 'global' by default */ + if (lib == NULL) pusherror(L); + return lib; +} + + +static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)(voidf)GetProcAddress((HMODULE)lib, sym); + if (f == NULL) pusherror(L); + return f; +} + +/* }====================================================== */ + + +#else /* }{ */ +/* +** {====================================================== +** Fallback for other systems +** ======================================================= +*/ + +#undef LIB_FAIL +#define LIB_FAIL "absent" + + +#define DLMSG "dynamic libraries not enabled; check your Lua installation" + + +static void lsys_unloadlib (void *lib) { + (void)(lib); /* not used */ +} + + +static void *lsys_load (lua_State *L, const char *path, int seeglb) { + (void)(path); (void)(seeglb); /* not used */ + lua_pushliteral(L, DLMSG); + return NULL; +} + + +static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { + (void)(lib); (void)(sym); /* not used */ + lua_pushliteral(L, DLMSG); + return NULL; +} + +/* }====================================================== */ +#endif /* } */ + + +/* +** {================================================================== +** Set Paths +** =================================================================== +*/ + +/* +** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment +** variables that Lua check to set its paths. +*/ +#if !defined(LUA_PATH_VAR) +#define LUA_PATH_VAR "LUA_PATH" +#endif + +#if !defined(LUA_CPATH_VAR) +#define LUA_CPATH_VAR "LUA_CPATH" +#endif + + + +/* +** return registry.LUA_NOENV as a boolean +*/ +static int noenv (lua_State *L) { + int b; + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); + b = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + return b; +} + + +/* +** Set a path +*/ +static void setpath (lua_State *L, const char *fieldname, + const char *envname, + const char *dft) { + const char *dftmark; + const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX); + const char *path = getenv(nver); /* try versioned name */ + if (path == NULL) /* no versioned environment variable? */ + path = getenv(envname); /* try unversioned name */ + if (path == NULL || noenv(L)) /* no environment variable? */ + lua_pushstring(L, dft); /* use default */ + else if ((dftmark = strstr(path, LUA_PATH_SEP LUA_PATH_SEP)) == NULL) + lua_pushstring(L, path); /* nothing to change */ + else { /* path contains a ";;": insert default path in its place */ + size_t len = strlen(path); + luaL_Buffer b; + luaL_buffinit(L, &b); + if (path < dftmark) { /* is there a prefix before ';;'? */ + luaL_addlstring(&b, path, dftmark - path); /* add it */ + luaL_addchar(&b, *LUA_PATH_SEP); + } + luaL_addstring(&b, dft); /* add default */ + if (dftmark < path + len - 2) { /* is there a suffix after ';;'? */ + luaL_addchar(&b, *LUA_PATH_SEP); + luaL_addlstring(&b, dftmark + 2, (path + len - 2) - dftmark); + } + luaL_pushresult(&b); + } + setprogdir(L); + lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */ + lua_pop(L, 1); /* pop versioned variable name ('nver') */ +} + +/* }================================================================== */ + + +/* +** return registry.CLIBS[path] +*/ +static void *checkclib (lua_State *L, const char *path) { + void *plib; + lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); + lua_getfield(L, -1, path); + plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ + lua_pop(L, 2); /* pop CLIBS table and 'plib' */ + return plib; +} + + +/* +** registry.CLIBS[path] = plib -- for queries +** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries +*/ +static void addtoclib (lua_State *L, const char *path, void *plib) { + lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); + lua_pushlightuserdata(L, plib); + lua_pushvalue(L, -1); + lua_setfield(L, -3, path); /* CLIBS[path] = plib */ + lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ + lua_pop(L, 1); /* pop CLIBS table */ +} + + +/* +** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib +** handles in list CLIBS +*/ +static int gctm (lua_State *L) { + lua_Integer n = luaL_len(L, 1); + for (; n >= 1; n--) { /* for each handle, in reverse order */ + lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ + lsys_unloadlib(lua_touserdata(L, -1)); + lua_pop(L, 1); /* pop handle */ + } + return 0; +} + + + +/* error codes for 'lookforfunc' */ +#define ERRLIB 1 +#define ERRFUNC 2 + +/* +** Look for a C function named 'sym' in a dynamically loaded library +** 'path'. +** First, check whether the library is already loaded; if not, try +** to load it. +** Then, if 'sym' is '*', return true (as library has been loaded). +** Otherwise, look for symbol 'sym' in the library and push a +** C function with that symbol. +** Return 0 and 'true' or a function in the stack; in case of +** errors, return an error code and an error message in the stack. +*/ +static int lookforfunc (lua_State *L, const char *path, const char *sym) { + void *reg = checkclib(L, path); /* check loaded C libraries */ + if (reg == NULL) { /* must load library? */ + reg = lsys_load(L, path, *sym == '*'); /* global symbols if 'sym'=='*' */ + if (reg == NULL) return ERRLIB; /* unable to load library */ + addtoclib(L, path, reg); + } + if (*sym == '*') { /* loading only library (no function)? */ + lua_pushboolean(L, 1); /* return 'true' */ + return 0; /* no errors */ + } + else { + lua_CFunction f = lsys_sym(L, reg, sym); + if (f == NULL) + return ERRFUNC; /* unable to find function */ + lua_pushcfunction(L, f); /* else create new function */ + return 0; /* no errors */ + } +} + + +static int ll_loadlib (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + const char *init = luaL_checkstring(L, 2); + int stat = lookforfunc(L, path, init); + if (l_likely(stat == 0)) /* no errors? */ + return 1; /* return the loaded function */ + else { /* error; error message is on stack top */ + luaL_pushfail(L); + lua_insert(L, -2); + lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); + return 3; /* return fail, error message, and where */ + } +} + + + +/* +** {====================================================== +** 'require' function +** ======================================================= +*/ + + +static int readable (const char *filename) { + FILE *f = fopen(filename, "r"); /* try to open file */ + if (f == NULL) return 0; /* open failed */ + fclose(f); + return 1; +} + + +/* +** Get the next name in '*path' = 'name1;name2;name3;...', changing +** the ending ';' to '\0' to create a zero-terminated string. Return +** NULL when list ends. +*/ +static const char *getnextfilename (char **path, char *end) { + char *sep; + char *name = *path; + if (name == end) + return NULL; /* no more names */ + else if (*name == '\0') { /* from previous iteration? */ + *name = *LUA_PATH_SEP; /* restore separator */ + name++; /* skip it */ + } + sep = strchr(name, *LUA_PATH_SEP); /* find next separator */ + if (sep == NULL) /* separator not found? */ + sep = end; /* name goes until the end */ + *sep = '\0'; /* finish file name */ + *path = sep; /* will start next search from here */ + return name; +} + + +/* +** Given a path such as ";blabla.so;blublu.so", pushes the string +** +** no file 'blabla.so' +** no file 'blublu.so' +*/ +static void pusherrornotfound (lua_State *L, const char *path) { + luaL_Buffer b; + luaL_buffinit(L, &b); + luaL_addstring(&b, "no file '"); + luaL_addgsub(&b, path, LUA_PATH_SEP, "'\n\tno file '"); + luaL_addstring(&b, "'"); + luaL_pushresult(&b); +} + + +static const char *searchpath (lua_State *L, const char *name, + const char *path, + const char *sep, + const char *dirsep) { + luaL_Buffer buff; + char *pathname; /* path with name inserted */ + char *endpathname; /* its end */ + const char *filename; + /* separator is non-empty and appears in 'name'? */ + if (*sep != '\0' && strchr(name, *sep) != NULL) + name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ + luaL_buffinit(L, &buff); + /* add path to the buffer, replacing marks ('?') with the file name */ + luaL_addgsub(&buff, path, LUA_PATH_MARK, name); + luaL_addchar(&buff, '\0'); + pathname = luaL_buffaddr(&buff); /* writable list of file names */ + endpathname = pathname + luaL_bufflen(&buff) - 1; + while ((filename = getnextfilename(&pathname, endpathname)) != NULL) { + if (readable(filename)) /* does file exist and is readable? */ + return lua_pushstring(L, filename); /* save and return name */ + } + luaL_pushresult(&buff); /* push path to create error message */ + pusherrornotfound(L, lua_tostring(L, -1)); /* create error message */ + return NULL; /* not found */ +} + + +static int ll_searchpath (lua_State *L) { + const char *f = searchpath(L, luaL_checkstring(L, 1), + luaL_checkstring(L, 2), + luaL_optstring(L, 3, "."), + luaL_optstring(L, 4, LUA_DIRSEP)); + if (f != NULL) return 1; + else { /* error message is on top of the stack */ + luaL_pushfail(L); + lua_insert(L, -2); + return 2; /* return fail + error message */ + } +} + + +static const char *findfile (lua_State *L, const char *name, + const char *pname, + const char *dirsep) { + const char *path; + lua_getfield(L, lua_upvalueindex(1), pname); + path = lua_tostring(L, -1); + if (l_unlikely(path == NULL)) + luaL_error(L, "'package.%s' must be a string", pname); + return searchpath(L, name, path, ".", dirsep); +} + + +static int checkload (lua_State *L, int stat, const char *filename) { + if (l_likely(stat)) { /* module loaded successfully? */ + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; /* return open function and file name */ + } + else + return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); +} + + +static int searcher_Lua (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + filename = findfile(L, name, "path", LUA_LSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); +} + + +/* +** Try to find a load function for module 'modname' at file 'filename'. +** First, change '.' to '_' in 'modname'; then, if 'modname' has +** the form X-Y (that is, it has an "ignore mark"), build a function +** name "luaopen_X" and look for it. (For compatibility, if that +** fails, it also tries "luaopen_Y".) If there is no ignore mark, +** look for a function named "luaopen_modname". +*/ +static int loadfunc (lua_State *L, const char *filename, const char *modname) { + const char *openfunc; + const char *mark; + modname = luaL_gsub(L, modname, ".", LUA_OFSEP); + mark = strchr(modname, *LUA_IGMARK); + if (mark) { + int stat; + openfunc = lua_pushlstring(L, modname, mark - modname); + openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc); + stat = lookforfunc(L, filename, openfunc); + if (stat != ERRFUNC) return stat; + modname = mark + 1; /* else go ahead and try old-style name */ + } + openfunc = lua_pushfstring(L, LUA_POF"%s", modname); + return lookforfunc(L, filename, openfunc); +} + + +static int searcher_C (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (loadfunc(L, filename, name) == 0), filename); +} + + +static int searcher_Croot (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + const char *p = strchr(name, '.'); + int stat; + if (p == NULL) return 0; /* is root */ + lua_pushlstring(L, name, p - name); + filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* root not found */ + if ((stat = loadfunc(L, filename, name)) != 0) { + if (stat != ERRFUNC) + return checkload(L, 0, filename); /* real error */ + else { /* open function not found */ + lua_pushfstring(L, "no module '%s' in file '%s'", name, filename); + return 1; + } + } + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; +} + + +static int searcher_preload (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); + if (lua_getfield(L, -1, name) == LUA_TNIL) { /* not found? */ + lua_pushfstring(L, "no field package.preload['%s']", name); + return 1; + } + else { + lua_pushliteral(L, ":preload:"); + return 2; + } +} + + +static void findloader (lua_State *L, const char *name) { + int i; + luaL_Buffer msg; /* to build error message */ + /* push 'package.searchers' to index 3 in the stack */ + if (l_unlikely(lua_getfield(L, lua_upvalueindex(1), "searchers") + != LUA_TTABLE)) + luaL_error(L, "'package.searchers' must be a table"); + luaL_buffinit(L, &msg); + /* iterate over available searchers to find a loader */ + for (i = 1; ; i++) { + luaL_addstring(&msg, "\n\t"); /* error-message prefix */ + if (l_unlikely(lua_rawgeti(L, 3, i) == LUA_TNIL)) { /* no more searchers? */ + lua_pop(L, 1); /* remove nil */ + luaL_buffsub(&msg, 2); /* remove prefix */ + luaL_pushresult(&msg); /* create error message */ + luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1)); + } + lua_pushstring(L, name); + lua_call(L, 1, 2); /* call it */ + if (lua_isfunction(L, -2)) /* did it find a loader? */ + return; /* module loader found */ + else if (lua_isstring(L, -2)) { /* searcher returned error message? */ + lua_pop(L, 1); /* remove extra return */ + luaL_addvalue(&msg); /* concatenate error message */ + } + else { /* no error message */ + lua_pop(L, 2); /* remove both returns */ + luaL_buffsub(&msg, 2); /* remove prefix */ + } + } +} + + +static int ll_require (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_settop(L, 1); /* LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_getfield(L, 2, name); /* LOADED[name] */ + if (lua_toboolean(L, -1)) /* is it there? */ + return 1; /* package is already loaded */ + /* else must load package */ + lua_pop(L, 1); /* remove 'getfield' result */ + findloader(L, name); + lua_rotate(L, -2, 1); /* function <-> loader data */ + lua_pushvalue(L, 1); /* name is 1st argument to module loader */ + lua_pushvalue(L, -3); /* loader data is 2nd argument */ + /* stack: ...; loader data; loader function; mod. name; loader data */ + lua_call(L, 2, 1); /* run loader to load module */ + /* stack: ...; loader data; result from loader */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* LOADED[name] = returned value */ + else + lua_pop(L, 1); /* pop nil */ + if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_copy(L, -1, -2); /* replace loader result */ + lua_setfield(L, 2, name); /* LOADED[name] = true */ + } + lua_rotate(L, -2, 1); /* loader data <-> module result */ + return 2; /* return module result and loader data */ +} + +/* }====================================================== */ + + + + +static const luaL_Reg pk_funcs[] = { + {"loadlib", ll_loadlib}, + {"searchpath", ll_searchpath}, + /* placeholders */ + {"preload", NULL}, + {"cpath", NULL}, + {"path", NULL}, + {"searchers", NULL}, + {"loaded", NULL}, + {NULL, NULL} +}; + + +static const luaL_Reg ll_funcs[] = { + {"require", ll_require}, + {NULL, NULL} +}; + + +static void createsearcherstable (lua_State *L) { + static const lua_CFunction searchers[] = { + searcher_preload, + searcher_Lua, + searcher_C, + searcher_Croot, + NULL + }; + int i; + /* create 'searchers' table */ + lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); + /* fill it with predefined searchers */ + for (i=0; searchers[i] != NULL; i++) { + lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ + lua_pushcclosure(L, searchers[i], 1); + lua_rawseti(L, -2, i+1); + } + lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ +} + + +/* +** create table CLIBS to keep track of loaded C libraries, +** setting a finalizer to close all libraries when closing state. +*/ +static void createclibstable (lua_State *L) { + luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */ + lua_createtable(L, 0, 1); /* create metatable for CLIBS */ + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ + lua_setmetatable(L, -2); +} + + +LUAMOD_API int luaopen_package (lua_State *L) { + createclibstable(L); + luaL_newlib(L, pk_funcs); /* create 'package' table */ + createsearcherstable(L); + /* set paths */ + setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT); + setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT); + /* store config information */ + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" + LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); + lua_setfield(L, -2, "config"); + /* set field 'loaded' */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_setfield(L, -2, "loaded"); + /* set field 'preload' */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); + lua_setfield(L, -2, "preload"); + lua_pushglobaltable(L); + lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ + luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ + lua_pop(L, 1); /* pop global table */ + return 1; /* return 'package' table */ +} + diff --git a/User/system/lua/src/lobject.c b/User/system/lua/src/lobject.c new file mode 100644 index 0000000..9cfa522 --- /dev/null +++ b/User/system/lua/src/lobject.c @@ -0,0 +1,602 @@ +/* +** $Id: lobject.c $ +** Some generic functions over Lua objects +** See Copyright Notice in lua.h +*/ + +#define lobject_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lctype.h" +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "lvm.h" + + +/* +** Computes ceil(log2(x)) +*/ +int luaO_ceillog2 (unsigned int x) { + static const lu_byte log_2[256] = { /* log_2[i] = ceil(log2(i - 1)) */ + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + }; + int l = 0; + x--; + while (x >= 256) { l += 8; x >>= 8; } + return l + log_2[x]; +} + + +static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, + lua_Integer v2) { + switch (op) { + case LUA_OPADD: return intop(+, v1, v2); + case LUA_OPSUB:return intop(-, v1, v2); + case LUA_OPMUL:return intop(*, v1, v2); + case LUA_OPMOD: return luaV_mod(L, v1, v2); + case LUA_OPIDIV: return luaV_idiv(L, v1, v2); + case LUA_OPBAND: return intop(&, v1, v2); + case LUA_OPBOR: return intop(|, v1, v2); + case LUA_OPBXOR: return intop(^, v1, v2); + case LUA_OPSHL: return luaV_shiftl(v1, v2); + case LUA_OPSHR: return luaV_shiftr(v1, v2); + case LUA_OPUNM: return intop(-, 0, v1); + case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1); + default: lua_assert(0); return 0; + } +} + + +static lua_Number numarith (lua_State *L, int op, lua_Number v1, + lua_Number v2) { + switch (op) { + case LUA_OPADD: return luai_numadd(L, v1, v2); + case LUA_OPSUB: return luai_numsub(L, v1, v2); + case LUA_OPMUL: return luai_nummul(L, v1, v2); + case LUA_OPDIV: return luai_numdiv(L, v1, v2); + case LUA_OPPOW: return luai_numpow(L, v1, v2); + case LUA_OPIDIV: return luai_numidiv(L, v1, v2); + case LUA_OPUNM: return luai_numunm(L, v1); + case LUA_OPMOD: return luaV_modf(L, v1, v2); + default: lua_assert(0); return 0; + } +} + + +int luaO_rawarith (lua_State *L, int op, const TValue *p1, const TValue *p2, + TValue *res) { + switch (op) { + case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: + case LUA_OPSHL: case LUA_OPSHR: + case LUA_OPBNOT: { /* operate only on integers */ + lua_Integer i1; lua_Integer i2; + if (tointegerns(p1, &i1) && tointegerns(p2, &i2)) { + setivalue(res, intarith(L, op, i1, i2)); + return 1; + } + else return 0; /* fail */ + } + case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */ + lua_Number n1; lua_Number n2; + if (tonumberns(p1, n1) && tonumberns(p2, n2)) { + setfltvalue(res, numarith(L, op, n1, n2)); + return 1; + } + else return 0; /* fail */ + } + default: { /* other operations */ + lua_Number n1; lua_Number n2; + if (ttisinteger(p1) && ttisinteger(p2)) { + setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); + return 1; + } + else if (tonumberns(p1, n1) && tonumberns(p2, n2)) { + setfltvalue(res, numarith(L, op, n1, n2)); + return 1; + } + else return 0; /* fail */ + } + } +} + + +void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, + StkId res) { + if (!luaO_rawarith(L, op, p1, p2, s2v(res))) { + /* could not perform raw operation; try metamethod */ + luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD)); + } +} + + +int luaO_hexavalue (int c) { + if (lisdigit(c)) return c - '0'; + else return (ltolower(c) - 'a') + 10; +} + + +static int isneg (const char **s) { + if (**s == '-') { (*s)++; return 1; } + else if (**s == '+') (*s)++; + return 0; +} + + + +/* +** {================================================================== +** Lua's implementation for 'lua_strx2number' +** =================================================================== +*/ + +#if !defined(lua_strx2number) + +/* maximum number of significant digits to read (to avoid overflows + even with single floats) */ +#define MAXSIGDIG 30 + +/* +** convert a hexadecimal numeric string to a number, following +** C99 specification for 'strtod' +*/ +static lua_Number lua_strx2number (const char *s, char **endptr) { + int dot = lua_getlocaledecpoint(); + lua_Number r = l_mathop(0.0); /* result (accumulator) */ + int sigdig = 0; /* number of significant digits */ + int nosigdig = 0; /* number of non-significant digits */ + int e = 0; /* exponent correction */ + int neg; /* 1 if number is negative */ + int hasdot = 0; /* true after seen a dot */ + *endptr = cast_charp(s); /* nothing is valid yet */ + while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ + neg = isneg(&s); /* check sign */ + if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ + return l_mathop(0.0); /* invalid format (no '0x') */ + for (s += 2; ; s++) { /* skip '0x' and read numeral */ + if (*s == dot) { + if (hasdot) break; /* second dot? stop loop */ + else hasdot = 1; + } + else if (lisxdigit(cast_uchar(*s))) { + if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */ + nosigdig++; + else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */ + r = (r * l_mathop(16.0)) + luaO_hexavalue(*s); + else e++; /* too many digits; ignore, but still count for exponent */ + if (hasdot) e--; /* decimal digit? correct exponent */ + } + else break; /* neither a dot nor a digit */ + } + if (nosigdig + sigdig == 0) /* no digits? */ + return l_mathop(0.0); /* invalid format */ + *endptr = cast_charp(s); /* valid up to here */ + e *= 4; /* each digit multiplies/divides value by 2^4 */ + if (*s == 'p' || *s == 'P') { /* exponent part? */ + int exp1 = 0; /* exponent value */ + int neg1; /* exponent sign */ + s++; /* skip 'p' */ + neg1 = isneg(&s); /* sign */ + if (!lisdigit(cast_uchar(*s))) + return l_mathop(0.0); /* invalid; must have at least one digit */ + while (lisdigit(cast_uchar(*s))) /* read exponent */ + exp1 = exp1 * 10 + *(s++) - '0'; + if (neg1) exp1 = -exp1; + e += exp1; + *endptr = cast_charp(s); /* valid up to here */ + } + if (neg) r = -r; + return l_mathop(ldexp)(r, e); +} + +#endif +/* }====================================================== */ + + +/* maximum length of a numeral to be converted to a number */ +#if !defined (L_MAXLENNUM) +#define L_MAXLENNUM 200 +#endif + +/* +** Convert string 's' to a Lua number (put in 'result'). Return NULL on +** fail or the address of the ending '\0' on success. ('mode' == 'x') +** means a hexadecimal numeral. +*/ +static const char *l_str2dloc (const char *s, lua_Number *result, int mode) { + char *endptr; + *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */ + : lua_str2number(s, &endptr); + if (endptr == s) return NULL; /* nothing recognized? */ + while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */ + return (*endptr == '\0') ? endptr : NULL; /* OK iff no trailing chars */ +} + + +/* +** Convert string 's' to a Lua number (put in 'result') handling the +** current locale. +** This function accepts both the current locale or a dot as the radix +** mark. If the conversion fails, it may mean number has a dot but +** locale accepts something else. In that case, the code copies 's' +** to a buffer (because 's' is read-only), changes the dot to the +** current locale radix mark, and tries to convert again. +** The variable 'mode' checks for special characters in the string: +** - 'n' means 'inf' or 'nan' (which should be rejected) +** - 'x' means a hexadecimal numeral +** - '.' just optimizes the search for the common case (no special chars) +*/ +static const char *l_str2d (const char *s, lua_Number *result) { + const char *endptr; + const char *pmode = strpbrk(s, ".xXnN"); /* look for special chars */ + int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0; + if (mode == 'n') /* reject 'inf' and 'nan' */ + return NULL; + endptr = l_str2dloc(s, result, mode); /* try to convert */ + if (endptr == NULL) { /* failed? may be a different locale */ + char buff[L_MAXLENNUM + 1]; + const char *pdot = strchr(s, '.'); + if (pdot == NULL || strlen(s) > L_MAXLENNUM) + return NULL; /* string too long or no dot; fail */ + strcpy(buff, s); /* copy string to buffer */ + buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */ + endptr = l_str2dloc(buff, result, mode); /* try again */ + if (endptr != NULL) + endptr = s + (endptr - buff); /* make relative to 's' */ + } + return endptr; +} + + +#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10) +#define MAXLASTD cast_int(LUA_MAXINTEGER % 10) + +static const char *l_str2int (const char *s, lua_Integer *result) { + lua_Unsigned a = 0; + int empty = 1; + int neg; + while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ + neg = isneg(&s); + if (s[0] == '0' && + (s[1] == 'x' || s[1] == 'X')) { /* hex? */ + s += 2; /* skip '0x' */ + for (; lisxdigit(cast_uchar(*s)); s++) { + a = a * 16 + luaO_hexavalue(*s); + empty = 0; + } + } + else { /* decimal */ + for (; lisdigit(cast_uchar(*s)); s++) { + int d = *s - '0'; + if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */ + return NULL; /* do not accept it (as integer) */ + a = a * 10 + d; + empty = 0; + } + } + while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */ + if (empty || *s != '\0') return NULL; /* something wrong in the numeral */ + else { + *result = l_castU2S((neg) ? 0u - a : a); + return s; + } +} + + +size_t luaO_str2num (const char *s, TValue *o) { + lua_Integer i; lua_Number n; + const char *e; + if ((e = l_str2int(s, &i)) != NULL) { /* try as an integer */ + setivalue(o, i); + } + else if ((e = l_str2d(s, &n)) != NULL) { /* else try as a float */ + setfltvalue(o, n); + } + else + return 0; /* conversion failed */ + return (e - s) + 1; /* success; return string size */ +} + + +int luaO_utf8esc (char *buff, unsigned long x) { + int n = 1; /* number of bytes put in buffer (backwards) */ + lua_assert(x <= 0x7FFFFFFFu); + if (x < 0x80) /* ascii? */ + buff[UTF8BUFFSZ - 1] = cast_char(x); + else { /* need continuation bytes */ + unsigned int mfb = 0x3f; /* maximum that fits in first byte */ + do { /* add continuation bytes */ + buff[UTF8BUFFSZ - (n++)] = cast_char(0x80 | (x & 0x3f)); + x >>= 6; /* remove added bits */ + mfb >>= 1; /* now there is one less bit available in first byte */ + } while (x > mfb); /* still needs continuation byte? */ + buff[UTF8BUFFSZ - n] = cast_char((~mfb << 1) | x); /* add first byte */ + } + return n; +} + + +/* +** Maximum length of the conversion of a number to a string. Must be +** enough to accommodate both LUA_INTEGER_FMT and LUA_NUMBER_FMT. +** (For a long long int, this is 19 digits plus a sign and a final '\0', +** adding to 21. For a long double, it can go to a sign, 33 digits, +** the dot, an exponent letter, an exponent sign, 5 exponent digits, +** and a final '\0', adding to 43.) +*/ +#define MAXNUMBER2STR 44 + + +/* +** Convert a number object to a string, adding it to a buffer +*/ +static int tostringbuff (TValue *obj, char *buff) { + int len; + lua_assert(ttisnumber(obj)); + if (ttisinteger(obj)) + len = lua_integer2str(buff, MAXNUMBER2STR, ivalue(obj)); + else { + len = lua_number2str(buff, MAXNUMBER2STR, fltvalue(obj)); + if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */ + buff[len++] = lua_getlocaledecpoint(); + buff[len++] = '0'; /* adds '.0' to result */ + } + } + return len; +} + + +/* +** Convert a number object to a Lua string, replacing the value at 'obj' +*/ +void luaO_tostring (lua_State *L, TValue *obj) { + char buff[MAXNUMBER2STR]; + int len = tostringbuff(obj, buff); + setsvalue(L, obj, luaS_newlstr(L, buff, len)); +} + + + + +/* +** {================================================================== +** 'luaO_pushvfstring' +** =================================================================== +*/ + +/* +** Size for buffer space used by 'luaO_pushvfstring'. It should be +** (LUA_IDSIZE + MAXNUMBER2STR) + a minimal space for basic messages, +** so that 'luaG_addinfo' can work directly on the buffer. +*/ +#define BUFVFS (LUA_IDSIZE + MAXNUMBER2STR + 95) + +/* buffer used by 'luaO_pushvfstring' */ +typedef struct BuffFS { + lua_State *L; + int pushed; /* true if there is a part of the result on the stack */ + int blen; /* length of partial string in 'space' */ + char space[BUFVFS]; /* holds last part of the result */ +} BuffFS; + + +/* +** Push given string to the stack, as part of the result, and +** join it to previous partial result if there is one. +** It may call 'luaV_concat' while using one slot from EXTRA_STACK. +** This call cannot invoke metamethods, as both operands must be +** strings. It can, however, raise an error if the result is too +** long. In that case, 'luaV_concat' frees the extra slot before +** raising the error. +*/ +static void pushstr (BuffFS *buff, const char *str, size_t lstr) { + lua_State *L = buff->L; + setsvalue2s(L, L->top.p, luaS_newlstr(L, str, lstr)); + L->top.p++; /* may use one slot from EXTRA_STACK */ + if (!buff->pushed) /* no previous string on the stack? */ + buff->pushed = 1; /* now there is one */ + else /* join previous string with new one */ + luaV_concat(L, 2); +} + + +/* +** empty the buffer space into the stack +*/ +static void clearbuff (BuffFS *buff) { + pushstr(buff, buff->space, buff->blen); /* push buffer contents */ + buff->blen = 0; /* space now is empty */ +} + + +/* +** Get a space of size 'sz' in the buffer. If buffer has not enough +** space, empty it. 'sz' must fit in an empty buffer. +*/ +static char *getbuff (BuffFS *buff, int sz) { + lua_assert(buff->blen <= BUFVFS); lua_assert(sz <= BUFVFS); + if (sz > BUFVFS - buff->blen) /* not enough space? */ + clearbuff(buff); + return buff->space + buff->blen; +} + + +#define addsize(b,sz) ((b)->blen += (sz)) + + +/* +** Add 'str' to the buffer. If string is larger than the buffer space, +** push the string directly to the stack. +*/ +static void addstr2buff (BuffFS *buff, const char *str, size_t slen) { + if (slen <= BUFVFS) { /* does string fit into buffer? */ + char *bf = getbuff(buff, cast_int(slen)); + memcpy(bf, str, slen); /* add string to buffer */ + addsize(buff, cast_int(slen)); + } + else { /* string larger than buffer */ + clearbuff(buff); /* string comes after buffer's content */ + pushstr(buff, str, slen); /* push string */ + } +} + + +/* +** Add a numeral to the buffer. +*/ +static void addnum2buff (BuffFS *buff, TValue *num) { + char *numbuff = getbuff(buff, MAXNUMBER2STR); + int len = tostringbuff(num, numbuff); /* format number into 'numbuff' */ + addsize(buff, len); +} + + +/* +** this function handles only '%d', '%c', '%f', '%p', '%s', and '%%' + conventional formats, plus Lua-specific '%I' and '%U' +*/ +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { + BuffFS buff; /* holds last part of the result */ + const char *e; /* points to next '%' */ + buff.pushed = buff.blen = 0; + buff.L = L; + while ((e = strchr(fmt, '%')) != NULL) { + addstr2buff(&buff, fmt, e - fmt); /* add 'fmt' up to '%' */ + switch (*(e + 1)) { /* conversion specifier */ + case 's': { /* zero-terminated string */ + const char *s = va_arg(argp, char *); + if (s == NULL) s = "(null)"; + addstr2buff(&buff, s, strlen(s)); + break; + } + case 'c': { /* an 'int' as a character */ + char c = cast_uchar(va_arg(argp, int)); + addstr2buff(&buff, &c, sizeof(char)); + break; + } + case 'd': { /* an 'int' */ + TValue num; + setivalue(&num, va_arg(argp, int)); + addnum2buff(&buff, &num); + break; + } + case 'I': { /* a 'lua_Integer' */ + TValue num; + setivalue(&num, cast(lua_Integer, va_arg(argp, l_uacInt))); + addnum2buff(&buff, &num); + break; + } + case 'f': { /* a 'lua_Number' */ + TValue num; + setfltvalue(&num, cast_num(va_arg(argp, l_uacNumber))); + addnum2buff(&buff, &num); + break; + } + case 'p': { /* a pointer */ + const int sz = 3 * sizeof(void*) + 8; /* enough space for '%p' */ + char *bf = getbuff(&buff, sz); + void *p = va_arg(argp, void *); + int len = lua_pointer2str(bf, sz, p); + addsize(&buff, len); + break; + } + case 'U': { /* a 'long' as a UTF-8 sequence */ + char bf[UTF8BUFFSZ]; + int len = luaO_utf8esc(bf, va_arg(argp, long)); + addstr2buff(&buff, bf + UTF8BUFFSZ - len, len); + break; + } + case '%': { + addstr2buff(&buff, "%", 1); + break; + } + default: { + luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'", + *(e + 1)); + } + } + fmt = e + 2; /* skip '%' and the specifier */ + } + addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */ + clearbuff(&buff); /* empty buffer into the stack */ + lua_assert(buff.pushed == 1); + return getstr(tsvalue(s2v(L->top.p - 1))); +} + + +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; +} + +/* }================================================================== */ + + +#define RETS "..." +#define PRE "[string \"" +#define POS "\"]" + +#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) + +void luaO_chunkid (char *out, const char *source, size_t srclen) { + size_t bufflen = LUA_IDSIZE; /* free space in buffer */ + if (*source == '=') { /* 'literal' source */ + if (srclen <= bufflen) /* small enough? */ + memcpy(out, source + 1, srclen * sizeof(char)); + else { /* truncate it */ + addstr(out, source + 1, bufflen - 1); + *out = '\0'; + } + } + else if (*source == '@') { /* file name */ + if (srclen <= bufflen) /* small enough? */ + memcpy(out, source + 1, srclen * sizeof(char)); + else { /* add '...' before rest of name */ + addstr(out, RETS, LL(RETS)); + bufflen -= LL(RETS); + memcpy(out, source + 1 + srclen - bufflen, bufflen * sizeof(char)); + } + } + else { /* string; format as [string "source"] */ + const char *nl = strchr(source, '\n'); /* find first new line (if any) */ + addstr(out, PRE, LL(PRE)); /* add prefix */ + bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ + if (srclen < bufflen && nl == NULL) { /* small one-line source? */ + addstr(out, source, srclen); /* keep it */ + } + else { + if (nl != NULL) srclen = nl - source; /* stop at first newline */ + if (srclen > bufflen) srclen = bufflen; + addstr(out, source, srclen); + addstr(out, RETS, LL(RETS)); + } + memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); + } +} + diff --git a/User/system/lua/src/lobject.h b/User/system/lua/src/lobject.h new file mode 100644 index 0000000..980e42f --- /dev/null +++ b/User/system/lua/src/lobject.h @@ -0,0 +1,813 @@ +/* +** $Id: lobject.h $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + + +#ifndef lobject_h +#define lobject_h + + +#include + + +#include "llimits.h" +#include "lua.h" + + +/* +** Extra types for collectable non-values +*/ +#define LUA_TUPVAL LUA_NUMTYPES /* upvalues */ +#define LUA_TPROTO (LUA_NUMTYPES+1) /* function prototypes */ +#define LUA_TDEADKEY (LUA_NUMTYPES+2) /* removed keys in tables */ + + + +/* +** number of all possible types (including LUA_TNONE but excluding DEADKEY) +*/ +#define LUA_TOTALTYPES (LUA_TPROTO + 2) + + +/* +** tags for Tagged Values have the following use of bits: +** bits 0-3: actual tag (a LUA_T* constant) +** bits 4-5: variant bits +** bit 6: whether value is collectable +*/ + +/* add variant bits to a type */ +#define makevariant(t,v) ((t) | ((v) << 4)) + + + +/* +** Union of all Lua values +*/ +typedef union Value { + struct GCObject *gc; /* collectable objects */ + void *p; /* light userdata */ + lua_CFunction f; /* light C functions */ + lua_Integer i; /* integer numbers */ + lua_Number n; /* float numbers */ + /* not used, but may avoid warnings for uninitialized value */ + lu_byte ub; +} Value; + + +/* +** Tagged Values. This is the basic representation of values in Lua: +** an actual value plus a tag with its type. +*/ + +#define TValuefields Value value_; lu_byte tt_ + +typedef struct TValue { + TValuefields; +} TValue; + + +#define val_(o) ((o)->value_) +#define valraw(o) (val_(o)) + + +/* raw type tag of a TValue */ +#define rawtt(o) ((o)->tt_) + +/* tag with no variants (bits 0-3) */ +#define novariant(t) ((t) & 0x0F) + +/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ +#define withvariant(t) ((t) & 0x3F) +#define ttypetag(o) withvariant(rawtt(o)) + +/* type of a TValue */ +#define ttype(o) (novariant(rawtt(o))) + + +/* Macros to test type */ +#define checktag(o,t) (rawtt(o) == (t)) +#define checktype(o,t) (ttype(o) == (t)) + + +/* Macros for internal tests */ + +/* collectable object has the same tag as the original value */ +#define righttt(obj) (ttypetag(obj) == gcvalue(obj)->tt) + +/* +** Any value being manipulated by the program either is non +** collectable, or the collectable object has the right tag +** and it is not dead. The option 'L == NULL' allows other +** macros using this one to be used where L is not available. +*/ +#define checkliveness(L,obj) \ + ((void)L, lua_longassert(!iscollectable(obj) || \ + (righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj)))))) + + +/* Macros to set values */ + +/* set a value's tag */ +#define settt_(o,t) ((o)->tt_=(t)) + + +/* main macro to copy values (from 'obj2' to 'obj1') */ +#define setobj(L,obj1,obj2) \ + { TValue *io1=(obj1); const TValue *io2=(obj2); \ + io1->value_ = io2->value_; settt_(io1, io2->tt_); \ + checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); } + +/* +** Different types of assignments, according to source and destination. +** (They are mostly equal now, but may be different in the future.) +*/ + +/* from stack to stack */ +#define setobjs2s(L,o1,o2) setobj(L,s2v(o1),s2v(o2)) +/* to stack (not from same stack) */ +#define setobj2s(L,o1,o2) setobj(L,s2v(o1),o2) +/* from table to same table */ +#define setobjt2t setobj +/* to new object */ +#define setobj2n setobj +/* to table */ +#define setobj2t setobj + + +/* +** Entries in a Lua stack. Field 'tbclist' forms a list of all +** to-be-closed variables active in this stack. Dummy entries are +** used when the distance between two tbc variables does not fit +** in an unsigned short. They are represented by delta==0, and +** their real delta is always the maximum value that fits in +** that field. +*/ +typedef union StackValue { + TValue val; + struct { + TValuefields; + unsigned short delta; + } tbclist; +} StackValue; + + +/* index to stack elements */ +typedef StackValue *StkId; + + +/* +** When reallocating the stack, change all pointers to the stack into +** proper offsets. +*/ +typedef union { + StkId p; /* actual pointer */ + ptrdiff_t offset; /* used while the stack is being reallocated */ +} StkIdRel; + + +/* convert a 'StackValue' to a 'TValue' */ +#define s2v(o) (&(o)->val) + + + +/* +** {================================================================== +** Nil +** =================================================================== +*/ + +/* Standard nil */ +#define LUA_VNIL makevariant(LUA_TNIL, 0) + +/* Empty slot (which might be different from a slot containing nil) */ +#define LUA_VEMPTY makevariant(LUA_TNIL, 1) + +/* Value returned for a key not found in a table (absent key) */ +#define LUA_VABSTKEY makevariant(LUA_TNIL, 2) + + +/* macro to test for (any kind of) nil */ +#define ttisnil(v) checktype((v), LUA_TNIL) + + +/* macro to test for a standard nil */ +#define ttisstrictnil(o) checktag((o), LUA_VNIL) + + +#define setnilvalue(obj) settt_(obj, LUA_VNIL) + + +#define isabstkey(v) checktag((v), LUA_VABSTKEY) + + +/* +** macro to detect non-standard nils (used only in assertions) +*/ +#define isnonstrictnil(v) (ttisnil(v) && !ttisstrictnil(v)) + + +/* +** By default, entries with any kind of nil are considered empty. +** (In any definition, values associated with absent keys must also +** be accepted as empty.) +*/ +#define isempty(v) ttisnil(v) + + +/* macro defining a value corresponding to an absent key */ +#define ABSTKEYCONSTANT {NULL}, LUA_VABSTKEY + + +/* mark an entry as empty */ +#define setempty(v) settt_(v, LUA_VEMPTY) + + + +/* }================================================================== */ + + +/* +** {================================================================== +** Booleans +** =================================================================== +*/ + + +#define LUA_VFALSE makevariant(LUA_TBOOLEAN, 0) +#define LUA_VTRUE makevariant(LUA_TBOOLEAN, 1) + +#define ttisboolean(o) checktype((o), LUA_TBOOLEAN) +#define ttisfalse(o) checktag((o), LUA_VFALSE) +#define ttistrue(o) checktag((o), LUA_VTRUE) + + +#define l_isfalse(o) (ttisfalse(o) || ttisnil(o)) + + +#define setbfvalue(obj) settt_(obj, LUA_VFALSE) +#define setbtvalue(obj) settt_(obj, LUA_VTRUE) + +/* }================================================================== */ + + +/* +** {================================================================== +** Threads +** =================================================================== +*/ + +#define LUA_VTHREAD makevariant(LUA_TTHREAD, 0) + +#define ttisthread(o) checktag((o), ctb(LUA_VTHREAD)) + +#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc)) + +#define setthvalue(L,obj,x) \ + { TValue *io = (obj); lua_State *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VTHREAD)); \ + checkliveness(L,io); } + +#define setthvalue2s(L,o,t) setthvalue(L,s2v(o),t) + +/* }================================================================== */ + + +/* +** {================================================================== +** Collectable Objects +** =================================================================== +*/ + +/* +** Common Header for all collectable objects (in macro form, to be +** included in other objects) +*/ +#define CommonHeader struct GCObject *next; lu_byte tt; lu_byte marked + + +/* Common type for all collectable objects */ +typedef struct GCObject { + CommonHeader; +} GCObject; + + +/* Bit mark for collectable types */ +#define BIT_ISCOLLECTABLE (1 << 6) + +#define iscollectable(o) (rawtt(o) & BIT_ISCOLLECTABLE) + +/* mark a tag as collectable */ +#define ctb(t) ((t) | BIT_ISCOLLECTABLE) + +#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) + +#define gcvalueraw(v) ((v).gc) + +#define setgcovalue(L,obj,x) \ + { TValue *io = (obj); GCObject *i_g=(x); \ + val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); } + +/* }================================================================== */ + + +/* +** {================================================================== +** Numbers +** =================================================================== +*/ + +/* Variant tags for numbers */ +#define LUA_VNUMINT makevariant(LUA_TNUMBER, 0) /* integer numbers */ +#define LUA_VNUMFLT makevariant(LUA_TNUMBER, 1) /* float numbers */ + +#define ttisnumber(o) checktype((o), LUA_TNUMBER) +#define ttisfloat(o) checktag((o), LUA_VNUMFLT) +#define ttisinteger(o) checktag((o), LUA_VNUMINT) + +#define nvalue(o) check_exp(ttisnumber(o), \ + (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o))) +#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n) +#define ivalue(o) check_exp(ttisinteger(o), val_(o).i) + +#define fltvalueraw(v) ((v).n) +#define ivalueraw(v) ((v).i) + +#define setfltvalue(obj,x) \ + { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_VNUMFLT); } + +#define chgfltvalue(obj,x) \ + { TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); } + +#define setivalue(obj,x) \ + { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_VNUMINT); } + +#define chgivalue(obj,x) \ + { TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); } + +/* }================================================================== */ + + +/* +** {================================================================== +** Strings +** =================================================================== +*/ + +/* Variant tags for strings */ +#define LUA_VSHRSTR makevariant(LUA_TSTRING, 0) /* short strings */ +#define LUA_VLNGSTR makevariant(LUA_TSTRING, 1) /* long strings */ + +#define ttisstring(o) checktype((o), LUA_TSTRING) +#define ttisshrstring(o) checktag((o), ctb(LUA_VSHRSTR)) +#define ttislngstring(o) checktag((o), ctb(LUA_VLNGSTR)) + +#define tsvalueraw(v) (gco2ts((v).gc)) + +#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc)) + +#define setsvalue(L,obj,x) \ + { TValue *io = (obj); TString *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \ + checkliveness(L,io); } + +/* set a string to the stack */ +#define setsvalue2s(L,o,s) setsvalue(L,s2v(o),s) + +/* set a string to a new object */ +#define setsvalue2n setsvalue + + +/* +** Header for a string value. +*/ +typedef struct TString { + CommonHeader; + lu_byte extra; /* reserved words for short strings; "has hash" for longs */ + lu_byte shrlen; /* length for short strings, 0xFF for long strings */ + unsigned int hash; + union { + size_t lnglen; /* length for long strings */ + struct TString *hnext; /* linked list for hash table */ + } u; + char contents[1]; +} TString; + + + +/* +** Get the actual string (array of bytes) from a 'TString'. (Generic +** version and specialized versions for long and short strings.) +*/ +#define getstr(ts) ((ts)->contents) +#define getlngstr(ts) check_exp((ts)->shrlen == 0xFF, (ts)->contents) +#define getshrstr(ts) check_exp((ts)->shrlen != 0xFF, (ts)->contents) + + +/* get string length from 'TString *s' */ +#define tsslen(s) \ + ((s)->shrlen != 0xFF ? (s)->shrlen : (s)->u.lnglen) + +/* }================================================================== */ + + +/* +** {================================================================== +** Userdata +** =================================================================== +*/ + + +/* +** Light userdata should be a variant of userdata, but for compatibility +** reasons they are also different types. +*/ +#define LUA_VLIGHTUSERDATA makevariant(LUA_TLIGHTUSERDATA, 0) + +#define LUA_VUSERDATA makevariant(LUA_TUSERDATA, 0) + +#define ttislightuserdata(o) checktag((o), LUA_VLIGHTUSERDATA) +#define ttisfulluserdata(o) checktag((o), ctb(LUA_VUSERDATA)) + +#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) +#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc)) + +#define pvalueraw(v) ((v).p) + +#define setpvalue(obj,x) \ + { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_VLIGHTUSERDATA); } + +#define setuvalue(L,obj,x) \ + { TValue *io = (obj); Udata *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VUSERDATA)); \ + checkliveness(L,io); } + + +/* Ensures that addresses after this type are always fully aligned. */ +typedef union UValue { + TValue uv; + LUAI_MAXALIGN; /* ensures maximum alignment for udata bytes */ +} UValue; + + +/* +** Header for userdata with user values; +** memory area follows the end of this structure. +*/ +typedef struct Udata { + CommonHeader; + unsigned short nuvalue; /* number of user values */ + size_t len; /* number of bytes */ + struct Table *metatable; + GCObject *gclist; + UValue uv[1]; /* user values */ +} Udata; + + +/* +** Header for userdata with no user values. These userdata do not need +** to be gray during GC, and therefore do not need a 'gclist' field. +** To simplify, the code always use 'Udata' for both kinds of userdata, +** making sure it never accesses 'gclist' on userdata with no user values. +** This structure here is used only to compute the correct size for +** this representation. (The 'bindata' field in its end ensures correct +** alignment for binary data following this header.) +*/ +typedef struct Udata0 { + CommonHeader; + unsigned short nuvalue; /* number of user values */ + size_t len; /* number of bytes */ + struct Table *metatable; + union {LUAI_MAXALIGN;} bindata; +} Udata0; + + +/* compute the offset of the memory area of a userdata */ +#define udatamemoffset(nuv) \ + ((nuv) == 0 ? offsetof(Udata0, bindata) \ + : offsetof(Udata, uv) + (sizeof(UValue) * (nuv))) + +/* get the address of the memory block inside 'Udata' */ +#define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue)) + +/* compute the size of a userdata */ +#define sizeudata(nuv,nb) (udatamemoffset(nuv) + (nb)) + +/* }================================================================== */ + + +/* +** {================================================================== +** Prototypes +** =================================================================== +*/ + +#define LUA_VPROTO makevariant(LUA_TPROTO, 0) + + +/* +** Description of an upvalue for function prototypes +*/ +typedef struct Upvaldesc { + TString *name; /* upvalue name (for debug information) */ + lu_byte instack; /* whether it is in stack (register) */ + lu_byte idx; /* index of upvalue (in stack or in outer function's list) */ + lu_byte kind; /* kind of corresponding variable */ +} Upvaldesc; + + +/* +** Description of a local variable for function prototypes +** (used for debug information) +*/ +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + +/* +** Associates the absolute line source for a given instruction ('pc'). +** The array 'lineinfo' gives, for each instruction, the difference in +** lines from the previous instruction. When that difference does not +** fit into a byte, Lua saves the absolute line for that instruction. +** (Lua also saves the absolute line periodically, to speed up the +** computation of a line number: we can use binary search in the +** absolute-line array, but we must traverse the 'lineinfo' array +** linearly to compute a line.) +*/ +typedef struct AbsLineInfo { + int pc; + int line; +} AbsLineInfo; + +/* +** Function Prototypes +*/ +typedef struct Proto { + CommonHeader; + lu_byte numparams; /* number of fixed (named) parameters */ + lu_byte is_vararg; + lu_byte maxstacksize; /* number of registers needed by this function */ + int sizeupvalues; /* size of 'upvalues' */ + int sizek; /* size of 'k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of 'p' */ + int sizelocvars; + int sizeabslineinfo; /* size of 'abslineinfo' */ + int linedefined; /* debug information */ + int lastlinedefined; /* debug information */ + TValue *k; /* constants used by the function */ + Instruction *code; /* opcodes */ + struct Proto **p; /* functions defined inside the function */ + Upvaldesc *upvalues; /* upvalue information */ + ls_byte *lineinfo; /* information about source lines (debug information) */ + AbsLineInfo *abslineinfo; /* idem */ + LocVar *locvars; /* information about local variables (debug information) */ + TString *source; /* used for debug information */ + GCObject *gclist; +} Proto; + +/* }================================================================== */ + + +/* +** {================================================================== +** Functions +** =================================================================== +*/ + +#define LUA_VUPVAL makevariant(LUA_TUPVAL, 0) + + +/* Variant tags for functions */ +#define LUA_VLCL makevariant(LUA_TFUNCTION, 0) /* Lua closure */ +#define LUA_VLCF makevariant(LUA_TFUNCTION, 1) /* light C function */ +#define LUA_VCCL makevariant(LUA_TFUNCTION, 2) /* C closure */ + +#define ttisfunction(o) checktype(o, LUA_TFUNCTION) +#define ttisLclosure(o) checktag((o), ctb(LUA_VLCL)) +#define ttislcf(o) checktag((o), LUA_VLCF) +#define ttisCclosure(o) checktag((o), ctb(LUA_VCCL)) +#define ttisclosure(o) (ttisLclosure(o) || ttisCclosure(o)) + + +#define isLfunction(o) ttisLclosure(o) + +#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc)) +#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc)) +#define fvalue(o) check_exp(ttislcf(o), val_(o).f) +#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc)) + +#define fvalueraw(v) ((v).f) + +#define setclLvalue(L,obj,x) \ + { TValue *io = (obj); LClosure *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VLCL)); \ + checkliveness(L,io); } + +#define setclLvalue2s(L,o,cl) setclLvalue(L,s2v(o),cl) + +#define setfvalue(obj,x) \ + { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_VLCF); } + +#define setclCvalue(L,obj,x) \ + { TValue *io = (obj); CClosure *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VCCL)); \ + checkliveness(L,io); } + + +/* +** Upvalues for Lua closures +*/ +typedef struct UpVal { + CommonHeader; + union { + TValue *p; /* points to stack or to its own value */ + ptrdiff_t offset; /* used while the stack is being reallocated */ + } v; + union { + struct { /* (when open) */ + struct UpVal *next; /* linked list */ + struct UpVal **previous; + } open; + TValue value; /* the value (when closed) */ + } u; +} UpVal; + + + +#define ClosureHeader \ + CommonHeader; lu_byte nupvalues; GCObject *gclist + +typedef struct CClosure { + ClosureHeader; + lua_CFunction f; + TValue upvalue[1]; /* list of upvalues */ +} CClosure; + + +typedef struct LClosure { + ClosureHeader; + struct Proto *p; + UpVal *upvals[1]; /* list of upvalues */ +} LClosure; + + +typedef union Closure { + CClosure c; + LClosure l; +} Closure; + + +#define getproto(o) (clLvalue(o)->p) + +/* }================================================================== */ + + +/* +** {================================================================== +** Tables +** =================================================================== +*/ + +#define LUA_VTABLE makevariant(LUA_TTABLE, 0) + +#define ttistable(o) checktag((o), ctb(LUA_VTABLE)) + +#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc)) + +#define sethvalue(L,obj,x) \ + { TValue *io = (obj); Table *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VTABLE)); \ + checkliveness(L,io); } + +#define sethvalue2s(L,o,h) sethvalue(L,s2v(o),h) + + +/* +** Nodes for Hash tables: A pack of two TValue's (key-value pairs) +** plus a 'next' field to link colliding entries. The distribution +** of the key's fields ('key_tt' and 'key_val') not forming a proper +** 'TValue' allows for a smaller size for 'Node' both in 4-byte +** and 8-byte alignments. +*/ +typedef union Node { + struct NodeKey { + TValuefields; /* fields for value */ + lu_byte key_tt; /* key type */ + int next; /* for chaining */ + Value key_val; /* key value */ + } u; + TValue i_val; /* direct access to node's value as a proper 'TValue' */ +} Node; + + +/* copy a value into a key */ +#define setnodekey(L,node,obj) \ + { Node *n_=(node); const TValue *io_=(obj); \ + n_->u.key_val = io_->value_; n_->u.key_tt = io_->tt_; \ + checkliveness(L,io_); } + + +/* copy a value from a key */ +#define getnodekey(L,obj,node) \ + { TValue *io_=(obj); const Node *n_=(node); \ + io_->value_ = n_->u.key_val; io_->tt_ = n_->u.key_tt; \ + checkliveness(L,io_); } + + +/* +** About 'alimit': if 'isrealasize(t)' is true, then 'alimit' is the +** real size of 'array'. Otherwise, the real size of 'array' is the +** smallest power of two not smaller than 'alimit' (or zero iff 'alimit' +** is zero); 'alimit' is then used as a hint for #t. +*/ + +#define BITRAS (1 << 7) +#define isrealasize(t) (!((t)->flags & BITRAS)) +#define setrealasize(t) ((t)->flags &= cast_byte(~BITRAS)) +#define setnorealasize(t) ((t)->flags |= BITRAS) + + +typedef struct Table { + CommonHeader; + lu_byte flags; /* 1<

u.key_tt) +#define keyval(node) ((node)->u.key_val) + +#define keyisnil(node) (keytt(node) == LUA_TNIL) +#define keyisinteger(node) (keytt(node) == LUA_VNUMINT) +#define keyival(node) (keyval(node).i) +#define keyisshrstr(node) (keytt(node) == ctb(LUA_VSHRSTR)) +#define keystrval(node) (gco2ts(keyval(node).gc)) + +#define setnilkey(node) (keytt(node) = LUA_TNIL) + +#define keyiscollectable(n) (keytt(n) & BIT_ISCOLLECTABLE) + +#define gckey(n) (keyval(n).gc) +#define gckeyN(n) (keyiscollectable(n) ? gckey(n) : NULL) + + +/* +** Dead keys in tables have the tag DEADKEY but keep their original +** gcvalue. This distinguishes them from regular keys but allows them to +** be found when searched in a special way. ('next' needs that to find +** keys removed from a table during a traversal.) +*/ +#define setdeadkey(node) (keytt(node) = LUA_TDEADKEY) +#define keyisdead(node) (keytt(node) == LUA_TDEADKEY) + +/* }================================================================== */ + + + +/* +** 'module' operation for hashing (size is always a power of 2) +*/ +#define lmod(s,size) \ + (check_exp((size&(size-1))==0, (cast_int((s) & ((size)-1))))) + + +#define twoto(x) (1<<(x)) +#define sizenode(t) (twoto((t)->lsizenode)) + + +/* size of buffer for 'luaO_utf8esc' function */ +#define UTF8BUFFSZ 8 + +LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x); +LUAI_FUNC int luaO_ceillog2 (unsigned int x); +LUAI_FUNC int luaO_rawarith (lua_State *L, int op, const TValue *p1, + const TValue *p2, TValue *res); +LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1, + const TValue *p2, StkId res); +LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o); +LUAI_FUNC int luaO_hexavalue (int c); +LUAI_FUNC void luaO_tostring (lua_State *L, TValue *obj); +LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, + va_list argp); +LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t srclen); + + +#endif + diff --git a/User/system/lua/src/lopcodes.c b/User/system/lua/src/lopcodes.c new file mode 100644 index 0000000..c67aa22 --- /dev/null +++ b/User/system/lua/src/lopcodes.c @@ -0,0 +1,104 @@ +/* +** $Id: lopcodes.c $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#define lopcodes_c +#define LUA_CORE + +#include "lprefix.h" + + +#include "lopcodes.h" + + +/* ORDER OP */ + +LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { +/* MM OT IT T A mode opcode */ + opmode(0, 0, 0, 0, 1, iABC) /* OP_MOVE */ + ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADI */ + ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADF */ + ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADK */ + ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADKX */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADFALSE */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LFALSESKIP */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADTRUE */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADNIL */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETUPVAL */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABUP */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABLE */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETI */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETFIELD */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABUP */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABLE */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETI */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETFIELD */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NEWTABLE */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SELF */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDI */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUBK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MULK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MODK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POWK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIVK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIVK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BANDK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BORK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXORK */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHRI */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHLI */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADD */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUB */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MUL */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MOD */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POW */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIV */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIV */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BAND */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BOR */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXOR */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHL */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHR */ + ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBIN */ + ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINI*/ + ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINK*/ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_UNM */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BNOT */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NOT */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LEN */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_CONCAT */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_CLOSE */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TBC */ + ,opmode(0, 0, 0, 0, 0, isJ) /* OP_JMP */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQ */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LT */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LE */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQK */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQI */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LTI */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LEI */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GTI */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GEI */ + ,opmode(0, 0, 0, 1, 0, iABC) /* OP_TEST */ + ,opmode(0, 0, 0, 1, 1, iABC) /* OP_TESTSET */ + ,opmode(0, 1, 1, 0, 1, iABC) /* OP_CALL */ + ,opmode(0, 1, 1, 0, 1, iABC) /* OP_TAILCALL */ + ,opmode(0, 0, 1, 0, 0, iABC) /* OP_RETURN */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN0 */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN1 */ + ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORLOOP */ + ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORPREP */ + ,opmode(0, 0, 0, 0, 0, iABx) /* OP_TFORPREP */ + ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TFORCALL */ + ,opmode(0, 0, 0, 0, 1, iABx) /* OP_TFORLOOP */ + ,opmode(0, 0, 1, 0, 0, iABC) /* OP_SETLIST */ + ,opmode(0, 0, 0, 0, 1, iABx) /* OP_CLOSURE */ + ,opmode(0, 1, 0, 0, 1, iABC) /* OP_VARARG */ + ,opmode(0, 0, 1, 0, 1, iABC) /* OP_VARARGPREP */ + ,opmode(0, 0, 0, 0, 0, iAx) /* OP_EXTRAARG */ +}; + diff --git a/User/system/lua/src/lopcodes.h b/User/system/lua/src/lopcodes.h new file mode 100644 index 0000000..46911ca --- /dev/null +++ b/User/system/lua/src/lopcodes.h @@ -0,0 +1,405 @@ +/* +** $Id: lopcodes.h $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lopcodes_h +#define lopcodes_h + +#include "llimits.h" + + +/*=========================================================================== + We assume that instructions are unsigned 32-bit integers. + All instructions have an opcode in the first 7 bits. + Instructions can have the following formats: + + 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 + 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +iABC C(8) | B(8) |k| A(8) | Op(7) | +iABx Bx(17) | A(8) | Op(7) | +iAsBx sBx (signed)(17) | A(8) | Op(7) | +iAx Ax(25) | Op(7) | +isJ sJ (signed)(25) | Op(7) | + + A signed argument is represented in excess K: the represented value is + the written unsigned value minus K, where K is half the maximum for the + corresponding unsigned argument. +===========================================================================*/ + + +enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ + + +/* +** size and position of opcode arguments. +*/ +#define SIZE_C 8 +#define SIZE_B 8 +#define SIZE_Bx (SIZE_C + SIZE_B + 1) +#define SIZE_A 8 +#define SIZE_Ax (SIZE_Bx + SIZE_A) +#define SIZE_sJ (SIZE_Bx + SIZE_A) + +#define SIZE_OP 7 + +#define POS_OP 0 + +#define POS_A (POS_OP + SIZE_OP) +#define POS_k (POS_A + SIZE_A) +#define POS_B (POS_k + 1) +#define POS_C (POS_B + SIZE_B) + +#define POS_Bx POS_k + +#define POS_Ax POS_A + +#define POS_sJ POS_A + + +/* +** limits for opcode arguments. +** we use (signed) 'int' to manipulate most arguments, +** so they must fit in ints. +*/ + +/* Check whether type 'int' has at least 'b' bits ('b' < 32) */ +#define L_INTHASBITS(b) ((UINT_MAX >> ((b) - 1)) >= 1) + + +#if L_INTHASBITS(SIZE_Bx) +#define MAXARG_Bx ((1<>1) /* 'sBx' is signed */ + + +#if L_INTHASBITS(SIZE_Ax) +#define MAXARG_Ax ((1<> 1) + + +#define MAXARG_A ((1<> 1) + +#define int2sC(i) ((i) + OFFSET_sC) +#define sC2int(i) ((i) - OFFSET_sC) + + +/* creates a mask with 'n' 1 bits at position 'p' */ +#define MASK1(n,p) ((~((~(Instruction)0)<<(n)))<<(p)) + +/* creates a mask with 'n' 0 bits at position 'p' */ +#define MASK0(n,p) (~MASK1(n,p)) + +/* +** the following macros help to manipulate instructions +*/ + +#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0))) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ + ((cast(Instruction, o)<>(pos)) & MASK1(size,0))) +#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ + ((cast(Instruction, v)<> sC */ +OP_SHLI,/* A B sC R[A] := sC << R[B] */ + +OP_ADD,/* A B C R[A] := R[B] + R[C] */ +OP_SUB,/* A B C R[A] := R[B] - R[C] */ +OP_MUL,/* A B C R[A] := R[B] * R[C] */ +OP_MOD,/* A B C R[A] := R[B] % R[C] */ +OP_POW,/* A B C R[A] := R[B] ^ R[C] */ +OP_DIV,/* A B C R[A] := R[B] / R[C] */ +OP_IDIV,/* A B C R[A] := R[B] // R[C] */ + +OP_BAND,/* A B C R[A] := R[B] & R[C] */ +OP_BOR,/* A B C R[A] := R[B] | R[C] */ +OP_BXOR,/* A B C R[A] := R[B] ~ R[C] */ +OP_SHL,/* A B C R[A] := R[B] << R[C] */ +OP_SHR,/* A B C R[A] := R[B] >> R[C] */ + +OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] (*) */ +OP_MMBINI,/* A sB C k call C metamethod over R[A] and sB */ +OP_MMBINK,/* A B C k call C metamethod over R[A] and K[B] */ + +OP_UNM,/* A B R[A] := -R[B] */ +OP_BNOT,/* A B R[A] := ~R[B] */ +OP_NOT,/* A B R[A] := not R[B] */ +OP_LEN,/* A B R[A] := #R[B] (length operator) */ + +OP_CONCAT,/* A B R[A] := R[A].. ... ..R[A + B - 1] */ + +OP_CLOSE,/* A close all upvalues >= R[A] */ +OP_TBC,/* A mark variable A "to be closed" */ +OP_JMP,/* sJ pc += sJ */ +OP_EQ,/* A B k if ((R[A] == R[B]) ~= k) then pc++ */ +OP_LT,/* A B k if ((R[A] < R[B]) ~= k) then pc++ */ +OP_LE,/* A B k if ((R[A] <= R[B]) ~= k) then pc++ */ + +OP_EQK,/* A B k if ((R[A] == K[B]) ~= k) then pc++ */ +OP_EQI,/* A sB k if ((R[A] == sB) ~= k) then pc++ */ +OP_LTI,/* A sB k if ((R[A] < sB) ~= k) then pc++ */ +OP_LEI,/* A sB k if ((R[A] <= sB) ~= k) then pc++ */ +OP_GTI,/* A sB k if ((R[A] > sB) ~= k) then pc++ */ +OP_GEI,/* A sB k if ((R[A] >= sB) ~= k) then pc++ */ + +OP_TEST,/* A k if (not R[A] == k) then pc++ */ +OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] (*) */ + +OP_CALL,/* A B C R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */ +OP_TAILCALL,/* A B C k return R[A](R[A+1], ... ,R[A+B-1]) */ + +OP_RETURN,/* A B C k return R[A], ... ,R[A+B-2] (see note) */ +OP_RETURN0,/* return */ +OP_RETURN1,/* A return R[A] */ + +OP_FORLOOP,/* A Bx update counters; if loop continues then pc-=Bx; */ +OP_FORPREP,/* A Bx ; + if not to run then pc+=Bx+1; */ + +OP_TFORPREP,/* A Bx create upvalue for R[A + 3]; pc+=Bx */ +OP_TFORCALL,/* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */ +OP_TFORLOOP,/* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */ + +OP_SETLIST,/* A B C k R[A][C+i] := R[A+i], 1 <= i <= B */ + +OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */ + +OP_VARARG,/* A C R[A], R[A+1], ..., R[A+C-2] = vararg */ + +OP_VARARGPREP,/*A (adjust vararg parameters) */ + +OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ +} OpCode; + + +#define NUM_OPCODES ((int)(OP_EXTRAARG) + 1) + + + +/*=========================================================================== + Notes: + + (*) Opcode OP_LFALSESKIP is used to convert a condition to a boolean + value, in a code equivalent to (not cond ? false : true). (It + produces false and skips the next instruction producing true.) + + (*) Opcodes OP_MMBIN and variants follow each arithmetic and + bitwise opcode. If the operation succeeds, it skips this next + opcode. Otherwise, this opcode calls the corresponding metamethod. + + (*) Opcode OP_TESTSET is used in short-circuit expressions that need + both to jump and to produce a value, such as (a = b or c). + + (*) In OP_CALL, if (B == 0) then B = top - A. If (C == 0), then + 'top' is set to last_result+1, so next open instruction (OP_CALL, + OP_RETURN*, OP_SETLIST) may use 'top'. + + (*) In OP_VARARG, if (C == 0) then use actual number of varargs and + set top (like in OP_CALL with C == 0). + + (*) In OP_RETURN, if (B == 0) then return up to 'top'. + + (*) In OP_LOADKX and OP_NEWTABLE, the next instruction is always + OP_EXTRAARG. + + (*) In OP_SETLIST, if (B == 0) then real B = 'top'; if k, then + real C = EXTRAARG _ C (the bits of EXTRAARG concatenated with the + bits of C). + + (*) In OP_NEWTABLE, B is log2 of the hash size (which is always a + power of 2) plus 1, or zero for size zero. If not k, the array size + is C. Otherwise, the array size is EXTRAARG _ C. + + (*) For comparisons, k specifies what condition the test should accept + (true or false). + + (*) In OP_MMBINI/OP_MMBINK, k means the arguments were flipped + (the constant is the first operand). + + (*) All 'skips' (pc++) assume that next instruction is a jump. + + (*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the + function builds upvalues, which may need to be closed. C > 0 means + the function is vararg, so that its 'func' must be corrected before + returning; in this case, (C - 1) is its number of fixed parameters. + + (*) In comparisons with an immediate operand, C signals whether the + original operand was a float. (It must be corrected in case of + metamethods.) + +===========================================================================*/ + + +/* +** masks for instruction properties. The format is: +** bits 0-2: op mode +** bit 3: instruction set register A +** bit 4: operator is a test (next instruction must be a jump) +** bit 5: instruction uses 'L->top' set by previous instruction (when B == 0) +** bit 6: instruction sets 'L->top' for next instruction (when C == 0) +** bit 7: instruction is an MM instruction (call a metamethod) +*/ + +LUAI_DDEC(const lu_byte luaP_opmodes[NUM_OPCODES];) + +#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 7)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 3)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 4)) +#define testITMode(m) (luaP_opmodes[m] & (1 << 5)) +#define testOTMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testMMMode(m) (luaP_opmodes[m] & (1 << 7)) + +/* "out top" (set top for next instruction) */ +#define isOT(i) \ + ((testOTMode(GET_OPCODE(i)) && GETARG_C(i) == 0) || \ + GET_OPCODE(i) == OP_TAILCALL) + +/* "in top" (uses top from previous instruction) */ +#define isIT(i) (testITMode(GET_OPCODE(i)) && GETARG_B(i) == 0) + +#define opmode(mm,ot,it,t,a,m) \ + (((mm) << 7) | ((ot) << 6) | ((it) << 5) | ((t) << 4) | ((a) << 3) | (m)) + + +/* number of list items to accumulate before a SETLIST instruction */ +#define LFIELDS_PER_FLUSH 50 + +#endif diff --git a/User/system/lua/src/lopnames.h b/User/system/lua/src/lopnames.h new file mode 100644 index 0000000..965cec9 --- /dev/null +++ b/User/system/lua/src/lopnames.h @@ -0,0 +1,103 @@ +/* +** $Id: lopnames.h $ +** Opcode names +** See Copyright Notice in lua.h +*/ + +#if !defined(lopnames_h) +#define lopnames_h + +#include + + +/* ORDER OP */ + +static const char *const opnames[] = { + "MOVE", + "LOADI", + "LOADF", + "LOADK", + "LOADKX", + "LOADFALSE", + "LFALSESKIP", + "LOADTRUE", + "LOADNIL", + "GETUPVAL", + "SETUPVAL", + "GETTABUP", + "GETTABLE", + "GETI", + "GETFIELD", + "SETTABUP", + "SETTABLE", + "SETI", + "SETFIELD", + "NEWTABLE", + "SELF", + "ADDI", + "ADDK", + "SUBK", + "MULK", + "MODK", + "POWK", + "DIVK", + "IDIVK", + "BANDK", + "BORK", + "BXORK", + "SHRI", + "SHLI", + "ADD", + "SUB", + "MUL", + "MOD", + "POW", + "DIV", + "IDIV", + "BAND", + "BOR", + "BXOR", + "SHL", + "SHR", + "MMBIN", + "MMBINI", + "MMBINK", + "UNM", + "BNOT", + "NOT", + "LEN", + "CONCAT", + "CLOSE", + "TBC", + "JMP", + "EQ", + "LT", + "LE", + "EQK", + "EQI", + "LTI", + "LEI", + "GTI", + "GEI", + "TEST", + "TESTSET", + "CALL", + "TAILCALL", + "RETURN", + "RETURN0", + "RETURN1", + "FORLOOP", + "FORPREP", + "TFORPREP", + "TFORCALL", + "TFORLOOP", + "SETLIST", + "CLOSURE", + "VARARG", + "VARARGPREP", + "EXTRAARG", + NULL +}; + +#endif + diff --git a/User/system/lua/src/loslib.c b/User/system/lua/src/loslib.c new file mode 100644 index 0000000..ba80d72 --- /dev/null +++ b/User/system/lua/src/loslib.c @@ -0,0 +1,430 @@ +/* +** $Id: loslib.c $ +** Standard Operating System library +** See Copyright Notice in lua.h +*/ + +#define loslib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** {================================================================== +** List of valid conversion specifiers for the 'strftime' function; +** options are grouped by length; group of length 2 start with '||'. +** =================================================================== +*/ +#if !defined(LUA_STRFTIMEOPTIONS) /* { */ + +#if defined(LUA_USE_WINDOWS) +#define LUA_STRFTIMEOPTIONS "aAbBcdHIjmMpSUwWxXyYzZ%" \ + "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */ +#elif defined(LUA_USE_C89) /* ANSI C 89 (only 1-char options) */ +#define LUA_STRFTIMEOPTIONS "aAbBcdHIjmMpSUwWxXyYZ%" +#else /* C99 specification */ +#define LUA_STRFTIMEOPTIONS "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \ + "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */ +#endif + +#endif /* } */ +/* }================================================================== */ + + +/* +** {================================================================== +** Configuration for time-related stuff +** =================================================================== +*/ + +/* +** type to represent time_t in Lua +*/ +#if !defined(LUA_NUMTIME) /* { */ + +#define l_timet lua_Integer +#define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) +#define l_gettime(L,arg) luaL_checkinteger(L, arg) + +#else /* }{ */ + +#define l_timet lua_Number +#define l_pushtime(L,t) lua_pushnumber(L,(lua_Number)(t)) +#define l_gettime(L,arg) luaL_checknumber(L, arg) + +#endif /* } */ + + +#if !defined(l_gmtime) /* { */ +/* +** By default, Lua uses gmtime/localtime, except when POSIX is available, +** where it uses gmtime_r/localtime_r +*/ + +#if defined(LUA_USE_POSIX) /* { */ + +#define l_gmtime(t,r) gmtime_r(t,r) +#define l_localtime(t,r) localtime_r(t,r) + +#else /* }{ */ + +/* ISO C definitions */ +#define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t)) +#define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t)) + +#endif /* } */ + +#endif /* } */ + +/* }================================================================== */ + + +/* +** {================================================================== +** Configuration for 'tmpnam': +** By default, Lua uses tmpnam except when POSIX is available, where +** it uses mkstemp. +** =================================================================== +*/ +#if !defined(lua_tmpnam) /* { */ + +#if defined(LUA_USE_POSIX) /* { */ + +#include + +#define LUA_TMPNAMBUFSIZE 32 + +#if !defined(LUA_TMPNAMTEMPLATE) +#define LUA_TMPNAMTEMPLATE "/tmp/lua_XXXXXX" +#endif + +#define lua_tmpnam(b,e) { \ + strcpy(b, LUA_TMPNAMTEMPLATE); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } + +#else /* }{ */ + +/* ISO C definitions */ +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } + +#endif /* } */ + +#endif /* } */ +/* }================================================================== */ + + +#if !defined(l_system) +#if defined(LUA_USE_IOS) +/* Despite claiming to be ISO C, iOS does not implement 'system'. */ +#define l_system(cmd) ((cmd) == NULL ? 0 : -1) +#else +#define l_system(cmd) system(cmd) /* default definition */ +#endif +#endif + + +static int os_execute (lua_State *L) { + const char *cmd = luaL_optstring(L, 1, NULL); + int stat; + errno = 0; + stat = l_system(cmd); + if (cmd != NULL) + return luaL_execresult(L, stat); + else { + lua_pushboolean(L, stat); /* true if there is a shell */ + return 1; + } +} + + +static int os_remove (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + errno = 0; + return luaL_fileresult(L, remove(filename) == 0, filename); +} + + +static int os_rename (lua_State *L) { + const char *fromname = luaL_checkstring(L, 1); + const char *toname = luaL_checkstring(L, 2); + errno = 0; + return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); +} + + +static int os_tmpname (lua_State *L) { + char buff[LUA_TMPNAMBUFSIZE]; + int err; + lua_tmpnam(buff, err); + if (l_unlikely(err)) + return luaL_error(L, "unable to generate a unique filename"); + lua_pushstring(L, buff); + return 1; +} + + +static int os_getenv (lua_State *L) { + lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ + return 1; +} + + +static int os_clock (lua_State *L) { + lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); + return 1; +} + + +/* +** {====================================================== +** Time/Date operations +** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, +** wday=%w+1, yday=%j, isdst=? } +** ======================================================= +*/ + +/* +** About the overflow check: an overflow cannot occur when time +** is represented by a lua_Integer, because either lua_Integer is +** large enough to represent all int fields or it is not large enough +** to represent a time that cause a field to overflow. However, if +** times are represented as doubles and lua_Integer is int, then the +** time 0x1.e1853b0d184f6p+55 would cause an overflow when adding 1900 +** to compute the year. +*/ +static void setfield (lua_State *L, const char *key, int value, int delta) { + #if (defined(LUA_NUMTIME) && LUA_MAXINTEGER <= INT_MAX) + if (l_unlikely(value > LUA_MAXINTEGER - delta)) + luaL_error(L, "field '%s' is out-of-bound", key); + #endif + lua_pushinteger(L, (lua_Integer)value + delta); + lua_setfield(L, -2, key); +} + + +static void setboolfield (lua_State *L, const char *key, int value) { + if (value < 0) /* undefined? */ + return; /* does not set field */ + lua_pushboolean(L, value); + lua_setfield(L, -2, key); +} + + +/* +** Set all fields from structure 'tm' in the table on top of the stack +*/ +static void setallfields (lua_State *L, struct tm *stm) { + setfield(L, "year", stm->tm_year, 1900); + setfield(L, "month", stm->tm_mon, 1); + setfield(L, "day", stm->tm_mday, 0); + setfield(L, "hour", stm->tm_hour, 0); + setfield(L, "min", stm->tm_min, 0); + setfield(L, "sec", stm->tm_sec, 0); + setfield(L, "yday", stm->tm_yday, 1); + setfield(L, "wday", stm->tm_wday, 1); + setboolfield(L, "isdst", stm->tm_isdst); +} + + +static int getboolfield (lua_State *L, const char *key) { + int res; + res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1); + lua_pop(L, 1); + return res; +} + + +static int getfield (lua_State *L, const char *key, int d, int delta) { + int isnum; + int t = lua_getfield(L, -1, key); /* get field and its type */ + lua_Integer res = lua_tointegerx(L, -1, &isnum); + if (!isnum) { /* field is not an integer? */ + if (l_unlikely(t != LUA_TNIL)) /* some other value? */ + return luaL_error(L, "field '%s' is not an integer", key); + else if (l_unlikely(d < 0)) /* absent field; no default? */ + return luaL_error(L, "field '%s' missing in date table", key); + res = d; + } + else { + if (!(res >= 0 ? res - delta <= INT_MAX : INT_MIN + delta <= res)) + return luaL_error(L, "field '%s' is out-of-bound", key); + res -= delta; + } + lua_pop(L, 1); + return (int)res; +} + + +static const char *checkoption (lua_State *L, const char *conv, + ptrdiff_t convlen, char *buff) { + const char *option = LUA_STRFTIMEOPTIONS; + int oplen = 1; /* length of options being checked */ + for (; *option != '\0' && oplen <= convlen; option += oplen) { + if (*option == '|') /* next block? */ + oplen++; /* will check options with next length (+1) */ + else if (memcmp(conv, option, oplen) == 0) { /* match? */ + memcpy(buff, conv, oplen); /* copy valid option to buffer */ + buff[oplen] = '\0'; + return conv + oplen; /* return next item */ + } + } + luaL_argerror(L, 1, + lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv)); + return conv; /* to avoid warnings */ +} + + +static time_t l_checktime (lua_State *L, int arg) { + l_timet t = l_gettime(L, arg); + luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds"); + return (time_t)t; +} + + +/* maximum size for an individual 'strftime' item */ +#define SIZETIMEFMT 250 + + +static int os_date (lua_State *L) { + size_t slen; + const char *s = luaL_optlstring(L, 1, "%c", &slen); + time_t t = luaL_opt(L, l_checktime, 2, time(NULL)); + const char *se = s + slen; /* 's' end */ + struct tm tmr, *stm; + if (*s == '!') { /* UTC? */ + stm = l_gmtime(&t, &tmr); + s++; /* skip '!' */ + } + else + stm = l_localtime(&t, &tmr); + if (stm == NULL) /* invalid date? */ + return luaL_error(L, + "date result cannot be represented in this installation"); + if (strcmp(s, "*t") == 0) { + lua_createtable(L, 0, 9); /* 9 = number of fields */ + setallfields(L, stm); + } + else { + char cc[4]; /* buffer for individual conversion specifiers */ + luaL_Buffer b; + cc[0] = '%'; + luaL_buffinit(L, &b); + while (s < se) { + if (*s != '%') /* not a conversion specifier? */ + luaL_addchar(&b, *s++); + else { + size_t reslen; + char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT); + s++; /* skip '%' */ + s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */ + reslen = strftime(buff, SIZETIMEFMT, cc, stm); + luaL_addsize(&b, reslen); + } + } + luaL_pushresult(&b); + } + return 1; +} + + +static int os_time (lua_State *L) { + time_t t; + if (lua_isnoneornil(L, 1)) /* called without args? */ + t = time(NULL); /* get current time */ + else { + struct tm ts; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); /* make sure table is at the top */ + ts.tm_year = getfield(L, "year", -1, 1900); + ts.tm_mon = getfield(L, "month", -1, 1); + ts.tm_mday = getfield(L, "day", -1, 0); + ts.tm_hour = getfield(L, "hour", 12, 0); + ts.tm_min = getfield(L, "min", 0, 0); + ts.tm_sec = getfield(L, "sec", 0, 0); + ts.tm_isdst = getboolfield(L, "isdst"); + t = mktime(&ts); + setallfields(L, &ts); /* update fields with normalized values */ + } + if (t != (time_t)(l_timet)t || t == (time_t)(-1)) + return luaL_error(L, + "time result cannot be represented in this installation"); + l_pushtime(L, t); + return 1; +} + + +static int os_difftime (lua_State *L) { + time_t t1 = l_checktime(L, 1); + time_t t2 = l_checktime(L, 2); + lua_pushnumber(L, (lua_Number)difftime(t1, t2)); + return 1; +} + +/* }====================================================== */ + + +static int os_setlocale (lua_State *L) { + static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, + LC_NUMERIC, LC_TIME}; + static const char *const catnames[] = {"all", "collate", "ctype", "monetary", + "numeric", "time", NULL}; + const char *l = luaL_optstring(L, 1, NULL); + int op = luaL_checkoption(L, 2, "all", catnames); + lua_pushstring(L, setlocale(cat[op], l)); + return 1; +} + + +static int os_exit (lua_State *L) { + int status; + if (lua_isboolean(L, 1)) + status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE); + else + status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS); + if (lua_toboolean(L, 2)) + lua_close(L); + if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */ + return 0; +} + + +static const luaL_Reg syslib[] = { + {"clock", os_clock}, + {"date", os_date}, + {"difftime", os_difftime}, + {"execute", os_execute}, + {"exit", os_exit}, + {"getenv", os_getenv}, + {"remove", os_remove}, + {"rename", os_rename}, + {"setlocale", os_setlocale}, + {"time", os_time}, + {"tmpname", os_tmpname}, + {NULL, NULL} +}; + +/* }====================================================== */ + + + +LUAMOD_API int luaopen_os (lua_State *L) { + luaL_newlib(L, syslib); + return 1; +} + diff --git a/User/system/lua/src/lparser.c b/User/system/lua/src/lparser.c new file mode 100644 index 0000000..2b888c7 --- /dev/null +++ b/User/system/lua/src/lparser.c @@ -0,0 +1,1967 @@ +/* +** $Id: lparser.c $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#define lparser_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" + + + +/* maximum number of local variables per function (must be smaller + than 250, due to the bytecode format) */ +#define MAXVARS 200 + + +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) + + +/* because all strings are unified by the scanner, the parser + can use pointer equality for string equality */ +#define eqstr(a,b) ((a) == (b)) + + +/* +** nodes for block list (list of active blocks) +*/ +typedef struct BlockCnt { + struct BlockCnt *previous; /* chain */ + int firstlabel; /* index of first label in this block */ + int firstgoto; /* index of first pending goto in this block */ + lu_byte nactvar; /* # active locals outside the block */ + lu_byte upval; /* true if some variable in the block is an upvalue */ + lu_byte isloop; /* true if 'block' is a loop */ + lu_byte insidetbc; /* true if inside the scope of a to-be-closed var. */ +} BlockCnt; + + + +/* +** prototypes for recursive non-terminal functions +*/ +static void statement (LexState *ls); +static void expr (LexState *ls, expdesc *v); + + +static l_noret error_expected (LexState *ls, int token) { + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); +} + + +static l_noret errorlimit (FuncState *fs, int limit, const char *what) { + lua_State *L = fs->ls->L; + const char *msg; + int line = fs->f->linedefined; + const char *where = (line == 0) + ? "main function" + : luaO_pushfstring(L, "function at line %d", line); + msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", + what, limit, where); + luaX_syntaxerror(fs->ls, msg); +} + + +static void checklimit (FuncState *fs, int v, int l, const char *what) { + if (v > l) errorlimit(fs, l, what); +} + + +/* +** Test whether next token is 'c'; if so, skip it. +*/ +static int testnext (LexState *ls, int c) { + if (ls->t.token == c) { + luaX_next(ls); + return 1; + } + else return 0; +} + + +/* +** Check that next token is 'c'. +*/ +static void check (LexState *ls, int c) { + if (ls->t.token != c) + error_expected(ls, c); +} + + +/* +** Check that next token is 'c' and skip it. +*/ +static void checknext (LexState *ls, int c) { + check(ls, c); + luaX_next(ls); +} + + +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } + + +/* +** Check that next token is 'what' and skip it. In case of error, +** raise an error that the expected 'what' should match a 'who' +** in line 'where' (if that is not the current line). +*/ +static void check_match (LexState *ls, int what, int who, int where) { + if (l_unlikely(!testnext(ls, what))) { + if (where == ls->linenumber) /* all in the same line? */ + error_expected(ls, what); /* do not need a complex message */ + else { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, + "%s expected (to close %s at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } + } +} + + +static TString *str_checkname (LexState *ls) { + TString *ts; + check(ls, TK_NAME); + ts = ls->t.seminfo.ts; + luaX_next(ls); + return ts; +} + + +static void init_exp (expdesc *e, expkind k, int i) { + e->f = e->t = NO_JUMP; + e->k = k; + e->u.info = i; +} + + +static void codestring (expdesc *e, TString *s) { + e->f = e->t = NO_JUMP; + e->k = VKSTR; + e->u.strval = s; +} + + +static void codename (LexState *ls, expdesc *e) { + codestring(e, str_checkname(ls)); +} + + +/* +** Register a new local variable in the active 'Proto' (for debug +** information). +*/ +static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) { + Proto *f = fs->f; + int oldsize = f->sizelocvars; + luaM_growvector(ls->L, f->locvars, fs->ndebugvars, f->sizelocvars, + LocVar, SHRT_MAX, "local variables"); + while (oldsize < f->sizelocvars) + f->locvars[oldsize++].varname = NULL; + f->locvars[fs->ndebugvars].varname = varname; + f->locvars[fs->ndebugvars].startpc = fs->pc; + luaC_objbarrier(ls->L, f, varname); + return fs->ndebugvars++; +} + + +/* +** Create a new local variable with the given 'name'. Return its index +** in the function. +*/ +static int new_localvar (LexState *ls, TString *name) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Dyndata *dyd = ls->dyd; + Vardesc *var; + checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, + MAXVARS, "local variables"); + luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, + dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); + var = &dyd->actvar.arr[dyd->actvar.n++]; + var->vd.kind = VDKREG; /* default */ + var->vd.name = name; + return dyd->actvar.n - 1 - fs->firstlocal; +} + +#define new_localvarliteral(ls,v) \ + new_localvar(ls, \ + luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1)); + + + +/* +** Return the "variable description" (Vardesc) of a given variable. +** (Unless noted otherwise, all variables are referred to by their +** compiler indices.) +*/ +static Vardesc *getlocalvardesc (FuncState *fs, int vidx) { + return &fs->ls->dyd->actvar.arr[fs->firstlocal + vidx]; +} + + +/* +** Convert 'nvar', a compiler index level, to its corresponding +** register. For that, search for the highest variable below that level +** that is in a register and uses its register index ('ridx') plus one. +*/ +static int reglevel (FuncState *fs, int nvar) { + while (nvar-- > 0) { + Vardesc *vd = getlocalvardesc(fs, nvar); /* get previous variable */ + if (vd->vd.kind != RDKCTC) /* is in a register? */ + return vd->vd.ridx + 1; + } + return 0; /* no variables in registers */ +} + + +/* +** Return the number of variables in the register stack for the given +** function. +*/ +int luaY_nvarstack (FuncState *fs) { + return reglevel(fs, fs->nactvar); +} + + +/* +** Get the debug-information entry for current variable 'vidx'. +*/ +static LocVar *localdebuginfo (FuncState *fs, int vidx) { + Vardesc *vd = getlocalvardesc(fs, vidx); + if (vd->vd.kind == RDKCTC) + return NULL; /* no debug info. for constants */ + else { + int idx = vd->vd.pidx; + lua_assert(idx < fs->ndebugvars); + return &fs->f->locvars[idx]; + } +} + + +/* +** Create an expression representing variable 'vidx' +*/ +static void init_var (FuncState *fs, expdesc *e, int vidx) { + e->f = e->t = NO_JUMP; + e->k = VLOCAL; + e->u.var.vidx = vidx; + e->u.var.ridx = getlocalvardesc(fs, vidx)->vd.ridx; +} + + +/* +** Raises an error if variable described by 'e' is read only +*/ +static void check_readonly (LexState *ls, expdesc *e) { + FuncState *fs = ls->fs; + TString *varname = NULL; /* to be set if variable is const */ + switch (e->k) { + case VCONST: { + varname = ls->dyd->actvar.arr[e->u.info].vd.name; + break; + } + case VLOCAL: { + Vardesc *vardesc = getlocalvardesc(fs, e->u.var.vidx); + if (vardesc->vd.kind != VDKREG) /* not a regular variable? */ + varname = vardesc->vd.name; + break; + } + case VUPVAL: { + Upvaldesc *up = &fs->f->upvalues[e->u.info]; + if (up->kind != VDKREG) + varname = up->name; + break; + } + default: + return; /* other cases cannot be read-only */ + } + if (varname) { + const char *msg = luaO_pushfstring(ls->L, + "attempt to assign to const variable '%s'", getstr(varname)); + luaK_semerror(ls, msg); /* error */ + } +} + + +/* +** Start the scope for the last 'nvars' created variables. +*/ +static void adjustlocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + int reglevel = luaY_nvarstack(fs); + int i; + for (i = 0; i < nvars; i++) { + int vidx = fs->nactvar++; + Vardesc *var = getlocalvardesc(fs, vidx); + var->vd.ridx = reglevel++; + var->vd.pidx = registerlocalvar(ls, fs, var->vd.name); + } +} + + +/* +** Close the scope for all variables up to level 'tolevel'. +** (debug info.) +*/ +static void removevars (FuncState *fs, int tolevel) { + fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); + while (fs->nactvar > tolevel) { + LocVar *var = localdebuginfo(fs, --fs->nactvar); + if (var) /* does it have debug information? */ + var->endpc = fs->pc; + } +} + + +/* +** Search the upvalues of the function 'fs' for one +** with the given 'name'. +*/ +static int searchupvalue (FuncState *fs, TString *name) { + int i; + Upvaldesc *up = fs->f->upvalues; + for (i = 0; i < fs->nups; i++) { + if (eqstr(up[i].name, name)) return i; + } + return -1; /* not found */ +} + + +static Upvaldesc *allocupvalue (FuncState *fs) { + Proto *f = fs->f; + int oldsize = f->sizeupvalues; + checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); + luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, + Upvaldesc, MAXUPVAL, "upvalues"); + while (oldsize < f->sizeupvalues) + f->upvalues[oldsize++].name = NULL; + return &f->upvalues[fs->nups++]; +} + + +static int newupvalue (FuncState *fs, TString *name, expdesc *v) { + Upvaldesc *up = allocupvalue(fs); + FuncState *prev = fs->prev; + if (v->k == VLOCAL) { + up->instack = 1; + up->idx = v->u.var.ridx; + up->kind = getlocalvardesc(prev, v->u.var.vidx)->vd.kind; + lua_assert(eqstr(name, getlocalvardesc(prev, v->u.var.vidx)->vd.name)); + } + else { + up->instack = 0; + up->idx = cast_byte(v->u.info); + up->kind = prev->f->upvalues[v->u.info].kind; + lua_assert(eqstr(name, prev->f->upvalues[v->u.info].name)); + } + up->name = name; + luaC_objbarrier(fs->ls->L, fs->f, name); + return fs->nups - 1; +} + + +/* +** Look for an active local variable with the name 'n' in the +** function 'fs'. If found, initialize 'var' with it and return +** its expression kind; otherwise return -1. +*/ +static int searchvar (FuncState *fs, TString *n, expdesc *var) { + int i; + for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { + Vardesc *vd = getlocalvardesc(fs, i); + if (eqstr(n, vd->vd.name)) { /* found? */ + if (vd->vd.kind == RDKCTC) /* compile-time constant? */ + init_exp(var, VCONST, fs->firstlocal + i); + else /* real variable */ + init_var(fs, var, i); + return var->k; + } + } + return -1; /* not found */ +} + + +/* +** Mark block where variable at given level was defined +** (to emit close instructions later). +*/ +static void markupval (FuncState *fs, int level) { + BlockCnt *bl = fs->bl; + while (bl->nactvar > level) + bl = bl->previous; + bl->upval = 1; + fs->needclose = 1; +} + + +/* +** Mark that current block has a to-be-closed variable. +*/ +static void marktobeclosed (FuncState *fs) { + BlockCnt *bl = fs->bl; + bl->upval = 1; + bl->insidetbc = 1; + fs->needclose = 1; +} + + +/* +** Find a variable with the given name 'n'. If it is an upvalue, add +** this upvalue into all intermediate functions. If it is a global, set +** 'var' as 'void' as a flag. +*/ +static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { + if (fs == NULL) /* no more levels? */ + init_exp(var, VVOID, 0); /* default is global */ + else { + int v = searchvar(fs, n, var); /* look up locals at current level */ + if (v >= 0) { /* found? */ + if (v == VLOCAL && !base) + markupval(fs, var->u.var.vidx); /* local will be used as an upval */ + } + else { /* not found as local at current level; try upvalues */ + int idx = searchupvalue(fs, n); /* try existing upvalues */ + if (idx < 0) { /* not found? */ + singlevaraux(fs->prev, n, var, 0); /* try upper levels */ + if (var->k == VLOCAL || var->k == VUPVAL) /* local or upvalue? */ + idx = newupvalue(fs, n, var); /* will be a new upvalue */ + else /* it is a global or a constant */ + return; /* don't need to do anything at this level */ + } + init_exp(var, VUPVAL, idx); /* new or old upvalue */ + } + } +} + + +/* +** Find a variable with the given name 'n', handling global variables +** too. +*/ +static void singlevar (LexState *ls, expdesc *var) { + TString *varname = str_checkname(ls); + FuncState *fs = ls->fs; + singlevaraux(fs, varname, var, 1); + if (var->k == VVOID) { /* global name? */ + expdesc key; + singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ + lua_assert(var->k != VVOID); /* this one must exist */ + luaK_exp2anyregup(fs, var); /* but could be a constant */ + codestring(&key, varname); /* key is variable name */ + luaK_indexed(fs, var, &key); /* env[varname] */ + } +} + + +/* +** Adjust the number of results from an expression list 'e' with 'nexps' +** expressions to 'nvars' values. +*/ +static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { + FuncState *fs = ls->fs; + int needed = nvars - nexps; /* extra values needed */ + if (hasmultret(e->k)) { /* last expression has multiple returns? */ + int extra = needed + 1; /* discount last expression itself */ + if (extra < 0) + extra = 0; + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + } + else { + if (e->k != VVOID) /* at least one expression? */ + luaK_exp2nextreg(fs, e); /* close last expression */ + if (needed > 0) /* missing values? */ + luaK_nil(fs, fs->freereg, needed); /* complete with nils */ + } + if (needed > 0) + luaK_reserveregs(fs, needed); /* registers for extra values */ + else /* adding 'needed' is actually a subtraction */ + fs->freereg += needed; /* remove extra values */ +} + + +#define enterlevel(ls) luaE_incCstack(ls->L) + + +#define leavelevel(ls) ((ls)->L->nCcalls--) + + +/* +** Generates an error that a goto jumps into the scope of some +** local variable. +*/ +static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { + const char *varname = getstr(getlocalvardesc(ls->fs, gt->nactvar)->vd.name); + const char *msg = " at line %d jumps into the scope of local '%s'"; + msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname); + luaK_semerror(ls, msg); /* raise the error */ +} + + +/* +** Solves the goto at index 'g' to given 'label' and removes it +** from the list of pending gotos. +** If it jumps into the scope of some variable, raises an error. +*/ +static void solvegoto (LexState *ls, int g, Labeldesc *label) { + int i; + Labellist *gl = &ls->dyd->gt; /* list of gotos */ + Labeldesc *gt = &gl->arr[g]; /* goto to be resolved */ + lua_assert(eqstr(gt->name, label->name)); + if (l_unlikely(gt->nactvar < label->nactvar)) /* enter some scope? */ + jumpscopeerror(ls, gt); + luaK_patchlist(ls->fs, gt->pc, label->pc); + for (i = g; i < gl->n - 1; i++) /* remove goto from pending list */ + gl->arr[i] = gl->arr[i + 1]; + gl->n--; +} + + +/* +** Search for an active label with the given name. +*/ +static Labeldesc *findlabel (LexState *ls, TString *name) { + int i; + Dyndata *dyd = ls->dyd; + /* check labels in current function for a match */ + for (i = ls->fs->firstlabel; i < dyd->label.n; i++) { + Labeldesc *lb = &dyd->label.arr[i]; + if (eqstr(lb->name, name)) /* correct label? */ + return lb; + } + return NULL; /* label not found */ +} + + +/* +** Adds a new label/goto in the corresponding list. +*/ +static int newlabelentry (LexState *ls, Labellist *l, TString *name, + int line, int pc) { + int n = l->n; + luaM_growvector(ls->L, l->arr, n, l->size, + Labeldesc, SHRT_MAX, "labels/gotos"); + l->arr[n].name = name; + l->arr[n].line = line; + l->arr[n].nactvar = ls->fs->nactvar; + l->arr[n].close = 0; + l->arr[n].pc = pc; + l->n = n + 1; + return n; +} + + +static int newgotoentry (LexState *ls, TString *name, int line, int pc) { + return newlabelentry(ls, &ls->dyd->gt, name, line, pc); +} + + +/* +** Solves forward jumps. Check whether new label 'lb' matches any +** pending gotos in current block and solves them. Return true +** if any of the gotos need to close upvalues. +*/ +static int solvegotos (LexState *ls, Labeldesc *lb) { + Labellist *gl = &ls->dyd->gt; + int i = ls->fs->bl->firstgoto; + int needsclose = 0; + while (i < gl->n) { + if (eqstr(gl->arr[i].name, lb->name)) { + needsclose |= gl->arr[i].close; + solvegoto(ls, i, lb); /* will remove 'i' from the list */ + } + else + i++; + } + return needsclose; +} + + +/* +** Create a new label with the given 'name' at the given 'line'. +** 'last' tells whether label is the last non-op statement in its +** block. Solves all pending gotos to this new label and adds +** a close instruction if necessary. +** Returns true iff it added a close instruction. +*/ +static int createlabel (LexState *ls, TString *name, int line, + int last) { + FuncState *fs = ls->fs; + Labellist *ll = &ls->dyd->label; + int l = newlabelentry(ls, ll, name, line, luaK_getlabel(fs)); + if (last) { /* label is last no-op statement in the block? */ + /* assume that locals are already out of scope */ + ll->arr[l].nactvar = fs->bl->nactvar; + } + if (solvegotos(ls, &ll->arr[l])) { /* need close? */ + luaK_codeABC(fs, OP_CLOSE, luaY_nvarstack(fs), 0, 0); + return 1; + } + return 0; +} + + +/* +** Adjust pending gotos to outer level of a block. +*/ +static void movegotosout (FuncState *fs, BlockCnt *bl) { + int i; + Labellist *gl = &fs->ls->dyd->gt; + /* correct pending gotos to current block */ + for (i = bl->firstgoto; i < gl->n; i++) { /* for each pending goto */ + Labeldesc *gt = &gl->arr[i]; + /* leaving a variable scope? */ + if (reglevel(fs, gt->nactvar) > reglevel(fs, bl->nactvar)) + gt->close |= bl->upval; /* jump may need a close */ + gt->nactvar = bl->nactvar; /* update goto level */ + } +} + + +static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { + bl->isloop = isloop; + bl->nactvar = fs->nactvar; + bl->firstlabel = fs->ls->dyd->label.n; + bl->firstgoto = fs->ls->dyd->gt.n; + bl->upval = 0; + bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc); + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == luaY_nvarstack(fs)); +} + + +/* +** generates an error for an undefined 'goto'. +*/ +static l_noret undefgoto (LexState *ls, Labeldesc *gt) { + const char *msg; + if (eqstr(gt->name, luaS_newliteral(ls->L, "break"))) { + msg = "break outside loop at line %d"; + msg = luaO_pushfstring(ls->L, msg, gt->line); + } + else { + msg = "no visible label '%s' for at line %d"; + msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); + } + luaK_semerror(ls, msg); +} + + +static void leaveblock (FuncState *fs) { + BlockCnt *bl = fs->bl; + LexState *ls = fs->ls; + int hasclose = 0; + int stklevel = reglevel(fs, bl->nactvar); /* level outside the block */ + removevars(fs, bl->nactvar); /* remove block locals */ + lua_assert(bl->nactvar == fs->nactvar); /* back to level on entry */ + if (bl->isloop) /* has to fix pending breaks? */ + hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0); + if (!hasclose && bl->previous && bl->upval) /* still need a 'close'? */ + luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0); + fs->freereg = stklevel; /* free registers */ + ls->dyd->label.n = bl->firstlabel; /* remove local labels */ + fs->bl = bl->previous; /* current block now is previous one */ + if (bl->previous) /* was it a nested block? */ + movegotosout(fs, bl); /* update pending gotos to enclosing block */ + else { + if (bl->firstgoto < ls->dyd->gt.n) /* still pending gotos? */ + undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ + } +} + + +/* +** adds a new prototype into list of prototypes +*/ +static Proto *addprototype (LexState *ls) { + Proto *clp; + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; /* prototype of current function */ + if (fs->np >= f->sizep) { + int oldsize = f->sizep; + luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); + while (oldsize < f->sizep) + f->p[oldsize++] = NULL; + } + f->p[fs->np++] = clp = luaF_newproto(L); + luaC_objbarrier(L, f, clp); + return clp; +} + + +/* +** codes instruction to create new closure in parent function. +** The OP_CLOSURE instruction uses the last available register, +** so that, if it invokes the GC, the GC knows which registers +** are in use at that time. + +*/ +static void codeclosure (LexState *ls, expdesc *v) { + FuncState *fs = ls->fs->prev; + init_exp(v, VRELOC, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); + luaK_exp2nextreg(fs, v); /* fix it at the last register */ +} + + +static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { + Proto *f = fs->f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + ls->fs = fs; + fs->pc = 0; + fs->previousline = f->linedefined; + fs->iwthabs = 0; + fs->lasttarget = 0; + fs->freereg = 0; + fs->nk = 0; + fs->nabslineinfo = 0; + fs->np = 0; + fs->nups = 0; + fs->ndebugvars = 0; + fs->nactvar = 0; + fs->needclose = 0; + fs->firstlocal = ls->dyd->actvar.n; + fs->firstlabel = ls->dyd->label.n; + fs->bl = NULL; + f->source = ls->source; + luaC_objbarrier(ls->L, f, f->source); + f->maxstacksize = 2; /* registers 0/1 are always valid */ + enterblock(fs, bl, 0); +} + + +static void close_func (LexState *ls) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + luaK_ret(fs, luaY_nvarstack(fs), 0); /* final return */ + leaveblock(fs); + lua_assert(fs->bl == NULL); + luaK_finish(fs); + luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction); + luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte); + luaM_shrinkvector(L, f->abslineinfo, f->sizeabslineinfo, + fs->nabslineinfo, AbsLineInfo); + luaM_shrinkvector(L, f->k, f->sizek, fs->nk, TValue); + luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); + luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->ndebugvars, LocVar); + luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); + ls->fs = fs->prev; + luaC_checkGC(L); +} + + + +/*============================================================*/ +/* GRAMMAR RULES */ +/*============================================================*/ + + +/* +** check whether current token is in the follow set of a block. +** 'until' closes syntactical blocks, but do not close scope, +** so it is handled in separate. +*/ +static int block_follow (LexState *ls, int withuntil) { + switch (ls->t.token) { + case TK_ELSE: case TK_ELSEIF: + case TK_END: case TK_EOS: + return 1; + case TK_UNTIL: return withuntil; + default: return 0; + } +} + + +static void statlist (LexState *ls) { + /* statlist -> { stat [';'] } */ + while (!block_follow(ls, 1)) { + if (ls->t.token == TK_RETURN) { + statement(ls); + return; /* 'return' must be last statement */ + } + statement(ls); + } +} + + +static void fieldsel (LexState *ls, expdesc *v) { + /* fieldsel -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyregup(fs, v); + luaX_next(ls); /* skip the dot or colon */ + codename(ls, &key); + luaK_indexed(fs, v, &key); +} + + +static void yindex (LexState *ls, expdesc *v) { + /* index -> '[' expr ']' */ + luaX_next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + checknext(ls, ']'); +} + + +/* +** {====================================================================== +** Rules for Constructors +** ======================================================================= +*/ + + +typedef struct ConsControl { + expdesc v; /* last list item read */ + expdesc *t; /* table descriptor */ + int nh; /* total number of 'record' elements */ + int na; /* number of array elements already stored */ + int tostore; /* number of array elements pending to be stored */ +} ConsControl; + + +static void recfield (LexState *ls, ConsControl *cc) { + /* recfield -> (NAME | '['exp']') = exp */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc tab, key, val; + if (ls->t.token == TK_NAME) { + checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + codename(ls, &key); + } + else /* ls->t.token == '[' */ + yindex(ls, &key); + cc->nh++; + checknext(ls, '='); + tab = *cc->t; + luaK_indexed(fs, &tab, &key); + expr(ls, &val); + luaK_storevar(fs, &tab, &val); + fs->freereg = reg; /* free registers */ +} + + +static void closelistfield (FuncState *fs, ConsControl *cc) { + if (cc->v.k == VVOID) return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) { + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ + cc->na += cc->tostore; + cc->tostore = 0; /* no more items pending */ + } +} + + +static void lastlistfield (FuncState *fs, ConsControl *cc) { + if (cc->tostore == 0) return; + if (hasmultret(cc->v.k)) { + luaK_setmultret(fs, &cc->v); + luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); + cc->na--; /* do not count last expression (unknown number of elements) */ + } + else { + if (cc->v.k != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); + } + cc->na += cc->tostore; +} + + +static void listfield (LexState *ls, ConsControl *cc) { + /* listfield -> exp */ + expr(ls, &cc->v); + cc->tostore++; +} + + +static void field (LexState *ls, ConsControl *cc) { + /* field -> listfield | recfield */ + switch(ls->t.token) { + case TK_NAME: { /* may be 'listfield' or 'recfield' */ + if (luaX_lookahead(ls) != '=') /* expression? */ + listfield(ls, cc); + else + recfield(ls, cc); + break; + } + case '[': { + recfield(ls, cc); + break; + } + default: { + listfield(ls, cc); + break; + } + } +} + + +static void constructor (LexState *ls, expdesc *t) { + /* constructor -> '{' [ field { sep field } [sep] ] '}' + sep -> ',' | ';' */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + ConsControl cc; + luaK_code(fs, 0); /* space for extra arg. */ + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VNONRELOC, fs->freereg); /* table will be at stack top */ + luaK_reserveregs(fs, 1); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + checknext(ls, '{'); + do { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + if (ls->t.token == '}') break; + closelistfield(fs, &cc); + field(ls, &cc); + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + luaK_settablesize(fs, pc, t->u.info, cc.na, cc.nh); +} + +/* }====================================================================== */ + + +static void setvararg (FuncState *fs, int nparams) { + fs->f->is_vararg = 1; + luaK_codeABC(fs, OP_VARARGPREP, nparams, 0, 0); +} + + +static void parlist (LexState *ls) { + /* parlist -> [ {NAME ','} (NAME | '...') ] */ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int nparams = 0; + int isvararg = 0; + if (ls->t.token != ')') { /* is 'parlist' not empty? */ + do { + switch (ls->t.token) { + case TK_NAME: { + new_localvar(ls, str_checkname(ls)); + nparams++; + break; + } + case TK_DOTS: { + luaX_next(ls); + isvararg = 1; + break; + } + default: luaX_syntaxerror(ls, " or '...' expected"); + } + } while (!isvararg && testnext(ls, ',')); + } + adjustlocalvars(ls, nparams); + f->numparams = cast_byte(fs->nactvar); + if (isvararg) + setvararg(fs, f->numparams); /* declared vararg */ + luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */ +} + + +static void body (LexState *ls, expdesc *e, int ismethod, int line) { + /* body -> '(' parlist ')' block END */ + FuncState new_fs; + BlockCnt bl; + new_fs.f = addprototype(ls); + new_fs.f->linedefined = line; + open_func(ls, &new_fs, &bl); + checknext(ls, '('); + if (ismethod) { + new_localvarliteral(ls, "self"); /* create 'self' parameter */ + adjustlocalvars(ls, 1); + } + parlist(ls); + checknext(ls, ')'); + statlist(ls); + new_fs.f->lastlinedefined = ls->linenumber; + check_match(ls, TK_END, TK_FUNCTION, line); + codeclosure(ls, e); + close_func(ls); +} + + +static int explist (LexState *ls, expdesc *v) { + /* explist -> expr { ',' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; +} + + +static void funcargs (LexState *ls, expdesc *f) { + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + int line = ls->linenumber; + switch (ls->t.token) { + case '(': { /* funcargs -> '(' [ explist ] ')' */ + luaX_next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else { + explist(ls, &args); + if (hasmultret(args.k)) + luaK_setmultret(fs, &args); + } + check_match(ls, ')', '(', line); + break; + } + case '{': { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + codestring(&args, ls->t.seminfo.ts); + luaX_next(ls); /* must use 'seminfo' before 'next' */ + break; + } + default: { + luaX_syntaxerror(ls, "function arguments expected"); + } + } + lua_assert(f->k == VNONRELOC); + base = f->u.info; /* base register for call */ + if (hasmultret(args.k)) + nparams = LUA_MULTRET; /* open call */ + else { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base+1); + } + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); + luaK_fixline(fs, line); + fs->freereg = base+1; /* call removes function and arguments and leaves + one result (unless changed later) */ +} + + + + +/* +** {====================================================================== +** Expression parsing +** ======================================================================= +*/ + + +static void primaryexp (LexState *ls, expdesc *v) { + /* primaryexp -> NAME | '(' expr ')' */ + switch (ls->t.token) { + case '(': { + int line = ls->linenumber; + luaX_next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: { + singlevar(ls, v); + return; + } + default: { + luaX_syntaxerror(ls, "unexpected symbol"); + } + } +} + + +static void suffixedexp (LexState *ls, expdesc *v) { + /* suffixedexp -> + primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ + FuncState *fs = ls->fs; + primaryexp(ls, v); + for (;;) { + switch (ls->t.token) { + case '.': { /* fieldsel */ + fieldsel(ls, v); + break; + } + case '[': { /* '[' exp ']' */ + expdesc key; + luaK_exp2anyregup(fs, v); + yindex(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': { /* ':' NAME funcargs */ + expdesc key; + luaX_next(ls); + codename(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v); + break; + } + case '(': case TK_STRING: case '{': { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v); + break; + } + default: return; + } + } +} + + +static void simpleexp (LexState *ls, expdesc *v) { + /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... | + constructor | FUNCTION body | suffixedexp */ + switch (ls->t.token) { + case TK_FLT: { + init_exp(v, VKFLT, 0); + v->u.nval = ls->t.seminfo.r; + break; + } + case TK_INT: { + init_exp(v, VKINT, 0); + v->u.ival = ls->t.seminfo.i; + break; + } + case TK_STRING: { + codestring(v, ls->t.seminfo.ts); + break; + } + case TK_NIL: { + init_exp(v, VNIL, 0); + break; + } + case TK_TRUE: { + init_exp(v, VTRUE, 0); + break; + } + case TK_FALSE: { + init_exp(v, VFALSE, 0); + break; + } + case TK_DOTS: { /* vararg */ + FuncState *fs = ls->fs; + check_condition(ls, fs->f->is_vararg, + "cannot use '...' outside a vararg function"); + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1)); + break; + } + case '{': { /* constructor */ + constructor(ls, v); + return; + } + case TK_FUNCTION: { + luaX_next(ls); + body(ls, v, 0, ls->linenumber); + return; + } + default: { + suffixedexp(ls, v); + return; + } + } + luaX_next(ls); +} + + +static UnOpr getunopr (int op) { + switch (op) { + case TK_NOT: return OPR_NOT; + case '-': return OPR_MINUS; + case '~': return OPR_BNOT; + case '#': return OPR_LEN; + default: return OPR_NOUNOPR; + } +} + + +static BinOpr getbinopr (int op) { + switch (op) { + case '+': return OPR_ADD; + case '-': return OPR_SUB; + case '*': return OPR_MUL; + case '%': return OPR_MOD; + case '^': return OPR_POW; + case '/': return OPR_DIV; + case TK_IDIV: return OPR_IDIV; + case '&': return OPR_BAND; + case '|': return OPR_BOR; + case '~': return OPR_BXOR; + case TK_SHL: return OPR_SHL; + case TK_SHR: return OPR_SHR; + case TK_CONCAT: return OPR_CONCAT; + case TK_NE: return OPR_NE; + case TK_EQ: return OPR_EQ; + case '<': return OPR_LT; + case TK_LE: return OPR_LE; + case '>': return OPR_GT; + case TK_GE: return OPR_GE; + case TK_AND: return OPR_AND; + case TK_OR: return OPR_OR; + default: return OPR_NOBINOPR; + } +} + + +/* +** Priority table for binary operators. +*/ +static const struct { + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { /* ORDER OPR */ + {10, 10}, {10, 10}, /* '+' '-' */ + {11, 11}, {11, 11}, /* '*' '%' */ + {14, 13}, /* '^' (right associative) */ + {11, 11}, {11, 11}, /* '/' '//' */ + {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ + {7, 7}, {7, 7}, /* '<<' '>>' */ + {9, 8}, /* '..' (right associative) */ + {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ + {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ + {2, 2}, {1, 1} /* and, or */ +}; + +#define UNARY_PRIORITY 12 /* priority for unary operators */ + + +/* +** subexpr -> (simpleexp | unop subexpr) { binop subexpr } +** where 'binop' is any binary operator with a priority higher than 'limit' +*/ +static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) { /* prefix (unary) operator? */ + int line = ls->linenumber; + luaX_next(ls); /* skip operator */ + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v, line); + } + else simpleexp(ls, v); + /* expand while operators have priorities higher than 'limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) { + expdesc v2; + BinOpr nextop; + int line = ls->linenumber; + luaX_next(ls); /* skip operator */ + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls->fs, op, v, &v2, line); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ +} + + +static void expr (LexState *ls, expdesc *v) { + subexpr(ls, v, 0); +} + +/* }==================================================================== */ + + + +/* +** {====================================================================== +** Rules for Statements +** ======================================================================= +*/ + + +static void block (LexState *ls) { + /* block -> statlist */ + FuncState *fs = ls->fs; + BlockCnt bl; + enterblock(fs, &bl, 0); + statlist(ls); + leaveblock(fs); +} + + +/* +** structure to chain all variables in the left-hand side of an +** assignment +*/ +struct LHS_assign { + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ +}; + + +/* +** check whether, in an assignment to an upvalue/local variable, the +** upvalue/local variable is begin used in a previous assignment to a +** table. If so, save original upvalue/local value in a safe place and +** use this safe copy in the previous assignment. +*/ +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) { /* check all previous assignments */ + if (vkisindexed(lh->v.k)) { /* assignment to table field? */ + if (lh->v.k == VINDEXUP) { /* is table an upvalue? */ + if (v->k == VUPVAL && lh->v.u.ind.t == v->u.info) { + conflict = 1; /* table is the upvalue being assigned now */ + lh->v.k = VINDEXSTR; + lh->v.u.ind.t = extra; /* assignment will use safe copy */ + } + } + else { /* table is a register */ + if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.ridx) { + conflict = 1; /* table is the local being assigned now */ + lh->v.u.ind.t = extra; /* assignment will use safe copy */ + } + /* is index the local being assigned? */ + if (lh->v.k == VINDEXED && v->k == VLOCAL && + lh->v.u.ind.idx == v->u.var.ridx) { + conflict = 1; + lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ + } + } + } + } + if (conflict) { + /* copy upvalue/local value to a temporary (in position 'extra') */ + if (v->k == VLOCAL) + luaK_codeABC(fs, OP_MOVE, extra, v->u.var.ridx, 0); + else + luaK_codeABC(fs, OP_GETUPVAL, extra, v->u.info, 0); + luaK_reserveregs(fs, 1); + } +} + +/* +** Parse and compile a multiple assignment. The first "variable" +** (a 'suffixedexp') was already read by the caller. +** +** assignment -> suffixedexp restassign +** restassign -> ',' suffixedexp restassign | '=' explist +*/ +static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) { + expdesc e; + check_condition(ls, vkisvar(lh->v.k), "syntax error"); + check_readonly(ls, &lh->v); + if (testnext(ls, ',')) { /* restassign -> ',' suffixedexp restassign */ + struct LHS_assign nv; + nv.prev = lh; + suffixedexp(ls, &nv.v); + if (!vkisindexed(nv.v.k)) + check_conflict(ls, lh, &nv.v); + enterlevel(ls); /* control recursion depth */ + restassign(ls, &nv, nvars+1); + leavelevel(ls); + } + else { /* restassign -> '=' explist */ + int nexps; + checknext(ls, '='); + nexps = explist(ls, &e); + if (nexps != nvars) + adjust_assign(ls, nvars, nexps, &e); + else { + luaK_setoneret(ls->fs, &e); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } + } + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); +} + + +static int cond (LexState *ls) { + /* cond -> exp */ + expdesc v; + expr(ls, &v); /* read condition */ + if (v.k == VNIL) v.k = VFALSE; /* 'falses' are all equal here */ + luaK_goiftrue(ls->fs, &v); + return v.f; +} + + +static void gotostat (LexState *ls) { + FuncState *fs = ls->fs; + int line = ls->linenumber; + TString *name = str_checkname(ls); /* label's name */ + Labeldesc *lb = findlabel(ls, name); + if (lb == NULL) /* no label? */ + /* forward jump; will be resolved when the label is declared */ + newgotoentry(ls, name, line, luaK_jump(fs)); + else { /* found a label */ + /* backward jump; will be resolved here */ + int lblevel = reglevel(fs, lb->nactvar); /* label level */ + if (luaY_nvarstack(fs) > lblevel) /* leaving the scope of a variable? */ + luaK_codeABC(fs, OP_CLOSE, lblevel, 0, 0); + /* create jump and link it to the label */ + luaK_patchlist(fs, luaK_jump(fs), lb->pc); + } +} + + +/* +** Break statement. Semantically equivalent to "goto break". +*/ +static void breakstat (LexState *ls) { + int line = ls->linenumber; + luaX_next(ls); /* skip break */ + newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, luaK_jump(ls->fs)); +} + + +/* +** Check whether there is already a label with the given 'name'. +*/ +static void checkrepeated (LexState *ls, TString *name) { + Labeldesc *lb = findlabel(ls, name); + if (l_unlikely(lb != NULL)) { /* already defined? */ + const char *msg = "label '%s' already defined on line %d"; + msg = luaO_pushfstring(ls->L, msg, getstr(name), lb->line); + luaK_semerror(ls, msg); /* error */ + } +} + + +static void labelstat (LexState *ls, TString *name, int line) { + /* label -> '::' NAME '::' */ + checknext(ls, TK_DBCOLON); /* skip double colon */ + while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) + statement(ls); /* skip other no-op statements */ + checkrepeated(ls, name); /* check for repeated labels */ + createlabel(ls, name, line, block_follow(ls, 0)); +} + + +static void whilestat (LexState *ls, int line) { + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int whileinit; + int condexit; + BlockCnt bl; + luaX_next(ls); /* skip WHILE */ + whileinit = luaK_getlabel(fs); + condexit = cond(ls); + enterblock(fs, &bl, 1); + checknext(ls, TK_DO); + block(ls); + luaK_jumpto(fs, whileinit); + check_match(ls, TK_END, TK_WHILE, line); + leaveblock(fs); + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ +} + + +static void repeatstat (LexState *ls, int line) { + /* repeatstat -> REPEAT block UNTIL cond */ + int condexit; + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + BlockCnt bl1, bl2; + enterblock(fs, &bl1, 1); /* loop block */ + enterblock(fs, &bl2, 0); /* scope block */ + luaX_next(ls); /* skip REPEAT */ + statlist(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + condexit = cond(ls); /* read condition (inside scope block) */ + leaveblock(fs); /* finish scope */ + if (bl2.upval) { /* upvalues? */ + int exit = luaK_jump(fs); /* normal exit must jump over fix */ + luaK_patchtohere(fs, condexit); /* repetition must close upvalues */ + luaK_codeABC(fs, OP_CLOSE, reglevel(fs, bl2.nactvar), 0, 0); + condexit = luaK_jump(fs); /* repeat after closing upvalues */ + luaK_patchtohere(fs, exit); /* normal exit comes to here */ + } + luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ + leaveblock(fs); /* finish loop */ +} + + +/* +** Read an expression and generate code to put its results in next +** stack slot. +** +*/ +static void exp1 (LexState *ls) { + expdesc e; + expr(ls, &e); + luaK_exp2nextreg(ls->fs, &e); + lua_assert(e.k == VNONRELOC); +} + + +/* +** Fix for instruction at position 'pc' to jump to 'dest'. +** (Jump addresses are relative in Lua). 'back' true means +** a back jump. +*/ +static void fixforjump (FuncState *fs, int pc, int dest, int back) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest - (pc + 1); + if (back) + offset = -offset; + if (l_unlikely(offset > MAXARG_Bx)) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_Bx(*jmp, offset); +} + + +/* +** Generate code for a 'for' loop. +*/ +static void forbody (LexState *ls, int base, int line, int nvars, int isgen) { + /* forbody -> DO block */ + static const OpCode forprep[2] = {OP_FORPREP, OP_TFORPREP}; + static const OpCode forloop[2] = {OP_FORLOOP, OP_TFORLOOP}; + BlockCnt bl; + FuncState *fs = ls->fs; + int prep, endfor; + checknext(ls, TK_DO); + prep = luaK_codeABx(fs, forprep[isgen], base, 0); + enterblock(fs, &bl, 0); /* scope for declared variables */ + adjustlocalvars(ls, nvars); + luaK_reserveregs(fs, nvars); + block(ls); + leaveblock(fs); /* end of scope for declared variables */ + fixforjump(fs, prep, luaK_getlabel(fs), 0); + if (isgen) { /* generic for? */ + luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); + luaK_fixline(fs, line); + } + endfor = luaK_codeABx(fs, forloop[isgen], base, 0); + fixforjump(fs, endfor, prep + 1, 1); + luaK_fixline(fs, line); +} + + +static void fornum (LexState *ls, TString *varname, int line) { + /* fornum -> NAME = exp,exp[,exp] forbody */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for state)"); + new_localvar(ls, varname); + checknext(ls, '='); + exp1(ls); /* initial value */ + checknext(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else { /* default step = 1 */ + luaK_int(fs, fs->freereg, 1); + luaK_reserveregs(fs, 1); + } + adjustlocalvars(ls, 3); /* control variables */ + forbody(ls, base, line, 1, 0); +} + + +static void forlist (LexState *ls, TString *indexname) { + /* forlist -> NAME {,NAME} IN explist forbody */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 5; /* gen, state, control, toclose, 'indexname' */ + int line; + int base = fs->freereg; + /* create control variables */ + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for state)"); + /* create declared variables */ + new_localvar(ls, indexname); + while (testnext(ls, ',')) { + new_localvar(ls, str_checkname(ls)); + nvars++; + } + checknext(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, 4, explist(ls, &e), &e); + adjustlocalvars(ls, 4); /* control variables */ + marktobeclosed(fs); /* last control var. must be closed */ + luaK_checkstack(fs, 3); /* extra space to call generator */ + forbody(ls, base, line, nvars - 4, 1); +} + + +static void forstat (LexState *ls, int line) { + /* forstat -> FOR (fornum | forlist) END */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 1); /* scope for loop and control variables */ + luaX_next(ls); /* skip 'for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) { + case '=': fornum(ls, varname, line); break; + case ',': case TK_IN: forlist(ls, varname); break; + default: luaX_syntaxerror(ls, "'=' or 'in' expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); /* loop scope ('break' jumps to this point) */ +} + + +static void test_then_block (LexState *ls, int *escapelist) { + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + BlockCnt bl; + FuncState *fs = ls->fs; + expdesc v; + int jf; /* instruction to skip 'then' code (if condition is false) */ + luaX_next(ls); /* skip IF or ELSEIF */ + expr(ls, &v); /* read condition */ + checknext(ls, TK_THEN); + if (ls->t.token == TK_BREAK) { /* 'if x then break' ? */ + int line = ls->linenumber; + luaK_goiffalse(ls->fs, &v); /* will jump if condition is true */ + luaX_next(ls); /* skip 'break' */ + enterblock(fs, &bl, 0); /* must enter block before 'goto' */ + newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, v.t); + while (testnext(ls, ';')) {} /* skip semicolons */ + if (block_follow(ls, 0)) { /* jump is the entire block? */ + leaveblock(fs); + return; /* and that is it */ + } + else /* must skip over 'then' part if condition is false */ + jf = luaK_jump(fs); + } + else { /* regular case (not a break) */ + luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ + enterblock(fs, &bl, 0); + jf = v.f; + } + statlist(ls); /* 'then' part */ + leaveblock(fs); + if (ls->t.token == TK_ELSE || + ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ + luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ + luaK_patchtohere(fs, jf); +} + + +static void ifstat (LexState *ls, int line) { + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + int escapelist = NO_JUMP; /* exit list for finished parts */ + test_then_block(ls, &escapelist); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) + test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ + if (testnext(ls, TK_ELSE)) + block(ls); /* 'else' part */ + check_match(ls, TK_END, TK_IF, line); + luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ +} + + +static void localfunc (LexState *ls) { + expdesc b; + FuncState *fs = ls->fs; + int fvar = fs->nactvar; /* function's variable index */ + new_localvar(ls, str_checkname(ls)); /* new local variable */ + adjustlocalvars(ls, 1); /* enter its scope */ + body(ls, &b, 0, ls->linenumber); /* function created in next register */ + /* debug information will only see the variable after this point! */ + localdebuginfo(fs, fvar)->startpc = fs->pc; +} + + +static int getlocalattribute (LexState *ls) { + /* ATTRIB -> ['<' Name '>'] */ + if (testnext(ls, '<')) { + const char *attr = getstr(str_checkname(ls)); + checknext(ls, '>'); + if (strcmp(attr, "const") == 0) + return RDKCONST; /* read-only variable */ + else if (strcmp(attr, "close") == 0) + return RDKTOCLOSE; /* to-be-closed variable */ + else + luaK_semerror(ls, + luaO_pushfstring(ls->L, "unknown attribute '%s'", attr)); + } + return VDKREG; /* regular variable */ +} + + +static void checktoclose (FuncState *fs, int level) { + if (level != -1) { /* is there a to-be-closed variable? */ + marktobeclosed(fs); + luaK_codeABC(fs, OP_TBC, reglevel(fs, level), 0, 0); + } +} + + +static void localstat (LexState *ls) { + /* stat -> LOCAL NAME ATTRIB { ',' NAME ATTRIB } ['=' explist] */ + FuncState *fs = ls->fs; + int toclose = -1; /* index of to-be-closed variable (if any) */ + Vardesc *var; /* last variable */ + int vidx, kind; /* index and kind of last variable */ + int nvars = 0; + int nexps; + expdesc e; + do { + vidx = new_localvar(ls, str_checkname(ls)); + kind = getlocalattribute(ls); + getlocalvardesc(fs, vidx)->vd.kind = kind; + if (kind == RDKTOCLOSE) { /* to-be-closed? */ + if (toclose != -1) /* one already present? */ + luaK_semerror(ls, "multiple to-be-closed variables in local list"); + toclose = fs->nactvar + nvars; + } + nvars++; + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist(ls, &e); + else { + e.k = VVOID; + nexps = 0; + } + var = getlocalvardesc(fs, vidx); /* get last variable */ + if (nvars == nexps && /* no adjustments? */ + var->vd.kind == RDKCONST && /* last variable is const? */ + luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */ + var->vd.kind = RDKCTC; /* variable is a compile-time constant */ + adjustlocalvars(ls, nvars - 1); /* exclude last variable */ + fs->nactvar++; /* but count it */ + } + else { + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); + } + checktoclose(fs, toclose); +} + + +static int funcname (LexState *ls, expdesc *v) { + /* funcname -> NAME {fieldsel} [':' NAME] */ + int ismethod = 0; + singlevar(ls, v); + while (ls->t.token == '.') + fieldsel(ls, v); + if (ls->t.token == ':') { + ismethod = 1; + fieldsel(ls, v); + } + return ismethod; +} + + +static void funcstat (LexState *ls, int line) { + /* funcstat -> FUNCTION funcname body */ + int ismethod; + expdesc v, b; + luaX_next(ls); /* skip FUNCTION */ + ismethod = funcname(ls, &v); + body(ls, &b, ismethod, line); + check_readonly(ls, &v); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition "happens" in the first line */ +} + + +static void exprstat (LexState *ls) { + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + suffixedexp(ls, &v.v); + if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ + v.prev = NULL; + restassign(ls, &v, 1); + } + else { /* stat -> func */ + Instruction *inst; + check_condition(ls, v.v.k == VCALL, "syntax error"); + inst = &getinstruction(fs, &v.v); + SETARG_C(*inst, 1); /* call statement uses no results */ + } +} + + +static void retstat (LexState *ls) { + /* stat -> RETURN [explist] [';'] */ + FuncState *fs = ls->fs; + expdesc e; + int nret; /* number of values being returned */ + int first = luaY_nvarstack(fs); /* first slot to be returned */ + if (block_follow(ls, 1) || ls->t.token == ';') + nret = 0; /* return no values */ + else { + nret = explist(ls, &e); /* optional return values */ + if (hasmultret(e.k)) { + luaK_setmultret(fs, &e); + if (e.k == VCALL && nret == 1 && !fs->bl->insidetbc) { /* tail call? */ + SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL); + lua_assert(GETARG_A(getinstruction(fs,&e)) == luaY_nvarstack(fs)); + } + nret = LUA_MULTRET; /* return all values */ + } + else { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); /* can use original slot */ + else { /* values must go to the top of the stack */ + luaK_exp2nextreg(fs, &e); + lua_assert(nret == fs->freereg - first); + } + } + } + luaK_ret(fs, first, nret); + testnext(ls, ';'); /* skip optional semicolon */ +} + + +static void statement (LexState *ls) { + int line = ls->linenumber; /* may be needed for error messages */ + enterlevel(ls); + switch (ls->t.token) { + case ';': { /* stat -> ';' (empty statement) */ + luaX_next(ls); /* skip ';' */ + break; + } + case TK_IF: { /* stat -> ifstat */ + ifstat(ls, line); + break; + } + case TK_WHILE: { /* stat -> whilestat */ + whilestat(ls, line); + break; + } + case TK_DO: { /* stat -> DO block END */ + luaX_next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + break; + } + case TK_FOR: { /* stat -> forstat */ + forstat(ls, line); + break; + } + case TK_REPEAT: { /* stat -> repeatstat */ + repeatstat(ls, line); + break; + } + case TK_FUNCTION: { /* stat -> funcstat */ + funcstat(ls, line); + break; + } + case TK_LOCAL: { /* stat -> localstat */ + luaX_next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + break; + } + case TK_DBCOLON: { /* stat -> label */ + luaX_next(ls); /* skip double colon */ + labelstat(ls, str_checkname(ls), line); + break; + } + case TK_RETURN: { /* stat -> retstat */ + luaX_next(ls); /* skip RETURN */ + retstat(ls); + break; + } + case TK_BREAK: { /* stat -> breakstat */ + breakstat(ls); + break; + } + case TK_GOTO: { /* stat -> 'goto' NAME */ + luaX_next(ls); /* skip 'goto' */ + gotostat(ls); + break; + } + default: { /* stat -> func | assignment */ + exprstat(ls); + break; + } + } + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && + ls->fs->freereg >= luaY_nvarstack(ls->fs)); + ls->fs->freereg = luaY_nvarstack(ls->fs); /* free registers */ + leavelevel(ls); +} + +/* }====================================================================== */ + + +/* +** compiles the main function, which is a regular vararg function with an +** upvalue named LUA_ENV +*/ +static void mainfunc (LexState *ls, FuncState *fs) { + BlockCnt bl; + Upvaldesc *env; + open_func(ls, fs, &bl); + setvararg(fs, 0); /* main function is always declared vararg */ + env = allocupvalue(fs); /* ...set environment upvalue */ + env->instack = 1; + env->idx = 0; + env->kind = VDKREG; + env->name = ls->envn; + luaC_objbarrier(ls->L, fs->f, env->name); + luaX_next(ls); /* read first token */ + statlist(ls); /* parse main body */ + check(ls, TK_EOS); + close_func(ls); +} + + +LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar) { + LexState lexstate; + FuncState funcstate; + LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ + setclLvalue2s(L, L->top.p, cl); /* anchor it (to avoid being collected) */ + luaD_inctop(L); + lexstate.h = luaH_new(L); /* create table for scanner */ + sethvalue2s(L, L->top.p, lexstate.h); /* anchor it */ + luaD_inctop(L); + funcstate.f = cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); + funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ + luaC_objbarrier(L, funcstate.f, funcstate.f->source); + lexstate.buff = buff; + lexstate.dyd = dyd; + dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; + luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar); + mainfunc(&lexstate, &funcstate); + lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); + /* all scopes should be correctly finished */ + lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); + L->top.p--; /* remove scanner's table */ + return cl; /* closure is on the stack, too */ +} + diff --git a/User/system/lua/src/lparser.h b/User/system/lua/src/lparser.h new file mode 100644 index 0000000..5e4500f --- /dev/null +++ b/User/system/lua/src/lparser.h @@ -0,0 +1,171 @@ +/* +** $Id: lparser.h $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* +** Expression and variable descriptor. +** Code generation for variables and expressions can be delayed to allow +** optimizations; An 'expdesc' structure describes a potentially-delayed +** variable/expression. It has a description of its "main" value plus a +** list of conditional jumps that can also produce its value (generated +** by short-circuit operators 'and'/'or'). +*/ + +/* kinds of variables/expressions */ +typedef enum { + VVOID, /* when 'expdesc' describes the last expression of a list, + this kind means an empty list (so, no expression) */ + VNIL, /* constant nil */ + VTRUE, /* constant true */ + VFALSE, /* constant false */ + VK, /* constant in 'k'; info = index of constant in 'k' */ + VKFLT, /* floating constant; nval = numerical float value */ + VKINT, /* integer constant; ival = numerical integer value */ + VKSTR, /* string constant; strval = TString address; + (string is fixed by the lexer) */ + VNONRELOC, /* expression has its value in a fixed register; + info = result register */ + VLOCAL, /* local variable; var.ridx = register index; + var.vidx = relative index in 'actvar.arr' */ + VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ + VCONST, /* compile-time variable; + info = absolute index in 'actvar.arr' */ + VINDEXED, /* indexed variable; + ind.t = table register; + ind.idx = key's R index */ + VINDEXUP, /* indexed upvalue; + ind.t = table upvalue; + ind.idx = key's K index */ + VINDEXI, /* indexed variable with constant integer; + ind.t = table register; + ind.idx = key's value */ + VINDEXSTR, /* indexed variable with literal string; + ind.t = table register; + ind.idx = key's K index */ + VJMP, /* expression is a test/comparison; + info = pc of corresponding jump instruction */ + VRELOC, /* expression can put result in any register; + info = instruction pc */ + VCALL, /* expression is a function call; info = instruction pc */ + VVARARG /* vararg expression; info = instruction pc */ +} expkind; + + +#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXSTR) +#define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR) + + +typedef struct expdesc { + expkind k; + union { + lua_Integer ival; /* for VKINT */ + lua_Number nval; /* for VKFLT */ + TString *strval; /* for VKSTR */ + int info; /* for generic use */ + struct { /* for indexed variables */ + short idx; /* index (R or "long" K) */ + lu_byte t; /* table (register or upvalue) */ + } ind; + struct { /* for local variables */ + lu_byte ridx; /* register holding the variable */ + unsigned short vidx; /* compiler index (in 'actvar.arr') */ + } var; + } u; + int t; /* patch list of 'exit when true' */ + int f; /* patch list of 'exit when false' */ +} expdesc; + + +/* kinds of variables */ +#define VDKREG 0 /* regular */ +#define RDKCONST 1 /* constant */ +#define RDKTOCLOSE 2 /* to-be-closed */ +#define RDKCTC 3 /* compile-time constant */ + +/* description of an active local variable */ +typedef union Vardesc { + struct { + TValuefields; /* constant value (if it is a compile-time constant) */ + lu_byte kind; + lu_byte ridx; /* register holding the variable */ + short pidx; /* index of the variable in the Proto's 'locvars' array */ + TString *name; /* variable name */ + } vd; + TValue k; /* constant value (if any) */ +} Vardesc; + + + +/* description of pending goto statements and label statements */ +typedef struct Labeldesc { + TString *name; /* label identifier */ + int pc; /* position in code */ + int line; /* line where it appeared */ + lu_byte nactvar; /* number of active variables in that position */ + lu_byte close; /* goto that escapes upvalues */ +} Labeldesc; + + +/* list of labels or gotos */ +typedef struct Labellist { + Labeldesc *arr; /* array */ + int n; /* number of entries in use */ + int size; /* array size */ +} Labellist; + + +/* dynamic structures used by the parser */ +typedef struct Dyndata { + struct { /* list of all active local variables */ + Vardesc *arr; + int n; + int size; + } actvar; + Labellist gt; /* list of pending gotos */ + Labellist label; /* list of active labels */ +} Dyndata; + + +/* control of blocks */ +struct BlockCnt; /* defined in lparser.c */ + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to 'ncode') */ + int lasttarget; /* 'label' of last 'jump label' */ + int previousline; /* last line that was saved in 'lineinfo' */ + int nk; /* number of elements in 'k' */ + int np; /* number of elements in 'p' */ + int nabslineinfo; /* number of elements in 'abslineinfo' */ + int firstlocal; /* index of first local var (in Dyndata array) */ + int firstlabel; /* index of first label (in 'dyd->label->arr') */ + short ndebugvars; /* number of elements in 'f->locvars' */ + lu_byte nactvar; /* number of active local variables */ + lu_byte nups; /* number of upvalues */ + lu_byte freereg; /* first free register */ + lu_byte iwthabs; /* instructions issued since last absolute line info */ + lu_byte needclose; /* function needs to close upvalues when returning */ +} FuncState; + + +LUAI_FUNC int luaY_nvarstack (FuncState *fs); +LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar); + + +#endif diff --git a/User/system/lua/src/lprefix.h b/User/system/lua/src/lprefix.h new file mode 100644 index 0000000..484f2ad --- /dev/null +++ b/User/system/lua/src/lprefix.h @@ -0,0 +1,45 @@ +/* +** $Id: lprefix.h $ +** Definitions for Lua code that must come before any other header file +** See Copyright Notice in lua.h +*/ + +#ifndef lprefix_h +#define lprefix_h + + +/* +** Allows POSIX/XSI stuff +*/ +#if !defined(LUA_USE_C89) /* { */ + +#if !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE 600 +#elif _XOPEN_SOURCE == 0 +#undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ +#endif + +/* +** Allows manipulation of large files in gcc and some other compilers +*/ +#if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) +#define _LARGEFILE_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#endif + +#endif /* } */ + + +/* +** Windows stuff +*/ +#if defined(_WIN32) /* { */ + +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ +#endif + +#endif /* } */ + +#endif + diff --git a/User/system/lua/src/lstate.c b/User/system/lua/src/lstate.c new file mode 100644 index 0000000..7fefacb --- /dev/null +++ b/User/system/lua/src/lstate.c @@ -0,0 +1,445 @@ +/* +** $Id: lstate.c $ +** Global State +** See Copyright Notice in lua.h +*/ + +#define lstate_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + + +/* +** thread state + extra space +*/ +typedef struct LX { + lu_byte extra_[LUA_EXTRASPACE]; + lua_State l; +} LX; + + +/* +** Main thread combines a thread state and the global state +*/ +typedef struct LG { + LX l; + global_State g; +} LG; + + + +#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) + + +/* +** A macro to create a "random" seed when a state is created; +** the seed is used to randomize string hashes. +*/ +#if !defined(luai_makeseed) + +#include + +/* +** Compute an initial seed with some level of randomness. +** Rely on Address Space Layout Randomization (if present) and +** current time. +*/ +#define addbuff(b,p,e) \ + { size_t t = cast_sizet(e); \ + memcpy(b + p, &t, sizeof(t)); p += sizeof(t); } + +static unsigned int luai_makeseed (lua_State *L) { + char buff[3 * sizeof(size_t)]; + unsigned int h = cast_uint(time(NULL)); + int p = 0; + addbuff(buff, p, L); /* heap variable */ + addbuff(buff, p, &h); /* local variable */ + addbuff(buff, p, &lua_newstate); /* public function */ + lua_assert(p == sizeof(buff)); + return luaS_hash(buff, p, h); +} + +#endif + + +/* +** set GCdebt to a new value keeping the value (totalbytes + GCdebt) +** invariant (and avoiding underflows in 'totalbytes') +*/ +void luaE_setdebt (global_State *g, l_mem debt) { + l_mem tb = gettotalbytes(g); + lua_assert(tb > 0); + if (debt < tb - MAX_LMEM) + debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */ + g->totalbytes = tb - debt; + g->GCdebt = debt; +} + + +LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) { + UNUSED(L); UNUSED(limit); + return LUAI_MAXCCALLS; /* warning?? */ +} + + +CallInfo *luaE_extendCI (lua_State *L) { + CallInfo *ci; + lua_assert(L->ci->next == NULL); + ci = luaM_new(L, CallInfo); + lua_assert(L->ci->next == NULL); + L->ci->next = ci; + ci->previous = L->ci; + ci->next = NULL; + ci->u.l.trap = 0; + L->nci++; + return ci; +} + + +/* +** free all CallInfo structures not in use by a thread +*/ +static void freeCI (lua_State *L) { + CallInfo *ci = L->ci; + CallInfo *next = ci->next; + ci->next = NULL; + while ((ci = next) != NULL) { + next = ci->next; + luaM_free(L, ci); + L->nci--; + } +} + + +/* +** free half of the CallInfo structures not in use by a thread, +** keeping the first one. +*/ +void luaE_shrinkCI (lua_State *L) { + CallInfo *ci = L->ci->next; /* first free CallInfo */ + CallInfo *next; + if (ci == NULL) + return; /* no extra elements */ + while ((next = ci->next) != NULL) { /* two extra elements? */ + CallInfo *next2 = next->next; /* next's next */ + ci->next = next2; /* remove next from the list */ + L->nci--; + luaM_free(L, next); /* free next */ + if (next2 == NULL) + break; /* no more elements */ + else { + next2->previous = ci; + ci = next2; /* continue */ + } + } +} + + +/* +** Called when 'getCcalls(L)' larger or equal to LUAI_MAXCCALLS. +** If equal, raises an overflow error. If value is larger than +** LUAI_MAXCCALLS (which means it is handling an overflow) but +** not much larger, does not report an error (to allow overflow +** handling to work). +*/ +void luaE_checkcstack (lua_State *L) { + if (getCcalls(L) == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) + luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ +} + + +LUAI_FUNC void luaE_incCstack (lua_State *L) { + L->nCcalls++; + if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) + luaE_checkcstack(L); +} + + +static void stack_init (lua_State *L1, lua_State *L) { + int i; CallInfo *ci; + /* initialize stack array */ + L1->stack.p = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue); + L1->tbclist.p = L1->stack.p; + for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++) + setnilvalue(s2v(L1->stack.p + i)); /* erase new stack */ + L1->top.p = L1->stack.p; + L1->stack_last.p = L1->stack.p + BASIC_STACK_SIZE; + /* initialize first ci */ + ci = &L1->base_ci; + ci->next = ci->previous = NULL; + ci->callstatus = CIST_C; + ci->func.p = L1->top.p; + ci->u.c.k = NULL; + ci->nresults = 0; + setnilvalue(s2v(L1->top.p)); /* 'function' entry for this 'ci' */ + L1->top.p++; + ci->top.p = L1->top.p + LUA_MINSTACK; + L1->ci = ci; +} + + +static void freestack (lua_State *L) { + if (L->stack.p == NULL) + return; /* stack not completely built yet */ + L->ci = &L->base_ci; /* free the entire 'ci' list */ + freeCI(L); + lua_assert(L->nci == 0); + luaM_freearray(L, L->stack.p, stacksize(L) + EXTRA_STACK); /* free stack */ +} + + +/* +** Create registry table and its predefined values +*/ +static void init_registry (lua_State *L, global_State *g) { + /* create registry */ + Table *registry = luaH_new(L); + sethvalue(L, &g->l_registry, registry); + luaH_resize(L, registry, LUA_RIDX_LAST, 0); + /* registry[LUA_RIDX_MAINTHREAD] = L */ + setthvalue(L, ®istry->array[LUA_RIDX_MAINTHREAD - 1], L); + /* registry[LUA_RIDX_GLOBALS] = new table (table of globals) */ + sethvalue(L, ®istry->array[LUA_RIDX_GLOBALS - 1], luaH_new(L)); +} + + +/* +** open parts of the state that may cause memory-allocation errors. +*/ +static void f_luaopen (lua_State *L, void *ud) { + global_State *g = G(L); + UNUSED(ud); + stack_init(L, L); /* init stack */ + init_registry(L, g); + luaS_init(L); + luaT_init(L); + luaX_init(L); + g->gcstp = 0; /* allow gc */ + setnilvalue(&g->nilvalue); /* now state is complete */ + luai_userstateopen(L); +} + + +/* +** preinitialize a thread with consistent values without allocating +** any memory (to avoid errors) +*/ +static void preinit_thread (lua_State *L, global_State *g) { + G(L) = g; + L->stack.p = NULL; + L->ci = NULL; + L->nci = 0; + L->twups = L; /* thread has no upvalues */ + L->nCcalls = 0; + L->errorJmp = NULL; + L->hook = NULL; + L->hookmask = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->status = LUA_OK; + L->errfunc = 0; + L->oldpc = 0; +} + + +static void close_state (lua_State *L) { + global_State *g = G(L); + if (!completestate(g)) /* closing a partially built state? */ + luaC_freeallobjects(L); /* just collect its objects */ + else { /* closing a fully built state */ + L->ci = &L->base_ci; /* unwind CallInfo list */ + luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */ + luaC_freeallobjects(L); /* collect all objects */ + luai_userstateclose(L); + } + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); + freestack(L); + lua_assert(gettotalbytes(g) == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ +} + + +LUA_API lua_State *lua_newthread (lua_State *L) { + global_State *g = G(L); + GCObject *o; + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + /* create new thread */ + o = luaC_newobjdt(L, LUA_TTHREAD, sizeof(LX), offsetof(LX, l)); + L1 = gco2th(o); + /* anchor it on L stack */ + setthvalue2s(L, L->top.p, L1); + api_incr_top(L); + preinit_thread(L1, g); + L1->hookmask = L->hookmask; + L1->basehookcount = L->basehookcount; + L1->hook = L->hook; + resethookcount(L1); + /* initialize L1 extra space */ + memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread), + LUA_EXTRASPACE); + luai_userstatethread(L, L1); + stack_init(L1, L); /* init stack */ + lua_unlock(L); + return L1; +} + + +void luaE_freethread (lua_State *L, lua_State *L1) { + LX *l = fromstate(L1); + luaF_closeupval(L1, L1->stack.p); /* close all upvalues */ + lua_assert(L1->openupval == NULL); + luai_userstatefree(L, L1); + freestack(L1); + luaM_free(L, l); +} + + +int luaE_resetthread (lua_State *L, int status) { + CallInfo *ci = L->ci = &L->base_ci; /* unwind CallInfo list */ + setnilvalue(s2v(L->stack.p)); /* 'function' entry for basic 'ci' */ + ci->func.p = L->stack.p; + ci->callstatus = CIST_C; + if (status == LUA_YIELD) + status = LUA_OK; + L->status = LUA_OK; /* so it can run __close metamethods */ + status = luaD_closeprotected(L, 1, status); + if (status != LUA_OK) /* errors? */ + luaD_seterrorobj(L, status, L->stack.p + 1); + else + L->top.p = L->stack.p + 1; + ci->top.p = L->top.p + LUA_MINSTACK; + luaD_reallocstack(L, cast_int(ci->top.p - L->stack.p), 0); + return status; +} + + +LUA_API int lua_closethread (lua_State *L, lua_State *from) { + int status; + lua_lock(L); + L->nCcalls = (from) ? getCcalls(from) : 0; + status = luaE_resetthread(L, L->status); + lua_unlock(L); + return status; +} + + +/* +** Deprecated! Use 'lua_closethread' instead. +*/ +LUA_API int lua_resetthread (lua_State *L) { + return lua_closethread(L, NULL); +} + + +LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { + int i; + lua_State *L; + global_State *g; + LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); + if (l == NULL) return NULL; + L = &l->l.l; + g = &l->g; + L->tt = LUA_VTHREAD; + g->currentwhite = bitmask(WHITE0BIT); + L->marked = luaC_white(g); + preinit_thread(L, g); + g->allgc = obj2gco(L); /* by now, only object is the main thread */ + L->next = NULL; + incnny(L); /* main thread is always non yieldable */ + g->frealloc = f; + g->ud = ud; + g->warnf = NULL; + g->ud_warn = NULL; + g->mainthread = L; + g->seed = luai_makeseed(L); + g->gcstp = GCSTPGC; /* no GC while building state */ + g->strt.size = g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(&g->l_registry); + g->panic = NULL; + g->gcstate = GCSpause; + g->gckind = KGC_INC; + g->gcstopem = 0; + g->gcemergency = 0; + g->finobj = g->tobefnz = g->fixedgc = NULL; + g->firstold1 = g->survival = g->old1 = g->reallyold = NULL; + g->finobjsur = g->finobjold1 = g->finobjrold = NULL; + g->sweepgc = NULL; + g->gray = g->grayagain = NULL; + g->weak = g->ephemeron = g->allweak = NULL; + g->twups = NULL; + g->totalbytes = sizeof(LG); + g->GCdebt = 0; + g->lastatomic = 0; + setivalue(&g->nilvalue, 0); /* to signal that state is not yet built */ + setgcparam(g->gcpause, LUAI_GCPAUSE); + setgcparam(g->gcstepmul, LUAI_GCMUL); + g->gcstepsize = LUAI_GCSTEPSIZE; + setgcparam(g->genmajormul, LUAI_GENMAJORMUL); + g->genminormul = LUAI_GENMINORMUL; + for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + return L; +} + + +LUA_API void lua_close (lua_State *L) { + lua_lock(L); + L = G(L)->mainthread; /* only the main thread can be closed */ + close_state(L); +} + + +void luaE_warning (lua_State *L, const char *msg, int tocont) { + lua_WarnFunction wf = G(L)->warnf; + if (wf != NULL) + wf(G(L)->ud_warn, msg, tocont); +} + + +/* +** Generate a warning from an error message +*/ +void luaE_warnerror (lua_State *L, const char *where) { + TValue *errobj = s2v(L->top.p - 1); /* error object */ + const char *msg = (ttisstring(errobj)) + ? getstr(tsvalue(errobj)) + : "error object is not a string"; + /* produce warning "error in %s (%s)" (where, msg) */ + luaE_warning(L, "error in ", 1); + luaE_warning(L, where, 1); + luaE_warning(L, " (", 1); + luaE_warning(L, msg, 1); + luaE_warning(L, ")", 0); +} + diff --git a/User/system/lua/src/lstate.h b/User/system/lua/src/lstate.h new file mode 100644 index 0000000..007704c --- /dev/null +++ b/User/system/lua/src/lstate.h @@ -0,0 +1,408 @@ +/* +** $Id: lstate.h $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lua.h" + + +/* Some header files included here need this definition */ +typedef struct CallInfo CallInfo; + + +#include "lobject.h" +#include "ltm.h" +#include "lzio.h" + + +/* +** Some notes about garbage-collected objects: All objects in Lua must +** be kept somehow accessible until being freed, so all objects always +** belong to one (and only one) of these lists, using field 'next' of +** the 'CommonHeader' for the link: +** +** 'allgc': all objects not marked for finalization; +** 'finobj': all objects marked for finalization; +** 'tobefnz': all objects ready to be finalized; +** 'fixedgc': all objects that are not to be collected (currently +** only small strings, such as reserved words). +** +** For the generational collector, some of these lists have marks for +** generations. Each mark points to the first element in the list for +** that particular generation; that generation goes until the next mark. +** +** 'allgc' -> 'survival': new objects; +** 'survival' -> 'old': objects that survived one collection; +** 'old1' -> 'reallyold': objects that became old in last collection; +** 'reallyold' -> NULL: objects old for more than one cycle. +** +** 'finobj' -> 'finobjsur': new objects marked for finalization; +** 'finobjsur' -> 'finobjold1': survived """"; +** 'finobjold1' -> 'finobjrold': just old """"; +** 'finobjrold' -> NULL: really old """". +** +** All lists can contain elements older than their main ages, due +** to 'luaC_checkfinalizer' and 'udata2finalize', which move +** objects between the normal lists and the "marked for finalization" +** lists. Moreover, barriers can age young objects in young lists as +** OLD0, which then become OLD1. However, a list never contains +** elements younger than their main ages. +** +** The generational collector also uses a pointer 'firstold1', which +** points to the first OLD1 object in the list. It is used to optimize +** 'markold'. (Potentially OLD1 objects can be anywhere between 'allgc' +** and 'reallyold', but often the list has no OLD1 objects or they are +** after 'old1'.) Note the difference between it and 'old1': +** 'firstold1': no OLD1 objects before this point; there can be all +** ages after it. +** 'old1': no objects younger than OLD1 after this point. +*/ + +/* +** Moreover, there is another set of lists that control gray objects. +** These lists are linked by fields 'gclist'. (All objects that +** can become gray have such a field. The field is not the same +** in all objects, but it always has this name.) Any gray object +** must belong to one of these lists, and all objects in these lists +** must be gray (with two exceptions explained below): +** +** 'gray': regular gray objects, still waiting to be visited. +** 'grayagain': objects that must be revisited at the atomic phase. +** That includes +** - black objects got in a write barrier; +** - all kinds of weak tables during propagation phase; +** - all threads. +** 'weak': tables with weak values to be cleared; +** 'ephemeron': ephemeron tables with white->white entries; +** 'allweak': tables with weak keys and/or weak values to be cleared. +** +** The exceptions to that "gray rule" are: +** - TOUCHED2 objects in generational mode stay in a gray list (because +** they must be visited again at the end of the cycle), but they are +** marked black because assignments to them must activate barriers (to +** move them back to TOUCHED1). +** - Open upvales are kept gray to avoid barriers, but they stay out +** of gray lists. (They don't even have a 'gclist' field.) +*/ + + + +/* +** About 'nCcalls': This count has two parts: the lower 16 bits counts +** the number of recursive invocations in the C stack; the higher +** 16 bits counts the number of non-yieldable calls in the stack. +** (They are together so that we can change and save both with one +** instruction.) +*/ + + +/* true if this thread does not have non-yieldable calls in the stack */ +#define yieldable(L) (((L)->nCcalls & 0xffff0000) == 0) + +/* real number of C calls */ +#define getCcalls(L) ((L)->nCcalls & 0xffff) + + +/* Increment the number of non-yieldable calls */ +#define incnny(L) ((L)->nCcalls += 0x10000) + +/* Decrement the number of non-yieldable calls */ +#define decnny(L) ((L)->nCcalls -= 0x10000) + +/* Non-yieldable call increment */ +#define nyci (0x10000 | 1) + + + + +struct lua_longjmp; /* defined in ldo.c */ + + +/* +** Atomic type (relative to signals) to better ensure that 'lua_sethook' +** is thread safe +*/ +#if !defined(l_signalT) +#include +#define l_signalT sig_atomic_t +#endif + + +/* +** Extra stack space to handle TM calls and some other extras. This +** space is not included in 'stack_last'. It is used only to avoid stack +** checks, either because the element will be promptly popped or because +** there will be a stack check soon after the push. Function frames +** never use this extra space, so it does not need to be kept clean. +*/ +#define EXTRA_STACK 5 + + +#define BASIC_STACK_SIZE (2*LUA_MINSTACK) + +#define stacksize(th) cast_int((th)->stack_last.p - (th)->stack.p) + + +/* kinds of Garbage Collection */ +#define KGC_INC 0 /* incremental gc */ +#define KGC_GEN 1 /* generational gc */ + + +typedef struct stringtable { + TString **hash; + int nuse; /* number of elements */ + int size; +} stringtable; + + +/* +** Information about a call. +** About union 'u': +** - field 'l' is used only for Lua functions; +** - field 'c' is used only for C functions. +** About union 'u2': +** - field 'funcidx' is used only by C functions while doing a +** protected call; +** - field 'nyield' is used only while a function is "doing" an +** yield (from the yield until the next resume); +** - field 'nres' is used only while closing tbc variables when +** returning from a function; +** - field 'transferinfo' is used only during call/returnhooks, +** before the function starts or after it ends. +*/ +struct CallInfo { + StkIdRel func; /* function index in the stack */ + StkIdRel top; /* top for this function */ + struct CallInfo *previous, *next; /* dynamic call link */ + union { + struct { /* only for Lua functions */ + const Instruction *savedpc; + volatile l_signalT trap; /* function is tracing lines/counts */ + int nextraargs; /* # of extra arguments in vararg functions */ + } l; + struct { /* only for C functions */ + lua_KFunction k; /* continuation in case of yields */ + ptrdiff_t old_errfunc; + lua_KContext ctx; /* context info. in case of yields */ + } c; + } u; + union { + int funcidx; /* called-function index */ + int nyield; /* number of values yielded */ + int nres; /* number of values returned */ + struct { /* info about transferred values (for call/return hooks) */ + unsigned short ftransfer; /* offset of first value transferred */ + unsigned short ntransfer; /* number of values transferred */ + } transferinfo; + } u2; + short nresults; /* expected number of results from this function */ + unsigned short callstatus; +}; + + +/* +** Bits in CallInfo status +*/ +#define CIST_OAH (1<<0) /* original value of 'allowhook' */ +#define CIST_C (1<<1) /* call is running a C function */ +#define CIST_FRESH (1<<2) /* call is on a fresh "luaV_execute" frame */ +#define CIST_HOOKED (1<<3) /* call is running a debug hook */ +#define CIST_YPCALL (1<<4) /* doing a yieldable protected call */ +#define CIST_TAIL (1<<5) /* call was tail called */ +#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ +#define CIST_FIN (1<<7) /* function "called" a finalizer */ +#define CIST_TRAN (1<<8) /* 'ci' has transfer information */ +#define CIST_CLSRET (1<<9) /* function is closing tbc variables */ +/* Bits 10-12 are used for CIST_RECST (see below) */ +#define CIST_RECST 10 +#if defined(LUA_COMPAT_LT_LE) +#define CIST_LEQ (1<<13) /* using __lt for __le */ +#endif + + +/* +** Field CIST_RECST stores the "recover status", used to keep the error +** status while closing to-be-closed variables in coroutines, so that +** Lua can correctly resume after an yield from a __close method called +** because of an error. (Three bits are enough for error status.) +*/ +#define getcistrecst(ci) (((ci)->callstatus >> CIST_RECST) & 7) +#define setcistrecst(ci,st) \ + check_exp(((st) & 7) == (st), /* status must fit in three bits */ \ + ((ci)->callstatus = ((ci)->callstatus & ~(7 << CIST_RECST)) \ + | ((st) << CIST_RECST))) + + +/* active function is a Lua function */ +#define isLua(ci) (!((ci)->callstatus & CIST_C)) + +/* call is running Lua code (not a hook) */ +#define isLuacode(ci) (!((ci)->callstatus & (CIST_C | CIST_HOOKED))) + +/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ +#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) +#define getoah(st) ((st) & CIST_OAH) + + +/* +** 'global state', shared by all threads of this state +*/ +typedef struct global_State { + lua_Alloc frealloc; /* function to reallocate memory */ + void *ud; /* auxiliary data to 'frealloc' */ + l_mem totalbytes; /* number of bytes currently allocated - GCdebt */ + l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ + lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ + lu_mem lastatomic; /* see function 'genstep' in file 'lgc.c' */ + stringtable strt; /* hash table for strings */ + TValue l_registry; + TValue nilvalue; /* a nil value */ + unsigned int seed; /* randomized seed for hashes */ + lu_byte currentwhite; + lu_byte gcstate; /* state of garbage collector */ + lu_byte gckind; /* kind of GC running */ + lu_byte gcstopem; /* stops emergency collections */ + lu_byte genminormul; /* control for minor generational collections */ + lu_byte genmajormul; /* control for major generational collections */ + lu_byte gcstp; /* control whether GC is running */ + lu_byte gcemergency; /* true if this is an emergency collection */ + lu_byte gcpause; /* size of pause between successive GCs */ + lu_byte gcstepmul; /* GC "speed" */ + lu_byte gcstepsize; /* (log2 of) GC granularity */ + GCObject *allgc; /* list of all collectable objects */ + GCObject **sweepgc; /* current position of sweep in list */ + GCObject *finobj; /* list of collectable objects with finalizers */ + GCObject *gray; /* list of gray objects */ + GCObject *grayagain; /* list of objects to be traversed atomically */ + GCObject *weak; /* list of tables with weak values */ + GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ + GCObject *allweak; /* list of all-weak tables */ + GCObject *tobefnz; /* list of userdata to be GC */ + GCObject *fixedgc; /* list of objects not to be collected */ + /* fields for generational collector */ + GCObject *survival; /* start of objects that survived one GC cycle */ + GCObject *old1; /* start of old1 objects */ + GCObject *reallyold; /* objects more than one cycle old ("really old") */ + GCObject *firstold1; /* first OLD1 object in the list (if any) */ + GCObject *finobjsur; /* list of survival objects with finalizers */ + GCObject *finobjold1; /* list of old1 objects with finalizers */ + GCObject *finobjrold; /* list of really old objects with finalizers */ + struct lua_State *twups; /* list of threads with open upvalues */ + lua_CFunction panic; /* to be called in unprotected errors */ + struct lua_State *mainthread; + TString *memerrmsg; /* message for memory-allocation errors */ + TString *tmname[TM_N]; /* array with tag-method names */ + struct Table *mt[LUA_NUMTYPES]; /* metatables for basic types */ + TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ + lua_WarnFunction warnf; /* warning function */ + void *ud_warn; /* auxiliary data to 'warnf' */ +} global_State; + + +/* +** 'per thread' state +*/ +struct lua_State { + CommonHeader; + lu_byte status; + lu_byte allowhook; + unsigned short nci; /* number of items in 'ci' list */ + StkIdRel top; /* first free slot in the stack */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + StkIdRel stack_last; /* end of stack (last element + 1) */ + StkIdRel stack; /* stack base */ + UpVal *openupval; /* list of open upvalues in this stack */ + StkIdRel tbclist; /* list of to-be-closed variables */ + GCObject *gclist; + struct lua_State *twups; /* list of threads with open upvalues */ + struct lua_longjmp *errorJmp; /* current error recover point */ + CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ + volatile lua_Hook hook; + ptrdiff_t errfunc; /* current error handling function (stack index) */ + l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */ + int oldpc; /* last pc traced */ + int basehookcount; + int hookcount; + volatile l_signalT hookmask; +}; + + +#define G(L) (L->l_G) + +/* +** 'g->nilvalue' being a nil value flags that the state was completely +** build. +*/ +#define completestate(g) ttisnil(&g->nilvalue) + + +/* +** Union of all collectable objects (only for conversions) +** ISO C99, 6.5.2.3 p.5: +** "if a union contains several structures that share a common initial +** sequence [...], and if the union object currently contains one +** of these structures, it is permitted to inspect the common initial +** part of any of them anywhere that a declaration of the complete type +** of the union is visible." +*/ +union GCUnion { + GCObject gc; /* common header */ + struct TString ts; + struct Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct lua_State th; /* thread */ + struct UpVal upv; +}; + + +/* +** ISO C99, 6.7.2.1 p.14: +** "A pointer to a union object, suitably converted, points to each of +** its members [...], and vice versa." +*/ +#define cast_u(o) cast(union GCUnion *, (o)) + +/* macros to convert a GCObject into a specific value */ +#define gco2ts(o) \ + check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) +#define gco2u(o) check_exp((o)->tt == LUA_VUSERDATA, &((cast_u(o))->u)) +#define gco2lcl(o) check_exp((o)->tt == LUA_VLCL, &((cast_u(o))->cl.l)) +#define gco2ccl(o) check_exp((o)->tt == LUA_VCCL, &((cast_u(o))->cl.c)) +#define gco2cl(o) \ + check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) +#define gco2t(o) check_exp((o)->tt == LUA_VTABLE, &((cast_u(o))->h)) +#define gco2p(o) check_exp((o)->tt == LUA_VPROTO, &((cast_u(o))->p)) +#define gco2th(o) check_exp((o)->tt == LUA_VTHREAD, &((cast_u(o))->th)) +#define gco2upv(o) check_exp((o)->tt == LUA_VUPVAL, &((cast_u(o))->upv)) + + +/* +** macro to convert a Lua object into a GCObject +** (The access to 'tt' tries to ensure that 'v' is actually a Lua object.) +*/ +#define obj2gco(v) check_exp((v)->tt >= LUA_TSTRING, &(cast_u(v)->gc)) + + +/* actual number of total bytes allocated */ +#define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt) + +LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); +LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); +LUAI_FUNC void luaE_shrinkCI (lua_State *L); +LUAI_FUNC void luaE_checkcstack (lua_State *L); +LUAI_FUNC void luaE_incCstack (lua_State *L); +LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); +LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); +LUAI_FUNC int luaE_resetthread (lua_State *L, int status); + + +#endif + diff --git a/User/system/lua/src/lstring.c b/User/system/lua/src/lstring.c new file mode 100644 index 0000000..9775735 --- /dev/null +++ b/User/system/lua/src/lstring.c @@ -0,0 +1,274 @@ +/* +** $Id: lstring.c $ +** String table (keeps all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#define lstring_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" + + +/* +** Maximum size for string table. +*/ +#define MAXSTRTB cast_int(luaM_limitN(MAX_INT, TString*)) + + +/* +** equality for long strings +*/ +int luaS_eqlngstr (TString *a, TString *b) { + size_t len = a->u.lnglen; + lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR); + return (a == b) || /* same instance or... */ + ((len == b->u.lnglen) && /* equal length and ... */ + (memcmp(getlngstr(a), getlngstr(b), len) == 0)); /* equal contents */ +} + + +unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { + unsigned int h = seed ^ cast_uint(l); + for (; l > 0; l--) + h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); + return h; +} + + +unsigned int luaS_hashlongstr (TString *ts) { + lua_assert(ts->tt == LUA_VLNGSTR); + if (ts->extra == 0) { /* no hash? */ + size_t len = ts->u.lnglen; + ts->hash = luaS_hash(getlngstr(ts), len, ts->hash); + ts->extra = 1; /* now it has its hash */ + } + return ts->hash; +} + + +static void tablerehash (TString **vect, int osize, int nsize) { + int i; + for (i = osize; i < nsize; i++) /* clear new elements */ + vect[i] = NULL; + for (i = 0; i < osize; i++) { /* rehash old part of the array */ + TString *p = vect[i]; + vect[i] = NULL; + while (p) { /* for each string in the list */ + TString *hnext = p->u.hnext; /* save next */ + unsigned int h = lmod(p->hash, nsize); /* new position */ + p->u.hnext = vect[h]; /* chain it into array */ + vect[h] = p; + p = hnext; + } + } +} + + +/* +** Resize the string table. If allocation fails, keep the current size. +** (This can degrade performance, but any non-zero size should work +** correctly.) +*/ +void luaS_resize (lua_State *L, int nsize) { + stringtable *tb = &G(L)->strt; + int osize = tb->size; + TString **newvect; + if (nsize < osize) /* shrinking table? */ + tablerehash(tb->hash, osize, nsize); /* depopulate shrinking part */ + newvect = luaM_reallocvector(L, tb->hash, osize, nsize, TString*); + if (l_unlikely(newvect == NULL)) { /* reallocation failed? */ + if (nsize < osize) /* was it shrinking table? */ + tablerehash(tb->hash, nsize, osize); /* restore to original size */ + /* leave table as it was */ + } + else { /* allocation succeeded */ + tb->hash = newvect; + tb->size = nsize; + if (nsize > osize) + tablerehash(newvect, osize, nsize); /* rehash for new size */ + } +} + + +/* +** Clear API string cache. (Entries cannot be empty, so fill them with +** a non-collectable string.) +*/ +void luaS_clearcache (global_State *g) { + int i, j; + for (i = 0; i < STRCACHE_N; i++) + for (j = 0; j < STRCACHE_M; j++) { + if (iswhite(g->strcache[i][j])) /* will entry be collected? */ + g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */ + } +} + + +/* +** Initialize the string table and the string cache +*/ +void luaS_init (lua_State *L) { + global_State *g = G(L); + int i, j; + stringtable *tb = &G(L)->strt; + tb->hash = luaM_newvector(L, MINSTRTABSIZE, TString*); + tablerehash(tb->hash, 0, MINSTRTABSIZE); /* clear array */ + tb->size = MINSTRTABSIZE; + /* pre-create memory-error message */ + g->memerrmsg = luaS_newliteral(L, MEMERRMSG); + luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ + for (i = 0; i < STRCACHE_N; i++) /* fill cache with valid strings */ + for (j = 0; j < STRCACHE_M; j++) + g->strcache[i][j] = g->memerrmsg; +} + + + +/* +** creates a new string object +*/ +static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) { + TString *ts; + GCObject *o; + size_t totalsize; /* total size of TString object */ + totalsize = sizelstring(l); + o = luaC_newobj(L, tag, totalsize); + ts = gco2ts(o); + ts->hash = h; + ts->extra = 0; + getstr(ts)[l] = '\0'; /* ending 0 */ + return ts; +} + + +TString *luaS_createlngstrobj (lua_State *L, size_t l) { + TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed); + ts->u.lnglen = l; + ts->shrlen = 0xFF; /* signals that it is a long string */ + return ts; +} + + +void luaS_remove (lua_State *L, TString *ts) { + stringtable *tb = &G(L)->strt; + TString **p = &tb->hash[lmod(ts->hash, tb->size)]; + while (*p != ts) /* find previous element */ + p = &(*p)->u.hnext; + *p = (*p)->u.hnext; /* remove element from its list */ + tb->nuse--; +} + + +static void growstrtab (lua_State *L, stringtable *tb) { + if (l_unlikely(tb->nuse == MAX_INT)) { /* too many strings? */ + luaC_fullgc(L, 1); /* try to free some... */ + if (tb->nuse == MAX_INT) /* still too many? */ + luaM_error(L); /* cannot even create a message... */ + } + if (tb->size <= MAXSTRTB / 2) /* can grow string table? */ + luaS_resize(L, tb->size * 2); +} + + +/* +** Checks whether short string exists and reuses it or creates a new one. +*/ +static TString *internshrstr (lua_State *L, const char *str, size_t l) { + TString *ts; + global_State *g = G(L); + stringtable *tb = &g->strt; + unsigned int h = luaS_hash(str, l, g->seed); + TString **list = &tb->hash[lmod(h, tb->size)]; + lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ + for (ts = *list; ts != NULL; ts = ts->u.hnext) { + if (l == ts->shrlen && (memcmp(str, getshrstr(ts), l * sizeof(char)) == 0)) { + /* found! */ + if (isdead(g, ts)) /* dead (but not collected yet)? */ + changewhite(ts); /* resurrect it */ + return ts; + } + } + /* else must create a new string */ + if (tb->nuse >= tb->size) { /* need to grow string table? */ + growstrtab(L, tb); + list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ + } + ts = createstrobj(L, l, LUA_VSHRSTR, h); + ts->shrlen = cast_byte(l); + memcpy(getshrstr(ts), str, l * sizeof(char)); + ts->u.hnext = *list; + *list = ts; + tb->nuse++; + return ts; +} + + +/* +** new string (with explicit length) +*/ +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + if (l <= LUAI_MAXSHORTLEN) /* short string? */ + return internshrstr(L, str, l); + else { + TString *ts; + if (l_unlikely(l * sizeof(char) >= (MAX_SIZE - sizeof(TString)))) + luaM_toobig(L); + ts = luaS_createlngstrobj(L, l); + memcpy(getlngstr(ts), str, l * sizeof(char)); + return ts; + } +} + + +/* +** Create or reuse a zero-terminated string, first checking in the +** cache (using the string address as a key). The cache can contain +** only zero-terminated strings, so it is safe to use 'strcmp' to +** check hits. +*/ +TString *luaS_new (lua_State *L, const char *str) { + unsigned int i = point2uint(str) % STRCACHE_N; /* hash */ + int j; + TString **p = G(L)->strcache[i]; + for (j = 0; j < STRCACHE_M; j++) { + if (strcmp(str, getstr(p[j])) == 0) /* hit? */ + return p[j]; /* that is it */ + } + /* normal route */ + for (j = STRCACHE_M - 1; j > 0; j--) + p[j] = p[j - 1]; /* move out last element */ + /* new element is first in the list */ + p[0] = luaS_newlstr(L, str, strlen(str)); + return p[0]; +} + + +Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue) { + Udata *u; + int i; + GCObject *o; + if (l_unlikely(s > MAX_SIZE - udatamemoffset(nuvalue))) + luaM_toobig(L); + o = luaC_newobj(L, LUA_VUSERDATA, sizeudata(nuvalue, s)); + u = gco2u(o); + u->len = s; + u->nuvalue = nuvalue; + u->metatable = NULL; + for (i = 0; i < nuvalue; i++) + setnilvalue(&u->uv[i].uv); + return u; +} + diff --git a/User/system/lua/src/lstring.h b/User/system/lua/src/lstring.h new file mode 100644 index 0000000..450c239 --- /dev/null +++ b/User/system/lua/src/lstring.h @@ -0,0 +1,57 @@ +/* +** $Id: lstring.h $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" + + +/* +** Memory-allocation error message must be preallocated (it cannot +** be created after memory is exhausted) +*/ +#define MEMERRMSG "not enough memory" + + +/* +** Size of a TString: Size of the header plus space for the string +** itself (including final '\0'). +*/ +#define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) + +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s)/sizeof(char))-1)) + + +/* +** test whether a string is a reserved word +*/ +#define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0) + + +/* +** equality for short strings, which are always internalized +*/ +#define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) + + +LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); +LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); +LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); +LUAI_FUNC void luaS_resize (lua_State *L, int newsize); +LUAI_FUNC void luaS_clearcache (global_State *g); +LUAI_FUNC void luaS_init (lua_State *L); +LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue); +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); +LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); +LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); + + +#endif diff --git a/User/system/lua/src/lstrlib.c b/User/system/lua/src/lstrlib.c new file mode 100644 index 0000000..0316716 --- /dev/null +++ b/User/system/lua/src/lstrlib.c @@ -0,0 +1,1874 @@ +/* +** $Id: lstrlib.c $ +** Standard library for string operations and pattern-matching +** See Copyright Notice in lua.h +*/ + +#define lstrlib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** maximum number of captures that a pattern can do during +** pattern-matching. This limit is arbitrary, but must fit in +** an unsigned char. +*/ +#if !defined(LUA_MAXCAPTURES) +#define LUA_MAXCAPTURES 32 +#endif + + +/* macro to 'unsign' a character */ +#define uchar(c) ((unsigned char)(c)) + + +/* +** Some sizes are better limited to fit in 'int', but must also fit in +** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.) +*/ +#define MAX_SIZET ((size_t)(~(size_t)0)) + +#define MAXSIZE \ + (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX)) + + + + +static int str_len (lua_State *L) { + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushinteger(L, (lua_Integer)l); + return 1; +} + + +/* +** translate a relative initial string position +** (negative means back from end): clip result to [1, inf). +** The length of any string in Lua must fit in a lua_Integer, +** so there are no overflows in the casts. +** The inverted comparison avoids a possible overflow +** computing '-pos'. +*/ +static size_t posrelatI (lua_Integer pos, size_t len) { + if (pos > 0) + return (size_t)pos; + else if (pos == 0) + return 1; + else if (pos < -(lua_Integer)len) /* inverted comparison */ + return 1; /* clip to 1 */ + else return len + (size_t)pos + 1; +} + + +/* +** Gets an optional ending string position from argument 'arg', +** with default value 'def'. +** Negative means back from end: clip result to [0, len] +*/ +static size_t getendpos (lua_State *L, int arg, lua_Integer def, + size_t len) { + lua_Integer pos = luaL_optinteger(L, arg, def); + if (pos > (lua_Integer)len) + return len; + else if (pos >= 0) + return (size_t)pos; + else if (pos < -(lua_Integer)len) + return 0; + else return len + (size_t)pos + 1; +} + + +static int str_sub (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t start = posrelatI(luaL_checkinteger(L, 2), l); + size_t end = getendpos(L, 3, -1, l); + if (start <= end) + lua_pushlstring(L, s + start - 1, (end - start) + 1); + else lua_pushliteral(L, ""); + return 1; +} + + +static int str_reverse (lua_State *L) { + size_t l, i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + char *p = luaL_buffinitsize(L, &b, l); + for (i = 0; i < l; i++) + p[i] = s[l - i - 1]; + luaL_pushresultsize(&b, l); + return 1; +} + + +static int str_lower (lua_State *L) { + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + char *p = luaL_buffinitsize(L, &b, l); + for (i=0; i MAXSIZE / n)) + return luaL_error(L, "resulting string too large"); + else { + size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep; + luaL_Buffer b; + char *p = luaL_buffinitsize(L, &b, totallen); + while (n-- > 1) { /* first n-1 copies (followed by separator) */ + memcpy(p, s, l * sizeof(char)); p += l; + if (lsep > 0) { /* empty 'memcpy' is not that cheap */ + memcpy(p, sep, lsep * sizeof(char)); + p += lsep; + } + } + memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ + luaL_pushresultsize(&b, totallen); + } + return 1; +} + + +static int str_byte (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + lua_Integer pi = luaL_optinteger(L, 2, 1); + size_t posi = posrelatI(pi, l); + size_t pose = getendpos(L, 3, pi, l); + int n, i; + if (posi > pose) return 0; /* empty interval; return no values */ + if (l_unlikely(pose - posi >= (size_t)INT_MAX)) /* arithmetic overflow? */ + return luaL_error(L, "string slice too long"); + n = (int)(pose - posi) + 1; + luaL_checkstack(L, n, "string slice too long"); + for (i=0; iinit) { + state->init = 1; + luaL_buffinit(L, &state->B); + } + luaL_addlstring(&state->B, (const char *)b, size); + return 0; +} + + +static int str_dump (lua_State *L) { + struct str_Writer state; + int strip = lua_toboolean(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, 1); /* ensure function is on the top of the stack */ + state.init = 0; + if (l_unlikely(lua_dump(L, writer, &state, strip) != 0)) + return luaL_error(L, "unable to dump given function"); + luaL_pushresult(&state.B); + return 1; +} + + + +/* +** {====================================================== +** METAMETHODS +** ======================================================= +*/ + +#if defined(LUA_NOCVTS2N) /* { */ + +/* no coercion from strings to numbers */ + +static const luaL_Reg stringmetamethods[] = { + {"__index", NULL}, /* placeholder */ + {NULL, NULL} +}; + +#else /* }{ */ + +static int tonum (lua_State *L, int arg) { + if (lua_type(L, arg) == LUA_TNUMBER) { /* already a number? */ + lua_pushvalue(L, arg); + return 1; + } + else { /* check whether it is a numerical string */ + size_t len; + const char *s = lua_tolstring(L, arg, &len); + return (s != NULL && lua_stringtonumber(L, s) == len + 1); + } +} + + +static void trymt (lua_State *L, const char *mtname) { + lua_settop(L, 2); /* back to the original arguments */ + if (l_unlikely(lua_type(L, 2) == LUA_TSTRING || + !luaL_getmetafield(L, 2, mtname))) + luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2, + luaL_typename(L, -2), luaL_typename(L, -1)); + lua_insert(L, -3); /* put metamethod before arguments */ + lua_call(L, 2, 1); /* call metamethod */ +} + + +static int arith (lua_State *L, int op, const char *mtname) { + if (tonum(L, 1) && tonum(L, 2)) + lua_arith(L, op); /* result will be on the top */ + else + trymt(L, mtname); + return 1; +} + + +static int arith_add (lua_State *L) { + return arith(L, LUA_OPADD, "__add"); +} + +static int arith_sub (lua_State *L) { + return arith(L, LUA_OPSUB, "__sub"); +} + +static int arith_mul (lua_State *L) { + return arith(L, LUA_OPMUL, "__mul"); +} + +static int arith_mod (lua_State *L) { + return arith(L, LUA_OPMOD, "__mod"); +} + +static int arith_pow (lua_State *L) { + return arith(L, LUA_OPPOW, "__pow"); +} + +static int arith_div (lua_State *L) { + return arith(L, LUA_OPDIV, "__div"); +} + +static int arith_idiv (lua_State *L) { + return arith(L, LUA_OPIDIV, "__idiv"); +} + +static int arith_unm (lua_State *L) { + return arith(L, LUA_OPUNM, "__unm"); +} + + +static const luaL_Reg stringmetamethods[] = { + {"__add", arith_add}, + {"__sub", arith_sub}, + {"__mul", arith_mul}, + {"__mod", arith_mod}, + {"__pow", arith_pow}, + {"__div", arith_div}, + {"__idiv", arith_idiv}, + {"__unm", arith_unm}, + {"__index", NULL}, /* placeholder */ + {NULL, NULL} +}; + +#endif /* } */ + +/* }====================================================== */ + +/* +** {====================================================== +** PATTERN MATCHING +** ======================================================= +*/ + + +#define CAP_UNFINISHED (-1) +#define CAP_POSITION (-2) + + +typedef struct MatchState { + const char *src_init; /* init of source string */ + const char *src_end; /* end ('\0') of source string */ + const char *p_end; /* end ('\0') of pattern */ + lua_State *L; + int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ + unsigned char level; /* total number of captures (finished or unfinished) */ + struct { + const char *init; + ptrdiff_t len; + } capture[LUA_MAXCAPTURES]; +} MatchState; + + +/* recursive function */ +static const char *match (MatchState *ms, const char *s, const char *p); + + +/* maximum recursion depth for 'match' */ +#if !defined(MAXCCALLS) +#define MAXCCALLS 200 +#endif + + +#define L_ESC '%' +#define SPECIALS "^$*+?.([%-" + + +static int check_capture (MatchState *ms, int l) { + l -= '1'; + if (l_unlikely(l < 0 || l >= ms->level || + ms->capture[l].len == CAP_UNFINISHED)) + return luaL_error(ms->L, "invalid capture index %%%d", l + 1); + return l; +} + + +static int capture_to_close (MatchState *ms) { + int level = ms->level; + for (level--; level>=0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) return level; + return luaL_error(ms->L, "invalid pattern capture"); +} + + +static const char *classend (MatchState *ms, const char *p) { + switch (*p++) { + case L_ESC: { + if (l_unlikely(p == ms->p_end)) + luaL_error(ms->L, "malformed pattern (ends with '%%')"); + return p+1; + } + case '[': { + if (*p == '^') p++; + do { /* look for a ']' */ + if (l_unlikely(p == ms->p_end)) + luaL_error(ms->L, "malformed pattern (missing ']')"); + if (*(p++) == L_ESC && p < ms->p_end) + p++; /* skip escapes (e.g. '%]') */ + } while (*p != ']'); + return p+1; + } + default: { + return p; + } + } +} + + +static int match_class (int c, int cl) { + int res; + switch (tolower(cl)) { + case 'a' : res = isalpha(c); break; + case 'c' : res = iscntrl(c); break; + case 'd' : res = isdigit(c); break; + case 'g' : res = isgraph(c); break; + case 'l' : res = islower(c); break; + case 'p' : res = ispunct(c); break; + case 's' : res = isspace(c); break; + case 'u' : res = isupper(c); break; + case 'w' : res = isalnum(c); break; + case 'x' : res = isxdigit(c); break; + case 'z' : res = (c == 0); break; /* deprecated option */ + default: return (cl == c); + } + return (islower(cl) ? res : !res); +} + + +static int matchbracketclass (int c, const char *p, const char *ec) { + int sig = 1; + if (*(p+1) == '^') { + sig = 0; + p++; /* skip the '^' */ + } + while (++p < ec) { + if (*p == L_ESC) { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p+1) == '-') && (p+2 < ec)) { + p+=2; + if (uchar(*(p-2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) return sig; + } + return !sig; +} + + +static int singlematch (MatchState *ms, const char *s, const char *p, + const char *ep) { + if (s >= ms->src_end) + return 0; + else { + int c = uchar(*s); + switch (*p) { + case '.': return 1; /* matches any char */ + case L_ESC: return match_class(c, uchar(*(p+1))); + case '[': return matchbracketclass(c, p, ep-1); + default: return (uchar(*p) == c); + } + } +} + + +static const char *matchbalance (MatchState *ms, const char *s, + const char *p) { + if (l_unlikely(p >= ms->p_end - 1)) + luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); + if (*s != *p) return NULL; + else { + int b = *p; + int e = *(p+1); + int cont = 1; + while (++s < ms->src_end) { + if (*s == e) { + if (--cont == 0) return s+1; + } + else if (*s == b) cont++; + } + } + return NULL; /* string ends out of balance */ +} + + +static const char *max_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + ptrdiff_t i = 0; /* counts maximum expand for item */ + while (singlematch(ms, s + i, p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i>=0) { + const char *res = match(ms, (s+i), ep+1); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; +} + + +static const char *min_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + for (;;) { + const char *res = match(ms, s, ep+1); + if (res != NULL) + return res; + else if (singlematch(ms, s, p, ep)) + s++; /* try with one more repetition */ + else return NULL; + } +} + + +static const char *start_capture (MatchState *ms, const char *s, + const char *p, int what) { + const char *res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level+1; + if ((res=match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; +} + + +static const char *end_capture (MatchState *ms, const char *s, + const char *p) { + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; +} + + +static const char *match_capture (MatchState *ms, const char *s, int l) { + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end-s) >= len && + memcmp(ms->capture[l].init, s, len) == 0) + return s+len; + else return NULL; +} + + +static const char *match (MatchState *ms, const char *s, const char *p) { + if (l_unlikely(ms->matchdepth-- == 0)) + luaL_error(ms->L, "pattern too complex"); + init: /* using goto to optimize tail recursion */ + if (p != ms->p_end) { /* end of pattern? */ + switch (*p) { + case '(': { /* start capture */ + if (*(p + 1) == ')') /* position capture? */ + s = start_capture(ms, s, p + 2, CAP_POSITION); + else + s = start_capture(ms, s, p + 1, CAP_UNFINISHED); + break; + } + case ')': { /* end capture */ + s = end_capture(ms, s, p + 1); + break; + } + case '$': { + if ((p + 1) != ms->p_end) /* is the '$' the last char in pattern? */ + goto dflt; /* no; go to default */ + s = (s == ms->src_end) ? s : NULL; /* check end of string */ + break; + } + case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ + switch (*(p + 1)) { + case 'b': { /* balanced string? */ + s = matchbalance(ms, s, p + 2); + if (s != NULL) { + p += 4; goto init; /* return match(ms, s, p + 4); */ + } /* else fail (s == NULL) */ + break; + } + case 'f': { /* frontier? */ + const char *ep; char previous; + p += 2; + if (l_unlikely(*p != '[')) + luaL_error(ms->L, "missing '[' after '%%f' in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s - 1); + if (!matchbracketclass(uchar(previous), p, ep - 1) && + matchbracketclass(uchar(*s), p, ep - 1)) { + p = ep; goto init; /* return match(ms, s, ep); */ + } + s = NULL; /* match failed */ + break; + } + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p + 1))); + if (s != NULL) { + p += 2; goto init; /* return match(ms, s, p + 2) */ + } + break; + } + default: goto dflt; + } + break; + } + default: dflt: { /* pattern class plus optional suffix */ + const char *ep = classend(ms, p); /* points to optional suffix */ + /* does not match at least once? */ + if (!singlematch(ms, s, p, ep)) { + if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */ + p = ep + 1; goto init; /* return match(ms, s, ep + 1); */ + } + else /* '+' or no suffix */ + s = NULL; /* fail */ + } + else { /* matched once */ + switch (*ep) { /* handle optional suffix */ + case '?': { /* optional */ + const char *res; + if ((res = match(ms, s + 1, ep + 1)) != NULL) + s = res; + else { + p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */ + } + break; + } + case '+': /* 1 or more repetitions */ + s++; /* 1 match already done */ + /* FALLTHROUGH */ + case '*': /* 0 or more repetitions */ + s = max_expand(ms, s, p, ep); + break; + case '-': /* 0 or more repetitions (minimum) */ + s = min_expand(ms, s, p, ep); + break; + default: /* no suffix */ + s++; p = ep; goto init; /* return match(ms, s + 1, ep); */ + } + } + break; + } + } + } + ms->matchdepth++; + return s; +} + + + +static const char *lmemfind (const char *s1, size_t l1, + const char *s2, size_t l2) { + if (l2 == 0) return s1; /* empty strings are everywhere */ + else if (l2 > l1) return NULL; /* avoids a negative 'l1' */ + else { + const char *init; /* to search for a '*s2' inside 's1' */ + l2--; /* 1st char will be checked by 'memchr' */ + l1 = l1-l2; /* 's2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { + init++; /* 1st char is already checked */ + if (memcmp(init, s2+1, l2) == 0) + return init-1; + else { /* correct 'l1' and 's1' to try again */ + l1 -= init-s1; + s1 = init; + } + } + return NULL; /* not found */ + } +} + + +/* +** get information about the i-th capture. If there are no captures +** and 'i==0', return information about the whole match, which +** is the range 's'..'e'. If the capture is a string, return +** its length and put its address in '*cap'. If it is an integer +** (a position), push it on the stack and return CAP_POSITION. +*/ +static size_t get_onecapture (MatchState *ms, int i, const char *s, + const char *e, const char **cap) { + if (i >= ms->level) { + if (l_unlikely(i != 0)) + luaL_error(ms->L, "invalid capture index %%%d", i + 1); + *cap = s; + return e - s; + } + else { + ptrdiff_t capl = ms->capture[i].len; + *cap = ms->capture[i].init; + if (l_unlikely(capl == CAP_UNFINISHED)) + luaL_error(ms->L, "unfinished capture"); + else if (capl == CAP_POSITION) + lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); + return capl; + } +} + + +/* +** Push the i-th capture on the stack. +*/ +static void push_onecapture (MatchState *ms, int i, const char *s, + const char *e) { + const char *cap; + ptrdiff_t l = get_onecapture(ms, i, s, e, &cap); + if (l != CAP_POSITION) + lua_pushlstring(ms->L, cap, l); + /* else position was already pushed */ +} + + +static int push_captures (MatchState *ms, const char *s, const char *e) { + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) + push_onecapture(ms, i, s, e); + return nlevels; /* number of strings pushed */ +} + + +/* check whether pattern has no special characters */ +static int nospecials (const char *p, size_t l) { + size_t upto = 0; + do { + if (strpbrk(p + upto, SPECIALS)) + return 0; /* pattern has a special character */ + upto += strlen(p + upto) + 1; /* may have more after \0 */ + } while (upto <= l); + return 1; /* no special chars found */ +} + + +static void prepstate (MatchState *ms, lua_State *L, + const char *s, size_t ls, const char *p, size_t lp) { + ms->L = L; + ms->matchdepth = MAXCCALLS; + ms->src_init = s; + ms->src_end = s + ls; + ms->p_end = p + lp; +} + + +static void reprepstate (MatchState *ms) { + ms->level = 0; + lua_assert(ms->matchdepth == MAXCCALLS); +} + + +static int str_find_aux (lua_State *L, int find) { + size_t ls, lp; + const char *s = luaL_checklstring(L, 1, &ls); + const char *p = luaL_checklstring(L, 2, &lp); + size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1; + if (init > ls) { /* start after string's end? */ + luaL_pushfail(L); /* cannot find anything */ + return 1; + } + /* explicit request or no special characters? */ + if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { + /* do a plain search */ + const char *s2 = lmemfind(s + init, ls - init, p, lp); + if (s2) { + lua_pushinteger(L, (s2 - s) + 1); + lua_pushinteger(L, (s2 - s) + lp); + return 2; + } + } + else { + MatchState ms; + const char *s1 = s + init; + int anchor = (*p == '^'); + if (anchor) { + p++; lp--; /* skip anchor character */ + } + prepstate(&ms, L, s, ls, p, lp); + do { + const char *res; + reprepstate(&ms); + if ((res=match(&ms, s1, p)) != NULL) { + if (find) { + lua_pushinteger(L, (s1 - s) + 1); /* start */ + lua_pushinteger(L, res - s); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + luaL_pushfail(L); /* not found */ + return 1; +} + + +static int str_find (lua_State *L) { + return str_find_aux(L, 1); +} + + +static int str_match (lua_State *L) { + return str_find_aux(L, 0); +} + + +/* state for 'gmatch' */ +typedef struct GMatchState { + const char *src; /* current position */ + const char *p; /* pattern */ + const char *lastmatch; /* end of last match */ + MatchState ms; /* match state */ +} GMatchState; + + +static int gmatch_aux (lua_State *L) { + GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3)); + const char *src; + gm->ms.L = L; + for (src = gm->src; src <= gm->ms.src_end; src++) { + const char *e; + reprepstate(&gm->ms); + if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) { + gm->src = gm->lastmatch = e; + return push_captures(&gm->ms, src, e); + } + } + return 0; /* not found */ +} + + +static int gmatch (lua_State *L) { + size_t ls, lp; + const char *s = luaL_checklstring(L, 1, &ls); + const char *p = luaL_checklstring(L, 2, &lp); + size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1; + GMatchState *gm; + lua_settop(L, 2); /* keep strings on closure to avoid being collected */ + gm = (GMatchState *)lua_newuserdatauv(L, sizeof(GMatchState), 0); + if (init > ls) /* start after string's end? */ + init = ls + 1; /* avoid overflows in 's + init' */ + prepstate(&gm->ms, L, s, ls, p, lp); + gm->src = s + init; gm->p = p; gm->lastmatch = NULL; + lua_pushcclosure(L, gmatch_aux, 3); + return 1; +} + + +static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + size_t l; + lua_State *L = ms->L; + const char *news = lua_tolstring(L, 3, &l); + const char *p; + while ((p = (char *)memchr(news, L_ESC, l)) != NULL) { + luaL_addlstring(b, news, p - news); + p++; /* skip ESC */ + if (*p == L_ESC) /* '%%' */ + luaL_addchar(b, *p); + else if (*p == '0') /* '%0' */ + luaL_addlstring(b, s, e - s); + else if (isdigit(uchar(*p))) { /* '%n' */ + const char *cap; + ptrdiff_t resl = get_onecapture(ms, *p - '1', s, e, &cap); + if (resl == CAP_POSITION) + luaL_addvalue(b); /* add position to accumulated result */ + else + luaL_addlstring(b, cap, resl); + } + else + luaL_error(L, "invalid use of '%c' in replacement string", L_ESC); + l -= p + 1 - news; + news = p + 1; + } + luaL_addlstring(b, news, l); +} + + +/* +** Add the replacement value to the string buffer 'b'. +** Return true if the original string was changed. (Function calls and +** table indexing resulting in nil or false do not change the subject.) +*/ +static int add_value (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e, int tr) { + lua_State *L = ms->L; + switch (tr) { + case LUA_TFUNCTION: { /* call the function */ + int n; + lua_pushvalue(L, 3); /* push the function */ + n = push_captures(ms, s, e); /* all captures as arguments */ + lua_call(L, n, 1); /* call it */ + break; + } + case LUA_TTABLE: { /* index the table */ + push_onecapture(ms, 0, s, e); /* first capture is the index */ + lua_gettable(L, 3); + break; + } + default: { /* LUA_TNUMBER or LUA_TSTRING */ + add_s(ms, b, s, e); /* add value to the buffer */ + return 1; /* something changed */ + } + } + if (!lua_toboolean(L, -1)) { /* nil or false? */ + lua_pop(L, 1); /* remove value */ + luaL_addlstring(b, s, e - s); /* keep original text */ + return 0; /* no changes */ + } + else if (l_unlikely(!lua_isstring(L, -1))) + return luaL_error(L, "invalid replacement value (a %s)", + luaL_typename(L, -1)); + else { + luaL_addvalue(b); /* add result to accumulator */ + return 1; /* something changed */ + } +} + + +static int str_gsub (lua_State *L) { + size_t srcl, lp; + const char *src = luaL_checklstring(L, 1, &srcl); /* subject */ + const char *p = luaL_checklstring(L, 2, &lp); /* pattern */ + const char *lastmatch = NULL; /* end of last match */ + int tr = lua_type(L, 3); /* replacement type */ + lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ + int anchor = (*p == '^'); + lua_Integer n = 0; /* replacement count */ + int changed = 0; /* change flag */ + MatchState ms; + luaL_Buffer b; + luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table"); + luaL_buffinit(L, &b); + if (anchor) { + p++; lp--; /* skip anchor character */ + } + prepstate(&ms, L, src, srcl, p, lp); + while (n < max_s) { + const char *e; + reprepstate(&ms); /* (re)prepare state for new match */ + if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */ + n++; + changed = add_value(&ms, &b, src, e, tr) | changed; + src = lastmatch = e; + } + else if (src < ms.src_end) /* otherwise, skip one character */ + luaL_addchar(&b, *src++); + else break; /* end of subject */ + if (anchor) break; + } + if (!changed) /* no changes? */ + lua_pushvalue(L, 1); /* return original string */ + else { /* something changed */ + luaL_addlstring(&b, src, ms.src_end-src); + luaL_pushresult(&b); /* create and return new string */ + } + lua_pushinteger(L, n); /* number of substitutions */ + return 2; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** STRING FORMAT +** ======================================================= +*/ + +#if !defined(lua_number2strx) /* { */ + +/* +** Hexadecimal floating-point formatter +*/ + +#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char)) + + +/* +** Number of bits that goes into the first digit. It can be any value +** between 1 and 4; the following definition tries to align the number +** to nibble boundaries by making what is left after that first digit a +** multiple of 4. +*/ +#define L_NBFD ((l_floatatt(MANT_DIG) - 1)%4 + 1) + + +/* +** Add integer part of 'x' to buffer and return new 'x' +*/ +static lua_Number adddigit (char *buff, int n, lua_Number x) { + lua_Number dd = l_mathop(floor)(x); /* get integer part from 'x' */ + int d = (int)dd; + buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */ + return x - dd; /* return what is left */ +} + + +static int num2straux (char *buff, int sz, lua_Number x) { + /* if 'inf' or 'NaN', format it like '%g' */ + if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL) + return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x); + else if (x == 0) { /* can be -0... */ + /* create "0" or "-0" followed by exponent */ + return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x); + } + else { + int e; + lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */ + int n = 0; /* character count */ + if (m < 0) { /* is number negative? */ + buff[n++] = '-'; /* add sign */ + m = -m; /* make it positive */ + } + buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */ + m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */ + e -= L_NBFD; /* this digit goes before the radix point */ + if (m > 0) { /* more digits? */ + buff[n++] = lua_getlocaledecpoint(); /* add radix point */ + do { /* add as many digits as needed */ + m = adddigit(buff, n++, m * 16); + } while (m > 0); + } + n += l_sprintf(buff + n, sz - n, "p%+d", e); /* add exponent */ + lua_assert(n < sz); + return n; + } +} + + +static int lua_number2strx (lua_State *L, char *buff, int sz, + const char *fmt, lua_Number x) { + int n = num2straux(buff, sz, x); + if (fmt[SIZELENMOD] == 'A') { + int i; + for (i = 0; i < n; i++) + buff[i] = toupper(uchar(buff[i])); + } + else if (l_unlikely(fmt[SIZELENMOD] != 'a')) + return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); + return n; +} + +#endif /* } */ + + +/* +** Maximum size for items formatted with '%f'. This size is produced +** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.', +** and '\0') + number of decimal digits to represent maxfloat (which +** is maximum exponent + 1). (99+3+1, adding some extra, 110) +*/ +#define MAX_ITEMF (110 + l_floatatt(MAX_10_EXP)) + + +/* +** All formats except '%f' do not need that large limit. The other +** float formats use exponents, so that they fit in the 99 limit for +** significant digits; 's' for large strings and 'q' add items directly +** to the buffer; all integer formats also fit in the 99 limit. The +** worst case are floats: they may need 99 significant digits, plus +** '0x', '-', '.', 'e+XXXX', and '\0'. Adding some extra, 120. +*/ +#define MAX_ITEM 120 + + +/* valid flags in a format specification */ +#if !defined(L_FMTFLAGSF) + +/* valid flags for a, A, e, E, f, F, g, and G conversions */ +#define L_FMTFLAGSF "-+#0 " + +/* valid flags for o, x, and X conversions */ +#define L_FMTFLAGSX "-#0" + +/* valid flags for d and i conversions */ +#define L_FMTFLAGSI "-+0 " + +/* valid flags for u conversions */ +#define L_FMTFLAGSU "-0" + +/* valid flags for c, p, and s conversions */ +#define L_FMTFLAGSC "-" + +#endif + + +/* +** Maximum size of each format specification (such as "%-099.99d"): +** Initial '%', flags (up to 5), width (2), period, precision (2), +** length modifier (8), conversion specifier, and final '\0', plus some +** extra. +*/ +#define MAX_FORMAT 32 + + +static void addquoted (luaL_Buffer *b, const char *s, size_t len) { + luaL_addchar(b, '"'); + while (len--) { + if (*s == '"' || *s == '\\' || *s == '\n') { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + } + else if (iscntrl(uchar(*s))) { + char buff[10]; + if (!isdigit(uchar(*(s+1)))) + l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s)); + else + l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s)); + luaL_addstring(b, buff); + } + else + luaL_addchar(b, *s); + s++; + } + luaL_addchar(b, '"'); +} + + +/* +** Serialize a floating-point number in such a way that it can be +** scanned back by Lua. Use hexadecimal format for "common" numbers +** (to preserve precision); inf, -inf, and NaN are handled separately. +** (NaN cannot be expressed as a numeral, so we write '(0/0)' for it.) +*/ +static int quotefloat (lua_State *L, char *buff, lua_Number n) { + const char *s; /* for the fixed representations */ + if (n == (lua_Number)HUGE_VAL) /* inf? */ + s = "1e9999"; + else if (n == -(lua_Number)HUGE_VAL) /* -inf? */ + s = "-1e9999"; + else if (n != n) /* NaN? */ + s = "(0/0)"; + else { /* format number as hexadecimal */ + int nb = lua_number2strx(L, buff, MAX_ITEM, + "%" LUA_NUMBER_FRMLEN "a", n); + /* ensures that 'buff' string uses a dot as the radix character */ + if (memchr(buff, '.', nb) == NULL) { /* no dot? */ + char point = lua_getlocaledecpoint(); /* try locale point */ + char *ppoint = (char *)memchr(buff, point, nb); + if (ppoint) *ppoint = '.'; /* change it to a dot */ + } + return nb; + } + /* for the fixed representations */ + return l_sprintf(buff, MAX_ITEM, "%s", s); +} + + +static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { + switch (lua_type(L, arg)) { + case LUA_TSTRING: { + size_t len; + const char *s = lua_tolstring(L, arg, &len); + addquoted(b, s, len); + break; + } + case LUA_TNUMBER: { + char *buff = luaL_prepbuffsize(b, MAX_ITEM); + int nb; + if (!lua_isinteger(L, arg)) /* float? */ + nb = quotefloat(L, buff, lua_tonumber(L, arg)); + else { /* integers */ + lua_Integer n = lua_tointeger(L, arg); + const char *format = (n == LUA_MININTEGER) /* corner case? */ + ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hex */ + : LUA_INTEGER_FMT; /* else use default format */ + nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n); + } + luaL_addsize(b, nb); + break; + } + case LUA_TNIL: case LUA_TBOOLEAN: { + luaL_tolstring(L, arg, NULL); + luaL_addvalue(b); + break; + } + default: { + luaL_argerror(L, arg, "value has no literal form"); + } + } +} + + +static const char *get2digits (const char *s) { + if (isdigit(uchar(*s))) { + s++; + if (isdigit(uchar(*s))) s++; /* (2 digits at most) */ + } + return s; +} + + +/* +** Check whether a conversion specification is valid. When called, +** first character in 'form' must be '%' and last character must +** be a valid conversion specifier. 'flags' are the accepted flags; +** 'precision' signals whether to accept a precision. +*/ +static void checkformat (lua_State *L, const char *form, const char *flags, + int precision) { + const char *spec = form + 1; /* skip '%' */ + spec += strspn(spec, flags); /* skip flags */ + if (*spec != '0') { /* a width cannot start with '0' */ + spec = get2digits(spec); /* skip width */ + if (*spec == '.' && precision) { + spec++; + spec = get2digits(spec); /* skip precision */ + } + } + if (!isalpha(uchar(*spec))) /* did not go to the end? */ + luaL_error(L, "invalid conversion specification: '%s'", form); +} + + +/* +** Get a conversion specification and copy it to 'form'. +** Return the address of its last character. +*/ +static const char *getformat (lua_State *L, const char *strfrmt, + char *form) { + /* spans flags, width, and precision ('0' is included as a flag) */ + size_t len = strspn(strfrmt, L_FMTFLAGSF "123456789."); + len++; /* adds following character (should be the specifier) */ + /* still needs space for '%', '\0', plus a length modifier */ + if (len >= MAX_FORMAT - 10) + luaL_error(L, "invalid format (too long)"); + *(form++) = '%'; + memcpy(form, strfrmt, len * sizeof(char)); + *(form + len) = '\0'; + return strfrmt + len - 1; +} + + +/* +** add length modifier into formats +*/ +static void addlenmod (char *form, const char *lenmod) { + size_t l = strlen(form); + size_t lm = strlen(lenmod); + char spec = form[l - 1]; + strcpy(form + l - 1, lenmod); + form[l + lm - 1] = spec; + form[l + lm] = '\0'; +} + + +static int str_format (lua_State *L) { + int top = lua_gettop(L); + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt+sfl; + const char *flags; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); /* %% */ + else { /* format item */ + char form[MAX_FORMAT]; /* to store the format ('%...') */ + int maxitem = MAX_ITEM; /* maximum length for the result */ + char *buff = luaL_prepbuffsize(&b, maxitem); /* to put result */ + int nb = 0; /* number of bytes in result */ + if (++arg > top) + return luaL_argerror(L, arg, "no value"); + strfrmt = getformat(L, strfrmt, form); + switch (*strfrmt++) { + case 'c': { + checkformat(L, form, L_FMTFLAGSC, 0); + nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg)); + break; + } + case 'd': case 'i': + flags = L_FMTFLAGSI; + goto intcase; + case 'u': + flags = L_FMTFLAGSU; + goto intcase; + case 'o': case 'x': case 'X': + flags = L_FMTFLAGSX; + intcase: { + lua_Integer n = luaL_checkinteger(L, arg); + checkformat(L, form, flags, 1); + addlenmod(form, LUA_INTEGER_FRMLEN); + nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n); + break; + } + case 'a': case 'A': + checkformat(L, form, L_FMTFLAGSF, 1); + addlenmod(form, LUA_NUMBER_FRMLEN); + nb = lua_number2strx(L, buff, maxitem, form, + luaL_checknumber(L, arg)); + break; + case 'f': + maxitem = MAX_ITEMF; /* extra space for '%f' */ + buff = luaL_prepbuffsize(&b, maxitem); + /* FALLTHROUGH */ + case 'e': case 'E': case 'g': case 'G': { + lua_Number n = luaL_checknumber(L, arg); + checkformat(L, form, L_FMTFLAGSF, 1); + addlenmod(form, LUA_NUMBER_FRMLEN); + nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n); + break; + } + case 'p': { + const void *p = lua_topointer(L, arg); + checkformat(L, form, L_FMTFLAGSC, 0); + if (p == NULL) { /* avoid calling 'printf' with argument NULL */ + p = "(null)"; /* result */ + form[strlen(form) - 1] = 's'; /* format it as a string */ + } + nb = l_sprintf(buff, maxitem, form, p); + break; + } + case 'q': { + if (form[2] != '\0') /* modifiers? */ + return luaL_error(L, "specifier '%%q' cannot have modifiers"); + addliteral(L, &b, arg); + break; + } + case 's': { + size_t l; + const char *s = luaL_tolstring(L, arg, &l); + if (form[2] == '\0') /* no modifiers? */ + luaL_addvalue(&b); /* keep entire string */ + else { + luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); + checkformat(L, form, L_FMTFLAGSC, 1); + if (strchr(form, '.') == NULL && l >= 100) { + /* no precision and string is too long to be formatted */ + luaL_addvalue(&b); /* keep entire string */ + } + else { /* format the string into 'buff' */ + nb = l_sprintf(buff, maxitem, form, s); + lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ + } + } + break; + } + default: { /* also treat cases 'pnLlh' */ + return luaL_error(L, "invalid conversion '%s' to 'format'", form); + } + } + lua_assert(nb < maxitem); + luaL_addsize(&b, nb); + } + } + luaL_pushresult(&b); + return 1; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** PACK/UNPACK +** ======================================================= +*/ + + +/* value used for padding */ +#if !defined(LUAL_PACKPADBYTE) +#define LUAL_PACKPADBYTE 0x00 +#endif + +/* maximum size for the binary representation of an integer */ +#define MAXINTSIZE 16 + +/* number of bits in a character */ +#define NB CHAR_BIT + +/* mask for one character (NB 1's) */ +#define MC ((1 << NB) - 1) + +/* size of a lua_Integer */ +#define SZINT ((int)sizeof(lua_Integer)) + + +/* dummy union to get native endianness */ +static const union { + int dummy; + char little; /* true iff machine is little endian */ +} nativeendian = {1}; + + +/* +** information to pack/unpack stuff +*/ +typedef struct Header { + lua_State *L; + int islittle; + int maxalign; +} Header; + + +/* +** options for pack/unpack +*/ +typedef enum KOption { + Kint, /* signed integers */ + Kuint, /* unsigned integers */ + Kfloat, /* single-precision floating-point numbers */ + Knumber, /* Lua "native" floating-point numbers */ + Kdouble, /* double-precision floating-point numbers */ + Kchar, /* fixed-length strings */ + Kstring, /* strings with prefixed length */ + Kzstr, /* zero-terminated strings */ + Kpadding, /* padding */ + Kpaddalign, /* padding for alignment */ + Knop /* no-op (configuration or spaces) */ +} KOption; + + +/* +** Read an integer numeral from string 'fmt' or return 'df' if +** there is no numeral +*/ +static int digit (int c) { return '0' <= c && c <= '9'; } + +static int getnum (const char **fmt, int df) { + if (!digit(**fmt)) /* no number? */ + return df; /* return default value */ + else { + int a = 0; + do { + a = a*10 + (*((*fmt)++) - '0'); + } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10); + return a; + } +} + + +/* +** Read an integer numeral and raises an error if it is larger +** than the maximum size for integers. +*/ +static int getnumlimit (Header *h, const char **fmt, int df) { + int sz = getnum(fmt, df); + if (l_unlikely(sz > MAXINTSIZE || sz <= 0)) + return luaL_error(h->L, "integral size (%d) out of limits [1,%d]", + sz, MAXINTSIZE); + return sz; +} + + +/* +** Initialize Header +*/ +static void initheader (lua_State *L, Header *h) { + h->L = L; + h->islittle = nativeendian.little; + h->maxalign = 1; +} + + +/* +** Read and classify next option. 'size' is filled with option's size. +*/ +static KOption getoption (Header *h, const char **fmt, int *size) { + /* dummy structure to get native alignment requirements */ + struct cD { char c; union { LUAI_MAXALIGN; } u; }; + int opt = *((*fmt)++); + *size = 0; /* default */ + switch (opt) { + case 'b': *size = sizeof(char); return Kint; + case 'B': *size = sizeof(char); return Kuint; + case 'h': *size = sizeof(short); return Kint; + case 'H': *size = sizeof(short); return Kuint; + case 'l': *size = sizeof(long); return Kint; + case 'L': *size = sizeof(long); return Kuint; + case 'j': *size = sizeof(lua_Integer); return Kint; + case 'J': *size = sizeof(lua_Integer); return Kuint; + case 'T': *size = sizeof(size_t); return Kuint; + case 'f': *size = sizeof(float); return Kfloat; + case 'n': *size = sizeof(lua_Number); return Knumber; + case 'd': *size = sizeof(double); return Kdouble; + case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint; + case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint; + case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; + case 'c': + *size = getnum(fmt, -1); + if (l_unlikely(*size == -1)) + luaL_error(h->L, "missing size for format option 'c'"); + return Kchar; + case 'z': return Kzstr; + case 'x': *size = 1; return Kpadding; + case 'X': return Kpaddalign; + case ' ': break; + case '<': h->islittle = 1; break; + case '>': h->islittle = 0; break; + case '=': h->islittle = nativeendian.little; break; + case '!': { + const int maxalign = offsetof(struct cD, u); + h->maxalign = getnumlimit(h, fmt, maxalign); + break; + } + default: luaL_error(h->L, "invalid format option '%c'", opt); + } + return Knop; +} + + +/* +** Read, classify, and fill other details about the next option. +** 'psize' is filled with option's size, 'notoalign' with its +** alignment requirements. +** Local variable 'size' gets the size to be aligned. (Kpadal option +** always gets its full alignment, other options are limited by +** the maximum alignment ('maxalign'). Kchar option needs no alignment +** despite its size. +*/ +static KOption getdetails (Header *h, size_t totalsize, + const char **fmt, int *psize, int *ntoalign) { + KOption opt = getoption(h, fmt, psize); + int align = *psize; /* usually, alignment follows size */ + if (opt == Kpaddalign) { /* 'X' gets alignment from following option */ + if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0) + luaL_argerror(h->L, 1, "invalid next option for option 'X'"); + } + if (align <= 1 || opt == Kchar) /* need no alignment? */ + *ntoalign = 0; + else { + if (align > h->maxalign) /* enforce maximum alignment */ + align = h->maxalign; + if (l_unlikely((align & (align - 1)) != 0)) /* not a power of 2? */ + luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); + *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); + } + return opt; +} + + +/* +** Pack integer 'n' with 'size' bytes and 'islittle' endianness. +** The final 'if' handles the case when 'size' is larger than +** the size of a Lua integer, correcting the extra sign-extension +** bytes if necessary (by default they would be zeros). +*/ +static void packint (luaL_Buffer *b, lua_Unsigned n, + int islittle, int size, int neg) { + char *buff = luaL_prepbuffsize(b, size); + int i; + buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */ + for (i = 1; i < size; i++) { + n >>= NB; + buff[islittle ? i : size - 1 - i] = (char)(n & MC); + } + if (neg && size > SZINT) { /* negative number need sign extension? */ + for (i = SZINT; i < size; i++) /* correct extra bytes */ + buff[islittle ? i : size - 1 - i] = (char)MC; + } + luaL_addsize(b, size); /* add result to buffer */ +} + + +/* +** Copy 'size' bytes from 'src' to 'dest', correcting endianness if +** given 'islittle' is different from native endianness. +*/ +static void copywithendian (char *dest, const char *src, + int size, int islittle) { + if (islittle == nativeendian.little) + memcpy(dest, src, size); + else { + dest += size - 1; + while (size-- != 0) + *(dest--) = *(src++); + } +} + + +static int str_pack (lua_State *L) { + luaL_Buffer b; + Header h; + const char *fmt = luaL_checkstring(L, 1); /* format string */ + int arg = 1; /* current argument to pack */ + size_t totalsize = 0; /* accumulate total size of result */ + initheader(L, &h); + lua_pushnil(L); /* mark to separate arguments from string buffer */ + luaL_buffinit(L, &b); + while (*fmt != '\0') { + int size, ntoalign; + KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); + totalsize += ntoalign + size; + while (ntoalign-- > 0) + luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */ + arg++; + switch (opt) { + case Kint: { /* signed integers */ + lua_Integer n = luaL_checkinteger(L, arg); + if (size < SZINT) { /* need overflow check? */ + lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); + luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); + } + packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); + break; + } + case Kuint: { /* unsigned integers */ + lua_Integer n = luaL_checkinteger(L, arg); + if (size < SZINT) /* need overflow check? */ + luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), + arg, "unsigned overflow"); + packint(&b, (lua_Unsigned)n, h.islittle, size, 0); + break; + } + case Kfloat: { /* C float */ + float f = (float)luaL_checknumber(L, arg); /* get argument */ + char *buff = luaL_prepbuffsize(&b, sizeof(f)); + /* move 'f' to final result, correcting endianness if needed */ + copywithendian(buff, (char *)&f, sizeof(f), h.islittle); + luaL_addsize(&b, size); + break; + } + case Knumber: { /* Lua float */ + lua_Number f = luaL_checknumber(L, arg); /* get argument */ + char *buff = luaL_prepbuffsize(&b, sizeof(f)); + /* move 'f' to final result, correcting endianness if needed */ + copywithendian(buff, (char *)&f, sizeof(f), h.islittle); + luaL_addsize(&b, size); + break; + } + case Kdouble: { /* C double */ + double f = (double)luaL_checknumber(L, arg); /* get argument */ + char *buff = luaL_prepbuffsize(&b, sizeof(f)); + /* move 'f' to final result, correcting endianness if needed */ + copywithendian(buff, (char *)&f, sizeof(f), h.islittle); + luaL_addsize(&b, size); + break; + } + case Kchar: { /* fixed-size string */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, len <= (size_t)size, arg, + "string longer than given size"); + luaL_addlstring(&b, s, len); /* add string */ + while (len++ < (size_t)size) /* pad extra space */ + luaL_addchar(&b, LUAL_PACKPADBYTE); + break; + } + case Kstring: { /* strings with length count */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, size >= (int)sizeof(size_t) || + len < ((size_t)1 << (size * NB)), + arg, "string length does not fit in given size"); + packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ + luaL_addlstring(&b, s, len); + totalsize += len; + break; + } + case Kzstr: { /* zero-terminated string */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); + luaL_addlstring(&b, s, len); + luaL_addchar(&b, '\0'); /* add zero at the end */ + totalsize += len + 1; + break; + } + case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */ + case Kpaddalign: case Knop: + arg--; /* undo increment */ + break; + } + } + luaL_pushresult(&b); + return 1; +} + + +static int str_packsize (lua_State *L) { + Header h; + const char *fmt = luaL_checkstring(L, 1); /* format string */ + size_t totalsize = 0; /* accumulate total size of result */ + initheader(L, &h); + while (*fmt != '\0') { + int size, ntoalign; + KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); + luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1, + "variable-length format"); + size += ntoalign; /* total space used by option */ + luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, + "format result too large"); + totalsize += size; + } + lua_pushinteger(L, (lua_Integer)totalsize); + return 1; +} + + +/* +** Unpack an integer with 'size' bytes and 'islittle' endianness. +** If size is smaller than the size of a Lua integer and integer +** is signed, must do sign extension (propagating the sign to the +** higher bits); if size is larger than the size of a Lua integer, +** it must check the unread bytes to see whether they do not cause an +** overflow. +*/ +static lua_Integer unpackint (lua_State *L, const char *str, + int islittle, int size, int issigned) { + lua_Unsigned res = 0; + int i; + int limit = (size <= SZINT) ? size : SZINT; + for (i = limit - 1; i >= 0; i--) { + res <<= NB; + res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i]; + } + if (size < SZINT) { /* real size smaller than lua_Integer? */ + if (issigned) { /* needs sign extension? */ + lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1); + res = ((res ^ mask) - mask); /* do sign extension */ + } + } + else if (size > SZINT) { /* must check unread bytes */ + int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; + for (i = limit; i < size; i++) { + if (l_unlikely((unsigned char)str[islittle ? i : size - 1 - i] != mask)) + luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); + } + } + return (lua_Integer)res; +} + + +static int str_unpack (lua_State *L) { + Header h; + const char *fmt = luaL_checkstring(L, 1); + size_t ld; + const char *data = luaL_checklstring(L, 2, &ld); + size_t pos = posrelatI(luaL_optinteger(L, 3, 1), ld) - 1; + int n = 0; /* number of results */ + luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); + initheader(L, &h); + while (*fmt != '\0') { + int size, ntoalign; + KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); + luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2, + "data string too short"); + pos += ntoalign; /* skip alignment */ + /* stack space for item + next position */ + luaL_checkstack(L, 2, "too many results"); + n++; + switch (opt) { + case Kint: + case Kuint: { + lua_Integer res = unpackint(L, data + pos, h.islittle, size, + (opt == Kint)); + lua_pushinteger(L, res); + break; + } + case Kfloat: { + float f; + copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); + lua_pushnumber(L, (lua_Number)f); + break; + } + case Knumber: { + lua_Number f; + copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); + lua_pushnumber(L, f); + break; + } + case Kdouble: { + double f; + copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); + lua_pushnumber(L, (lua_Number)f); + break; + } + case Kchar: { + lua_pushlstring(L, data + pos, size); + break; + } + case Kstring: { + size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); + luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short"); + lua_pushlstring(L, data + pos + size, len); + pos += len; /* skip string */ + break; + } + case Kzstr: { + size_t len = strlen(data + pos); + luaL_argcheck(L, pos + len < ld, 2, + "unfinished string for format 'z'"); + lua_pushlstring(L, data + pos, len); + pos += len + 1; /* skip string plus final '\0' */ + break; + } + case Kpaddalign: case Kpadding: case Knop: + n--; /* undo increment */ + break; + } + pos += size; + } + lua_pushinteger(L, pos + 1); /* next position */ + return n + 1; +} + +/* }====================================================== */ + + +static const luaL_Reg strlib[] = { + {"byte", str_byte}, + {"char", str_char}, + {"dump", str_dump}, + {"find", str_find}, + {"format", str_format}, + {"gmatch", gmatch}, + {"gsub", str_gsub}, + {"len", str_len}, + {"lower", str_lower}, + {"match", str_match}, + {"rep", str_rep}, + {"reverse", str_reverse}, + {"sub", str_sub}, + {"upper", str_upper}, + {"pack", str_pack}, + {"packsize", str_packsize}, + {"unpack", str_unpack}, + {NULL, NULL} +}; + + +static void createmetatable (lua_State *L) { + /* table to be metatable for strings */ + luaL_newlibtable(L, stringmetamethods); + luaL_setfuncs(L, stringmetamethods, 0); + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); /* copy table */ + lua_setmetatable(L, -2); /* set table as metatable for strings */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* get string library */ + lua_setfield(L, -2, "__index"); /* metatable.__index = string */ + lua_pop(L, 1); /* pop metatable */ +} + + +/* +** Open string library +*/ +LUAMOD_API int luaopen_string (lua_State *L) { + luaL_newlib(L, strlib); + createmetatable(L); + return 1; +} + diff --git a/User/system/lua/src/ltable.c b/User/system/lua/src/ltable.c new file mode 100644 index 0000000..3353c04 --- /dev/null +++ b/User/system/lua/src/ltable.c @@ -0,0 +1,995 @@ +/* +** $Id: ltable.c $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#define ltable_c +#define LUA_CORE + +#include "lprefix.h" + + +/* +** Implementation of tables (aka arrays, objects, or hash tables). +** Tables keep its elements in two parts: an array part and a hash part. +** Non-negative integer keys are all candidates to be kept in the array +** part. The actual size of the array is the largest 'n' such that +** more than half the slots between 1 and n are in use. +** Hash uses a mix of chained scatter table with Brent's variation. +** A main invariant of these tables is that, if an element is not +** in its main position (i.e. the 'original' position that its hash gives +** to it), then the colliding element is in its own main position. +** Hence even when the load factor reaches 100%, performance remains good. +*/ + +#include +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lvm.h" + + +/* +** MAXABITS is the largest integer such that MAXASIZE fits in an +** unsigned int. +*/ +#define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1) + + +/* +** MAXASIZE is the maximum size of the array part. It is the minimum +** between 2^MAXABITS and the maximum size that, measured in bytes, +** fits in a 'size_t'. +*/ +#define MAXASIZE luaM_limitN(1u << MAXABITS, TValue) + +/* +** MAXHBITS is the largest integer such that 2^MAXHBITS fits in a +** signed int. +*/ +#define MAXHBITS (MAXABITS - 1) + + +/* +** MAXHSIZE is the maximum size of the hash part. It is the minimum +** between 2^MAXHBITS and the maximum size such that, measured in bytes, +** it fits in a 'size_t'. +*/ +#define MAXHSIZE luaM_limitN(1u << MAXHBITS, Node) + + +/* +** When the original hash value is good, hashing by a power of 2 +** avoids the cost of '%'. +*/ +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) + +/* +** for other types, it is better to avoid modulo by power of 2, as +** they can have many 2 factors. +*/ +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) + + +#define hashstr(t,str) hashpow2(t, (str)->hash) +#define hashboolean(t,p) hashpow2(t, p) + + +#define hashpointer(t,p) hashmod(t, point2uint(p)) + + +#define dummynode (&dummynode_) + +static const Node dummynode_ = { + {{NULL}, LUA_VEMPTY, /* value's value and type */ + LUA_VNIL, 0, {NULL}} /* key type, next, and key value */ +}; + + +static const TValue absentkey = {ABSTKEYCONSTANT}; + + +/* +** Hash for integers. To allow a good hash, use the remainder operator +** ('%'). If integer fits as a non-negative int, compute an int +** remainder, which is faster. Otherwise, use an unsigned-integer +** remainder, which uses all bits and ensures a non-negative result. +*/ +static Node *hashint (const Table *t, lua_Integer i) { + lua_Unsigned ui = l_castS2U(i); + if (ui <= cast_uint(INT_MAX)) + return hashmod(t, cast_int(ui)); + else + return hashmod(t, ui); +} + + +/* +** Hash for floating-point numbers. +** The main computation should be just +** n = frexp(n, &i); return (n * INT_MAX) + i +** but there are some numerical subtleties. +** In a two-complement representation, INT_MAX does not has an exact +** representation as a float, but INT_MIN does; because the absolute +** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the +** absolute value of the product 'frexp * -INT_MIN' is smaller or equal +** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when +** adding 'i'; the use of '~u' (instead of '-u') avoids problems with +** INT_MIN. +*/ +#if !defined(l_hashfloat) +static int l_hashfloat (lua_Number n) { + int i; + lua_Integer ni; + n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN); + if (!lua_numbertointeger(n, &ni)) { /* is 'n' inf/-inf/NaN? */ + lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == cast_num(HUGE_VAL)); + return 0; + } + else { /* normal case */ + unsigned int u = cast_uint(i) + cast_uint(ni); + return cast_int(u <= cast_uint(INT_MAX) ? u : ~u); + } +} +#endif + + +/* +** returns the 'main' position of an element in a table (that is, +** the index of its hash value). +*/ +static Node *mainpositionTV (const Table *t, const TValue *key) { + switch (ttypetag(key)) { + case LUA_VNUMINT: { + lua_Integer i = ivalue(key); + return hashint(t, i); + } + case LUA_VNUMFLT: { + lua_Number n = fltvalue(key); + return hashmod(t, l_hashfloat(n)); + } + case LUA_VSHRSTR: { + TString *ts = tsvalue(key); + return hashstr(t, ts); + } + case LUA_VLNGSTR: { + TString *ts = tsvalue(key); + return hashpow2(t, luaS_hashlongstr(ts)); + } + case LUA_VFALSE: + return hashboolean(t, 0); + case LUA_VTRUE: + return hashboolean(t, 1); + case LUA_VLIGHTUSERDATA: { + void *p = pvalue(key); + return hashpointer(t, p); + } + case LUA_VLCF: { + lua_CFunction f = fvalue(key); + return hashpointer(t, f); + } + default: { + GCObject *o = gcvalue(key); + return hashpointer(t, o); + } + } +} + + +l_sinline Node *mainpositionfromnode (const Table *t, Node *nd) { + TValue key; + getnodekey(cast(lua_State *, NULL), &key, nd); + return mainpositionTV(t, &key); +} + + +/* +** Check whether key 'k1' is equal to the key in node 'n2'. This +** equality is raw, so there are no metamethods. Floats with integer +** values have been normalized, so integers cannot be equal to +** floats. It is assumed that 'eqshrstr' is simply pointer equality, so +** that short strings are handled in the default case. +** A true 'deadok' means to accept dead keys as equal to their original +** values. All dead keys are compared in the default case, by pointer +** identity. (Only collectable objects can produce dead keys.) Note that +** dead long strings are also compared by identity. +** Once a key is dead, its corresponding value may be collected, and +** then another value can be created with the same address. If this +** other value is given to 'next', 'equalkey' will signal a false +** positive. In a regular traversal, this situation should never happen, +** as all keys given to 'next' came from the table itself, and therefore +** could not have been collected. Outside a regular traversal, we +** have garbage in, garbage out. What is relevant is that this false +** positive does not break anything. (In particular, 'next' will return +** some other valid item on the table or nil.) +*/ +static int equalkey (const TValue *k1, const Node *n2, int deadok) { + if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ + !(deadok && keyisdead(n2) && iscollectable(k1))) + return 0; /* cannot be same key */ + switch (keytt(n2)) { + case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: + return 1; + case LUA_VNUMINT: + return (ivalue(k1) == keyival(n2)); + case LUA_VNUMFLT: + return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2))); + case LUA_VLIGHTUSERDATA: + return pvalue(k1) == pvalueraw(keyval(n2)); + case LUA_VLCF: + return fvalue(k1) == fvalueraw(keyval(n2)); + case ctb(LUA_VLNGSTR): + return luaS_eqlngstr(tsvalue(k1), keystrval(n2)); + default: + return gcvalue(k1) == gcvalueraw(keyval(n2)); + } +} + + +/* +** True if value of 'alimit' is equal to the real size of the array +** part of table 't'. (Otherwise, the array part must be larger than +** 'alimit'.) +*/ +#define limitequalsasize(t) (isrealasize(t) || ispow2((t)->alimit)) + + +/* +** Returns the real size of the 'array' array +*/ +LUAI_FUNC unsigned int luaH_realasize (const Table *t) { + if (limitequalsasize(t)) + return t->alimit; /* this is the size */ + else { + unsigned int size = t->alimit; + /* compute the smallest power of 2 not smaller than 'size' */ + size |= (size >> 1); + size |= (size >> 2); + size |= (size >> 4); + size |= (size >> 8); +#if (UINT_MAX >> 14) > 3 /* unsigned int has more than 16 bits */ + size |= (size >> 16); +#if (UINT_MAX >> 30) > 3 + size |= (size >> 32); /* unsigned int has more than 32 bits */ +#endif +#endif + size++; + lua_assert(ispow2(size) && size/2 < t->alimit && t->alimit < size); + return size; + } +} + + +/* +** Check whether real size of the array is a power of 2. +** (If it is not, 'alimit' cannot be changed to any other value +** without changing the real size.) +*/ +static int ispow2realasize (const Table *t) { + return (!isrealasize(t) || ispow2(t->alimit)); +} + + +static unsigned int setlimittosize (Table *t) { + t->alimit = luaH_realasize(t); + setrealasize(t); + return t->alimit; +} + + +#define limitasasize(t) check_exp(isrealasize(t), t->alimit) + + + +/* +** "Generic" get version. (Not that generic: not valid for integers, +** which may be in array part, nor for floats with integral values.) +** See explanation about 'deadok' in function 'equalkey'. +*/ +static const TValue *getgeneric (Table *t, const TValue *key, int deadok) { + Node *n = mainpositionTV(t, key); + for (;;) { /* check whether 'key' is somewhere in the chain */ + if (equalkey(key, n, deadok)) + return gval(n); /* that's it */ + else { + int nx = gnext(n); + if (nx == 0) + return &absentkey; /* not found */ + n += nx; + } + } +} + + +/* +** returns the index for 'k' if 'k' is an appropriate key to live in +** the array part of a table, 0 otherwise. +*/ +static unsigned int arrayindex (lua_Integer k) { + if (l_castS2U(k) - 1u < MAXASIZE) /* 'k' in [1, MAXASIZE]? */ + return cast_uint(k); /* 'key' is an appropriate array index */ + else + return 0; +} + + +/* +** returns the index of a 'key' for table traversals. First goes all +** elements in the array part, then elements in the hash part. The +** beginning of a traversal is signaled by 0. +*/ +static unsigned int findindex (lua_State *L, Table *t, TValue *key, + unsigned int asize) { + unsigned int i; + if (ttisnil(key)) return 0; /* first iteration */ + i = ttisinteger(key) ? arrayindex(ivalue(key)) : 0; + if (i - 1u < asize) /* is 'key' inside array part? */ + return i; /* yes; that's the index */ + else { + const TValue *n = getgeneric(t, key, 1); + if (l_unlikely(isabstkey(n))) + luaG_runerror(L, "invalid key to 'next'"); /* key not found */ + i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return (i + 1) + asize; + } +} + + +int luaH_next (lua_State *L, Table *t, StkId key) { + unsigned int asize = luaH_realasize(t); + unsigned int i = findindex(L, t, s2v(key), asize); /* find original key */ + for (; i < asize; i++) { /* try first array part */ + if (!isempty(&t->array[i])) { /* a non-empty entry? */ + setivalue(s2v(key), i + 1); + setobj2s(L, key + 1, &t->array[i]); + return 1; + } + } + for (i -= asize; cast_int(i) < sizenode(t); i++) { /* hash part */ + if (!isempty(gval(gnode(t, i)))) { /* a non-empty entry? */ + Node *n = gnode(t, i); + getnodekey(L, s2v(key), n); + setobj2s(L, key + 1, gval(n)); + return 1; + } + } + return 0; /* no more elements */ +} + + +static void freehash (lua_State *L, Table *t) { + if (!isdummy(t)) + luaM_freearray(L, t->node, cast_sizet(sizenode(t))); +} + + +/* +** {============================================================= +** Rehash +** ============================================================== +*/ + +/* +** Compute the optimal size for the array part of table 't'. 'nums' is a +** "count array" where 'nums[i]' is the number of integers in the table +** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of +** integer keys in the table and leaves with the number of keys that +** will go to the array part; return the optimal size. (The condition +** 'twotoi > 0' in the for loop stops the loop if 'twotoi' overflows.) +*/ +static unsigned int computesizes (unsigned int nums[], unsigned int *pna) { + int i; + unsigned int twotoi; /* 2^i (candidate for optimal size) */ + unsigned int a = 0; /* number of elements smaller than 2^i */ + unsigned int na = 0; /* number of elements to go to array part */ + unsigned int optimal = 0; /* optimal size for array part */ + /* loop while keys can fill more than half of total size */ + for (i = 0, twotoi = 1; + twotoi > 0 && *pna > twotoi / 2; + i++, twotoi *= 2) { + a += nums[i]; + if (a > twotoi/2) { /* more than half elements present? */ + optimal = twotoi; /* optimal size (till now) */ + na = a; /* all elements up to 'optimal' will go to array part */ + } + } + lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal); + *pna = na; + return optimal; +} + + +static int countint (lua_Integer key, unsigned int *nums) { + unsigned int k = arrayindex(key); + if (k != 0) { /* is 'key' an appropriate array index? */ + nums[luaO_ceillog2(k)]++; /* count as such */ + return 1; + } + else + return 0; +} + + +/* +** Count keys in array part of table 't': Fill 'nums[i]' with +** number of keys that will go into corresponding slice and return +** total number of non-nil keys. +*/ +static unsigned int numusearray (const Table *t, unsigned int *nums) { + int lg; + unsigned int ttlg; /* 2^lg */ + unsigned int ause = 0; /* summation of 'nums' */ + unsigned int i = 1; /* count to traverse all array keys */ + unsigned int asize = limitasasize(t); /* real array size */ + /* traverse each slice */ + for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) { + unsigned int lc = 0; /* counter */ + unsigned int lim = ttlg; + if (lim > asize) { + lim = asize; /* adjust upper limit */ + if (i > lim) + break; /* no more elements to count */ + } + /* count elements in range (2^(lg - 1), 2^lg] */ + for (; i <= lim; i++) { + if (!isempty(&t->array[i-1])) + lc++; + } + nums[lg] += lc; + ause += lc; + } + return ause; +} + + +static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) { + int totaluse = 0; /* total number of elements */ + int ause = 0; /* elements added to 'nums' (can go to array part) */ + int i = sizenode(t); + while (i--) { + Node *n = &t->node[i]; + if (!isempty(gval(n))) { + if (keyisinteger(n)) + ause += countint(keyival(n), nums); + totaluse++; + } + } + *pna += ause; + return totaluse; +} + + +/* +** Creates an array for the hash part of a table with the given +** size, or reuses the dummy node if size is zero. +** The computation for size overflow is in two steps: the first +** comparison ensures that the shift in the second one does not +** overflow. +*/ +static void setnodevector (lua_State *L, Table *t, unsigned int size) { + if (size == 0) { /* no elements to hash part? */ + t->node = cast(Node *, dummynode); /* use common 'dummynode' */ + t->lsizenode = 0; + t->lastfree = NULL; /* signal that it is using dummy node */ + } + else { + int i; + int lsize = luaO_ceillog2(size); + if (lsize > MAXHBITS || (1u << lsize) > MAXHSIZE) + luaG_runerror(L, "table overflow"); + size = twoto(lsize); + t->node = luaM_newvector(L, size, Node); + for (i = 0; i < cast_int(size); i++) { + Node *n = gnode(t, i); + gnext(n) = 0; + setnilkey(n); + setempty(gval(n)); + } + t->lsizenode = cast_byte(lsize); + t->lastfree = gnode(t, size); /* all positions are free */ + } +} + + +/* +** (Re)insert all elements from the hash part of 'ot' into table 't'. +*/ +static void reinsert (lua_State *L, Table *ot, Table *t) { + int j; + int size = sizenode(ot); + for (j = 0; j < size; j++) { + Node *old = gnode(ot, j); + if (!isempty(gval(old))) { + /* doesn't need barrier/invalidate cache, as entry was + already present in the table */ + TValue k; + getnodekey(L, &k, old); + luaH_set(L, t, &k, gval(old)); + } + } +} + + +/* +** Exchange the hash part of 't1' and 't2'. +*/ +static void exchangehashpart (Table *t1, Table *t2) { + lu_byte lsizenode = t1->lsizenode; + Node *node = t1->node; + Node *lastfree = t1->lastfree; + t1->lsizenode = t2->lsizenode; + t1->node = t2->node; + t1->lastfree = t2->lastfree; + t2->lsizenode = lsizenode; + t2->node = node; + t2->lastfree = lastfree; +} + + +/* +** Resize table 't' for the new given sizes. Both allocations (for +** the hash part and for the array part) can fail, which creates some +** subtleties. If the first allocation, for the hash part, fails, an +** error is raised and that is it. Otherwise, it copies the elements from +** the shrinking part of the array (if it is shrinking) into the new +** hash. Then it reallocates the array part. If that fails, the table +** is in its original state; the function frees the new hash part and then +** raises the allocation error. Otherwise, it sets the new hash part +** into the table, initializes the new part of the array (if any) with +** nils and reinserts the elements of the old hash back into the new +** parts of the table. +*/ +void luaH_resize (lua_State *L, Table *t, unsigned int newasize, + unsigned int nhsize) { + unsigned int i; + Table newt; /* to keep the new hash part */ + unsigned int oldasize = setlimittosize(t); + TValue *newarray; + /* create new hash part with appropriate size into 'newt' */ + setnodevector(L, &newt, nhsize); + if (newasize < oldasize) { /* will array shrink? */ + t->alimit = newasize; /* pretend array has new size... */ + exchangehashpart(t, &newt); /* and new hash */ + /* re-insert into the new hash the elements from vanishing slice */ + for (i = newasize; i < oldasize; i++) { + if (!isempty(&t->array[i])) + luaH_setint(L, t, i + 1, &t->array[i]); + } + t->alimit = oldasize; /* restore current size... */ + exchangehashpart(t, &newt); /* and hash (in case of errors) */ + } + /* allocate new array */ + newarray = luaM_reallocvector(L, t->array, oldasize, newasize, TValue); + if (l_unlikely(newarray == NULL && newasize > 0)) { /* allocation failed? */ + freehash(L, &newt); /* release new hash part */ + luaM_error(L); /* raise error (with array unchanged) */ + } + /* allocation ok; initialize new part of the array */ + exchangehashpart(t, &newt); /* 't' has the new hash ('newt' has the old) */ + t->array = newarray; /* set new array part */ + t->alimit = newasize; + for (i = oldasize; i < newasize; i++) /* clear new slice of the array */ + setempty(&t->array[i]); + /* re-insert elements from old hash part into new parts */ + reinsert(L, &newt, t); /* 'newt' now has the old hash */ + freehash(L, &newt); /* free old hash part */ +} + + +void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { + int nsize = allocsizenode(t); + luaH_resize(L, t, nasize, nsize); +} + +/* +** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i +*/ +static void rehash (lua_State *L, Table *t, const TValue *ek) { + unsigned int asize; /* optimal size for array part */ + unsigned int na; /* number of keys in the array part */ + unsigned int nums[MAXABITS + 1]; + int i; + int totaluse; + for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */ + setlimittosize(t); + na = numusearray(t, nums); /* count keys in array part */ + totaluse = na; /* all those keys are integer keys */ + totaluse += numusehash(t, nums, &na); /* count keys in hash part */ + /* count extra key */ + if (ttisinteger(ek)) + na += countint(ivalue(ek), nums); + totaluse++; + /* compute new size for array part */ + asize = computesizes(nums, &na); + /* resize the table to new computed sizes */ + luaH_resize(L, t, asize, totaluse - na); +} + + + +/* +** }============================================================= +*/ + + +Table *luaH_new (lua_State *L) { + GCObject *o = luaC_newobj(L, LUA_VTABLE, sizeof(Table)); + Table *t = gco2t(o); + t->metatable = NULL; + t->flags = cast_byte(maskflags); /* table has no metamethod fields */ + t->array = NULL; + t->alimit = 0; + setnodevector(L, t, 0); + return t; +} + + +void luaH_free (lua_State *L, Table *t) { + freehash(L, t); + luaM_freearray(L, t->array, luaH_realasize(t)); + luaM_free(L, t); +} + + +static Node *getfreepos (Table *t) { + if (!isdummy(t)) { + while (t->lastfree > t->node) { + t->lastfree--; + if (keyisnil(t->lastfree)) + return t->lastfree; + } + } + return NULL; /* could not find a free place */ +} + + + +/* +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. +*/ +static void luaH_newkey (lua_State *L, Table *t, const TValue *key, + TValue *value) { + Node *mp; + TValue aux; + if (l_unlikely(ttisnil(key))) + luaG_runerror(L, "table index is nil"); + else if (ttisfloat(key)) { + lua_Number f = fltvalue(key); + lua_Integer k; + if (luaV_flttointeger(f, &k, F2Ieq)) { /* does key fit in an integer? */ + setivalue(&aux, k); + key = &aux; /* insert it as an integer */ + } + else if (l_unlikely(luai_numisnan(f))) + luaG_runerror(L, "table index is NaN"); + } + if (ttisnil(value)) + return; /* do not insert nil values */ + mp = mainpositionTV(t, key); + if (!isempty(gval(mp)) || isdummy(t)) { /* main position is taken? */ + Node *othern; + Node *f = getfreepos(t); /* get a free place */ + if (f == NULL) { /* cannot find a free place? */ + rehash(L, t, key); /* grow table */ + /* whatever called 'newkey' takes care of TM cache */ + luaH_set(L, t, key, value); /* insert key into grown table */ + return; + } + lua_assert(!isdummy(t)); + othern = mainpositionfromnode(t, mp); + if (othern != mp) { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (othern + gnext(othern) != mp) /* find previous */ + othern += gnext(othern); + gnext(othern) = cast_int(f - othern); /* rechain to point to 'f' */ + *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + if (gnext(mp) != 0) { + gnext(f) += cast_int(mp - f); /* correct 'next' */ + gnext(mp) = 0; /* now 'mp' is free */ + } + setempty(gval(mp)); + } + else { /* colliding node is in its own main position */ + /* new node will go into free position */ + if (gnext(mp) != 0) + gnext(f) = cast_int((mp + gnext(mp)) - f); /* chain new position */ + else lua_assert(gnext(f) == 0); + gnext(mp) = cast_int(f - mp); + mp = f; + } + } + setnodekey(L, mp, key); + luaC_barrierback(L, obj2gco(t), key); + lua_assert(isempty(gval(mp))); + setobj2t(L, gval(mp), value); +} + + +/* +** Search function for integers. If integer is inside 'alimit', get it +** directly from the array part. Otherwise, if 'alimit' is not +** the real size of the array, the key still can be in the array part. +** In this case, do the "Xmilia trick" to check whether 'key-1' is +** smaller than the real size. +** The trick works as follow: let 'p' be an integer such that +** '2^(p+1) >= alimit > 2^p', or '2^(p+1) > alimit-1 >= 2^p'. +** That is, 2^(p+1) is the real size of the array, and 'p' is the highest +** bit on in 'alimit-1'. What we have to check becomes 'key-1 < 2^(p+1)'. +** We compute '(key-1) & ~(alimit-1)', which we call 'res'; it will +** have the 'p' bit cleared. If the key is outside the array, that is, +** 'key-1 >= 2^(p+1)', then 'res' will have some bit on higher than 'p', +** therefore it will be larger or equal to 'alimit', and the check +** will fail. If 'key-1 < 2^(p+1)', then 'res' has no bit on higher than +** 'p', and as the bit 'p' itself was cleared, 'res' will be smaller +** than 2^p, therefore smaller than 'alimit', and the check succeeds. +** As special cases, when 'alimit' is 0 the condition is trivially false, +** and when 'alimit' is 1 the condition simplifies to 'key-1 < alimit'. +** If key is 0 or negative, 'res' will have its higher bit on, so that +** if cannot be smaller than alimit. +*/ +const TValue *luaH_getint (Table *t, lua_Integer key) { + lua_Unsigned alimit = t->alimit; + if (l_castS2U(key) - 1u < alimit) /* 'key' in [1, t->alimit]? */ + return &t->array[key - 1]; + else if (!isrealasize(t) && /* key still may be in the array part? */ + (((l_castS2U(key) - 1u) & ~(alimit - 1u)) < alimit)) { + t->alimit = cast_uint(key); /* probably '#t' is here now */ + return &t->array[key - 1]; + } + else { /* key is not in the array part; check the hash */ + Node *n = hashint(t, key); + for (;;) { /* check whether 'key' is somewhere in the chain */ + if (keyisinteger(n) && keyival(n) == key) + return gval(n); /* that's it */ + else { + int nx = gnext(n); + if (nx == 0) break; + n += nx; + } + } + return &absentkey; + } +} + + +/* +** search function for short strings +*/ +const TValue *luaH_getshortstr (Table *t, TString *key) { + Node *n = hashstr(t, key); + lua_assert(key->tt == LUA_VSHRSTR); + for (;;) { /* check whether 'key' is somewhere in the chain */ + if (keyisshrstr(n) && eqshrstr(keystrval(n), key)) + return gval(n); /* that's it */ + else { + int nx = gnext(n); + if (nx == 0) + return &absentkey; /* not found */ + n += nx; + } + } +} + + +const TValue *luaH_getstr (Table *t, TString *key) { + if (key->tt == LUA_VSHRSTR) + return luaH_getshortstr(t, key); + else { /* for long strings, use generic case */ + TValue ko; + setsvalue(cast(lua_State *, NULL), &ko, key); + return getgeneric(t, &ko, 0); + } +} + + +/* +** main search function +*/ +const TValue *luaH_get (Table *t, const TValue *key) { + switch (ttypetag(key)) { + case LUA_VSHRSTR: return luaH_getshortstr(t, tsvalue(key)); + case LUA_VNUMINT: return luaH_getint(t, ivalue(key)); + case LUA_VNIL: return &absentkey; + case LUA_VNUMFLT: { + lua_Integer k; + if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */ + return luaH_getint(t, k); /* use specialized version */ + /* else... */ + } /* FALLTHROUGH */ + default: + return getgeneric(t, key, 0); + } +} + + +/* +** Finish a raw "set table" operation, where 'slot' is where the value +** should have been (the result of a previous "get table"). +** Beware: when using this function you probably need to check a GC +** barrier and invalidate the TM cache. +*/ +void luaH_finishset (lua_State *L, Table *t, const TValue *key, + const TValue *slot, TValue *value) { + if (isabstkey(slot)) + luaH_newkey(L, t, key, value); + else + setobj2t(L, cast(TValue *, slot), value); +} + + +/* +** beware: when using this function you probably need to check a GC +** barrier and invalidate the TM cache. +*/ +void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) { + const TValue *slot = luaH_get(t, key); + luaH_finishset(L, t, key, slot, value); +} + + +void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { + const TValue *p = luaH_getint(t, key); + if (isabstkey(p)) { + TValue k; + setivalue(&k, key); + luaH_newkey(L, t, &k, value); + } + else + setobj2t(L, cast(TValue *, p), value); +} + + +/* +** Try to find a boundary in the hash part of table 't'. From the +** caller, we know that 'j' is zero or present and that 'j + 1' is +** present. We want to find a larger key that is absent from the +** table, so that we can do a binary search between the two keys to +** find a boundary. We keep doubling 'j' until we get an absent index. +** If the doubling would overflow, we try LUA_MAXINTEGER. If it is +** absent, we are ready for the binary search. ('j', being max integer, +** is larger or equal to 'i', but it cannot be equal because it is +** absent while 'i' is present; so 'j > i'.) Otherwise, 'j' is a +** boundary. ('j + 1' cannot be a present integer key because it is +** not a valid integer in Lua.) +*/ +static lua_Unsigned hash_search (Table *t, lua_Unsigned j) { + lua_Unsigned i; + if (j == 0) j++; /* the caller ensures 'j + 1' is present */ + do { + i = j; /* 'i' is a present index */ + if (j <= l_castS2U(LUA_MAXINTEGER) / 2) + j *= 2; + else { + j = LUA_MAXINTEGER; + if (isempty(luaH_getint(t, j))) /* t[j] not present? */ + break; /* 'j' now is an absent index */ + else /* weird case */ + return j; /* well, max integer is a boundary... */ + } + } while (!isempty(luaH_getint(t, j))); /* repeat until an absent t[j] */ + /* i < j && t[i] present && t[j] absent */ + while (j - i > 1u) { /* do a binary search between them */ + lua_Unsigned m = (i + j) / 2; + if (isempty(luaH_getint(t, m))) j = m; + else i = m; + } + return i; +} + + +static unsigned int binsearch (const TValue *array, unsigned int i, + unsigned int j) { + while (j - i > 1u) { /* binary search */ + unsigned int m = (i + j) / 2; + if (isempty(&array[m - 1])) j = m; + else i = m; + } + return i; +} + + +/* +** Try to find a boundary in table 't'. (A 'boundary' is an integer index +** such that t[i] is present and t[i+1] is absent, or 0 if t[1] is absent +** and 'maxinteger' if t[maxinteger] is present.) +** (In the next explanation, we use Lua indices, that is, with base 1. +** The code itself uses base 0 when indexing the array part of the table.) +** The code starts with 'limit = t->alimit', a position in the array +** part that may be a boundary. +** +** (1) If 't[limit]' is empty, there must be a boundary before it. +** As a common case (e.g., after 't[#t]=nil'), check whether 'limit-1' +** is present. If so, it is a boundary. Otherwise, do a binary search +** between 0 and limit to find a boundary. In both cases, try to +** use this boundary as the new 'alimit', as a hint for the next call. +** +** (2) If 't[limit]' is not empty and the array has more elements +** after 'limit', try to find a boundary there. Again, try first +** the special case (which should be quite frequent) where 'limit+1' +** is empty, so that 'limit' is a boundary. Otherwise, check the +** last element of the array part. If it is empty, there must be a +** boundary between the old limit (present) and the last element +** (absent), which is found with a binary search. (This boundary always +** can be a new limit.) +** +** (3) The last case is when there are no elements in the array part +** (limit == 0) or its last element (the new limit) is present. +** In this case, must check the hash part. If there is no hash part +** or 'limit+1' is absent, 'limit' is a boundary. Otherwise, call +** 'hash_search' to find a boundary in the hash part of the table. +** (In those cases, the boundary is not inside the array part, and +** therefore cannot be used as a new limit.) +*/ +lua_Unsigned luaH_getn (Table *t) { + unsigned int limit = t->alimit; + if (limit > 0 && isempty(&t->array[limit - 1])) { /* (1)? */ + /* there must be a boundary before 'limit' */ + if (limit >= 2 && !isempty(&t->array[limit - 2])) { + /* 'limit - 1' is a boundary; can it be a new limit? */ + if (ispow2realasize(t) && !ispow2(limit - 1)) { + t->alimit = limit - 1; + setnorealasize(t); /* now 'alimit' is not the real size */ + } + return limit - 1; + } + else { /* must search for a boundary in [0, limit] */ + unsigned int boundary = binsearch(t->array, 0, limit); + /* can this boundary represent the real size of the array? */ + if (ispow2realasize(t) && boundary > luaH_realasize(t) / 2) { + t->alimit = boundary; /* use it as the new limit */ + setnorealasize(t); + } + return boundary; + } + } + /* 'limit' is zero or present in table */ + if (!limitequalsasize(t)) { /* (2)? */ + /* 'limit' > 0 and array has more elements after 'limit' */ + if (isempty(&t->array[limit])) /* 'limit + 1' is empty? */ + return limit; /* this is the boundary */ + /* else, try last element in the array */ + limit = luaH_realasize(t); + if (isempty(&t->array[limit - 1])) { /* empty? */ + /* there must be a boundary in the array after old limit, + and it must be a valid new limit */ + unsigned int boundary = binsearch(t->array, t->alimit, limit); + t->alimit = boundary; + return boundary; + } + /* else, new limit is present in the table; check the hash part */ + } + /* (3) 'limit' is the last element and either is zero or present in table */ + lua_assert(limit == luaH_realasize(t) && + (limit == 0 || !isempty(&t->array[limit - 1]))); + if (isdummy(t) || isempty(luaH_getint(t, cast(lua_Integer, limit + 1)))) + return limit; /* 'limit + 1' is absent */ + else /* 'limit + 1' is also present */ + return hash_search(t, limit); +} + + + +#if defined(LUA_DEBUG) + +/* export these functions for the test library */ + +Node *luaH_mainposition (const Table *t, const TValue *key) { + return mainpositionTV(t, key); +} + +#endif diff --git a/User/system/lua/src/ltable.h b/User/system/lua/src/ltable.h new file mode 100644 index 0000000..8e68903 --- /dev/null +++ b/User/system/lua/src/ltable.h @@ -0,0 +1,63 @@ +/* +** $Id: ltable.h $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define gnode(t,i) (&(t)->node[i]) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->u.next) + + +/* +** Clear all bits of fast-access metamethods, which means that the table +** may have any of these metamethods. (First access that fails after the +** clearing will set the bit again.) +*/ +#define invalidateTMcache(t) ((t)->flags &= ~maskflags) + + +/* true when 't' is using 'dummynode' as its hash part */ +#define isdummy(t) ((t)->lastfree == NULL) + + +/* allocated size for hash nodes */ +#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) + + +/* returns the Node, given the value of a table entry */ +#define nodefromval(v) cast(Node *, (v)) + + +LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); +LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, + TValue *value); +LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, + TValue *value); +LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, + const TValue *slot, TValue *value); +LUAI_FUNC Table *luaH_new (lua_State *L); +LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, + unsigned int nhsize); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); +LUAI_FUNC void luaH_free (lua_State *L, Table *t); +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC lua_Unsigned luaH_getn (Table *t); +LUAI_FUNC unsigned int luaH_realasize (const Table *t); + + +#if defined(LUA_DEBUG) +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); +#endif + + +#endif diff --git a/User/system/lua/src/ltablib.c b/User/system/lua/src/ltablib.c new file mode 100644 index 0000000..e6bc4d0 --- /dev/null +++ b/User/system/lua/src/ltablib.c @@ -0,0 +1,430 @@ +/* +** $Id: ltablib.c $ +** Library for Table Manipulation +** See Copyright Notice in lua.h +*/ + +#define ltablib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** Operations that an object must define to mimic a table +** (some functions only need some of them) +*/ +#define TAB_R 1 /* read */ +#define TAB_W 2 /* write */ +#define TAB_L 4 /* length */ +#define TAB_RW (TAB_R | TAB_W) /* read/write */ + + +#define aux_getn(L,n,w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n)) + + +static int checkfield (lua_State *L, const char *key, int n) { + lua_pushstring(L, key); + return (lua_rawget(L, -n) != LUA_TNIL); +} + + +/* +** Check that 'arg' either is a table or can behave like one (that is, +** has a metatable with the required metamethods) +*/ +static void checktab (lua_State *L, int arg, int what) { + if (lua_type(L, arg) != LUA_TTABLE) { /* is it not a table? */ + int n = 1; /* number of elements to pop */ + if (lua_getmetatable(L, arg) && /* must have metatable */ + (!(what & TAB_R) || checkfield(L, "__index", ++n)) && + (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) && + (!(what & TAB_L) || checkfield(L, "__len", ++n))) { + lua_pop(L, n); /* pop metatable and tested metamethods */ + } + else + luaL_checktype(L, arg, LUA_TTABLE); /* force an error */ + } +} + + +static int tinsert (lua_State *L) { + lua_Integer pos; /* where to insert new element */ + lua_Integer e = aux_getn(L, 1, TAB_RW); + e = luaL_intop(+, e, 1); /* first empty element */ + switch (lua_gettop(L)) { + case 2: { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: { + lua_Integer i; + pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ + /* check whether 'pos' is in [1, e] */ + luaL_argcheck(L, (lua_Unsigned)pos - 1u < (lua_Unsigned)e, 2, + "position out of bounds"); + for (i = e; i > pos; i--) { /* move up elements */ + lua_geti(L, 1, i - 1); + lua_seti(L, 1, i); /* t[i] = t[i - 1] */ + } + break; + } + default: { + return luaL_error(L, "wrong number of arguments to 'insert'"); + } + } + lua_seti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int tremove (lua_State *L) { + lua_Integer size = aux_getn(L, 1, TAB_RW); + lua_Integer pos = luaL_optinteger(L, 2, size); + if (pos != size) /* validate 'pos' if given */ + /* check whether 'pos' is in [1, size + 1] */ + luaL_argcheck(L, (lua_Unsigned)pos - 1u <= (lua_Unsigned)size, 2, + "position out of bounds"); + lua_geti(L, 1, pos); /* result = t[pos] */ + for ( ; pos < size; pos++) { + lua_geti(L, 1, pos + 1); + lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ + } + lua_pushnil(L); + lua_seti(L, 1, pos); /* remove entry t[pos] */ + return 1; +} + + +/* +** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever +** possible, copy in increasing order, which is better for rehashing. +** "possible" means destination after original range, or smaller +** than origin, or copying to another table. +*/ +static int tmove (lua_State *L) { + lua_Integer f = luaL_checkinteger(L, 2); + lua_Integer e = luaL_checkinteger(L, 3); + lua_Integer t = luaL_checkinteger(L, 4); + int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ + checktab(L, 1, TAB_R); + checktab(L, tt, TAB_W); + if (e >= f) { /* otherwise, nothing to move */ + lua_Integer n, i; + luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3, + "too many elements to move"); + n = e - f + 1; /* number of elements to move */ + luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4, + "destination wrap around"); + if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) { + for (i = 0; i < n; i++) { + lua_geti(L, 1, f + i); + lua_seti(L, tt, t + i); + } + } + else { + for (i = n - 1; i >= 0; i--) { + lua_geti(L, 1, f + i); + lua_seti(L, tt, t + i); + } + } + } + lua_pushvalue(L, tt); /* return destination table */ + return 1; +} + + +static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) { + lua_geti(L, 1, i); + if (l_unlikely(!lua_isstring(L, -1))) + luaL_error(L, "invalid value (%s) at index %I in table for 'concat'", + luaL_typename(L, -1), (LUAI_UACINT)i); + luaL_addvalue(b); +} + + +static int tconcat (lua_State *L) { + luaL_Buffer b; + lua_Integer last = aux_getn(L, 1, TAB_R); + size_t lsep; + const char *sep = luaL_optlstring(L, 2, "", &lsep); + lua_Integer i = luaL_optinteger(L, 3, 1); + last = luaL_optinteger(L, 4, last); + luaL_buffinit(L, &b); + for (; i < last; i++) { + addfield(L, &b, i); + luaL_addlstring(&b, sep, lsep); + } + if (i == last) /* add last value (if interval was not empty) */ + addfield(L, &b, i); + luaL_pushresult(&b); + return 1; +} + + +/* +** {====================================================== +** Pack/unpack +** ======================================================= +*/ + +static int tpack (lua_State *L) { + int i; + int n = lua_gettop(L); /* number of elements to pack */ + lua_createtable(L, n, 1); /* create result table */ + lua_insert(L, 1); /* put it at index 1 */ + for (i = n; i >= 1; i--) /* assign elements */ + lua_seti(L, 1, i); + lua_pushinteger(L, n); + lua_setfield(L, 1, "n"); /* t.n = number of elements */ + return 1; /* return table */ +} + + +static int tunpack (lua_State *L) { + lua_Unsigned n; + lua_Integer i = luaL_optinteger(L, 2, 1); + lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); + if (i > e) return 0; /* empty range */ + n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */ + if (l_unlikely(n >= (unsigned int)INT_MAX || + !lua_checkstack(L, (int)(++n)))) + return luaL_error(L, "too many results to unpack"); + for (; i < e; i++) { /* push arg[i..e - 1] (to avoid overflows) */ + lua_geti(L, 1, i); + } + lua_geti(L, 1, e); /* push last element */ + return (int)n; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Quicksort +** (based on 'Algorithms in MODULA-3', Robert Sedgewick; +** Addison-Wesley, 1993.) +** ======================================================= +*/ + + +/* type for array indices */ +typedef unsigned int IdxT; + + +/* +** Produce a "random" 'unsigned int' to randomize pivot choice. This +** macro is used only when 'sort' detects a big imbalance in the result +** of a partition. (If you don't want/need this "randomness", ~0 is a +** good choice.) +*/ +#if !defined(l_randomizePivot) /* { */ + +#include + +/* size of 'e' measured in number of 'unsigned int's */ +#define sof(e) (sizeof(e) / sizeof(unsigned int)) + +/* +** Use 'time' and 'clock' as sources of "randomness". Because we don't +** know the types 'clock_t' and 'time_t', we cannot cast them to +** anything without risking overflows. A safe way to use their values +** is to copy them to an array of a known type and use the array values. +*/ +static unsigned int l_randomizePivot (void) { + clock_t c = clock(); + time_t t = time(NULL); + unsigned int buff[sof(c) + sof(t)]; + unsigned int i, rnd = 0; + memcpy(buff, &c, sof(c) * sizeof(unsigned int)); + memcpy(buff + sof(c), &t, sof(t) * sizeof(unsigned int)); + for (i = 0; i < sof(buff); i++) + rnd += buff[i]; + return rnd; +} + +#endif /* } */ + + +/* arrays larger than 'RANLIMIT' may use randomized pivots */ +#define RANLIMIT 100u + + +static void set2 (lua_State *L, IdxT i, IdxT j) { + lua_seti(L, 1, i); + lua_seti(L, 1, j); +} + + +/* +** Return true iff value at stack index 'a' is less than the value at +** index 'b' (according to the order of the sort). +*/ +static int sort_comp (lua_State *L, int a, int b) { + if (lua_isnil(L, 2)) /* no function? */ + return lua_compare(L, a, b, LUA_OPLT); /* a < b */ + else { /* function */ + int res; + lua_pushvalue(L, 2); /* push function */ + lua_pushvalue(L, a-1); /* -1 to compensate function */ + lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ + lua_call(L, 2, 1); /* call function */ + res = lua_toboolean(L, -1); /* get result */ + lua_pop(L, 1); /* pop result */ + return res; + } +} + + +/* +** Does the partition: Pivot P is at the top of the stack. +** precondition: a[lo] <= P == a[up-1] <= a[up], +** so it only needs to do the partition from lo + 1 to up - 2. +** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up] +** returns 'i'. +*/ +static IdxT partition (lua_State *L, IdxT lo, IdxT up) { + IdxT i = lo; /* will be incremented before first use */ + IdxT j = up - 1; /* will be decremented before first use */ + /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ + for (;;) { + /* next loop: repeat ++i while a[i] < P */ + while ((void)lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (l_unlikely(i == up - 1)) /* a[i] < P but a[up - 1] == P ?? */ + luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ + /* next loop: repeat --j while P < a[j] */ + while ((void)lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { + if (l_unlikely(j < i)) /* j < i but a[j] > P ?? */ + luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[j] */ + } + /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */ + if (j < i) { /* no elements out of place? */ + /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */ + lua_pop(L, 1); /* pop a[j] */ + /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */ + set2(L, up - 1, i); + return i; + } + /* otherwise, swap a[i] - a[j] to restore invariant and repeat */ + set2(L, i, j); + } +} + + +/* +** Choose an element in the middle (2nd-3th quarters) of [lo,up] +** "randomized" by 'rnd' +*/ +static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) { + IdxT r4 = (up - lo) / 4; /* range/4 */ + IdxT p = rnd % (r4 * 2) + (lo + r4); + lua_assert(lo + r4 <= p && p <= up - r4); + return p; +} + + +/* +** Quicksort algorithm (recursive function) +*/ +static void auxsort (lua_State *L, IdxT lo, IdxT up, + unsigned int rnd) { + while (lo < up) { /* loop for tail recursion */ + IdxT p; /* Pivot index */ + IdxT n; /* to be used later */ + /* sort elements 'lo', 'p', and 'up' */ + lua_geti(L, 1, lo); + lua_geti(L, 1, up); + if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */ + set2(L, lo, up); /* swap a[lo] - a[up] */ + else + lua_pop(L, 2); /* remove both values */ + if (up - lo == 1) /* only 2 elements? */ + return; /* already sorted */ + if (up - lo < RANLIMIT || rnd == 0) /* small interval or no randomize? */ + p = (lo + up)/2; /* middle element is a good pivot */ + else /* for larger intervals, it is worth a random pivot */ + p = choosePivot(lo, up, rnd); + lua_geti(L, 1, p); + lua_geti(L, 1, lo); + if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */ + set2(L, p, lo); /* swap a[p] - a[lo] */ + else { + lua_pop(L, 1); /* remove a[lo] */ + lua_geti(L, 1, up); + if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */ + set2(L, p, up); /* swap a[up] - a[p] */ + else + lua_pop(L, 2); + } + if (up - lo == 2) /* only 3 elements? */ + return; /* already sorted */ + lua_geti(L, 1, p); /* get middle element (Pivot) */ + lua_pushvalue(L, -1); /* push Pivot */ + lua_geti(L, 1, up - 1); /* push a[up - 1] */ + set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */ + p = partition(L, lo, up); + /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */ + if (p - lo < up - p) { /* lower interval is smaller? */ + auxsort(L, lo, p - 1, rnd); /* call recursively for lower interval */ + n = p - lo; /* size of smaller interval */ + lo = p + 1; /* tail call for [p + 1 .. up] (upper interval) */ + } + else { + auxsort(L, p + 1, up, rnd); /* call recursively for upper interval */ + n = up - p; /* size of smaller interval */ + up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */ + } + if ((up - lo) / 128 > n) /* partition too imbalanced? */ + rnd = l_randomizePivot(); /* try a new randomization */ + } /* tail call auxsort(L, lo, up, rnd) */ +} + + +static int sort (lua_State *L) { + lua_Integer n = aux_getn(L, 1, TAB_RW); + if (n > 1) { /* non-trivial interval? */ + luaL_argcheck(L, n < INT_MAX, 1, "array too big"); + if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ + luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */ + lua_settop(L, 2); /* make sure there are two arguments */ + auxsort(L, 1, (IdxT)n, 0); + } + return 0; +} + +/* }====================================================== */ + + +static const luaL_Reg tab_funcs[] = { + {"concat", tconcat}, + {"insert", tinsert}, + {"pack", tpack}, + {"unpack", tunpack}, + {"remove", tremove}, + {"move", tmove}, + {"sort", sort}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_table (lua_State *L) { + luaL_newlib(L, tab_funcs); + return 1; +} + diff --git a/User/system/lua/src/ltm.c b/User/system/lua/src/ltm.c new file mode 100644 index 0000000..07a0608 --- /dev/null +++ b/User/system/lua/src/ltm.c @@ -0,0 +1,271 @@ +/* +** $Id: ltm.c $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#define ltm_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + +static const char udatatypename[] = "userdata"; + +LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTYPES] = { + "no value", + "nil", "boolean", udatatypename, "number", + "string", "table", "function", udatatypename, "thread", + "upvalue", "proto" /* these last cases are used for tests only */ +}; + + +void luaT_init (lua_State *L) { + static const char *const luaT_eventname[] = { /* ORDER TM */ + "__index", "__newindex", + "__gc", "__mode", "__len", "__eq", + "__add", "__sub", "__mul", "__mod", "__pow", + "__div", "__idiv", + "__band", "__bor", "__bxor", "__shl", "__shr", + "__unm", "__bnot", "__lt", "__le", + "__concat", "__call", "__close" + }; + int i; + for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); + luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ + } +} + + +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods +*/ +const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { + const TValue *tm = luaH_getshortstr(events, ename); + lua_assert(event <= TM_EQ); + if (notm(tm)) { /* no tag method? */ + events->flags |= cast_byte(1u<metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = G(L)->mt[ttype(o)]; + } + return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : &G(L)->nilvalue); +} + + +/* +** Return the name of the type of an object. For tables and userdata +** with metatable, use their '__name' metafield, if present. +*/ +const char *luaT_objtypename (lua_State *L, const TValue *o) { + Table *mt; + if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || + (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { + const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); + if (ttisstring(name)) /* is '__name' a string? */ + return getstr(tsvalue(name)); /* use it as type name */ + } + return ttypename(ttype(o)); /* else use standard type name */ +} + + +void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, const TValue *p3) { + StkId func = L->top.p; + setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ + setobj2s(L, func + 1, p1); /* 1st argument */ + setobj2s(L, func + 2, p2); /* 2nd argument */ + setobj2s(L, func + 3, p3); /* 3rd argument */ + L->top.p = func + 4; + /* metamethod may yield only when called from Lua code */ + if (isLuacode(L->ci)) + luaD_call(L, func, 0); + else + luaD_callnoyield(L, func, 0); +} + + +void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, StkId res) { + ptrdiff_t result = savestack(L, res); + StkId func = L->top.p; + setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ + setobj2s(L, func + 1, p1); /* 1st argument */ + setobj2s(L, func + 2, p2); /* 2nd argument */ + L->top.p += 3; + /* metamethod may yield only when called from Lua code */ + if (isLuacode(L->ci)) + luaD_call(L, func, 1); + else + luaD_callnoyield(L, func, 1); + res = restorestack(L, result); + setobjs2s(L, res, --L->top.p); /* move result to its place */ +} + + +static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (notm(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (notm(tm)) return 0; + luaT_callTMres(L, tm, p1, p2, res); + return 1; +} + + +void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + if (l_unlikely(!callbinTM(L, p1, p2, res, event))) { + switch (event) { + case TM_BAND: case TM_BOR: case TM_BXOR: + case TM_SHL: case TM_SHR: case TM_BNOT: { + if (ttisnumber(p1) && ttisnumber(p2)) + luaG_tointerror(L, p1, p2); + else + luaG_opinterror(L, p1, p2, "perform bitwise operation on"); + } + /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ + default: + luaG_opinterror(L, p1, p2, "perform arithmetic on"); + } + } +} + + +void luaT_tryconcatTM (lua_State *L) { + StkId top = L->top.p; + if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2, + TM_CONCAT))) + luaG_concaterror(L, s2v(top - 2), s2v(top - 1)); +} + + +void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, + int flip, StkId res, TMS event) { + if (flip) + luaT_trybinTM(L, p2, p1, res, event); + else + luaT_trybinTM(L, p1, p2, res, event); +} + + +void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, + int flip, StkId res, TMS event) { + TValue aux; + setivalue(&aux, i2); + luaT_trybinassocTM(L, p1, &aux, flip, res, event); +} + + +/* +** Calls an order tag method. +** For lessequal, LUA_COMPAT_LT_LE keeps compatibility with old +** behavior: if there is no '__le', try '__lt', based on l <= r iff +** !(r < l) (assuming a total order). If the metamethod yields during +** this substitution, the continuation has to know about it (to negate +** the result of rtop.p, event)) /* try original event */ + return !l_isfalse(s2v(L->top.p)); +#if defined(LUA_COMPAT_LT_LE) + else if (event == TM_LE) { + /* try '!(p2 < p1)' for '(p1 <= p2)' */ + L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ + if (callbinTM(L, p2, p1, L->top.p, TM_LT)) { + L->ci->callstatus ^= CIST_LEQ; /* clear mark */ + return l_isfalse(s2v(L->top.p)); + } + /* else error will remove this 'ci'; no need to clear mark */ + } +#endif + luaG_ordererror(L, p1, p2); /* no metamethod found */ + return 0; /* to avoid warnings */ +} + + +int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, + int flip, int isfloat, TMS event) { + TValue aux; const TValue *p2; + if (isfloat) { + setfltvalue(&aux, cast_num(v2)); + } + else + setivalue(&aux, v2); + if (flip) { /* arguments were exchanged? */ + p2 = p1; p1 = &aux; /* correct them */ + } + else + p2 = &aux; + return luaT_callorderTM(L, p1, p2, event); +} + + +void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci, + const Proto *p) { + int i; + int actual = cast_int(L->top.p - ci->func.p) - 1; /* number of arguments */ + int nextra = actual - nfixparams; /* number of extra arguments */ + ci->u.l.nextraargs = nextra; + luaD_checkstack(L, p->maxstacksize + 1); + /* copy function to the top of the stack */ + setobjs2s(L, L->top.p++, ci->func.p); + /* move fixed parameters to the top of the stack */ + for (i = 1; i <= nfixparams; i++) { + setobjs2s(L, L->top.p++, ci->func.p + i); + setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */ + } + ci->func.p += actual + 1; + ci->top.p += actual + 1; + lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p); +} + + +void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) { + int i; + int nextra = ci->u.l.nextraargs; + if (wanted < 0) { + wanted = nextra; /* get all extra arguments available */ + checkstackGCp(L, nextra, where); /* ensure stack space */ + L->top.p = where + nextra; /* next instruction will need top */ + } + for (i = 0; i < wanted && i < nextra; i++) + setobjs2s(L, where + i, ci->func.p - nextra + i); + for (; i < wanted; i++) /* complete required results with nil */ + setnilvalue(s2v(where + i)); +} + diff --git a/User/system/lua/src/ltm.h b/User/system/lua/src/ltm.h new file mode 100644 index 0000000..73b833c --- /dev/null +++ b/User/system/lua/src/ltm.h @@ -0,0 +1,103 @@ +/* +** $Id: ltm.h $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" and "ORDER OP" +*/ +typedef enum { + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_LEN, + TM_EQ, /* last tag method with fast access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_MOD, + TM_POW, + TM_DIV, + TM_IDIV, + TM_BAND, + TM_BOR, + TM_BXOR, + TM_SHL, + TM_SHR, + TM_UNM, + TM_BNOT, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_CLOSE, + TM_N /* number of elements in the enum */ +} TMS; + + +/* +** Mask with 1 in all fast-access methods. A 1 in any of these bits +** in the flag of a (meta)table means the metatable does not have the +** corresponding metamethod field. (Bit 7 of the flag is used for +** 'isrealasize'.) +*/ +#define maskflags (~(~0u << (TM_EQ + 1))) + + +/* +** Test whether there is no tagmethod. +** (Because tagmethods use raw accesses, the result may be an "empty" nil.) +*/ +#define notm(tm) ttisnil(tm) + + +#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ + ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l,et,e) gfasttm(G(l), et, e) + +#define ttypename(x) luaT_typenames_[(x) + 1] + +LUAI_DDEC(const char *const luaT_typenames_[LUA_TOTALTYPES];) + + +LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); + +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init (lua_State *L); + +LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, const TValue *p3); +LUAI_FUNC void luaT_callTMres (lua_State *L, const TValue *f, + const TValue *p1, const TValue *p2, StkId p3); +LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event); +LUAI_FUNC void luaT_tryconcatTM (lua_State *L); +LUAI_FUNC void luaT_trybinassocTM (lua_State *L, const TValue *p1, + const TValue *p2, int inv, StkId res, TMS event); +LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, + int inv, StkId res, TMS event); +LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, + const TValue *p2, TMS event); +LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, + int inv, int isfloat, TMS event); + +LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, + struct CallInfo *ci, const Proto *p); +LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, + StkId where, int wanted); + + +#endif diff --git a/User/system/lua/src/lua.h b/User/system/lua/src/lua.h new file mode 100644 index 0000000..f050dac --- /dev/null +++ b/User/system/lua/src/lua.h @@ -0,0 +1,523 @@ +/* +** $Id: lua.h $ +** Lua - A Scripting Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION_MAJOR "5" +#define LUA_VERSION_MINOR "4" +#define LUA_VERSION_RELEASE "7" + +#define LUA_VERSION_NUM 504 +#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 7) + +#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2024 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" + + +/* mark for precompiled code ('Lua') */ +#define LUA_SIGNATURE "\x1bLua" + +/* option for multiple returns in 'lua_pcall' and 'lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** Pseudo-indices +** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty +** space after that to help overflow detection) +*/ +#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000) +#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) + + +/* thread status */ +#define LUA_OK 0 +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + +#define LUA_NUMTYPES 9 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* predefined values in the registry */ +#define LUA_RIDX_MAINTHREAD 1 +#define LUA_RIDX_GLOBALS 2 +#define LUA_RIDX_LAST LUA_RIDX_GLOBALS + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + +/* unsigned integer type */ +typedef LUA_UNSIGNED lua_Unsigned; + +/* type for continuation-function contexts */ +typedef LUA_KCONTEXT lua_KContext; + + +/* +** Type for C functions registered with Lua +*/ +typedef int (*lua_CFunction) (lua_State *L); + +/* +** Type for continuation functions +*/ +typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx); + + +/* +** Type for functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud); + + +/* +** Type for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** Type for warning functions +*/ +typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont); + + +/* +** Type used by the debug API to collect debug information +*/ +typedef struct lua_Debug lua_Debug; + + +/* +** Functions to be called by the debugger in specific events +*/ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* +** RCS ident string +*/ +extern const char lua_ident[]; + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); +LUA_API int (lua_closethread) (lua_State *L, lua_State *from); +LUA_API int (lua_resetthread) (lua_State *L); /* Deprecated! */ + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +LUA_API lua_Number (lua_version) (lua_State *L); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_absindex) (lua_State *L, int idx); +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_rotate) (lua_State *L, int idx, int n); +LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx); +LUA_API int (lua_checkstack) (lua_State *L, int n); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isinteger) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); +LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API lua_Unsigned (lua_rawlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** Comparison and arithmetic functions +*/ + +#define LUA_OPADD 0 /* ORDER TM, ORDER OP */ +#define LUA_OPSUB 1 +#define LUA_OPMUL 2 +#define LUA_OPMOD 3 +#define LUA_OPPOW 4 +#define LUA_OPDIV 5 +#define LUA_OPIDIV 6 +#define LUA_OPBAND 7 +#define LUA_OPBOR 8 +#define LUA_OPBXOR 9 +#define LUA_OPSHL 10 +#define LUA_OPSHR 11 +#define LUA_OPUNM 12 +#define LUA_OPBNOT 13 + +LUA_API void (lua_arith) (lua_State *L, int op); + +#define LUA_OPEQ 0 +#define LUA_OPLT 1 +#define LUA_OPLE 2 + +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t len); +LUA_API const char *(lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API int (lua_getglobal) (lua_State *L, const char *name); +LUA_API int (lua_gettable) (lua_State *L, int idx); +LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API int (lua_geti) (lua_State *L, int idx, lua_Integer n); +LUA_API int (lua_rawget) (lua_State *L, int idx); +LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n); +LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p); + +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdatauv) (lua_State *L, size_t sz, int nuvalue); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API int (lua_getiuservalue) (lua_State *L, int idx, int n); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_setglobal) (lua_State *L, const char *name); +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_seti) (lua_State *L, int idx, lua_Integer n); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, lua_Integer n); +LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API int (lua_setiuservalue) (lua_State *L, int idx, int n); + + +/* +** 'load' and 'call' functions (load and run Lua code) +*/ +LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, + lua_KContext ctx, lua_KFunction k); +#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) + +LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, + lua_KContext ctx, lua_KFunction k); +#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) + +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname, const char *mode); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, + lua_KFunction k); +LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg, + int *nres); +LUA_API int (lua_status) (lua_State *L); +LUA_API int (lua_isyieldable) (lua_State *L); + +#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) + + +/* +** Warning-related functions +*/ +LUA_API void (lua_setwarnf) (lua_State *L, lua_WarnFunction f, void *ud); +LUA_API void (lua_warning) (lua_State *L, const char *msg, int tocont); + + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 +#define LUA_GCISRUNNING 9 +#define LUA_GCGEN 10 +#define LUA_GCINC 11 + +LUA_API int (lua_gc) (lua_State *L, int what, ...); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); +LUA_API void (lua_len) (lua_State *L, int idx); + +LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); + +LUA_API void (lua_toclose) (lua_State *L, int idx); +LUA_API void (lua_closeslot) (lua_State *L, int idx); + + +/* +** {============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE)) + +#define lua_tonumber(L,i) lua_tonumberx(L,(i),NULL) +#define lua_tointeger(L,i) lua_tointegerx(L,(i),NULL) + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) lua_pushstring(L, "" s) + +#define lua_pushglobaltable(L) \ + ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + +#define lua_insert(L,idx) lua_rotate(L, (idx), 1) + +#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1)) + +#define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1)) + +/* }============================================================== */ + + +/* +** {============================================================== +** compatibility macros +** =============================================================== +*/ +#if defined(LUA_COMPAT_APIINTCASTS) + +#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) +#define lua_tounsignedx(L,i,is) ((lua_Unsigned)lua_tointegerx(L,i,is)) +#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL) + +#endif + +#define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1) +#define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1) +#define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1) + +#define LUA_NUMTAGS LUA_NUMTYPES + +/* }============================================================== */ + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILCALL 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + + +LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar); +LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n); +LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n); + +LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n); +LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1, + int fidx2, int n2); + +LUA_API void (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook (lua_gethook) (lua_State *L); +LUA_API int (lua_gethookmask) (lua_State *L); +LUA_API int (lua_gethookcount) (lua_State *L); + +LUA_API int (lua_setcstacklimit) (lua_State *L, unsigned int limit); + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ + const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ + const char *source; /* (S) */ + size_t srclen; /* (S) */ + int currentline; /* (l) */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + unsigned char nups; /* (u) number of upvalues */ + unsigned char nparams;/* (u) number of parameters */ + char isvararg; /* (u) */ + char istailcall; /* (t) */ + unsigned short ftransfer; /* (r) index of first value transferred */ + unsigned short ntransfer; /* (r) number of transferred values */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + struct CallInfo *i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2024 Lua.org, PUC-Rio. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************/ + + +#endif diff --git a/User/system/lua/src/lua.hpp b/User/system/lua/src/lua.hpp new file mode 100644 index 0000000..ec417f5 --- /dev/null +++ b/User/system/lua/src/lua.hpp @@ -0,0 +1,9 @@ +// lua.hpp +// Lua header files for C++ +// <> not supplied automatically because Lua also compiles as C++ + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} diff --git a/User/system/lua/src/luaconf.h b/User/system/lua/src/luaconf.h new file mode 100644 index 0000000..33bb580 --- /dev/null +++ b/User/system/lua/src/luaconf.h @@ -0,0 +1,802 @@ +/* +** $Id: luaconf.h $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef luaconf_h +#define luaconf_h + +#include +#include + + +/* +** =================================================================== +** General Configuration File for Lua +** +** Some definitions here can be changed externally, through the compiler +** (e.g., with '-D' options): They are commented out or protected +** by '#if !defined' guards. However, several other definitions +** should be changed directly here, either because they affect the +** Lua ABI (by making the changes here, you ensure that all software +** connected to Lua, such as C libraries, will be compiled with the same +** configuration); or because they are seldom changed. +** +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +** {==================================================================== +** System Configuration: macros to adapt (if needed) Lua to some +** particular platform, for instance restricting it to C89. +** ===================================================================== +*/ + +/* +@@ LUA_USE_C89 controls the use of non-ISO-C89 features. +** Define it if you want Lua to avoid the use of a few C99 features +** or Windows-specific features on Windows. +*/ +/* #define LUA_USE_C89 */ + + +/* +** By default, Lua on Windows use (some) specific Windows features +*/ +#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE) +#define LUA_USE_WINDOWS /* enable goodies for regular Windows */ +#endif + + +#if defined(LUA_USE_WINDOWS) +#define LUA_DL_DLL /* enable support for DLL */ +#define LUA_USE_C89 /* broadly, Windows is C89 */ +#endif + + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#endif + + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* MacOS does not need -ldl */ +#endif + + +#if defined(LUA_USE_IOS) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN +#endif + + +/* +@@ LUAI_IS32INT is true iff 'int' has (at least) 32 bits. +*/ +#define LUAI_IS32INT ((UINT_MAX >> 30) >= 3) + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Number types. These options should not be +** set externally, because any other code connected to Lua must +** use the same configuration. +** =================================================================== +*/ + +/* +@@ LUA_INT_TYPE defines the type for Lua integers. +@@ LUA_FLOAT_TYPE defines the type for Lua floats. +** Lua should work fine with any mix of these options supported +** by your C compiler. The usual configurations are 64-bit integers +** and 'double' (the default), 32-bit integers and 'float' (for +** restricted platforms), and 'long'/'double' (for C compilers not +** compliant with C99, which may not have support for 'long long'). +*/ + +/* predefined options for LUA_INT_TYPE */ +#define LUA_INT_INT 1 +#define LUA_INT_LONG 2 +#define LUA_INT_LONGLONG 3 + +/* predefined options for LUA_FLOAT_TYPE */ +#define LUA_FLOAT_FLOAT 1 +#define LUA_FLOAT_DOUBLE 2 +#define LUA_FLOAT_LONGDOUBLE 3 + + +/* Default configuration ('long long' and 'double', for 64-bit Lua) */ +#define LUA_INT_DEFAULT LUA_INT_LONGLONG +#define LUA_FLOAT_DEFAULT LUA_FLOAT_DOUBLE + + +/* +@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. +*/ +#define LUA_32BITS 0 + + +/* +@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for +** C89 ('long' and 'double'); Windows always has '__int64', so it does +** not need to use this case. +*/ +#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) +#define LUA_C89_NUMBERS 1 +#else +#define LUA_C89_NUMBERS 0 +#endif + + +#if LUA_32BITS /* { */ +/* +** 32-bit integers and 'float' +*/ +#if LUAI_IS32INT /* use 'int' if big enough */ +#define LUA_INT_TYPE LUA_INT_INT +#else /* otherwise use 'long' */ +#define LUA_INT_TYPE LUA_INT_LONG +#endif +#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT + +#elif LUA_C89_NUMBERS /* }{ */ +/* +** largest types available for C89 ('long' and 'double') +*/ +#define LUA_INT_TYPE LUA_INT_LONG +#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE + +#else /* }{ */ +/* use defaults */ + +#define LUA_INT_TYPE LUA_INT_DEFAULT +#define LUA_FLOAT_TYPE LUA_FLOAT_DEFAULT + +#endif /* } */ + + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Paths. +** =================================================================== +*/ + +/* +** LUA_PATH_SEP is the character that separates templates in a path. +** LUA_PATH_MARK is the string that marks the substitution points in a +** template. +** LUA_EXEC_DIR in a Windows path is replaced by the executable's +** directory. +*/ +#define LUA_PATH_SEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXEC_DIR "!" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +** Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +** C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ + +#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#if defined(_WIN32) /* { */ +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\" + +#if !defined(LUA_PATH_DEFAULT) +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \ + LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \ + ".\\?.lua;" ".\\?\\init.lua" +#endif + +#if !defined(LUA_CPATH_DEFAULT) +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.dll;" \ + LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \ + LUA_CDIR"loadall.dll;" ".\\?.dll" +#endif + +#else /* }{ */ + +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/" +#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/" + +#if !defined(LUA_PATH_DEFAULT) +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ + "./?.lua;" "./?/init.lua" +#endif + +#if !defined(LUA_CPATH_DEFAULT) +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" +#endif + +#endif /* } */ + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if !defined(LUA_DIRSEP) + +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + +#endif + + +/* +** LUA_IGMARK is a mark to ignore all after it when building the +** module name (e.g., used to build the luaopen_ function name). +** Typically, the suffix after the mark is the module version, +** as in "mod-v1.2.so". +*/ +#define LUA_IGMARK "-" + +/* }================================================================== */ + + +/* +** {================================================================== +** Marks for exported symbols in the C code +** =================================================================== +*/ + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all auxiliary library functions. +@@ LUAMOD_API is a mark for all standard library opening functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) /* { */ + +#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ +#define LUA_API __declspec(dllexport) +#else /* }{ */ +#define LUA_API __declspec(dllimport) +#endif /* } */ + +#else /* }{ */ + +#define LUA_API extern + +#endif /* } */ + + +/* +** More often than not the libs go together with the core. +*/ +#define LUALIB_API LUA_API +#define LUAMOD_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +** exported to outside modules. +@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables, +** none of which to be exported to outside modules (LUAI_DDEF for +** definitions and LUAI_DDEC for declarations). +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. Not all elf targets support +** this attribute. Unfortunately, gcc does not offer a way to check +** whether the target offers that support, and those without support +** give a warning about it. To avoid these warnings, change to the +** default definition. +*/ +#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) /* { */ +#define LUAI_FUNC __attribute__((visibility("internal"))) extern +#else /* }{ */ +#define LUAI_FUNC extern +#endif /* } */ + +#define LUAI_DDEC(dec) LUAI_FUNC dec +#define LUAI_DDEF /* empty */ + +/* }================================================================== */ + + +/* +** {================================================================== +** Compatibility with previous versions +** =================================================================== +*/ + +/* +@@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3. +** You can define it to get all options, or change specific options +** to fit your specific needs. +*/ +#if defined(LUA_COMPAT_5_3) /* { */ + +/* +@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated +** functions in the mathematical library. +** (These functions were already officially removed in 5.3; +** nevertheless they are still available here.) +*/ +#define LUA_COMPAT_MATHLIB + +/* +@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for +** manipulating other integer types (lua_pushunsigned, lua_tounsigned, +** luaL_checkint, luaL_checklong, etc.) +** (These macros were also officially removed in 5.3, but they are still +** available here.) +*/ +#define LUA_COMPAT_APIINTCASTS + + +/* +@@ LUA_COMPAT_LT_LE controls the emulation of the '__le' metamethod +** using '__lt'. +*/ +#define LUA_COMPAT_LT_LE + + +/* +@@ The following macros supply trivial compatibility for some +** changes in the API. The macros themselves document how to +** change your code to avoid using them. +** (Once more, these macros were officially removed in 5.3, but they are +** still available here.) +*/ +#define lua_strlen(L,i) lua_rawlen(L, (i)) + +#define lua_objlen(L,i) lua_rawlen(L, (i)) + +#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) +#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) + +#endif /* } */ + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Numbers (low-level part). +** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_* +** satisfy your needs. +** =================================================================== +*/ + +/* +@@ LUAI_UACNUMBER is the result of a 'default argument promotion' +@@ over a floating number. +@@ l_floatatt(x) corrects float attribute 'x' to the proper float type +** by prefixing it with one of FLT/DBL/LDBL. +@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. +@@ LUA_NUMBER_FMT is the format for writing floats. +@@ lua_number2str converts a float to a string. +@@ l_mathop allows the addition of an 'l' or 'f' to all math operations. +@@ l_floor takes the floor of a float. +@@ lua_str2number converts a decimal numeral to a number. +*/ + + +/* The following definitions are good for most cases here */ + +#define l_floor(x) (l_mathop(floor)(x)) + +#define lua_number2str(s,sz,n) \ + l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n)) + +/* +@@ lua_numbertointeger converts a float number with an integral value +** to an integer, or returns 0 if float is not within the range of +** a lua_Integer. (The range comparisons are tricky because of +** rounding. The tests here assume a two-complement representation, +** where MININTEGER always has an exact representation as a float; +** MAXINTEGER may not have one, and therefore its conversion to float +** may have an ill-defined value.) +*/ +#define lua_numbertointeger(n,p) \ + ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ + (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ + (*(p) = (LUA_INTEGER)(n), 1)) + + +/* now the variable definitions */ + +#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */ + +#define LUA_NUMBER float + +#define l_floatatt(n) (FLT_##n) + +#define LUAI_UACNUMBER double + +#define LUA_NUMBER_FRMLEN "" +#define LUA_NUMBER_FMT "%.7g" + +#define l_mathop(op) op##f + +#define lua_str2number(s,p) strtof((s), (p)) + + +#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */ + +#define LUA_NUMBER long double + +#define l_floatatt(n) (LDBL_##n) + +#define LUAI_UACNUMBER long double + +#define LUA_NUMBER_FRMLEN "L" +#define LUA_NUMBER_FMT "%.19Lg" + +#define l_mathop(op) op##l + +#define lua_str2number(s,p) strtold((s), (p)) + +#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */ + +#define LUA_NUMBER double + +#define l_floatatt(n) (DBL_##n) + +#define LUAI_UACNUMBER double + +#define LUA_NUMBER_FRMLEN "" +#define LUA_NUMBER_FMT "%.14g" + +#define l_mathop(op) op + +#define lua_str2number(s,p) strtod((s), (p)) + +#else /* }{ */ + +#error "numeric float type not defined" + +#endif /* } */ + + + +/* +@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. +@@ LUAI_UACINT is the result of a 'default argument promotion' +@@ over a LUA_INTEGER. +@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. +@@ LUA_INTEGER_FMT is the format for writing integers. +@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. +@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. +@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED. +@@ lua_integer2str converts an integer to a string. +*/ + + +/* The following definitions are good for most cases here */ + +#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d" + +#define LUAI_UACINT LUA_INTEGER + +#define lua_integer2str(s,sz,n) \ + l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n)) + +/* +** use LUAI_UACINT here to avoid problems with promotions (which +** can turn a comparison between unsigneds into a signed comparison) +*/ +#define LUA_UNSIGNED unsigned LUAI_UACINT + + +/* now the variable definitions */ + +#if LUA_INT_TYPE == LUA_INT_INT /* { int */ + +#define LUA_INTEGER int +#define LUA_INTEGER_FRMLEN "" + +#define LUA_MAXINTEGER INT_MAX +#define LUA_MININTEGER INT_MIN + +#define LUA_MAXUNSIGNED UINT_MAX + +#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */ + +#define LUA_INTEGER long +#define LUA_INTEGER_FRMLEN "l" + +#define LUA_MAXINTEGER LONG_MAX +#define LUA_MININTEGER LONG_MIN + +#define LUA_MAXUNSIGNED ULONG_MAX + +#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */ + +/* use presence of macro LLONG_MAX as proxy for C99 compliance */ +#if defined(LLONG_MAX) /* { */ +/* use ISO C99 stuff */ + +#define LUA_INTEGER long long +#define LUA_INTEGER_FRMLEN "ll" + +#define LUA_MAXINTEGER LLONG_MAX +#define LUA_MININTEGER LLONG_MIN + +#define LUA_MAXUNSIGNED ULLONG_MAX + +#elif defined(LUA_USE_WINDOWS) /* }{ */ +/* in Windows, can use specific Windows types */ + +#define LUA_INTEGER __int64 +#define LUA_INTEGER_FRMLEN "I64" + +#define LUA_MAXINTEGER _I64_MAX +#define LUA_MININTEGER _I64_MIN + +#define LUA_MAXUNSIGNED _UI64_MAX + +#else /* }{ */ + +#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \ + or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)" + +#endif /* } */ + +#else /* }{ */ + +#error "numeric integer type not defined" + +#endif /* } */ + +/* }================================================================== */ + + +/* +** {================================================================== +** Dependencies with C99 and other C details +** =================================================================== +*/ + +/* +@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89. +** (All uses in Lua have only one format item.) +*/ +#if !defined(LUA_USE_C89) +#define l_sprintf(s,sz,f,i) snprintf(s,sz,f,i) +#else +#define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i)) +#endif + + +/* +@@ lua_strx2number converts a hexadecimal numeral to a number. +** In C99, 'strtod' does that conversion. Otherwise, you can +** leave 'lua_strx2number' undefined and Lua will provide its own +** implementation. +*/ +#if !defined(LUA_USE_C89) +#define lua_strx2number(s,p) lua_str2number(s,p) +#endif + + +/* +@@ lua_pointer2str converts a pointer to a readable string in a +** non-specified way. +*/ +#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p) + + +/* +@@ lua_number2strx converts a float to a hexadecimal numeral. +** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that. +** Otherwise, you can leave 'lua_number2strx' undefined and Lua will +** provide its own implementation. +*/ +#if !defined(LUA_USE_C89) +#define lua_number2strx(L,b,sz,f,n) \ + ((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n))) +#endif + + +/* +** 'strtof' and 'opf' variants for math functions are not valid in +** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the +** availability of these variants. ('math.h' is already included in +** all files that use these macros.) +*/ +#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF)) +#undef l_mathop /* variants not available */ +#undef lua_str2number +#define l_mathop(op) (lua_Number)op /* no variant */ +#define lua_str2number(s,p) ((lua_Number)strtod((s), (p))) +#endif + + +/* +@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation +** functions. It must be a numerical type; Lua will use 'intptr_t' if +** available, otherwise it will use 'ptrdiff_t' (the nearest thing to +** 'intptr_t' in C89) +*/ +#define LUA_KCONTEXT ptrdiff_t + +#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \ + __STDC_VERSION__ >= 199901L +#include +#if defined(INTPTR_MAX) /* even in C99 this type is optional */ +#undef LUA_KCONTEXT +#define LUA_KCONTEXT intptr_t +#endif +#endif + + +/* +@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point). +** Change that if you do not want to use C locales. (Code using this +** macro must include the header 'locale.h'.) +*/ +#if !defined(lua_getlocaledecpoint) +#define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) +#endif + + +/* +** macros to improve jump prediction, used mostly for error handling +** and debug facilities. (Some macros in the Lua API use these macros. +** Define LUA_NOBUILTIN if you do not want '__builtin_expect' in your +** code.) +*/ +#if !defined(luai_likely) + +#if defined(__GNUC__) && !defined(LUA_NOBUILTIN) +#define luai_likely(x) (__builtin_expect(((x) != 0), 1)) +#define luai_unlikely(x) (__builtin_expect(((x) != 0), 0)) +#else +#define luai_likely(x) (x) +#define luai_unlikely(x) (x) +#endif + +#endif + + +#if defined(LUA_CORE) || defined(LUA_LIB) +/* shorter names for Lua's own use */ +#define l_likely(x) luai_likely(x) +#define l_unlikely(x) luai_unlikely(x) +#endif + + + +/* }================================================================== */ + + +/* +** {================================================================== +** Language Variations +** ===================================================================== +*/ + +/* +@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some +** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from +** numbers to strings. Define LUA_NOCVTS2N to turn off automatic +** coercion from strings to numbers. +*/ +/* #define LUA_NOCVTN2S */ +/* #define LUA_NOCVTS2N */ + + +/* +@@ LUA_USE_APICHECK turns on several consistency checks on the C API. +** Define it as a help when debugging C code. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(l,e) assert(e) +#endif + +/* }================================================================== */ + + +/* +** {================================================================== +** Macros that affect the API and must be stable (that is, must be the +** same when you compile Lua and when you compile code that links to +** Lua). +** ===================================================================== +*/ + +/* +@@ LUAI_MAXSTACK limits the size of the Lua stack. +** CHANGE it if you need a different limit. This limit is arbitrary; +** its only purpose is to stop Lua from consuming unlimited stack +** space (and to reserve some numbers for pseudo-indices). +** (It must fit into max(size_t)/32 and max(int)/2.) +*/ +#if LUAI_IS32INT +#define LUAI_MAXSTACK 1000000 +#else +#define LUAI_MAXSTACK 15000 +#endif + + +/* +@@ LUA_EXTRASPACE defines the size of a raw memory area associated with +** a Lua state with very fast access. +** CHANGE it if you need a different size. +*/ +#define LUA_EXTRASPACE (sizeof(void *)) + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +** of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +@@ LUAL_BUFFERSIZE is the initial buffer size used by the lauxlib +** buffer system. +*/ +#define LUAL_BUFFERSIZE ((int)(16 * sizeof(void*) * sizeof(lua_Number))) + + +/* +@@ LUAI_MAXALIGN defines fields that, when used in a union, ensure +** maximum alignment for the other items in that union. +*/ +#define LUAI_MAXALIGN lua_Number n; double u; void *s; lua_Integer i; long l + +/* }================================================================== */ + + + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + + + +#endif + diff --git a/User/system/lua/src/lualib.h b/User/system/lua/src/lualib.h new file mode 100644 index 0000000..2625529 --- /dev/null +++ b/User/system/lua/src/lualib.h @@ -0,0 +1,52 @@ +/* +** $Id: lualib.h $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +/* version suffix for environment variable names */ +#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR + + +LUAMOD_API int (luaopen_base) (lua_State *L); + +#define LUA_COLIBNAME "coroutine" +LUAMOD_API int (luaopen_coroutine) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUAMOD_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUAMOD_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUAMOD_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUAMOD_API int (luaopen_string) (lua_State *L); + +#define LUA_UTF8LIBNAME "utf8" +LUAMOD_API int (luaopen_utf8) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUAMOD_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUAMOD_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUAMOD_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + +#endif diff --git a/User/system/lua/src/lundump.c b/User/system/lua/src/lundump.c new file mode 100644 index 0000000..e8d92a8 --- /dev/null +++ b/User/system/lua/src/lundump.c @@ -0,0 +1,335 @@ +/* +** $Id: lundump.c $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#define lundump_c +#define LUA_CORE + +#include "lprefix.h" + + +#include +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstring.h" +#include "lundump.h" +#include "lzio.h" + + +#if !defined(luai_verifycode) +#define luai_verifycode(L,f) /* empty */ +#endif + + +typedef struct { + lua_State *L; + ZIO *Z; + const char *name; +} LoadState; + + +static l_noret error (LoadState *S, const char *why) { + luaO_pushfstring(S->L, "%s: bad binary format (%s)", S->name, why); + luaD_throw(S->L, LUA_ERRSYNTAX); +} + + +/* +** All high-level loads go through loadVector; you can change it to +** adapt to the endianness of the input +*/ +#define loadVector(S,b,n) loadBlock(S,b,(n)*sizeof((b)[0])) + +static void loadBlock (LoadState *S, void *b, size_t size) { + if (luaZ_read(S->Z, b, size) != 0) + error(S, "truncated chunk"); +} + + +#define loadVar(S,x) loadVector(S,&x,1) + + +static lu_byte loadByte (LoadState *S) { + int b = zgetc(S->Z); + if (b == EOZ) + error(S, "truncated chunk"); + return cast_byte(b); +} + + +static size_t loadUnsigned (LoadState *S, size_t limit) { + size_t x = 0; + int b; + limit >>= 7; + do { + b = loadByte(S); + if (x >= limit) + error(S, "integer overflow"); + x = (x << 7) | (b & 0x7f); + } while ((b & 0x80) == 0); + return x; +} + + +static size_t loadSize (LoadState *S) { + return loadUnsigned(S, MAX_SIZET); +} + + +static int loadInt (LoadState *S) { + return cast_int(loadUnsigned(S, INT_MAX)); +} + + +static lua_Number loadNumber (LoadState *S) { + lua_Number x; + loadVar(S, x); + return x; +} + + +static lua_Integer loadInteger (LoadState *S) { + lua_Integer x; + loadVar(S, x); + return x; +} + + +/* +** Load a nullable string into prototype 'p'. +*/ +static TString *loadStringN (LoadState *S, Proto *p) { + lua_State *L = S->L; + TString *ts; + size_t size = loadSize(S); + if (size == 0) /* no string? */ + return NULL; + else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ + char buff[LUAI_MAXSHORTLEN]; + loadVector(S, buff, size); /* load string into buffer */ + ts = luaS_newlstr(L, buff, size); /* create string */ + } + else { /* long string */ + ts = luaS_createlngstrobj(L, size); /* create string */ + setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */ + luaD_inctop(L); + loadVector(S, getlngstr(ts), size); /* load directly in final place */ + L->top.p--; /* pop string */ + } + luaC_objbarrier(L, p, ts); + return ts; +} + + +/* +** Load a non-nullable string into prototype 'p'. +*/ +static TString *loadString (LoadState *S, Proto *p) { + TString *st = loadStringN(S, p); + if (st == NULL) + error(S, "bad format for constant string"); + return st; +} + + +static void loadCode (LoadState *S, Proto *f) { + int n = loadInt(S); + f->code = luaM_newvectorchecked(S->L, n, Instruction); + f->sizecode = n; + loadVector(S, f->code, n); +} + + +static void loadFunction(LoadState *S, Proto *f, TString *psource); + + +static void loadConstants (LoadState *S, Proto *f) { + int i; + int n = loadInt(S); + f->k = luaM_newvectorchecked(S->L, n, TValue); + f->sizek = n; + for (i = 0; i < n; i++) + setnilvalue(&f->k[i]); + for (i = 0; i < n; i++) { + TValue *o = &f->k[i]; + int t = loadByte(S); + switch (t) { + case LUA_VNIL: + setnilvalue(o); + break; + case LUA_VFALSE: + setbfvalue(o); + break; + case LUA_VTRUE: + setbtvalue(o); + break; + case LUA_VNUMFLT: + setfltvalue(o, loadNumber(S)); + break; + case LUA_VNUMINT: + setivalue(o, loadInteger(S)); + break; + case LUA_VSHRSTR: + case LUA_VLNGSTR: + setsvalue2n(S->L, o, loadString(S, f)); + break; + default: lua_assert(0); + } + } +} + + +static void loadProtos (LoadState *S, Proto *f) { + int i; + int n = loadInt(S); + f->p = luaM_newvectorchecked(S->L, n, Proto *); + f->sizep = n; + for (i = 0; i < n; i++) + f->p[i] = NULL; + for (i = 0; i < n; i++) { + f->p[i] = luaF_newproto(S->L); + luaC_objbarrier(S->L, f, f->p[i]); + loadFunction(S, f->p[i], f->source); + } +} + + +/* +** Load the upvalues for a function. The names must be filled first, +** because the filling of the other fields can raise read errors and +** the creation of the error message can call an emergency collection; +** in that case all prototypes must be consistent for the GC. +*/ +static void loadUpvalues (LoadState *S, Proto *f) { + int i, n; + n = loadInt(S); + f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); + f->sizeupvalues = n; + for (i = 0; i < n; i++) /* make array valid for GC */ + f->upvalues[i].name = NULL; + for (i = 0; i < n; i++) { /* following calls can raise errors */ + f->upvalues[i].instack = loadByte(S); + f->upvalues[i].idx = loadByte(S); + f->upvalues[i].kind = loadByte(S); + } +} + + +static void loadDebug (LoadState *S, Proto *f) { + int i, n; + n = loadInt(S); + f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte); + f->sizelineinfo = n; + loadVector(S, f->lineinfo, n); + n = loadInt(S); + f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo); + f->sizeabslineinfo = n; + for (i = 0; i < n; i++) { + f->abslineinfo[i].pc = loadInt(S); + f->abslineinfo[i].line = loadInt(S); + } + n = loadInt(S); + f->locvars = luaM_newvectorchecked(S->L, n, LocVar); + f->sizelocvars = n; + for (i = 0; i < n; i++) + f->locvars[i].varname = NULL; + for (i = 0; i < n; i++) { + f->locvars[i].varname = loadStringN(S, f); + f->locvars[i].startpc = loadInt(S); + f->locvars[i].endpc = loadInt(S); + } + n = loadInt(S); + if (n != 0) /* does it have debug information? */ + n = f->sizeupvalues; /* must be this many */ + for (i = 0; i < n; i++) + f->upvalues[i].name = loadStringN(S, f); +} + + +static void loadFunction (LoadState *S, Proto *f, TString *psource) { + f->source = loadStringN(S, f); + if (f->source == NULL) /* no source in dump? */ + f->source = psource; /* reuse parent's source */ + f->linedefined = loadInt(S); + f->lastlinedefined = loadInt(S); + f->numparams = loadByte(S); + f->is_vararg = loadByte(S); + f->maxstacksize = loadByte(S); + loadCode(S, f); + loadConstants(S, f); + loadUpvalues(S, f); + loadProtos(S, f); + loadDebug(S, f); +} + + +static void checkliteral (LoadState *S, const char *s, const char *msg) { + char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ + size_t len = strlen(s); + loadVector(S, buff, len); + if (memcmp(s, buff, len) != 0) + error(S, msg); +} + + +static void fchecksize (LoadState *S, size_t size, const char *tname) { + if (loadByte(S) != size) + error(S, luaO_pushfstring(S->L, "%s size mismatch", tname)); +} + + +#define checksize(S,t) fchecksize(S,sizeof(t),#t) + +static void checkHeader (LoadState *S) { + /* skip 1st char (already read and checked) */ + checkliteral(S, &LUA_SIGNATURE[1], "not a binary chunk"); + if (loadByte(S) != LUAC_VERSION) + error(S, "version mismatch"); + if (loadByte(S) != LUAC_FORMAT) + error(S, "format mismatch"); + checkliteral(S, LUAC_DATA, "corrupted chunk"); + checksize(S, Instruction); + checksize(S, lua_Integer); + checksize(S, lua_Number); + if (loadInteger(S) != LUAC_INT) + error(S, "integer format mismatch"); + if (loadNumber(S) != LUAC_NUM) + error(S, "float format mismatch"); +} + + +/* +** Load precompiled chunk. +*/ +LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { + LoadState S; + LClosure *cl; + if (*name == '@' || *name == '=') + S.name = name + 1; + else if (*name == LUA_SIGNATURE[0]) + S.name = "binary string"; + else + S.name = name; + S.L = L; + S.Z = Z; + checkHeader(&S); + cl = luaF_newLclosure(L, loadByte(&S)); + setclLvalue2s(L, L->top.p, cl); + luaD_inctop(L); + cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); + loadFunction(&S, cl->p, NULL); + lua_assert(cl->nupvalues == cl->p->sizeupvalues); + luai_verifycode(L, cl->p); + return cl; +} + diff --git a/User/system/lua/src/lundump.h b/User/system/lua/src/lundump.h new file mode 100644 index 0000000..a97676c --- /dev/null +++ b/User/system/lua/src/lundump.h @@ -0,0 +1,35 @@ +/* +** $Id: lundump.h $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef lundump_h +#define lundump_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* data to catch conversion errors */ +#define LUAC_DATA "\x19\x93\r\n\x1a\n" + +#define LUAC_INT 0x5678 +#define LUAC_NUM cast_num(370.5) + +/* +** Encode major-minor version in one byte, one nibble for each +*/ +#define LUAC_VERSION (((LUA_VERSION_NUM / 100) * 16) + LUA_VERSION_NUM % 100) + +#define LUAC_FORMAT 0 /* this is the official format */ + +/* load one chunk; from lundump.c */ +LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); + +/* dump one chunk; from ldump.c */ +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, + void* data, int strip); + +#endif diff --git a/User/system/lua/src/lutf8lib.c b/User/system/lua/src/lutf8lib.c new file mode 100644 index 0000000..3a5b9bc --- /dev/null +++ b/User/system/lua/src/lutf8lib.c @@ -0,0 +1,291 @@ +/* +** $Id: lutf8lib.c $ +** Standard library for UTF-8 manipulation +** See Copyright Notice in lua.h +*/ + +#define lutf8lib_c +#define LUA_LIB + +#include "lprefix.h" + + +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#define MAXUNICODE 0x10FFFFu + +#define MAXUTF 0x7FFFFFFFu + + +#define MSGInvalid "invalid UTF-8 code" + +/* +** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits. +*/ +#if (UINT_MAX >> 30) >= 1 +typedef unsigned int utfint; +#else +typedef unsigned long utfint; +#endif + + +#define iscont(c) (((c) & 0xC0) == 0x80) +#define iscontp(p) iscont(*(p)) + + +/* from strlib */ +/* translate a relative string position: negative means back from end */ +static lua_Integer u_posrelat (lua_Integer pos, size_t len) { + if (pos >= 0) return pos; + else if (0u - (size_t)pos > len) return 0; + else return (lua_Integer)len + pos + 1; +} + + +/* +** Decode one UTF-8 sequence, returning NULL if byte sequence is +** invalid. The array 'limits' stores the minimum value for each +** sequence length, to check for overlong representations. Its first +** entry forces an error for non-ascii bytes with no continuation +** bytes (count == 0). +*/ +static const char *utf8_decode (const char *s, utfint *val, int strict) { + static const utfint limits[] = + {~(utfint)0, 0x80, 0x800, 0x10000u, 0x200000u, 0x4000000u}; + unsigned int c = (unsigned char)s[0]; + utfint res = 0; /* final result */ + if (c < 0x80) /* ascii? */ + res = c; + else { + int count = 0; /* to count number of continuation bytes */ + for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */ + unsigned int cc = (unsigned char)s[++count]; /* read next byte */ + if (!iscont(cc)) /* not a continuation byte? */ + return NULL; /* invalid byte sequence */ + res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ + } + res |= ((utfint)(c & 0x7F) << (count * 5)); /* add first byte */ + if (count > 5 || res > MAXUTF || res < limits[count]) + return NULL; /* invalid byte sequence */ + s += count; /* skip continuation bytes read */ + } + if (strict) { + /* check for invalid code points; too large or surrogates */ + if (res > MAXUNICODE || (0xD800u <= res && res <= 0xDFFFu)) + return NULL; + } + if (val) *val = res; + return s + 1; /* +1 to include first byte */ +} + + +/* +** utf8len(s [, i [, j [, lax]]]) --> number of characters that +** start in the range [i,j], or nil + current position if 's' is not +** well formed in that interval +*/ +static int utflen (lua_State *L) { + lua_Integer n = 0; /* counter for the number of characters */ + size_t len; /* string length in bytes */ + const char *s = luaL_checklstring(L, 1, &len); + lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); + lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); + int lax = lua_toboolean(L, 4); + luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, + "initial position out of bounds"); + luaL_argcheck(L, --posj < (lua_Integer)len, 3, + "final position out of bounds"); + while (posi <= posj) { + const char *s1 = utf8_decode(s + posi, NULL, !lax); + if (s1 == NULL) { /* conversion error? */ + luaL_pushfail(L); /* return fail ... */ + lua_pushinteger(L, posi + 1); /* ... and current position */ + return 2; + } + posi = s1 - s; + n++; + } + lua_pushinteger(L, n); + return 1; +} + + +/* +** codepoint(s, [i, [j [, lax]]]) -> returns codepoints for all +** characters that start in the range [i,j] +*/ +static int codepoint (lua_State *L) { + size_t len; + const char *s = luaL_checklstring(L, 1, &len); + lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); + lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); + int lax = lua_toboolean(L, 4); + int n; + const char *se; + luaL_argcheck(L, posi >= 1, 2, "out of bounds"); + luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of bounds"); + if (posi > pose) return 0; /* empty interval; return no values */ + if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ + return luaL_error(L, "string slice too long"); + n = (int)(pose - posi) + 1; /* upper bound for number of returns */ + luaL_checkstack(L, n, "string slice too long"); + n = 0; /* count the number of returns */ + se = s + pose; /* string end */ + for (s += posi - 1; s < se;) { + utfint code; + s = utf8_decode(s, &code, !lax); + if (s == NULL) + return luaL_error(L, MSGInvalid); + lua_pushinteger(L, code); + n++; + } + return n; +} + + +static void pushutfchar (lua_State *L, int arg) { + lua_Unsigned code = (lua_Unsigned)luaL_checkinteger(L, arg); + luaL_argcheck(L, code <= MAXUTF, arg, "value out of range"); + lua_pushfstring(L, "%U", (long)code); +} + + +/* +** utfchar(n1, n2, ...) -> char(n1)..char(n2)... +*/ +static int utfchar (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + if (n == 1) /* optimize common case of single char */ + pushutfchar(L, 1); + else { + int i; + luaL_Buffer b; + luaL_buffinit(L, &b); + for (i = 1; i <= n; i++) { + pushutfchar(L, i); + luaL_addvalue(&b); + } + luaL_pushresult(&b); + } + return 1; +} + + +/* +** offset(s, n, [i]) -> index where n-th character counting from +** position 'i' starts; 0 means character at 'i'. +*/ +static int byteoffset (lua_State *L) { + size_t len; + const char *s = luaL_checklstring(L, 1, &len); + lua_Integer n = luaL_checkinteger(L, 2); + lua_Integer posi = (n >= 0) ? 1 : len + 1; + posi = u_posrelat(luaL_optinteger(L, 3, posi), len); + luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, + "position out of bounds"); + if (n == 0) { + /* find beginning of current byte sequence */ + while (posi > 0 && iscontp(s + posi)) posi--; + } + else { + if (iscontp(s + posi)) + return luaL_error(L, "initial position is a continuation byte"); + if (n < 0) { + while (n < 0 && posi > 0) { /* move back */ + do { /* find beginning of previous character */ + posi--; + } while (posi > 0 && iscontp(s + posi)); + n++; + } + } + else { + n--; /* do not move for 1st character */ + while (n > 0 && posi < (lua_Integer)len) { + do { /* find beginning of next character */ + posi++; + } while (iscontp(s + posi)); /* (cannot pass final '\0') */ + n--; + } + } + } + if (n == 0) /* did it find given character? */ + lua_pushinteger(L, posi + 1); + else /* no such character */ + luaL_pushfail(L); + return 1; +} + + +static int iter_aux (lua_State *L, int strict) { + size_t len; + const char *s = luaL_checklstring(L, 1, &len); + lua_Unsigned n = (lua_Unsigned)lua_tointeger(L, 2); + if (n < len) { + while (iscontp(s + n)) n++; /* go to next character */ + } + if (n >= len) /* (also handles original 'n' being negative) */ + return 0; /* no more codepoints */ + else { + utfint code; + const char *next = utf8_decode(s + n, &code, strict); + if (next == NULL || iscontp(next)) + return luaL_error(L, MSGInvalid); + lua_pushinteger(L, n + 1); + lua_pushinteger(L, code); + return 2; + } +} + + +static int iter_auxstrict (lua_State *L) { + return iter_aux(L, 1); +} + +static int iter_auxlax (lua_State *L) { + return iter_aux(L, 0); +} + + +static int iter_codes (lua_State *L) { + int lax = lua_toboolean(L, 2); + const char *s = luaL_checkstring(L, 1); + luaL_argcheck(L, !iscontp(s), 1, MSGInvalid); + lua_pushcfunction(L, lax ? iter_auxlax : iter_auxstrict); + lua_pushvalue(L, 1); + lua_pushinteger(L, 0); + return 3; +} + + +/* pattern to match a single UTF-8 character */ +#define UTF8PATT "[\0-\x7F\xC2-\xFD][\x80-\xBF]*" + + +static const luaL_Reg funcs[] = { + {"offset", byteoffset}, + {"codepoint", codepoint}, + {"char", utfchar}, + {"len", utflen}, + {"codes", iter_codes}, + /* placeholders */ + {"charpattern", NULL}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_utf8 (lua_State *L) { + luaL_newlib(L, funcs); + lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1); + lua_setfield(L, -2, "charpattern"); + return 1; +} + diff --git a/User/system/lua/src/lvm.c b/User/system/lua/src/lvm.c new file mode 100644 index 0000000..fcd24e1 --- /dev/null +++ b/User/system/lua/src/lvm.c @@ -0,0 +1,1899 @@ +/* +** $Id: lvm.c $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#define lvm_c +#define LUA_CORE + +#include "lprefix.h" + +#include +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + +/* +** By default, use jump tables in the main interpreter loop on gcc +** and compatible compilers. +*/ +#if !defined(LUA_USE_JUMPTABLE) +#if defined(__GNUC__) +#define LUA_USE_JUMPTABLE 1 +#else +#define LUA_USE_JUMPTABLE 0 +#endif +#endif + + + +/* limit for table tag-method chains (to avoid infinite loops) */ +#define MAXTAGLOOP 2000 + + +/* +** 'l_intfitsf' checks whether a given integer is in the range that +** can be converted to a float without rounding. Used in comparisons. +*/ + +/* number of bits in the mantissa of a float */ +#define NBM (l_floatatt(MANT_DIG)) + +/* +** Check whether some integers may not fit in a float, testing whether +** (maxinteger >> NBM) > 0. (That implies (1 << NBM) <= maxinteger.) +** (The shifts are done in parts, to avoid shifting by more than the size +** of an integer. In a worst case, NBM == 113 for long double and +** sizeof(long) == 32.) +*/ +#if ((((LUA_MAXINTEGER >> (NBM / 4)) >> (NBM / 4)) >> (NBM / 4)) \ + >> (NBM - (3 * (NBM / 4)))) > 0 + +/* limit for integers that fit in a float */ +#define MAXINTFITSF ((lua_Unsigned)1 << NBM) + +/* check whether 'i' is in the interval [-MAXINTFITSF, MAXINTFITSF] */ +#define l_intfitsf(i) ((MAXINTFITSF + l_castS2U(i)) <= (2 * MAXINTFITSF)) + +#else /* all integers fit in a float precisely */ + +#define l_intfitsf(i) 1 + +#endif + + +/* +** Try to convert a value from string to a number value. +** If the value is not a string or is a string not representing +** a valid numeral (or if coercions from strings to numbers +** are disabled via macro 'cvt2num'), do not modify 'result' +** and return 0. +*/ +static int l_strton (const TValue *obj, TValue *result) { + lua_assert(obj != result); + if (!cvt2num(obj)) /* is object not a string? */ + return 0; + else { + TString *st = tsvalue(obj); + return (luaO_str2num(getstr(st), result) == tsslen(st) + 1); + } +} + + +/* +** Try to convert a value to a float. The float case is already handled +** by the macro 'tonumber'. +*/ +int luaV_tonumber_ (const TValue *obj, lua_Number *n) { + TValue v; + if (ttisinteger(obj)) { + *n = cast_num(ivalue(obj)); + return 1; + } + else if (l_strton(obj, &v)) { /* string coercible to number? */ + *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */ + return 1; + } + else + return 0; /* conversion failed */ +} + + +/* +** try to convert a float to an integer, rounding according to 'mode'. +*/ +int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode) { + lua_Number f = l_floor(n); + if (n != f) { /* not an integral value? */ + if (mode == F2Ieq) return 0; /* fails if mode demands integral value */ + else if (mode == F2Iceil) /* needs ceil? */ + f += 1; /* convert floor to ceil (remember: n != f) */ + } + return lua_numbertointeger(f, p); +} + + +/* +** try to convert a value to an integer, rounding according to 'mode', +** without string coercion. +** ("Fast track" handled by macro 'tointegerns'.) +*/ +int luaV_tointegerns (const TValue *obj, lua_Integer *p, F2Imod mode) { + if (ttisfloat(obj)) + return luaV_flttointeger(fltvalue(obj), p, mode); + else if (ttisinteger(obj)) { + *p = ivalue(obj); + return 1; + } + else + return 0; +} + + +/* +** try to convert a value to an integer. +*/ +int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode) { + TValue v; + if (l_strton(obj, &v)) /* does 'obj' point to a numerical string? */ + obj = &v; /* change it to point to its corresponding number */ + return luaV_tointegerns(obj, p, mode); +} + + +/* +** Try to convert a 'for' limit to an integer, preserving the semantics +** of the loop. Return true if the loop must not run; otherwise, '*p' +** gets the integer limit. +** (The following explanation assumes a positive step; it is valid for +** negative steps mutatis mutandis.) +** If the limit is an integer or can be converted to an integer, +** rounding down, that is the limit. +** Otherwise, check whether the limit can be converted to a float. If +** the float is too large, clip it to LUA_MAXINTEGER. If the float +** is too negative, the loop should not run, because any initial +** integer value is greater than such limit; so, the function returns +** true to signal that. (For this latter case, no integer limit would be +** correct; even a limit of LUA_MININTEGER would run the loop once for +** an initial value equal to LUA_MININTEGER.) +*/ +static int forlimit (lua_State *L, lua_Integer init, const TValue *lim, + lua_Integer *p, lua_Integer step) { + if (!luaV_tointeger(lim, p, (step < 0 ? F2Iceil : F2Ifloor))) { + /* not coercible to in integer */ + lua_Number flim; /* try to convert to float */ + if (!tonumber(lim, &flim)) /* cannot convert to float? */ + luaG_forerror(L, lim, "limit"); + /* else 'flim' is a float out of integer bounds */ + if (luai_numlt(0, flim)) { /* if it is positive, it is too large */ + if (step < 0) return 1; /* initial value must be less than it */ + *p = LUA_MAXINTEGER; /* truncate */ + } + else { /* it is less than min integer */ + if (step > 0) return 1; /* initial value must be greater than it */ + *p = LUA_MININTEGER; /* truncate */ + } + } + return (step > 0 ? init > *p : init < *p); /* not to run? */ +} + + +/* +** Prepare a numerical for loop (opcode OP_FORPREP). +** Return true to skip the loop. Otherwise, +** after preparation, stack will be as follows: +** ra : internal index (safe copy of the control variable) +** ra + 1 : loop counter (integer loops) or limit (float loops) +** ra + 2 : step +** ra + 3 : control variable +*/ +static int forprep (lua_State *L, StkId ra) { + TValue *pinit = s2v(ra); + TValue *plimit = s2v(ra + 1); + TValue *pstep = s2v(ra + 2); + if (ttisinteger(pinit) && ttisinteger(pstep)) { /* integer loop? */ + lua_Integer init = ivalue(pinit); + lua_Integer step = ivalue(pstep); + lua_Integer limit; + if (step == 0) + luaG_runerror(L, "'for' step is zero"); + setivalue(s2v(ra + 3), init); /* control variable */ + if (forlimit(L, init, plimit, &limit, step)) + return 1; /* skip the loop */ + else { /* prepare loop counter */ + lua_Unsigned count; + if (step > 0) { /* ascending loop? */ + count = l_castS2U(limit) - l_castS2U(init); + if (step != 1) /* avoid division in the too common case */ + count /= l_castS2U(step); + } + else { /* step < 0; descending loop */ + count = l_castS2U(init) - l_castS2U(limit); + /* 'step+1' avoids negating 'mininteger' */ + count /= l_castS2U(-(step + 1)) + 1u; + } + /* store the counter in place of the limit (which won't be + needed anymore) */ + setivalue(plimit, l_castU2S(count)); + } + } + else { /* try making all values floats */ + lua_Number init; lua_Number limit; lua_Number step; + if (l_unlikely(!tonumber(plimit, &limit))) + luaG_forerror(L, plimit, "limit"); + if (l_unlikely(!tonumber(pstep, &step))) + luaG_forerror(L, pstep, "step"); + if (l_unlikely(!tonumber(pinit, &init))) + luaG_forerror(L, pinit, "initial value"); + if (step == 0) + luaG_runerror(L, "'for' step is zero"); + if (luai_numlt(0, step) ? luai_numlt(limit, init) + : luai_numlt(init, limit)) + return 1; /* skip the loop */ + else { + /* make sure internal values are all floats */ + setfltvalue(plimit, limit); + setfltvalue(pstep, step); + setfltvalue(s2v(ra), init); /* internal index */ + setfltvalue(s2v(ra + 3), init); /* control variable */ + } + } + return 0; +} + + +/* +** Execute a step of a float numerical for loop, returning +** true iff the loop must continue. (The integer case is +** written online with opcode OP_FORLOOP, for performance.) +*/ +static int floatforloop (StkId ra) { + lua_Number step = fltvalue(s2v(ra + 2)); + lua_Number limit = fltvalue(s2v(ra + 1)); + lua_Number idx = fltvalue(s2v(ra)); /* internal index */ + idx = luai_numadd(L, idx, step); /* increment index */ + if (luai_numlt(0, step) ? luai_numle(idx, limit) + : luai_numle(limit, idx)) { + chgfltvalue(s2v(ra), idx); /* update internal index */ + setfltvalue(s2v(ra + 3), idx); /* and control variable */ + return 1; /* jump back */ + } + else + return 0; /* finish the loop */ +} + + +/* +** Finish the table access 'val = t[key]'. +** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to +** t[k] entry (which must be empty). +*/ +void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, + const TValue *slot) { + int loop; /* counter to avoid infinite loops */ + const TValue *tm; /* metamethod */ + for (loop = 0; loop < MAXTAGLOOP; loop++) { + if (slot == NULL) { /* 't' is not a table? */ + lua_assert(!ttistable(t)); + tm = luaT_gettmbyobj(L, t, TM_INDEX); + if (l_unlikely(notm(tm))) + luaG_typeerror(L, t, "index"); /* no metamethod */ + /* else will try the metamethod */ + } + else { /* 't' is a table */ + lua_assert(isempty(slot)); + tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */ + if (tm == NULL) { /* no metamethod? */ + setnilvalue(s2v(val)); /* result is nil */ + return; + } + /* else will try the metamethod */ + } + if (ttisfunction(tm)) { /* is metamethod a function? */ + luaT_callTMres(L, tm, t, key, val); /* call it */ + return; + } + t = tm; /* else try to access 'tm[key]' */ + if (luaV_fastget(L, t, key, slot, luaH_get)) { /* fast track? */ + setobj2s(L, val, slot); /* done */ + return; + } + /* else repeat (tail call 'luaV_finishget') */ + } + luaG_runerror(L, "'__index' chain too long; possible loop"); +} + + +/* +** Finish a table assignment 't[key] = val'. +** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points +** to the entry 't[key]', or to a value with an absent key if there +** is no such entry. (The value at 'slot' must be empty, otherwise +** 'luaV_fastget' would have done the job.) +*/ +void luaV_finishset (lua_State *L, const TValue *t, TValue *key, + TValue *val, const TValue *slot) { + int loop; /* counter to avoid infinite loops */ + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; /* '__newindex' metamethod */ + if (slot != NULL) { /* is 't' a table? */ + Table *h = hvalue(t); /* save 't' table */ + lua_assert(isempty(slot)); /* slot must be empty */ + tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ + if (tm == NULL) { /* no metamethod? */ + luaH_finishset(L, h, key, slot, val); /* set new value */ + invalidateTMcache(h); + luaC_barrierback(L, obj2gco(h), val); + return; + } + /* else will try the metamethod */ + } + else { /* not a table; check metamethod */ + tm = luaT_gettmbyobj(L, t, TM_NEWINDEX); + if (l_unlikely(notm(tm))) + luaG_typeerror(L, t, "index"); + } + /* try the metamethod */ + if (ttisfunction(tm)) { + luaT_callTM(L, tm, t, key, val); + return; + } + t = tm; /* else repeat assignment over 'tm' */ + if (luaV_fastget(L, t, key, slot, luaH_get)) { + luaV_finishfastset(L, t, slot, val); + return; /* done */ + } + /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */ + } + luaG_runerror(L, "'__newindex' chain too long; possible loop"); +} + + +/* +** Compare two strings 'ts1' x 'ts2', returning an integer less-equal- +** -greater than zero if 'ts1' is less-equal-greater than 'ts2'. +** The code is a little tricky because it allows '\0' in the strings +** and it uses 'strcoll' (to respect locales) for each segment +** of the strings. Note that segments can compare equal but still +** have different lengths. +*/ +static int l_strcmp (const TString *ts1, const TString *ts2) { + const char *s1 = getstr(ts1); + size_t rl1 = tsslen(ts1); /* real length */ + const char *s2 = getstr(ts2); + size_t rl2 = tsslen(ts2); + for (;;) { /* for each segment */ + int temp = strcoll(s1, s2); + if (temp != 0) /* not equal? */ + return temp; /* done */ + else { /* strings are equal up to a '\0' */ + size_t zl1 = strlen(s1); /* index of first '\0' in 's1' */ + size_t zl2 = strlen(s2); /* index of first '\0' in 's2' */ + if (zl2 == rl2) /* 's2' is finished? */ + return (zl1 == rl1) ? 0 : 1; /* check 's1' */ + else if (zl1 == rl1) /* 's1' is finished? */ + return -1; /* 's1' is less than 's2' ('s2' is not finished) */ + /* both strings longer than 'zl'; go on comparing after the '\0' */ + zl1++; zl2++; + s1 += zl1; rl1 -= zl1; s2 += zl2; rl2 -= zl2; + } + } +} + + +/* +** Check whether integer 'i' is less than float 'f'. If 'i' has an +** exact representation as a float ('l_intfitsf'), compare numbers as +** floats. Otherwise, use the equivalence 'i < f <=> i < ceil(f)'. +** If 'ceil(f)' is out of integer range, either 'f' is greater than +** all integers or less than all integers. +** (The test with 'l_intfitsf' is only for performance; the else +** case is correct for all values, but it is slow due to the conversion +** from float to int.) +** When 'f' is NaN, comparisons must result in false. +*/ +l_sinline int LTintfloat (lua_Integer i, lua_Number f) { + if (l_intfitsf(i)) + return luai_numlt(cast_num(i), f); /* compare them as floats */ + else { /* i < f <=> i < ceil(f) */ + lua_Integer fi; + if (luaV_flttointeger(f, &fi, F2Iceil)) /* fi = ceil(f) */ + return i < fi; /* compare them as integers */ + else /* 'f' is either greater or less than all integers */ + return f > 0; /* greater? */ + } +} + + +/* +** Check whether integer 'i' is less than or equal to float 'f'. +** See comments on previous function. +*/ +l_sinline int LEintfloat (lua_Integer i, lua_Number f) { + if (l_intfitsf(i)) + return luai_numle(cast_num(i), f); /* compare them as floats */ + else { /* i <= f <=> i <= floor(f) */ + lua_Integer fi; + if (luaV_flttointeger(f, &fi, F2Ifloor)) /* fi = floor(f) */ + return i <= fi; /* compare them as integers */ + else /* 'f' is either greater or less than all integers */ + return f > 0; /* greater? */ + } +} + + +/* +** Check whether float 'f' is less than integer 'i'. +** See comments on previous function. +*/ +l_sinline int LTfloatint (lua_Number f, lua_Integer i) { + if (l_intfitsf(i)) + return luai_numlt(f, cast_num(i)); /* compare them as floats */ + else { /* f < i <=> floor(f) < i */ + lua_Integer fi; + if (luaV_flttointeger(f, &fi, F2Ifloor)) /* fi = floor(f) */ + return fi < i; /* compare them as integers */ + else /* 'f' is either greater or less than all integers */ + return f < 0; /* less? */ + } +} + + +/* +** Check whether float 'f' is less than or equal to integer 'i'. +** See comments on previous function. +*/ +l_sinline int LEfloatint (lua_Number f, lua_Integer i) { + if (l_intfitsf(i)) + return luai_numle(f, cast_num(i)); /* compare them as floats */ + else { /* f <= i <=> ceil(f) <= i */ + lua_Integer fi; + if (luaV_flttointeger(f, &fi, F2Iceil)) /* fi = ceil(f) */ + return fi <= i; /* compare them as integers */ + else /* 'f' is either greater or less than all integers */ + return f < 0; /* less? */ + } +} + + +/* +** Return 'l < r', for numbers. +*/ +l_sinline int LTnum (const TValue *l, const TValue *r) { + lua_assert(ttisnumber(l) && ttisnumber(r)); + if (ttisinteger(l)) { + lua_Integer li = ivalue(l); + if (ttisinteger(r)) + return li < ivalue(r); /* both are integers */ + else /* 'l' is int and 'r' is float */ + return LTintfloat(li, fltvalue(r)); /* l < r ? */ + } + else { + lua_Number lf = fltvalue(l); /* 'l' must be float */ + if (ttisfloat(r)) + return luai_numlt(lf, fltvalue(r)); /* both are float */ + else /* 'l' is float and 'r' is int */ + return LTfloatint(lf, ivalue(r)); + } +} + + +/* +** Return 'l <= r', for numbers. +*/ +l_sinline int LEnum (const TValue *l, const TValue *r) { + lua_assert(ttisnumber(l) && ttisnumber(r)); + if (ttisinteger(l)) { + lua_Integer li = ivalue(l); + if (ttisinteger(r)) + return li <= ivalue(r); /* both are integers */ + else /* 'l' is int and 'r' is float */ + return LEintfloat(li, fltvalue(r)); /* l <= r ? */ + } + else { + lua_Number lf = fltvalue(l); /* 'l' must be float */ + if (ttisfloat(r)) + return luai_numle(lf, fltvalue(r)); /* both are float */ + else /* 'l' is float and 'r' is int */ + return LEfloatint(lf, ivalue(r)); + } +} + + +/* +** return 'l < r' for non-numbers. +*/ +static int lessthanothers (lua_State *L, const TValue *l, const TValue *r) { + lua_assert(!ttisnumber(l) || !ttisnumber(r)); + if (ttisstring(l) && ttisstring(r)) /* both are strings? */ + return l_strcmp(tsvalue(l), tsvalue(r)) < 0; + else + return luaT_callorderTM(L, l, r, TM_LT); +} + + +/* +** Main operation less than; return 'l < r'. +*/ +int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { + if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ + return LTnum(l, r); + else return lessthanothers(L, l, r); +} + + +/* +** return 'l <= r' for non-numbers. +*/ +static int lessequalothers (lua_State *L, const TValue *l, const TValue *r) { + lua_assert(!ttisnumber(l) || !ttisnumber(r)); + if (ttisstring(l) && ttisstring(r)) /* both are strings? */ + return l_strcmp(tsvalue(l), tsvalue(r)) <= 0; + else + return luaT_callorderTM(L, l, r, TM_LE); +} + + +/* +** Main operation less than or equal to; return 'l <= r'. +*/ +int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { + if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ + return LEnum(l, r); + else return lessequalothers(L, l, r); +} + + +/* +** Main operation for equality of Lua values; return 't1 == t2'. +** L == NULL means raw equality (no metamethods) +*/ +int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { + const TValue *tm; + if (ttypetag(t1) != ttypetag(t2)) { /* not the same variant? */ + if (ttype(t1) != ttype(t2) || ttype(t1) != LUA_TNUMBER) + return 0; /* only numbers can be equal with different variants */ + else { /* two numbers with different variants */ + /* One of them is an integer. If the other does not have an + integer value, they cannot be equal; otherwise, compare their + integer values. */ + lua_Integer i1, i2; + return (luaV_tointegerns(t1, &i1, F2Ieq) && + luaV_tointegerns(t2, &i2, F2Ieq) && + i1 == i2); + } + } + /* values have same type and same variant */ + switch (ttypetag(t1)) { + case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: return 1; + case LUA_VNUMINT: return (ivalue(t1) == ivalue(t2)); + case LUA_VNUMFLT: return luai_numeq(fltvalue(t1), fltvalue(t2)); + case LUA_VLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); + case LUA_VLCF: return fvalue(t1) == fvalue(t2); + case LUA_VSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2)); + case LUA_VLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2)); + case LUA_VUSERDATA: { + if (uvalue(t1) == uvalue(t2)) return 1; + else if (L == NULL) return 0; + tm = fasttm(L, uvalue(t1)->metatable, TM_EQ); + if (tm == NULL) + tm = fasttm(L, uvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + case LUA_VTABLE: { + if (hvalue(t1) == hvalue(t2)) return 1; + else if (L == NULL) return 0; + tm = fasttm(L, hvalue(t1)->metatable, TM_EQ); + if (tm == NULL) + tm = fasttm(L, hvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + default: + return gcvalue(t1) == gcvalue(t2); + } + if (tm == NULL) /* no TM? */ + return 0; /* objects are different */ + else { + luaT_callTMres(L, tm, t1, t2, L->top.p); /* call TM */ + return !l_isfalse(s2v(L->top.p)); + } +} + + +/* macro used by 'luaV_concat' to ensure that element at 'o' is a string */ +#define tostring(L,o) \ + (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1))) + +#define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0) + +/* copy strings in stack from top - n up to top - 1 to buffer */ +static void copy2buff (StkId top, int n, char *buff) { + size_t tl = 0; /* size already copied */ + do { + TString *st = tsvalue(s2v(top - n)); + size_t l = tsslen(st); /* length of string being copied */ + memcpy(buff + tl, getstr(st), l * sizeof(char)); + tl += l; + } while (--n > 0); +} + + +/* +** Main operation for concatenation: concat 'total' values in the stack, +** from 'L->top.p - total' up to 'L->top.p - 1'. +*/ +void luaV_concat (lua_State *L, int total) { + if (total == 1) + return; /* "all" values already concatenated */ + do { + StkId top = L->top.p; + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (!(ttisstring(s2v(top - 2)) || cvt2str(s2v(top - 2))) || + !tostring(L, s2v(top - 1))) + luaT_tryconcatTM(L); /* may invalidate 'top' */ + else if (isemptystr(s2v(top - 1))) /* second operand is empty? */ + cast_void(tostring(L, s2v(top - 2))); /* result is first operand */ + else if (isemptystr(s2v(top - 2))) { /* first operand is empty string? */ + setobjs2s(L, top - 2, top - 1); /* result is second op. */ + } + else { + /* at least two non-empty string values; get as many as possible */ + size_t tl = tsslen(tsvalue(s2v(top - 1))); + TString *ts; + /* collect total length and number of strings */ + for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { + size_t l = tsslen(tsvalue(s2v(top - n - 1))); + if (l_unlikely(l >= MAX_SIZE - sizeof(TString) - tl)) { + L->top.p = top - total; /* pop strings to avoid wasting stack */ + luaG_runerror(L, "string length overflow"); + } + tl += l; + } + if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ + char buff[LUAI_MAXSHORTLEN]; + copy2buff(top, n, buff); /* copy strings to buffer */ + ts = luaS_newlstr(L, buff, tl); + } + else { /* long string; copy strings directly to final result */ + ts = luaS_createlngstrobj(L, tl); + copy2buff(top, n, getlngstr(ts)); + } + setsvalue2s(L, top - n, ts); /* create result */ + } + total -= n - 1; /* got 'n' strings to create one new */ + L->top.p -= n - 1; /* popped 'n' strings and pushed one */ + } while (total > 1); /* repeat until only 1 result left */ +} + + +/* +** Main operation 'ra = #rb'. +*/ +void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { + const TValue *tm; + switch (ttypetag(rb)) { + case LUA_VTABLE: { + Table *h = hvalue(rb); + tm = fasttm(L, h->metatable, TM_LEN); + if (tm) break; /* metamethod? break switch to call it */ + setivalue(s2v(ra), luaH_getn(h)); /* else primitive len */ + return; + } + case LUA_VSHRSTR: { + setivalue(s2v(ra), tsvalue(rb)->shrlen); + return; + } + case LUA_VLNGSTR: { + setivalue(s2v(ra), tsvalue(rb)->u.lnglen); + return; + } + default: { /* try metamethod */ + tm = luaT_gettmbyobj(L, rb, TM_LEN); + if (l_unlikely(notm(tm))) /* no metamethod? */ + luaG_typeerror(L, rb, "get length of"); + break; + } + } + luaT_callTMres(L, tm, rb, rb, ra); +} + + +/* +** Integer division; return 'm // n', that is, floor(m/n). +** C division truncates its result (rounds towards zero). +** 'floor(q) == trunc(q)' when 'q >= 0' or when 'q' is integer, +** otherwise 'floor(q) == trunc(q) - 1'. +*/ +lua_Integer luaV_idiv (lua_State *L, lua_Integer m, lua_Integer n) { + if (l_unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ + if (n == 0) + luaG_runerror(L, "attempt to divide by zero"); + return intop(-, 0, m); /* n==-1; avoid overflow with 0x80000...//-1 */ + } + else { + lua_Integer q = m / n; /* perform C division */ + if ((m ^ n) < 0 && m % n != 0) /* 'm/n' would be negative non-integer? */ + q -= 1; /* correct result for different rounding */ + return q; + } +} + + +/* +** Integer modulus; return 'm % n'. (Assume that C '%' with +** negative operands follows C99 behavior. See previous comment +** about luaV_idiv.) +*/ +lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) { + if (l_unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ + if (n == 0) + luaG_runerror(L, "attempt to perform 'n%%0'"); + return 0; /* m % -1 == 0; avoid overflow with 0x80000...%-1 */ + } + else { + lua_Integer r = m % n; + if (r != 0 && (r ^ n) < 0) /* 'm/n' would be non-integer negative? */ + r += n; /* correct result for different rounding */ + return r; + } +} + + +/* +** Float modulus +*/ +lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) { + lua_Number r; + luai_nummod(L, m, n, r); + return r; +} + + +/* number of bits in an integer */ +#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT) + + +/* +** Shift left operation. (Shift right just negates 'y'.) +*/ +lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { + if (y < 0) { /* shift right? */ + if (y <= -NBITS) return 0; + else return intop(>>, x, -y); + } + else { /* shift left */ + if (y >= NBITS) return 0; + else return intop(<<, x, y); + } +} + + +/* +** create a new Lua closure, push it in the stack, and initialize +** its upvalues. +*/ +static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, + StkId ra) { + int nup = p->sizeupvalues; + Upvaldesc *uv = p->upvalues; + int i; + LClosure *ncl = luaF_newLclosure(L, nup); + ncl->p = p; + setclLvalue2s(L, ra, ncl); /* anchor new closure in stack */ + for (i = 0; i < nup; i++) { /* fill in its upvalues */ + if (uv[i].instack) /* upvalue refers to local variable? */ + ncl->upvals[i] = luaF_findupval(L, base + uv[i].idx); + else /* get upvalue from enclosing function */ + ncl->upvals[i] = encup[uv[i].idx]; + luaC_objbarrier(L, ncl, ncl->upvals[i]); + } +} + + +/* +** finish execution of an opcode interrupted by a yield +*/ +void luaV_finishOp (lua_State *L) { + CallInfo *ci = L->ci; + StkId base = ci->func.p + 1; + Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ + OpCode op = GET_OPCODE(inst); + switch (op) { /* finish its execution */ + case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { + setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top.p); + break; + } + case OP_UNM: case OP_BNOT: case OP_LEN: + case OP_GETTABUP: case OP_GETTABLE: case OP_GETI: + case OP_GETFIELD: case OP_SELF: { + setobjs2s(L, base + GETARG_A(inst), --L->top.p); + break; + } + case OP_LT: case OP_LE: + case OP_LTI: case OP_LEI: + case OP_GTI: case OP_GEI: + case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */ + int res = !l_isfalse(s2v(L->top.p - 1)); + L->top.p--; +#if defined(LUA_COMPAT_LT_LE) + if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ + ci->callstatus ^= CIST_LEQ; /* clear mark */ + res = !res; /* negate result */ + } +#endif + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); + if (res != GETARG_k(inst)) /* condition failed? */ + ci->u.l.savedpc++; /* skip jump instruction */ + break; + } + case OP_CONCAT: { + StkId top = L->top.p - 1; /* top when 'luaT_tryconcatTM' was called */ + int a = GETARG_A(inst); /* first element to concatenate */ + int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */ + setobjs2s(L, top - 2, top); /* put TM result in proper position */ + L->top.p = top - 1; /* top is one after last element (at top-2) */ + luaV_concat(L, total); /* concat them (may yield again) */ + break; + } + case OP_CLOSE: { /* yielded closing variables */ + ci->u.l.savedpc--; /* repeat instruction to close other vars. */ + break; + } + case OP_RETURN: { /* yielded closing variables */ + StkId ra = base + GETARG_A(inst); + /* adjust top to signal correct number of returns, in case the + return is "up to top" ('isIT') */ + L->top.p = ra + ci->u2.nres; + /* repeat instruction to close other vars. and complete the return */ + ci->u.l.savedpc--; + break; + } + default: { + /* only these other opcodes can yield */ + lua_assert(op == OP_TFORCALL || op == OP_CALL || + op == OP_TAILCALL || op == OP_SETTABUP || op == OP_SETTABLE || + op == OP_SETI || op == OP_SETFIELD); + break; + } + } +} + + + + +/* +** {================================================================== +** Macros for arithmetic/bitwise/comparison opcodes in 'luaV_execute' +** =================================================================== +*/ + +#define l_addi(L,a,b) intop(+, a, b) +#define l_subi(L,a,b) intop(-, a, b) +#define l_muli(L,a,b) intop(*, a, b) +#define l_band(a,b) intop(&, a, b) +#define l_bor(a,b) intop(|, a, b) +#define l_bxor(a,b) intop(^, a, b) + +#define l_lti(a,b) (a < b) +#define l_lei(a,b) (a <= b) +#define l_gti(a,b) (a > b) +#define l_gei(a,b) (a >= b) + + +/* +** Arithmetic operations with immediate operands. 'iop' is the integer +** operation, 'fop' is the float operation. +*/ +#define op_arithI(L,iop,fop) { \ + StkId ra = RA(i); \ + TValue *v1 = vRB(i); \ + int imm = GETARG_sC(i); \ + if (ttisinteger(v1)) { \ + lua_Integer iv1 = ivalue(v1); \ + pc++; setivalue(s2v(ra), iop(L, iv1, imm)); \ + } \ + else if (ttisfloat(v1)) { \ + lua_Number nb = fltvalue(v1); \ + lua_Number fimm = cast_num(imm); \ + pc++; setfltvalue(s2v(ra), fop(L, nb, fimm)); \ + }} + + +/* +** Auxiliary function for arithmetic operations over floats and others +** with two register operands. +*/ +#define op_arithf_aux(L,v1,v2,fop) { \ + lua_Number n1; lua_Number n2; \ + if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ + pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ + }} + + +/* +** Arithmetic operations over floats and others with register operands. +*/ +#define op_arithf(L,fop) { \ + StkId ra = RA(i); \ + TValue *v1 = vRB(i); \ + TValue *v2 = vRC(i); \ + op_arithf_aux(L, v1, v2, fop); } + + +/* +** Arithmetic operations with K operands for floats. +*/ +#define op_arithfK(L,fop) { \ + StkId ra = RA(i); \ + TValue *v1 = vRB(i); \ + TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \ + op_arithf_aux(L, v1, v2, fop); } + + +/* +** Arithmetic operations over integers and floats. +*/ +#define op_arith_aux(L,v1,v2,iop,fop) { \ + StkId ra = RA(i); \ + if (ttisinteger(v1) && ttisinteger(v2)) { \ + lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ + pc++; setivalue(s2v(ra), iop(L, i1, i2)); \ + } \ + else op_arithf_aux(L, v1, v2, fop); } + + +/* +** Arithmetic operations with register operands. +*/ +#define op_arith(L,iop,fop) { \ + TValue *v1 = vRB(i); \ + TValue *v2 = vRC(i); \ + op_arith_aux(L, v1, v2, iop, fop); } + + +/* +** Arithmetic operations with K operands. +*/ +#define op_arithK(L,iop,fop) { \ + TValue *v1 = vRB(i); \ + TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \ + op_arith_aux(L, v1, v2, iop, fop); } + + +/* +** Bitwise operations with constant operand. +*/ +#define op_bitwiseK(L,op) { \ + StkId ra = RA(i); \ + TValue *v1 = vRB(i); \ + TValue *v2 = KC(i); \ + lua_Integer i1; \ + lua_Integer i2 = ivalue(v2); \ + if (tointegerns(v1, &i1)) { \ + pc++; setivalue(s2v(ra), op(i1, i2)); \ + }} + + +/* +** Bitwise operations with register operands. +*/ +#define op_bitwise(L,op) { \ + StkId ra = RA(i); \ + TValue *v1 = vRB(i); \ + TValue *v2 = vRC(i); \ + lua_Integer i1; lua_Integer i2; \ + if (tointegerns(v1, &i1) && tointegerns(v2, &i2)) { \ + pc++; setivalue(s2v(ra), op(i1, i2)); \ + }} + + +/* +** Order operations with register operands. 'opn' actually works +** for all numbers, but the fast track improves performance for +** integers. +*/ +#define op_order(L,opi,opn,other) { \ + StkId ra = RA(i); \ + int cond; \ + TValue *rb = vRB(i); \ + if (ttisinteger(s2v(ra)) && ttisinteger(rb)) { \ + lua_Integer ia = ivalue(s2v(ra)); \ + lua_Integer ib = ivalue(rb); \ + cond = opi(ia, ib); \ + } \ + else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) \ + cond = opn(s2v(ra), rb); \ + else \ + Protect(cond = other(L, s2v(ra), rb)); \ + docondjump(); } + + +/* +** Order operations with immediate operand. (Immediate operand is +** always small enough to have an exact representation as a float.) +*/ +#define op_orderI(L,opi,opf,inv,tm) { \ + StkId ra = RA(i); \ + int cond; \ + int im = GETARG_sB(i); \ + if (ttisinteger(s2v(ra))) \ + cond = opi(ivalue(s2v(ra)), im); \ + else if (ttisfloat(s2v(ra))) { \ + lua_Number fa = fltvalue(s2v(ra)); \ + lua_Number fim = cast_num(im); \ + cond = opf(fa, fim); \ + } \ + else { \ + int isf = GETARG_C(i); \ + Protect(cond = luaT_callorderiTM(L, s2v(ra), im, inv, isf, tm)); \ + } \ + docondjump(); } + +/* }================================================================== */ + + +/* +** {================================================================== +** Function 'luaV_execute': main interpreter loop +** =================================================================== +*/ + +/* +** some macros for common tasks in 'luaV_execute' +*/ + + +#define RA(i) (base+GETARG_A(i)) +#define RB(i) (base+GETARG_B(i)) +#define vRB(i) s2v(RB(i)) +#define KB(i) (k+GETARG_B(i)) +#define RC(i) (base+GETARG_C(i)) +#define vRC(i) s2v(RC(i)) +#define KC(i) (k+GETARG_C(i)) +#define RKC(i) ((TESTARG_k(i)) ? k + GETARG_C(i) : s2v(base + GETARG_C(i))) + + + +#define updatetrap(ci) (trap = ci->u.l.trap) + +#define updatebase(ci) (base = ci->func.p + 1) + + +#define updatestack(ci) \ + { if (l_unlikely(trap)) { updatebase(ci); ra = RA(i); } } + + +/* +** Execute a jump instruction. The 'updatetrap' allows signals to stop +** tight loops. (Without it, the local copy of 'trap' could never change.) +*/ +#define dojump(ci,i,e) { pc += GETARG_sJ(i) + e; updatetrap(ci); } + + +/* for test instructions, execute the jump instruction that follows it */ +#define donextjump(ci) { Instruction ni = *pc; dojump(ci, ni, 1); } + +/* +** do a conditional jump: skip next instruction if 'cond' is not what +** was expected (parameter 'k'), else do next instruction, which must +** be a jump. +*/ +#define docondjump() if (cond != GETARG_k(i)) pc++; else donextjump(ci); + + +/* +** Correct global 'pc'. +*/ +#define savepc(L) (ci->u.l.savedpc = pc) + + +/* +** Whenever code can raise errors, the global 'pc' and the global +** 'top' must be correct to report occasional errors. +*/ +#define savestate(L,ci) (savepc(L), L->top.p = ci->top.p) + + +/* +** Protect code that, in general, can raise errors, reallocate the +** stack, and change the hooks. +*/ +#define Protect(exp) (savestate(L,ci), (exp), updatetrap(ci)) + +/* special version that does not change the top */ +#define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci)) + +/* +** Protect code that can only raise errors. (That is, it cannot change +** the stack or hooks.) +*/ +#define halfProtect(exp) (savestate(L,ci), (exp)) + +/* 'c' is the limit of live values in the stack */ +#define checkGC(L,c) \ + { luaC_condGC(L, (savepc(L), L->top.p = (c)), \ + updatetrap(ci)); \ + luai_threadyield(L); } + + +/* fetch an instruction and prepare its execution */ +#define vmfetch() { \ + if (l_unlikely(trap)) { /* stack reallocation or hooks? */ \ + trap = luaG_traceexec(L, pc); /* handle hooks */ \ + updatebase(ci); /* correct stack */ \ + } \ + i = *(pc++); \ +} + +#define vmdispatch(o) switch(o) +#define vmcase(l) case l: +#define vmbreak break + + +void luaV_execute (lua_State *L, CallInfo *ci) { + LClosure *cl; + TValue *k; + StkId base; + const Instruction *pc; + int trap; +#if LUA_USE_JUMPTABLE +#include "ljumptab.h" +#endif + startfunc: + trap = L->hookmask; + returning: /* trap already set */ + cl = ci_func(ci); + k = cl->p->k; + pc = ci->u.l.savedpc; + if (l_unlikely(trap)) + trap = luaG_tracecall(L); + base = ci->func.p + 1; + /* main loop of interpreter */ + for (;;) { + Instruction i; /* instruction being executed */ + vmfetch(); + #if 0 + /* low-level line tracing for debugging Lua */ + printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p))); + #endif + lua_assert(base == ci->func.p + 1); + lua_assert(base <= L->top.p && L->top.p <= L->stack_last.p); + /* invalidate top for instructions not expecting it */ + lua_assert(isIT(i) || (cast_void(L->top.p = base), 1)); + vmdispatch (GET_OPCODE(i)) { + vmcase(OP_MOVE) { + StkId ra = RA(i); + setobjs2s(L, ra, RB(i)); + vmbreak; + } + vmcase(OP_LOADI) { + StkId ra = RA(i); + lua_Integer b = GETARG_sBx(i); + setivalue(s2v(ra), b); + vmbreak; + } + vmcase(OP_LOADF) { + StkId ra = RA(i); + int b = GETARG_sBx(i); + setfltvalue(s2v(ra), cast_num(b)); + vmbreak; + } + vmcase(OP_LOADK) { + StkId ra = RA(i); + TValue *rb = k + GETARG_Bx(i); + setobj2s(L, ra, rb); + vmbreak; + } + vmcase(OP_LOADKX) { + StkId ra = RA(i); + TValue *rb; + rb = k + GETARG_Ax(*pc); pc++; + setobj2s(L, ra, rb); + vmbreak; + } + vmcase(OP_LOADFALSE) { + StkId ra = RA(i); + setbfvalue(s2v(ra)); + vmbreak; + } + vmcase(OP_LFALSESKIP) { + StkId ra = RA(i); + setbfvalue(s2v(ra)); + pc++; /* skip next instruction */ + vmbreak; + } + vmcase(OP_LOADTRUE) { + StkId ra = RA(i); + setbtvalue(s2v(ra)); + vmbreak; + } + vmcase(OP_LOADNIL) { + StkId ra = RA(i); + int b = GETARG_B(i); + do { + setnilvalue(s2v(ra++)); + } while (b--); + vmbreak; + } + vmcase(OP_GETUPVAL) { + StkId ra = RA(i); + int b = GETARG_B(i); + setobj2s(L, ra, cl->upvals[b]->v.p); + vmbreak; + } + vmcase(OP_SETUPVAL) { + StkId ra = RA(i); + UpVal *uv = cl->upvals[GETARG_B(i)]; + setobj(L, uv->v.p, s2v(ra)); + luaC_barrier(L, uv, s2v(ra)); + vmbreak; + } + vmcase(OP_GETTABUP) { + StkId ra = RA(i); + const TValue *slot; + TValue *upval = cl->upvals[GETARG_B(i)]->v.p; + TValue *rc = KC(i); + TString *key = tsvalue(rc); /* key must be a short string */ + if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { + setobj2s(L, ra, slot); + } + else + Protect(luaV_finishget(L, upval, rc, ra, slot)); + vmbreak; + } + vmcase(OP_GETTABLE) { + StkId ra = RA(i); + const TValue *slot; + TValue *rb = vRB(i); + TValue *rc = vRC(i); + lua_Unsigned n; + if (ttisinteger(rc) /* fast track for integers? */ + ? (cast_void(n = ivalue(rc)), luaV_fastgeti(L, rb, n, slot)) + : luaV_fastget(L, rb, rc, slot, luaH_get)) { + setobj2s(L, ra, slot); + } + else + Protect(luaV_finishget(L, rb, rc, ra, slot)); + vmbreak; + } + vmcase(OP_GETI) { + StkId ra = RA(i); + const TValue *slot; + TValue *rb = vRB(i); + int c = GETARG_C(i); + if (luaV_fastgeti(L, rb, c, slot)) { + setobj2s(L, ra, slot); + } + else { + TValue key; + setivalue(&key, c); + Protect(luaV_finishget(L, rb, &key, ra, slot)); + } + vmbreak; + } + vmcase(OP_GETFIELD) { + StkId ra = RA(i); + const TValue *slot; + TValue *rb = vRB(i); + TValue *rc = KC(i); + TString *key = tsvalue(rc); /* key must be a short string */ + if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { + setobj2s(L, ra, slot); + } + else + Protect(luaV_finishget(L, rb, rc, ra, slot)); + vmbreak; + } + vmcase(OP_SETTABUP) { + const TValue *slot; + TValue *upval = cl->upvals[GETARG_A(i)]->v.p; + TValue *rb = KB(i); + TValue *rc = RKC(i); + TString *key = tsvalue(rb); /* key must be a short string */ + if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { + luaV_finishfastset(L, upval, slot, rc); + } + else + Protect(luaV_finishset(L, upval, rb, rc, slot)); + vmbreak; + } + vmcase(OP_SETTABLE) { + StkId ra = RA(i); + const TValue *slot; + TValue *rb = vRB(i); /* key (table is in 'ra') */ + TValue *rc = RKC(i); /* value */ + lua_Unsigned n; + if (ttisinteger(rb) /* fast track for integers? */ + ? (cast_void(n = ivalue(rb)), luaV_fastgeti(L, s2v(ra), n, slot)) + : luaV_fastget(L, s2v(ra), rb, slot, luaH_get)) { + luaV_finishfastset(L, s2v(ra), slot, rc); + } + else + Protect(luaV_finishset(L, s2v(ra), rb, rc, slot)); + vmbreak; + } + vmcase(OP_SETI) { + StkId ra = RA(i); + const TValue *slot; + int c = GETARG_B(i); + TValue *rc = RKC(i); + if (luaV_fastgeti(L, s2v(ra), c, slot)) { + luaV_finishfastset(L, s2v(ra), slot, rc); + } + else { + TValue key; + setivalue(&key, c); + Protect(luaV_finishset(L, s2v(ra), &key, rc, slot)); + } + vmbreak; + } + vmcase(OP_SETFIELD) { + StkId ra = RA(i); + const TValue *slot; + TValue *rb = KB(i); + TValue *rc = RKC(i); + TString *key = tsvalue(rb); /* key must be a short string */ + if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) { + luaV_finishfastset(L, s2v(ra), slot, rc); + } + else + Protect(luaV_finishset(L, s2v(ra), rb, rc, slot)); + vmbreak; + } + vmcase(OP_NEWTABLE) { + StkId ra = RA(i); + int b = GETARG_B(i); /* log2(hash size) + 1 */ + int c = GETARG_C(i); /* array size */ + Table *t; + if (b > 0) + b = 1 << (b - 1); /* size is 2^(b - 1) */ + lua_assert((!TESTARG_k(i)) == (GETARG_Ax(*pc) == 0)); + if (TESTARG_k(i)) /* non-zero extra argument? */ + c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */ + pc++; /* skip extra argument */ + L->top.p = ra + 1; /* correct top in case of emergency GC */ + t = luaH_new(L); /* memory allocation */ + sethvalue2s(L, ra, t); + if (b != 0 || c != 0) + luaH_resize(L, t, c, b); /* idem */ + checkGC(L, ra + 1); + vmbreak; + } + vmcase(OP_SELF) { + StkId ra = RA(i); + const TValue *slot; + TValue *rb = vRB(i); + TValue *rc = RKC(i); + TString *key = tsvalue(rc); /* key must be a string */ + setobj2s(L, ra + 1, rb); + if (luaV_fastget(L, rb, key, slot, luaH_getstr)) { + setobj2s(L, ra, slot); + } + else + Protect(luaV_finishget(L, rb, rc, ra, slot)); + vmbreak; + } + vmcase(OP_ADDI) { + op_arithI(L, l_addi, luai_numadd); + vmbreak; + } + vmcase(OP_ADDK) { + op_arithK(L, l_addi, luai_numadd); + vmbreak; + } + vmcase(OP_SUBK) { + op_arithK(L, l_subi, luai_numsub); + vmbreak; + } + vmcase(OP_MULK) { + op_arithK(L, l_muli, luai_nummul); + vmbreak; + } + vmcase(OP_MODK) { + savestate(L, ci); /* in case of division by 0 */ + op_arithK(L, luaV_mod, luaV_modf); + vmbreak; + } + vmcase(OP_POWK) { + op_arithfK(L, luai_numpow); + vmbreak; + } + vmcase(OP_DIVK) { + op_arithfK(L, luai_numdiv); + vmbreak; + } + vmcase(OP_IDIVK) { + savestate(L, ci); /* in case of division by 0 */ + op_arithK(L, luaV_idiv, luai_numidiv); + vmbreak; + } + vmcase(OP_BANDK) { + op_bitwiseK(L, l_band); + vmbreak; + } + vmcase(OP_BORK) { + op_bitwiseK(L, l_bor); + vmbreak; + } + vmcase(OP_BXORK) { + op_bitwiseK(L, l_bxor); + vmbreak; + } + vmcase(OP_SHRI) { + StkId ra = RA(i); + TValue *rb = vRB(i); + int ic = GETARG_sC(i); + lua_Integer ib; + if (tointegerns(rb, &ib)) { + pc++; setivalue(s2v(ra), luaV_shiftl(ib, -ic)); + } + vmbreak; + } + vmcase(OP_SHLI) { + StkId ra = RA(i); + TValue *rb = vRB(i); + int ic = GETARG_sC(i); + lua_Integer ib; + if (tointegerns(rb, &ib)) { + pc++; setivalue(s2v(ra), luaV_shiftl(ic, ib)); + } + vmbreak; + } + vmcase(OP_ADD) { + op_arith(L, l_addi, luai_numadd); + vmbreak; + } + vmcase(OP_SUB) { + op_arith(L, l_subi, luai_numsub); + vmbreak; + } + vmcase(OP_MUL) { + op_arith(L, l_muli, luai_nummul); + vmbreak; + } + vmcase(OP_MOD) { + savestate(L, ci); /* in case of division by 0 */ + op_arith(L, luaV_mod, luaV_modf); + vmbreak; + } + vmcase(OP_POW) { + op_arithf(L, luai_numpow); + vmbreak; + } + vmcase(OP_DIV) { /* float division (always with floats) */ + op_arithf(L, luai_numdiv); + vmbreak; + } + vmcase(OP_IDIV) { /* floor division */ + savestate(L, ci); /* in case of division by 0 */ + op_arith(L, luaV_idiv, luai_numidiv); + vmbreak; + } + vmcase(OP_BAND) { + op_bitwise(L, l_band); + vmbreak; + } + vmcase(OP_BOR) { + op_bitwise(L, l_bor); + vmbreak; + } + vmcase(OP_BXOR) { + op_bitwise(L, l_bxor); + vmbreak; + } + vmcase(OP_SHR) { + op_bitwise(L, luaV_shiftr); + vmbreak; + } + vmcase(OP_SHL) { + op_bitwise(L, luaV_shiftl); + vmbreak; + } + vmcase(OP_MMBIN) { + StkId ra = RA(i); + Instruction pi = *(pc - 2); /* original arith. expression */ + TValue *rb = vRB(i); + TMS tm = (TMS)GETARG_C(i); + StkId result = RA(pi); + lua_assert(OP_ADD <= GET_OPCODE(pi) && GET_OPCODE(pi) <= OP_SHR); + Protect(luaT_trybinTM(L, s2v(ra), rb, result, tm)); + vmbreak; + } + vmcase(OP_MMBINI) { + StkId ra = RA(i); + Instruction pi = *(pc - 2); /* original arith. expression */ + int imm = GETARG_sB(i); + TMS tm = (TMS)GETARG_C(i); + int flip = GETARG_k(i); + StkId result = RA(pi); + Protect(luaT_trybiniTM(L, s2v(ra), imm, flip, result, tm)); + vmbreak; + } + vmcase(OP_MMBINK) { + StkId ra = RA(i); + Instruction pi = *(pc - 2); /* original arith. expression */ + TValue *imm = KB(i); + TMS tm = (TMS)GETARG_C(i); + int flip = GETARG_k(i); + StkId result = RA(pi); + Protect(luaT_trybinassocTM(L, s2v(ra), imm, flip, result, tm)); + vmbreak; + } + vmcase(OP_UNM) { + StkId ra = RA(i); + TValue *rb = vRB(i); + lua_Number nb; + if (ttisinteger(rb)) { + lua_Integer ib = ivalue(rb); + setivalue(s2v(ra), intop(-, 0, ib)); + } + else if (tonumberns(rb, nb)) { + setfltvalue(s2v(ra), luai_numunm(L, nb)); + } + else + Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); + vmbreak; + } + vmcase(OP_BNOT) { + StkId ra = RA(i); + TValue *rb = vRB(i); + lua_Integer ib; + if (tointegerns(rb, &ib)) { + setivalue(s2v(ra), intop(^, ~l_castS2U(0), ib)); + } + else + Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT)); + vmbreak; + } + vmcase(OP_NOT) { + StkId ra = RA(i); + TValue *rb = vRB(i); + if (l_isfalse(rb)) + setbtvalue(s2v(ra)); + else + setbfvalue(s2v(ra)); + vmbreak; + } + vmcase(OP_LEN) { + StkId ra = RA(i); + Protect(luaV_objlen(L, ra, vRB(i))); + vmbreak; + } + vmcase(OP_CONCAT) { + StkId ra = RA(i); + int n = GETARG_B(i); /* number of elements to concatenate */ + L->top.p = ra + n; /* mark the end of concat operands */ + ProtectNT(luaV_concat(L, n)); + checkGC(L, L->top.p); /* 'luaV_concat' ensures correct top */ + vmbreak; + } + vmcase(OP_CLOSE) { + StkId ra = RA(i); + Protect(luaF_close(L, ra, LUA_OK, 1)); + vmbreak; + } + vmcase(OP_TBC) { + StkId ra = RA(i); + /* create new to-be-closed upvalue */ + halfProtect(luaF_newtbcupval(L, ra)); + vmbreak; + } + vmcase(OP_JMP) { + dojump(ci, i, 0); + vmbreak; + } + vmcase(OP_EQ) { + StkId ra = RA(i); + int cond; + TValue *rb = vRB(i); + Protect(cond = luaV_equalobj(L, s2v(ra), rb)); + docondjump(); + vmbreak; + } + vmcase(OP_LT) { + op_order(L, l_lti, LTnum, lessthanothers); + vmbreak; + } + vmcase(OP_LE) { + op_order(L, l_lei, LEnum, lessequalothers); + vmbreak; + } + vmcase(OP_EQK) { + StkId ra = RA(i); + TValue *rb = KB(i); + /* basic types do not use '__eq'; we can use raw equality */ + int cond = luaV_rawequalobj(s2v(ra), rb); + docondjump(); + vmbreak; + } + vmcase(OP_EQI) { + StkId ra = RA(i); + int cond; + int im = GETARG_sB(i); + if (ttisinteger(s2v(ra))) + cond = (ivalue(s2v(ra)) == im); + else if (ttisfloat(s2v(ra))) + cond = luai_numeq(fltvalue(s2v(ra)), cast_num(im)); + else + cond = 0; /* other types cannot be equal to a number */ + docondjump(); + vmbreak; + } + vmcase(OP_LTI) { + op_orderI(L, l_lti, luai_numlt, 0, TM_LT); + vmbreak; + } + vmcase(OP_LEI) { + op_orderI(L, l_lei, luai_numle, 0, TM_LE); + vmbreak; + } + vmcase(OP_GTI) { + op_orderI(L, l_gti, luai_numgt, 1, TM_LT); + vmbreak; + } + vmcase(OP_GEI) { + op_orderI(L, l_gei, luai_numge, 1, TM_LE); + vmbreak; + } + vmcase(OP_TEST) { + StkId ra = RA(i); + int cond = !l_isfalse(s2v(ra)); + docondjump(); + vmbreak; + } + vmcase(OP_TESTSET) { + StkId ra = RA(i); + TValue *rb = vRB(i); + if (l_isfalse(rb) == GETARG_k(i)) + pc++; + else { + setobj2s(L, ra, rb); + donextjump(ci); + } + vmbreak; + } + vmcase(OP_CALL) { + StkId ra = RA(i); + CallInfo *newci; + int b = GETARG_B(i); + int nresults = GETARG_C(i) - 1; + if (b != 0) /* fixed number of arguments? */ + L->top.p = ra + b; /* top signals number of arguments */ + /* else previous instruction set top */ + savepc(L); /* in case of errors */ + if ((newci = luaD_precall(L, ra, nresults)) == NULL) + updatetrap(ci); /* C call; nothing else to be done */ + else { /* Lua call: run function in this same C frame */ + ci = newci; + goto startfunc; + } + vmbreak; + } + vmcase(OP_TAILCALL) { + StkId ra = RA(i); + int b = GETARG_B(i); /* number of arguments + 1 (function) */ + int n; /* number of results when calling a C function */ + int nparams1 = GETARG_C(i); + /* delta is virtual 'func' - real 'func' (vararg functions) */ + int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; + if (b != 0) + L->top.p = ra + b; + else /* previous instruction set top */ + b = cast_int(L->top.p - ra); + savepc(ci); /* several calls here can raise errors */ + if (TESTARG_k(i)) { + luaF_closeupval(L, base); /* close upvalues from current call */ + lua_assert(L->tbclist.p < base); /* no pending tbc variables */ + lua_assert(base == ci->func.p + 1); + } + if ((n = luaD_pretailcall(L, ci, ra, b, delta)) < 0) /* Lua function? */ + goto startfunc; /* execute the callee */ + else { /* C function? */ + ci->func.p -= delta; /* restore 'func' (if vararg) */ + luaD_poscall(L, ci, n); /* finish caller */ + updatetrap(ci); /* 'luaD_poscall' can change hooks */ + goto ret; /* caller returns after the tail call */ + } + } + vmcase(OP_RETURN) { + StkId ra = RA(i); + int n = GETARG_B(i) - 1; /* number of results */ + int nparams1 = GETARG_C(i); + if (n < 0) /* not fixed? */ + n = cast_int(L->top.p - ra); /* get what is available */ + savepc(ci); + if (TESTARG_k(i)) { /* may there be open upvalues? */ + ci->u2.nres = n; /* save number of returns */ + if (L->top.p < ci->top.p) + L->top.p = ci->top.p; + luaF_close(L, base, CLOSEKTOP, 1); + updatetrap(ci); + updatestack(ci); + } + if (nparams1) /* vararg function? */ + ci->func.p -= ci->u.l.nextraargs + nparams1; + L->top.p = ra + n; /* set call for 'luaD_poscall' */ + luaD_poscall(L, ci, n); + updatetrap(ci); /* 'luaD_poscall' can change hooks */ + goto ret; + } + vmcase(OP_RETURN0) { + if (l_unlikely(L->hookmask)) { + StkId ra = RA(i); + L->top.p = ra; + savepc(ci); + luaD_poscall(L, ci, 0); /* no hurry... */ + trap = 1; + } + else { /* do the 'poscall' here */ + int nres; + L->ci = ci->previous; /* back to caller */ + L->top.p = base - 1; + for (nres = ci->nresults; l_unlikely(nres > 0); nres--) + setnilvalue(s2v(L->top.p++)); /* all results are nil */ + } + goto ret; + } + vmcase(OP_RETURN1) { + if (l_unlikely(L->hookmask)) { + StkId ra = RA(i); + L->top.p = ra + 1; + savepc(ci); + luaD_poscall(L, ci, 1); /* no hurry... */ + trap = 1; + } + else { /* do the 'poscall' here */ + int nres = ci->nresults; + L->ci = ci->previous; /* back to caller */ + if (nres == 0) + L->top.p = base - 1; /* asked for no results */ + else { + StkId ra = RA(i); + setobjs2s(L, base - 1, ra); /* at least this result */ + L->top.p = base; + for (; l_unlikely(nres > 1); nres--) + setnilvalue(s2v(L->top.p++)); /* complete missing results */ + } + } + ret: /* return from a Lua function */ + if (ci->callstatus & CIST_FRESH) + return; /* end this frame */ + else { + ci = ci->previous; + goto returning; /* continue running caller in this frame */ + } + } + vmcase(OP_FORLOOP) { + StkId ra = RA(i); + if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ + lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1))); + if (count > 0) { /* still more iterations? */ + lua_Integer step = ivalue(s2v(ra + 2)); + lua_Integer idx = ivalue(s2v(ra)); /* internal index */ + chgivalue(s2v(ra + 1), count - 1); /* update counter */ + idx = intop(+, idx, step); /* add step to index */ + chgivalue(s2v(ra), idx); /* update internal index */ + setivalue(s2v(ra + 3), idx); /* and control variable */ + pc -= GETARG_Bx(i); /* jump back */ + } + } + else if (floatforloop(ra)) /* float loop */ + pc -= GETARG_Bx(i); /* jump back */ + updatetrap(ci); /* allows a signal to break the loop */ + vmbreak; + } + vmcase(OP_FORPREP) { + StkId ra = RA(i); + savestate(L, ci); /* in case of errors */ + if (forprep(L, ra)) + pc += GETARG_Bx(i) + 1; /* skip the loop */ + vmbreak; + } + vmcase(OP_TFORPREP) { + StkId ra = RA(i); + /* create to-be-closed upvalue (if needed) */ + halfProtect(luaF_newtbcupval(L, ra + 3)); + pc += GETARG_Bx(i); + i = *(pc++); /* go to next instruction */ + lua_assert(GET_OPCODE(i) == OP_TFORCALL && ra == RA(i)); + goto l_tforcall; + } + vmcase(OP_TFORCALL) { + l_tforcall: { + StkId ra = RA(i); + /* 'ra' has the iterator function, 'ra + 1' has the state, + 'ra + 2' has the control variable, and 'ra + 3' has the + to-be-closed variable. The call will use the stack after + these values (starting at 'ra + 4') + */ + /* push function, state, and control variable */ + memcpy(ra + 4, ra, 3 * sizeof(*ra)); + L->top.p = ra + 4 + 3; + ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ + updatestack(ci); /* stack may have changed */ + i = *(pc++); /* go to next instruction */ + lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); + goto l_tforloop; + }} + vmcase(OP_TFORLOOP) { + l_tforloop: { + StkId ra = RA(i); + if (!ttisnil(s2v(ra + 4))) { /* continue loop? */ + setobjs2s(L, ra + 2, ra + 4); /* save control variable */ + pc -= GETARG_Bx(i); /* jump back */ + } + vmbreak; + }} + vmcase(OP_SETLIST) { + StkId ra = RA(i); + int n = GETARG_B(i); + unsigned int last = GETARG_C(i); + Table *h = hvalue(s2v(ra)); + if (n == 0) + n = cast_int(L->top.p - ra) - 1; /* get up to the top */ + else + L->top.p = ci->top.p; /* correct top in case of emergency GC */ + last += n; + if (TESTARG_k(i)) { + last += GETARG_Ax(*pc) * (MAXARG_C + 1); + pc++; + } + if (last > luaH_realasize(h)) /* needs more space? */ + luaH_resizearray(L, h, last); /* preallocate it at once */ + for (; n > 0; n--) { + TValue *val = s2v(ra + n); + setobj2t(L, &h->array[last - 1], val); + last--; + luaC_barrierback(L, obj2gco(h), val); + } + vmbreak; + } + vmcase(OP_CLOSURE) { + StkId ra = RA(i); + Proto *p = cl->p->p[GETARG_Bx(i)]; + halfProtect(pushclosure(L, p, cl->upvals, base, ra)); + checkGC(L, ra + 1); + vmbreak; + } + vmcase(OP_VARARG) { + StkId ra = RA(i); + int n = GETARG_C(i) - 1; /* required results */ + Protect(luaT_getvarargs(L, ci, ra, n)); + vmbreak; + } + vmcase(OP_VARARGPREP) { + ProtectNT(luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p)); + if (l_unlikely(trap)) { /* previous "Protect" updated trap */ + luaD_hookcall(L, ci); + L->oldpc = 1; /* next opcode will be seen as a "new" line */ + } + updatebase(ci); /* function has new base after adjustment */ + vmbreak; + } + vmcase(OP_EXTRAARG) { + lua_assert(0); + vmbreak; + } + } + } +} + +/* }================================================================== */ diff --git a/User/system/lua/src/lvm.h b/User/system/lua/src/lvm.h new file mode 100644 index 0000000..dba1ad2 --- /dev/null +++ b/User/system/lua/src/lvm.h @@ -0,0 +1,141 @@ +/* +** $Id: lvm.h $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lvm_h +#define lvm_h + + +#include "ldo.h" +#include "lobject.h" +#include "ltm.h" + + +#if !defined(LUA_NOCVTN2S) +#define cvt2str(o) ttisnumber(o) +#else +#define cvt2str(o) 0 /* no conversion from numbers to strings */ +#endif + + +#if !defined(LUA_NOCVTS2N) +#define cvt2num(o) ttisstring(o) +#else +#define cvt2num(o) 0 /* no conversion from strings to numbers */ +#endif + + +/* +** You can define LUA_FLOORN2I if you want to convert floats to integers +** by flooring them (instead of raising an error if they are not +** integral values) +*/ +#if !defined(LUA_FLOORN2I) +#define LUA_FLOORN2I F2Ieq +#endif + + +/* +** Rounding modes for float->integer coercion + */ +typedef enum { + F2Ieq, /* no rounding; accepts only integral values */ + F2Ifloor, /* takes the floor of the number */ + F2Iceil /* takes the ceil of the number */ +} F2Imod; + + +/* convert an object to a float (including string coercion) */ +#define tonumber(o,n) \ + (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) + + +/* convert an object to a float (without string coercion) */ +#define tonumberns(o,n) \ + (ttisfloat(o) ? ((n) = fltvalue(o), 1) : \ + (ttisinteger(o) ? ((n) = cast_num(ivalue(o)), 1) : 0)) + + +/* convert an object to an integer (including string coercion) */ +#define tointeger(o,i) \ + (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ + : luaV_tointeger(o,i,LUA_FLOORN2I)) + + +/* convert an object to an integer (without string coercion) */ +#define tointegerns(o,i) \ + (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ + : luaV_tointegerns(o,i,LUA_FLOORN2I)) + + +#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) + +#define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) + + +/* +** fast track for 'gettable': if 't' is a table and 't[k]' is present, +** return 1 with 'slot' pointing to 't[k]' (position of final result). +** Otherwise, return 0 (meaning it will have to check metamethod) +** with 'slot' pointing to an empty 't[k]' (if 't' is a table) or NULL +** (otherwise). 'f' is the raw get function to use. +*/ +#define luaV_fastget(L,t,k,slot,f) \ + (!ttistable(t) \ + ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ + : (slot = f(hvalue(t), k), /* else, do raw access */ \ + !isempty(slot))) /* result not empty? */ + + +/* +** Special case of 'luaV_fastget' for integers, inlining the fast case +** of 'luaH_getint'. +*/ +#define luaV_fastgeti(L,t,k,slot) \ + (!ttistable(t) \ + ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ + : (slot = (l_castS2U(k) - 1u < hvalue(t)->alimit) \ + ? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \ + !isempty(slot))) /* result not empty? */ + + +/* +** Finish a fast set operation (when fast get succeeds). In that case, +** 'slot' points to the place to put the value. +*/ +#define luaV_finishfastset(L,t,slot,v) \ + { setobj2t(L, cast(TValue *,slot), v); \ + luaC_barrierback(L, gcvalue(t), v); } + + +/* +** Shift right is the same as shift left with a negative 'y' +*/ +#define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y)) + + + +LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); +LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); +LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode); +LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, + F2Imod mode); +LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); +LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, + StkId val, const TValue *slot); +LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, + TValue *val, const TValue *slot); +LUAI_FUNC void luaV_finishOp (lua_State *L); +LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); +LUAI_FUNC void luaV_concat (lua_State *L, int total); +LUAI_FUNC lua_Integer luaV_idiv (lua_State *L, lua_Integer x, lua_Integer y); +LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); +LUAI_FUNC lua_Number luaV_modf (lua_State *L, lua_Number x, lua_Number y); +LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); +LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); + +#endif diff --git a/User/system/lua/src/lzio.c b/User/system/lua/src/lzio.c new file mode 100644 index 0000000..cd0a02d --- /dev/null +++ b/User/system/lua/src/lzio.c @@ -0,0 +1,68 @@ +/* +** $Id: lzio.c $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + +#define lzio_c +#define LUA_CORE + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "llimits.h" +#include "lmem.h" +#include "lstate.h" +#include "lzio.h" + + +int luaZ_fill (ZIO *z) { + size_t size; + lua_State *L = z->L; + const char *buff; + lua_unlock(L); + buff = z->reader(L, z->data, &size); + lua_lock(L); + if (buff == NULL || size == 0) + return EOZ; + z->n = size - 1; /* discount char being returned */ + z->p = buff; + return cast_uchar(*(z->p++)); +} + + +void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { + z->L = L; + z->reader = reader; + z->data = data; + z->n = 0; + z->p = NULL; +} + + +/* --------------------------------------------------------------- read --- */ +size_t luaZ_read (ZIO *z, void *b, size_t n) { + while (n) { + size_t m; + if (z->n == 0) { /* no bytes in buffer? */ + if (luaZ_fill(z) == EOZ) /* try to read more */ + return n; /* no more input; return number of missing bytes */ + else { + z->n++; /* luaZ_fill consumed first byte; put it back */ + z->p--; + } + } + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} + diff --git a/User/system/lua/src/lzio.h b/User/system/lua/src/lzio.h new file mode 100644 index 0000000..38f397f --- /dev/null +++ b/User/system/lua/src/lzio.h @@ -0,0 +1,66 @@ +/* +** $Id: lzio.h $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#ifndef lzio_h +#define lzio_h + +#include "lua.h" + +#include "lmem.h" + + +#define EOZ (-1) /* end of stream */ + +typedef struct Zio ZIO; + +#define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) + + +typedef struct Mbuffer { + char *buffer; + size_t n; + size_t buffsize; +} Mbuffer; + +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) + +#define luaZ_buffer(buff) ((buff)->buffer) +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_bufflen(buff) ((buff)->n) + +#define luaZ_buffremove(buff,i) ((buff)->n -= (i)) +#define luaZ_resetbuffer(buff) ((buff)->n = 0) + + +#define luaZ_resizebuffer(L, buff, size) \ + ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ + (buff)->buffsize, size), \ + (buff)->buffsize = size) + +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) + + +LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, + void *data); +LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ + + + +/* --------- Private Part ------------------ */ + +struct Zio { + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ + lua_Reader reader; /* reader function */ + void *data; /* additional data */ + lua_State *L; /* Lua state (for reader) */ +}; + + +LUAI_FUNC int luaZ_fill (ZIO *z); + +#endif diff --git a/freertos_f407.ioc b/freertos_f407.ioc index 264ced4..38da243 100644 --- a/freertos_f407.ioc +++ b/freertos_f407.ioc @@ -123,6 +123,7 @@ NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false NVIC.TIM6_DAC_IRQn=true\:4\:0\:true\:false\:true\:false\:false\:true\:true NVIC.TimeBase=TIM6_DAC_IRQn NVIC.TimeBaseIP=TIM6 +NVIC.USART1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false PA10.Mode=Asynchronous PA10.Signal=USART1_RX @@ -226,7 +227,7 @@ ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_RTC_Init-RTC-false-HAL-true,5-MX_SDIO_SD_Init-SDIO-false-HAL-true,6-MX_FATFS_Init-FATFS-false-HAL-false,7-MX_USART1_UART_Init-USART1-false-HAL-true,8-MX_SPI3_Init-SPI3-false-HAL-true,9-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_RTC_Init-RTC-false-HAL-true,5-MX_SDIO_SD_Init-SDIO-false-HAL-true,6-MX_FATFS_Init-FATFS-false-HAL-false,7-MX_USART1_UART_Init-USART1-false-HAL-true,8-MX_SPI3_Init-SPI3-false-HAL-true,9-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false RCC.48MHZClocksFreq_Value=48000000 RCC.AHBFreq_Value=168000000 RCC.APB1CLKDivider=RCC_HCLK_DIV4 @@ -243,7 +244,7 @@ RCC.HCLKFreq_Value=168000000 RCC.HSE_VALUE=8000000 RCC.HSI_VALUE=16000000 RCC.I2SClocksFreq_Value=192000000 -RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQ,PLLQCLKFreq_Value,PLLSourceVirtual,RCC_RTC_Clock_SourceVirtual,RCC_RTC_Clock_Source_FROM_HSE,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S +RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQ,PLLQCLKFreq_Value,RCC_RTC_Clock_SourceVirtual,RCC_RTC_Clock_Source_FROM_HSE,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S RCC.LSI_VALUE=32000 RCC.MCO2PinFreq_Value=168000000 RCC.PLLCLKFreq_Value=168000000 @@ -251,7 +252,6 @@ RCC.PLLM=4 RCC.PLLN=168 RCC.PLLQ=7 RCC.PLLQCLKFreq_Value=48000000 -RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE RCC.RCC_RTC_Clock_SourceVirtual=RCC_RTCCLKSOURCE_LSE RCC.RCC_RTC_Clock_Source_FROM_HSE=RCC_RTCCLKSOURCE_HSE_DIV8 RCC.RTCFreq_Value=32768